[NLP]使用LDA模型计算文档相似度

来源:互联网 发布:淘宝店铺双十一宣传语 编辑:程序博客网 时间:2024/05/29 23:47

定义

wiki关于lda的定义:

隐含狄利克雷分布简称LDA(Latent Dirichlet allocation),是一种主题模型,它可以将文档集中每篇文档的主题按照概率分布的形式给出。同时它是一种无监督学习算法,在训练时不需要手工标注的训练集,需要的仅仅是文档集以及指定主题的数量k即可。此外LDA的另一个优点则是,对于每一个主题均可找出一些词语来描述它。
LDA首先由Blei, David M.、吴恩达和Jordan, Michael I于2003年提出,目前在文本挖掘领域包括文本主题识别、文本分类以及文本相似度计算方面都有应用。

lda也是一种典型的词袋模型,它假设每一篇文档都是一组词的集合,并且词与词之间没有顺序和先后关系。一篇文章可以包含多个主题,文档中的每一个词都是由其中的一个主题生成。

实现

import codecsfrom gensim.models import LdaModelfrom gensim.corpora import Dictionaryfrom gensim import corpora, modelsimport numpy as npimport jiebaimport tutorials.data_util as dudef get_dict():    train = []    fp = codecs.open('../xx.txt', 'r', encoding='utf8')#文本文件,输入需要提取主题的文档    stopwords = ['的', '吗', '我', '会', '使用', '跟', '了', '有', '什么', '这个', '下', '或者', '能', '要', '怎么', '呢', '吧', '都']#取出停用词    for line in fp:        line = list(jieba.cut(line))        train.append([w for w in line if w not in stopwords])    dictionary = Dictionary(train)    return dictionary,traindef train_model():    dictionary=get_dict()[0]    train=get_dict()[1]    corpus = [ dictionary.doc2bow(text) for text in train ]    lda = LdaModel(corpus=corpus, id2word=dictionary, num_topics=7)    #模型的保存/ 加载    lda.save('test_lda.model')#计算两个文档的相似度def lda_sim(s1,s2):    lda = models.ldamodel.LdaModel.load('test_lda.model')    test_doc = list(jieba.cut(s1))  # 新文档进行分词    dictionary=get_dict()[0]    doc_bow = dictionary.doc2bow(test_doc)  # 文档转换成bow    doc_lda = lda[doc_bow]  # 得到新文档的主题分布    # 输出新文档的主题分布    # print(doc_lda)    list_doc1 = [i[1] for i in doc_lda]    # print('list_doc1',list_doc1)    test_doc2 = list(jieba.cut(s2))  # 新文档进行分词    doc_bow2 = dictionary.doc2bow(test_doc2)  # 文档转换成bow    doc_lda2 = lda[doc_bow2]  # 得到新文档的主题分布    # 输出新文档的主题分布    # print(doc_lda)    list_doc2 = [i[1] for i in doc_lda2]    # print('list_doc2',list_doc2)    try:        sim = np.dot(list_doc1, list_doc2) / (np.linalg.norm(list_doc1) * np.linalg.norm(list_doc2))    except ValueError:        sim=0    #得到文档之间的相似度,越大表示越相近    return sim