mahout 实战

来源:互联网 发布:三星手机数据迁移 编辑:程序博客网 时间:2024/06/05 05:37

Mahout实战(数据挖掘)

1、 Mahout安装测试

1.1 下载Mahout

http://mahout.apache.org/general/downloads.html

1.2 解压

tar -zxvf mahout-distribution-0.9.tar.gz

1.3 配置环境变量

1.3.1 配置Mahout环境变量

export MAHOUT_HOME=

export MAHOUT_CONF_DIR=

export PATH=MAHOUT_HOME/conf:MAHOUT_HOME/bin:$PATH

1.3.2 配置Mahout所需的Hadoop环境变量

export HADOOP_HOME=

export HADOOP_CONF_DIR=

export PATH=PATH:HADOOP_HOME/bin

1.4 验证Mahout是否安装成功

执行命令mahout。若列出一些算法,则成功。

2、Mahout算法库介绍

2.1 协同过滤算法

基于用户的协同过滤算法:Single Machine 和spark

基于项目的协同过滤算法:Single Machine ,MapReduce和spark

基于ALS的矩阵分解算法:Single Machine和MapReduce

基于隐式反馈ALS的矩阵分解算法:Single Machine和MapReduce

SVD++:Single Machine

Weighted Matrix Factorization:Single Machine

2.2 分类算法

Logistic Regression - trained via SGD:Single Machine

Naive Bayes / Complementary Naive Bayes:MapReduce和spark

Random Forest:MapReduce

Hidden Markov Models:Single Machine

Multilayer Perceptron:Single Machine

2.3 聚类算法

Canopy Clustering:deprecated

k-Means Clustering:Single Machine和MapReduce

Fuzzy k-Means:Single Machine和MapReduce

Streaming k-Means:Single Machine和MapReduce

Spectral Clustering:MapReduce

2.4 降维模型

Singular Value Decomposition:Single Machine ,MapReduce和spark

Stochastic SVD:Single Machine ,MapReduce和spark

PCA (via Stochastic SVD):Single Machine ,MapReduce和spark

QR Decomposition:Single Machine ,MapReduce和spark

2.5 主题模型

Latent Dirichlet Allocation:Single Machine和MapReduce

参考文献

http://mahout.apache.org/users/basics/algorithms.html

3、 解析聚类算法

3.1 概述

簇(Cluster):一个数据对象的集合,在同一个类中,对象之间具有相似性;不同类的对象之间是相异的。

聚类分析:把一个给定的数据对象集合分成不同的簇;所谓聚类就是按照事物的某些属性,把事物聚集成类, 使类间的相似性尽可能的小,类内相似性尽量大的过程。

聚类是一种 无监督分类法: 没有预先指定的类别.

聚类分析中 类的特征:聚类所说的类不是事先给定的,而是根据数据的相似性和距离来划分聚类的数目和结构都没有事先假定。

典型应用

  • 作为一个独立的分析工具,用于了解数据的分布
  • 作为其它算法的一个数据预处理步骤
  • 异常分析

3.2 聚类的常规应用

市场销售: 帮助市场人员发现客户中的不同群体,然后用这些知识来开展一个目标明确的市场计划

土地使用: 在一个陆地观察数据库中标识那些土地使用相似的地区

保险: 对购买了汽车保险的客户,标识那些有较高平均赔偿成本的客户

地震研究: 根据地质断层的特点把已观察到的地震中心分成不同的类

文本聚类:新闻聚类,网页聚类

图像处理:基于聚类的图像分割,可以提取图片中的重要类簇进行分析

3.3 聚类类型

数据聚类算法可以分为结构性或者分散性。结构性算法利用以前成功使用过的聚类器进行分类,而分散型算法则是一次确定所有分类。结构性算法可以从上至下或者从下至上双向进行计算。从下至上算法从每个对象作为单独分类开始,不断融合其中相近的对象。而从上至下算法则是把所有对象作为一个整体分类,然后逐渐分小。

3.4 聚类测量

  在结构性聚类中,关键性的一步就是要选择测量的距离。一个简单的测量就是使用曼哈顿距离,它相当于每个变量的绝对差值之和。

  一个更为常见的测量是欧式空间距离,他的算法是找到一个空间,来计算每个空间中点到原点的距离,然后对所有距离进行换算。

常用的几个距离计算方法

  • 欧式距离(2-norm距离)
  • 曼哈顿距离(Manhattan distance, 1-norm距离)
  • infinity norm
  • 马氏距离
  • 余弦相似性
  • 汉明距离

3.5 结构性聚类

  层次聚类算法,要么是自底向上聚集型的,即从叶子节点开始,最终汇聚到根节点;要么是自顶向下分裂型的,即从根节点开始,递归的向下分裂。任意非负值的函数都可以用于衡量一对观测值之间的相似度。决定一个类别是否分裂或者合并的是一个连动的标准,它是两两观测值之间距离的函数。在一个指定高度上切割此树,可以得到一个相应精度的分类。

3.6 分散性聚类

K-均值法及衍生算法

K-均值算法表示以空间中k个点为中心进行聚类,对最靠近他们的对象归类。
算法归纳为:

  1. 选择聚类的个数k
  2. 任意产生k个聚类,然后确定聚类中心,或者直接生成k个中心
  3. 对每个点确定其聚类中心点
  4. 再计算其聚类新中心,转到2

重复以上步骤直到满足收敛要求。(通常就是确定的中心点不再改变)

该算法的最大优势在于简洁和快速。劣势在于对于一些结果并不能够满足需要,因为结果往往受随机点的影响很大。

参考文献

http://zh.wikipedia.org/zh-cn/%E8%81%9A%E7%B1%BB%E5%88%86%E6%9E%90

4、 解析分类算法

4.1 分类概述

  分类的目的是学会一个分类函数(分类模型、分类器),该模型能把数据库中的数据影射到给定类别中的一个。

  分类是一种基于训练样本数据(这些数据都已经被贴标签)区分另外的样本数据标签的过程,即另外的样本数据应该如何贴标签的问题。举一个简单的例子,现在有一批人的血型已经被确定,并且每个人都有M个指标来描述这个人,那么这批人的M个指标数据就是训练样本数据,根据这些训练样本数据,建立分类器(即运用分类算法得到一些规则),然后使用分类器对测试样本集中的未被贴标签的数据进行血型判断。分类算法和聚类算法的不同之处在于,分类是有指导的学习,而聚类是一种无指导的学习。有指导和无指导其实是指在训练的时候训练样本数据是否提前被贴上了标签。

4.2 分类应用

垃圾邮件(信)识别:通过历史垃圾信和正常信训练,识别信件中的垃圾信。

图像分类:如人脸识别,属于二分类,通过学习判断图片中有无人脸。OCR光学字符识别,判断验证码字符。识别图片中物品种类,等等。

信用卡用户等级分类:通过历史数据学习,判断用户的信用卡等级。

文本分类:通过对不同主题(社会、国际、体育、娱乐、科技等)文本的统计,预测新文本主题。

4.3 分类基本过程

训练集:数据库中为建立模型而被分析的数据元组形成训练集。训练集中的单个元组称为训练样本,每个训练样本有一个类别标记。一个具体样本的形式可为:( v1, v2, …, vn; c );其中vi表示属性值,c表示类别

测试集:用于评估分类模型的准确率

分类的基本过程

数据分类(data classfication)是一个三步过程。

  1. 通过分析数据库元组来构造模型(学习)
  2. 对模型进行评估(recall、precision、F1、ROC)
  3. 使用模型进行分类

4.4 常见分类算法

决策树系列:ID3,C4.5,bagging,random forest,GBDT

贝叶斯算法:朴素贝叶斯,贝叶斯网络

神经网络:BP神经网络,小波神经网络,卷积神经网络,深信神经网络

逻辑回归:常用于二分类,可以计算出分类指数,搜索排名中常用

AdaBoost:一般分类精度较高,使用十分广泛。人脸识别中分类算法常常使用。迭代次数过多容易过拟合

SVM(支持向量机):分类精度较高,使用十分广泛

参考文献

http://book.2cto.com/201408/45689.html

5、 协同过滤算法

5.1 什么是协同过滤

  协同过滤是利用集体智慧的一个典型方法。要理解什么是协同过滤 (Collaborative Filtering, 简称 CF),首先想一个简单的问题,如果你现在想看个电影,但你不知道具体看哪部,你会怎么做?大部分的人会问问周围的朋友,看看最近有什么好看的电影推荐,而我们一般更倾向于从口味比较类似的朋友那里得到推荐。这就是协同过滤的核心思想。换句话说,就是借鉴和你相关人群的观点来进行推荐,很好理解。

5.2 协同过滤的实现

要实现协同过滤的推荐算法,要进行以下三个步骤:

  1. 收集用户行为数据(正面影响推荐行为,不同行为加权处理)
  2. 计算物品或者用户相似度(根据收集数据,计算物品或者用户相似度)
  3. 进行推荐(根据用户对物品打分及物品或者用户相似度计算推荐指数,同时去除已经发生行为的物品)

5.2.1 收集数据

  这里的数据指的都是用户的历史行为数据,比如用户的购买历史,关注,收藏行为,或者发表了某些评论,给某个物品打了多少分等等,这些都可以用来作为数据供推荐算法使用,服务于推荐算法。需要特别指出的在于,不同的数据准确性不同,粒度也不同,在使用时需要考虑到噪音所带来的影响。

5.2.2 相似度计算

  这一步其实就是计算用户间以及物品间的相似度。以下是几种计算相似度的方法:

欧几里德距离



欧几里得相似度



皮尔逊相关系数



Cosine相似度



Tanimoto相似度


5.2.3 推荐计算

  在协同过滤中,有两种主流方法:基于用户的协同过滤,和基于物品的协同过滤。

  基于用户的 CF 的基本思想相当简单,基于用户对物品的偏好找到相邻邻居用户,然后将邻居用户喜欢的推荐给当前用户。计算上,就是将一个用户对所有物品的偏好作为一个向量来计算用户之间的相似度,找到 K 邻居后,根据邻居的相似度权重以及他们对物品的偏好,预测当前用户没有偏好的未涉及物品,计算得到一个排序的物品列表作为推荐。 下图给出了一个例子,对于用户 A,根据用户的历史偏好,这里只计算得到一个邻居 - 用户 C,然后将用户 C 喜欢的物品 D 推荐给用户 A。


  基于物品的 CF 的原理和基于用户的 CF 类似,只是在计算邻居时采用物品本身,而不是从用户的角度,即基于用户对物品的偏好找到相似的物品,然后根据用户的历史偏好,推荐相似的物品给他。从计算的角度看,就是将所有用户对某个物品的偏好作为一个向量来计算物品之间的相似度,得到物品的相似物品后,根据用户历史的偏好预测当前用户还没有表示偏好的物品,计算得到一个排序的物品列表作为推荐。下图给出了一个例子,对于物品 A,根据所有用户的历史偏好,喜欢物品 A 的用户都喜欢物品 C,得出物品 A 和物品 C 比较相似,而用户 C 喜欢物品 A,那么可以推断出用户 C 可能也喜欢物品 C。


5.2.4 计算复杂度

  Item CF 和 User CF 是基于协同过滤推荐的两个最基本的算法,User CF 是很早以前就提出来了,Item CF 是从 Amazon 的论文和专利发表之后(2001 年左右)开始流行,大家都觉得 Item CF 从性能和复杂度上比 User CF 更优,其中的一个主要原因就是对于一个在线网站,用户的数量往往大大超过物品的数量,同时物品的数据相对稳定,因此计算物品的相似度不但计算量较小,同时也不必频繁更新。但我们往往忽略了这种情况只适应于提供商品的电子商务网站,对于新闻,博客或者微内容的推荐系统,情况往往是相反的,物品的数量是海量的,同时也是更新频繁的,所以单从复杂度的角度,这两个算法在不同的系统中各有优势,推荐引擎的设计者需要根据自己应用的特点选择更加合适的算法。

5.2.5 适用场景

  在非社交网络的网站中,内容内在的联系是很重要的推荐原则,它比基于相似用户的推荐原则更加有效。比如在购书网站上,当你看一本书的时候,推荐引擎会给你推荐相关的书籍,这个推荐的重要性远远超过了网站首页对该用户的综合推荐。可以看到,在这种情况下,Item CF 的推荐成为了引导用户浏览的重要手段。同时 Item CF 便于为推荐做出解释,在一个非社交网络的网站中,给某个用户推荐一本书,同时给出的解释是某某和你有相似兴趣的人也看了这本书,这很难让用户信服,因为用户可能根本不认识那个人;但如果解释说是因为这本书和你以前看的某本书相似,用户可能就觉得合理而采纳了此推荐。

  相反的,在现今很流行的社交网络站点中,User CF 是一个更不错的选择,User CF 加上社会网络信息,可以增加用户对推荐解释的信服程度。

5.2.6 推荐多样性和精度

  研究推荐引擎的学者们在相同的数据集合上分别用 User CF 和 Item CF 计算推荐结果,发现推荐列表中,只有 50% 是一样的,还有 50% 完全不同。但是这两个算法确有相似的精度,所以可以说,这两个算法是很互补的。

  关于推荐的多样性,有两种度量方法:

  第一种度量方法是从单个用户的角度度量,就是说给定一个用户,查看系统给出的推荐列表是否多样,也就是要比较推荐列表中的物品之间两两的相似度,不难想到,对这种度量方法,Item CF 的多样性显然不如 User CF 的好,因为 Item CF 的推荐就是和以前看的东西最相似的。

  第二种度量方法是考虑系统的多样性,也被称为覆盖率 (Coverage),它是指一个推荐系统是否能够提供给所有用户丰富的选择。在这种指标下,Item CF 的多样性要远远好于 User CF, 因为 User CF 总是倾向于推荐热门的,从另一个侧面看,也就是说,Item CF 的推荐有很好的新颖性,很擅长推荐长尾里的物品。所以,尽管大多数情况,Item CF 的精度略小于 User CF, 但如果考虑多样性,Item CF 却比 User CF 好很多。

  如果你对推荐的多样性还心存疑惑,那么下面我们再举个实例看看 User CF 和 Item CF 的多样性到底有什么差别。首先,假设每个用户兴趣爱好都是广泛的,喜欢好几个领域的东西,不过每个用户肯定也有一个主要的领域,对这个领域会比其他领域更加关心。给定一个用户,假设他喜欢 3 个领域 A,B,C,A 是他喜欢的主要领域,这个时候我们来看 User CF 和 Item CF 倾向于做出什么推荐:如果用 User CF, 它会将 A,B,C 三个领域中比较热门的东西推荐给用户;而如果用 ItemCF,它会基本上只推荐 A 领域的东西给用户。所以我们看到因为 User CF 只推荐热门的,所以它在推荐长尾里项目方面的能力不足;而 Item CF 只推荐 A 领域给用户,这样他有限的推荐列表中就可能包含了一定数量的不热门的长尾物品,同时 Item CF 的推荐对这个用户而言,显然多样性不足。但是对整个系统而言,因为不同的用户的主要兴趣点不同,所以系统的覆盖率会比较好。

  从上面的分析,可以很清晰的看到,这两种推荐都有其合理性,但都不是最好的选择,因此他们的精度也会有损失。其实对这类系统的最好选择是,如果系统给这个用户推荐 30 个物品,既不是每个领域挑选 10 个最热门的给他,也不是推荐 30 个 A 领域的给他,而是比如推荐 15 个 A 领域的给他,剩下的 15 个从 B,C 中选择。所以结合 User CF 和 Item CF 是最优的选择,结合的基本原则就是当采用 Item CF 导致系统对个人推荐的多样性不足时,我们通过加入 User CF 增加个人推荐的多样性,从而提高精度,而当因为采用 User CF 而使系统的整体多样性不足时,我们可以通过加入 Item CF 增加整体的多样性,同样同样可以提高推荐的精度。

5.2.7 用户对推荐算法的适应度

  前面我们大部分都是从推荐引擎的角度考虑哪个算法更优,但其实我们更多的应该考虑作为推荐引擎的最终使用者——用户对推荐算法的适应度。

  对于 User CF,推荐的原则是假设用户会喜欢那些和他有相同喜好的用户喜欢的东西,但如果一个用户没有相同喜好的朋友,那 User CF 的算法的效果就会很差,所以一个用户对的 CF 算法的适应度是和他有多少共同喜好用户成正比的。

   CF 算法也有一个基本假设,就是用户会喜欢和他以前喜欢的东西相似的东西,那么我们可以计算一个用户喜欢的物品的自相似度。一个用户喜欢物品的自相似度大,就说明他喜欢的东西都是比较相似的,也就是说他比较符合 Item CF 方法的基本假设,那么他对 Item CF 的适应度自然比较好;反之,如果自相似度小,就说明这个用户的喜好习惯并不满足 Item CF 方法的基本假设,那么对于这种用户,用 Item CF 方法做出好的推荐的可能性非常低。

参考文献

http://www.ibm.com/developerworks/cn/web/1103_zhaoct_recommstudy2/index.html

6、 Canopy 算法

6.1 基本思想

Canopy聚类是一个非常简单、快速,并且精度让人惊讶的聚类方法。此聚类算法的大体思想为:

  1. 将数据集向量化得到一个list后放入内存,选择两个距离阈值:T1和T2,其中T1 > T2,对应下图,实线圈为T1,虚线圈为T2,T1和T2的值可以用交叉校验来确定;
  2. 从list中任取一点P,用低计算成本方法快速计算点P与所有Canopy之间的距离(如果当前不存在Canopy,则把点P作为一个Canopy),如果点P与某个Canopy距离在T1以内,则将点P加入到这个Canopy;
  3. 如果点P曾经与某个Canopy的距离在T2以内,则需要把点P从list中删除,这一步是认为点P此时与这个Canopy已经够近了,因此它不可以再做其它Canopy的中心了;
  4. 重复步骤2、3,直到list为空结束。

数据集划分完成后,效果图如下:

6.2 并行策略

  Canopy并行点是比较明显的,就是生成Canopy的过程可以并行,第一阶段,各个slave可以依据存储在本地的数据,各自在本地用上述算法生成若干Canopy,最后在master机器将这些Canopy用相同算法汇总后得到最终的Canopy集合,第二阶段聚类操作就利用最终的Canopy集合进行。

  用map-reduce描述就是:datanode在map阶段,利用上述算法在本地生成若干Canopy,之后通过reduce操作对map阶段的canopy再次计算得到最终的Canopy集合。

6.3 mahout Canopy 算法实战(hadoop)

实例数据下载:使用数据synthetic_control.data,数据包括600个数据点(行),每个数据点有60个属性。

数据下载: http://archive.ics.uci.edu/ml/databases/synthetic_control/

下面是Canopy聚类算法的执行命令参数

mahout canopy \

-i <input vectors directory> \

-o <output working directory> \

-dm <DistanceMeasure> \

-t1 <T1 threshold> \

-t2 <T2 threshold> \

-t3 <optional reducer T1 threshold> \

-t4 <optional reducer T2 threshold> \

-cf <optional cluster filter size (default: 0)> \

-ow <overwrite output directory if present> \

-cl <run input vector clustering after computing Canopies> \

-xm <execution method: sequential or mapreduce>

6.3.1 mahout 输入格式转化

  从上面“-i”参数可以看出,canopy需要输入的文本为向量文本,需要将数据格式转化为向量。在mahout中,向量被实现为三个不同的类,每个类都是针对不同场景优化的:DenseVector、RandomAccessSparseVector和SequentialAccessSparseVector。

  DenseVector可被视为一个double型数组,其大小为数据中的特征个数。因为不管数组的元素是不是0,数组中所有元素都被预先分配了空间。我们称之为密集的(dense)。

  RandomAccessSparseVector被实现为integer型和double型之间的一个HashMap,只有非零元素被分配空间。因此,这类向量被成为稀疏向量。(应用于文本聚类)

  SequentialAccessSparseVector实现为两个并列的数组,一个是integer型另一个是double型。其中只保留了非零元素。与面向随机访问的RandomAccessSparseVector不同,它是为顺序读取而优化的。

  具体选择那种实现依赖于算法。如果算法要对向量的值做许多随机插入和更新,就适合使用像DenseVector和RandomAccessSparseVector这样支持快速随机访问的实现。另一方面,而对于像k-means聚类这样反复计算向量大小的算法,SequentialAccessSparseVector实现的执行速度就会比RandomAccessSparseVector更快。

DenseVector数据转化步骤

  1. 将synthetic_control.data上传至hdfs文件夹/user/clusters/original
  2. 执行
    Mahout org.apache.mahout.clustering.conversion.InputDriver \

    -i /user/clusters/original \

    -o /user/clusters/output \

    -v org.apache.mahout.math.DenseVector
  3. 向量的结果会保存在/user/clusters/output中,查看方式为:mahout vectordump -i /user/clusters/output -o vector.txt,将向量转化为本地vector.txt文件

6.3.2 自然语言文本文件转化为向量文件

测试数据使用搜狗语料库文本数据。

数据下载地址:http://www.sogou.com/labs/dl/c.html

文本向量转化步骤:

  1. 解压搜狗语料库文件SogouC.reduced.20061127.zip
  2. 将搜狗语料库中的文本文件进行分词,可以在本地将文本文件进行分词完成后上传至HDFS,也可以先将原始文本文件上传至HDFS再进行分词处理。前者处理方式可以使用python jieba分词、java ansj分词、NLPIR分词,后者可以使用spark+ansj分词或者hadoop+NLPIR/ansj分词,处理后HDFS文件位置为/user/SouGouWordSegmention
  3. 转换操作

    mahout seqdirectory -i /user/SouGouWordSegmention \

    -o /user/ChineseSeq -ow -xm mapreduce

    此步骤将文本文件转为序列化文件

    seqdirectory将文件进行序列化。Seqdirectory参数含义为:-i为输入文件目录,-o为输出目录,-ow为如果目录存在则覆盖,-xm为执行方式。
  4. 将序列化文件转为向量文件

    mahout seq2sparse -i /user/ChineseSeq -o /user/ChineseVector
    -ow -seq -nv -wt TFIDF -a org.apache.lucene.analysis.core.WhitespaceAnalyzer

    使用seq2sparse将序列化后的文件进行向量化。

    seq2sparse参数含义为:

    -i 输入文件路径,-o输出文件路径,-ow 如果目录存在则覆盖,-seq表明为顺序读取向量,-nv 输出向量为命名向量,-wt使用权重方式,-a指定分词器类名。

向量化后目录结构为:

  • df-count
  • dictionary-file-0
  • frequency-file-0
  • tf-vectors
  • tfidf-vectors
  • tokenized-documents
  • wordcount

其中tfidf-vectors为我需要的向量文件。

若想查看上述二进制文件,可以使用如下方式:

查看df-count,dictionary.file-0,frequency.file-0,tokenized-documents和wordcount,使用如下命令:mahout seqdumper –i inputfile –o outputfile

查看tf-vectorstfidf-vectors文件,使用如下命令:

mahout vectordump -d /user/ChineseVector/dictionary.file-0 -dt sequencefile \

-i /user/ChineseVector/tfidf-vectors -o ./seq2sparse/tfidf-vectors.txt

mahout vectordump -d /user/ChineseVector/dictionary.file-0 -dt sequencefile \

-i /user/ChineseVector/tf-vectors -o ./seq2sparse/tf-vectors.txt

-d参数为指定词典,-dt指定词典类型(文本或者序列化文件),-o文件指的是本地文件

6.3.3 Canopy聚类操作

mahout canopy \

-i /user/clusters/output \

-o /user/canopy \

-dm org.apache.mahout.common.distance.EuclideanDistanceMeasure \

-t1 100 \

-t2 50 \

-t3 100 \

-t4 50 \

-ow \

-cl \

-xm mapreduce

参数含义参考上面6.3

此处mahout命令也可以使用hadoop命令实现,实现方式为:
Hadoop jar /path/mahout-core-job.jar org.apache.mahout.clustering.canopy.CanopyDriver \

-i /user/clusters/output \

-o /user/canopy \

-dm org.apache.mahout.common.distance.EuclideanDistanceMeasure \

-t1 100 \

-t2 50 \

-t3 100 \

-t4 50 \

-ow \

-cl \

-xm mapreduce

如果想查看聚类结果,使用如下命令:

mahout clusterdump -i /user/canopy/clusters-0-final -o canopycenter

mahout vectordump -i /user/canopy/clusteredPoints -o canopyvector

7、 K-Means 算法

7.1 K-Means算法简介

  k-means一种非常简单地基于距离的聚类算法,认为每个Cluster由相似的点组成而这种相似性由距离来衡量,不同Cluster间的点应该尽量不相似,每个Cluster都会有一个“重心”;另外它也是一种排他的算法,即任意点必然属于某一Cluster且只属于该Cluster。当然它的缺点也比较明显,例如:对于孤立点敏感、数值k的确定。

典型的算法如下,它是一种迭代的算法:

  1. 根据事先给定的k值建立初始划分,得到k个Cluster,比如,可以随机选择k个点作为k个Cluster的重心,又或者用Canopy Clustering得到的Cluster作为初始重心(当然这个时候k的值由Canopy Clustering得结果决定)
  2. 计算每个点到各个Cluster重心的距离,将它加入到最近的那个Cluster
  3. 重新计算每个Cluster的重心
  4. 重复过程2~3,直到各个Cluster重心在某个精度范围内不变化或者达到最大迭代次数

  别看算法简单,很多复杂算法的实际效果或许都不如它,而且它的局部性较好,容易并行化,对大规模数据集很有意义;算法时间复杂度是:O(nkt),其中:n 是聚类点个数,k 是Cluster个数,t 是迭代次数。

7.2 并行化策略

K-Means较好地局部性使它能很好的被并行化。第一阶段,生成Cluster的过程可以并行化,各个Slaves读取存在本地的数据集,用上述算法生成Cluster集合,最后用若干Cluster集合生成第一次迭代的全局Cluster集合,然后重复这个过程直到满足结束条件,第二阶段,用之前得到的Cluster进行聚类操作。

map-reduce描述:

  1. 根据设定的k值随机生成k个聚类中心,在map阶段读出位于本地的数据集,输出每个点及其对应的Cluster
  2. reduce阶段将map阶段输出的每个集群,重新计算集群中心点,并更新
  3. 如果执行条件迭代次数k和收敛误差值不满足条件,循环上面的map和reduce阶段

7.3 mahout的K-Means算法实战

7.3.1 数字数据进行K-Means聚类

数据向量化:参考6.3.1 DenseVector转化,测试数据同样使用6.3中的yntheticcontrol.data

K-Means聚类操作:

mahout kmeans \

-i /user/clusters/output \

-o /user/kmeans \

-dm org.apache.mahout.common.distance.EuclideanDistanceMeasure \

-c /user/canopy/clusters-0-final \

-x 10 \

-ow \

-cl \

-xm mapreduce

参数含义-i 输入文件,-o 输出目录,-dm 距离计算方式,-c 初始聚类中心,-x 最大执行次数,-ow 如果结果存在则重写,-cl 产生聚类向量,-xm 执行方式。

上面实例是将canopy的结果做为了k-means的聚类初始中心。如果没有聚类中心,设置-k参数,同时-c指定存储初始聚类中心的文件夹。

查看k-means聚类结果方式:

mahout clusterdump -i /user/kmeans/clusters-4-final -o kmeanscenter

mahout vectordump -i /user/kmeans/clusteredPoints -o kmeansvector

上面两个向量分别查看最终聚类文件和聚类点文件(每个点的向量化表示)。

7.3.2 自然语言文件进行K-Means文本聚类

文本数据向量化:参考6.3.2的转化方式,测试数据采用6.3.2上传至hdfs的SouGouWordSegmention(搜狗语料库)文件,此文件已经进行了分词处理。

k-means文本聚类操作:

mahout kmeans \

-i /user/ChineseVector/tf-vectors \

-o /user/kmeans-chinese \

-c /user/centroids \

-k 9 \

-dm org.apache.mahout.common.distance.CosineDistanceMeasure \

-x 10 \

-cl \

-ow \

-xm mapreduce

参数含义-i 指定向量化后文本向量文件,-c 存储初始聚类中心的空文件夹,dm 使用了cosine距离方式,其他参数与上面一致。

查看初始centriod命令:

mahout seqdumper -i /user/centroids -o randomSeed.txt

查看k-means文本聚类结果:

mahout clusterdump -i /user/kmeans-chinese/clusters-2-final -o kmeanscenter -d /user/ChineseVector/dictionary.file-0 -dt sequencefile

mahout vectordump -i /user/kmeans-chinese/clusteredPoints -o kmeansvector -d /user/ChineseVector/dictionary.file-0 -dt sequencefile

上面第一条命令查看聚类最终结果,第二条命令查看参与聚类的文本向量化表示。参数含义-i 输入文件目录,-o 输出文本文件本地目录,-d 词典对照文件,-dt 词典文件类型。

8、 分类算法

8.1 贝叶斯算法简介

  贝叶斯分类算法是统计学的一种分类方法,它是一类利用概率统计知识进行分类的算法。在许多场合,朴素贝叶斯(Naive Bayes,NB)分类算法可以与决策树和神经网络分类算法相媲美,该算法能运用到大型数据库中,而且方法简单、分类准确率高、速度快。

  由于贝叶斯定理假设一个属性值对给定类的影响独立于其它属性的值,而此假设在实际情况中经常是不成立的,因此其分类准确率可能会下降。

  学过概率理论的人都知道条件概率的公式:P(AB) = P(A)P(B|A) = P(B)P(A|B);即事件A和事件B同时发生的概率等于 在发生A的条件下B发生的概率乘以A的概率。由条件概率公式推导出 贝叶斯公式:P(B|A) = P(A|B)P(B)/P(A);即, 已知P(A|B),P(A) 和 P(B) 可以计算出P(B|A)。

8.2 贝叶斯算法原理介绍

理论上,概率模型分类器是一个条件概率模型,假定实例向量为有n个特征,X的分类概率模型为



独立的类型变量C有若干类别,条件依赖于若干特征变量,如果特征数量n 较大或者每个特征能取大量值时,基于概率模型列出概率表变得不现实。所以我们修改这个模型使之变得可行。使用贝叶斯定理,条件概率可以表示为



使用贝叶斯概率术语,上面的等式可以表示为



实际中,我们只关心分式中的分子部分,因为分母不依赖于C,而且特征Fi的值是给定的,于是分母可以认为是一个常数。这样分子就等价于联合概率模型



使用链式法则,可将该式写成条件概率的形式,如下所示:



现在“朴素” 的条件独立性假设开始发挥作用:对于给定的类别C,当j!=i,特征Fi和Fj条件独立,这代表着







前提为 i!=j,k,l

所以联合分布模型可以表达为:



这意味着变量C的条件概率分布可以表示为:



上式中因子是一个依赖于特征值的缩放因子,当特征值知道时,Z为常量。

参考文献:http://en.wikipedia.org/wiki/Naive_Bayes_classifier

贝叶斯分类器最常用的场景 为:文本分类,垃圾邮件过滤等。

  朴素贝叶斯分类器是一种有监督学习,常见有两种模型,多项式模型(multinomial model)即为词频型和伯努利模型(Bernoulli model)即文档型。二者的计算粒度不一样,多项式模型以单词为粒度,伯努利模型以文件为粒度,因此二者的先验概率和类条件概率的计算方法都不同。计算后验概率时,对于一个文档d,多项式模型中,只有在d中出现过的单词,才会参与后验概率计算,伯努利模型中,没有在d中出现,但是在全局单词表中出现的单词,也会参与计算,不过是作为“反方”参与的。这里暂不考虑特征抽取、为避免消除测试文档时类条件概率中有为0现象而做的取对数等问题。

8.2.1 多项式模型

基本原理

  在多项式模型中, 设某文档d=(t1,t2,…,tk),tk是该文档中出现过的单词,允许重复,则

先验概率 P(c)= 类c下单词总数/整个训练样本的单词总数

类条件概率 P(tk|c)=(类c下单词tk在各个文档中出现过的次数之和+1)/(类c下单词总数+|V|)

V 是训练样本的单词表(即抽取单词,单词出现多次,只算一个),|V| 则表示训练样本包含多少种单词。 P(tk|c) 可以看作是单词tk 在证明d属于类c 上提供了多大的证据,而 P(c)则可以认为是类别c在整体上占多大比例(有多大可能性)。

举例

给定一组分好类的文本训练数据,如下

dociddoc类别
in c=China?1Chinese Beijing Chineseyes2Chinese Chinese Shanghaiyes3Chinese Macaoyes4Tokyo Japan Chineseno

给定一个新样本Chinese Chinese Chinese Tokyo Japan,对其进行分类。该文本用属性向量表示为d=(Chinese, Chinese, Chinese, Tokyo, Japan),类别集合为Y={yes, no}。

类yes下总共有8个单词,类no下总共有3个单词,训练样本单词总数为11,因此P(yes)=8/11, P(no)=3/11。类条件概率计算如下:

P(Chinese | yes)=(5+1)/(8+6)=6/14=3/7

P(Japan | yes)=P(Tokyo | yes)= (0+1)/(8+6)=1/14

P(Chinese|no)=(1+1)/(3+6)=2/9

P(Japan|no)=P(Tokyo| no) =(1+1)/(3+6)=2/9

分母中的8,是指yes类别下text的长度,也即训练样本的单词总数,6是指训练样本有Chinese,Beijing,Shanghai, Macao, Tokyo, Japan 共6个单词,3是指no类下共有3个单词。

有了以上类条件概率,开始计算后验概率:

P(yes | d)=(3/7)3×1/14×1/14×8/11=108/184877≈0.00058417

P(no | d)= (2/9)3×2/9×2/9×3/11=32/216513≈0.00014780

比较大小,即可知道这个文档属于类别china。

8.2.2 伯努利模型

基本原理

P(c)= 类c下文件总数/整个训练样本的文件总数

P(tk|c)=(类c下包含单词tk的文件数+1)/(类c下单词总数+2)

举例

使用前面例子中的数据,模型换成伯努利模型。

类yes下总共有3个文件,类no下有1个文件,训练样本文件总数为11,因此P(yes)=3/4, P(Chinese | yes)=(3+1)/(3+2)=4/5,条件概率如下:

P(Japan | yes)=P(Tokyo | yes)=(0+1)/(3+2)=1/5

P(Beijing | yes)= P(Macao|yes)= P(Shanghai |yes)=(1+1)/(3+2)=2/5

P(Chinese|no)=(1+1)/(1+2)=2/3

P(Japan|no)=P(Tokyo| no) =(1+1)/(1+2)=2/3

P(Beijing| no)= P(Macao| no)= P(Shanghai | no)=(0+1)/(1+2)=1/3

有了以上类条件概率,开始计算后验概率

P(yes|d)=P(yes)×P(Chinese|yes)×P(Japan|yes)×P(Tokyo|yes)×(1-P(Beijing|yes))×(1-P(Shanghai|yes))×(1-P(Macao|yes))=3/4×4/5×1/5×1/5×(1-2/5) ×(1-2/5)×(1-2/5)=81/15625≈0.005

P(no|d)= 1/4×2/3×2/3×2/3×(1-1/3)×(1-1/3)×(1-1/3)=16/729≈0.022

因此,这个文档不属于类别china

参考文献:http://m.oschina.net/blog/56724

8.3 贝叶斯算法hadoop实战

测试集选取:搜狗语料库

数据预处理:将搜狗语料库中的新闻文件进行分词并上传至hdfs的/user/SouGouWordSegmention文件下。

执行步骤

  1. 文本序列化

    mahout seqdirectory -i /user/SouGouWordSegmention \

    -o /user/ChineseSeq -ow -xm mapreduce

    查看序列化文件命令:

    mahout seqdumper -i /user/ChineseSeq -o chineseseq.txt
  2. 序列化文件转为向量

    mahout seq2sparse -i /user/ChineseSeq -o /user/ChineseVector \

    -ow -seq -nv -wt TFIDF -a org.apache.lucene.analysis.core.WhitespaceAnalyzer

    向量查看方式:

    mahout seqdumper -i /user/ChineseVector/wordcount -o wordcount.txt

    mahout seqdumper -i /user/ChineseVector/tokenized-documents \

    -o tokenized-documents.txt

    mahout vectordump -d /user/ChineseVector/dictionary.file-0 -dt sequencefile \

    -i /user/ChineseVector/tfidf-vectors -o ./seq2sparse/tfidf-vectors.txt
  3. 数据集随机分训练集和测试集

    mahout split -i /user/ChineseVector/tfidf-vectors \

    -tr /user/naivebayes/train \

    -te /user/naivebayes/test -rp 30 -ow -seq -xm mappreduce

    参数含义-tr 训练集,-te 测试集,-rp 分片比例,-seq 表示输入文件为序列化文件
  4. 朴素贝叶斯训练

    mahout trainnb -i /user/naivebayes/train -o /user/naivebayes/result \

    -el -li /user/naivebayes/labelindex -ow –c

    参数含义-el 表示从输入数据抽取类别,-li 类别标签索引存储位置,-c 使用补充贝叶斯方法。
  5. 朴素贝叶斯测试评估

    mahout testnb -i /user/naivebayes/test -m /user/naivebayes/result \

    -o /user/naivebayes/predict -l /user/naivebayes/labelindex \

    -ow –c

    参数含义-m 代表朴素贝叶斯模型,-l 类别索引文件,-c 使用补充贝叶斯方法

9、 Mahout item-based 协同过滤推荐实战

9.1 业务理解

理解项目目标,在本例中就是理解在这个项目中进行什么样的推荐,最终达到什么样的推荐结果,如何让用户对推荐满意。

9.2 数据理解

  理解项目需要什么样的数据,在本例中就是我们进行推荐需要何种行为数据。需要的数据能反映出一个用户对另一个用户的积极的评价或者消极的评价。同时,理解用户的不同行为产生的影响不同,例如,用户的浏览行为相比用户发信行为将会产生较弱的评价。

  本例中我们需要的数据为:用户的浏览行为,用户的发信行为,用户的关注行为。

9.3 数据准备

数据准备阶段将建模所需数据进行数据清洗和数据转化。在本例中我们会对用户浏览行为、收藏行为、购买行为数据进行处理。
步骤如下

  1. 提取用户浏览行为数据,去除违法用户或者不符合要求用户行为数据
  2. 提取用户收藏行为数据,去除违法用户或者不符合要求用户行为数据
  3. 提取用户购买行为数据,去除违法用户或者不符合要求用户行为数据
  4. 统计上面用户对相同用户产生行为次数
  5. 将上面不同行为数据指定不同权值(一般根据经验),将权值乘以产生行为次数,最终得出用户之间的评分,格式为(userid,beuserid,score)

9.4 建模

使用mahout item-based cf算法对上面数据计算,得出推荐结果。

具体推荐命令如下:

hadoop jar /opt/cloudera/parcels/CDH/lib/hadoop-yarn/lib/mahout-core-0.9-cdh5.1.2-job.jar \

org.apache.mahout.cf.taste.hadoop.item.RecommenderJob \

-Dmapred.reduce.tasks=500 \

–similarityClassname SIMILARITY_TANIMOTO_COEFFICIENT \

–input /user/hive/warehouse/input \

–output /user/hive/warehouse/output \

–tempDir /user/hive/warehouse/temp \

–outputPathForSimilarityMatrix /user/hive/warehouse/similarmatrix \

–maxSimilaritiesPerItem 60 \

–maxPrefsPerUser 100 \

–numRecommendations 50 \

–startPhase 0

参数含义

-Dmapred.reduce.tasks=500设置reduce个数

–similarityClassname 相似度计算函数选取

–input 输入数据HDFS位置

–output 推荐结果存放位置

–tempDir 中间计算结果存放位置

–outputPathForSimilarityMatrix 相似度矩阵HDFS存放路径,此数据为item相似度

–maxSimilaritiesPerItem 指定每个item的做多相似item个数

–maxPrefsPerUser 指定每个用户最多评价item个数

–numRecommendations 指定为每个用户推荐物品数

–startPhase 指定程序开始阶段

9.5 推荐数据过滤

由于推荐的用户没有进行严格的限制,仅仅是根据用户行为推荐用户可能喜欢的用户,所以会存在推荐用户不符合用户择偶标准的情况,需要对推荐数据进行过滤,筛选出符合条件的推荐。

9.6 评估

  总体来讲,评估推荐系统的实验方法有三种,分别是离线评测、在线评测和用户调研。

  离线评测通过把数据集分成训练集和测试集,在训练集上学习和调整模型参数,在测试集上进行测试,计算精确度、运行效率等指标,达到评测的目的。这种方法实施简单方便,只需要收集数据,不需要与用户的交互。但能说明的问题较少,比如不能评估出推荐系统对用户行为的影响。这种方法一般用以衡量推荐算法在预测环节中的能力,淘汰掉预测不准确的算法。

  推荐系统的实际效果依赖于多种因素,如用户意图、用户背景知识、对系统的熟悉度、信任度、用户界面等,这些因素在离线评中不易重现,需要线上评测来完成,一般线上评测可以使用 AB test 的方法。

  线上评测和用户调研的方法在人机交互领域对推荐系统的研究中比较常用。

9.7 部署

  由于协同过滤算法是一种离线计算方法,不能实时计算,所以协同过滤的结果一般都是计算好的。在本例中,我们会将用户相似度矩阵数据和推荐结果数据(过滤后的)存入HBase或者Redis。

  对于上面数据使用做一个简要说明。协同过滤推荐的结果考虑比较综合,可以将这个结果推荐放到主页推荐。对于相似度数据,可以在用户浏览某一用户(物品)时,为其推荐与被浏览用户(物品)相似的用户(物品)。

9.8 注意事项

以上的协同过滤推荐系统是最基本版本,在使用过程中会存在较大问题。
简单列举几个:

  • 热点物品问题(item-based)。

    热门物品一般比冷门物品容易有较高的物品相似度,致使推荐结果覆盖率较低。一般冷门相似物品更能代表一致的兴趣。应当适当降低热门物品相似度数值。
  • 热点用户问题(user-based)

    行为较多的用户容易与其它用户有较高的用户相似度,致使为用户推荐的数据多少来自于行为较多用户接触过的物品,降低了推荐的覆盖率。
  • 时间上下文。

    在电商网站中时间上下文,可以体现季节,当前流行度等因素。在交友网站中时间上下文也可以代表用户的活跃度。
  • 推荐多样性问题。

    基于物品的协同过滤,相似度进行归一化有助于提高推荐的多样性。因为不同物品内部的相似度不平衡,有些物品内部的相似度较高,造成推荐结果倾向于该类物品。对于两个不同的类,什么样的类其类内物品之间的相似度高,什么样的类其类内物品相似度低呢?一般来说,热门的类其类内物品相似度一般比较大。如果不进行归一化,就会推荐比较热门的类里面的物品,而这些物品也是比较热门的。因此,推荐的覆盖率就比较低。相反,如果进行相似度的归一化,则可以提高推荐系统的覆盖率。
0 0
原创粉丝点击