【问题标题】:Calculating Jaccard similarity on two lists to return highest similarity words in Python计算两个列表上的 Jaccard 相似度以在 Python 中返回最高相似度的单词
【发布时间】:2020-06-03 12:46:19
【问题描述】:

我有一个巨大的列表(包含约 25 万个单词),这是唯一的单词。 (说清单1)

我有另一个列表,其中包含 5 个拼写错误的单词。 (说清单2)

我需要找到 jaccard 相似度(基于不同的 ngram)。在两个列表之间,并从 list1 返回最接近的匹配词。根据我在这个网站上找到的一些答案,我能够:

  1. 通过函数将两个列表拆分为 ngram。
  2. 计算第二个列表的第一个元素和第一个列表的 jaccard 相似度。

这给了我一个有效的答案。但是,我无法从这里开始从 list1 返回最匹配的单词。我知道我需要将 ngram 函数应用于我的 list1 的每个元素。然后用 list2 计算 jaccard 相似度,并从中返回最大值元素。但无法通过循环实现它。这是我正在使用的代码:

def spell_correcter(list2=['word1', 'word2',... 'word5']):
    from sklearn.metrics import jaccard_similarity_score
    import re

    def find_ngrams(text: str, number: int=3) -> set:
    #returns a set of ngrams for the given string

        if not text:
            return set()

        str1 = ''.join(text)
        words = [f'  {x} ' for x in re.split(r'\W+', str1.lower()) if x.strip()]

        ngrams = set()

        for word in words:
            for x in range(0, len(word) - number + 1):
                ngrams.add(word[x:x+number])

        return ngrams


    def similarity(text1: str, text2: str, number: int=3) -> float:
    #Finds the similarity between 2 strings using ngrams.

        ngrams1 = find_ngrams(text1, number)
        ngrams2 = find_ngrams(text2, number)
        num_unique = len(ngrams1 | ngrams2)
        num_equal = len(ngrams1 & ngrams2)

        #Tried to compute for entire list1; very slow. Didn't execute
        #for i in range(0, len(text1)):
            #ngrams1 = find_ngrams(text1, number)
            #num_unique = len(ngrams1 | ngrams2)
            #num_equal = len(ngrams1 & ngrams2)
            #jaccard = float(num_equal) / float(num_unique)


        return float(num_equal) / float(num_unique)

    b = list2[0]
    a = similarity(list1, b)

    return a

有人可以帮忙处理这段代码吗?

【问题讨论】:

    标签: python similarity levenshtein-distance n-gram sentence-similarity


    【解决方案1】:

    Shingling 是通过获取连续单词并将它们分组来创建单个对象的过程。
    我们对列表 1 进行标记并创建一个 ngram fo len(list2) 并计算每个 ngram 与列表 2 的 jaccard 相似度。这将给出列表 1 中最相似的单词与列表 2 中的单词:

    def jaccard_similarity(list_x, list_y):
        set_x = set(list_x)
        set_y = set(list_y)
        intersection = set_x.intersection(set_y)
        union = set_x.union(set_y)
        return len(intersection) / len(union) if len(union) > 0 else 0
    
    def shingling_jaccard_similarity(text_x, text_y, n):
        x = list(nltk.ngrams(tokenizer.tokenize(text_x), n))
        y = list(nltk.ngrams(tokenizer.tokenize(text_y), n))
        sim_score = jaccard_similarity(x,y)
        return sim_score
    
    shingling_jaccard_similarity(list1, list2, len(list2))
    

    【讨论】:

    • 你能解释一下为什么会这样吗?
    猜你喜欢
    • 2017-03-27
    • 1970-01-01
    • 2022-01-04
    • 2018-01-02
    • 2015-05-03
    • 2011-10-06
    • 2017-04-09
    • 1970-01-01
    • 2019-08-05
    相关资源
    最近更新 更多