0

この質問は、SOに関する2つの回答に導かれた2つのコードの集大成です。私が持っていた最初の質問は、2 つの文字列の類似性を比較する方法でした。次のコードで見られるように、良い答えが得られました。

コード 1

def get_bigrams(string):
    '''
    Takes a string and returns a list of bigrams
    '''
    s = string.lower()
    return { s[i:i+2] for i in range(len(s) - 1) }

def string_similarity(str1, str2):
    '''
    Perform bigram comparison between two strings
    and return a percentage match in decimal form
    '''
    pairs1 = get_bigrams(str1)
    pairs2 = get_bigrams(str2)
    intersection = set(pairs1) & set(pairs2)
    return (2.0 * len(intersection)) / (len(pairs1) + len(pairs2))

その後、上記のコードを実行するために、名前のリストを並べ替える方法が必要でした。以下に示すように、ここにコードを取得しました。

コード 2

import itertools
persons = ["Peter parker", "Richard Parker", "Parker Richard", "Aunt May"]
similarity = []
for p1, p2 in itertools.combinations(persons, 2):
    similarity.append(string_similarity(p1,p2))
    print("%s - %s: " %(p1, p2) + " " + str(string_similarity(p1, p2)))

similarity = sorted(similarity, key=float)
print(similarity)

さて、最後のハードルは、データがリストになく、最終的に追跡したい主キーを持つデータベースから実際にフェッチされることです。つまり、複数の名前を比較する場合、たとえば ID 1 と ID 2 が最も異なるということをマークする必要があります。これら 2 つの ID が最も異なる ID であると判断するには、上記の「code1」の結果を次のように並べ替える必要があります。

Peter parker - Richard Parker:  0.5454545454545454
Peter parker - Parker Richard:  0.5454545454545454
Peter parker - Aunt May:  0.0
Richard Parker - Parker Richard:  0.8333333333333334
Richard Parker - Aunt May:  0.0
Parker Richard - Aunt May:  0.0
[0.0, 0.0, 0.0, 0.5454545454545454, 0.5454545454545454, 0.8333333333333334]

それらの名前の代わりに私の頭の中で、名前が取得されたプライマリ ID が必要なので、辞書を使用して考えています。を使用して {PID:Name}、{PID1:Name1}、PID2:Name2} の辞書を実行し、 を使用code2して類似度の値を取得しcode1、結果を並べ替えて、類似度が最も高い名前が PID1 と PID3 であることを知る方法はありますか? または、現在考えているよりもエレガントで髪を引っ張らない方法はありますか...

4

1 に答える 1

1

はい、ペア(ID、名前)を関連付ける必要があります。これには、辞書、タプル、さらにはクラスを使用できます。たとえば、タプルを使用すると、コード 2は次のように変更されます。

persons = [('id1', "Peter parker"), ('id2' ,"Richard Parker"), ('id3' ,"Parker Richard"), ('id4' ,"Aunt May")]
similarity = [[p1, p2, string_similarity(p1[1], p2[1])]
                for p1, p2 in itertools.combinations(persons, 2)]

similarity = sorted(similarity, key=lambda x: x[2], reverse=True)
for p1, p2, sim in similarity:    
    print "{} - {}: {}".format(p1, p2, sim)  # p1[0], p2[0] to show ids only

あなたは得る:

('id2', 'Richard Parker') - ('id3', 'Parker Richard'): 0.833333333333
('id1', 'Peter parker') - ('id2', 'Richard Parker'): 0.545454545455
('id1', 'Peter parker') - ('id3', 'Parker Richard'): 0.545454545455
('id1', 'Peter parker') - ('id4', 'Aunt May'): 0.0
('id2', 'Richard Parker') - ('id4', 'Aunt May'): 0.0
('id3', 'Parker Richard') - ('id4', 'Aunt May'): 0.0
于 2013-09-09T14:58:41.690 に答える