将offsets存储在HBase中

将offsets存储在HBase中

HBase可以作为一个可靠的外部数据库来持久化offsets。通过将offsets存储在外部系统中,Spark Streaming应用功能能够重读或者回放任何仍然存储在Kafka中的数据。

根据HBase的设计模式,允许应用能够以rowkey和column的结构将多个Spark Streaming应用和多个Kafka topic存放在一张表格中。在这个例子中,表格以topic名称、消费者group id和Spark Streaming 的batchTime.milliSeconds作为rowkey以做唯一标识。尽管batchTime.milliSeconds不是必须的,但是它能够更好地展示历史的每批次的offsets。表格将存储30天的累积数据,如果超出30天则会被移除。下面是创建表格的DDL和结构

对每一个批次的消息,使用saveOffsets()将从指定topic中读取的offsets保存到HBase中

在执行streaming任务之前,首先会使用getLastCommittedOffsets()来从HBase中读取上一次任务结束时所保存的offsets。该方法将采用常用方案来返回kafka topic分区offsets。

情形1:Streaming任务第一次启动,从zookeeper中获取给定topic的分区数,然后将每个分区的offset都设置为0,并返回。

情形2:一个运行了很长时间的streaming任务停止并且给定的topic增加了新的分区,处理方式是从zookeeper中获取给定topic的分区数,对于所有老的分区,offset依然使用HBase中所保存,对于新的分区则将offset设置为0。

情形3:Streaming任务长时间运行后停止并且topic分区没有任何变化,在这个情形下,直接使用HBase中所保存的offset即可。

在Spark Streaming应用启动之后如果topic增加了新的分区,那么应用只能读取到老的分区中的数据,新的是读取不到的。所以如果想读取新的分区中的数据,那么就得重新启动Spark Streaming应用。

当我们获取到offsets之后我们就可以创建一个Kafka Direct DStream

在完成本批次的数据处理之后调用saveOffsets()保存offsets.
你可以到HBase中去查看不同topic和消费者组的offset数据

storm

storm

Storm架构

类似于Hadoop的架构,主从(Master/Slave)
Nimbus: 主
    集群的主节点,负责任务(task)的指派和分发、资源的分配
Supervisor: 从
    可以启动多个Worker,具体几个呢?可以通过配置来指定
    一个Topo可以运行在多个Worker之上,也可以通过配置来指定
    集群的从节点,(负责干活的),负责执行任务的具体部分
    启动和停止自己管理的Worker进程
无状态,在他们上面的信息(元数据)会存储在ZK中
Worker: 运行具体组件逻辑(Spout/Bolt)的进程
=====================分割线===================
task: 
    Spout和Bolt
    Worker中每一个Spout和Bolt的线程称为一个Task
executor: spout和bolt可能会共享一个线程
提交代码到集群:
storm jar /home/hadoop/lib/storm-1.0.jar com.bigdata.ClusterSumStormTopology
storm 其他命令的使用
list
    Syntax: storm list
    List the running topologies and their statuses.
如何停止作业
    kill
        Syntax: storm kill topology-name [-w wait-time-secs]

并行度

一个worker进程执行的是一个topo的子集
一个worker进程会启动1..n个executor线程来执行一个topo的component
一个运行的topo就是由集群中多台物理机上的多个worker进程组成

executor是一个被worker进程启动的单独线程,每个executor只会运行1个topo的一个component
task是最终运行spout或者bolt代码的最小执行单元

默认:
    一个supervisor节点最多启动4个worker进程  
    每一个topo默认占用一个worker进程         
    每个worker进程会启动一个executor        
    每个executor启动一个task   

Total slots:4  
Executors: 3   但是stormUI上是 spout + bolt = 2  why 3?
隐藏的acker 导致的
通过代码对并行度的理解:
Config conf = new Config();
conf.setNumWorkers(2); // use two worker processes
topologyBuilder.setSpout("blue-spout", new BlueSpout(), 2); // set parallelism hint to 2
topologyBuilder.setBolt("green-bolt", new GreenBolt(), 2)
           .setNumTasks(4)
           .shuffleGrouping("blue-spout");topologyBuilder.setBolt("yellow-bolt", new YellowBolt(), 6)
           .shuffleGrouping("green-bolt");StormSubmitter.submitTopology(
    "mytopology",
    conf,
    topologyBuilder.createTopology()
);

##解释:
conf.setNumWorkers(2) --->两个worker
setSpout("blue-spout", new BlueSpout(), 2)---> 2个spout executor 对应默认的2个task
setBolt("green-bolt", new GreenBolt(), 2).setNumTasks(4) ---> 2个executor 4个task(因为它指定了setNumTasks个数)

结果:
1个topology
2个workers  
2+2+2[2个worker 就有2个acker] = 6个executors  
2+4+2[2个worker 就有2个acker默认2个task] = 8个task
修改正在运行的topology的并行度:
#Reconfigure the topology "mytopology" to use 5 worker processes,
#the spout "blue-spout" to use 3 executors 
#the bolt "yellow-bolt" to use 10 executors.

1.可以使用StormUI来rebalance the topology.
2.也可以使用命令行来修改:$ storm rebalance mytopology -n 5 -e blue-spout=3 -e yellow-bolt=10

stream grouping分组策略内置[build-in]有8种:

常用的有两种:
1.shuffle grouping 随机分配也就是轮询RoundRobin 这样不会造成数据倾斜
2.fileds grouping 比如按照字段hash取模分组 
如果想自定义分组策略:--> 自定义分组策略需要实现CustomStreamGroup接口

解密大数据ID-Mapping

集奥聚合带你解密大数据ID-Mapping
来源:数据观 时间:2016-06-27 14:46:24 作者:集奥聚合
  谈到大数据,有一个非常基本但又关键的环节就是ID-Mapping(Identifier -Mapping)。ID-Mapping通俗的说就是把几份不同来源的数据,通过各种技术手段识别为同一个对象或主体,例如同一台设备(直接),同一个用户(间接),同一家企业(间接)等等,可以形象地理解为用户画像的“拼图”过程。一个用户的行为信息、属性数据是分散在很多不同的数据来源的,因此从单个数据来看,都相当于“盲人摸象”,看到的只是这个用户一个片面的画像,而ID-Mapping能把碎片化的数据全部串联起来,消除数据孤岛,提供一个用户的完整信息视图,同时让某一个领域的数据在另一个领域绽放出巨大的价值。
  ID-Mapping有非常多的用处,比如跨屏跟踪和跨设备跟踪,将一个用户的手机、PC、平板等设备的上的行为信息串联到一起。再比如这两年非常热的程序化交易,它的一个重要环节就是要把当前广告请求的用户和第一方DMP平台里的用户历史兴趣数据匹配起来。可以说,没有ID-Mapping,程序化交易就变成了盲目投放,它的实时竞价,精准投放的优势也就不存在了。
  ID-Mapping既然有这么大的作用,那么应该如何做好ID-Mapping呢?这个环节不是一个简单的按照Key匹配的过程,集奥聚合作为领先的第三方大数据公司,研发了多项ID-Mapping 的独家技术,用新的匹配技术和算法模型来重塑了ID-Mapping过程。据粗略评估,集奥聚合ID-Mapping系统有能力把十几个数据源的 56亿ID(Identifier,即标识符)匹配到一起,准确率达到 95%以上,有效用户总量提升了30%,平均每个用户的标签量提升200%以上。值得注意的是,这里的Identifier是指标识符,而并非Identity(身份信息),集奥聚合可在完全脱敏,不(也无需)识别、指出用户姓甚名谁的身份信息的情况下合法地将标识符对应至某匿名用户。
  简单来说,集奥聚合ID-Mapping体系有三个层面。
  第一个层面是物理Mapping
  这是最单纯基本的层面,也就是如何精准地记录和标识一个用户,例如利用硬件设备码生成一个统一的设备码,利用一些强账号来标识用户等等。这个层面上主要的技术难度在于ID的稳定性、唯一性和持久性。
  第二个层面是基于用户行为做迭代滚动Mapping
  由于原始数据存在噪音,同一个用户的多份数据、多种ID之间是“多对多”的关系。那么哪些ID是可信的呢?
  我们设计了一个置信度传播的机器学习图模型来帮助确定哪些身份ID是可信的。

  算法示意图如上,每个节点是一个UID或QQ号或GID等标识的潜在的“用户”
   一开始节点之间关系的概率是随机的
   其中总有两个ID的关系是强置信的prior
   迭代收敛后,哪些ID是归属于同一个用户的标识符被识别出来
  大体来说,这个算法的过程是给每一个ID,以及两个ID,如IMEI和邮箱之间的pair关系都有一个预设的置信度。而所有的ID根据两两关联构成了一张图,那么每个ID的置信度根据这张网的结构传播给相关联的ID,同时也从其他ID那边接收置信度,而pair关系的置信度不变。当算法迭代收敛时,高置信度的ID就是可信的。同一个子图内的ID就标识了同一个用户。用类似的算法,我们也可以评价每个数据源的质量等。
  第三个层面是基于用户兴趣做相似用户的合并
  如果说层面二主要还在判断标识一个用户的ID是否正确,那么层面三致力于把行为相似的用户给合并起来。
  例如,某一个用户的设备多次连接同一个Wi-Fi网关,但是每次链接都会随机更换ID,那么相当于这个用户的数据“分裂”在多个不同ID下。那么如何把这些ID合并成同一个用户呢?
  除了上述做法之外,集奥聚合开发了相似用户合并技术。基于用户的上网时间偏好、网址访问偏好、点击行为偏好、浏览行为偏好、APP偏好和社交账号偏好等,为每个用户提取了上千个特征之后,进行相似用户的聚类。
  聚类中选择类中心附近的用户,再加上一些辅助准则判定,就可以把用户合并起来。
  经实际测试,可以把用户ID总量减少80%,同时保持用户合并的准确率在91%以上。使用的历史数据时间窗越长就越精准。仅此一项就能让用户的标签密度提升 500%。最早出现于安卓
深入浅出理解 Cookie Mapping
Posted on 2014 年 11 月 9 日 by Abbo
在RTB(实时竞价广告,Real-Time-Bidding)广告领域(当然实际上不仅仅是这个领域),有一个常见的词汇叫 Cookie Mapping(Cookie 匹配),一会又是DSP(需求方供应平台)与DSP的Cookie Mapping,一会又是DSP与Ad Exchange的Cookie Mapping,一会还有DMP(数据管理平台)与DSP的Cookie Mapping,已经完全把大家搞浑了。许多互联网广告从业者都不清楚到底什么是 Cookie Mapping,到底又是为什么要 Cookie Mapping。今天就以小小的笔记,分享大家疑问的解答。
用户唯一标识体系
在互联网中,我们有着许多标识唯一用户的技术手段,其中,最为常见的就是 Cookie 了(什么是Cookie请参看网站分析中的Cookie)。简单的多,Cookie具备几个特征:
• 唯一性,一个Cookie是唯一存在于一个域名下的;
• 归属权,一个Cookie必须属于某一个域名,且相互不能访问使用;
• 持久性,一个Cookie可以持久的存在于一个浏览器中。
正因为Cookie具备上述几个特征,也就衍生出Cookie在使用上的一些特点了,我们以DSP.COM(广告购买平台),ADX.COM(广告交易平台),DMP.COM(数据管理平台)为例,存在以下结论:
• DSP.COM,ADX.COM,DMP.COM都存在各自的用户标识体系(各自定义的唯一ID标识);
• 用户Abbo在上述三个产品的ID分别是dsp-1,adx-a,dmp-①,且相互不能访问使用。
就这样,DSP.COM,ADX.COM,DMP.COM都可以唯一的标识出用户Abbo,但他们并不能互相读取标识信息。
共享用户特征
由于客户需求,广告主在DSP.COM,ADX.COM,DMP.COM均有业务存在:
• 广告主使用DSP.COM进行广告投放,并且用户Abbo点击了游戏广告;
• 用户Abbo主动使用了DMP.COM提供的浏览器购物比价插件服务;
• 用户Abbo点击过位于交易平台ADX.COM上的职业学习、求职类广告;
刚好,DSP.COM识别出了Abbo喜欢玩游戏特征,DMP.COM识别出了Abbo是男性用户,ADX.COM识别出了Abbo是个年轻人。此时问题来了,由于三方的数据并不共享,因此对于广告主而言,仅知道dsp-1喜欢玩游戏,adx-a是年轻人,dmp-①是男性用户。广告主并不能直接知道Abbo是个喜爱玩游戏的年轻男性。
最终目标,我们需要不同产品体系中的用户的特征,合并绑定到一个用户上来,这也就是本文主题的关键——Cookie Mapping。
常见 Mapping 方式
我们刚刚看到,不同厂商、产品对用户都使用了不同的标识体系,诸如dsp-a,adx-a,dmp-①此类。因此,我们在Cookie Mapping中的最为基础的信息表——ID映射关系,俗称Cookie Mapping表。它负责使dsp-1,adx-a,dmp-①关联起来。
要使同一个用户在不同体系中关联起来,只有一个做法,那就是当用户发生行为的时候,同时能够联通多家厂商、产品。也就是出现了以下最常见的几种Mapping方式生成ID映射关系表:
• 用户加载网页代码时候,同时加载DSP.COM,ADX.COM,DMP.COM的代码,互相调用Mapping接口传输ID信息;(客户端Mapping)
• 用户加载网页代码时候,由服务端转发携带ID的请求,由ADX.COM服务器告诉DSP.COM相关ID信息。(服务端Mapping)
这样一来,经过大量的Mapping匹配后,不同厂商、产品之间也就自然形成了一套对应ID映射关系表格了。
移动端的 Mapping
移动终端的发展趋势,Cookie的效果已经远不如PC端了——PC端的用户上网行为,往往发生在一两款Web浏览软件(浏览器)中,而移动端App较为分散,用户行为、特征体现在更多的应用程序(App)上。况且,移动终端的唯一性,存在着更多的ID体系标识唯一用户,诸如MAC地址、iOS IDFA、Android ID等等。这些ID往往是具备一定唯一性,并且能够在不同App中共享的标识信息。因此,移动终端有时候也不需要 Mapping,如果约定俗成的使用某一类ID也是可以进行唯一用户标识的。
斗胆小结
斗胆小结本文,观点并不一定全部正确,如有不足,还请点出:
• 唯一标识需求将长期存在;
• Cookie标识在PC端短期内(10年)不会消失;
• 多终端的发展,将出现更多标识体系;
• Mapping ID的需求将长期存在。
Open-ID是一个很好的想法,也是一个很好的应用,特别是第三方开源Open-ID产品,个人觉得还是值得一

一点做用户画像的人生经验(一):ID强打通

  1. 背景
    在构建精准用户画像时,面临着这样一个问题:日志采集不能成功地收集用户的所有ID,且每条业务线有各自定义的UID用来标识用户,从而造成了用户ID的零碎化。因此,为了做用户标签的整合,用户ID之间的强打通(亦称为ID-Mapping)成了迫切的需求。大概三年前,在知乎上有这样一个与之相类似的问题:如何用MR实现并查集以对海量数据pair做聚合;目前为止还无人解答。本文将提供一个可能的解决方案——如何用MR计算框架来实现大数据下的ID强打通。
    首先,简要地介绍下Android设备常见的ID:
    • IMEI(International Mobile Equipment Identity),即通常所说的手机序列号、手机“串号”,用于在移动电话网络中识别每一部独立的手机等行动通讯装置;序列号共有15位数字,前6位(TAC)是型号核准号码,代表手机类型。接着2位(FAC)是最后装配号,代表产地。后6位(SNR)是串号,代表生产顺序号。最后1位(SP)一般为0,是检验码,备用。
    • MAC(Media Access Control)一般代指MAC位址,为网卡的标识,用来定义网络设备的位置。
    • IMSI(International Mobile SubscriberIdentification Number),储存在SIM卡中,可用于区别移动用户的有效信息;其总长度不超过15位,同样使用0~9的数字。其中MCC是移动用户所属国家代号,占3位数字,中国的MCC规定为460;MNC是移动网号码,最多由两位数字组成,用于识别移动用户所归属的移动通信网;MSIN是移动用户识别码,用以识别某一移动通信网中的移动用户。
    • Android ID是系统随机生成的设备ID 为一串64位的编码(十六进制的字符串),通过它可以知道设备的寿命(在设备恢复出厂设置或刷机后,该值可能会改变)。
  2. 设计
    从图论的角度出发,ID强打通更像是将小连通图合并成一个大连通图;比如,在日志中出现如下三条记录,分别表示三个ID集合(小连通图):
    A B C
    C   D
        D   E
    
    通过将三个小连通图合并,便可得到一个大连通图——完整的ID集合列表A B C D E。淘宝明风介绍了如何用Spark GraphX通过outerJoinVertices等运算符来做大数据下的多图合并;针对ID强打通的场景,也可采用类似的思路:日志数据构建大的稀疏图,然后采用自join的方式做打通。但是,我并没有选用GraphX,理由如下:
    • GraphX只支持有向图,而不支持无向图,而ID之间的关联关系是一个无向连通图;
    • GraphX的join操作不完全可控,“不完全可控”是指在做图合并时我们需要做过滤山寨设备、一对多的ID等操作,而在GraphX封装好的join算子上实现过滤操作则成本过高。
    因而,基于MR计算模型(Spark框架)我设计新的ID打通算法;算法流程如下:打通的map阶段将ID集合id_set中每一个Id做key然后进行打散(id_set.map(id -> id_set))),Reduce阶段按key做id_set的合并。通过观察发现:仅需要两步MR便可完成上述打通的操作。以上面的例子做说明,第一步MR完成后,打通ID集合为:A B C D、 C D E,第二步MR完成后便得到完整的ID集合列表A B C D E。但是,在两步MR过程中,所有的key都会对应一个聚合结果,而其中一些聚合结果只是中间结果。故而引入了key_set用于保存聚合时的key值,加入了第三步MR,通过比较key_set与id_set来对中间聚合结果进行过滤。算法的伪代码如下:
    MR step1:
    Map:
    input: id_set
    process: flatMap id_set;
    output: id -> (id_set, 1)
    
    Rduce:
    process: reduceByKey
    output: id -> (id_set, empty key_set, int_value)
    

MR step2:
Map:
input: id -> (id_set, empty key_set, int_value)
process: flatMap id_set, if have id_aggregation, then add key to key_set
output: id -> (id_set, key_set, int_value)
Reduce:
process: reduceByKey
output: id -> (id_set, key_set, int_value)

MR step3:
Map:
input: id -> (id_set, empty key_set, int_value)
process: flatMap id_set, if have id_aggregation, then add key to key_set
output: id -> (id_set, key_set, int_value)
Reduce:
process: reduceByKey
output: id -> (id_set, key_set, int_value)

Filters:
process: if have id_aggregation, then add key to key_set
filter: if no id_aggregation or key_set == id_set
distinct

  1. 实现
    针对上述ID强打通算法,Spark实现代码如下:
    case class DvcId(id: String, value: String)
    val log: RDD[mutable.Set[DvcId]]// MR1val rdd1: RDD[(DvcId, (mutable.Set[DvcId], mutable.Set[DvcId], Int))] = log
    .flatMap { set =>
    set.map(t => (t, (set, 1)))
    }.reduceByKey { (t1, t2) =>
    t1._1 ++= t2._1
    val added = t1._2 + t2._2
    (t1._1, added)
    }.map { t =>
    (t._1, (t._2._1, mutable.Set.empty[DvcId], t._2._2))
    }// MR2val rdd2: RDD[(DvcId, (mutable.Set[DvcId], mutable.Set[DvcId], Int))] = rdd1
    .flatMap(flatIdSet).reduceByKey(tuple3Add)// MR3val rdd3: RDD[(DvcId, (mutable.Set[DvcId], mutable.Set[DvcId], Int))] = rdd2
    .flatMap(flatIdSet).reduceByKey(tuple3Add)// filterval rdd4 = rdd3.filter { t =>
    t._2._2 += t._1
    t._2._3 == 1 || (t._2._1 – t._2.2).isEmpty
    }.map(
    ._2._1).distinct()
    // flat id_setdef flatIdSet(row: (DvcId, (mutable.Set[DvcId], mutable.Set[DvcId], Int))) = {
    row._2._3 match {
    case 1 =>
    Array((row._1, (row._2._1, row._2._2, row._2._3)))
    case _ =>
    row._2._2 += row._1 // add key to keySet
    row._2._1.map(d => (d, (row._2._1, row._2._2, row._2._3))).toArray
    }
    }
    def tuple3Add(t1: (mutable.Set[DvcId], mutable.Set[DvcId], Int),
    t2: (mutable.Set[DvcId], mutable.Set[DvcId], Int)) = {
    
    t1._1 ++= t2._1
    t1._2 ++= t2._2
    val added = t1._3 + t2._3
    (t1._1, t1._2, added)
    }
    其中,引入常量1是为了标记该条记录是否发生了ID聚合的情况。
    ID强打通算法实现起来比较简单,但是在实际的应用时,日志数据往往是带噪声的:
    • 有山寨设备;
    • ID之间存在着一对多的情况,比如,各业务线的UID的靠谱程度不一,有的UID会对应到多个设备。
    另外,ID强打通后是HDFS的离线数据,为了提供线上服务、保证ID之间的一一对应关系,应选择何种分布式数据库、表应如何设计、如何做到数据更新时而不影响线上服务等等,则是另一个需要思考的问题。

逻辑回归算法的实战案例实现(LR)

逻辑回归算法的实战案例实现(LR)

逻辑回归

逻辑回归(Logistic Regression, LR)又称为逻辑回归分析,是分类和预测算法中的一种。通过历史数据的表现对未来结果发生的概率进行预测。例如,我们可以将购买的概率设置为因变量,将用户的特征属性,例如性别,年龄,注册时间等设置为自变量。根据特征属性预测购买的概率。逻辑回归与回归分析有很多相似之处,在开始介绍逻辑回归之前我们先来看下回归分析。
CsQx4e.png
回归分析用来描述自变量x和因变量Y之间的关系,或者说自变量X对因变量Y的影响程度,并对因变量Y进行预测。其中因变量是我们希望获得的结果,自变量是影响结果的潜在因素,自变量可以有一个,也可以有多个。一个自变量的叫做一元回归分析,超过一个自变量的叫做多元回归分析。

广告费用和曝光次数的案例:

下面是一组广告费用和曝光次数的数据,费用和曝光次数一一对应。其中曝光次数是我们希望知道的结果,费用是影响曝光次数的因素,我们将费用设置为自变量X,将曝光次数设置为因变量Y,通过一元线性回归方程和判定系数可以发现费用(X)对曝光次数(Y)的影响。

Cslp3d.png

以下为一元回归线性方式,其中y是因变量,X是自变量,我们只需求出截距b0和斜率b1就可以获得费用和曝光次数之间的关系,并对曝光次数进行预测。这里我们使用最小二乘法来计算截距b0和斜率b1。最小二乘法通过最小化误差的平方和寻找数据的最佳函数匹配。

CslCjI.png

下表中是使用最小二乘法计算回归方程的一些必要的计算过程。在表中最左侧的两列分别为自变量X和因变量Y,我们首先计算出自变量和因变量的均值,然后计算每一个观测值与均值的差,以及用于计算回归方程斜率b1所需的数据。

Csliut.png

根据表中的数据按公式计算出了回归方程的斜率b1,计算过程如下。斜率表示了自变量和因变量间的关系,斜率为正表示自变量和因变量正相关,斜率为负表示自变量和因变量负相关,斜率为0表示自变量和因变量不相关。

CslkHf.png

求得斜率b1后,按下面的公式可以求出Y轴的截距b0。

CslVUS.png

将斜率b1和截距b0代入到回归方程中,通过这个方程我们可以获得自变量和因变量的关系,费用每增加1元,曝光次数会增长7437次。以下为回归方程和图示。

Cslugs.png

CslQuq.png

在回归方程的图示中,还有一个R平方,这个值叫做判定系数,用来衡量回归方程是否很好的拟合了样本的数据。判定系数在0-1之间,值越大说明拟合的越好,换句话说就是自变量对因变量的解释度越高。判定系数的计算公式为SST=SSR+SSE,其中SST是总平方和,SSR是回归平方和,SSE是误差平方和。下表为计算判定系数所需三个指标的一些必要的计算过程。

CsllD0.png

根据前面求得的回归平方和(SSR)和总平方和(SST)求得判定系数为0.94344。

CslGUU.png

以上为回归方程的计算过程,在根据费用预测曝光数量的场景下,我们可以通过回归方程在已知费用的情况下计算出曝光数量。

用户的属性和特征来判断用户购买意愿的案例:

逻辑回归与回归方程相比在线性回归的基础上增加了一个逻辑函数。例如通过用户的属性和特征来判断用户最终是否会进行购买。其中购买的概率是因变量Y,用户的属性和特征是自变量X。Y值越大说明用户购买的概率越大。这里我们使用事件发生的可能性(odds)来表示购买与未购买的比值。

CslJ5F.png

使用E作为购买事件,P(E)是购买的概率,P(E’)是未购买的概率,Odds(E)是事件E(购买)发生的可能性。

CsltC4.png

Odds是一个从0到无穷的数字,Odds的值越大,表明事件发生的可能性越大。下面我们要将Odds转化为0-1之间的概率函数。首先对Odds取自然对数,得到logit方程,logit是一个范围在负无穷到正无穷的值。

Csl0Dx.png

基于上面的logit方程,获得以下公式:

CslBb6.png

其中使用π替换了公式中的P(E),π=P(E)。根据指数函数和对数规则获得以下公式:

Csly5D.png

并最终获得逻辑回归方程:

CslcPe.png

下面根据逻辑回归方程来计算用户购买的概率,下表是用户注册天数和是否购买的数据,其中注册天数是自变量X,是否购买是自变量Y。我们将购买标记为1,将未购买标记为0。接下来我们将在Excel中通过8个步骤计算出逻辑回归方程的斜率和截距。并通过方程预测新用户是否会购买。

Csl22d.png

第一步,使用Excel的排序功能对原始数据按因变量Y进行排序,将已购买和未购买的数据分开,使得数据特征更加明显。
第二步,按照Logit方程预设斜率b1和截距b0的值,这里我们将两个值都预设为0.1。后续再通过Excel求最优解。
第三步,按照logit方程,使用之前预设的斜率和截距值计算出L值。
CslfKI.png

第四步,将L值取自然对数,
第五步,计算P(X)的值,P(X)为事件发生的可能性(Odds)。具体的计算步骤和过程见下图。
CslIVf.png

第六步,计算每个值的对数似然函数估计值(Log-Likelihood)。方法和过程见下图。
第七步,将对数似然函数值进行汇总。
Csloa8.png

第八步,使用Excel的规划求解功能,计算最大对数似然函数值。方法和过程见下图。设置汇总的对数似然函数值LL为最大化的目标,预设的斜率b1和截距b0是可变单元格,取消”使无约束变量为非负数”的选项。进行求解。
CslHPg.png

Excel将自动求出逻辑回归方程中斜率和截距的最优解,结果如下图所示。

CslLxs.png

求得逻辑回归方程的斜率和截距以后,我们可以将值代入方程,获得一个注册天数与购买概率的预测模型,通过这个模型我们可以对不同注册天数(X)用户的购买概率(Y)进行预测。以下为计算过程。

CslXMn.png

第一步,输入自变量注册天数(X)的值,这里我们输入50天。
第二步,将输入的X值,以及斜率和截距套入Logit方程,求出L值。
第三步,对L值取自然对数。
第四步,求时间发生可能性P(X)的概率值。
注册天数为50天的用户购买的概率约为17.60%。

我们将所有注册天数的值代入到购买概率预测模型中,获得了一条注册天数对购买概率影响的曲线。从曲线中可以发现,注册天数在较低和较高天数的用户购买概率较为平稳。中间天数用户的购买概率变化较大。

Cslvq0.png

我们继续在上面的计算结果中增加新的自变量“年龄”。以下是原始数据的截图。现在有年龄和注册天数两个自变量和一个因变量。

Cs1SaT.png

依照前面的方法计算斜率和截距的最优解,并获得逻辑回归方程,将不同的年龄和注册天数代入到方程中,获得了用户年龄和注册天数对购买的预测模型。我们通过Excel的三维图表来绘制年龄和注册天数对购买概率的影响。

Cs1CiF.png

从图中可以看出,购买概率随着注册天数的增加而增长,并且在相同的注册天数下,年龄较小的用户购买概率相对较高。

k均值聚类(k-means)

1、摘要

在前面的文章中,介绍了三种常见的分类算法。分类作为一种监督学习方法,要求必须事先明确知道各个类别的信息,并且断言所有待分类项都有一个类别与之对应。但是很多时候上述条件得不到满足,尤其是在处理海量数据的时候,如果通过预处理使得数据满足分类算法的要求,则代价非常大,这时候可以考虑使用聚类算法。聚类属于无监督学习,相比于分类,聚类不依赖预定义的类和类标号的训练实例。本文首先介绍聚类的基础——距离与相异度,然后介绍一种常见的聚类算法——k均值和k中心点聚类,最后会举一个实例:应用聚类方法试图解决一个在体育界大家颇具争议的问题——中国男足近几年在亚洲到底处于几流水平。

2、相异度计算

在正式讨论聚类前,我们要先弄清楚一个问题:如何定量计算两个可比较元素间的相异度。用通俗的话说,相异度就是两个东西差别有多大,例如人类与章鱼的相异度明显大于人类与黑猩猩的相异度,这是能我们直观感受到的。但是,计算机没有这种直观感受能力,我们必须对相异度在数学上进行定量定义。
CdhcUe.png,其中X,Y是两个元素项,各自具有n个可度量特征属性,那么X和Y的相异度定义为:CdhRCd.png,其中R为实数域。也就是说相异度是两个元素对实数域的一个映射,所映射的实数定量表示两个元素的相异度。
下面介绍不同类型变量相异度计算方法。

2.1、标量

标量也就是无方向意义的数字,也叫标度变量。现在先考虑元素的所有特征属性都是标量的情况。例如,计算X={2,1,102}和Y={1,3,2}的相异度。一种很自然的想法是用两者的欧几里得距离来作为相异度,欧几里得距离的定义如下:
CdhW8A.png

其意义就是两个元素在欧氏空间中的集合距离,因为其直观易懂且可解释性强,被广泛用于标识两个标量元素的相异度。将上面两个示例数据代入公式,可得两者的欧氏距离为:
CdhfgI.png

除欧氏距离外,常用作度量标量相异度的还有曼哈顿距离和闵可夫斯基距离,两者定义如下:
曼哈顿距离:Cdhhvt.png

闵可夫斯基距离:Cdh5KP.png

欧氏距离和曼哈顿距离可以看做是闵可夫斯基距离在p=2和p=1下的特例。另外这三种距离都可以加权,这个很容易理解,不再赘述。
下面要说一下标量的规格化问题。上面这样计算相异度的方式有一点问题,就是取值范围大的属性对距离的影响高于取值范围小的属性。例如上述例子中第三个属性的取值跨度远大于前两个,这样不利于真实反映真实的相异度,为了解决这个问题,一般要对属性值进行规格化。所谓规格化就是将各个属性值按比例映射到相同的取值区间,这样是为了平衡各个属性对距离的影响。通常将各个属性均映射到[0,1]区间,映射公式为:
CdhIDf.png

其中max(ai)和min(ai)表示所有元素项中第i个属性的最大值和最小值。例如,将示例中的元素规格化到[0,1]区间后,就变成了X’={1,0,1},Y’={0,1,0},重新计算欧氏距离约为1.732。

2.2、二元变量

所谓二元变量是只能取0和1两种值变量,有点类似布尔值,通常用来标识是或不是这种二值属性。对于二元变量,上一节提到的距离不能很好标识其相异度,我们需要一种更适合的标识。一种常用的方法是用元素相同序位同值属性的比例来标识其相异度。
设有X={1,0,0,0,1,0,1,1},Y={0,0,0,1,1,1,1,1},可以看到,两个元素第2、3、5、7和8个属性取值相同,而第1、4和6个取值不同,那么相异度可以标识为3/8=0.375。一般的,对于二元变量,相异度可用“取值不同的同位属性数/单个元素的属性位数”标识。
上面所说的相异度应该叫做对称二元相异度。现实中还有一种情况,就是我们只关心两者都取1的情况,而认为两者都取0的属性并不意味着两者更相似。例如在根据病情对病人聚类时,如果两个人都患有肺癌,我们认为两个人增强了相似度,但如果两个人都没患肺癌,并不觉得这加强了两人的相似性,在这种情况下,改用“取值不同的同位属性数/(单个元素的属性位数-同取0的位数)”来标识相异度,这叫做非对称二元相异度。如果用1减去非对称二元相异度,则得到非对称二元相似度,也叫Jaccard系数,是一个非常重要的概念。

2.3、分类变量

分类变量是二元变量的推广,类似于程序中的枚举变量,但各个值没有数字或序数意义,如颜色、民族等等,对于分类变量,用“取值不同的同位属性数/单个元素的全部属性数”来标识其相异度。

2.4、序数变量

序数变量是具有序数意义的分类变量,通常可以按照一定顺序意义排列,如冠军、亚军和季军。对于序数变量,一般为每个值分配一个数,叫做这个值的秩,然后以秩代替原值当做标量属性计算相异度。

2.5、向量

对于向量,由于它不仅有大小而且有方向,所以闵可夫斯基距离不是度量其相异度的好办法,一种流行的做法是用两个向量的余弦度量,其度量公式为:
Cdh7VS.png

其中||X||表示X的欧几里得范数。要注意,余弦度量度量的不是两者的相异度,而是相似度!

3、聚类问题

在讨论完了相异度计算的问题,就可以正式定义聚类问题了。
所谓聚类问题,就是给定一个元素集合D,其中每个元素具有n个可观察属性,使用某种算法将D划分成k个子集,要求每个子集内部的元素之间相异度尽可能低,而不同子集的元素相异度尽可能高。其中每个子集叫做一个簇。
与分类不同,分类是示例式学习,要求分类前明确各个类别,并断言每个元素映射到一个类别,而聚类是观察式学习,在聚类前可以不知道类别甚至不给定类别数量,是无监督学习的一种。目前聚类广泛应用于统计学、生物学、数据库技术和市场营销等领域,相应的算法也非常的多。本文仅介绍一种最简单的聚类算法——k均值(k-means)算法。

4、K-means算法及其示例

k均值算法的计算过程非常直观:

1、从D中随机取k个元素,作为k个簇的各自的中心。
2、分别计算剩下的元素到k个簇中心的相异度,将这些元素分别划归到相异度最低的簇。
3、根据聚类结果,重新计算k个簇各自的中心,计算方法是取簇中所有元素各自维度的算术平均数。
4、将D中全部元素按照新的中心重新聚类。
5、重复第4步,直到聚类结果不再变化。
6、将结果输出。

由于算法比较直观,没有什么可以过多讲解的。下面,我们来看看k-means算法一个有趣的应用示例:中国男足近几年到底在亚洲处于几流水平?

今年中国男足可算是杯具到家了,几乎到了过街老鼠人人喊打的地步。对于目前中国男足在亚洲的地位,各方也是各执一词,有人说中国男足亚洲二流,有人说三流,还有人说根本不入流,更有人说其实不比日韩差多少,是亚洲一流。既然争论不能解决问题,我们就让数据告诉我们结果吧。

下图是我采集的亚洲15只球队在2005年-2010年间大型杯赛的战绩(由于澳大利亚是后来加入亚足联的,所以这里没有收录):
CdhHUg.png

其中包括两次世界杯和一次亚洲杯。我提前对数据做了如下预处理:对于世界杯,进入决赛圈则取其最终排名,没有进入决赛圈的,打入预选赛十强赛赋予40,预选赛小组未出线的赋予50。对于亚洲杯,前四名取其排名,八强赋予5,十六强赋予9,预选赛没出现的赋予17。这样做是为了使得所有数据变为标量,便于后续聚类。

下面先对数据进行[0,1]规格化,下面是规格化后的数据:
Cdhb5Q.png

接着用k-means算法进行聚类。设k=3,即将这15支球队分成三个集团。

现抽取日本、巴林和泰国的值作为三个簇的种子,即初始化三个簇的中心为A:{0.3, 0, 0.19},B:{0.7, 0.76, 0.5}和C:{1, 1, 0.5}。下面,计算所有球队分别对三个中心点的相异度,这里以欧氏距离度量。下面是我用程序求取的结果:
CdhO8s.png

从做到右依次表示各支球队到当前中心点的欧氏距离,将每支球队分到最近的簇,可对各支球队做如下聚类:
中国C,日本A,韩国A,伊朗A,沙特A,伊拉克C,卡塔尔C,阿联酋C,乌兹别克斯坦B,泰国C,越南C,阿曼C,巴林B,朝鲜B,印尼C。

第一次聚类结果:

A:日本,韩国,伊朗,沙特;
B:乌兹别克斯坦,巴林,朝鲜;
C:中国,伊拉克,卡塔尔,阿联酋,泰国,越南,阿曼,印尼。

下面根据第一次聚类结果,调整各个簇的中心点。
A簇的新中心点为:{(0.3+0+0.24+0.3)/4=0.21, (0+0.15+0.76+0.76)/4=0.4175, (0.19+0.13+0.25+0.06)/4=0.1575} = {0.21, 0.4175, 0.1575}
用同样的方法计算得到B和C簇的新中心点分别为{0.7, 0.7333, 0.4167},{1, 0.94, 0.40625}。

用调整后的中心点再次进行聚类,得到:
CdhX2n.png

第二次迭代后的结果为:

中国C,日本A,韩国A,伊朗A,沙特A,伊拉克C,卡塔尔C,阿联酋C,乌兹别克斯坦B,泰国C,越南C,阿曼C,巴林B,朝鲜B,印尼C。
结果无变化,说明结果已收敛,于是给出最终聚类结果:

亚洲一流:日本,韩国,伊朗,沙特
亚洲二流:乌兹别克斯坦,巴林,朝鲜
亚洲三流:中国,伊拉克,卡塔尔,阿联酋,泰国,越南,阿曼,印尼

看来数据告诉我们,说国足近几年处在亚洲三流水平真的是没有冤枉他们,至少从国际杯赛战绩是这样的。
其实上面的分析数据不仅告诉了我们聚类信息,还提供了一些其它有趣的信息,例如从中可以定量分析出各个球队之间的差距,例如,在亚洲一流队伍中,日本与沙特水平最接近,而伊朗则相距他们较远,这也和近几年伊朗没落的实际相符。另外,乌兹别克斯坦和巴林虽然没有打进近两届世界杯,不过凭借预算赛和亚洲杯上的出色表现占据B组一席之地,而朝鲜由于打入了2010世界杯决赛圈而有幸进入B组,可是同样奇迹般夺得2007年亚洲杯的伊拉克却被分在三流,看来亚洲杯冠军的分量还不如打进世界杯决赛圈重啊。其它有趣的信息,有兴趣的朋友可以进一步挖掘。

逻辑回归模型(Logistic Regression)

逻辑回归(Logistic Regression)是机器学习中的一种分类模型,由于算法的简单和高效,在实际中应用非常广泛。本文主要关注逻辑回归算法的数学模型和参数求解方法,最后也会简单讨论下逻辑回归和贝叶斯分类的关系,以及在多分类问题上的推广。

逻辑回归

问题

实际工作中,我们可能会遇到如下问题:

1.预测一个用户是否点击特定的商品
2.判断用户的性别
3.预测用户是否会购买给定的品类
4.判断一条评论是正面的还是负面的

这些都可以看做是分类问题,更准确地,都可以看做是二分类问题。同时,这些问题本身对美团也有很重要的价值,能够帮助我们更好的了解我们的用户,服务我们的用户。要解决这些问题,通常会用到一些已有的分类算法,比如逻辑回归,或者支持向量机。它们都属于有监督的学习,因此在使用这些算法之前,必须要先收集一批标注好的数据作为训练集。有些标注可以从log中拿到(用户的点击,购买),有些可以从用户填写的信息中获得(性别),也有一些可能需要人工标注(评论情感极性)。另一方面,知道了一个用户或者一条评论的标签后,我们还需要知道用什么样的特征去描述我们的数据,对用户来说,可以从用户的浏览记录和购买记录中获取相应的统计特征,而对于评论来说,最直接的则是文本特征。这样拿到数据的特征和标签后,就得到一组训练数据:

Csn3M6.png
其中 xi 是一个 m 维的向量,CsnYZD.png ,y 在 {0, 1} 中取值。(本文用{1,0}表示正例和负例,后文沿用此定义。)

我们的问题可以简化为,如何找到这样一个决策函数Csntde.png,它在未知数据集上能有足够好的表现。至于如何衡量一个二分类模型的好坏,我们可以用分类错误率这样的指标:Csnaid.png 。也可以用准确率,召回率,AUC等指标来衡量。

值得一提的是,模型效果往往和所用特征密切相关。特征工程在任何一个实用的机器学习系统中都是必不可少的。

模型

sigmoid 函数

在介绍逻辑回归模型之前,我们先引入sigmoid函数,其数学形式是:

CsnWJs.png
对应的函数曲线如下图所示:
Csnhzq.png

从上图可以看到sigmoid函数是一个s形的曲线,它的取值在[0, 1]之间,在远离0的地方函数的值会很快接近0/1。这个性质使我们能够以概率的方式来解释(后边延伸部分会简单讨论为什么用该函数做概率建模是合理的)。

决策函数

一个机器学习的模型,实际上是把决策函数限定在某一组条件下,这组限定条件就决定了模型的假设空间。当然,我们还希望这组限定条件简单而合理。而逻辑回归模型所做的假设是:

Csn5Q0.png
这里的 g(h) 是上边提到的 sigmoid 函数,相应的决策函数为:

CsnIyV.png
选择0.5作为阈值是一个一般的做法,实际应用时特定的情况可以选择不同阈值,如果对正例的判别准确性要求高,可以选择阈值大一些,对正例的召回要求高,则可以选择阈值小一些。

参数求解

模型的数学形式确定后,剩下就是如何去求解模型中的参数。统计学中常用的一种方法是最大似然估计,即找到一组参数,使得在这组参数下,我们的数据的似然度(概率)越大。在逻辑回归模型中,似然度可表示为:

Csn7eU.png
取对数可以得到对数似然度:

Csnbo4.png
另一方面,在机器学习领域,我们更经常遇到的是损失函数的概念,其衡量的是模型预测错误的程度。常用的损失函数有0-1损失,log损失,hinge损失等。其中log损失在单个数据点上的定义为CsnOY9.png
如果取整个数据集上的平均log损失,我们可以得到

CsnXWR.png
即在逻辑回归模型中,我们最大化似然函数和最小化log损失函数实际上是等价的。对于该优化问题,存在多种求解方法,这里以梯度下降的为例说明。梯度下降(Gradient Descent)又叫作最速梯度下降,是一种迭代求解的方法,通过在每一步选取使目标函数变化最快的一个方向调整参数的值来逼近最优值。基本步骤如下:

选择下降方向(梯度方向,∇J(θ))
选择步长,更新参数 CsnvS1.png
重复以上两步直到满足终止条件
CsnxQx.png
其中损失函数的梯度计算方法为:

Csnzy6.png
沿梯度负方向选择一个较小的步长可以保证损失函数是减小的,另一方面,逻辑回归的损失函数是凸函数(加入正则项后是严格凸函数),可以保证我们找到的局部最优值同时是全局最优。此外,常用的凸优化的方法都可以用于求解该问题。例如共轭梯度下降,牛顿法,LBFGS等。

分类边界

知道如何求解参数后,我们来看一下模型得到的最后结果是什么样的。很容易可以从sigmoid函数看出,当CsuCwD.png 时,y=1,否则 y=0。CsuFFH.png 是模型隐含的分类平面(在高维空间中,我们说是超平面)。所以说逻辑回归本质上是一个线性模型,但是,这不意味着只有线性可分的数据能通过LR求解,实际上,我们可以通过特征变换的方式把低维空间转换到高维空间,而在低维空间不可分的数据,到高维空间中线性可分的几率会高一些。下面两个图的对比说明了线性分类曲线和非线性分类曲线(通过特征映射)。
CsuAfA.png

左图是一个线性可分的数据集,右图在原始空间中线性不可分,但是在特征转换 CsuVSI.png 后的空间是线性可分的,对应的原始空间中分类边界为一条类椭圆曲线。

正则化

当模型的参数过多时,很容易遇到过拟合的问题。这时就需要有一种方法来控制模型的复杂度,典型的做法在优化目标中加入正则项,通过惩罚过大的参数来防止过拟合:

CsulkQ.png
一般情况下,取p=1或p=2,分别对应L1,L2正则化,两者的区别可以从下图中看出来,L1正则化(左图)倾向于使参数变为0,因此能产生稀疏解。
Csu3fs.png

实际应用时,由于我们数据的维度可能非常高,L1正则化因为能产生稀疏解,使用的更为广泛一些。

延伸

生成模型和判别模型

逻辑回归是一种判别模型,表现为直接对条件概率P(y|x)建模,而不关心背后的数据分布P(x,y)。而高斯贝叶斯模型(Gaussian Naive Bayes)是一种生成模型,先对数据的联合分布建模,再通过贝叶斯公式来计算样本属于各个类别的后验概率,即:

CsuGpn.png
通常假设P(x|y)是高斯分布,P(y)是多项式分布,相应的参数都可以通过最大似然估计得到。如果我们考虑二分类问题,通过简单的变化可以得到:

CsuJlq.png
如果 σ1=σ0,二次项会抵消,我们得到一个简单的线性关系:

CsuY60.png
由上式进一步可以得到:

CsuBtJ.png
可以看到,这个概率和逻辑回归中的形式是一样的。这种情况下GNB 和 LR 会学习到同一个模型。实际上,在更一般的假设(P(x|y)的分布属于指数分布族)下,我们都可以得到类似的结论。

多分类(softmax)

如果y不是在[0,1]中取值,而是在K个类别中取值,这时问题就变为一个多分类问题。有两种方式可以出处理该类问题:一种是我们对每个类别训练一个二元分类器(One-vs-all),当K个类别不是互斥的时候,比如用户会购买哪种品类,这种方法是合适的。如果K个类别是互斥的,即 y=i 的时候意味着 y 不能取其他的值,比如用户的年龄段,这种情况下 Softmax 回归更合适一些。Softmax 回归是直接对逻辑回归在多分类的推广,相应的模型也可以叫做多元逻辑回归(Multinomial Logistic Regression)。模型通过 softmax 函数来对概率建模,具体形式如下:

Csu66x.png
而决策函数为:CsucX6.png
对应的损失函数为:

Csu5hd.png
类似的,我们也可以通过梯度下降或其他高阶方法来求解该问题,这里不再赘述。

应用

本文开始部分提到了几个在实际中遇到的问题,这里以预测用户对品类的购买偏好为例,介绍一下美团是如何用逻辑回归解决工作中问题的。该问题可以转换为预测用户在未来某个时间段是否会购买某个品类,如果把会购买标记为1,不会购买标记为0,就转换为一个二分类问题。我们用到的特征包括用户在美团的浏览,购买等历史信息,见下表
CsQHj1.png

其中提取的特征的时间跨度为30天,标签为2天。生成的训练数据大约在7000万量级(美团一个月有过行为的用户),我们人工把相似的小品类聚合起来,最后有18个较为典型的品类集合。如果用户在给定的时间内购买某一品类集合,就作为正例。哟了训练数据后,使用Spark版的LR算法对每个品类训练一个二分类模型,迭代次数设为100次的话模型训练需要40分钟左右,平均每个模型2分钟,测试集上的AUC也大多在0.8以上。训练好的模型会保存下来,用于预测在各个品类上的购买概率。预测的结果则会用于推荐等场景。

由于不同品类之间正负例分布不同,有些品类正负例分布很不均衡,我们还尝试了不同的采样方法,最终目标是提高下单率等线上指标。经过一些参数调优,品类偏好特征为推荐和排序带来了超过1%的下单率提升。

此外,由于LR模型的简单高效,易于实现,可以为后续模型优化提供一个不错的baseline,我们在排序等服务中也使用了LR模型。

总结

逻辑回归的数学模型和求解都相对比较简洁,实现相对简单。通过对特征做离散化和其他映射,逻辑回归也可以处理非线性问题,是一个非常强大的分类器。因此在实际应用中,当我们能够拿到许多低层次的特征时,可以考虑使用逻辑回归来解决我们的问题。

参考资料

Wikipedia, http://en.wikipedia.org/wiki/Logistic_regression

决策树算法及模型

决策树

决策树(Decision Tree)是一种简单但是广泛使用的分类器。通过训练数据构建决策树,可以高效的对未知的数据进行分类。决策数有两大优点:1)决策树模型可以读性好,具有描述性,有助于人工分析;2)效率高,决策树只需要一次构建,反复使用,每一次预测的最大计算次数不超过决策树的深度。

如何预测

先看看下面的数据表格:
CdDKU0.png

上表根据历史数据,记录已有的用户是否可以偿还债务,以及相关的信息。通过该数据,构建的决策树如下:
CdD32F.png

比如新来一个用户:无房产,单身,年收入55K,那么根据上面的决策树,可以预测他无法偿还债务(蓝色虚线路径)。从上面的决策树,还可以知道是否拥有房产可以很大的决定用户是否可以偿还债务,对借贷业务具有指导意义。

基本步骤

决策树构建的基本步骤如下:

1.开始,所有记录看作一个节点
2.遍历每个变量的每一种分割方式,找到最好的分割点
3.分割成两个节点N1和N2
4.对N1和N2分别继续执行2-3步,直到每个节点足够“纯”为止

决策树的变量可以有两种:

1) 数字型(Numeric):变量类型是整数或浮点数,如前面例子中的“年收入”。用“>=”,“>”,“<”或“<=”作为分割条件(排序后,利用已有的分割情况,可以优化分割算法的时间复杂度)。

2) 名称型(Nominal):类似编程语言中的枚举类型,变量只能重有限的选项中选取,比如前面例子中的“婚姻情况”,只能是“单身”,“已婚”或“离婚”。使用“=”来分割。

如何评估分割点的好坏?如果一个分割点可以将当前的所有节点分为两类,使得每一类都很“纯”,也就是同一类的记录较多,那么就是一个好分割点。比如上面的例子,“拥有房产”,可以将记录分成了两类,“是”的节点全部都可以偿还债务,非常“纯”;“否”的节点,可以偿还贷款和无法偿还贷款的人都有,不是很“纯”,但是两个节点加起来的纯度之和与原始节点的纯度之差最大,所以按照这种方法分割。构建决策树采用贪心算法,只考虑当前纯度差最大的情况作为分割点。

量化纯度

前面讲到,决策树是根据“纯度”来构建的,如何量化纯度呢?这里介绍三种纯度计算方法。如果记录被分为n类,每一类的比例P(i)=第i类的数目/总数目。还是拿上面的例子,10个数据中可以偿还债务的记录比例为P(1) = 7/10 = 0.7,无法偿还的为P(2) = 3/10 = 0.3,N = 2。
CdD0PK.png

纯度差,也称为信息增益(Information Gain),公式如下:
CdDD2D.png

其中,I代表不纯度(也就是上面三个公式的任意一种),K代表分割的节点数,一般K = 2。vj表示子节点中的记录数目。上面公式实际上就是当前节点的不纯度减去子节点不纯度的加权平均数,权重由子节点记录数与当前节点记录数的比例决定。

停止条件

决策树的构建过程是一个递归的过程,所以需要确定停止条件,否则过程将不会结束。一种最直观的方式是当每个子节点只有一种类型的记录时停止,但是这样往往会使得树的节点过多,导致过拟合问题(Overfitting)。另一种可行的方法是当前节点中的记录数低于一个最小的阀值,那么就停止分割,将max(P(i))对应的分类作为当前叶节点的分类。

过渡拟合

采用上面算法生成的决策树在事件中往往会导致过滤拟合。也就是该决策树对训练数据可以得到很低的错误率,但是运用到测试数据上却得到非常高的错误率。过渡拟合的原因有以下几点:

噪音数据:训练数据中存在噪音数据,决策树的某些节点有噪音数据作为分割标准,导致决策树无法代表真实数据。
缺少代表性数据:训练数据没有包含所有具有代表性的数据,导致某一类数据无法很好的匹配,这一点可以通过观察混淆矩阵(Confusion Matrix)分析得出。
多重比较(Mulitple Comparition):举个列子,股票分析师预测股票涨或跌。假设分析师都是靠随机猜测,也就是他们正确的概率是0.5。每一个人预测10次,那么预测正确的次数在8次或8次以上的概率为
CdDrxe.png
,只有5%左右,比较低。但是如果50个分析师,每个人预测10次,选择至少一个人得到8次或以上的人作为代表,那么概率为
CdD6rd.png
,概率十分大,随着分析师人数的增加,概率无限接近1。但是,选出来的分析师其实是打酱油的,他对未来的预测不能做任何保证。上面这个例子就是多重比较。这一情况和决策树选取分割点类似,需要在每个变量的每一个值中选取一个作为分割的代表,所以选出一个噪音分割标准的概率是很大的。

优化方案1:修剪枝叶

决策树过渡拟合往往是因为太过“茂盛”,也就是节点过多,所以需要裁剪(Prune Tree)枝叶。裁剪枝叶的策略对决策树正确率的影响很大。主要有两种裁剪策略。

前置裁剪 在构建决策树的过程时,提前停止。那么,会将切分节点的条件设置的很苛刻,导致决策树很短小。结果就是决策树无法达到最优。实践证明这中策略无法得到较好的结果。

后置裁剪 决策树构建好后,然后才开始裁剪。采用两种方法:1)用单一叶节点代替整个子树,叶节点的分类采用子树中最主要的分类;2)将一个字数完全替代另外一颗子树。后置裁剪有个问题就是计算效率,有些节点计算后就被裁剪了,导致有点浪费。

优化方案2:K-Fold Cross Validation

首先计算出整体的决策树T,叶节点个数记作N,设i属于[1,N]。对每个i,使用K-Fold Validataion方法计算决策树,并裁剪到i个节点,计算错误率,最后求出平均错误率。这样可以用具有最小错误率对应的i作为最终决策树的大小,对原始决策树进行裁剪,得到最优决策树。

优化方案3:Random Forest

Random Forest是用训练数据随机的计算出许多决策树,形成了一个森林。然后用这个森林对未知数据进行预测,选取投票最多的分类。实践证明,此算法的错误率得到了经一步的降低。这种方法背后的原理可以用“三个臭皮匠定一个诸葛亮”这句谚语来概括。一颗树预测正确的概率可能不高,但是集体预测正确的概率却很高。

准确率估计

决策树T构建好后,需要估计预测准确率。直观说明,比如N条测试数据,X预测正确的记录数,那么可以估计acc = X/N为T的准确率。但是,这样不是很科学。因为我们是通过样本估计的准确率,很有可能存在偏差。所以,比较科学的方法是估计一个准确率的区间,这里就要用到统计学中的置信区间(Confidence Interval)。

设T的准确率p是一个客观存在的值,X的概率分布为X ~ B(N,p),即X遵循概率为p,次数为N的二项分布(Binomial Distribution),期望E(X) = Np,方差Var(X) = Np(1-p)。由于当N很大时,二项分布可以近似有正太分布(Normal Distribution)计算,一般N会很大,所以X ~ N(np,np(1-p))。可以算出,acc = X/N的期望E(acc) = E(X/N) = E(X)/N = p,方差Var(acc) = Var(X/N) = Var(X) / N2 = p(1-p) / N,所以acc ~ N(p,p*(1-p)/N)。这样,就可以通过正太分布的置信区间的计算方式计算执行区间了。

正太分布的置信区间求解如下:

1) 将acc标准化,即
Cd6lw9.png

2) 选择置信水平α= 95%,或其他值,这取决于你需要对这个区间有多自信。一般来说,α越大,区间越大。

3) 求出 α/2和1-α/2对应的标准正太分布的统计量
CdD4G8.png
CdD5RS.png
(均为常量)。然后解下面关于p的不等式。acc可以有样本估计得出。即可以得到关于p的执行区间
CdDHqs.png

another example:
有一天,小明无聊,对宿舍玩CS的舍友进行统计,结果刚记下四行,被舍友认为影响发挥,给踢到床下去了,让我们看看可怜的小明的记录:
CdyrxU.png

为了对得起小明记录的这四条记录,我们对其进行决策树分析,从数据中看:

  1. 如果一个玩家子弹很多,那么即使血少他也会战斗,如果子弹少的话,即使血多,他也会逃跑隐蔽起来;
  2. 那我们再看子弹少的情况下,武器靠刀子,当血多时候,他还是会打一打得,但是血少,就立即逃跑隐蔽了。

这是我们大脑直觉上去分析,既然本文我是想聊一聊决策树,那么我们就用决策树来对小明的这些数据小试牛刀一下,顺便来慰藉一下小明(从小到大我们已经看过无数的小明了,这里再借用一下大度的小明)。

我们现在将数据分为两块:

X = {武器类型,子弹数量,血}
Y = {行为}
我们建立这颗决策树的目的就是,让计算机自动去寻找最合适的映射关系,即:Y = f(X),所谓听上去大雅的“数据挖掘”学科,干得也差不多就是这回事,X我们称之为样本,Y我们称之为结果(行为/类)。

样本是多维的,X = {x1,x2,…xn},如本例:X = {x1=武器类型,x2=子弹数量,x3=血},我们就是要通过这些不同维度的观测记录数据,和应对的不同结果,找到规律(映射关系),举个例子:

X = {天气,温度,湿度,女友约会} -> Y = {是否答应兄弟下午去打篮球}
X = {老妈说你是胖子,老婆说你是胖子,自己上秤评估自己体重} -> Y = {去办健身卡减肥}

这样来说,X的多维不同的数据,大个比方,更像是很多大臣,那么我们就是要根据这些大臣的意见,来决策,如本例:

左大臣:武器类型
中大臣:子弹数量
右大臣:血

这些大臣每个人都有想法,左右着皇帝继续战斗还是撤退,但是三个也不能全信,那么我们就要根据他们的陈年老帐(训练样本)来评判他们的话语的重要性,当然,优先级高的肯定话语是有重量的,我们先提前来预览一下这个例子训练出来的决策树的样子:
CdrCL9.png

这个根据小明的数据训练出来的决策树是不是和我们刚才拍脑门分析出来的结果差不多呢?看,子弹多就开打,子弹少,在看看用什么武器,如果又没子弹又用机枪,那铁定跑,如果用小刀,在掂量一下自己血厚不厚,厚则打,不厚则逃,看来决策树分析的结果还是可以的啊,接下来,我们来研究研究,计算机(这个只会重复人们给它设定的代码的家伙)是如何实现这样的分析的。

既然是三个大臣提意见{左大臣:武器类型,中大臣:子弹数量,右大臣:血},那么我们要分析一下历史数据(训练数据)他们哪个话更靠谱:

我们先单纯的看看左大臣的历史战绩(统计训练样本):

机枪 -> 战斗
机枪 -> 逃跑
小刀 -> 战斗
小刀 -> 逃跑
用机枪,你战斗逃跑的概率都是50%,用刀子,你亦似打似逃!看来这个大臣立场不坚定啊!

再看看中大臣的:

子弹多 -> 战斗
子弹少 -> 逃跑
子弹少 -> 战斗
子弹少 -> 逃跑
用机枪,你战斗概率是100%,用刀子,你33.3%打,你66.6%撤!这位大臣似乎坚定了一些。

再看看右大臣的:

血少 -> 战斗
血多 -> 逃跑
血多 -> 战斗
血少 -> 逃跑
和左大臣一样,立场不坚定,50:50啊!

这样,中大臣的话的重量就提升了,因此决策书的第一层就重用中大臣吧(中大臣变成一品大员)

计算机是怎么来做到这一步的呢?且让我一步一步讲:

决策树训练中,有一个很重要的尺子,来衡量大臣的可信度,这个尺子,就是信息论的熵(Entropy),这个熵是何许人也,竟然朝廷大臣的可信度竟然用次来衡量,让我们对他做个自我介绍吧:
熵,洋名为(Entropy),乃测量信息的混乱程度为职,纵横科学界各门学术之中,为人低调,俭朴,就一个很短的公式:E = sum(-p(I)*log(p(I))),I=1:N(N类结果,如本例两种,战斗或逃跑),当信息一致,所有样本都属于一个类别I,那么熵为0,如果样本完全随机,那么熵为1,表明这个臣子对这种状态的预测就是胡言乱语。

OK,熵,告诉我你对这个数据的看法:

E(机枪) = -(1/2)Log2(1/2) - (1/2)Log(1/2) = 0.5 + 0.5 = 1
E(小刀) = -(1/2)Log2(1/2) - (1/2)Log(1/2) = 0.5 + 0.5 = 1
E(子弹多) = -(1/1)Log2(1/1) - (0/1)Log(0/1) = 0 + 0 = 0
E(子弹少) = -(1/3)Log2(1/3) - (2/3)Log(2/3) = 0.5283 + 0.39 = 0.9183
E(血多) = -(1/2)Log2(1/2) - (1/2)Log(1/2) = 0.5 + 0.5 = 1
E(血少) = -(1/2)Log2(1/2) - (1/2)Log(1/2) = 0.5 + 0.5 = 1

那么我们怎么用这个熵来衡量大臣(每维数据)的可信度呢,这里还要再引出一位仁兄,其是熵的上级,他熟知熵的能力,很会用熵,他就是信息增益(Information Gain),我们来看看这位上级是如何用熵来衡量的:
Gain(Sample,Action) = E(sample) - sum(|Sample(v)|/Sample * E(Sample(v)))

OK,Information Gain,说说你是怎么评估这个例子的三位大臣的!

Gain(武器类型) = E(S) - (2/4)E(机枪) - (2/4)E(小刀) = 1 - (2/4)1 - (2/4)1 = 0
Gain(子弹数量) = E(S) - (1/4)E(子弹多) - (3/4)E(子弹少) = 1 - (1/4)0 - (3/4)0.9183 = 0.3113
Gain(血量) = E(S) - (2/4)E(血多) - (2/4)E(血少) = 1 - (2/4)1 - (2/4)1 = 0

接着,计算机通过信息增益结果,选择最大的,作为一品大员
CdrEi6.png

且看一品大员对子弹多的情况下料事如神(暂且不说本例样本少),但是其在子弹少的情况下,决策还是不行的,那么,再用同样的方法,再去选择二品,三品,这就是决策树的训练。

电商常见分析指标

电商常见分析指标
信息流、物流和资金流三大平台是电子商务的三个最为重要的平台。而电子商务信息系统最核心的能力是大数据能力,包括大数据处理、数据分析和数据挖掘能力。无论是电商平台(如淘宝)还是在电商平台上销售产品的卖家,都需要掌握大数据分析的能力。越成熟的电商平台,越需要以通过大数据能力驱动电子商务运营的精细化,更好的提升运营效果,提升业绩。构建系统的电子商务数据分析指标体系是数据电商精细化运营的重要前提,本文将重点介绍电商数据分析指标体系。
电商数据分析指标体系分为八大类指标,包括总体运营指标、网站流量累指标、销售转化指标、客户价值指标、商品及供应链指标、营销活动指标、风险控制指标和市场竞争指标。不同类别指标对应电商运营的不同环节,如网站流量指标对应的是网站运营环节,销售转化、客户价值和营销活动指标对应的是电商销售环节。
1.电商总体运营指标
CYaO3t.png

电商总体运营整体指标主要面向的人群电商运营的高层,通过总体运营指标评估电商运营的整体效果。电商总体运营整体指标包括四方面的指标:

(1)流量类指标

独立访客数(UV),指访问电商网站的不重复用户数。对于PC网站,统计系统会在每个访问网站的用户浏览器上“种”一个cookie来标记这个用户,这样每当被标记cookie的用户访问网站时,统计系统都会识别到此用户。在一定统计周期内如(一天)统计系统会利用消重技术,对同一cookie在一天内多次访问网站的用户仅记录为一个用户。而在移动终端区分独立用户的方式则是按独立设备计算独立用户。

页面访问数(PV),即页面浏览量,用户每一次对电商网站或着移动电商应用中的每个网页访问均被记录一次,用户对同一页面的多次访问,访问量累计。
人均页面访问数,即页面访问数(PV)/独立访客数,该指标反映的是网站访问粘性。

(2)订单产生效率指标

总订单数量,即访客完成网上下单的订单数之和。
访问到下单的转化率,即电商网站下单的次数与访问该网站的次数之比。

(3)总体销售业绩指标

网站成交额(GMV),电商成交金额,即只要网民下单,生成订单号,便可以计算在GMV里面。
销售金额。销售金额是货品出售的金额总额。

注:无论这个订单最终是否成交,有些订单下单未付款或取消,都算GMV,销售金额一般只指实际成交金额,所以,GMV的数字一般比销售金额大。

客单价,即订单金额与订单数量的比值。

(4)整体指标

销售毛利,是销售收入与成本的差值。销售毛利中只扣除了商品原始成本,不扣除没有计入成本的期间费用(管理费用、财务费用、营业费用)。
毛利率,是衡量电商企业盈利能力的指标,是销售毛利与销售收入的比值。如京东的2014年毛利率连续四个季度稳步上升,从第一季度的10.0%上升至第四季度的12.7%,体现出京东盈利能力的提升。

2.网站流量指标
CYa6AJ.png

(1)流量规模类指标
常用的流量规模类指标包括独立访客数和页面访问数,相应的指标定义在前文(电商总体运营指标)已经描述,在此不在赘述

(2)流量成本累指标
单位访客获取成本。该指标指在流量推广中,广告活动产生的投放费用与广告活动带来的独立访客数的比值。单位访客成本最好与平均每个访客带来的收入以及这些访客带来的转化率进行关联分析。若单位访客成本上升,但访客转化率和单位访客收入不变或下降,则很可能流量推广出现问题,尤其要关注渠道推广的作弊问题。

(3)流量质量类指标
跳出率(Bounce Rate)也被称为蹦失率,为浏览单页即退出的次数/该页访问次数,跳出率只能衡量该页做为着陆页面(LandingPage)的访问。如果花钱做推广,着落页的跳出率高,很可能是因为推广渠道选择出现失误,推广渠道目标人群和和被推广网站到目标人群不够匹配,导致大部分访客来了访问一次就离开。

页面访问时长。页访问时长是指单个页面被访问的时间。并不是页面访问时长越长越好,要视情况而定。对于电商网站,页面访问时间要结合转化率来看,如果页面访问时间长,但转化率低,则页面体验出现问题的可能性很大。

人均页面浏览量。人均页面浏览量是指在统计周期内,平均每个访客所浏览的页面量。人均页面浏览量反应的是网站的粘性。

(4)会员类指标

注册会员数。指一定统计周期内的注册会员数量。
活跃会员数。活跃会员数,指在一定时期内有消费或登录行为的会员总数。
活跃会员率。即活跃会员占注册会员总数的比重。
会员复购率。指在统计周期内产生二次及二次以上购买的会员占购买会员的总数。
会员平均购买次数。指在统计周期内每个会员平均购买的次数,即订单总数/购买用户总数。会员复购率高的电商网站平均购买次数也高。
会员回购率。指上一期末活跃会员在下一期时间内有购买行为的会员比率。
会员留存率。会员在某段时间内开始访问你的网站,经过一段时间后,仍然会继续访问你的网站就被认作是留存,这部分会员占当时新增会员的比例就是新会员留存率,这种留存的计算方法是按照活跃来计算,另外一种计算留存的方法是按消费来计算,即某段的新增消费用户在往后一段时间时间周期(时间周期可以是日、周、月、季度和半年度)还继续消费的会员比率。留存率一般看新会员留存率,当然也可以看活跃会员留存。留存率反应的是电商留住会员的能力。

3.网站销售(转化率)类指标
CYaghR.png

(1)购物车类指标
基础类指标,包括一定统计周期内加入购物车次数、加入购物车买家数、加入购物车买家数以及加入购物车商品数。
转化类指标,主要是购物车支付转化率,即一定周期内加入购物车商品支付买家数与加入购物车购买家数的比值。

(2)下单类指标
基础类指标,包括一定统计周期内的下单笔数、下单金额以及下单买家数。
转化类指标,主要是浏览下单转化率,即下单买家数与网站访客数(UV)的比值。

(3)支付类指标
基础统计类指标,包括一定统计周期内支付金额、支付买家数和支付商品数。
转化类指标。包括浏览-支付买家转化率(支付买家数/网站访客数)、下单-支付金额转化率(支付金额/下单金额)、下单-支付买家数转化率(支付买家数/下单买家数)和下单-支付时长(下单时间到支付时间的差值)。

4.客户价值类指标
CYaW1x.png

客户指标。常见客户指标包括一定统计周期内的累计购买客户数和客单价。客单价是指每一个客户平均购买商品的金额,也即是平均交易金额,即成交金额与成交用户数的比值。

新客户指标。常见新客户指标包括一定统计周期内的新客户数量、新客户获取成本和新客户客单价。其中,新客户客单价是指第一次在店铺中产生消费行为的客户所产生交易额与新客户数量的比值。影响新客户客单价的因素除了与推广渠道的质量有关系,还与电商店铺活动以及关联销售有关。

老客户指标。常见老客户指标包括消费频率、最近一次购买时间、消费金额和重复购买率。消费频率是指客户在一定期间内所购买的次数;最近一次购买时间表示客户最近一次购买的时间离现在有多远;客户消费金额指客户在最近一段时间内购买的金额。消费频率越高,最近一次购买时间离现在越近,消费金额越高的客户越有价值。重复购买率则指消费者对该品牌产品或者服务的重复购买次数,重复购买率越多,则反应出消费者对品牌的忠诚度就越高,反之则越低。重复购买率可以按两种口径来统计:第一种,从客户数角度,重复购买率指在一定周期内下单次数在两次及两次以上的人数与总下单人数之比,如在一个月内,有100个客户成交,其中有20个是购买两次及以上,则重复购买率为20%;第二种,按交易计算,即重复购买交易次数与总交易次数的比值,如某月内,一共产生了100笔交易,其中有20个人有了二次购买,这20人中的10个人又有了三次购买,则重复购买次数为30次,重复购买率为30%。

5.商品类指标
CYafc6.png

产品总数指标。包括SKU、SPU和在线SPU。SKU是物理上不可分割的最小存货单位。SPU即Standard Product Unit (标准化产品单元),SPU是商品信息聚合的最小单位,是一组可复用、易检索的标准化信息的集合,该集合描述了一个产品的特性。通俗点讲,属性值、特性相同的商品就可以称为一个SPU。如iphone5S是一个SPU,而iPhone 5S配置为16G版、4G手机、颜色为金色、网络类型为TD-LTE/TD-SCDMA/WCDMA/GSM则是一个SKU。在线SPU则是在线商品的SPU数。

产品优势性指标。主要是独家产品的收入占比,即独家销售的产品收入占总销售收入的比例。

品牌存量指标。包括品牌数和在线品牌数指标。品牌数指商品的品牌总数量。在线品牌数则指在线商品的品牌总数量。

上架。包括上架商品SKU数、上架商品SPU数、上架在线SPU数、上架商品数和上架在线商品数。

首发。包括首次上架商品数和首次上架在线商品数。

6.市场营销活动指标
CYaIBD.png

市场营销活动指标。包括新增访问人数、新增注册人数、总访问次数、订单数量、下单转化率以及ROI。其中,下单转化率是指活动期间,某活动所带来的下单的次数与访问该活动的次数之比。投资回报率(ROI)是指,某一活动期间,产生的交易金额与活动投放成本金额的比值。

广告投放指标。包括新增访问人数、新增注册人数、总访问次数、订单数量、UV订单转化率、广告投资回报率。其中,下单转化率是指某广告所带来的下单的次数与访问该活动的次数之比。投资回报率(ROI)是指,某广告产生的交易金额与广告投放成本金额的比值。

7.风控类指标
CYa7AH.png

买家评价指标。包括买家评价数,买家评价卖家数、买家评价上传图片数、买家评价率、买家好评率以及卖家差评率。其中,买家评价率是指某段时间参与评价的卖家与该时间段买家数量的比值,是反映用户对评价的参与度,电商网站目前都在积极引导用户评价,以作为其他买家购物时候的参考。买家好评率指某段时间内好评的买家数量与该时间段买家数量的比值。同样,买家差评率指某段时间内差评的买家数量与该时间段买家数量的比值。尤其是买家差评率,是非常值得关注的指标,需要监控起来,一旦发现买家差评率在加速上升,一定要提高警惕,分析引起差评率上升的原因,及时改进。

买家投诉类指标。包括发起投诉(或申诉),撤销投诉(或申诉),投诉率(买家投诉人数占买家数量的比例)等。投诉量和投诉率都需要及时监控,以发现问题,及时优化。

8.市场竞争类指标
CYaHNd.png

市场份额相关指标,包括市场占有率、市场扩大率和用户份额。市场占有率指电商网站交易额占同期所有同类型电商网站整体交易额的比重;市场扩大率指购物网站占有率较上一个统计周期增长的百分比;用户份额指购物网站独立访问用户数占同期所有B2C购物网站合计独立访问用户数的比例。

网站排名,包括交易额排名和流量排名。交易额排名指电商网站交易额在所有同类电商网站中的排名;流量排名指电商网站独立访客数量在所有同类电商网站中的排名。

总之,本文介绍了电商数据分析的基础指标体系,涵盖了流量、销售转化率、客户价值、商品类目、营销活动、风控和市场竞争指标,这些指标都需要系统化的进行统计和监控,才能更好的发现电商运营健康度的问题,以更好及时改进和优化,提升电商收入。如销售转化率,其本质上是一个漏斗模型,如从网站首页到最终购买各个阶段的转化率的监控和分析是网站运营健康度很重要的分析方向。

HBASE总结:出自Google论文的发表

HBASE:出自Google论文的发表

[列式存储、多版本(timestamp)的、nosql数据库]
hbase架构图:要能手画出来

**HBase没有单节点故障(因为zookeeper),可以有多个Hmaster,跟namenode一样,同一时刻只有一个hmaster在工作

HBase的功能:

*hadoop数据库:
    1.存储数据 
    2.检索数据
*和RDBMS[关系型数据库]相比:
    1.海量数据:数据条目数--上亿
    2.检索的速度:准时性、秒级别
*基于hdfs: hdfs的优势
    1.数据安全性[副本机制]
    2.普通商用PC server就ok
1.Table中的所有行都是按照rowkey的字典序排列
2.Table在行的方向上分割为多个Region
3.Region是按照大小分割的,每个表开始只有一个region[会有一个starkey和endkey,前毕后包],随着数据增多,region不断增大,当增大到一定阀值时,region就会等分为两个新的region,之后会有越来越多的region。
4.Region是HBase中分布式存储和负载均衡的最小单位,不同region分不到不同的RegionServer上.
5.Region虽然是分布式存储的最小单元,但是不是存储的最小单元。
存储的最小单元是cell,{rowkey,column,version}
        *唯一性
        *数据没有类型,以字节码形式存储

region由一个或多个store组成,每个store保存一个column family;
每个store又由一个memStore和0至多个storeFile组成;
memStore存储在内存中,storeFile存储在hdfs上
hbase 旧版本的web监听端口 60010,新版本是16010

HBASE数据写入流程:

put ---> cell
    step0: 先进行记录 --->HLog 【WAL(write ahead logging:日志预写功能)】 loc:hdfs
            存储的log数据类型是sequenceFile

——- WAL的作用是防止写入内存时,region挂掉,数据丢失

step1: 写入memStore     loc:内存
step2: 当内存达到一定阈值时,写入storeFile  ---> loc: hdfs

HBASE 用户读取数据流程:

1)先到memStore里面去读
2)然后到BlockCache里面读 --> *每个RegionServer只有一个BlockCache*
3)最后到HFile里面读取数据
4)然后对数据进行Merge --> 最后返回数据集

MemSore和BlockCache

*HBase上的RegionServer的内存分为两部分:
    1.Memstore --> 用来 写
        写请求会先写入Memstore,RegionServer会给每个Region提供一个Memstore,当Memstore写满64M以后,会启动flush舒心到磁盘。
    2.BlockCache --> 用来读
        读请求先到Memstore中查询数据,查不到就到BlockCache中查询,再差不读奥就会到磁盘上读,并把读的结果放入BlockCache。
        BlockCache达到上限后,会启动淘汰机制,淘汰掉最老的一批数据
*在注重读取响应时间的场景下,可以将BlockCache设置大些,Memstore设置小些,以加大缓存的命中率。

数据检索的三种方式:

1.get rowkey --- 最快的方式
2.scan range --- 用的最多的方式 【一般先range扫描,然后get】
3.scan ---全表扫描,基本不用

HBase中有类似于RDBMS中Database的概念

命名空间:
    *用户自定义的表的命名空间,默认情况下 --->  default
    *系统自带的元数据的表的命名空间 ---> hbase

HBase数据迁移

使用 MapReduce把文件生成hdfs上的HFile,然后进行bulk load into hbase table

**HBase表RowKey的设计**

**现实环境中出现的问题:
*默认情况下创建一张HBase表,自动会为表创建一个Region [startkey,endkey) 前毕后包
    *无论在测试环境还是生产环境中,创建完表以后会往表中导入大量数据
        步骤:
            file/datas -> HFile -> bulk load into hbase table
        此时Region只有一个,而region是被RegionServer管理的,
        当导入数据量慢慢增大后Region就会被split成两个Region,
        但是此时RegionServer很可能就会挂掉,此时就会出现问题...

解决方案[举例]:
    创建表时,多创建一些Region(依据表的rowkey进行设计 + 结合业务)
        比如说:有5个region,他们被多个RegionServer管理
            再插入数据时,会向5个Region中分别插入数据,这样就均衡了
**具体解决方案:

表的RowKey设计中:

**如何在海量数据中,查询到我想要的数据???
    核心思想:
        1.依据RowKey查询最快
        2.对RowKey进行范围查询range
        3.前缀查询  
            比如:startkey:15221467820_20180409000053 和 endkey:15221467828_20180419000053
            这时只会比较15221467820 和 15221467828 而后面的_2018.. 则不会进行匹配    

解决方法:

a).HBase的预分区:
    Region的划分依赖于RowKey,预先预估一些RowKey(年月日时分秒)[最常用的就是这两种,其他的方法rowkey设计都不能自定义]
        1. create 'tb1','cf1',splits => ['20180409000000','20180419000000','20180429000000']
        2. create 'tb1','cf1',splits_file => '/root/data/logs-split.txt'
           [这种情况就是把分段的rowkey写入了文件里]
    这样就分为了4个Region,因为它会把头和尾也算进去
b).根据业务来对RowKey的设计:
        举例:移动运营商电话呼叫查询详单:
            RowKey: 
                phone + time 
                15221467820_20180409010000
            infor: 
                上海  主叫   152216888888   30        国内通话 0.00
                area active opposite_phone talk_time model price 
        依据查询条件:
            phone + (start_time - end_time)
        代码:
            scan 
                startrow
                    15221467820_20180409000000
                stoprow
                    15221467820_20180419000000
    保证了实时性

HBase数据存储二级索引[索引表]的设计以及数据同步解决方案:

基于以上的移动运营商电话呼叫查询详单:

二级索引表:
    RowKey:
        opposite_phone
    columnFamily对应的colume:
        主表的RowKey
主表和索引表的同步:
    >> phoenix 
            >> jdbc 方式才能同步
    >>先在solr里创建索引表
     solr   //在solr中创建索引表
            国外有个框架交 lily
                cloudera search 封装了lily,只要配置下cloudera
                cloudera search会在主表插入数据时,自动更新solr里的索引表

HBase之 表的属性:

面试会问到:**每个RegionServer只有一个HLog和一个BlockCache

1.HBase的表的压缩[HFile compression]--表的属性:
**在企业中通常使用snappy格式进行压缩,可以减少容量的存储,和减少io流,提高传输效率
    跟hive一样,需要一些编译jar包,然后放到lib的native里
    [这里使用软连接 ln -s /xx/xx /xx  具体看官方文档],还有一些参数的配置,才能使用
        创建表的时候:
            create 'user',{NAME='cf1',COMPRESSION=>'SNAPPY'}
2. HBase 标的属性:IN_MEMORY=>'false'、BLOCKCACHE=>'true'
        HBase为什么查询这么快 就是因为这些表的属性的存储机制!!
        通常我们自定义创建的表的相应列簇下的IN_MEMORY属性都是false!
        通过describe 'hbase:meta'可以查询到 IN_MEMORY=>'true' BLOCKCACHE => 'true',
        意为meta元数据存放于blockcache的inmemory内存中
            IN_MEMORY队列存放HBase的meta表元数据信息,因为meta存储了用户表的
            通常 BLOCKCACHE 这个属性的设置要慎用,比如我们查询后的数据后续还会用到这时可以设置为true
            如果后续用不到这些数据就要设置此属性为false

HBase的Cache分等级:

默认情况下:整个BlockCache的内存分配 
1.IN_MEMORY 1/4    in_memory 用于存储hbase的meta元数据信息    2.Single 1/4   single就是用的次数较少的数据
3.Muti    1/2          muti就是用的次数较多的数据
如果BlockCache的内存到达阈值,会先清理single然后清理muti,in_memory的内存不会被清理!

HBase表的compaction

随着写入数据的不断增加,hbase会把小的hfile进行合并,以以减少IO查询次数,合并有两种:
1.minor compaction
    Minor Compaction是指选取一些小的、相邻的StoreFile将他们合并成一个更大的StoreFile,
    在这个过程中不会处理已经Deleted或Expired的Cell。一次Minor Compaction的结果是更少并且更大的StoreFile。
2.major compaction
    Major Compaction是指将所有的StoreFile合并成一个StoreFile,这个过程还会清理三类无意义数据:被删除的数据、TTL过期数据、版本号超过设定版本号的数据。另外,一般情况下,Major Compaction时间会持续比较长,会阻塞数据的吸入和查询!!!,整个过程会消耗大量系统资源,对上层业务有比较大的影响。因此线上业务都会将关闭自动触发Major Compaction功能,改为手动在业务低峰期触发。

HBase和Hive集成:

此时实质上Hive就是HBase的一个客户端!
应用场景:
    日志文件 --> hive --> hive-hbase-table --> insert .. select ...

电商订单查询之HBase:

1.用户下单后-->存到RDBMS[关系型数据库]中 即未完成的订单
2.订单完成后-->数据迁移到HBase中

查询比如三个月内的订单:
 1.主表[订单显示表]:
    rowkey: userid_orderCreateTime_orderId  
    cfname: orderInfor
    [本来userid+orderCreateTime就可以保证唯一性,加orderId的原因是为了二次查询]
 2.订单详情表:
     rowkey: orderId_orderItemId
    cfname: itemInfor
 3.索引表:
     比如用户输入订单号:我们后台Redis或者MongoDB里会有相对应的订单编码
     获取到订单编码然后到索引表中去查
         索引表的rowkey:订单编号 column: 主表的rowkey
         就可以到hbase主表中查询订单
补充文件类型 .tsv[tab] .csv[comma]:
user.tsv tsv后缀格式的文件:每行数据以tab 制表符分割的 
user.csv csv后缀格式的文件:每行数据以逗号分割的

dmp介绍

dmp

(数据管理平台)
编辑
DMP(Data Management Platform)数据管理平台,是把分散的多方数据进行整合纳入统一的技术平台,并对这些数据进行标准化和细分,让用户可以把这些细分结果推向现有的互动营销环境里的平台。
中文名
数据管理平台
外文名
Data Management Platform
释 义
数据进行整合纳入统一的技术平台
简 称
DMP
目录
. 1 作用
. 2 类型
作用
编辑
•能快速查询、反馈和快速呈现结果
•能帮助客户更快进入到市场周期中
•能促成企业用户和合作伙伴之间的合作
•能深入的预测分析并作出反应
•能带来各方面的竞争优势
•能降低信息获取及人力成本
类型
编辑
1、结构化的数据,比如Oracle数据库数据等;
  2、非结构化的数据,比如各种文件、图像、音频等数据,等等。
  结构化数据(即数据库数据)在当今的信息系统中占据最核心、最重要的位置。结构化数据从产生―使用―消亡这样一个完整过程的管理,就是数据生命周期管理(所谓的ILM)。
核心元素包括:
•数据整合及标准化能力:采用统一化的方式,将各方数据吸纳整合。
•数据细分管理能力:创建出独一无二、有意义的客户细分,进行有效营销活动。
•功能健全的数据标签:提供数据标签灵活性,便于营销活动的使用。
•自助式的用户界面:基于网页web界面或其他集成方案直接获取数据工具,功能和几种形式报表和分析。
•相关渠道环境的连接:跟相关渠道的集成,包含网站端、展示广告、电子邮件以及搜索和视频,让营销者能找到、定位和提供细分群体相关高度的营销信息。