Python字符串匹配完全等于Postgresql相似度函数

问题描述 投票:1回答:2

我一直在PostgreSQL中使用pg_trgm模块的相似性函数,现在我正在寻找类似于Python中的Similarity的单词相似度函数。我在python中找到了很多方法,例如difflib,nltk,但这些方法都没有产生类似于PostgreSQL的相似性函数的结果。

我一直在使用这个代码进行单词匹配,但结果与PostgreSQL相似性函数的结果有很大不同。这些结果是否比PostgreSQL的相似性功能更好?是否有任何方法或库可用于产生类似于PostgreSQL相似度函数的结果?

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,")
python postgresql similarity
2个回答
1
投票

我知道这是旧的,但是我需要同样的东西,而且我没有找到任何东西,当谷歌搜索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)

0
投票

从PostgreSQL文档:https://www.postgresql.org/docs/9.1/static/pgtrgm.html

trigram是一组从字符串中取出的三个连续字符。我们可以通过计算它们共享的三元组的数量来测量两个字符串的相似性。这个简单的想法对于测量许多自然语言中单词的相似性非常有效。

注意:在确定字符串中包含的三元组时,字符串被认为有两个空格前缀,一个空格后缀。例如,字符串“cat”中的三元组的集合是“c”,“ca”,“cat”和“at”。

python中没有用于此功能的内置模块。可能有像fuzzyset这样的库可以提供帮助 - 但无论哪种方式,python中都没有标准函数。

© www.soinside.com 2019 - 2024. All rights reserved.