Python 分词、文本相似度分析

文本相似度分析的步骤:
1、读取文档
2、对要计算的多篇文档进行分词
3、对文档进行整理成指定格式,方便后续进行计算
4、计算出词语的词频
5、【可选】对词频低的词语进行过滤
6、建立语料库词典
7、加载要对比的文档
8、将要对比的文档通过doc2bow转化为词袋模型
9、对词袋模型进行进一步处理,得到新语料库
10、将新语料库通过tfidfmodel进行处理,得到tfidf
11、通过token2id得到特征数
12、稀疏矩阵相似度,从而建立索引
13、得到最终相似度结果
  
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
# Created on 2019-09-05 16:08:30
# Project: xiangsidujisuan
from pyspider.libs.base_handler import *
from gensim import corpora,models,similarities
import jieba
#from collections import defaultdict
class Handler(BaseHandler):
    crawl_config = {
    }
    @every(minutes=24 * 60)
    def on_start(self):
        doc0 = "我不喜欢上海"
        doc1 = "上海是一个好地方"
        doc2 = "北京是一个好地方"
        doc3 = "上海好吃的在哪里"
        doc4 = "上海好玩的在哪里"
        doc5 = "上海是好地方"
        doc6 = "上海路和上海人"
        doc7 = "今天去土耳其偷耳机!"
        doc8 = "招标代理文.pdf"
        
        
        all_doc = [] #文档列表
        all_doc.append(doc0)
        all_doc.append(doc1)
        all_doc.append(doc2)
        all_doc.append(doc3)
        all_doc.append(doc4)
        all_doc.append(doc5)
        all_doc.append(doc6)
        all_doc.append(doc7)
        all_doc.append(doc8)
        
        #分词
        all_doc_list = [] #文档分词列表
        for doc in all_doc:
            doc_list = [word for word in jieba.cut(doc)]
            all_doc_list.append(doc_list)
        print('分词后:' + str(all_doc_list))
        
        
        #获取词袋
        dictionary = corpora.Dictionary(all_doc_list) #用dictionary方法获取词袋(bag-of-words),词语去重
        '''
        ## 如果想要过滤掉出现次数为1的词,可以使用以下代码
        ids=[]
        for key in dictionary.iterkeys():
            if dictionary.dfs[key] == 1:
                ids.append(key)
        dictionary.filter_tokens(bad_ids=ids)
        
        ## 去掉单个字
        ids3=[]
        for key,items in dictionary.iteritems():
            if len(items) == 1:
                ids3.append(key)
        dictionary.filter_tokens(bad_ids=ids3)
        '''
        #print(dictionary)
        #print(dictionary.keys()) #词袋中用数字对所有词进行了编号
        print('词  袋:' + str(dictionary.token2id)) #编号与词之间的对应关系
        
        
        #制作语料库,语料库是一组向量,向量中的元素是一个二元组(编号、频次数),对应分词后的文档中的每一个词。
        corpus = [dictionary.doc2bow(doc) for doc in all_doc_list] #使用doc2bow制作语料库,转换为稀疏矩阵,稀疏向量
        print('语料库:' + str(corpus)) #编号经过了从小到大的排序
        
        
        #相似度分析
        #使用TF-IDF模型对语料库建模,"词频"(TF)和"逆文档频率"(IDF)
        tfidf = models.TfidfModel(corpus)
        
        
        doc_test="招司(看)托,21-0-在与9个df"
        doc_test_list = [word for word in jieba.cut(doc_test)] #分词
        print('\n分词后:' + str(doc_test_list))
        
        
        #制作语料库
        doc_test_vec = dictionary.doc2bow(doc_test_list) #使用doc2bow制作语料库,转换为稀疏矩阵,稀疏向量
        print('语料库:' + str(doc_test_vec))
        
        #获取测试文档中,每个词的TF-IDF值
        print('TF-IDF值:' + str(tfidf[doc_test_vec]))
        
        
        #对每个目标文档,分析测试文档的相似度
        index = similarities.SparseMatrixSimilarity(tfidf[corpus], num_features=len(dictionary.keys()))
        sim = index[tfidf[doc_test_vec]]
        #print(sim)
        print('相似度:' + str(sorted(enumerate(sim), key=lambda item: -item[1],reverse = False )))
        
        
'''
#获取文档摘要
from HTMLParser import HTMLParser
class SummaryHTMLParser(HTMLParser):
    """Parse HTML text to get a summary
        >>> text = u'<p>Hi guys:</p><p>This is a example using SummaryHTMLParser.</p>'
        >>> parser = SummaryHTMLParser(10)
        >>> parser.feed(text)
        >>> parser.get_summary(u'...')
        u'<p>Higuys:Thi...</p>'
    """
    def __init__(self, count):
        HTMLParser.__init__(self)
        self.count = count
        self.summary = u''
    def feed(self, data):
        """Only accept unicode `data`"""
        assert(isinstance(data, unicode))
        HTMLParser.feed(self, data)
    def handle_data(self, data):
        more = self.count - len(self.summary)
        if more > 0:
            # Remove possible whitespaces in `data`
            data_without_whitespace = u''.join(data.split())
            self.summary += data_without_whitespace[0:more]
    def get_summary(self, suffix=u'', wrapper=u'p'):
        return u'<{0}>{1}{2}</{0}>'.format(wrapper, self.summary, suffix)
    def get_summary(self,text, count):
        assert(1==2)
        return text[0:count]
'''