Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/357.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python中的字符串相似性度量_Python_Algorithm_String_Levenshtein Distance - Fatal编程技术网

Python中的字符串相似性度量

Python中的字符串相似性度量,python,algorithm,string,levenshtein-distance,Python,Algorithm,String,Levenshtein Distance,我想找出两个字符串之间的相似性。佩奇有一些例子。Python实现了。在这些限制条件下,是否有更好的算法(希望还有python库) 我想在字符串之间进行模糊匹配。例如,匹配('Hello,All you peopl','Hello,All you peopl')应该返回True 假阴性是可以接受的,假阳性是可以接受的,但极少数情况除外 这是在非实时设置下完成的,因此速度不太重要 [编辑]我正在比较多字字符串 对于我的情况,除了Levenshtein距离(或Levenshtein比率)之外的其他算法

我想找出两个字符串之间的相似性。佩奇有一些例子。Python实现了。在这些限制条件下,是否有更好的算法(希望还有python库)

  • 我想在字符串之间进行模糊匹配。例如,匹配('Hello,All you peopl','Hello,All you peopl')应该返回True
  • 假阴性是可以接受的,假阳性是可以接受的,但极少数情况除外
  • 这是在非实时设置下完成的,因此速度不太重要
  • [编辑]我正在比较多字字符串
  • 对于我的情况,除了Levenshtein距离(或Levenshtein比率)之外的其他算法会更好吗?

    这就是你的意思吗

    >>> get_close_matches('appel', ['ape', 'apple', 'peach', 'puppy'])
    ['apple', 'ape']
    >>> import keyword
    >>> get_close_matches('wheel', keyword.kwlist)
    ['while']
    >>> get_close_matches('apple', keyword.kwlist)
    []
    >>> get_close_matches('accept', keyword.kwlist)
    ['except']
    

    <

    P> >谢菲尔德大学的字符串相似性度量有很大的资源。它有一个各种指标的列表(不仅仅是Levenshtein),并且有它们的开源实现。看起来它们中的许多应该很容易适应Python

    以下是列表的一部分:

    • 汉明距离
    • Levenshtein距离
    • Needleman-Wunch距离算法
    • 还有更多

      • 我意识到这不是一回事,但这已经足够接近了:

        >>> import difflib
        >>> a = 'Hello, All you people'
        >>> b = 'hello, all You peopl'
        >>> seq=difflib.SequenceMatcher(a=a.lower(), b=b.lower())
        >>> seq.ratio()
        0.97560975609756095
        
        你可以把它作为一个函数

        def similar(seq1, seq2):
            return difflib.SequenceMatcher(a=seq1.lower(), b=seq2.lower()).ratio() > 0.9
        
        >>> similar(a, b)
        True
        >>> similar('Hello, world', 'Hi, world')
        False
        

        我会使用Levenshtein距离,或所谓的Damerau距离(考虑了换位),而不是difflib,原因有两个:(1)“足够快”(动态编程算法)和“嗖嗖”(位碰撞)C代码可用;(2)众所周知的行为,例如Levenshtein满足三角形不等式,因此可用于Burkhard-Keller树

        阈值:仅当距离小于(1-X)*max(len(string1)、len(string2))时,才应将其视为“正”,并调整X(相似系数)以适合自己。选择X的一种方法是获得一个匹配样本,计算每个匹配的X,忽略X<例如0.8或0.9的情况,然后按X的降序对剩余部分进行排序,并对它们进行观察,插入正确的结果,计算不同级别X的一些错误成本度量


        注意,你的ape/apple示例的距离为2,因此X为0.6。。。如果我在拼命寻找某个东西,并且有很高的假阴性惩罚,我只会使用低至0.75的阈值

        我知道这是不一样的,但你可以调整比率以过滤出不够相似的字符串,并返回与你要找的字符串最接近的匹配项

        也许您会对语义相似性度量更感兴趣

        我知道你们说过速度不是问题,但若你们正在为你们的算法处理大量的字符串,下面的内容是非常有用的

        def spellcheck(self, sentence):
            #return ' '.join([difflib.get_close_matches(word, wordlist,1 , 0)[0] for word in sentence.split()])
            return ' '.join( [ sorted( { Levenshtein.ratio(x, word):x for x in wordlist }.items(), reverse=True)[0][1] for word in sentence.split() ] )
        
        它比difflib快20倍左右


        导入Levenshtein

        此代码段将计算两个字符串的difflib、Levenshtein、Sørensen和Jaccard相似性值。在下面的代码片段中,我迭代了一个tsv,其中感兴趣的字符串占据了tsv的
        [3]
        [4]
        列。(
        pip-install-python-Levenshtein
        pip-install-distance
        ):


        关于第2点:阅读以下内容:。根据你的第2点,最好的相似性度量是只调用相同的字符串。任何模糊的东西都会有误报。。那么,接近人类的智慧,没有错误是我所寻找的。人类可以得出结论,阿佩尔和苹果是完全一样的,但猿不是。很可能我没有把我的观点说清楚。(1)“没有错误”是不可能的,即使是精确匹配。“苹果”(水果)!=“苹果”(计算机等制造商)。(2) 如果“接近人类的智能”是可用的,它既不是在一个完整的代码屏幕上,也不是免费的。(3)考虑使用一种允许换位的方法,它将Appel/Apple比猿/苹果和猿/ APP高。谢谢。这可能会给我一些好主意,但不是我想要的
        get_close_matches('appel',['ape','peach','puppy'))
        get me ape。我可以设置截止值,但从一些快速实验来看,误报太常见了。运行此操作时,我遇到了“IndexError:list index out-range”错误。为什么我会得到它?@FeyziBagirov你能用你的脚本和输入发布github的要点吗?
        import codecs, difflib, Levenshtein, distance
        
        with codecs.open("titles.tsv","r","utf-8") as f:
            title_list = f.read().split("\n")[:-1]
        
            for row in title_list:
        
                sr      = row.lower().split("\t")
        
                diffl   = difflib.SequenceMatcher(None, sr[3], sr[4]).ratio()
                lev     = Levenshtein.ratio(sr[3], sr[4]) 
                sor     = 1 - distance.sorensen(sr[3], sr[4])
                jac     = 1 - distance.jaccard(sr[3], sr[4])
        
                print diffl, lev, sor, jac