什么是Mahout?

” Apache Mahout™ project’s goal is to build a scalable machine learning library ”

我来拓展一下:
(1) Mahout 是Apache旗下的开源项目,集成了大量的机器学习算法。
(2) 大部分算法,可以运行在Hadoop上,具有很好的拓展性,使得大数据上的机器学习成为可能。

本篇主要探讨 Mahout 0.9 中的聚类(Clustering)工具的用法。

一、数据准备

Mahout聚类算法的输入为List<Vector>,即需要将每个待聚类的文档,表示为向量形式。

在本文中,我们选择经典的 Reuters21578 文本语料。尝试对新闻内容进行文本聚类。

1、下载数据

1
axel - n 20 http : //kdd.ics.uci.edu/databases/reuters21578/reuters21578.tar.gz

2、解压缩数据

1
tar - xzvf . / reuters21578 . tar . gz . / reuters - sgm

解压缩之后,reuters-sgm下,包含了若干*.sgm文件,每个文件中又包含了若干下属结构化文档:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

< REUTERS TOPICS = "NO" LEWISSPLIT = "TRAIN" CGISPLIT = "TRAINING-SET" OLDID = "5545" NEWID = "2" >
< DATE > 26 - FEB - 1987 15 : 02 : 20.00 < / DATE >
< TOPICS > < / TOPICS >
< PLACES > < D > usa < / D > < / PLACES >
< PEOPLE > < / PEOPLE >
< ORGS > < / ORGS >
< EXCHANGES > < / EXCHANGES >
< COMPANIES > < / COMPANIES >
< UNKNOWN >
F Y
f0708 reute
d f BC - STANDARD - OIL - & lt ; SRD > - TO    02 - 26 0082 < / UNKNOWN >
< TEXT >
< TITLE > STANDARD OIL & lt ; SRD > TO FORM FINANCIAL UNIT < / TITLE >
< DATELINE >      CLEVELAND , Feb 26 - < / DATELINE > < BODY > Standard Oil Co and BP North America
Inc said they plan to form a venture to manage the money market
borrowing and investment activities of both companies .
     BP North America is a subsidiary of British Petroleum Co
Plc & lt ; BP > , which also owns a 55 pct interest in Standard Oil .
     The venture will be called BP / Standard Financial Trading
and will be operated by Standard Oil under the oversight of a
joint management committee .
Reuter
< / BODY > < / TEXT >
< / REUTERS >

在下文中,我们主要使用<TITLE>和<BODY>中的文本。即标题+正文。

3、抽取

Mahout中内置了对上述Reuters预料的抽取程序,我们可以直接使用。

1
mahout org . apache . lucene . benchmark . utils . ExtractReuters . / reuters - sgm . / reuters - out

如上所述,抽取好的结果在./reuters-out文件夹下面,每篇<REUTERS>文档,变成了一个独立的文件。

一共有21578个txt,即数据集中含有21578篇文档:-)

说下命名规则吧,例如:文件名:./reuters-out/reut2-006.sgm-246.txt,表示来自于./reuters-sgm/reut2-006.sgm中的第246篇文档,下标从0开始。

4、转换成SequenceFile

对于传统的文本聚类算法而言,下一步应该是:将文本转化为词的向量空间表示。

然而,不要太着急哦。

由于Mahout运行在Hadoop上,HDFS是为大文件设计的。如果我们把上述21578个txt都拷贝上去,这样是非常不合适的

设想下:假设对1000万篇新闻进行聚类,难道要拷贝1000w个文件么?这会把name node搞挂的。

因此,Mahout采用SequenceFile作为其基本的数据交换格式。

内置的seqdirectory命令(这个命令设计的不合理,应该叫directoryseq才对),可以完成 文本目录->SequenceFile的转换过程。

1
mahout seqdirectory - i file : //$(pwd)/reuters-out/ -o file://$(pwd)/reuters-seq/ -c UTF-8 -chunk 64 -xm sequential

上述命令蕴含了2个大坑,在其他文档中均没有仔细说明:
(1) -xm sequential,表示在本地执行,而不是用MapReduce执行。如果是后者,我们势必要将这些小文件上传到HDFS上,那样的话,还要SequenceFile做甚……
(2) 然而seqdirectory在执行的时候,并不因为十本地模式,就在本地文件系统上寻找。而是根据-i -o的文件系统前缀来判断文件位置。也就是说,默认情况,依然十在HDFS上查找的……所以,这个file://的前缀是非常有必要的。

其他2个参数:

  • -c UTF8:编码。
  • -chunk 64:64MB一个Chunk,应该和HDFS的BLOCK保持一致或者倍数关系。

5、转换为向量表示

为了适应多种数据,聚类算法多使用向量空间作为输入数据。

由于我们先前已经得到了处理好的SequenceFile,从这一步开始,就可以在Hadoop上进行啦。

1
hadoop dfs - put reuters - seq / user / coder4

开始text->Vector的转换:

1
mahout seq2sparse - i / user / coder4 / reuters - seq - o / user / coder4 / reuters - sparse - ow -- weight tfidf -- maxDFPercent 85 -- namedVector

输入和输出不解释了。在Mahout中的向量类型可以称为sparse。

参数说明如下:

  • -ow( 或 –overwrite):即使输出目录存在,依然覆盖。
  • –weight(或 -wt) tfidf:权重公式,大家都懂的。其他可选的有tf (当LDA时建议使用)。
  • –maxDFPercent(或 -x) 85:过滤高频词,当DF大于85%时,将不在作为词特征输出到向量中。
  • –namedVector (或-nv):向量会输出附加信息。

其他可能有用的选项:

  • –analyzerName(或-a):指定其他分词器。
  • –minDF:最小DF阈值。
  • –minSupport:最小的支持度阈值,默认为2。
  • –maxNGramSize(或-ng):是否创建ngram,默认为1。建议一般设定到2就够了。
  • –minLLR(或 -ml):The minimum Log Likelihood Ratio。默认为1.0。当设定了-ng > 1后,建议设置为较大的值,只过滤有意义的N-Gram。
  • –logNormalize(或 -lnorm):是否对输出向量做Log变换。
  • –norm(或 -n):是否对输出向量做p-norm变换,默认不变换。

看一下产出:

1
2
3
4
5
6
7
8
9

hadoop dfs - ls / user / coder4 / reuters - sparse
Found 7 items
/ user / coder4 / reuters - sparse / df - count
/ user / coder4 / reuters - sparse / dictionary . file - 0
/ user / coder4 / reuters - sparse / frequency . file - 0
/ user / coder4 / reuters - sparse / tf - vectors
/ user / coder4 / reuters - sparse / tfidf - vectors
/ user / coder4 / reuters - sparse / tokenized - documents
/ user / coder4 / reuters - sparse / wordcount

说明各个文件的用途:

  • dictionary.file-0:词文本 -> 词id(int)的映射。词转化为id,这是常见做法。
  • frequency.file:词id -> 文档集词频(cf)。
  • wordcount(目录): 词文本 -> 文档集词频(cf),这个应该是各种过滤处理之前的信息。
  • df-count(目录): 词id -> 文档频率(df)。
  • tf-vectors、tfidf-vectors (均为目录):词向量,每篇文档一行,格式为{词id:特征值},其中特征值为tf或tfidf。有用采用了内置类型VectorWritable,需要用命令”mahout vectordump -i <path>”查看。
  • tokenized-documents:分词后的文档。

二、KMeans

1、运行K-Means

1
mahout kmeans - i / user / coder4 / reuters - sparse / tfidf - vectors - c / user / coder4 / reuters - kmeans - clusters - o / user / coder4 / reuters - kmeans - k 20 - dm org . apache . mahout . common . distance . CosineDistanceMeasure - x 200 - ow -- clustering

参数说明如下:

  • -i:输入为上面产出的tfidf向量。
  • -o:每一轮迭代的结果将输出在这里。
  • -k:几个簇。
  • -c:这是一个神奇的变量。若不设定k,则用这个目录里面的点,作为聚类中心点。否则,随机选择k个点,作为中心点。
  • -dm:距离公式,文本类型推荐用cosine距离。
  • -x :最大迭代次数。
  • –clustering:在mapreduce模式运行。
  • –convergenceDelta:迭代收敛阈值,默认0.5,对于Cosine来说略大。

输出1,初始随机选择的中心点:

1
2
3

hadoop dfs - ls / user / coder4 / reuters - kmeans - clusters
Found 1 items
/ user / coder4 / reuters - kmeans - clusters / part - randomSeed

输出2,聚类过程、结果:

1
2
3
4
5
6
7

hadoop dfs - ls / user / coder4 / reuters - kmeans
Found 5 items
/ user / coder4 / reuters - kmeans / _policy
/ user / coder4 / reuters - kmeans / clusteredPoints
/ user / coder4 / reuters - kmeans / clusters - 0
/ user / coder4 / reuters - kmeans / clusters - 1
/ user / coder4 / reuters - kmeans / clusters - 2 - final

其中,clusters-k(-final)为每次迭代后,簇的20个中心点的信息。

而clusterdPoints,存储了 簇id -> 文档id 的映射。

2、查看簇结果

首先,用clusterdump,来查看k(20)个簇的信息。

1
2
3
4
5

# Get to Local
hadoop dfs - get / user / coder4 / reuters - kmeans / . /
hadoop dfs - get / user / coder4 / reuters - sparse / . /
# View ..
mahout clusterdump - i / user / coder4 / reuters - kmeans / clusters - 2 - final - d . / reuters - sparse / dictionary . file - 0 - dt sequencefile - o . / reuters - kmeans - cluster - dump / - n 20

要说明的是,clusterdump似乎只能在本地执行……所以先把数据下载到本地吧。

参数说明:

  • -i :我们只看最终迭代生成的簇结果。
  • -d :使用 词 -> 词id 映射,使得我们输出结果中,可以直接显示每个簇,权重最高的词文本,而不是词id。
  • -dt:上面映射类型,由于我们是seqdictionary生成的,so。。
  • -o:最终产出目录
  • -n:每个簇,只输出20个权重最高的词。

看看dump结果吧:

一共有20行,表示20个簇。每行形如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

VL - 12722 { n = 1305 c = [ . . . . zorinsky' s : 0.011 , zurich : 0.006... ] , r = [ . . . . yuan : 1.055 , yugoslav : 1.027 , . . . ] }
         Top Terms :
                 he                                        = >    3.105303428364896
                 said                                      = >    2.8756448350190205
                 would                                    = >    2.6413800148214874
                 have                                      = >    2.1552908992401942
                 government                                = >    1.8426488105364687
                 which                                    = >    1.749669294978467
                 economic                                  = >    1.7431561736768233
                 has                                      = >    1.7429241635333532
                 prices                                    = >    1.7182022383386604
                 oil                                      = >    1.673632335845538
                 from                                      = >      1.64287882106971
                 u . s                                      = >    1.6223870217115028
                 had                                      = >    1.602064758607711
                 more                                      = >    1.5874425666999086
                 last                                      = >    1.561653600890061
                 we                                        = >    1.5274837373316974
                 been                                      = >    1.4653439554674872
                 year                                      = >    1.4279387724353894
                 could                                    = >    1.4152588548331426
                 minister                                  = >    1.4146991936183066

其中前面的12722是簇的ID,n=1305即簇中有这么多个文档。c向量是簇中心点向量,格式为 词文本:权重(点坐标),r是簇的半径向量,格式为 词文本:半径。

下面的Top Terms是簇中选取出来的特征词。

3、查看聚类结果

其实,聚类结果中,更重要的是,文档被聚到了哪个类。

遗憾的是,在很多资料中,都没有说明这一点。前文我们已经提到了,簇id -> 文档id的结果,保存在了clusteredPoints下面。这也是mahout内置类型存储的。我们可以用seqdumper命令查看。

1
mahout seqdumper - i / user / coder4 / reuters - kmeans / clusteredPoints /

其中,-d和-dt的原因同clusterdump。

如果不指定-o,默认输出到屏幕,输出结果为形如:

1
Key : 4255 : Value : wt : 1.0 distance : 0.7752480913348985    vec : / reut2 - 000.sgm - 0.txt = [ 14 : 4.670 , 35 : 7.545 , . . . 11278 : 6.394 , 11288 : 6.731 ]

其实,这个输出是一个SequenceFile,大家自己写程序也可以读出来的。

Key是ClusterID,上面clusterdump的时候,已经说了。

Value是文档的聚类结果:wt是文档属于簇的概率,对于kmeans总是1.0,/reut2-000.sgm-0.txt就是文档标志啦,前面seqdirectionary的-nv起作用了,再后面的就是这个点的各个词id和权重了。

三、Fuzzy-KMeans

KMeans是一种简单有效的聚类方法,但存在一些缺点。

例如:一个点只能属于一个簇,这种叫做硬聚类。而很多情况下,软聚类才是科学的。例如:《哈利波》属于小说,也属于电影。Fuzzy-Kmeans 通过引入“隶属度”的方式,实现了软聚类。

1、算法简介

详细的介绍转载自:http://home.deib.polimi.it/matteucc/Clustering/tutorial_html/cmeans.html

2、工具用法

执行Fuzzy-KMeans

1
mahout fkmeans - i / user / coder4 / reuters - sparse / tfidf - vectors - c / user / coder4 / reuters - fkmeans - clusters - o / user / coder4 / reuters - fkmeans - k 20 - dm org . apache . mahout . common . distance . CosineDistanceMeasure - m 1.05 - x 200 - ow -- clustering -- convergenceDelta 0.01

新增算法的柔软参数m,若m接近于1则接近于KMeans;随着m增加,会有越来越多的聚簇重叠(越多的点同时属于多个聚簇)。

3、查看隶属度

如上文所述,在Fuzzy-KMeans中,点以一定的 “概率” 隶属于聚簇。

我们可以用seqdumper查看隶属度:

1
mahout seqdumper - i / user / coder4 / reuters - fkmeans / clusteredPoints /

其中的 w: xxx.xxx表示了 隶属度,应当是 0~1之间的数。

四、Canopy

KMeans算法还有一个缺陷: k需要预先给定,在很多场景下,聚类形状都是预先无法知道的,k更无从谈起。因此,往往先用别的算法进行粗略聚类,同时确定初始值,然后再用KMeans算法。

1、算法简介

Canopy Clustering 算法提出于2000年。优点是计算速度快,缺点是结果准确性较低。

尽管如此,其结果依然可以大致描述 聚类中心的位置。因此,常用来与KMeans算法配合使用。

(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为空结束。

我再来简单概括一下:阈值T1 > T2。到簇中心点的距离 < T2的点,必须属于本聚簇(硬)。T2 < 到簇中心点距离 < T1的点,可以属于多个聚簇(软)。在后续计算可以被合并。

2、聚类用法

执行Canopy聚类

1
mahout canopy - i / user / coder4 / reuters - sparse / tfidf - vectors - o / user / coder4 / reuters - canopy - centroids - dm org . apache . mahout . common . distance . CosineDistanceMeasure - t1 140 - t2 80 - ow

如上所述,在距离的计算方面,我们选择了欧式距离。阈值T1=150, t2=75。

输出结果,也可以用ClusterDump查看。

1
mahout clusterdump - i / user / coder4 / reuters - canopy - centroids / clusters - 0 - final - d / user / coder4 / reuters - sparse / dictionary . file - 0 - dt sequencefile - n 20 | vim -

这是一个粗略、大致的结果。在实际应用中,经常被用来作为K-Means的初始聚簇中心,来代替随机选择的K个中心点。这一做法有2个优点:
(1) 无需决定K,因为我们的预设往往是不准的。
(2) 使用Canopy的聚类结果,是一个大致准确的中心点。而随机选择很可能陷入局部最优。

在执行k-means时,若我们不指定k,则会使用-c的路径作为初始聚簇中心点,并跳过随机选择的过程。

1
mahout kmeans - i / user / coder4 / reuters - sparse / tfidf - vectors - c / user / coder4 / reuters - canopy - centroids / clusters - 0 - final - o / user / coder4 / reuters - kmeans - dm org . apache . mahout . common . distance . CosineDistanceMeasure - x 200 - ow -- clustering

3、参数选择

最后,我们讨论以下Canopy的参数T1和T2。

  • T1 > T2,具体值是文档及距离计算公式而定。
  • 若T1过大,会使得许多点属于多个Canopy,造成各个簇的中心点距离比较近,使得簇之间的区分不明显。
  • 若T2过大,强标记数据点的数量会增加,从而减少簇个数。
  • 若T2过小,会增加簇的个数,以及计算时间。

网上有人给出了这个做法,仅供参考:

  1. 对数据进行采样。
  2. 计算所有文档之间的平均距离(使用要在Canopy中用的距离公式)。
  3. T1 = 平均距离 * 2;T2 = 平均距离。

上述做法有一定道理,但我认为,以下更加合理:

  1. 对数据进行采样。
  2. 选择一个T2,T1 = 2 * T1。
  3. 进行聚类,并评测聚类效果,可使用k-fold交叉验证。
  4. 迭代选择下一个T2。
  5. 直到找到最优的T1 T2。

五、Spectral

1、谱聚类算法简介

谱聚类算法,参考了文章《Mahout Spectral聚类》。

谱聚类算法是一种较为现代的图聚类算法。与K-Means等传统聚类相比,它具有以下特点:

  1. 可以对非欧式距离空间的点进行聚类。传统K-Means将点视为向量,并计算距离。而谱聚类算法要求直接给出两样本间相似度的矩阵。使得一些不便于在欧式空间计算的多特征聚类问题,有了更好的解法。(例如,性别,年龄2个特征,在欧式空间中就没有显著意义)。
  2. 上面的这一更宽泛的约束条件,使得谱聚类对样本空间的形状无限制,并能收敛于全局最优解(无需使用)。

一种典型的谱聚类算法的大致流程是:

  1. 构建样本集的相似度矩阵W。
  2. 对相似度矩阵W进行稀疏化,形成新的相似度矩阵A。
  3. 构建相似度矩阵A的拉普拉斯矩阵L。
  4. 计算拉普拉斯矩阵L的前k个特征值与特征向量,构建特征向量空间。
  5. 将前k个特征向量(列向量)组合成N*k的矩阵,每一行看成k维空间的一个向量,利用K-means或其它经典聚类算法对该矩阵进行聚类。

其中,转化为拉普拉斯矩阵实际是一个降维的过程。正是这一特点,使得谱聚类能够处理超大规模的数据。

2、Mahout中的谱聚类

上文已经提到:

  • 传统K-Means等聚类中,需要将每个样本转化为一个向量。
  • 谱聚类中,则需要直接给一个矩阵,其中存储了任意两个样本之间的相似度。

例如:

在实际应用中,相似矩阵(affinity matrix)是相当稀疏的。所以,Mahout采用了邻接矩阵的输入格式,即(i, j, affinity)表示第i个样本与第j个样本的相似度是affinity。

同时,还需要输入矩阵的维度。原因应该是很好理解的。

如上图中的数据,转化完毕后,就是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

0 , 0 , 0
0 , 1 , 0.6
0 , 2 , 0.9
0 , 3 , 0.1
0 , 4 , 0
0 , 5 , 0
1 , 0 , 0.6
1 , 1 , 0
1 , 2 , 0.8
1 , 3 , 0
1 , 4 , 0
1 , 5 , 0
2 , 0 , 0.9
2 , 1 , 0.8
2 , 2 , 0
2 , 3 , 0
2 , 4 , 0
2 , 5 , 0.2
3 , 0 , 0.1
3 , 1 , 0
3 , 2 , 0
3 , 3 , 0
3 , 4 , 0.7
3 , 5 , 0.9
4 , 0 , 0
4 , 1 , 0
4 , 2 , 0
4 , 3 , 0.7
4 , 4 , 0
4 , 5 , 0.8
5 , 0 , 0
5 , 1 , 0
5 , 2 , 0.2
5 , 3 , 0.9
5 , 4 , 0.8
5 , 5 , 0

Mahout中,将谱聚类与KMeans进行了整合,执行命令:

1
mahout spectralkmeans - i / user / coder4 / sc - data - o / user / coder4 / sc - spectral - d 6 - k 2 - x 100

参数说明:

  • -i :输入的相似度矩阵,邻接矩阵。
  • -k:目标聚成2个簇。
  • -o:聚簇中间结果。
  • -d:相似度矩阵维度为6,也即样本共6个。
  • -x:100,最多迭代100次。
  • -cd:收敛阈值,默认0.5

其他可选参数:

  • -ssvd:使用svd矩阵分解降维。
  • -q:svd相关。

输出的目录结构,与K-Means等相似:

1
2
3
4
5

/ user / coder4 / sc - spectral / clusters - 0 / part - eigenSeed
/ user / coder4 / sc - spectral / kmeans_out / _policy
/ user / coder4 / sc - spectral / kmeans_out / clusteredPoints
/ user / coder4 / sc - spectral / kmeans_out / clusters - 0
/ user / coder4 / sc - spectral / kmeans_out / clusters - 1 - final

说明一下:

  • sc-spectral/clusters-0:初始聚簇。
  • sc-spectral/kmeans_out/clusteredPoints:最终结果,样本->聚簇映射。
  • sc-spectral/kmeans_out/clusters-1-final:最终聚簇的信息。

先看一下聚簇映射:

1
2
3
4
5
6
7
8
9

mahout seqdumper - i / user / coder4 / sc - spectral / kmeans_out / clusteredPoints
# Output
Key : 1 : Value : wt : 1.0 distance : 0.48931489242582005    vec : 0 = [ 0.188 , - 0.982 ]
Key : 1 : Value : wt : 1.0 distance : 0.7493112387139778    vec : 1 = [ 0.915 , 0.404 ]
Key : 0 : Value : wt : 1.0 distance : 0.04922584424967602    vec : 2 = [ - 0.902 , 0.432 ]
Key : 1 : Value : wt : 1.0 distance : 0.2811018866117967    vec : 3 = [ 0.465 , - 0.885 ]
Key : 1 : Value : wt : 1.0 distance : 1.1021255831766634    vec : 4 = [ 0.748 , 0.664 ]
Key : 0 : Value : wt : 1.0 distance : 0.012306461062418617    vec : 5 = [ - 0.994 , 0.112 ]
Count : 6

如上所示,这个顺序,是按照输入样本顺序来的。Key 1表示属于第2个簇,0表示第1个簇。distance是点与簇的相似距离。

然后来看一下簇中心:

1
mahout clusterdump - i / user / coder4 / sc - spectral / kmeans_out / clusters - 1 - final

输出结果:

1
2
3
4
5
6
7
8
9
10

VL - 0 { n = 3 c = [ - 0.963 , 0.219 ] r = [ 0.043 , 0.151 ] }
         Weight : [ props - optional ] :    Point :
         1.0 : [ distance = 0.04922584424967602 ] : 2 = [ - 0.902 , 0.432 ]
         1.0 : [ distance = 0.012306461062418617 ] : 5 = [ - 0.994 , 0.112 ]
VL - 1 { n = 5 c = [ 0.501 , - 0.356 ] r = [ 0.293 , 0.732 ] }
         Weight : [ props - optional ] :    Point :
         1.0 : [ distance = 0.48931489242582005 ] : 0 = [ 0.188 , - 0.982 ]
         1.0 : [ distance = 0.7493112387139778 ] : 1 = [ 0.915 , 0.404 ]
         1.0 : [ distance = 0.2811018866117967 ] : 3 = [ 0.465 , - 0.885 ]
         1.0 : [ distance = 1.1021255831766634 ] : 4 = [ 0.748 , 0.664 ]

于 K-Means一样,VL-XX是簇名称,n代表簇中含有几个元素。c是簇中心,r是簇半径。

然而奇怪的是,我们可以发现,上面的n都是错的,而下面簇中点的打印是对的不知道是什么Bug…

六、LDA

LDA是一种主题模型,它是一种考虑了词贡献的,较为高级的“聚类”算法,主要功能为:

  1. 给定主题数k,输出文档属于每个主题的概率(越大表示越贴近该主题)。
  2. 输出每个主题中,权重最大的几个词。相当于传统聚类之后的Tag。

关于算法、原理方面,本文就不做过多的介绍了,感兴趣的可以查看相关论文。

考虑到LDA的特性,提取特征的时候,我们需要使用tf而非tfidf:

1
mahout seq2sparse - i / user / coder4 / reuters - seq - o / user / coder4 / reuters - sparse - ow -- weight tf -- maxDFPercent 50 -- namedVector

Mahout实现的LDA有个大坑:tf的vector,词必须是Ingeter类型,即要我们把word转换成wordid。

1
mahout rowid - i / user / coder4 / reuters - sparse / tf - vectors - o / user / coder4 / reuters - cvb - vectoers

生成的有2个子目录,我们只用下面这个matrix:

1
2
3
4

hadoop dfs - ls / user / coder4 / reuters - cvb - vectoers
Found 2 items
/ user / coder4 / reuters - cvb - vectoers / docIndex
/ user / coder4 / reuters - cvb - vectoers / matrix

LDA训练:

1
mahout cvb - i / user / coder4 / reuters - cvb - vectoers / matrix - dict / user / coder4 / reuters - sparse / dictionary . file - 0 - dt / user / coder4 / reuters - lda - documents - o / user / coder4 / reuters - lda - k 20 - x 100 - ow - nt 41807

上述参数,说明一下:

  • -k 主题数20
  • -dt:输出的?
  • -o:输出的?
  • -x:迭代100次,其实对于LDA,1000~2000次是比较合理的。
  • -nt:词的数量,即dictionary.file-0的大小。

PS:Mahout这个LDA,执行效率真心不高,也可能是我的数据太小,机器太少。

文档->主题的概率

Shell
1
mahout seqdumper - i / user / coder4 / reuters - lda - documents

输出共21578行,代表了文档集合中的所有文档。

  • Key是文档id,与文件的对应关系可以在/user/coder4/reuters-cvb-vectoers/docIndex中查看。
  • Value是文档属于Topic 0~19的概率。按照值Sort一下,就能知道文档属于哪个主题的概率最大。
1
Key : 0 : Value : { 0 : 6.598480107368694E - 4 , 1 : 0.0011146789596809571 , 2 : 0.031866546260962164 , 3 : 3.0247890790462996E - 4 , 4 : 0.03744780092635172 , 5 : 0.0013729445191034027 , 6 : 0.15611424913721567 , 7 : 0.0012755723292771565 , 8 : 5.7202115335459274E - 5 , 9 : 7.1215044519594E - 4 , 10 : 5.743926686503027E - 4 , 11 : 0.0031917247557773252 , 12 : 0.6581022112710254 , 13 : 0.00817715737882251 , 14 : 3.1885030061811875E - 4 , 15 : 0.011053824003897846 , 16 : 0.031248628641714408 , 17 : 0.03558264264919826 , 18 : 0.01996534695313223 , 19 : 8.617497653994247E - 4 }

主题->词的概率

Shell
1
mahout seqdumper - i / user / coder4 / reuters - lda
  • 一共有20行有效输出,Key 0~19,代表了20个主题。
  • 每个Value中有41806个词的权重。表示了词属于当前主题的权重。

本来有个LDAPrintTopics,可以直接打印Topic对应的词的,但是年久失修,已经不能用在新版的cvb的LDA上了。大家可以写程序对上免每个Topic中词的权重进行排序,从而获得每个主题的代表词

Mahout – Clustering (聚类篇)相关推荐

  1. Mahout0.9 – Clustering (聚类篇)

    Mahout – Clustering (聚类篇) Leave a reply 什么是Mahout? " Apache Mahout™ project's goal is to build ...

  2. 机器学习 聚类篇——DBSCAN的参数选择及其应用于离群值检测

    机器学习 聚类篇--DBSCAN的算法原理.参数选择及其应用于离群值检测 摘要 1. DBSCAN算法原理 1.1 基本概念定义 1.2 算法流程 2. 参数选择 2.1 领域半径:Eps的选取方法( ...

  3. 机器学习 聚类篇——python实现DBSCAN(基于密度的聚类方法)

    机器学习 聚类篇--python实现DBSCAN(基于密度的聚类方法) 摘要 python实现代码 计算实例 摘要 DBSCAN(Density-Based Spatial Clustering of ...

  4. Mahout kmeans聚类

    Mahout  K-means聚类 一.Kmeans 聚类原理 K-means算法是最为经典的基于划分的聚类方法,是十大经典数据挖掘算法之一.K-means算法的基本思想是:以空间中k个点为中心进行聚 ...

  5. Mahout K-means聚类

    在实际工作中,我们很少有完整的时间段能够仔细研透一门学问.因此针对一门新学问.一套新知识.一种新方法,我们追求的是,先把它用起来,让其有实际的产出,尔后如有必要再慢慢研究其内在机理,以逐渐达到熟练自如 ...

  6. 聚类篇——(五)层次聚类

    前面博文介绍了两种常用基于划分的聚类算法K-means聚类.K-Medoids聚类,还有有序样品聚类.本篇博文介绍基于层次的聚类算法,层次聚类主要有两种类型:合并的层次聚类和分裂的层次聚类.合并的层次 ...

  7. 聚类篇——(四)有序样品聚类

    本篇博文介绍另外一种聚类方法--有序样品聚类.有序样品聚类要求样品按一定的顺序排列,分类时是不能打乱次序的,即同一类样品必须是互相邻接的.比如要将新中国成立以来国民收入的情况划分为几个阶段,此阶段的划 ...

  8. Mahout(聚类算法)

    应用场景 Mahout 是一个基于 Hadoop 的机器学习和数据挖掘的分布式计算框架,封装实现了大量数据挖掘经典算法,为 Hadoop 开发人员提供了数据建模的标准,从而大大降低了大数据应用中并行挖 ...

  9. Mahout分步式程序开发 聚类Kmeans

    Hadoop家族系列文章,主要介绍Hadoop家族产品,常用的项目包括Hadoop, Hive, Pig, HBase, Sqoop, Mahout, Zookeeper, Avro, Ambari, ...

最新文章

  1. leetcode--最长回文子串--python
  2. AI工程师成长记 - 工作方法!
  3. a1278 win10声卡驱动_windows安装系列教程—驱动安装
  4. 【转】CSS3 Box-sizing
  5. win32下多线程同步方式之临界区,互斥量,事件对象,信号量
  6. boost安装_编译安装Mysql详细步骤
  7. 嵌套函数中的this指向的对象
  8. 前端学习(3132):react-hello-react之受控组件
  9. asp微信会员卡管理系统,超小的源码_带asp微信支付源码
  10. 利用jsonp、iframe和location.hash解决跨域问题
  11. mysql text 查询速度_数据库学习之让索引加快查询速度(四)
  12. 清华大学刘云浩教授——人工智能打开了潘多拉的盒子吗?
  13. 利用Drawable生成圆形图片
  14. 前端面试题总结(js、html、小程序、React、ES6、Vue、全栈)
  15. 次更新不适用您的计算机,Windows系统安装补丁时提示“此更新不适用于你的计算机”的解决方案!...
  16. bcc钱包地址生成linux,从Bcc到xdp原理分析
  17. 阿里云狂揽国际朋友圈,集体融入数字中国新时代
  18. 2021年江苏省淮安高考成绩查询,2021年江苏淮安高考时间:6月7日至9日
  19. 【大话设计模式-2】UML 类图的绘制(源码案例分析)
  20. NoSQL数据库资料

热门文章

  1. 微信域名防封解决方案
  2. 盘点六款适用于企业移动办公的通讯工具
  3. caffe验证集测试集准确率差别很大的可能原因
  4. 海思鸿蒙系统IPC摄像机,不仅首发鸿蒙系统,荣耀智慧屏还有升降摄像头!?
  5. OpenGL与红宝书第八版第一个程序配置
  6. 【工业相机】【深度2】相机靶面大小和测量精度的关系分析和计算:@opencv
  7. [机器翻译] 记一次多语言机器翻译模型的训练
  8. 毕业10年就能拿到百万年薪:00后大学生,为什么这么自信?
  9. 华三、华为网络模拟器
  10. 营销中的4P、4C、4S、4R、4V、4I