如何识别“答非所问”?使用gensim进行文本相似度计算

简介:

在文本处理中,比如商品评论挖掘,有时需要了解每个评论分别和商品的描述之间的相似度,以此衡量评论的客观性。

评论和商品描述的相似度越高,说明评论的用语比较官方,不带太多感情色彩,比较注重描述商品的属性和特性,角度更客观。

再比如知乎、贴吧等问答社区内问题下面有很多回复者,如何快速过滤掉与问题无关的回答或者垃圾广告??

那么Python 里面有计算文本相似度的程序包吗,恭喜你,不仅有,而且很好很强大。

使用gensim进行文本相似度计算

原理

1、文本相似度计算的需求始于搜索引擎。

搜索引擎需要计算“用户查询”和爬下来的众多”网页“之间的相似度,从而把最相似的排在最前返回给用户。

2、主要使用的算法是tf-idf

tf:term frequency 词频

idf:inverse document frequency 倒文档频率

主要思想是:如果某个词或短语在一篇文章中出现的频率高,并且在其他文章中很少出现,则认为此词或者短语具有很好的类别区分能力,适合用来分类。

第一步:把每个网页文本分词,成为词包(bag of words)。

第三步:统计网页(文档)总数M。

第三步:统计第一个网页词数N,计算第一个网页第一个词在该网页中出现的次数n,再找出该词在所有文档中出现的次数m。则该词的tf-idf 为:n/N * 1/(m/M) (还有其它的归一化公式,这里是最基本最直观的公式)

第四步:重复第三步,计算出一个网页所有词的tf-idf 值。

第五步:重复第四步,计算出所有网页每个词的tf-idf 值。

3、处理用户查询

第一步:对用户查询进行分词。

第二步:根据网页库(文档)的数据,计算用户查询中每个词的tf-idf 值。

4、相似度的计算

使用余弦相似度来计算用户查询和每个网页之间的夹角。夹角越小,越相似。

学习目标:

  1. 利用gensim包分析文档相似度

  2. 使用jieba进行中文分词

  3. 了解TF-IDF模型

注:为了简化问题,本文没有剔除停用词“stop-word”。实际应用中应该要剔除停用词。

安装相关包

pip install jieba

pip install gensim

关于结巴分词,这里推荐

https://github.com/WenDesi/zhcnSegment

已经将主要功能封装好,包括添加自定义语料,添加停用词等,简单、易调用

首先引入分词API库jieba、文本相似度库gensim


import jieba
from gensim import corpora,models,similarities

以下doc0-doc7是几个最简单的文档,我们可以称之为目标文档,本文就是分析doc_test(测试文档)与以上8个文档的相似度。


doc0 = "我不喜欢上海"

doc1 = "上海是一个好地方"

doc2 = "北京是一个好地方"

doc3 = "上海好吃的在哪里"

doc4 = "上海好玩的在哪里"

doc5 = "上海是好地方"

doc6 = "上海路和上海人"

doc7 = "喜欢小吃"

doc_test="我喜欢上海的小吃"

分词

首先,为了简化操作,把目标文档放到一个列表all_doc中。


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_list中


all_doc_list = []for doc in all_doc:
doc_list = [word for word in jieba.cut(doc)]
all_doc_list.append(doc_list)

把分词后形成的列表显示出来:

print(all_doc_list)

[[‘我’, ‘不’, ‘喜欢’, ‘上海’],
[‘上海’, ‘是’, ‘一个’, ‘好’, ‘地方’],
[‘北京’, ‘是’, ‘一个’, ‘好’, ‘地方’],
[‘上海’, ‘好吃’, ‘的’, ‘在’, ‘哪里’],
[‘上海’, ‘好玩’, ‘的’, ‘在’, ‘哪里’],
[‘上海’, ‘是’, ‘好’, ‘地方’],
[‘上海’, ‘路’, ‘和’, ‘上海’, ‘人’],
[‘喜欢’, ‘小吃’]]

以下把测试文档也进行分词,并保存在列表doc_test_list中


doc_test_list = [word for word in jieba.cut(doc_test)]
doc_test_list

[‘我’, ‘喜欢’, ‘上海’, ‘的’, ‘小吃’]

制作语料库

首先用dictionary方法获取词袋(bag-of-words)

dictionary = corpora.Dictionary(all_doc_list)

词袋中用数字对所有词进行了编号

dictionary.keys()

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17]

编号与词之间的对应关系

dictionary.token2id

{‘一个’: 4,
‘上海’: 0,
‘不’: 1,
‘人’: 14,
‘北京’: 8,
‘和’: 15,
‘哪里’: 9,
‘喜欢’: 2,
‘在’: 10,
‘地方’: 5,
‘好’: 6,
‘好吃’: 11,
‘好玩’: 13,
‘小吃’: 17,
‘我’: 3,
‘是’: 7,
‘的’: 12,
‘路’: 16}

以下使用doc2bow制作语料库


corpus = [dictionary.doc2bow(doc)
for doc in all_doc_list]

语料库如下。语料库是一组向量,向量中的元素是一个二元组(编号、频次数),对应分词后的文档中的每一个词。

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

以下用同样的方法,把测试文档也转换为二元组的向量


doc_test_vec = dictionary.doc2bow(doc_test_list)
doc_test_vec

[(0, 1), (2, 1), (3, 1), (12, 1), (17, 1)]

相似度分析

使用TF-IDF模型对语料库建模。

gensim包提供了这几个模型: TF-IDF、LSI 、LDA

因此我们直接拿来用就好


tfidf = models.TfidfModel(corpus)

#models.LsiModel()

#models.LdaModel()

获取测试文档中,每个词的TF-IDF值

tfidf[doc_test_vec]

[(0, 0.08112725037593049),
(2, 0.3909393754390612),
(3, 0.5864090631585919),
(12, 0.3909393754390612),
(17, 0.5864090631585919)]

对每个目标文档,分析测试文档的相似度


index = similarities.SparseMatrixSimilarity(tfidf[corpus],
num_features=len(dictionary.keys()))
sim = index[tfidf[doc_test_vec]]
sim


array([ 0.54680777, 0.01055349, 0. , 0.17724207, 0.17724207,
0.01354522, 0.01279765, 0.70477605], dtype=float32)

根据相似度排序

sorted(enumerate(sim), key=lambda item: -item[1])

[(7, 0.70477605),
(0, 0.54680777),
(3, 0.17724207),
(4, 0.17724207),
(5, 0.013545224),
(6, 0.01279765),
(1, 0.010553493),
(2, 0.0)]

从分析结果来看,测试文档与doc7相似度最高,其次是doc0,与doc2的相似度为零。大家可以根据TF-IDF的原理,看看是否符合预期。


原文发布时间为:2018-09-6

本文来自云栖社区合作伙伴“大数据挖掘DT机器学习”,了解相关信息可以关注“大数据挖掘DT机器学习”。

相关文章
|
4月前
|
机器学习/深度学习 人工智能 自然语言处理
基于非英语数据集的图形机器学习和集成学习方法增强文本分类和文本情感分析
基于非英语数据集的图形机器学习和集成学习方法增强文本分类和文本情感分析 摘要 近年来,机器学习方法,特别是图学习方法,在自然语言处理领域,特别是文本分类任务中取得了巨大的成果。然而,许多这样的模型在不同语言的数据集上显示出有限的泛化能力。在本研究中,我们在非英语数据集(如波斯语Digikala数据集)上研究并阐述了图形机器学习方法,该方法由用户对文本分类任务的意见组成。更具体地说,我们研究了(Pars)BERT与各种图神经网络(GNN)架构(如GCN、GAT和GIN)的不同组合,并使用集成学习方法来处理某些知名的非英语数据集上的文本分类任务。我们的分析和结果表明,应用GNN模型可以更好地捕捉文
58 0
|
2月前
|
机器学习/深度学习 自然语言处理 数据挖掘
Python数据分析中文本分析的重要技术点,包括文本预处理、特征提取、情感分析
Python数据分析中文本分析的重要技术点,包括文本预处理、特征提取、情感分析
73 1
Python数据分析中文本分析的重要技术点,包括文本预处理、特征提取、情感分析
|
2月前
|
自然语言处理 Python
【Python自然语言处理】文本向量化的六种常见模型讲解(独热编码、词袋模型、词频-逆文档频率模型、N元模型、单词-向量模型、文档-向量模型)
【Python自然语言处理】文本向量化的六种常见模型讲解(独热编码、词袋模型、词频-逆文档频率模型、N元模型、单词-向量模型、文档-向量模型)
90 0
|
2月前
|
机器学习/深度学习 算法 数据挖掘
【Python机器学习】K-Means算法对人脸图像进行聚类实战(附源码和数据集)
【Python机器学习】K-Means算法对人脸图像进行聚类实战(附源码和数据集)
43 0
|
7月前
|
人工智能 自然语言处理 算法
基于知识图谱的电影知识问答系统:训练TF-IDF 向量算法和朴素贝叶斯分类器、在 Neo4j 中查询
基于知识图谱的电影知识问答系统:训练TF-IDF 向量算法和朴素贝叶斯分类器、在 Neo4j 中查询
基于知识图谱的电影知识问答系统:训练TF-IDF 向量算法和朴素贝叶斯分类器、在 Neo4j 中查询
|
机器学习/深度学习 算法
基于机器学习knn算法的手写拼音识别
基于机器学习knn算法的手写拼音识别
82 0
基于机器学习knn算法的手写拼音识别
|
算法 数据可视化 IDE
基于 python 实现朴素贝叶斯分类-决策树-PCA人脸识别
基于 python 实现朴素贝叶斯分类-决策树-PCA人脸识别
196 0
基于 python 实现朴素贝叶斯分类-决策树-PCA人脸识别
|
机器学习/深度学习 算法 大数据
秒懂算法 | MNIST手写体识别
来源于谷歌的TensorFlow是目前Python编程领域最热门的深度学习框架。Google不仅是大数据和云计算的领导者,在机器学习和深度学习上也有很好的实践和积累,在2015年年底开源了内部使用的深度学习框架TensorFlow。
178 0
秒懂算法  | MNIST手写体识别
|
机器学习/深度学习 计算机视觉
使用python3.7和opencv4.1来实现人脸识别和人脸特征比对以及模型训练
OpenCV4.1已经发布将近一年了,其人脸识别速度和性能有了一定的提高,这里我们使用opencv来做一个实时活体面部识别的demo
使用python3.7和opencv4.1来实现人脸识别和人脸特征比对以及模型训练
|
机器学习/深度学习 自然语言处理 算法
SnowNLP使用自定义语料进行模型训练(情感分析)
SnowNLP使用自定义语料进行模型训练(情感分析)
938 1
SnowNLP使用自定义语料进行模型训练(情感分析)

相关产品