LDA代碼流程:
(1) 先對文檔切詞,然后對每個詞語賦ID編號0~(n-1),計算共有n個詞,m個文檔
(2) 參數,變量設置:
- K 主題數
- beta β
- alpha α
- iter_times 迭代次數
- top_words_num 每個主題特征詞個數
- p,概率向量,double類型,存儲采樣的臨時變量,長度為主題數
- nw,詞word在主題上的分布數,長度為[n][K]
- nwsum,每個主題的詞的總數,長度為[K]
- nd,每個文檔中各個主題的詞的總數,長度為[m][K]
- ndsum,每個文檔中詞的總數,長度為[m]
- Z,文檔中各個詞的所屬主題,長度為[m][各個文檔的詞個數]
- theta,長度為[m][K] 文章-主題分布
- phi,長度為[K][n] 詞-主題分布
(3) 初始化
- 先為各個文檔里的單詞隨機分配主題
- for i to 文檔數:
- ndsum[i] = 文檔i的單詞數
- for j to 文檔i的單詞數:
- 隨機主題topic
- Z[i][j] = topic
- nw[詞的ID編號][topic] += 1
- nd[i][topic] += 1
- nwsum[topic] += 1
(4) 開始迭代
- 迭代iter_times次:
- for i to 文檔數:
- for j to 文檔i的單詞數:
- topic = self.Z[i][j] 取出文檔i中第j的單詞的主題
- 取出文檔i中第j的單詞的ID編號id,假設去除這個詞后的主題分布
- nw[id][topic] -= 1
- nd[i][topic] -= 1
- nwsum[topic] -= 1
- ndsum[i] -= 1
- #計算每個主題的概率分布
- Vbeta = 單詞數 * self.beta
- Kalpha = K * self.alpha
- p = (nw[id] + beta)/(nwsum + Vbeta)*(nd[i] + alpha) / (ndsum[i] + Kalpha)
- for k to K:
- 隨機一個概率u in (0,p[K-1])
- #如果轉移概率大於u,則轉移.
- for topic to K:
- #確定文檔i中的第j個單詞的主題為topic,重新賦值
- nw[id][topic] +=1
- nwsum[topic] +=1
- nd[i][topic] +=1
- ndsum[i] +=1
(5) 計算文章-主題分布,計算詞-主題分布
- for i to m: #這文檔各個主題的單詞數除以這文檔總的單詞數
- theta[i] = (nd[i]+alpha)/(ndsum[i]+K * alpha)
- for i to K: #這主題各個的單詞的數量除以這主題總的單詞數
- phi[i] = (nw.T[i]+beta)/(nwsum[i]+ n * beta)
(6) 取各個主題的前top_words_num個特征詞