gensim文本主题模型推荐

用gensim包做中文文本的推荐

一、gensim是generate similar的简写,叫做普遍相似。对于gensim这个包建议新手直接使用anaconda工具进行集中安装

二、gensim包中做文本推荐要使用的几个重要的模块

     1、corpora  语料库(将文本文档转为文档向量(基于词频tfidf文档向量))

from gensim import corpora

import jieba

sentences = ["我喜欢吃土豆","土豆是个百搭的东西","我不喜欢今天雾霾的北京"]

texts=[]
for doc in sentences:
    words.append(list(jieba.cut(doc)))#分词
print words

dictionary = corpora.Dictionary(words)
print dictionary
print dic.token2id

{'\xe5\x8c\x97\xe4\xba\xac': 12, '\xe6\x90\xad': 6, '\xe7\x9a\x84': 9, '\xe5\x96\x9c\xe6\xac\xa2': 1, '\xe4\xb8\x8d': 10, '\xe4\xb8\x9c\xe8\xa5\xbf': 4, '\xe5\x9c\x9f\xe8\xb1\x86': 2, '\xe9\x9c\xbe': 14, '\xe6\x98\xaf': 7, '\xe4\xb8\xaa': 5, '\xe9\x9b\xbe': 13, '\xe7\x99\xbe': 8, '\xe4\xbb\x8a\xe5\xa4\xa9': 11, '\xe6\x88\x91': 3, '\xe5\x90\x83': 0}

#可以看到字符串为'\xe5\x8c\x97\xe4\xba\xac'(词)的编号为12,\xe4\xbb\x8a\xe5\xa4\xa9的编号为11....一共有15个词,编号从0到14

corpus = [dictionary.doc2bow(text) for text in words]
print corpus

[[(0, 1), (1, 1), (2, 1), (3, 1)], [(2, 1), (4, 1), (5, 1), (6, 1), (7, 1), (8, 1), (9, 1)], [(1, 1), (3, 1), (9, 1), (10, 1), (11, 1), (12, 1), (13, 1), (14, 1)]]

#这是一个镶嵌的列表,第一个子列表[(0, 1), (1, 1), (2, 1), (3, 1)]表示sentence中的第一个字符串的对应的文本向量,第二个子列表对应对应了第二个字符串的文本向量.....其中例如第一个子列表中(0,1)表示编号为0的词出现了一次........

#对curpus进行tfidf变换

tfidf=models.TfidfModel(corpus)

curpus_tfidf=tfidf[curpus]

for doc in curpus_tfidf:

      print  doc

#打印curpus_tfidf的信息,例如下面的第一个列表对应的curpus的第一个子列表,其中(0, 0.8425587958192721)表示编号为0的词的tfidf值是0.8425587958192721..........

[(0, 0.8425587958192721), (1, 0.3109633824035548), (2, 0.3109633824035548), (3, 0.3109633824035548)]
[(2, 0.16073253746956623), (4, 0.4355066251613605), (5, 0.4355066251613605), (6, 0.4355066251613605), (7, 0.4355066251613605), (8, 0.4355066251613605), (9, 0.16073253746956623)]
[(1, 0.1586956620869655), (3, 0.1586956620869655), (9, 0.1586956620869655), (10, 0.42998768831312806), (11, 0.42998768831312806), (12, 0.42998768831312806), (13, 0.42998768831312806), (14, 0.42998768831312806)]

例如:将文本向量vector进行tfidf变换

vector=[(0, 1), (4, 1)]

vector_tfidf=tfidf[vector]

for doc in vector_tfidf:

      print  doc

#打印vecter_tfidf的信息

[(0, 0.7071067811865475), (4, 0.7071067811865475)]

# tfidf[curpus]对curpus 进行tfidf变换,tfidf[vector]把新文本向量vector进行tfidf变换

     2、models   模型库(主题提取,主题训练)

根据上面tfidf变换,就可以进行模型训练,然后根据训练集提取出一定数量的主题

主题提取有两个模型:LSI和LDA

以LSI为例

from  gensim import   models

lsi=models.Lsimodel(corpus_tfidf,id2word=dictionary,num_topics=2)

#lsi表示根据corpus_tfidf 提取出前2个主题

corpus_lsi=lsi[corpus]

#查询corpus的每一个文本和这两个主题的相似度

corpus_lsi = lsi[corpus_tfidf]
for doc in corpus_lsi:
    print doc

[(0, -0.70861576320682107), (1, 0.1431958007198823)]
[(0, -0.42764142348481798), (1, -0.88527674470703799)]
[(0, -0.66124862582594512), (1, 0.4190711252114323)]

例如:计算新文本vector与两个主题的相似度

vector =[(13, 1), (14, 1)]

vector_lsi=lsi[vector]

#查询vector(一个文档向量)与这两个主题的每一个主题的相似度

print    vector_lsi

[(0, 0.50670602027401368), (1, -0.3678056037187441)]

     3、similarities   相似度计算库【(1)基于主题提取后计算新文本与训练集中的每一个文本的相似度

                                                        (2)直接计算新文本与训练集中每一个文本的相似度】

(1)基于主题模型(lsi)计算文本的相似度

index=similarities.MatrixSimilarity(lsi[corpus])(#建立索引)

sims=index[lsi[vector]](#计算vector(文本向量)与corpus中每一个文本的相似)

for  doc in sims:

      print doc

(2)直接计算新文本与训练集中每一个文本的相似度(没有进行主题提取)

index=similarities.SparseMatrixSimilarity(tfidf[corpus], num_features=15)

sims=index[tfidf[vector]]

for   doc in  sims:

       print   doc


三、文本主题推荐

主要步骤:

要做一些准备工作:

在anaconda工具中编写

加载停顿词库(stop_words)

设置默认utf-8编码格式

1、读取所有文本的目录(files_list)

2、读取每一个文本(*.txt)的内容(content)并把每一个文本内容读成一行写入到一个大文本中(full.txt)

          【注:得到训练集】

3、按行读取大文本内容,然后对每一行分词并去掉停顿词、数字、字母,最后存放在一个镶嵌的列表中(texts)               【注:对训练集进行预处理】

4、去掉只出现一次的词(frequency=1的词) 

          【注:对训练集进行预处理】

5、建立词典dictionary(所有词的集合并赋予唯一的id编号),然后将镶嵌的列表(texts)转化为一个文档向量矩阵(corpus)(基于词的频数),将文档向量矩阵转化为用tfidf表示的文档向量矩阵(转为词的频率)

          【注:将训练集中的文档转化为两种向量形式便于进行数学计算(预处理)】

6、主题提取(基于所有文本(训练集)提取出一定个数的主题)

          【两种重要的训练提取模型:(1)LSI(采用svd奇异值分解);(2)LDA(采用忘了)】

7、基于主题进行相似度的计算

          【两个角度来看:(1)一个新文本或训练集中的每一个文本与每一个主题都有相似度(2)给定一个新文本,                      计算与训练集中的文本的相似度】

8、给定新文本计算与训练集中的文本相似度并进行排名,然后向读者推荐相似文本。

         【可以推荐相似度靠前的10个文本】

代码示例

# -*- coding: utf-8 -*-
"""
Created on Fri Jun 24 17:37:33 2016


@author: yongsheng
"""
from __future__  import  division
import sys
import os
import re
import josn
import string
import numpy
import scipy
import gensim
from  gensim import models,corpora,similarities
import jieba
import  logging
import time
from   colections import defaultdict
loggging.basicConfig(format='%(asctime)s:%(levelname)s:%(message)s',level=logging.INFO)
printable=set(string.printable)
stop_file_read=open('C:\Users\yongsheng\Desktop\stop_word.txt','r')
stop_word=stop_file_read.read().decode('utf-8').split('\n')
filelist=[]
for file in os.listdir('files'):
    if 'txt' in file:
        filelist.append(os.path.join(files,file))


for file in filelist:
    filename=file.split('\\')[-1]
    f=open('C:\Users\yongsheng\Desktop\full.txt','w')
    lines=[]
    with open(file,'r')  as fd:
        for line in fd.readlines():
            line=line.replace('\n',' ')
            line=line.replace('-','')
            line=line.replace(',',' ')
            lines.append(line)
    f.write(filename+','+' '.join(lines)+'\n')
f.close()


texts=[]
textname=[]
fl=open('C:\Users\yongsheng\Desktop\full.txt','r')
for line in f.readlines():
    filelist=line.split(',')
    _filename=filelist[0]
    _content=filelist[1]
    seg_list=jieba.cut(_content,cut_all=False)
    seg_list_str=[]
    for seg in seg_list:
        if seg not in stop_word  and len(seg)>1 and seg not in printable:
            seg_list_str.append(str(seg))
    texts.append(seg_list_str)
    textname.append(_filename)
fl.close()
frequency=defaultdict(int)
for text in texts:
    for  token in text:
        frequency[token]+=1
texts=[[token for token in text if frequency[token]>1] for text in texts]
dictionary=corpora.Dictionary(texts)
corpus=[dictionary.doc2bow(text) for text in texts]
tfidf=models.TfidfModel(corpus)
corpus_tfidf=tfidf[corpus]
lsi=models.LsiModel(corpus_tfidf,dictionary=dictionary, num_topic=30)
lsi_corpus=lsi[corpus]
index=similarities.MatrixSimilarity(lsi[corpus])

假设查询的文章:vec
sims=index[lsi[vec]]
simsorts=sorted(enumerate(sims),key=lambda item:-item[1])
sims_filename=[]
sims_filecontext=[]
for item in simsorts[0:10]:
    sims_filename.append(textname[item[0]])
    sims_filecontext.append(texts[item[0]])
simsten=[' '.join(text) for text in sims_filecontext]
print simsten 

在此也参考了某位博主的的文章,加上对他每一步的解读。由于时间关系有很多地方没有写的很清楚,以后在慢慢补充。

你可能感兴趣的:(机器算法)