# LDA笔记

θ$\theta$ ：文档-主题分布，θmDirichlet(α)$\theta_m是Dirichlet(\alpha)$α$\alpha$是Dirichlet分布的超参数，K维向量（K是主题数）
ϕ$\phi$：主题-词分布，ϕzDirichlet(β)$\phi_z是Dirichlet(\beta)$β$\beta$是Dirichlet分布的超参数，V维向量（V是词典大小）
Z：词的主题，zmnMulti(θm)$z_{mn}是Multi(\theta_m)$
W：词，wmnMulti(ϕzmn)$w_{mn}是Multi(\phi_{z_{mn}})$

LDA假设一篇文档的生成过程如下：

1. 随机选择一个主题分布
2. 对文档中的每个词：
• 从主题分布中随机选择一个主题
• 从主题中随机选择一个单词

LDA的目标是估计θ$\theta$ϕ$\phi$，即估计哪些词对哪个主题重要，哪些主题对一个文档重要。

α$\alpha$: The higher the value the more likely each document is to contain a mixture of most of the topics instead of any single topic.
β$\beta$: higher value denotes that each topic is likely to contain a mixture of most of the words and not any word specifically.

### collapsed gibbs sampling

raw_docs=["eat turkey on turkey day holiday",
"i like to eat cake on holiday",
"turkey trot race on thanksgiving holiday",
"snail race the turtle",
"time travel space race",
"movie on thanksgiving",
"movie at air and space museum is cool movie",
"aspiring movie star"]
raw_docs_=[doc.split() for doc in raw_docs]

from gensim import corpora
dictionary=corpora.Dictionary(raw_docs_)
#dictionary为每个出现在语料库中的单词分配了一个独一无二的整数编号。这个操作收集了单词计数及其他相关的统计信息。
#dictionary.token2id得到字典{词，词的id}
docs=[[dictionary.token2id[word] for word in doc] for doc in raw_docs_]
"""

[2, 1, 3, 1, 0, 4]
[6, 8, 5, 2, 7, 3, 4]
[1, 9, 10, 3, 11, 4]
[12, 10, 13, 14]
[17, 16, 15, 10]
[18, 3, 11]
[18, 20, 19, 22, 15, 23, 24, 21, 18]
[25, 18, 26]
"""

import numpy as np
M=len(docs) #文档的个数
K=2 #主题的个数
V=len(dictionary.token2id) #词典的大小

#@wt: the count of each word being assigned to each topic
wt=np.zeros((K,V))

#@dt: the number of words assigned to each topic for each document
dt=np.zeros((M,K))

#@ta: topic assignment list
ta=[]
for di in range(M):
ta_di=[]
for w in docs[di]:
t=np.random.randint(0,K)
ta_di.append(t)

wt[t][w] = wt[t][w]+1
dt[di][t] = dt[di][t]+1
ta.append(ta_di)
"""

[1, 0, 0, 0, 1, 0]
[1, 0, 0, 0, 0, 0, 0]
[0, 1, 1, 1, 0, 0]
[0, 1, 1, 0]
[1, 1, 0, 0]
[1, 0, 0]
[0, 0, 1, 1, 1, 1, 1, 1, 0]
[0, 0, 1]

array([[ 4.,  2.],
[ 6.,  1.],
[ 3.,  3.],
[ 2.,  2.],
[ 2.,  2.],
[ 2.,  1.],
[ 3.,  6.],
[ 2.,  1.]])

array([[ 0.,  3.,  3.,  3.,  1.,  1.,  1.,  1.,  0.,  1.,  2.,  0.,  0.,
1.,  1.,  0.,  0.,  1.,  3.,  0.,  0.,  0.,  0.,  0.,  1.,  0.,
1.],
[ 1.,  0.,  1.,  0.,  1.,  0.,  0.,  0.,  1.,  2.,  0.,  1.,  1.,
0.,  0.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  0.,  1.,
0.]])
"""

P(zi=j)$P(z_i=j)$：token i 被分配给主题 j 的概率
zi$z_{-i}$：所有其他token的主题分配
wi$w_i$：token i 的词id
di$d_i$：token i 所在文档

W：文档集的所有单词总数
T：主题数，与前面定义的K相同
CWT$C^{WT}$：wt
Ww=1CWTwj$\sum_{w=1}^WC_{wj}^{WT}$：每个主题的token总数
CDT$C^{DT}$：dt
Tt=1CDTdit$\sum_{t=1}^TC_{d_it}^{DT}$：文档di的token总数
α$\alpha$：Parameter that sets the topic distribution for the documents
η$\eta$β$\beta$：Parameter that sets the topic distribution for the words

for m,doc in enumerate(docs):
for n,t in enumerate(doc):
z=ta[m][n]
#z_-i指当采样token w时，在wt和dt计数矩阵中不包括token w
dt[m][z]-=1
wt[z][t]-=1
#sampling
left=(wt[:,t]+eta)/(np.sum(wt,axis=1)+V*eta)
right=(dt[m]+alpha)
p_z=left*right
n_z=np.random.multinomial(1,p_z/p_z.sum()).argmax()
#保存新得到的主题n_z
dt[m][n_z]+=1
wt[n_z][t]+=1
ta[m][n]=n_z

ϕij$\phi_{ij}$是主题 j 中词 i 的概率

θdj$\theta_{dj}$是文档 d 中主题 j 的比例

### 多项分布

numpy.random.multinomial(n=10, pvals=[0.2,0.4,0.4], size = 1)