多个文本对比相似度分析

该程序中和了多个网上的小程序,下面的介绍中会一一标明出处。
程序会用到多个python包,主要是docx,gensim和jieba还有xlwt,没有的话,通过pip安装
要注意安装docx包是pip install python-docx,不是docx。
导入包

import os
import numpy as np
import docx
import jieba
import re
import xlwt
from gensim import corpora,models,similarities

1,把文件夹的所有目标docx文档导入一个list中

每一篇的文档都被弄成一个元素,由于docx.paragraphs读取文档内容是一段一段读,所以要用一个循环,将文档中的每一段先合起来再写入list中。代码如下

     for para in f.paragraphs:
          text+=para.text
     text_final = re.sub("[\s+\.\!\/_,$%^*(+\"\')]+|[+——()?【】“”!,。?、:~@#¥%……&*();]+","",text)#用正则表达式去除目标文档中的文本中的标点符号
     s.append(text)#储存在s的列表中

文本导入list总的代码如下

path = "D:/QQFile/sx1" #文件夹目录
files= os.listdir(path) #得到文件夹下的所有文件名称
s=[]
doc_test=''
for file in files:
     f = docx.Document(path+"/"+file); #打开文件
     text=''
     for para in f.paragraphs:
          text+=para.text
     text_final = re.sub("[\s+\.\!\/_,$%^*(+\"\')]+|[+——()?【】“”!,。?、:~@#¥%……&*();]+","",text)#用正则表达式去除目标文档中的文本中的标点符号
     s.append(text_final)#储存在s的列表中

注解 1,为什么要循环设置text=’'空集,不是在循环外,因为这样每次循环才只会加载一篇文档的内容,循环一次即为清空text内容,加载文本,再循环,清空,再加载。要不然设置在循环外,就每次循环,都会把前面一次循环的得出的文本内容一起导入。
2,os读取文件夹中的所有文档名称,不是按照文件顺序读的,是会重新生成顺序。

同样的,把要对比的文档即检测文档也加载到另外一个list中

test=docx.Document('C:/Users/Administrator/Desktop/张绮雯.docx')
for test_para in test.paragraphs:
     doc_test+=test_para.text
doc_test_final=re.sub("[\s+\.\!\/_,$%^*(+\"\')]+|[+——()?【】“”!,。?、:~@#¥%……&*();]+","",doc_test)#用正则表达式去除想对比文档中的文本中的标点符号

将目标文档和检测文档都进行分词,分别存入all_doc_list和doc_test_list中

all_doc_list=[]
for doc in s:
     doc_list=[word for word in jieba.cut(doc)]
     all_doc_list.append(doc_list)#将目标文档用jieba分词,并储存在all_doc_list中
doc_test_list = [word for word in jieba.cut(doc_test_final)]#将要对比的文档用jieba分词,并储存在doc_test_list中

制作语料库

首先用dictionary方法获取词袋(bag-of-words),在这其中,词袋会对所有词进行编号,并且与次之间斗个对应的关系。

dictionary = corpora.Dictionary(all_doc_list)

以下使用doc2bow制作语料库,生产的语料库是一组向量,向量中的元素是一个二元组(编号、频次数),对应分词后的文档中的每一个词。

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

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

doc_test_vec = dictionary.doc2bow(doc_test_list)

相似度分析

这块参考(https://blog.csdn.net/xiexf189/article/details/79092629)
使用TF-IDF模型对语料库建模

tfidf = models.TfidfModel(corpus)

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

tfidf[doc_test_vec]

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

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

根据相似度排序(这行代码在这次的实际程序中并没有用到,因为要编入excel表中,就不需要排序了)

sorted(enumerate(sim), key=lambda item: -item[1])#正序排列,最大在前。

将对比出的相似度生成excel表格并保存

这块参考(https://blog.csdn.net/qq_38839677/article/details/82151646)

xls=xlwt.Workbook()
sht1=xls.add_sheet('sheet1')
file_studentname=[]
for studentname in files:
     studentnames=re.sub(".docx","",studentname)
     file_studentname.append(studentnames)
for i,filename,_similarities in zip(np.arange(len(files)),file_studentname,sim):
     sht1.write(int(i),0,filename)
     sht1.write(int(i),1,str(_similarities))#这里要把i变成整形还有_similarities变成字符串
xls.save('/Users/Administrator/Desktop/相似度.xls')

sht1.write(int(i),1,str(_similarities))
这里为什么要把i变成整形还有_similarities变成字符串,因为那个生成出的sim是个数组,添加不进表格,所以要转换成str,不能转换成int整形,因为这样相似度就要么是0 要么是1了。i要变成整形,是因为从arange出来是一个字符串数字,但那里要表示的是表格中的坐标,所以要是数字,所以转换成整形数。

另外,for i,filename,_similarities in zip(np.arange(len(files)),file_studentname,sim)
这句循环也让我知道同时进行多步循环可以用zip函数,但记住,zip中的参数一定得是list,因为这样才能生成列表,这样才可以循环迭代。参看这个(https://blog.csdn.net/Gsdxiaohei/article/details/81701957)

在for i,filename,_similarities in zip(np.arange(len(files)),file_studentname,sim)中,第一个要加np.arange(),这样才能生成列表。
生成列表有两种方法
上下两个结果一样

for n in range(1,10):
    print(n)
print(list(range(1,10)))

结果:
1
2
3
4
5
6
7
8
9
[1, 2, 3, 4, 5, 6, 7, 8, 9]
也可以换一种方法:

import numpy as np
a=np.arange(1,10)
print(a)

结果为:
[1 2 3 4 5 6 7 8 9]
两种结果里面的数都是整形。

总代码如下

import os
import numpy as np
import docx
import jieba
import re
import xlwt
from gensim import corpora,models,similarities
path = "D:/QQFile/sx1"
files= os.listdir(path)
s=[]
doc_test=''
for file in files:
     f = docx.Document(path+"/"+file)
     text=''
     for para in f.paragraphs:
          text+=para.text
     text_final = re.sub("[\s+\.\!\/_,$%^*(+\"\')]+|[+——()?【】“”!,。?、:~@#¥%……&*();]+","",text)
     s.append(text_final)
test=docx.Document('C:/Users/Administrator/Desktop/张绮雯.docx')
for test_para in test.paragraphs:
     doc_test+=test_para.text
doc_test_final=re.sub("[\s+\.\!\/_,$%^*(+\"\')]+|[+——()?【】“”!,。?、:~@#¥%……&*();]+","",doc_test)
all_doc_list=[]
for doc in s:
     doc_list=[word for word in jieba.cut(doc)]
     all_doc_list.append(doc_list)
doc_test_list = [word for word in jieba.cut(doc_test_final)]

dictionary = corpora.Dictionary(all_doc_list)
corpus = [dictionary.doc2bow(doc) for doc in all_doc_list]
doc_test_vec = dictionary.doc2bow(doc_test_list)
tfidf = models.TfidfModel(corpus)
tfidf[doc_test_vec]
index = similarities.SparseMatrixSimilarity(tfidf[corpus], num_features=len(dictionary.keys()))
sim = index[tfidf[doc_test_vec]]
#sorted(enumerate(sim), key=lambda item: -item[1])
xls=xlwt.Workbook()
sht1=xls.add_sheet('sheet1')
file_studentname=[]
for studentname in files:
     studentnames=re.sub(".docx","",studentname)
     file_studentname.append(studentnames)
for i,filename,_similarities in zip(np.arange(len(files)),file_studentname,sim):
     sht1.write(int(i),0,filename)
     sht1.write(int(i),1,str(_similarities))
xls.save('/Users/Administrator/Desktop/相似度.xls')

运行结果如下:
代码结果

  • 2
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值