gensim在“中文查找(关键词)“与“txt文本“之间做相似度计算(返回最相似的文本)

本文目的

搜索关键词,返回最相关的txt文本内容(模仿搜索引擎)

网上的例子都是一个list里面放入几句话,然后输入关键词去计算相似度.

无法在实际中应用,例如

http://blog.csdn.net/appleyuchi/article/details/78062721

下面改进了下,

下面改为输入一句话,不是去list中查找,而是去文件夹中查找,这样就有一个搜索引擎的雏形

下面代码在python2.7,linux下运行,运行时,修改path以及question即可

path代表存放一大堆txt文件的文件夹的路径

下面代码实现question与这些txt文件做相似度计算的功能.

 

 

运行环境

 

组件版本
Ubuntu18.10
python2.7.12

运行方法


①mkdir train
②mkdir train_corpus_seg
③解压tc-corpus-train.zip到train文件夹中

注:

解压后会有一大堆文件夹,为了运行调试方便的目的,可以删除其余文件夹,只留两个文件夹即可,

每个文件夹表示一个大类。

④python corpus_segment.py
⑤python top.py

 

数据集采用复旦大学的新闻数据集tc-corpus-train.zip

下载链接是:

链接: https://pan.baidu.com/s/1hAxkar56UM6U_Eo8vm0rOA  密码: mpqd

 

实验大意

 

附录代码中设置搜索关键词question:“邹家华 矿产”(模仿搜索引擎中输入关键词)

返回与关键词最相关的一篇文章内容。(模仿搜索引擎返回最相关的网页)

附录代码中有三个模型,每个模型都返回了最匹配的文章的序号。

第一个模型额外增加代码get_article,返回了"最匹配的文章的序号"对应的"具体的内容"

其他两个模型仅仅返回最相关的文章的序号,不返回内容(若要返回文章内容可以模仿第一个模型的例子来添加)

 

实验运行结果

 

-------------------下面是tfidf模型(第1个提问)----------------------------------------------------
Building prefix dict from the default dictionary ...
Loading model from cache /tmp/jieba.cache
Loading model cost 0.545 seconds.
Prefix dict has been built succesfully.
[(1, 0.3586881756782532), (18, 0.28805285692214966), (15, 0.2172296941280365), (13, 0.20284029841423035), (21, 0.06617657840251923)]
搜索得到最匹配的文章是: 【 日期 】 19960404 【 版号 】 2 【 标题 】 全国 矿产资源 委员会 成立 邹家华 提出 全面 加强 矿产 资源管理 【 作者 】 朱幼棣 【 正文 】 据 新华社 北京 4 月 3 日电 ( 记者 朱幼棣 ) 全国 矿产资源 委员会 第一次 会议 今天 召开 , 国务院 副 总理 、 全国 资源委 主任 邹家华 说 , 国务院 决定 成立 全国 矿产资源 委员会 , 取代 原来 的 全国 矿产 储量 委员会 , 这是 国务院 为了 全面 加强 矿产 资源管理 的 一项 重要 措施 , 是 我国 矿产 资源管理 体制 上 的 一项 重要 改革 。 邹家华 说 , 国务院 十分重视 作为 国民经济 发展 的 基础产业 矿产资源 工作 。 我国 矿产 资源管理 体制 , 随着 国家 经济 的 发展 和 历史 演变 , 发生 了 许多 变化 , 总的来说 也 是 不断 适应 生产力 的 发展 , 也 因此 大大 推进 了 国民经济 的 发展 。 但 从 当前 实践 中看 , 矿产 资源管理 体制 不能 进一步 适应 生产力 发展 的 需要 , 没有 能够 按照 宪法 的 要求 , 真正 体现 中央政府 的 集中 、 统一 和 有效 的 管理 , 不能 在 维护 矿产资源 国家所有 的 权益 , 合理 规划 利用 资源 , 加强 政策 调控 等 方面 发挥 应有 的 作用 , 还 存在 着 多头管理 、 地方 保护 和 部门 分割 的 状况 。 为此 , 从 我国 国情 出发 , 需要 一个 高层次 的 议事 协调 机构 , 不仅 是 对 全国 矿产 储量 的 确认 , 而且 是 在 全国 范围 内 , 统筹 矿产资源 勘查 、 开发 、 利用 、 保护 与 管理 方面 的 政策 和 方针 , 协调 各 部门 和 各大 公司 的 工作 , 共同努力 办 一些 大事 、 实事 , 解决 一些 重大 问题 。 邹家华 说 , 党 的 十四届 五中全会 《 建议 》 和 八届 人大 四次会议 批准 的 《 纲要 》 , 对 加强 自然资源 保护 、 环境 、 生态 保护 也 提出 了 目标 、 工作 重点 和 政策措施 。 这 充分 显示 了 党中央 、 国务院 对 资源管理 工作 的 高度 关心 、 重视 和 支持 , 也 表明 了 资源管理 工作 责任 更 重大 、 任务 更 艰巨 。 对 今后 矿产资源 保护 管理 的 重要性 与 紧迫性 , 各 部门 、 各级 地方 政府 都 要 从 战略 高度 深刻 认识 。 全国 矿产资源 委员会 的 主要 任务 是 研究 矿产资源 政策 , 酝酿 一个 时期 内 资源 开发 与 保护 的 行动计划 和 重大项目 , 协调 各 部门 和 地方 的 关系 。 矿产资源 委员会 要 承担 起 维护 矿产资源 国家所有 、 促进 矿产资源 的 开发 与 保护 、 实现 可 持续 发展 的 历史使命 。 邹家华 提出 , 今后 资源 委员会 要 紧紧围绕 《 建议 》 和 《 纲要 》 的 目标 , 开拓 新 体制 、 探索 新 政策 、 制定 新 战略 , 做好 工作 , 一是 促进 资源管理 新 体制 的 建立 , 建设 统一 、 协调 、 高效 、 权威 的 中央 统一 管理 与 授权 地方 管理 相结合 的 资源管理 体系 ; 二是 促进 地质 勘查 和 矿业 的 健康 发展 , 为 国民经济 与 社会 发展 提供 必要 的 资源 保障 , 努力 达到 资源 供需平衡 ; 三是 通过 实施 可 持续 发展 战略 与 科教兴国 战略 , 最大 限度 地 合理 开发利用 矿产资源 , 提高 资源 的 综合利用 水平 , 保护 生态环境 ; 四是 促进 矿产资源 法制建设 , 推动 矿产资源 开发 与 管理 的 整体 水平 上 一个 新台阶 。 国务院 副 秘书长 周正庆 宣读 了 《 国务院办公厅 关于 将 全国 矿产 储量 委员会 更名 为 全国 矿产资源 委员会 及 组成 人员 的 通知 》 。
-------------------下面是tfidf模型(第2个提问)----------------------------------------------------
[(1, 0.3586881756782532), (18, 0.28805285692214966), (15, 0.2172296941280365)]
-------------------下面是LSI模型-----------------------------------
[(1, 0.948716402053833), (13, 0.8921045064926147)]
 

参考文献


Reference:
[1]https://blog.csdn.net/github_36326955/article/details/54891204
[2]https://blog.csdn.net/u011630575/article/details/80159298

 

附录

corpus_segment.py

#!/usr/bin/env python  
# -*- coding: UTF-8 -*-  
""" 
@version: python2.7.8  
@author: XiangguoSun 
@contact: sunxiangguodut@qq.com 
@file: corpus_segment.py 
@time: 2017/2/5 15:28 
@software: PyCharm 
"""  
import sys  
import os  
import jieba  
# 配置utf-8输出环境  
reload(sys)  
sys.setdefaultencoding('utf-8')  
# 保存至文件  
def savefile(savepath, content):  
    with open(savepath, "wb") as fp:  
        fp.write(content)  
    ''''' 
    上面两行是python2.6以上版本增加的语法,省略了繁琐的文件close和try操作 
    2.5版本需要from __future__ import with_statement 
    新手可以参考这个链接来学习http://zhoutall.com/archives/325 
    '''  
# 读取文件  
def readfile(path):  
    with open(path, "rb") as fp:  
        content = fp.read()  
    return content  
  
def corpus_segment(corpus_path, seg_path):  
    ''''' 
    corpus_path是未分词语料库路径 
    seg_path是分词后语料库存储路径 
    '''  
    catelist = os.listdir(corpus_path)  # 获取corpus_path下的所有子目录  
    ''''' 
    其中子目录的名字就是类别名,例如: 
    train_corpus/art/21.txt中,'train_corpus/'是corpus_path,'art'是catelist中的一个成员 
    '''  
  
    # 获取每个目录(类别)下所有的文件  
    for mydir in catelist:  
        ''''' 
        这里mydir就是train_corpus/art/21.txt中的art(即catelist中的一个类别) 
        '''  
        class_path = corpus_path + mydir + "/"  # 拼出分类子目录的路径如:train_corpus/art/  
        seg_dir = seg_path + mydir + "/"  # 拼出分词后存贮的对应目录路径如:train_corpus_seg/art/  
  
        if not os.path.exists(seg_dir):  # 是否存在分词目录,如果没有则创建该目录  
            os.makedirs(seg_dir)  
  
        file_list = os.listdir(class_path)  # 获取未分词语料库中某一类别中的所有文本  
        ''''' 
        train_corpus/art/中的 
        21.txt, 
        22.txt, 
        23.txt 
        ... 
        file_list=['21.txt','22.txt',...] 
        '''  
        for file_path in file_list:  # 遍历类别目录下的所有文件  
            fullname = class_path + file_path  # 拼出文件名全路径如:train_corpus/art/21.txt  
            content = readfile(fullname)  # 读取文件内容  
            '''''此时,content里面存贮的是原文本的所有字符,例如多余的空格、空行、回车等等, 
            接下来,我们需要把这些无关痛痒的字符统统去掉,变成只有标点符号做间隔的紧凑的文本内容 
            '''  
            content = content.replace("\r\n", "")  # 删除换行  
            content = content.replace(" ", "")#删除空行、多余的空格  
            content_seg = jieba.cut(content)  # 为文件内容分词  
            savefile(seg_dir + file_path, " ".join(content_seg))  # 将处理后的文件保存到分词后语料目录  
  
    print "中文语料分词结束!!!"  
  

if __name__=="__main__":  
    #对训练集进行分词  
    corpus_path = "./train/"  # 未分词分类语料库路径  
    seg_path = "./train_corpus_seg/"  # 分词后分类语料库路径,本程序输出结果  
    corpus_segment(corpus_path,seg_path)  
  
    # #对测试集进行分词  
    # corpus_path = "/home/appleyuchi/PycharmProjects/MultiNB/csdn_blog/54891204_tenwhy/chinese_text_classification-master/answer/"  # 未分词分类语料库路径  
    # seg_path = "/home/appleyuchi/PycharmProjects/MultiNB/csdn_blog/54891204_tenwhy/chinese_text_classification-master/test_corpus_seg/"  # 分词后分类语料库路径,本程序输出结果  
    # corpus_segment(corpus_path,seg_path)  

top.py

# #-*- coding:utf-8 -*-
# import sys
# reload(sys)
# sys.setdefaultencoding("utf-8")

import os
from gensim import corpora,models,similarities
folders="./train_corpus_seg/"
path="files/"
import jieba



#这个其实相当于搜索引擎(实际中是爬虫)
# 得到的各大网站的网页内容存储到一个个文件夹里面,
# 当用户搜索的时候,从文件夹里面搜索最相关文章匹配的链接返回给用户

file_list=[]
for folder in os.listdir(folders):#遍历所有类别的文件夹
    for file in os.listdir(folders+folder):
        file_list.append(file)




corpora_documents=[]
for folder in os.listdir(folders):#遍历所有类别的文件夹
    for file in os.listdir(folders+folder):#遍历每一类文件夹中的每个文件
        f=open(folders+folder+'/'+file)
        strs=f.read().replace('\n', '')#去掉回车键
        item_seg=strs.split()#根据空格保存分词后的结果
        corpora_documents.append(item_seg)


#下面部分代码来自[2]

# 生成字典和向量语料  
dictionary = corpora.Dictionary(corpora_documents)  
  
# 通过下面一句得到语料中每一篇文档对应的稀疏向量(这里是bow向量)  
corpus = [dictionary.doc2bow(text) for text in corpora_documents]  
# 向量的每一个元素代表了一个word在这篇文档中出现的次数  
# print(corpus)  
# corpora.MmCorpus.serialize('corpuse.mm',corpus)#保存生成的语料  
# corpus=corpora.MmCorpus('corpuse.mm')#加载  
  
# corpus是一个返回bow向量的迭代器。下面代码将完成对corpus中出现的每一个特征的IDF值的统计工作  
tfidf_model = models.TfidfModel(corpus)  
corpus_tfidf = tfidf_model[corpus]  


#根据关键词返回最相关的一篇文章(模仿搜索引擎)
def get_article(index):
    best_matchfile=file_list[index]
    for folder in os.listdir(folders):#遍历所有类别的文件夹
        for file in os.listdir(folders+folder):#遍历每一类文件夹中的每个文件
            if file==best_matchfile:
                f=open(folders+folder+'/'+file)
                strs=f.read().replace('\n', '')#去掉回车键
                return strs#返回最匹配的文章内容






question='邹家华 矿产'
print("-------------------下面是tfidf模型(第1个提问)----------------------------------------------------")

similarity = similarities.Similarity('Similarity-tfidf-index', corpus_tfidf,num_features=len(dictionary.dfs))
#注意这里的num_features如果随意改的话,可能会导致segmentation fault(原因不明).

test_data_1 = question
test_cut_raw_1 = list(jieba.cut(test_data_1))  # ['北京', '雾', '霾', '红色', '预警']
test_corpus_1 = dictionary.doc2bow(test_cut_raw_1)  # [(51, 1), (59, 1)],即在字典的56和60的地方出现重复的字段,这个值可能会变化
similarity.num_best = 5
test_corpus_tfidf_1 = tfidf_model[test_corpus_1]  # 根据之前训练生成的model,生成query的IFIDF值,然后进行相似度计算
# [(51, 0.7071067811865475), (59, 0.7071067811865475)]
print(similarity[test_corpus_tfidf_1])  # 返回最相似的样本材料,(index_of_document, similarity) tuples

best_match_article=get_article(similarity[test_corpus_tfidf_1][0][0])
print("搜索得到最匹配的文章是:",best_match_article)
 
 
print("-------------------下面是tfidf模型(第2个提问)----------------------------------------------------")
test_data_2 = question
test_cut_raw_2 = list(jieba.cut(test_data_2))
test_corpus_2 = dictionary.doc2bow(test_cut_raw_2)
test_corpus_tfidf_2 = tfidf_model[test_corpus_2]
similarity.num_best = 3
print(similarity[test_corpus_tfidf_2])  # 返回最相似的样本材料,(index_of_document, similarity) tuples
print("-------------------下面是LSI模型-----------------------------------")
# 使用LSI模型进行相似度计算
lsi = models.LsiModel(corpus_tfidf)
corpus_lsi = lsi[corpus_tfidf]
similarity_lsi = similarities.Similarity('Similarity-LSI-index', corpus_lsi, num_features=400, num_best=2)
# save
# LsiModel.load(fname, mmap='r')#加载
test_data_3 = question
test_cut_raw_3 = list(jieba.cut(test_data_3))  # 1.分词
test_corpus_3 = dictionary.doc2bow(test_cut_raw_3)  # 2.转换成bow向量(bow=bag of words)
test_corpus_tfidf_3 = tfidf_model[test_corpus_3]  # 3.计算tfidf值
test_corpus_lsi_3 = lsi[test_corpus_tfidf_3]  # 4.计算lsi值
# lsi.add_documents(test_corpus_lsi_3) #更新LSI的值
print(similarity_lsi[test_corpus_lsi_3])

 

 

 

 

 

### 回答1: Python 中有许多第三方库可用来计算文本相似度。常用的有: - `fuzzywuzzy`,它使用 Levenshtein 距离算法计算字符串之间相似度。 - `spaCy`,它使用 Cosine Similarity 算法计算文本之间相似度。 - `gensim` 中的 `doc2vec` 或 `word2vec`,它使用神经网络算法计算文本之间相似度。 需要注意的是,文本相似度并不是唯一的评估方法,具体使用哪个库和算法还要根据你的场景来决定。 ### 回答2: Python语言有很多用于匹配文本相似度的库和工具。其中最常用的包括difflib、fuzzywuzzy、nltk和gensim。 difflib库提供了一些类和方法用于比较和匹配文本字符串的差异程度,比如SeqMatcher类可以用来计算两个序列之间相似度,get_close_matches函数可以用来查找最接近的匹配项等。 fuzzywuzzy库是基于Levenshtein距离算法的文本匹配工具,可以衡量两个字符串之间的编辑距离,提供了一些模糊匹配的函数,如ratio函数用于计算两个字符串的相似程度,返回一个相似度百分比。 nltk库是一个自然语言处理工具包,其中包含了丰富的文本处理和匹配功能。它提供了一些用于标记文本计算词频、提取关键词、词干化和词向量化的函数和类。 gensim库是一个用于语义建模和相似度计算的库,它提供了一些算法和模型,如word2vec和doc2vec,可以用来将文本转换为向量表示,并计算向量之间相似度。 这些库与工具可以根据不同的文本相似度计算需求进行选择和使用。可以根据具体情况,选择合适的算法和模型,对文本进行预处理和特征提取,然后使用相应的函数和类进行相似度计算。 ### 回答3: Python中有多种方法来进行文本相似度的匹配,常用的方法包括以下几种: 1. 余弦相似度(Cosine Similarity):计算两个向量的夹角余弦值,值域在[-1, 1]之间。可以使用Python中的scipy库中的cosine函数来计算。 2. 编辑距离(Edit Distance):通过计算将一个字符串转换为另一个字符串所需的最少编辑操作次数来衡量文本之间相似度。可以使用Python中的Levenshtein库来计算编辑距离。 3. Jaccard相似度(Jaccard Similarity):计算两个集合的交集大小除以并集大小得到的相似度指标。可以使用Python中的set数据结构来计算。 4. 文本向量化(Text Vectorization):将文本转换为向量表示,常用的方法有词袋模型(Bag-of-Words)和TF-IDF。可以使用Python中的sklearn库中的CountVectorizer和TfidfVectorizer来实现。 除了这些常用的方法外,还有其他更复杂和高级的算法可以实现文本相似度匹配,如基于深度学习的模型(如BERT、Word2Vec等)和基于语义的模型(如WordNet、GloVe等),这些方法需要更复杂的模型和技术来实现。 总结起来,Python提供了多种库和工具来实现文本相似度匹配,可以根据具体需求选择合适的方法和算法来进行实现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值