模糊名称和昵称匹配

数据挖掘 深度学习 nlp
2021-10-14 11:58:28

我有一个具有以下结构的数据集:

full_name,nickname,match Christian Douglas,Chris,1, Jhon Stevens,Charlie,0, David Jr Simpson,Junior,1 Anastasia Williams,Stacie,1 Lara Williams,Ana,0 John Williams,Willy,1

其中每个预测变量行是一对全名、昵称和目标变量 match,当昵称对应于具有该名称的人时为 1,否则为 0。如您所见,从全名获得昵称的方式并不遵循特定的模式。

我想训练一个机器学习算法,给定一对全名、昵称,预测匹配概率。

我的基线只是试图查看匹配的 carachter 数量,以及类似的功能。但是,我正在考虑使用深度学习的 NLP 方法。我的问题是是否有特定于这个问题的神经网络架构。

3个回答

我在上一份工作中遇到了类似的问题。我的解决方案是通过(转换+比较)*许多组合构建特征并提供给模型,然后聚合和建模,即2层模型。关键是将编码和相似度分数作为特征。

转换:删除元音(非常适合某些词根)、删除结尾元音、删除双字符、转换为语音字符串(IPA、soundex、https: //pypi.org/project/Fuzzy/ )、替换听起来相似或具有相似性的字符其他语言的不同声音(J 在东欧听起来像 Y 在我们中, C 听起来像 K,D T,TTH,等等),...策略是处理人们名字中的许多怪异/不规则。

比较(相似和不同):尝试[字符级别,块/根/[pre/suf]fix级别,单词级别(可能不适用于您)]相似度和差异分数。尝试 Dice 系数、Levenshtein、Needleman–Wunsch、最长公共(非)连续子串、字符直方图相似度、# 个字符匹配、不匹配(左右各)等。您可以尝试使用 RNN/LSTM 并让它学习相似度对于每个变换。使用训练模型的输出作为另一个特征。

尝试以上不同的组合,并选择一些似乎有价值的组合。您可以简单地获取所有分数并拟合逻辑回归(或神经网络),或者您可以构建统计模型并基于小型训练集输出百分比排名以对其进行规范化。另一种预处理原始分数的方法是通过逻辑函数使用校准编码。然后将归一化分数中的摘要统计数据添加为附加功能。将所有这些推入最终模型。

您会处理源自阿拉伯语、西班牙语、法语等名称的名称吗?这只是额外的,但请考虑下载社会保障和美国人口普查名称统计数据,以通过更多名称变化来增强您的项目。我会把方法留给你,但它有助于了解可能的可能性。请注意,仅使用 Levenshtein 对 William->Bill、Dianne->Di、Larry->Lawrence、Mohammed->Muhamed 和 Hamed、Danielle->Daniela、Thomas->Tom 和 Jimmy->James 的效果并不好。 . 我提到的策略应该可以帮助你处理所有的变化。

要探索的其他资源:https: //github.com/jamesturk/jellyfish https://nameberry.com/list/276/If-You-Like-Danielle-You-Might-Love https://pypi.org/project /语音学/

我找不到任何有用的文献来使用深度学习来解决这个特定问题。大多数方法似乎都依赖于非机器学习方法,例如字符串相似度和列文斯坦距离。一个合理的基于深度学习的解决这个问题的方法是递归神经网络LSTM(长期短期记忆)或 GRU(门控循环单元)将是理想的。这个想法是让 RNN 具有内部状态并尊重输入的输入顺序。

与文本分类、情感分析或序列生成不同,此处文本的首选编码将是字符级别而不是单词级别

例如

Christian Douglas,Chris,1
Jhon Stevens,Charlie,0

会成为

[C,h,r,i,s,t,i,a,n, ,D,o,u,g,l,a,s, ,C,h,r,i,s] --> [1]
[J,h,o,n, ,S,t,e,v,e,n,s, ,C,h,a,r,l,i,e]       --> [0]

要匹配的两个字符串连接成一个序列。这里的直觉是,RNN 将逐个字符地处理序列并学习(读取更新权重)末尾的字符与它之前在同一序列中看到的具有相似的模式,以推断它应该是 1 而不是0。

[1/0] 的向量是目标变量。

标准的 RNN 预处理步骤照常适用——我们将在开头填充序列,使它们的长度都相同(比如 50),字符将被编码为数字而不是字符串等。

由于这里的字典很小(26 个字母 + 空格 + 填充),网络架构可以是一个相当简单的架构。单个嵌入层 + 循环层就足够了。

以这种方式构建问题允许我们使用普通 RNN 或开箱即用的 LSTM/GRU,而不是创建一个自定义架构,该架构将两个单独的字符串作为每个数据点的输入并抛出一个数字。

您可以试一试这种方法,看看是否能够令人满意地击败基线模型。

字符级 RNN 的好读物是Andrej Karpathy 的博客代码他试图解决的问题是不同的,代码是纯 numpy 的,但它仍然很好地捕捉到了这个想法。

我会使用一些规范化作为预处理,例如:

  • Jr转换为Junior.
  • 如 ldmtwo 所说,将名称转换为 Soundex

然后为此使用字符串算法而不是 ML,例如 Z 算法、KMP 算法或 Levenshtein 距离,然后在分数上使用阈值。