本文的目标是先熟悉文本相似度比较的流程,初衷前文也提过了主要是为了比较两个不同的地址体系,避免纯人工干预,相信论文查重也是部分利用这一原理,当然我对这些package未必理解,先解决会用能解决问题吧。

后续会继续拿神雕三部曲来做示范,把相关流程组装起来。

用Python进行简单的文本相似度分析

使用jieba进行中文分词

利用gensim包分析文档相似度

  通过corpora.Dictionary创建预料特征

  通过dictionary.doc2bow转换成稀疏矩阵

  通过models.TfidfModel完成tfidf统计

  通过similarities.SparseMatrixSimilarity进行文档相似度比较

代码示例

  1. #"""

  2. #用Python进行简单的文本相似度分析

  3. #使用jieba进行中文分词

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

  5. # 通过corpora.Dictionary创建预料特征

  6. # 通过dictionary.doc2bow转换成稀疏矩阵

  7. # 通过models.TfidfModel完成tfidf统计

  8. # 通过similarities.SparseMatrixSimilarity进行文档相似度比较

  9. import matplotlib

  10. import numpy as np

  11. import jieba

  12. from gensim import corpora,models,similarities

  13. from matplotlib import pyplot as plt

  14. #完成数据初始化工作

  15. doc0 = "海南省金江口花园"

  16. doc1 = "海南省海口市金江口花园"

  17. doc2 = "海南省海口市海甸二西路金江口花园"

  18. doc3 = "金江口花园小区"

  19. doc4 = "金江小区"

  20. doc5 = "海甸二西路"

  21. doc6 = "我住在金江口花园"

  22. doc7 = "金江口花园好玩吗"

  23. doc_test="金江口花园"

  24. #初始化数组,方便后续处理

  25. all_doc = []

  26. all_doc.append(doc0)

  27. all_doc.append(doc1)

  28. all_doc.append(doc2)

  29. all_doc.append(doc3)

  30. all_doc.append(doc4)

  31. all_doc.append(doc5)

  32. all_doc.append(doc6)

  33. all_doc.append(doc7)

  34. print(all_doc)

  35. #all_doc= ['海南省金江口花园', '海南省海口市金江口花园', '海南省海口市海甸二西路金江口花园', '金江口花园小区', '金江小区', '海甸二西路', '我住在金江口花园', '金江口花园好玩吗']

  36. #初始化分词后的数组

  37. all_doc_list = []

  38. #需要对个别词进行自定义词典

  39. jieba.add_word('金江口')

  40. for doc in all_doc:

  41. doc_list = [word for word in jieba.cut(doc)]

  42. all_doc_list.append(doc_list)

  43. #all_doc_list= <class 'list'>:

  44. # [['海南省', '金江口', '花园'],

  45. # ['海南省', '海口市', '金江口', '花园'],

  46. # ['海南省', '海口市', '海甸二', '西路', '金江口', '花园'],

  47. # ['金江口', '花园', '小区'],

  48. # ['金江', '小区'],

  49. # ['海甸二', '西路'],

  50. # ['我', '住', '在', '金江口', '花园'],

  51. # ['金江口', '花园', '好玩', '吗']]

  52. #对目标文章进行分词

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

  54. print('doc_test_list=',doc_test_list)

  55. #doc_test_list= ['金江口', '花园']

  56. #doc_test_list= ['金', '江口', '花园']

  57. #调用Gensim提供的API建立语料特征(此处即是word)的索引字典

  58. # texts就是若干个被拆成单词集合的文档的集合

  59. # dictionary就是把所有单词取一个set()

  60. # 并对set中每个单词分配一个Id号的map;

  61. dictionary = corpora.Dictionary(all_doc_list)

  62. print('dictionary=',dictionary)

  63. #dictionary= Dictionary(13 unique tokens: ['海南省', '花园', '金江口', '海口市', '海甸二']...)

  64. #dictionary= Dictionary(14 unique tokens: ['江口', '海南省', '花园', '金', '海口市']...)

  65. #打印语料特征索引字典的key

  66. print('dictionary.keys=',dictionary.keys())

  67. #dictionary.keys= [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]

  68. #dictionary.keys= [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]

  69. #打印语料特征索引字典内容

  70. print('dictionary.token2id=',dictionary.token2id)

  71. #dictionary.token2id= {'海南省': 0, '花园': 1, '金江口': 2, '海口市': 3, '海甸二': 4, '西路': 5, '小区': 6, '金江': 7, '住': 8, '在': 9, '我': 10, '吗': 11, '好玩': 12}

  72. #dictionary.token2id= {'江口': 0, '海南省': 1, '花园': 2, '金': 3, '海口市': 4, '海甸二': 5, '西路': 6, '小区': 7, '金江': 8, '住': 9, '在': 10, '我': 11, '吗': 12, '好玩': 13}

  73. #dictionary.doc2bow(doc)是把源文档 doc变成一个稀疏向量,[(0, 1), (1, 1)],表明id0,1的词汇出现了1次,至于其他词汇,没有出现。

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

  75. print('corpus=',corpus)

  76. #corpus= [[(0, 1), (1, 1), (2, 1)], [(0, 1), (1, 1), (2, 1), (3, 1)], [(0, 1), (1, 1), (2, 1), (3, 1), (4, 1), (5, 1)], [(1, 1), (2, 1), (6, 1)], [(6, 1), (7, 1)], [(4, 1), (5, 1)], [(1, 1), (2, 1), (8, 1), (9, 1), (10, 1)], [(1, 1), (2, 1), (11, 1), (12, 1)]]

  77. #corpus= [[(0, 1), (1, 1), (2, 1), (3, 1)], [(0, 1), (1, 1), (2, 1), (3, 1), (4, 1)], [(0, 1), (1, 1), (2, 1), (3, 1), (4, 1), (5, 1), (6, 1)], [(0, 1), (2, 1), (3, 1), (7, 1)], [(7, 1), (8, 1)], [(5, 1), (6, 1)], [(0, 1), (2, 1), (3, 1), (9, 1), (10, 1), (11, 1)], [(0, 1), (2, 1), (3, 1), (12, 1), (13, 1)]]

  78. #dictionary.doc2bow(doc)是把目标文档 doc变成一个稀疏向量,[(0, 1), (1, 1)],表明id0,1的词汇出现了1次,至于其他词汇,没有出现。

  79. doc_test_vec = dictionary.doc2bow(doc_test_list)

  80. print('doc_test_vec=',doc_test_vec)

  81. #doc_test_vec= [(1, 1), (2, 1)]

  82. #doc_test_vec= [(0, 1), (2, 1), (3, 1)]

  83. # corpus是一个返回bow向量的迭代器。

  84. # 下面将完成对corpus中出现的每一个特征的IDF值的统计工作,对源文档

  85. tfidf = models.TfidfModel(corpus)

  86. corpus_tfidf = tfidf[corpus]

  87. print('tfidf=',tfidf)

  88. #tfidf= TfidfModel(num_docs=8, num_nnz=29)

  89. #tfidf= TfidfModel(num_docs=8, num_nnz=35)

  90. print('tfidf[doc_test_vec]=',tfidf[doc_test_vec])

  91. #tfidf[doc_test_vec]= [(1, 0.7071067811865476), (2, 0.7071067811865476)]

  92. #tfidf[doc_test_vec]= [(0, 0.5773502691896257), (2, 0.5773502691896257), (3, 0.5773502691896257)]

  93. #查看model中的内容

  94. for item in corpus_tfidf:

  95. print(item)

  96. # 下面将完成对corpus中出现的每一个特征的IDF值的统计工作,对目标文档

  97. print('tfidf[doc_test_vec]=',tfidf[doc_test_vec])

  98. #tfidf[doc_test_vec]= [(1, 0.7071067811865476), (2, 0.7071067811865476)]

  99. #tfidf[doc_test_vec]= [(0, 0.5773502691896257), (2, 0.5773502691896257), (3, 0.5773502691896257)]

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

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

  102. sim = index[tfidf[doc_test_vec]]

  103. print('index=',index)

  104. #index= <gensim.similarities.docsim.SparseMatrixSimilarity object at 0x00000167D46412B0>

  105. #index= <gensim.similarities.docsim.SparseMatrixSimilarity object at 0x0000028C96C922B0>

  106. print('sim=',sim)

  107. #sim= [0.38314244 0.23298258 0.15496162 0.28159946 0. 0. 0.11224506 0.1370406 ]

  108. #sim= [0.45292395 0.2815491 0.18865925 0.33824706 0. 0. 0.1370406 0.16705726]

  109. #按顺序打印相似度的文档

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

  111. #[(0, 0.38314244), (3, 0.28159946), (1, 0.23298258), (2, 0.15496162), (7, 0.1370406), (6, 0.11224506), (4, 0.0), (5, 0.0)]

  112. #[(0, 0.45292395), (3, 0.33824706), (1, 0.2815491), (2, 0.18865925), (7, 0.16705726), (6, 0.1370406), (4, 0.0), (5, 0.0)]

  113. fig,ax=plt.subplots()

  114. pos=np.arange(0,len(all_doc)) #pos= [0 1 2 3 4 5 6 7]

  115. xlabel=['第'+str(x+1)+'行' for x in range(len(all_doc))]

  116. #xlabel= ['第1章', '第2章', '第3章', '第4章', '第5章', '第6章', '第7章', '第8章']

  117. matplotlib.rcParams['font.sans-serif']=['SimHei'] # 用黑体显示中文

  118. matplotlib.rcParams['axes.unicode_minus']=False # 正常显示负号

  119. ax.bar(pos,sim,0.5)

  120. ax.set_xticks(range(len(xlabel)))

  121. ax.set_xticklabels(xlabel)

  122. plt.xticks(rotation=90) # 将字体进行旋转

  123. plt.show()

  124. # 文章相似度比较的步骤和流程

  125. # 1、读取文档

  126. # 2 对要计算的多篇文档进行分词

  127. # 3、对文档进行整理成指定格式,方便后续进行计算

  128. # 4、计算出词语的词频

  129. # 5、【可选】对词频低的词语进行过滤

  130. # 6、建立语料库词典

  131. # 7、加载要对比的文档

  132. # 8、将要对比的文档通过doc2bow转化为词袋模型

  133. # 9、对词袋模型进行进一步处理,得到新语料库

  134. # 10、将新语料库通过tfidfmodel进行处理,得到tfidf

  135. # 11、通过token2id得到特征数

  136. # 12、稀疏矩阵相似度,从而建立索引

  137. # 13、得到最终相似度结果

关于词云可视化笔记七(文本相似度比较流程)_相似度