广告拍卖机制与点击率预估概述(二)
2016-01-28 15:53
435 查看
《广告拍卖机制与点击率预估概述(一)》中,我们介绍了点击率预估在广告系统中的重要性,这里我们对点击率预计与建模中主要使用到的架构、数据、与算法进行介绍。
系统架构
公欲善其事,并先利其器。
点击率预估可以说是大数据应用的典型案例。广告系统中有着大量日志,例如腾讯广点通有百亿的曝光。他们的点击、曝光就是天然的正、负样本数据。点击率预估涉及到大量日志信息的存储、处理与计算,而这些处理,业界主要借助那些工具来完成的呢?
从我过往的经验来看,业界主要借助一下四个解决方案:
hadoop
strom
mpi
spark
google是大数据处理的先驱,hadoop用于数据预处理的的三家马车:HDFS,mapreduce,hbase实际上是来之google的馈赠。
hadoop主要提供了几个问题的支持:
1、磁盘的读/写慢: HDFS通过并行提高存储速度。
2、并行硬件故障率高: HDFS通过冗余备份来提高容错性。
3、大数据汇总处理: MapReduce提供的可靠的编程模型。
4、HBASE非结构化数据的支持
他们的生态系统图可以概括如下(图非原创):
其中,mapreduce为我们提供了一个简单的计算框架,它主要通过数据并行的方式来进行并行计算。mapreduce的计算框架可以概括如下:
1、map:通过数据切分,根据数据量的多少,启动多个map端读数据进行处理。,以<key,value>键值对的形式,进行输出。
2、shuffle: 根据map端输出的<key,value>值,对数据进行排序。排序后的数据传送到reduce端进行处理。
3、reduce:reduce端对有相同key值的数据进行归并处理,并将最终的数据写入到hdfs中。
mapreduce框架中对数据进行了冗余备份,整个zookepeer负责对整个集群进行资源分布,任务调度,错误节点的重启,具有良好的容错性。
mapreduce + hdfs默认是以行来为单位来进行为单位进行数据的写入。日志中曝光与点击发生的时间的间隔时间从1s到数十分钟不等,而在点击率预估中,我们需要将曝光与点击关联起来来判断这个样本是正样例还是负样例。显然,常用的以行mapreduce + hdfs框架并不适用。
Hbase则为我们的日志提供了高速日志写入工具。Hbase也是广点通的实时样本数据流的使用工具。它底层还是基于hdfs完成的数据写入,只不过它以列的方式来对数据进行实时写入,具体的架构,我们可以参见下图(下图非原创,但是一时找不到准确的来源):
hbase主要给我们带来的主要的功能有两点:
1、百万列的数据写入。
从以行为key进行写入转换到以列为key进行写入,一条记录的列数和数据量大小得到了巨大的扩充。(可以想像一下,一条百万列的记录,在以行为key的map-reduce框架中出来起来会有多么的困难。数据的读入,排序都将有着巨大的延迟,甚至不可用)
2、高并发,低延迟
统一时间新产生的日志,无论曝光还是点击行为,无论他们的均可以同时的进行归并写入。具有高并发,低延迟的特点。
hadoop可以对点击率预估进行最基本的支持。如果选择合适的训练方法(例如一天训练一个模型、模型采用分片的方式进行训练),那么我们完全可以基于hadoop来搭建一套点击率预估系统。基于hadoop来完成数据的搜集,预处理、以及模型训练功能。
当然,hadoop也存在着一定的不足,hadoop的特点可以概括如下:
Hadoop的优点:
1、支持大数据的处理,可扩展性强。
2、容错性高且快速有效
3、社区资源丰富:pig,hive,mahout
hadoop的不足:
1、不支持迭代计算
2、批处理数据,响应时间慢
当需要学习一个模型的时候,我们往往需要对批量的数据进行多次迭代,并更新模型权重来逐步进行收敛。受限于计算架构,hadoop的map-reduce框架对机器学习的算法都支持不足:
1、缺少对迭代计算的支持
2、各个map/reduer独立工作,缺少消息同步机制
MPI(Message Passing Interface, MPI)以及spark是一个成熟的技术解决方案。
MPI的特点:
1、搭建简单、功能强大
2、开发难度略高,没有容错机制。
MPI是一个功能非常强大的并行计算工具,它更多的是一个编写消息传递程序而开发的广范使用的标准,我们最常用的实现版本为:MPICH。
MPI基于消息传递机制,理论上可以实现各种复杂的计算框架。但是底层的功能的开发主要是需要工程师自己去完成。开发的工作量相对较“重”。而当我们想要简单、快速验证一个模型和想法的时候,他的尝试、开发成本相对较高。
为了提供提供一套开发上更为简单的并行计算工具,Berkeley开发的一个开源的集群计算系统:spark。他主要提供了基于内存的数据迭代查询与计算的工具。spark需要学习一种新的开发语言scala,不过它的学习成本与开发成本非常小。非常适合作为快速的算法验证工具。(我们可以先在spark上实现代码,验证效果,后面迁移到运行更为高效、快速的mpi集群中来).
概括而言,spark的特点如下:
1、开发简单,快速迭代方便
2、新语言的学习成本,hdfs系统的支持
在点击率预估中,数据越实时,越能反馈用户当前的意图。举一个简单的例子,用户刚刚搜索了“充电宝”,那么下一个query“锤子”和手机的相关性可能更高。如果cookie或者合作的电商企业记录了用户在商场中搜索了一系列的“女士项链”,那么在qzone中给一个男性用户推荐一个 鲜花,甚至”女士手表“也是符合情理的。
hadoop中的map-reduce或者hbase对实时的数据的快速记录与处理应该说是分钟级别的,业界进行主要借助与storm进行更为实时的数据处理,它是一个分布式的、可容错的实时计算系统。
如下图所示(图片非原创):
storm中信息流根据拓扑结构,将数据流分配到各个数据平台中进行处理。它可以根据各个节点的负载情况分配数据流的,确保每一条消息都会被实时处理。(公司也有很多业务或部门大量使用storm进行数据处理,大家也可以搜索他们的文章进行更深入的了解).
storm最重要的两个特点是:
伸缩性强:我们可以增加更多的自己来应对信息流的增长。
良好的健壮性和容错:storm有良好的健壮性和容错功能,确保我们的数据不丢失。
在hadoop(hdfs,map-reduce,hbase),storm以及spark,mpi工具的基础上,基本上,我们可以搭建一个满足实时性、以及大数据处理的点击率预估系统了。
基础数据:
点击率预估主要依赖四类数据:用户、广告、上下文、以及场景信息。如下图:
在特征的设计上,我们可以把特征分为原始特征与cross特征,特征的cross方式可以集合业务知识设计组合方式,并且通过特征选择方式来进行特征选择。
cross特征示例:
特征的类型可以划分为两类:
数值型:年龄,广告历史点击率: (归一化)
Nominal: 学历(初中、高中、大学),行业(IT,教育)
当曝光量充足的时候,对于数值型的特征,我们可以通过区间切分的方法,来离散化它。例如我们采用线性模型的时候,自变量x与因变量y之间可能不是一个线性的关系。直接采用线性模型拟合它的时候会造成较大的偏差。
LR模型:
有很多种点击率预估模型可以供选择。例如LR(logstic regression),GBDT(gradient boosting descion tree) ,DNN(deep neural network)。其中,点击率预估最常用的模型是logistic regression model。因为他:
1、预估时间线性,可以大大减少线上系统的耗时。
这对于线上的实时服务来说,至关重要。
2、支持特征压缩:
LR可以通过L1的约束,大大的压缩特征空间,减少加载的模型大小。
我们以常用的人口统计为例:
1、人群 i 的观察数量
,人群数N,总观察数量M,
2、时间(例如疾病)i的发生概率 :
3、事件i第k维的特征 :
LR模型的假设:
π_i是一个sigmoid函数,他将【-00,+00】的数值空间压缩到0,1之间,其中0的取值为0.5,是一个分类点,并且sigmoid函数在0附近是非常sensitive的。
LR模型的求解:
lr模型是通过最大似然函数来进行求解,其中在N个样本中,每个样本有n_i个观察变量,其中y_i个人被观察到是发生了疾病,那么整个分布的联合概率为:
求解LR模型的参数,只需要最大化上面的联合概率即刻。因为我们一般通过梯度下降法进行求解,而一个连乘的公式,显然是难以求解的。对数函数与原函数增/减趋势保持一致的良好特性,如下图:
我们利用这个特性,求解将最大似然函数的最大值的求解,转换为其对数的最大值的求解。
给定我们最优化目标之后,函数的优化就变为凸优化问题(凸包的证明我们忽略),凸优化问题可以简单的描述如下(有详细了解的同学,可以参考后文推荐的书籍):
convex optimization(unconstraint):
凸函数的特点为:
1、有最小值解
2、函数处处可导
3、函数二次导数正定
凸函数的解有多种,最简单的可以采用最速梯度法求解:
每次求解函数的梯度,向负梯度方向搜索固定步长,求得得在当前方向下,函数最小值作为作为下一次函数的起始点。
最速下降法的计算较为简单,对于下降的步长,可以采用启发式搜寻&固定步数。但是,同时他的下降速度相对较慢。为了获得更快的下降速度,可以采用newton法进行求解。
牛顿法:
可以将函数进行泰勒展开:
每次求解泰勒展开式的最小值:
求解脱成如下图:
牛顿法的下载速度较为快速,但是需要求解Hessian矩阵,它的求逆计算复杂,存储量高。因此,BFGS(避免求逆);LBFGS(避免保存hessian矩阵)则是他们的改进。其中LBFGS方法最为常用。这里不展开对他们的介绍,有兴趣可以参见文献:convex optimization。
梯度的求解:
无论LBFGS还是最速梯度法,我们都需要对似然函数进行求解一阶导,他们的求导流程如下:
一阶偏导:
过拟合&稀疏正则化
广告中的特征有成百万甚至过亿,如果把所有的特征都加载到模型中:
1、将会大幅度的加载的负担。
2、大量的特征的权重,置信度不高或者并不显著。
因此,我们常常通过L1 或者 L2范式来对模型进行正则化约束。最大似然的公式如下:
我们可以把L1,L2分别看作是参数的先验分布:
L1先验拉普拉斯分布:
L2先验高斯分布:
基于L1,L2约束的loss function可以改写为:
我们从 L1先验拉普拉斯分布 L2先验高斯分布图可以看到:
L1更倾向将参数拉到0的附近,而L2常常会产生很多接近0的解,因此L1正则项的使用非常普遍,然而L1约束存在的一个问题:他在0附近不可导:
我们最常用OWLQN(Orthant-Wise Limited-memory Quasi-Newton)的方法进行求解,OWLQN核心是在0附近引入次梯度的概念:
次梯度:
lorthant to explore:
OWLQN的思想很简单实用:通过判断0点附近函数的导数,来判断函数的export方向,从而判断L1的梯度是应该按照正值来计算还是负值来计算。
LR模型的实现:
在已经知道LR的预估公式、损失函数,求解方式(LBFGS+OWLQN)的情况下,我们可以通过mpi实现一个并行的LR算法。一般可以通过如下的形式来进行实现:
我们将机器分为master和slave,其中master负责更新更新梯度、计算权重,各个master负责保存数据,累积计算梯度与loss。
除了传统的batch训练模型方法,我们也可以通过online的方式进行模型训练,online模型的理论相对稍复杂,但是实现简单。简单来收,online learning基于最小的regret bound来迭代进行模型更新。业界最常用的是google的FTRL方法:
这里简单说明一下公式中三项约束的物理意义:
第一个确保本次迭代方法尽量与前t次梯度累加方向相反。
第二项确保本次迭代不会大幅度偏移前t次的权重值。
第三项主要增加L1的约束。
相对batch online的模型更新时间快,模型计算简单。对新数据的相应更加及时,但是batch model可以达到更好的收敛。那种训练方法更试用,取决于具体的数据和应用场景。
概括而言,LR模型的特点如下:
优点
模型训练简单,训练时间较短。
在线预估快速
内存占用少
缺点:
人工构建大量的模型特征
线性模型
LR模型是业界最为主流的模型,也是这里重点的介绍模型,业界中也常常使用树模型或者图模型来进行建模。我们这里不进行深入探讨。大家有兴趣可以参考后面的文献。
下一篇,我将写一些具体的建模遇到的问题和tricks。
参考文献:
[1] The Google File System; http://labs.google.com/papers/gfs-sosp2003.pdf
[2] MapReduce: Simplifed Data Processing on Large Clusters; http://labs.google.com/papers/mapreduce-osdi04.pdf
[3] Bigtable: A Distributed Storage System for Structured Data;http://labs.google.com/papers/bigtable-osdi06.pdf
[4] http://storm.apache.org/
[5] Maximum Likelihood Estimation of Logistic Regression Models: Theory and Implementation. Scott A. Czepiel
[6] Numerical Optimization. Jorge Nocedal, Stephen J.Wright etc.
[7] Scalable Training of L1-Regularized Log-Linear Models. Galen Andrew, Jianfeng Gao
系统架构
公欲善其事,并先利其器。
点击率预估可以说是大数据应用的典型案例。广告系统中有着大量日志,例如腾讯广点通有百亿的曝光。他们的点击、曝光就是天然的正、负样本数据。点击率预估涉及到大量日志信息的存储、处理与计算,而这些处理,业界主要借助那些工具来完成的呢?
从我过往的经验来看,业界主要借助一下四个解决方案:
hadoop
strom
mpi
spark
google是大数据处理的先驱,hadoop用于数据预处理的的三家马车:HDFS,mapreduce,hbase实际上是来之google的馈赠。
google | hadoop |
GFS | HDFS |
mapreduce | mapreduce |
bigtable | hbase |
1、磁盘的读/写慢: HDFS通过并行提高存储速度。
2、并行硬件故障率高: HDFS通过冗余备份来提高容错性。
3、大数据汇总处理: MapReduce提供的可靠的编程模型。
4、HBASE非结构化数据的支持
他们的生态系统图可以概括如下(图非原创):
其中,mapreduce为我们提供了一个简单的计算框架,它主要通过数据并行的方式来进行并行计算。mapreduce的计算框架可以概括如下:
1、map:通过数据切分,根据数据量的多少,启动多个map端读数据进行处理。,以<key,value>键值对的形式,进行输出。
2、shuffle: 根据map端输出的<key,value>值,对数据进行排序。排序后的数据传送到reduce端进行处理。
3、reduce:reduce端对有相同key值的数据进行归并处理,并将最终的数据写入到hdfs中。
mapreduce框架中对数据进行了冗余备份,整个zookepeer负责对整个集群进行资源分布,任务调度,错误节点的重启,具有良好的容错性。
mapreduce + hdfs默认是以行来为单位来进行为单位进行数据的写入。日志中曝光与点击发生的时间的间隔时间从1s到数十分钟不等,而在点击率预估中,我们需要将曝光与点击关联起来来判断这个样本是正样例还是负样例。显然,常用的以行mapreduce + hdfs框架并不适用。
Hbase则为我们的日志提供了高速日志写入工具。Hbase也是广点通的实时样本数据流的使用工具。它底层还是基于hdfs完成的数据写入,只不过它以列的方式来对数据进行实时写入,具体的架构,我们可以参见下图(下图非原创,但是一时找不到准确的来源):
hbase主要给我们带来的主要的功能有两点:
1、百万列的数据写入。
从以行为key进行写入转换到以列为key进行写入,一条记录的列数和数据量大小得到了巨大的扩充。(可以想像一下,一条百万列的记录,在以行为key的map-reduce框架中出来起来会有多么的困难。数据的读入,排序都将有着巨大的延迟,甚至不可用)
2、高并发,低延迟
统一时间新产生的日志,无论曝光还是点击行为,无论他们的均可以同时的进行归并写入。具有高并发,低延迟的特点。
hadoop可以对点击率预估进行最基本的支持。如果选择合适的训练方法(例如一天训练一个模型、模型采用分片的方式进行训练),那么我们完全可以基于hadoop来搭建一套点击率预估系统。基于hadoop来完成数据的搜集,预处理、以及模型训练功能。
当然,hadoop也存在着一定的不足,hadoop的特点可以概括如下:
Hadoop的优点:
1、支持大数据的处理,可扩展性强。
2、容错性高且快速有效
3、社区资源丰富:pig,hive,mahout
hadoop的不足:
1、不支持迭代计算
2、批处理数据,响应时间慢
当需要学习一个模型的时候,我们往往需要对批量的数据进行多次迭代,并更新模型权重来逐步进行收敛。受限于计算架构,hadoop的map-reduce框架对机器学习的算法都支持不足:
1、缺少对迭代计算的支持
2、各个map/reduer独立工作,缺少消息同步机制
MPI(Message Passing Interface, MPI)以及spark是一个成熟的技术解决方案。
MPI的特点:
1、搭建简单、功能强大
2、开发难度略高,没有容错机制。
MPI是一个功能非常强大的并行计算工具,它更多的是一个编写消息传递程序而开发的广范使用的标准,我们最常用的实现版本为:MPICH。
MPI基于消息传递机制,理论上可以实现各种复杂的计算框架。但是底层的功能的开发主要是需要工程师自己去完成。开发的工作量相对较“重”。而当我们想要简单、快速验证一个模型和想法的时候,他的尝试、开发成本相对较高。
为了提供提供一套开发上更为简单的并行计算工具,Berkeley开发的一个开源的集群计算系统:spark。他主要提供了基于内存的数据迭代查询与计算的工具。spark需要学习一种新的开发语言scala,不过它的学习成本与开发成本非常小。非常适合作为快速的算法验证工具。(我们可以先在spark上实现代码,验证效果,后面迁移到运行更为高效、快速的mpi集群中来).
概括而言,spark的特点如下:
1、开发简单,快速迭代方便
2、新语言的学习成本,hdfs系统的支持
在点击率预估中,数据越实时,越能反馈用户当前的意图。举一个简单的例子,用户刚刚搜索了“充电宝”,那么下一个query“锤子”和手机的相关性可能更高。如果cookie或者合作的电商企业记录了用户在商场中搜索了一系列的“女士项链”,那么在qzone中给一个男性用户推荐一个 鲜花,甚至”女士手表“也是符合情理的。
hadoop中的map-reduce或者hbase对实时的数据的快速记录与处理应该说是分钟级别的,业界进行主要借助与storm进行更为实时的数据处理,它是一个分布式的、可容错的实时计算系统。
如下图所示(图片非原创):
storm中信息流根据拓扑结构,将数据流分配到各个数据平台中进行处理。它可以根据各个节点的负载情况分配数据流的,确保每一条消息都会被实时处理。(公司也有很多业务或部门大量使用storm进行数据处理,大家也可以搜索他们的文章进行更深入的了解).
storm最重要的两个特点是:
伸缩性强:我们可以增加更多的自己来应对信息流的增长。
良好的健壮性和容错:storm有良好的健壮性和容错功能,确保我们的数据不丢失。
在hadoop(hdfs,map-reduce,hbase),storm以及spark,mpi工具的基础上,基本上,我们可以搭建一个满足实时性、以及大数据处理的点击率预估系统了。
基础数据:
点击率预估主要依赖四类数据:用户、广告、上下文、以及场景信息。如下图:
在特征的设计上,我们可以把特征分为原始特征与cross特征,特征的cross方式可以集合业务知识设计组合方式,并且通过特征选择方式来进行特征选择。
cross特征示例:
特征的类型可以划分为两类:
数值型:年龄,广告历史点击率: (归一化)
Nominal: 学历(初中、高中、大学),行业(IT,教育)
当曝光量充足的时候,对于数值型的特征,我们可以通过区间切分的方法,来离散化它。例如我们采用线性模型的时候,自变量x与因变量y之间可能不是一个线性的关系。直接采用线性模型拟合它的时候会造成较大的偏差。
LR模型:
有很多种点击率预估模型可以供选择。例如LR(logstic regression),GBDT(gradient boosting descion tree) ,DNN(deep neural network)。其中,点击率预估最常用的模型是logistic regression model。因为他:
1、预估时间线性,可以大大减少线上系统的耗时。
这对于线上的实时服务来说,至关重要。
2、支持特征压缩:
LR可以通过L1的约束,大大的压缩特征空间,减少加载的模型大小。
我们以常用的人口统计为例:
1、人群 i 的观察数量
,人群数N,总观察数量M,
2、时间(例如疾病)i的发生概率 :
3、事件i第k维的特征 :
LR模型的假设:
π_i是一个sigmoid函数,他将【-00,+00】的数值空间压缩到0,1之间,其中0的取值为0.5,是一个分类点,并且sigmoid函数在0附近是非常sensitive的。
LR模型的求解:
lr模型是通过最大似然函数来进行求解,其中在N个样本中,每个样本有n_i个观察变量,其中y_i个人被观察到是发生了疾病,那么整个分布的联合概率为:
求解LR模型的参数,只需要最大化上面的联合概率即刻。因为我们一般通过梯度下降法进行求解,而一个连乘的公式,显然是难以求解的。对数函数与原函数增/减趋势保持一致的良好特性,如下图:
我们利用这个特性,求解将最大似然函数的最大值的求解,转换为其对数的最大值的求解。
给定我们最优化目标之后,函数的优化就变为凸优化问题(凸包的证明我们忽略),凸优化问题可以简单的描述如下(有详细了解的同学,可以参考后文推荐的书籍):
convex optimization(unconstraint):
凸函数的特点为:
1、有最小值解
2、函数处处可导
3、函数二次导数正定
凸函数的解有多种,最简单的可以采用最速梯度法求解:
每次求解函数的梯度,向负梯度方向搜索固定步长,求得得在当前方向下,函数最小值作为作为下一次函数的起始点。
最速下降法的计算较为简单,对于下降的步长,可以采用启发式搜寻&固定步数。但是,同时他的下降速度相对较慢。为了获得更快的下降速度,可以采用newton法进行求解。
牛顿法:
可以将函数进行泰勒展开:
每次求解泰勒展开式的最小值:
求解脱成如下图:
牛顿法的下载速度较为快速,但是需要求解Hessian矩阵,它的求逆计算复杂,存储量高。因此,BFGS(避免求逆);LBFGS(避免保存hessian矩阵)则是他们的改进。其中LBFGS方法最为常用。这里不展开对他们的介绍,有兴趣可以参见文献:convex optimization。
梯度的求解:
无论LBFGS还是最速梯度法,我们都需要对似然函数进行求解一阶导,他们的求导流程如下:
一阶偏导:
过拟合&稀疏正则化
广告中的特征有成百万甚至过亿,如果把所有的特征都加载到模型中:
1、将会大幅度的加载的负担。
2、大量的特征的权重,置信度不高或者并不显著。
因此,我们常常通过L1 或者 L2范式来对模型进行正则化约束。最大似然的公式如下:
我们可以把L1,L2分别看作是参数的先验分布:
L1先验拉普拉斯分布:
L2先验高斯分布:
基于L1,L2约束的loss function可以改写为:
我们从 L1先验拉普拉斯分布 L2先验高斯分布图可以看到:
L1更倾向将参数拉到0的附近,而L2常常会产生很多接近0的解,因此L1正则项的使用非常普遍,然而L1约束存在的一个问题:他在0附近不可导:
我们最常用OWLQN(Orthant-Wise Limited-memory Quasi-Newton)的方法进行求解,OWLQN核心是在0附近引入次梯度的概念:
次梯度:
lorthant to explore:
OWLQN的思想很简单实用:通过判断0点附近函数的导数,来判断函数的export方向,从而判断L1的梯度是应该按照正值来计算还是负值来计算。
LR模型的实现:
在已经知道LR的预估公式、损失函数,求解方式(LBFGS+OWLQN)的情况下,我们可以通过mpi实现一个并行的LR算法。一般可以通过如下的形式来进行实现:
我们将机器分为master和slave,其中master负责更新更新梯度、计算权重,各个master负责保存数据,累积计算梯度与loss。
除了传统的batch训练模型方法,我们也可以通过online的方式进行模型训练,online模型的理论相对稍复杂,但是实现简单。简单来收,online learning基于最小的regret bound来迭代进行模型更新。业界最常用的是google的FTRL方法:
这里简单说明一下公式中三项约束的物理意义:
第一个确保本次迭代方法尽量与前t次梯度累加方向相反。
第二项确保本次迭代不会大幅度偏移前t次的权重值。
第三项主要增加L1的约束。
相对batch online的模型更新时间快,模型计算简单。对新数据的相应更加及时,但是batch model可以达到更好的收敛。那种训练方法更试用,取决于具体的数据和应用场景。
概括而言,LR模型的特点如下:
优点
模型训练简单,训练时间较短。
在线预估快速
内存占用少
缺点:
人工构建大量的模型特征
线性模型
LR模型是业界最为主流的模型,也是这里重点的介绍模型,业界中也常常使用树模型或者图模型来进行建模。我们这里不进行深入探讨。大家有兴趣可以参考后面的文献。
下一篇,我将写一些具体的建模遇到的问题和tricks。
参考文献:
[1] The Google File System; http://labs.google.com/papers/gfs-sosp2003.pdf
[2] MapReduce: Simplifed Data Processing on Large Clusters; http://labs.google.com/papers/mapreduce-osdi04.pdf
[3] Bigtable: A Distributed Storage System for Structured Data;http://labs.google.com/papers/bigtable-osdi06.pdf
[4] http://storm.apache.org/
[5] Maximum Likelihood Estimation of Logistic Regression Models: Theory and Implementation. Scott A. Czepiel
[6] Numerical Optimization. Jorge Nocedal, Stephen J.Wright etc.
[7] Scalable Training of L1-Regularized Log-Linear Models. Galen Andrew, Jianfeng Gao
相关文章推荐
- 软件测试的艺术
- Html5 audio标签样式的修改
- 1/28 if
- 21-修改表给mysql添加外键
- Java基础-了解HashSet
- 判断一个字符串是否为数值型字符串
- 如何实现QML中的pathview
- 接口和抽象类有什么区别
- Eclipse Ctrl+Space 无法工作的问题
- 【SDOI2014】数数
- HTML meta标签总结与属性的使用介绍
- IIS Express
- 解决yum升级的问题“There was a problem importing one of the Python modules”
- JSON 解析(2)
- JSON 格式(1)
- 可模拟手机,导入apk即可
- 获取checkbox 的选中状态的id、checkbox的一些操作
- Spring Data JPA 的配置文件 已经数据库的状态
- 网站设置实体类属性的一种方式
- Tomcat性能调优-让小猫飞奔