【发布时间】:2017-09-23 04:56:31
【问题描述】:
我正在处理来自多个来源的一些聚合会员数据。我在一列中有名字,在另一列中有一个长的会员备忘录字符串。我想要将姓名与会员备忘录相匹配的最佳方式。
例如,
我想找到最好的方法:
'Barack Obama'
在以下字符串中,因为此数据是聚合的,格式可能不同。这里有几个例子:
"Member Data REWNEW:EX PAID ID:234242 Barack Obama WASHINGTON DC LAST CO 2834298:EEXE:00WIE"
"Member Data REWNEW:EX PAID ID:234242 Barack Hussein Obama WASHINGTON DC LAST CO 2834298:EEXE:00WIE"
"Member Data REWNEW:EX PAID ID:234242 Obama Barack WASHINGTON DC LAST CO 2834298:EEXE:00WIE"
"Member Data REWNEW:EX PAID ID:234242 Barack H Obama WASHINGTON DC LAST CO 2834298:EEXE:00WIE"
过去,我使用fuzzywuzzy 来做模糊逻辑匹配。如果我比较两个字符串,而不是试图在另一个较长的字符串中找到一个字符串,这往往会很好。例如:
from fuzzywuzzy import fuzz
from fuzzywuzzy import fuzz
print(fuzz.ratio("Barack Obama", "Barack Obama"))
print(fuzz.ratio("Michelle Obama", "Barack Obama"))
print(fuzz.ratio("Barack Obama", "Member Data REWNEW:EX PAID ID:234242 Barack Hussein Obama WASHINGTON DC LAST CO 2834298:EEXE:00WIE"))
print(fuzz.ratio("Michelle Obama", "Member Data REWNEW:EX PAID ID:234242 Barack Hussein Obama WASHINGTON DC LAST CO 2834298:EEXE:00WIE"))
100
54
22
16
很明显,前两个非常不同(100 对 54),但后两个似乎并没有那么不同,因此这不是最好的方法。
有人对如何最好地实现这种类型的字符串搜索有任何想法吗?
非常感谢!
更新1:
我试过了:
memo_string="Member Data REWNEW:EX PAID ID:234242 Barack Hussein Obama WASHINGTON DC LAST CO 2834298:EEXE:00WIE"
search_terms = "Barack Obama"
memo_words = memo_string.split(" ")
search_term_count = len(search_terms.split(" "))
memo_slices = []
for i in range(len(memo_words) - search_term_count):
memo_slices.append(" ".join(memo_words[i:i+search_term_count]))
max_for_memo = 0
best_match_in_memo = None
for memo_slice in memo_slices:
fuzz_score = fuzz.ratio(search_terms, memo_slice)
if fuzz_score > max_for_memo:
max_for_memo = fuzz_score
best_match_in_memo = memo_slice
print(max_for_memo)
I also tried with search_terms = 'Michelle Obama'
这两个分数分别是 52 和 50,这仍然提出了我在开始时所说的挑战,即我想要某种逻辑来更明确地将两者分开。
想法?
非常感谢!
【问题讨论】:
标签: python text fuzzy-logic