龙空技术网

优化|PLSA理论与实践

运筹OR帷幄 52

前言:

今天姐妹们对“foreach能return吗”大约比较珍视,大家都想要了解一些“foreach能return吗”的相关知识。那么小编同时在网络上搜集了一些对于“foreach能return吗””的相关内容,希望姐妹们能喜欢,兄弟们快快来了解一下吧!

PLSA又称为概率潜在语义分析,是一种利用概率生成模型对文本集合进行话题分析的无监督学习方法。该模型最大的特点是加入了主题这一隐变量,文本生成主题,主题生成单词,从而得到单词-文本共现矩阵。本文将对包含物理学、计算机科学、统计学、数学四个领域的15000条文献摘要的数据集(保存在Task-Corpus.csv中)使用PLSA算法进行处理。

一、算法推导1.1 E-steps二、算法实现

words = set()    word_counts = []    for document in documents:        seglist = word_tokenize(document)        wordlist = []        for word in seglist:            synsets = wordnet.synsets(word)            if synsets:                syn_word = synsets[0].lemmas()[0].name()                if syn_word not in stopwords:                    wordlist.append(syn_word)            else:                if word not in stopwords:                    wordlist.append(word)        words = words.union(wordlist)        word_counts.append(Counter(wordlist))    word2id = {words:id for id, words in enumerate(words)}    id2word = dict(enumerate(words))    N = len(documents) # number of documents    M = len(words) # number of words    X = np.zeros((N, M))    for i in range(N):        for keys in word_counts[i]:            X[i, word2id[keys]] = word_counts[i][keys]

然后根据(1)(2)(3)三式进行PLSA算法的编写。注意到这三个式子都可以写成矩阵的形式,提高运算效率。同时注意到这三个式子都和分子成正比,因此可以计算出份子再除以归一化常数即可。E-step的代码如下。

def E_step(lam, theta):    # lam: N * K, theta: K * M, p = K * N * M    N = lam.shape[0]    M = theta.shape[1]    lam_reshaped = np.tile(lam, (M, 1, 1)).transpose((2,1,0)) # K * N * M    theta_reshaped = np.tile(theta, (N, 1, 1)).transpose((1,0,2)) # K * N * M    temp = lam @ theta    p = lam_reshaped * theta_reshaped / temp    return p

M-step的代码如下。

def M_step(p, X):    # p: K * N * M, X: N * M, lam: N * K, theta: K * M    # update lam    lam = np.sum(p * X, axis=2) # K * N    lam = lam / np.sum(lam, axis=0) # normalization for each column    lam = lam.transpose((1,0)) # N * K    # update theta    theta = np.sum(p * X, axis=1) # K * M    theta = theta / np.sum(theta, axis=1)[:, np.newaxis] # normalization for each row        return lam, theta

计算对数似然的代码如下。

def LogLikelihood(p, X, lam, theta):    # p: K * N * M, X: N * M, lam: N * K, theta: K * M    res = np.sum(X * np.log(lam @ theta)) # N * M    return res
三、结果分析

由于笔记本电脑的内存有限,从所给数据集中随机抽取1000篇文本进行实验。设定主题数为4。某次实验的结果如下。构建的字典中包含11342个单词。字典保存在dictionary.json文件中。

程序在迭代152次后停止。可以看到对数似然确实在不断上升。

每个文本的主题分布保存在DocTopicDistribution.csv文件中。每个主题的单词分布保存在TopicWordDistribution.csv文件中。每个主题中出现概率最高的9个单词保存在topics.txt文件中,如下图所示。可以看到出现概率最高的单词分别为astatine, network, Associate_in_Nursing, algorithm,分别对应了物理学、计算机科学、统计学、数学四个领域。这证明了PLSA方法的有效性。

项目开源

本项目开源在kungfu-crab/PLSA: A python implementation for PLSA(Probabilistic Latent Semantic Analysis) using EM algorithm. (),仅作为学习交流使用,禁止转载与抄袭。

参考文献

[1] Hofmann, T. (1999). Probabilistic Latent Semantic Analysis. In Proceedings of the Fifteenth Conference on Uncertainty in Artificial Intelligence (pp. 289-296). Morgan Kaufmann Publishers Inc.

标签: #foreach能return吗