Skip to content

L1Uc/SentenceSimilarity

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

19 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SentenceSimilarity 中文句子相似度评分

基于Gensim库函数实现LSI,LDA,TF-IDF+余弦距离等方法

数据预处理

  • 原本的数据集是 标签 句子一 句子二 的形式,而计算相似度时暂时不需要使用标签,且需要两个句子分别在两个文件中(因为LSI和LDA都是主题模型,需要一部分句子做训练集,另一部分做测试集)。所以先写了 predata.py 对初始数据集进行预处理,将原有的数据集切分成 label ,sentence1 和 sentence2 三个部分,并分别存在三个txt文件中备用。

  • 在运行过程中发现原数据集过大(32万对句子),导致切分时间太长,同时考虑到后续程序的运行时间,选取8000对句子和16000对句子形成一个较小的数据集,再进行切分。

计算句子相似度

  • 分词的功能是使用 jieba 完成的,在其基础上加了一次封装,增加了去除停用词的功能,使分词的结果更为精确,易于分析。 Jieba 分词有三种模式,这里由于是句子,且语料和使用搜索引擎时的语料较为相似,所以在调用的时候使用了搜索引擎模式。

  • 定义一个SentenceSimilarity类,将删除低频词和自定义各个模型(如LSI和LDA)以及计算句子相似度的功能都写在这个类中,方便主函数直接调用。求句子相似度的函数(mysimilarity)直接将index函数的结果返回,在主函数中对相似度的打分进行排序和筛选并输出。这里有一点,因为测试集中的句子每一百句都是相同的,所以每一百句只需要计算一次相似度。

  • 排序之后选择和每一个句子相似度最高的前五个或第一个句子的id和得分进行输出,将它们存入 result.txt 中,便于后续的比较和计算。

选择5个句子输出:

for i in range(0,len(train_sentences)/100):
    mysims = ss.mysimilarity(test1_sentences[i*100])
    # 每一百行为一个整体
    sims_divided = mysims[i*100:(i+1)*100]
    # 对一百行内的相似度进行排序
    sort_sims = sorted(enumerate(sims_divided),key = lambda item : -item[1])
    # 选择前五个最高的相似度进行输出
    chosen_sims = sort_sims[:5]
    for j in range(0,5):
        print str(chosen_sims[j][0]) + " score:" + str(chosen_sims[j][1])

选择1个句子输出:

for i in range(0, len(train_sentences) / 100):
    mysims = ss.mysimilarity(test1_sentences[i * 100])
    # 每一百行为一个整体
    sims_divided = mysims[i * 100:(i + 1) * 100]
    # 对一百行内的相似度进行排序
    sort_sims = sorted(enumerate(sims_divided), key=lambda item: -item[1])
    # 选择相似度最高的进行输出
    chosen_sims = sort_sims[0]
    print str(chosen_sims[0]) + " score:" + str(chosen_sims[1])

计算准确率

  • evaluate.py 中,读入result和label文件中的内容,筛选出label中相关性为1的id,再计算出result中句子在全部句子中的id(因为之前输出的id范围都是0-100),比较得出这两个列表中相同的id数量,再除以(5*组数)就得到了平均的正确率。

存储格式转换

  • 在每次使用一百对句子建模时,遇到了批量转换txt文件编码的问题,遂写了 convert2utf-8.py 对160个txt文件进行编码格式的转换。这里的160个txt文件是用 predata2.py 切分出来的。

windows下运行

  1. 在命令行中 cd 到对应文件夹下,使用 python2 运行 demo.py
  2. 将所得结果保存至 result.txt
  3. 修改 evaluate.py 中的文件路径和文件名,使之与步骤2中存入的文件名一致
  4. 使用 python2 运行 evaluate.py,得到结果

结果分析

LSI和LDA实际上是主题模型,因此它们更适合于文章的相似度分析。从训练语料中得出几个主题,然后分析测试集和哪几个主题的关系最大,以此判断文章的相似度。所以用它们来做句子层面的相似度分析时难免正确率不高。而且由于它们主题模型的特性,训练集中不相关的语料越多,得到的主题数就越多,精确度就会降低,这正是使用了更大的数据量之后正确率反而降低了的原因。

从时间上来看,对两个模型来说,16000对句子所消耗的时间大致为8000对句子的两倍。而当我们对每一百对句子进行建模时,所用的时间是直接对8000对句子进行建模的18倍左右,这是因为后者只需要进行一次建模,而前者需要进行80次建模。但是从正确率来看,一百对句子独立建模比8000对句子直接建模的正确率提高了将近3个百分点,这也印证了数据量越大正确率越低的观点。

Todo

完成大数据集中相似度最高的句子检索功能

将几种不同数据量和模型的文件整合

About

中文句子相似度评分

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Languages