一直想寫一篇關于LDA模型訓練的源代碼走讀,但是因為個人水準以及時間原因未能如願,今天想起來就記錄了一下源碼走讀過程。有什麼解釋的不太清楚或者錯誤的地方請大家指正。
LDA模型訓練大緻經過以下這些步驟:
- 輸入資料(已轉換為Vector)和參數設定
- 根據LDA選擇的算法初始化優化器
- 疊代優化器
- 獲得LDA模型
下面對每一步的源碼進行代碼跟進。完整的項目可以到我的github下載下傳
1. 輸入資料和參數設定
檔案:ckooc-ml/algorithm/utils/LDAUtils.scala
入口方法:train()
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiI0NXYFhGd192UvwVe0lmdhJ3ZvwFM38CXlZHbvN3cpR2Lc1TPB10QGtWUCpEMJ9CXsxWam9CXwADNvwVZ6l2c052bm9CXUJDT1wkNhVzLcRnbvZ2LcZXUYpVd1kmYr50MZV3YyI2cKJDT29GRjBjUIF2LcRHelR3LcJzLctmch1mclRXY39TN0cTNyUTN2EzMxQDM2EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
主要是紅框中的三個部分:資料向量化、LDA優化器參數設定、執行訓練
這裡document中的Long類型是每個文檔的ID,後面Vector是tokens的向量表示,主要形式是(詞彙表大小,token的index數組,token對應的WC的數組)
LDA優化器參數設定主要是對訓練時需要用到的主題數、疊代次數、初始alpha、初始beta等進行設定
run方法時LDA訓練的主入口,方法具體實作如下:
主要實作三個功能:優化器的初始化、疊代優化器、擷取模型。後面對這幾部分進行詳細解析。
2. 根據LDA選擇的算法初始化優化器
因為這裡我使用的是EM算法,是以跟進LDAOptimizer.scala中直接看EMLDAOptimizer的initialize(docs: RDD[(Long, Vector)], lda:LDA)方法即可。
詳細解析:
2.1設定參數
2.2設定alpha和beta
注意:預設的alpha= (50.0 / K) + 1.0,beta = 1.1.通常情況下不用對這兩個超參數的初始值進行特殊設定,直接使用預設值即可。
2.3因為LDA模型訓練使用的是圖計算,故在此生成圖的邊(Document -> Term)
每條邊包含文檔ID,詞的索引、詞對應的WC,其中term2index方法功能如下:
2.4生成圖的各個節點
從上述代碼可以看到每個節點都是由一個節點ID和對應的由随機函數産生的關于主題的随機向量組成,節點ID又和邊關聯(VertexId= edge.srcId或edge.dstId)
2.5建構圖以及優化器參數設定
3. 疊代優化器
優化器的疊代主要是由優化器的next()方法實作:
這一步的實作主要使用了EM算法總的來說分為兩步E-Step和M-Step,這兩步的解釋如下:
- E-Step:假定參數已知,計算此時隐變量的後驗機率 。
基于spark mllib的LDA模型訓練源碼解析
- M-Step:帶入隐變量的後驗機率 ,最大化樣本分布的對數似然函數,求解相應的參數
基于spark mllib的LDA模型訓練源碼解析 和基于spark mllib的LDA模型訓練源碼解析 。基于spark mllib的LDA模型訓練源碼解析
詳細解析:
3.1 E-Step,計算每篇文檔的後驗機率,形成一個後驗主題機率分布
這裡主要計算每個主題的後驗機率的方法時computePTopic()方法:
3.2 M-Step,根據後驗機率分布計算
和
3.3根據新的
和
來更新圖,為下一次疊代做準備
EM算法的實作也可以參考:“通俗了解LDA主題模型”中關于pLSA和LDA的參數估計部分
4. 獲得LDA模型
這一部分比較簡單,直接使用訓練好的graph等資訊生成一個DistributedLDAModel即可
5. 總結
以上就是spark上整個的LDA模型訓練過程。總結下來還是挺簡單的,主要就以下幾個步驟:
- 初始參數構造圖(邊:doc-term,頂點:doc-topics)
- 使用EM算法,計算每個doc的 ,形成doc 的後驗主題分布
基于spark mllib的LDA模型訓練源碼解析 - 根據後驗主題分布計算參數 和
基于spark mllib的LDA模型訓練源碼解析 基于spark mllib的LDA模型訓練源碼解析 - 根據參數和更新圖
- 得到模型
其中2-4步根據疊代次數進行疊代