代码之家  ›  专栏  ›  技术社区  ›  Arya

获取多个字符串的相似百分比

  •  0
  • Arya  · 技术社区  · 6 年前

    python中是否有任何函数可以接受多行字符串并返回它们有多少相似性的百分比?有点像 SequenceMatcher 但对于多个字符串。

    例如,我们有以下句子

    Hello how are you?
    Hi how are you?
    hi how are you doing?
    Hey how is your day?
    

    我希望能根据句子之间的相似程度得到一个百分比

    假设我们有这三个句子

    Hello how are you?
    Hello how are you?
    Hello how are you?
    

    那么我们应该得到100%的相似

    但是如果我们有

    Hello how are you?
    Hello how are you?
    hola como estats?
    

    然后我们应该得到一个67%左右相似性的数字。

    3 回复  |  直到 6 年前
        1
  •  1
  •   Franco Piccolo    6 年前

    你可以使用 pandas 要使用数据帧进行操作, itertools.combinations 从列表中计算2个字符串的组合 difflib.SequenceMatcher 相似性计算:

    import pandas as pd
    import itertools
    from difflib import SequenceMatcher
    
    def similarity(a,b):
        seq = SequenceMatcher(a=a, b=b)
        return seq.ratio()    
    
    strings = ['Hello how are you?', 'Hi how are you?', 'hi how are you doing?', 'Hey how is your day?']
    combinations = itertools.combinations(strings,2)
    
    df = pd.DataFrame(list(combinations))
    df['similarity'] = df.apply(lambda x: similarity(x[0],x[1]), axis=1)
    
    df.similarity.mean()
    0.68
    
        2
  •  1
  •   dawg    6 年前

    天真地说,你可以沿着这些路线做一些事情:

    from collections import Counter 
    from itertools import zip_longest
    
    cases=[('Hello how are you?','Hello how are you?','Hello how are you?'),
           ('Hello how are you?','Hello how are you?','hola como estats?')]
    
    for t in cases:    
        sums=[]
        for st in zip_longest(*t,fillvalue='|'):
            sums.append((st,(len(Counter(st))-1)/len(st)))
        print(t)
        print('\n'.join(map(str, sums)))   
    

    印刷品:

    ('Hello how are you?', 'Hello how are you?', 'Hello how are you?')
    (('H', 'H', 'H'), 0.0)
    (('e', 'e', 'e'), 0.0)
    (('l', 'l', 'l'), 0.0)
    (('l', 'l', 'l'), 0.0)
    (('o', 'o', 'o'), 0.0)
    ((' ', ' ', ' '), 0.0)
    (('h', 'h', 'h'), 0.0)
    (('o', 'o', 'o'), 0.0)
    (('w', 'w', 'w'), 0.0)
    ((' ', ' ', ' '), 0.0)
    (('a', 'a', 'a'), 0.0)
    (('r', 'r', 'r'), 0.0)
    (('e', 'e', 'e'), 0.0)
    ((' ', ' ', ' '), 0.0)
    (('y', 'y', 'y'), 0.0)
    (('o', 'o', 'o'), 0.0)
    (('u', 'u', 'u'), 0.0)
    (('?', '?', '?'), 0.0)
    ('Hello how are you?', 'Hello how are you?', 'hola como estats?')
    (('H', 'H', 'h'), 0.3333333333333333)
    (('e', 'e', 'o'), 0.3333333333333333)
    (('l', 'l', 'l'), 0.0)
    (('l', 'l', 'a'), 0.3333333333333333)
    (('o', 'o', ' '), 0.3333333333333333)
    ((' ', ' ', 'c'), 0.3333333333333333)
    (('h', 'h', 'o'), 0.3333333333333333)
    (('o', 'o', 'm'), 0.3333333333333333)
    (('w', 'w', 'o'), 0.3333333333333333)
    ((' ', ' ', ' '), 0.0)
    (('a', 'a', 'e'), 0.3333333333333333)
    (('r', 'r', 's'), 0.3333333333333333)
    (('e', 'e', 't'), 0.3333333333333333)
    ((' ', ' ', 'a'), 0.3333333333333333)
    (('y', 'y', 't'), 0.3333333333333333)
    (('o', 'o', 's'), 0.3333333333333333)
    (('u', 'u', '?'), 0.3333333333333333)
    (('?', '?', '|'), 0.3333333333333333)
    

    所以第二种情况下的差异会稍微小于1/3,因为在最后的西班牙语句子中有两个相同的字符。

    然后将这个序列减少到一个总的差异。

        3
  •  0
  •   a_guest    6 年前

    你可以使用 numpy 从中创建成对相似矩阵 itertools.product .然后您可以从该矩阵中提取所需的相似性度量。在任何情况下,你都需要想出一个适合你的问题的度量(即成对量词)。

    import itertools as it
    import numpy as np
    
    
    def similarity_check(sentences, metric):
        pairwise = np.fromiter(map(
            metric,
            it.product(sentences, sentences)),
        dtype=float).reshape(len(sentences), -1)
        # return pairwise[np.triu_indices(len(sentences), 1)].mean()  # Option 1.
        return pairwise.mean(axis=0).max()  # Option 2.
    
    
    print(similarity_check([
        'Hello how are you?',
        'Hello how are you?',
        'Hello how are you?'
    ], lambda x: float(x[0] == x[1])))  # Plug in your own metric here.
    
    print(similarity_check([
        'Hello how are you?',
        'Hello how are you?',
        'hola como estats?'
    ], lambda x: float(x[0] == x[1])))  # Plug in your own metric here.
    
    推荐文章