- 对语料库分词,并统计词频(去掉common-words)。输入目标词语计算出相关度高的前十文本,并考虑算法耗时问题。数据在下面连接父目录下(cranfield.tar.gz为语料库需要解压):
代码
module
- os
获取解压的所有文件名称 - nltk
用到textobject,创建一个自己的textObject,并用该对象的内置方法统计每个word的频次。 - re
nltk模块分词并不完全符合要求,利用re的正则匹配方法进一步提取word。 - pandas
创建时间序列的数据,并用Series类的方法,整理结果数据。 - time
计算运行时间 - matplotlib
作图module - numpy
数值计算模块,用到均值、求和以及随机抽样函数
function
wordCountDict
建立2层嵌套的字典,最外层key为提取的word对应的value是一个字典,该字典的key为文件名称,value为该文件出现最外层key对应的word的频数(>=1)。统计仅仅由数值和字母构成的word且不包括stopwords,结果用于下面函数。searchRelativePaper
给处几个关键单词,统计出现这些单词的在每篇文章中出现的频数之和,降序排列结果,给出前10的文章文件夹名称。statQueryTime
统计不同查询关键字个数与查询时间花费之间关系,采取又放回的10次随机抽样期望代替目标值。
love & life为例查询top10-DOC
1 | cranfield0640 | 4 |
---|---|---|
2 | cranfield0768 | 3 |
3 | cranfield0727 | 2 |
4 | cranfield0865 | 1 |
5 | cranfield0482 | 1 |
6 | cranfield0724 | 1 |
7 | cranfield0844 | 1 |
8 | cranfield0658 | 1 |
9 | cranfield0909 | 1 |
10 | cranfield1352 | 1 |
后10 应该均为0没有统计意义
bottom 10 & top 10
bottom | count | top | count |
---|---|---|---|
ob | 1.0 | flow | 1732 |
nullify | 1.0 | pressure | 1120 |
inadmissable | 1.0 | number | 964 |
lina | 1.0 | results | 885 |
806 | 1.0 | boundary | 880 |
608 | 1.0 | mach | 813 |
shallower | 1.0 | theory | 777 |
cracking | 1.0 | layer | 720 |
objectionable | 1.0 | method | 674 |
428 | 1.0 | surface | 554.0 |
不仅仅这10个出现一次,因此这10个word不是唯一的答案。
words在campus出现频数统计histogram
word出现频率最高的为1750次,几乎所有word频都小于250次,因此进一步考虑去值小于250的直方图如下:
数据明显还是集中在50,因此进一步看小于50样本频数直方图:
总结:绝大部分部分word频数小于5次,很少一部分部分频数取值在[50,250],极少大于250,单词最大频数为1732。
统计查询时间与查询词语个数之间关系
统查询结果最大值为0(没有)、极少(出现次数之和 x : 0 < x <= 1 * n , n为给处关键字的个数), 多( x > 3 * n)
num of words | empty | little | many |
---|---|---|---|
1 | 0.00110281 | 0.00227954 | 0.00209611 |
2 | 0.0009027 | 0.00309847 | 0.003008 |
3 | 0.000802159 | 0.00382876 | 0.00483092 |
- empty(没有)、little(极少)、many(很多)这三者查询时间呈现一个递增关系。
- 当总查询结果为empty时, 查询时间和输入关键字个数影响关系可以忽略。另外两种情况,都会随着查询关键字个数的提升,查询时间明显增加。
余弦相似度计算相似性
在上面统计词频的基础上,利用前1000个高频词汇构建每篇文章的特征向量。然后利用余弦相似度计算query词汇与每篇文章的相似度(tutorial-11assignment3.pdf在github pool目录下,介绍了如何构建特征向量以及余弦相识度计算公式)。
代码
下面分别用两组代码检测:query: ['flow', 'number', 'layer']的结果:
结果now | 余弦相似度 | 结果before | 频数 |
---|---|---|---|
cranfield0050 | 0.281713 | cranfield0329 | 22.0 |
cranfield0899 | 0.271514 | cranfield1313 | 19.0 |
cranfield1302 | 0.256463 | cranfield0189 | 16.0 |
cranfield0335 | 0.255768 | cranfield0089 | 15.0 |
cranfield0343 | 0.254294 | cranfield0310 | 14.0 |
cranfield0668 | 0.238295 | cranfield0710 | 13.0 |
cranfield0192 | 0.235588 | cranfield1351 | 13.0 |
cranfield0004 | 0.234459 | cranfield0798 | 13.0 |
cranfield0310 | 0.231961 | cranfield1244 | 13.0 |
cranfield0089 | 0.231217 | cranfield0996 | 13.0 |
-
耗时:
词频统计:0.005005836486816406
余弦相似: 0.559490442276001 - 结论
两者方法结果出入很大,且查询时间后者是前者的100倍。但根据余弦相似度计算更科学,例如,A,B两篇文章都包含共同的查询词汇,但是A的词汇量远远高于B,那么A根据总体词汇频数统计大于B的可能很大,但是这并不是合理的,相反B与query词汇的相似度才高,利用余弦相似度很好解决了这点。