lda模型的python实现

来源:互联网 发布:json 格式检验 编辑:程序博客网 时间:2024/05/22 12:09
  • 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    #初始化随机分配类    for x in 文章数:        统计ndsum[文章id][词的个数]        for y in 每篇文章的词个数:            给所有词随机分派一个类            词在此类上的分布数目+1            此文章中此类的词的个数+1            此类的总词数 +1end
##实现代码片段,更详细看github项目#class LDAModel(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([ [0 for y in xrange(dpre.docs[x].length)] for x in xrange(dpre.docs_count)])        # M*doc.size(),文档中词的主题分布        #随机先分配类型        for x in xrange(len(self.Z)):            self.ndsum[x] = self.dpre.docs[x].length            for y in xrange(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] += 1                self.nd[x][topic] += 1                self.nwsum[topic] += 1        self.theta = np.array([ [0.0 for y in xrange(self.K)] for x in xrange(self.dpre.docs_count) ])        self.phi = np.array([ [ 0.0 for y in xrange(self.dpre.words_count) ] for x in xrange(self.K)]) 
  • sampling抽样过程

##伪代码#输入:初始化后的lda_model,迭代次数iter_times,超参数α、β,聚类个数K输出:theta(文章对应类的分布概率),phi(类对应词的分布概率),tassgin(文章中每个词的分派类结果),twords(每个类topN个高频词)begin    for i in 迭代次数:        for m in 文章个数:             for v in 文章中词:                取topic = Z[m][v]                令nw[v][topic]、nwsum[topic]、nd[m][topic]的统计量均-1                计算概率p[] #p[]为此词属于每个topic的概率                for k in (1,类的个数-1):                    p[k] += p[k-1]                再随机分派一次,记录被分派的新的topic                令nw[v][new_topic]、nwsum[new_topic]、nd[m][new_topic]的统计量均+1    #迭代完成后    输出模型end
#代码片段    def sampling(self,i,j):        topic = self.Z[i][j]        word = self.dpre.docs[i].words[j]        self.nw[word][topic] -= 1        self.nd[i][topic] -= 1        self.nwsum[topic] -= 1        self.ndsum[i] -= 1        Vbeta = 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)        for k in xrange(1,self.K):            self.p[k] += self.p[k-1]        u = random.uniform(0,self.p[self.K-1])        for topic in xrange(self.K):            if self.p[topic]>u:                break        self.nw[word][topic] +=1        self.nwsum[topic] +=1        self.nd[i][topic] +=1        self.ndsum[i] +=1        return topic

 


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


0 0
原创粉丝点击