该程序中和了多个网上的小程序,下面的介绍中会一一标明出处。
程序会用到多个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)
相似度分析
这块参考()
使用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表格并保存
这块参考()
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,因为这样才能生成列表,这样才可以循环迭代。参看这个()
在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')
运行结果如下: