如何比较两个大文本之间的度量 - 余弦,Jaccard相似度,Sim_MinEdit(Sim_String)和Python中的Sim_Simple

时间:2018-02-28 17:58:31

标签: python nlp

我正在研究文本分析项目,一次比较两个不同的报告,并将结果保存到pandas数据框中。

我能够获得余弦和jacard的相似之处,但需要确保我得到正确的措施。作为参数,我使用位于给定文件夹的文件名。

对于cosine_sim,我使用以下代码:

import re, math
from collections import Counter

WORD = re.compile(r'\w+')

def text_to_vector(text):
     words = WORD.findall(text)
     return Counter(words)

def get_cosine(file1, file2):
    t1 = file(Input_path+'/'+file1).read().replace('\n',' ')
    t2 = file(Input_path+'/'+file2).read().replace('\n',' ')    
    vec1 = text_to_vector(t1)
    vec2 = text_to_vector(t2)

    intersection = set(vec1.keys()) & set(vec2.keys())
    numerator = sum([vec1[x] * vec2[x] for x in intersection])
    sum1 = sum([vec1[x]**2 for x in vec1.keys()])
    sum2 = sum([vec2[x]**2 for x in vec2.keys()])
    denominator = math.sqrt(sum1) * math.sqrt(sum2)
    if not denominator:
       return 0.0
    else:
       return float(numerator) / denominator

对于Jaccard我得到以下内容:

def get_jaccard(file1, file2):
    t1 = file(Input_path+'/'+file1).read().replace('\n',' ')
    t2 = file(Input_path+'/'+file2).read().replace('\n',' ')    
    vec1 = text_to_vector(t1)
    vec2 = text_to_vector(t2)

    numerator = len(set(vec1.keys()).intersection(set(vec2.keys())))
    denominator = float(len(set(vec1.keys())) + len(set(vec2.keys())) -numerator) 

    if not denominator:
       return 0.0
    else:
       return float(numerator) / denominator

结果在小字符串示例上运行正常,但我不确定它们在大型测试文件上是否正确,尤其是Jaccard,因为我的结果与distance.jaccard有点不同(我使用列表来提供它,而不是字典)

关于其他指标,请确认可以使用以下方法计算sim_simple:

from difflib import SequenceMatcher

def similar(file1, file2):
    s1 = file(Input_path+'/'+file1).read().replace('\n',' ')
    s2 = file(Input_path+'/'+file2).read().replace('\n',' ')  
    list1 = list(set(text_to_list(s1)))
    list2 = list(set(text_to_list(s2)))
    return SequenceMatcher(None, list1, list2).ratio()

我不确定Sim_string(最小编辑)。这就像Levenshtein的距离,但在字面上,我不确定distance.levenshtein会不会有帮助。

你能帮我测试一下我得到的指标,并建议Sim_string使用什么。

非常感谢!!!

1 个答案:

答案 0 :(得分:2)

由于没有提及切换字位置(我在评论部分添加了实际客户的请求),我创建了以下过程。我确信它可以优化,但它适用于客户端。请注意,text_to_vector过程在原始问题文本中定义。我希望我的帖子对某人有用。

def Sim_MinEdit(file1, file2):
    s1 = file(Input_path+'/'+file1).read().replace('\n',' ')
    s2 = file(Input_path+'/'+file2).read().replace('\n',' ')
    dict1 = text_to_vector(s1)
    dict2 = text_to_vector(s2)
    dict_diff_1_2 = {k : dict2[k] for k in set(dict2) - set(dict1)}
    dict_diff_2_1 = {k : dict1[k] for k in set(dict1) - set(dict2)}
    dict_comm_1_2 = {k : abs(dict2[k] - dict1[k]) for k in 
    set(dict2).intersection(set(dict1))}
    numerator = sum(dict_diff_1_2.values()) + sum(dict_diff_2_1.values()) + 
    sum(dict_comm_1_2.values())
    denominator = sum(dict1.values()) + sum(dict2.values())
    if not denominator:
        return 0.0
    else:
        return 1 - (float(numerator) / denominator)