mahout作为开源软件包,集成了很多机器学习和数据挖掘算法,详细可见 mahout官网 。
关于LDA,这里就不说了,详见大神的 LDA数学八卦 。这里只是想吐嘈mahout官网lda的使用文档:根本就没什么文档嘛!
在mahout-0.9及以前版本,只支持hadoop1.0 . 支持hadoop2.0的mahout只有1.0-SNAPSHOT , 不过是可以用的。现在就记录一下本人使用时走过的坑(注:幸好有同事之前走过0.9的坑,所以我才能迅速的集成。本人也未读源码,只看过CVB0Driver)。
第一步 : github 去下最新的源码包,解压后直接编译即可,现在的1.0版本默认支持hadoop2.2(在hadoop 2.4上也可以用) .
第二步 :准备lda需要的输入文档集合。因为lda的输入文件需要为sequence file..所以以下的几步主要是将源文档集合转化为lda能够识别的sequencefile 输入。
1)、每篇文档为一个单独的本地文件 , 命名为当前文档的标识,一般为Id,如果文档量较大可以分子目录存放。
2)、使用 ./mahout seqdirectory 将1步的文档转成seq-file(因为1步有多个文件,循环执行).
$MAHOUT seqdirectory -i file://${LOCAL_DIR}/input/chunk-${i} -o file://${LOCAL_SEQ_DIR}/chunk-${i} -chunk 64 -c UTF-8 -ow -xm sequential hadoop fs -put ${LOCAL_SEQ_DIR}/chunk-${i} ${HDFS_SEQ_DIR}/
然后将输出的文件放在hdfs上
3)、使用$MAHOUT seq2sparse 进行各种转化(具体可见官方参数解释)
$MAHOUT seq2sparse -i ${HDFS_SEQ_DIR}/*/ -o ${HDFS_SPARSE_DIR} --weight tfidf --chunkSize 64 -seq -nr 10 --namedVector --analyzerName org.apache.lucene.analysis.core.WhitespaceAnalyzer --maxDFPercent 20
注意analyzerName , 如果你之前的文档没有切词,那么这里可以指定切词算法。如果已经切好词,这需要指定词与词之前的分隔符。我这里是已经切好词的文档,词之间以空格分隔。如果不指定,mahout会对你再节一次。
--weight就是词的权重,可以选用tf或tfidf..
4)、对文档进行matrix处理。这一步我在网上没有找到。。不知道我的同事在哪搞到的。
$MAHOUT rowid -i ${HDFS_SPARSE_DIR}/tfidf-vectors/$A -o ${HDFS_MATRIX_DIR}/$B
这里的rowid就是对doc id进行编号转换。如果你的docid不是intwritable。还是走一下这一步。这里的输入tfidf-vector取决于上一步的权重算法
5)、算法终于可以开始了。运行mahout cvb
$MAHOUT cvb --input ${HDFS_MATRIX_DIR}/*/matrix/ --output ${HDFS_MODEL_DIR} -k 14 -ow -x 100 --num_train_threads 5 -dict ${HDFS_SPARSE_DIR}/dictionary.file-* -dt ${HDFS_DOC_TOPICS_DIR} -mt ${HDFS_TOPIC_MODEL_DIR}
这里的输入就是上一步的输出,可以指定topic个数(-k) , 迭代次数(-x) , 如果你想知道训练集中每个文档的topic分布,需要指定 -dt .
这样就可以等待job执行完毕了。
第三步 训练结果的导出
1) 导出topic-model..即topic-term多项分布。因为在运行过程中mahout会对term和doc重新映射id.所以导出的时候需要使用这些字典文件。
$MAHOUT seqdumper -i ${HDFS_SPARSE_DIR}/dictionary.file-0 -o ${LOCAL_OUTPUT_DIR}/dic-dump ;//导出term的字典 $MAHOUT seqdumper -i ${HDFS_MODEL_DIR} -o ${LOCAL_OUTPUT_DIR}/topic-model //导出topic-model
topic-model的格式是key: topicId value:{termid:概率}.所以自己根据dic-dump解析一下就可以看topic及其下面的词了。
2)、导出doc-topics 。如果想试用KL距离之类的算法来计算文档的相似性(我用的是JS距离),那就需要在cvb的时候使用-dt参数。
$MAHOUT seqdumper -i ${HDFS_DOC_TOPICS_DIR} -o ${LOCAL_OUTPUT_DIR}/doc-topics-dump;//导出doc-topics-model
$MAHOUT seqdumper -i ${HDFS_MATRIX_DIR}/0000${index}/docIndex -o ${LOCAL_OUTPUT_DIR}/doc-dic-dump-${index} ;//导出docid字典,注意目录在matrix目录下
剩下的工作就与上一步相同 了。。。