查找重复邮寄地址的策略
我正在想办法找出重复的地址,主要是通过一个相似度评分来判断。比如说,这些地址是重复的:
addr_1 = '# 3 FAIRMONT LINK SOUTH'
addr_2 = '3 FAIRMONT LINK S'
addr_3 = '5703 - 48TH AVE'
adrr_4 = '5703- 48 AVENUE'
我打算对这些地址做一些字符串处理,比如把长的单词缩写,比如把“NORTH”变成“N”,然后去掉所有的空格、逗号、连字符和井号。现在,有了这样的处理结果,我该怎么把addr_3和其他地址进行比较,找出相似的呢?什么样的相似度百分比算是安全的?能不能给我一个简单的Python代码示例?
addr_1 = '3FAIRMONTLINKS'
addr_2 = '3FAIRMONTLINKS'
addr_3 = '570348THAV'
adrr_4 = '570348AV'
谢谢,
爱德华多
6 个回答
这应该能帮助你建立一个缩写词的词典:
去掉空格、逗号和破折号会让事情变得模糊不清。把它们替换成一个空格会更好。
比如说这个地址:
56 5th avenue
还有这个:
5, 65th avenue
用你的方法处理后,它们都会变成:
565THAV
你可以写一个好的地址简化算法,然后用字符串比较来检测重复。这应该能在一般情况下找到重复的地址。一般的相似度算法可能不太管用,因为一个数字的不同可能意味着地址的巨大变化。
这个算法可以这样进行:
- 把所有的逗号和破折号替换成空格。可以用translate方法来实现。
- 建立一个字典,把单词和它们的缩写形式放在一起。
- 如果“TH”出现在数字后面,就把它去掉。
首先,把地址字符串简化一下,把所有的空格压缩成每个单词之间只有一个空格,并把所有字母都变成小写(如果你喜欢,也可以变成大写):
adr = " ".join(adr.tolower().split())
然后,我会把像“41st Street”中的“st”或者“42nd Street”中的“nd”这样的东西去掉:
adr = re.sub("1st(\b|$)", r'1', adr)
adr = re.sub("([2-9])\s?nd(\b|$)", r'\1', adr)
注意,第二个sub()可以处理“2”和“nd”之间有空格的情况,但我没有设置第一个去处理这种情况;因为我不太确定怎么区分“41 St Ave”和“41 St”(第二个是“41 Street”的缩写)。
一定要仔细阅读re模块的所有帮助文档;它很强大,但有点难懂。
接下来,我会把剩下的内容分割成一个单词列表,并对那些看起来不像数字的列表项应用Soundex算法:
http://en.wikipedia.org/wiki/Soundex
http://wwwhomes.uni-bielefeld.de/gibbon/Forms/Python/SEARCH/soundex.html
adrlist = [word if word.isdigit() else soundex(word) for word in adr.split()]
然后你可以根据自己的想法处理这个列表,或者把它重新合并成一个字符串。
Soundex的整个想法是处理拼写错误的地址。如果这不是你想要的,那就可以忽略这个Soundex的想法。
祝你好运。