python - 计算两个列表上的 Jaccard 相似度以在 Python 中返回最高相似度的词
问题描述
我有一个巨大的列表(包含约 250k 个单词),这是唯一的单词。(说清单1)
我有另一个列表,其中包含 5 个拼写错误的单词。(说清单2)
我需要找到 Jaccard 相似性(基于不同的 ngram)。在两个列表之间,并从 list1 返回最接近的匹配词。根据我在这个网站上找到的一些答案,我能够:
- 通过函数将两个列表拆分为 ngram。
- 计算第二个列表和第一个列表的第一个元素的 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
有人可以帮忙处理这段代码吗?
解决方案
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))
推荐阅读
- json - 如何在 bash json 中使用 grep 找到一个空名称?
- python - 如何通过python重命名和重新定位最近下载的文件?
- java - 我正在使用 APACHE POI Java 转换 HTML2WORD 文档,但无法将页眉和页脚添加到新生成的 word 文档
- php - WordPress 安全标准希望我转义我的 html,但如何正确地做到这一点?
- c++ - 在不休眠或冻结线程的情况下等待特定时间 [1.7s] (C++)
- sql - SQL xxx.myTable 里面的xxx叫什么
- sql - 查询后结果不同
- javascript - 在循环内使用延迟函数递增日期
- bash - linux终端smtp登录
- c# - 如何在asp.net core的中间件中修改httpcontext中的request/response?