【问题标题】:What would be the best implementation of the __hash__ function if the __eq__ funciton determines equality using edit distance?____ 函数的 __hash__ 函数使用编辑距离确定相等性的最佳实现是什么?
【发布时间】:2018-02-11 20:28:53
【问题描述】:

我有一个奇怪的要求,我需要从两个不同且非常大的列表中找到常见的“客户”。两个列表中的每个条目都是一个 Customer 对象,其中包含客户的名字和姓氏及其地址(按地址行细分,例如 address_line1、address_line2 等)。问题是任何一个列表中的数据都可能不完整,例如,对于第一个列表中的一条记录,客户的名字可能会丢失,而在第二个列表中,对于同一客户,他的地址(第 2 行和第 3 行)可能会丢失。我需要做的是找到两个列表中都存在的客户。需要注意的一点是列表可能很大。要记住的另一点是,名称和地址在语义上可能相同,但在您进行精确字符串匹配时可能不会返回结果。例如,在第一个列表中,第一个列表中客户的地址可以是B-502 ABC Street 的形式,而第二个列表中同一客户的地址可以是B 502 ABC Street 的形式。我使用编辑距离的原因是考虑到列表中的用户输入错误并处理两个列表中存在的数据中的某些其他细微差异

我所做的是在Customer类中实现eq函数如下

import re
import editdistance # Using this: https://pypi.python.org/pypi/editdistance

class Customer:
    def __init__(self, fname, lname, address1, address2, address3, city):
        # Removing special characters from all arguments and converting them to lower case
        self.fname = re.sub("[^a-zA-Z0-9]", "", fname.lower())
        self.lname = re.sub("[^a-zA-Z0-9]", "", lname.lower())
        self.address1 = re.sub("[^a-zA-Z0-9]", "", address1.lower())
        self.address2 = re.sub("[^a-zA-Z0-9]", "", address2.lower())
        self.address3 = re.sub("[^a-zA-Z0-9]", "", address3.lower())
        self.city = re.sub("[^a-zA-Z0-9]", "", city.lower())

    def __eq__(self, other):
        if self.lname == "" or self.lname != other.lname:
            return False

        t = 0

        if self.fname != "" and other.fname != "" and self.fname[0] == other.fname[0]:
            t += 1

        if editdistance.eval(self.fname, other.fname) <= 2:
            t += 3

        if editdistance.eval(self.address1, other.address1) <= 3:
            t += 1

        if editdistance.eval(self.address2, other.address2) <= 3:
            t += 1

        if editdistance.eval(self.address3, other.address3) <= 3:
            t += 1

        if editdistance.eval(self.city, other.city) <= 2:
            t += 1

        if t >= 4:
            return True

        return False

    def __hash__():
        # TODO:  Have a robust implementation of a hash function here. If two objects are "equal", their hashes should be the same

为了让客户同时出现在两个列表中,我将执行以下操作:

set(first_list).intersection(set(second_list))

但为了使其工作,客户对象需要是可散列的。

有人可以帮我提供一个好的散列机制吗?

【问题讨论】:

    标签: python python-2.7 hash set set-intersection


    【解决方案1】:

    您唯一的选择是规范化数据。如果您需要比较相等性并且您可能有不同的格式,则解决方案是规范化。转换所有内容,使其在两个列表中的格式相同。

    我在西班牙的地址规范化算法中工作了几个月。同一地址的不同用户输入的组合是无穷无尽的(我正在研究一个 700 万行的数据库)。使用该距离函数可能不够准确,除非您确切知道同一地址的不同可能格式以及这些差异从函数返回的距离。

    第一个关键问题是,您可以承受的错误百分比是多少?因为有了用户输入和大数据,你总会有一些。

    下一步是测量使用该距离算法(或任何其他算法)获得的错误百分比。仔细选择样本数据,使百分比不会随完整数据而变化。

    如果该百分比适合您使用该算法,如果不适合,请查找其他算法并对其进行测量。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-02-13
      • 1970-01-01
      • 2022-08-16
      • 2011-05-16
      • 2011-06-07
      • 1970-01-01
      • 1970-01-01
      • 2011-02-23
      相关资源
      最近更新 更多