Python字符串匹配完全等于Postgresql相似性函数
我一直在使用PostgreSQL中pg_trgm模块的相似性函数,现在我正在搜索类似于Python中的相似性的单词相似性函数。我在python中发现了许多方法,例如difflib、nltk,但这些方法都不会产生类似于PostgreSQL的相似性函数的结果 我一直在使用这段代码进行单词匹配,但结果与PostgreSQL相似性函数的结果非常不同。这些结果是否比PostgreSQL的相似函数的结果更好?是否有任何方法或库可用于生成类似于PostgreSQL相似性函数的结果Python字符串匹配完全等于Postgresql相似性函数,python,postgresql,similarity,Python,Postgresql,Similarity,我一直在使用PostgreSQL中pg_trgm模块的相似性函数,现在我正在搜索类似于Python中的相似性的单词相似性函数。我在python中发现了许多方法,例如difflib、nltk,但这些方法都不会产生类似于PostgreSQL的相似性函数的结果 我一直在使用这段代码进行单词匹配,但结果与PostgreSQL相似性函数的结果非常不同。这些结果是否比PostgreSQL的相似函数的结果更好?是否有任何方法或库可用于生成类似于PostgreSQL相似性函数的结果 from difflib i
from difflib import SequenceMatcher
import nltk
from fuzzywuzzy import fuzz
def similar(a,b):
return SequenceMatcher(None,a,b).ratio()
def longest_common_substring(s1, s2):
m = [[0] * (1 + len(s2)) for i in xrange(1 + len(s1))]
longest, x_longest = 0, 0
for x in xrange(1, 1 + len(s1)):
for y in xrange(1, 1 + len(s2)):
if s1[x - 1] == s2[y - 1]:
m[x][y] = m[x - 1][y - 1] + 1
if m[x][y] > longest:
longest = m[x][y]
x_longest = x
else:
m[x][y] = 0
return s1[x_longest - longest: x_longest]
def similarity(s1, s2):
return 2. * len(longest_common_substring(s1, s2)) / (len(s1) + len(s2)) * 100
print similarity("New Highway Classic Academy Lahore","Old Highway Classic Academy")
print nltk.edit_distance("This is Your Shop","This")
print fuzz.ratio("ISE-Tower","UfTowerong,")
从PostgreSQL文档中: 三元组是从字符串中提取的一组三个连续字符。我们可以通过计算两个字符串共享的三元数来衡量它们的相似性。这个简单的想法对于测量许多自然语言中单词的相似性非常有效 注意:在确定字符串中包含的一组三叉图时,字符串被视为前缀为两个空格,后缀为一个空格。例如,字符串“cat”中的一组三角形是“c”、“ca”、“cat”和“at”
python中没有用于此功能的内置模块。可能有这样的库可以帮助实现这一点,但无论哪种方式,python中都没有标准函数。我知道这很旧,但我也需要同样的功能,在谷歌搜索python包时,我没有发现任何东西,这些包以postgres相同的方式进行三角相似性处理 所以我写了一个非常基本的函数来实现它。我已经在一些字符串上测试了它,它似乎给出了与postgres完全相同的结果。如果您感兴趣,请点击这里:
import re
def find_ngrams(text: str, number: int=3) -> set:
"""
returns a set of ngrams for the given string
:param text: the string to find ngrams for
:param number: the length the ngrams should be. defaults to 3 (trigrams)
:return: set of ngram strings
"""
if not text:
return set()
words = [f' {x} ' for x in re.split(r'\W+', text.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.
0 being completely different strings, and 1 being equal strings
"""
ngrams1 = find_ngrams(text1, number)
ngrams2 = find_ngrams(text2, number)
num_unique = len(ngrams1 | ngrams2)
num_equal = len(ngrams1 & ngrams2)
return float(num_equal) / float(num_unique)