1)共轭先验分布
参见http://blog.csdn.net/baimafujinji/article/details/51374202
a.共轭性:后验概率分布拥有与先验分布相同的函数形式。这个性质被叫做共轭性(Conjugacy)。它使得后验概率分布的函数形式与先验概率相同。例如,二项分布的参数之共轭先验就是我们前面介绍的 Beta 分布。多项式分布的参数之共轭先验则是 Dirichlet 分布,⽽⾼斯分布的均值之共轭先验是另⼀个⾼斯分布。
b.期望:
http://www.52nlp.cn/lda-math-%E8%AE%A4%E8%AF%86betadirichlet%E5%88%86%E5%B8%833
2)LDA文本分类
假设:
a.每篇文档有K个主题
b.每个主题由W种单词组成
c.对于每篇文档,主题先验分布服从Dirichlet分布
d.对于每种主题,单词先验分布服从Dirichlet分布
e.w(i,j)表示第i篇文档第j个单词,假设它先由第i篇文档的主题分布产生主题z(i,j),再由主题z(i,j)的单词分布产生。
步骤:
a.初始矩阵
Z # Z[i][j]表示第i文档的第j个词背分配的主题
W # W[i][j]表示第i文档的第j个词
nw # nw[w][z]表示词w被分配到主题z的次数
nd # nd[d][z]文档d中被分配为主题z的词的个数
nwsum # nwsum[z]表示主题z中包含的词的个数
ndsum # ndsum[d]表示文档d中包含的词的个数
theta # D * K 大小的矩阵,文档最终主题分布概率期望值
phi # K * V 大小的矩阵,主题最终单词分布概率期望值
b.随机分配矩阵Z
c.更新
对于每一篇文档的每个单词:
计算去掉当前词后的矩阵nw,nd,nwsum,ndsum
计算生成当前词的主题概率p=p(topic|document)*p(当前词|topic)
根据分布p抽样生成当前词新的topic
更新nw,nd,nwsum,ndsum
d.循环c,直至迭代次数或者达到收敛条件
python实现:
http://blog.csdn.net/eastmount/article/details/50824215
pip install lda
# -*- encoding: utf-8 -*-
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
import numpy as np
import lda
import lda.datasets
# document-term matrix
X = lda.datasets.load_reuters()
print("type(X): {}".format(type(X)))
print("shape: {}\n".format(X.shape))
print(X[:5, :5])
# the vocab
vocab = lda.datasets.load_reuters_vocab()
print("type(vocab): {}".format(type(vocab)))
print("len(vocab): {}\n".format(len(vocab)))
print(vocab[:5])
# titles for each story
titles = lda.datasets.load_reuters_titles()
print("type(titles): {}".format(type(titles)))
print("len(titles): {}\n".format(len(titles)))
print(titles[:5])
model = lda.LDA(n_topics=20, n_iter=500, random_state=1)
model.fit(X) # model.fit_transform(X) is also available
topic_word = model.topic_word_
print("type(topic_word): {}".format(type(topic_word)))
print("shape: {}".format(topic_word.shape))
print(vocab[:3])
print(topic_word[:, :3])
for n in range(5):
sum_pr = sum(topic_word[n,:])
print("topic: {} sum: {}".format(n, sum_pr))
n = 5
for i, topic_dist in enumerate(topic_word):
topic_words = np.array(vocab)[np.argsort(topic_dist)][:-(n+1):-1]
print('*Topic {}\n- {}'.format(i, ' '.join(topic_words)))
doc_topic = model.doc_topic_
print("type(doc_topic): {}".format(type(doc_topic)))
print("shape: {}".format(doc_topic.shape))
for n in range(10):
topic_most_pr = doc_topic[n].argmax()
print("doc: {} topic: {}".format(n, topic_most_pr))
import matplotlib.pyplot as plt
f, ax= plt.subplots(5, 1, figsize=(8, 6), sharex=True)
for i, k in enumerate([0, 5, 9, 14, 19]):
ax[i].stem(topic_word[k,:], linefmt='b-',
markerfmt='bo', basefmt='w-')
ax[i].set_xlim(-50,4350)
ax[i].set_ylim(0, 0.08)
ax[i].set_ylabel("Prob")
ax[i].set_title("topic {}".format(k))
ax[4].set_xlabel("word")
plt.tight_layout()
plt.show()
import matplotlib.pyplot as plt
f, ax= plt.subplots(5, 1, figsize=(8, 6), sharex=True)
for i, k in enumerate([1, 3, 4, 8, 9]):
ax[i].stem(doc_topic[k,:], linefmt='r-',
markerfmt='ro', basefmt='w-')
ax[i].set_xlim(-1, 21)
ax[i].set_ylim(0, 1)
ax[i].set_ylabel("Prob")
ax[i].set_title("Document {}".format(k))
ax[4].set_xlabel("Topic")
plt.tight_layout()
plt.show()