項目原理概述
利用sqoop將數據從MySQL導入到HDFS中,利用mahout的LDA的cvb實現對輸入數據進行聚類,並將結果更新到數據庫中。數據流向圖如下
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整個過程如下圖所示
在上面這個整體框架下,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的概率分布
算法總結
可以看出算法本質上面就是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,整個過程如圖所示
詳細流程代碼可以用vi /home/hadoop-user/scout_workspace/scout/bin/lda/cluster-dealsaccess-lda.sh查看,並可以用如下的圖進行表示
其中數據遷移到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的目錄結構
該scout項目的包依賴為hadoop及其依賴包, mahout-examples-0.9-job.jar, mysql-connector-java-5.1.25.jar, google的gson-2.2.4.jar包
主要職責為將數據文件在MySQL以及HDFS之間進行轉移,代碼量不多,花少量時間即可看懂。