0

这个问题是由 SO 上的两个答案引导的两段代码的高潮。我遇到的第一个问题是如何比较两个字符串之间的相似性,我得到了一个很好的答案,如下所示

代码 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 是最多变体的。为了确定这两个 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 回答