利用LDA進行文本聚類(hadoop, mahout)

項目原理概述

利用sqoop將數據從MySQL導入到HDFS中,利用mahout的LDA的cvb實現對輸入數據進行聚類,並將結果更新到數據庫中。數據流向圖如下

wKiom1Oo6OHBZ22CAABpeefLoaE419.jpg



mahout算法分析



輸入數據格式
爲<IntegerWritable, VectorWritable>的matrix矩陣,key爲待聚類文本的數字編號,value爲待聚類文本的單詞向量Vector, Vector的index爲單詞在字典中的編號, value爲TFIDF值。


算法相關參數詳解(不包含hadoop運行參數)
項目中所有參數設置均與mahout-0.9目錄下的examples/bin/cluster-reuters.sh的147-172行設置一樣,即
$SCOUT cvb -i ${WORK_DIR}/${ROWID_MATRIX_DIR}/matrix -o ${WORK_DIR}/${LDA_DIR} -k 20 -ow -x 20 -dict ${WORK_DIR}/${DICTIONARY_FILES} -dt ${WORK_DIR}/${LDA_TOPICS_DIR} -mt ${WORK_DIR}/${LDA_MODEL_DIR}


input -- 輸入數據的hdfs路徑,這裏是/home/hadoop-user/scout_workspace/scout/dataset/reuters-out-matrix-debug/matrix
dt -- 文檔主題輸出路徑,保存了每個文檔的相應topic的概率,這裏是/home/hadoop-user/scout_workspace/scout/dataset/reuters-lda-topics
mt -- model的路徑,這裏是/home/hadoop-user/scout_workspace/scout/dataset/reuters-lda-debug
k -- number of topics to learn,這裏設置成20
x -- 模型迭代次數,也就是需要多少次迭代來生成最後的Model,默認值20
seed -- Random seed,生成初始readModel時的種子,默認值System.nanoTime() % 10000
dict -- 字典路徑,這裏是/home/hadoop-user/scout_workspace/scout/dataset/reuters-out-seqdir-sparse-lda/dictionary.file-*
a -- Smoothing for document/topic distribution, document/topic分佈的平滑係數,默認爲1.0E-4
e -- Smoothing for topic/term distribution, topic/term分佈的平滑係數,默認爲1.0E-4
關於a和e,根據https://mahout.apache.org/users/clustering/latent-dirichlet-allocation.html描述,a和e的合適取值爲k/50(k爲topic數量),但是這個網頁還保留着mahout ldatopics的命令介紹,而mahout 0.8,0.9均沒有該命令,推測應該是比較陳舊的內容,因此還是根據cluster-reuters.sh中的設置來,也就是採取默認值。
mipd -- 這個參數非常重要,對於每個文檔程序是先用RandomSeed來生成一個初始的readModel然後進行mipd次迭代,算出最終的model進行更新,這裏選默認值10次


LDA算法程序分析

算法的大致流程如下


1.解析參數與Configuration設置


2.讀取Model(第一次運行時沒有這個過程)
如果hfds上面已經有部分model,那麼程序將讀取最後一個model,並以這個model作爲初始readModel來繼續進行算法迭代,也就是說有類似於斷電-重啓的機制


3.運行算法迭代(Mapper過程)生成LDA模型
這個過程是最爲複雜的階段,許多地方我也不是很明白,我將盡最大努力進行解釋

首先分析Mapper,即CachingCVB0Mapper,顧名思義就是能夠緩存的Mapper,表現在其readModel的選取上面,如果目錄裏面不存在任何model則用RandomSeed初始化一個readModel,否則讀取最近的一個model。程序將model劃分爲readModel和writeModel,這兩個都是TopicModel類,並由ModelTrainer來進行調度和管理



CachingCVB0Mapper整個過程如下圖所示(清晰大圖見附件)

wKioL1Oo6L7isZdGAAU5hEvrdVQ533.jpg



在上面這個整體框架下,mahout程序應用了CVB0 Algorithm來計算LDA模型, 在map過程中通過對向量docTopic和矩陣docTopicModel的反覆迭代求解,算出每個document的docTopicModel並且在update writeModel階段將docTopicModel矩陣進行向量的相加操作,經歷完所有的map過程後得到整個corpus的docTopicModel矩陣,最終在cleanup過程中將topic的index作爲key,矩陣docTopicModel作爲value寫入reduce。該過程涉及到的算法如下所示


CVB0算法分析圖解(清晰大圖見附件)


4.利用生成的LDA模型推導出topic的概率分佈

wKiom1Oo6OnTF4H0AAHED85K8zg941.jpg


算法總結

可以看出算法本質上面就是bayes公式和EM算法的結合
E過程就是首先假定一個均勻分佈且歸一化的topic概率分佈向量docTopics,利用該值通過貝葉斯公式算出單詞 - 主題的概率分佈矩陣 docTopicModel(見CVB0算法分析圖解中的第一步)


M過程就是根據生成的docTopicModel進行CVB0算法分析圖解中的2,3,4,5步重新計算得到新的docTopics


然後反覆重複 E - M 過程n次,得到收斂後的docTopics和docTopicModel,其中docTopicModel可以用於lda模型的更新,而docTopics就是我們聚類需要的topic概率分佈向量


算法後記
幾點問題還沒有得到解決
1.在mahout中是按照下面的式子計算docTopicModel的
double termTopicLikelihood =
   (topicTermRow.get(termIndex) + eta) * (topicWeight + alpha)/ (topicSum + eta * numTerms);
疑問就是該式子比貝葉斯公式添加了幾個平滑係數項,這樣寫的理論依據在哪裏,來源於哪篇著作或者論文,平滑係數eta和alpha分別是代表什麼含義,如何選取這兩個係數。
2.CVB0算法分析圖解中第2步進行歸一化的理論依據,即爲什麼要進行歸一化
3.update writeModel過程中對於topicTermCounts的計算
即爲什麼要在每次map時候對p(topic | term)進行累加,還沒有完全想明白


項目運行環境

hadoop-1.2.1

sqoop-1.4.4

mahout-0.9

關於環境的安裝部署請參考相關文章,這裏不多加贅述。上面三個軟件在我本機的都是部署在/home/hadoop-user/mahout_workspace/目錄下。另外自己寫的scout項目部署在/home/hadoop-user/scout_workspace/目錄下


項目代碼

項目代碼已經放到Github上https://github.com/ehomeshasha/scout,有興趣的同學可以下載下來看下,重點查看bin目錄下的腳本文件以及driver,export,analyzer等幾個包下的java文件


整個項目架構分析
該項目的初始數據保存在MySQL中, 算法分析需要map/reduce過程以及hdfs文件系統的參與, 最後將結果更新至MySQL,整個過程如圖所示

wKiom1Oo6OHBZ22CAABpeefLoaE419.jpg


詳細流程代碼可以用vi /home/hadoop-user/scout_workspace/scout/bin/lda/cluster-dealsaccess-lda.sh查看,並可以用如下的圖進行表示(清晰大圖見附件)
wKioL1Oo6LbjqmqHAAOQ50kbBKc551.jpg


其中數據遷移到hdfs可採用sqoop import命令來完成,實現此過程的sh文件在/home/hadoop-user/scout_workspace/scout/bin/sqooop_mysql_dumper.sh中,可用vi /home/hadoop-user/scout_workspace/scout/bin/sqooop_mysql_dumper.sh進行查看。Apache Sqoop的網址鏈接爲http://sqoop.apache.org/docs/1.4.4/SqoopUserGuide.html#_literal_sqoop_import_literal


最後一步更新MySQL可以查看scout項目源碼查看詳細過程, 連接jdbc用到了Apache的DbUtils的包。DbUtils的網站鏈接爲http://commons.apache.org/proper/commons-dbutils/


有用的腳本文件
scout/bin/lda/cluster-reuters-lda-debug.sh提取了mahout/examples/bin/cluster-reuters.sh的lda算法部分並進行了步驟拆分,適用於進行算法的調試, scout/bin/lda/cluster-reuters-lda-debug-dumper.sh文件是一個數據dumper腳本文件,可將lda算法產生的數據dump到本地並轉換成文本格式



Scout項目架構分析

Scout的目錄結構

wKioL1Oo6Y3h4gjfAAL-mYKfoNw189.jpg



該scout項目的包依賴爲hadoop及其依賴包, mahout-examples-0.9-job.jar, mysql-connector-java-5.1.25.jar, google的gson-2.2.4.jar包
主要職責爲將數據文件在MySQL以及HDFS之間進行轉移,代碼量不多,花少量時間即可看懂。




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章