【问题标题】:Data matching algorithm数据匹配算法
【发布时间】:2011-01-26 23:23:33
【问题描述】:

我目前正在从事一个需要实施数据匹配算法的项目。 外部系统传入它所知道的有关客户的所有数据,而我设计的系统必须返回匹配的客户。因此,外部系统随后会知道客户的正确 id,并且它会获取额外的数据,或者可以更新自己的特定客户的数据。

传入以下字段:

  • 姓名
  • 姓名2
  • 街道
  • 城市
  • 邮政编码
  • 银行账户号码
  • 银行名称
  • 银行代码
  • 电子邮件
  • 电话
  • 传真
  • 网络

数据可以是高质量的,并且有很多信息可用,但通常数据很糟糕,只有名称和地址可用,并且可能有拼写。

我正在.Net 中实施该项目。我目前做的事情是这样的:

public bool IsMatch(Customer customer)
{
    // CanIdentify just checks if the info is provided and has a specific length (e.g. > 1)
    if (CanIdentifyByStreet() && CanIdentifyByBankAccountNumber())
    {
        // some parsing of strings done before (substring, etc.)
        if(Street == customer.Street && AccountNumber == customer.BankAccountNumber) return true;
    }
    if (CanIdentifyByStreet() && CanIdentifyByZipCode() &&CanIdentifyByName())
    {
        ...
    }
}

我对上述方法不太满意。这是因为我必须为所有合理的情况(组合)编写 if 语句,所以我不会错过任何匹配实体的机会。

所以我想也许我可以创建某种匹配的分数。因此,对于每个匹配的标准,都会添加一个分数。喜欢:

public bool IsMatch(Customer customer)
{
    int matchingScore = 0;
    if (CanIdentifyByStreet())
    {
        if(....)
            matchingScore += 10;
    }
    if (CanIdentifyByName())
    {
        if(....)
            matchingScore += 10;
    }
    if (CanIdentifyBankAccountNumber())
    {
        if(....)
            matchingScore += 10;
    }

    if(matchingScore > iDontKnow)
        return true;
}

这将允许我考虑所有匹配数据,并根据某些权重增加匹配分数。如果分数足够高,那就是匹配。

知道我的问题是:是否有针对此类事情的最佳实践,例如匹配算法模式等?非常感谢!

【问题讨论】:

  • 你的意思是“拼写错误”,对吧?

标签: .net algorithm design-patterns


【解决方案1】:

如需灵感,请查看Levenshtein distance algorithm。这将为您提供一个合理的机制来衡量您的比较。

我还要补充一点,根据我的经验,您永远无法绝对确定地将两条任意数据匹配到同一个实体中。您需要向用户提供似是而非的匹配,然后用户可以确定 1920 E. Pine 的 John Smith 与 192 East Pine Road 的 Jon Smith 是否是同一个人。

【讨论】:

  • Levenshtein 和 hamming 太过分了。
  • 也许,我不确定他的具体要求是什么。他提出的解决方案中的 matchingScore 变量让我相信他需要一些权重系统来进行匹配,并且不确定如何进行。
  • +1;然后,您可以将第 n 个变量的差异存储到向量的第 n 个元素中,然后计算两个域对象的欧几里德距离以获得匹配(我想您需要在每个变量权重之前将一些常数倍增他们)@The Rook 为什么?看看维基百科的伪代码。
  • soundex 处理拼写错误怎么样?
【解决方案2】:

根据我对这类事情的经验,实际上是业务人员定义了可接受的匹配规则,而不是技术决策。这对我来说很有意义,因为企业最终承担了风险。此外,构成匹配的内容很容易发生变化,例如,如果他们使用该系统并发现有太多人被排除在外。

我认为您的第一种方法更有意义,因为如果您可以通过姓名和银行帐号匹配某人,那么您很确定就是他们。但是,如果姓名和银行信息不匹配,但地址、电话和所有匹配的信息(即配偶),那么评分系统可能会错误地匹配人。我意识到这是很多代码,但是只要您提取出实际的匹配代码(matchPhoneNumber 方法等),那么它在设计方面就很好。

我可能会更进一步,将匹配项提取到一个枚举中,然后列出可接受的匹配项。有点像这样: 接口匹配 { 布尔匹配(客户 c1,客户 c2); }

class BankAccountMatch implements Match
{
    public boolean matches(Customer c1, Customer c2)
    {
        return c1.getBankAccountNumber() == c2.getBankAccountNumber();
    }
}

static Match BANK_ACCOUNT_MATCH = new BankAccountMatch();

Match[][] validMatches = new Match[] [] {
        {BANK_ACCOUNT_MATCH, NAME_MATCH},
        {NAME_MATCH, ADDRESS_MATCH, FAX_MATCH}, ...
};

然后进行验证的代码将遍历 validMatches 数组并测试它们是否适合。我什至可以将有效匹配列表提取到配置文件中。不过,这一切都取决于您的系统所需的稳健性水平。

【讨论】:

    【解决方案3】:

    如果您将自己限制在地址和名称上,则可以只使用 harvesine 公式或空间索引(如果您有地理位置)。对于名称,您可以使用 trie 并仅获得第一个结果,可能是 10 个。

    【讨论】:

      【解决方案4】:

      机器学习方法怎么样。创建。每个项目的距离。

      这些成为您的输入空间。根据这些距离在正确匹配的 custers 上构建训练集。运行您最喜欢的机器学习算法。获取反映匹配强度的决策函数参数。调。适用于新案例。去银行。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-13
        • 2021-12-25
        • 2011-06-18
        • 1970-01-01
        • 2018-10-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多