⽤Python进⾏简单的⽂本相似度分析
学习⽬标:
1. 利⽤gensim包分析⽂档相似度
2. 使⽤jieba进⾏中⽂分词
3. 了解TF-IDF模型
环境:
Python 3.6.0 |Anaconda 4.3.1 (64-bit)
⼯具:
jupyter notebook
注:为了简化问题,本⽂没有剔除停⽤词“stop-word”。实际应⽤中应该要剔除停⽤词。
⾸先引⼊分词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]
编号与词之间的对应关系
{‘⼀个’: 4,玉和翡翠区别
‘上海’: 0,
‘不’: 1,
‘⼈’: 14,
‘北京’: 8,
‘和’: 15,
‘哪⾥’: 9,
‘喜欢’: 2,
‘在’: 10,
‘地⽅’: 5,
‘好’: 6,
‘好吃’: 11,
‘好玩’: 13,
‘⼩吃’: 17,
‘我’: 3,
‘是’: 7,桌面ie图标无法删除
‘的’: 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模型对语料库建模
tfidf = models.TfidfModel(corpus)
获取测试⽂档中,每个词的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的原理,看看是否符合预期。 最后总结⼀下⽂本相似度分析的步骤:
1. 读取⽂档
2. 对要计算的多篇⽂档进⾏分词
3. 对⽂档进⾏整理成指定格式,⽅便后续进⾏计算
4. 计算出词语的词频
5. 【可选】对词频低的词语进⾏过滤
6. 建⽴语料库词典
7. 加载要对⽐的⽂档
8. 将要对⽐的⽂档通过doc2bow转化为词袋模型
9. 对词袋模型进⾏进⼀步处理,得到新语料库
10. 将新语料库通过tfidfmodel进⾏处理,得到tfidf
11. 通过token2id得到特征数 12、稀疏矩阵相似度,从⽽建⽴索引 13、得到最终相似度结果
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论