lda模型的python实现

王朝学院·作者佚名  2016-08-27
窄屏简体版  字體: 小  |  中  |  大  |  超大  

LDA(Latent Dirichlet Allocation)是一种文档主题生成模型,最近看了点资料,准备使用python实现一下。至于数学模型相关知识,某度一大堆,这里也给出之前参考过的一个挺详细的文档lda算法漫游指南这篇博文只讲算法的sampling方法python实现。完整实现项目开源python-LDA

lda模型变量申请及初始化#

#伪代码#输入:文章集合(分词处理后),K(类的个数)

输出:已经随机分派了一次的lda模型

begin

申请几个统计量:

p 概率向量 维度:K

nw 词在类上的分布 维度:M*K 其中M为文章集合的词的总个数

nwsum 每个类上的词的总数 维度:K

nd 每篇文章中,各个类的词个数分布 维度:V*K 其中V为文章的总个数

ndsum 每篇文章中的词的总个数 维度:V

Z 每个词分派一个类 维度:V*每篇文章词的个数

theta 文章->类的概率分布 维度:V*K

phi 类->词的概率分布 维度:K*M#初始化随机分配类forxin文章数:

统计ndsum[文章id][词的个数]foryin每篇文章的词个数:

给所有词随机分派一个类

词在此类上的分布数目+1此文章中此类的词的个数+1此类的总词数+1end

#

#实现代码片段,更详细看github项目#classLDAModel(object):def__init__(self,dPRe):

self.dpre= dpre#获取预处理参数##模型参数#聚类个数K,迭代次数iter_times,每个类特征词个数top_Words_num,超参数α(alpha) β(beta)#self.K =K

self.beta=beta

self.alpha=alpha

self.iter_times=iter_times

self.top_words_num=top_words_num##文件变量#分好词的文件trainfile#词对应id文件wordidmapfile#文章-主题分布文件thetafile#词-主题分布文件phifile#每个主题topN词文件topNfile#最后分派结果文件tassginfile#模型训练选择的参数文件paramfile#self.wordidmapfile =wordidmapfile

self.trainfile=trainfile

self.thetafile=thetafile

self.phifile=phifile

self.topNfile=topNfile

self.tassginfile=tassginfile

self.paramfile=paramfile#p,概率向量 double类型,存储采样的临时变量#nw,词word在主题topic上的分布#nwsum,每各topic的词的总数#nd,每个doc中各个topic的词的总数#ndsum,每各doc中词的总数self.p =np.zeros(self.K)

self.nw= np.zeros((self.dpre.words_count,self.K),dtype="int")

self.nwsum= np.zeros(self.K,dtype="int")

self.nd= np.zeros((self.dpre.docs_count,self.K),dtype="int")

self.ndsum= np.zeros(dpre.docs_count,dtype="int")

self.Z= np.array([ [0foryinxrange(dpre.docs[x].length)]forxinxrange(dpre.docs_count)])#M*doc.size(),文档中词的主题分布#随机先分配类型forxinxrange(len(self.Z)):

self.ndsum[x]=self.dpre.docs[x].lengthforyinxrange(self.dpre.docs[x].length):

topic= random.randint(0,self.K-1)

self.Z[x][y]=topic

self.nw[self.dpre.docs[x].words[y]][topic]+= 1self.nd[x][topic]+= 1self.nwsum[topic]+= 1self.theta= np.array([ [0.0foryinxrange(self.K)]forxinxrange(self.dpre.docs_count) ])

self.phi= np.array([ [ 0.0foryinxrange(self.dpre.words_count) ]forxinxrange(self.K)])

sampling抽样过程#

#伪代码#输入:初始化后的lda_model,迭代次数iter_times,超参数α、β,聚类个数K

输出:theta(文章对应类的分布概率),phi(类对应词的分布概率),tassgin(文章中每个词的分派类结果),twords(每个类topN个高频词)

beginforiin迭代次数:formin文章个数:forvin文章中词:

取topic=Z[m][v]

令nw[v][topic]、nwsum[topic]、nd[m][topic]的统计量均-1计算概率p[]#p[]为此词属于每个topic的概率forkin(1,类的个数-1):

p[k]+= p[k-1]

再随机分派一次,记录被分派的新的topic

令nw[v][new_topic]、nwsum[new_topic]、nd[m][new_topic]的统计量均+1#迭代完成后输出模型

end

#代码片段defsampling(self,i,j):

topic=self.Z[i][j]

word=self.dpre.docs[i].words[j]

self.nw[word][topic]-= 1self.nd[i][topic]-= 1self.nwsum[topic]-= 1self.ndsum[i]-= 1Vbeta= self.dpre.words_count *self.beta

Kalpha= self.K *self.alpha

self.p= (self.nw[word] + self.beta)/(self.nwsum + Vbeta) *\

(self.nd[i]+ self.alpha) / (self.ndsum[i] +Kalpha)forkinxrange(1,self.K):

self.p[k]+= self.p[k-1]

u= random.uniform(0,self.p[self.K-1])fortopicinxrange(self.K):ifself.p[topic]>u:

breakself.nw[word][topic]+=1self.nwsum[topic]+=1self.nd[i][topic]+=1self.ndsum[i]+=1returntopic

此实现为最基础的LDA模型实现,聚类个数K,和超参数的设置要靠人工输入,自动计算的版本会在以后研究。

 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
© 2005- 王朝網路 版權所有 導航