使用Python检测无意义名称的难题

我正在尝试构建一个Python模型,用于将账户名称分类为合法或无意义。在这种特定情况下,字母的大小写并不重要,因为一些合法的账户名称可能全部由大写或小写字母组成。

免责声明:这仅是内部研究/实验,不会根据分类结果采取任何实际行动。

在我特定的情况下,有两种可能的特征可以揭示账户名称为可疑、无意义或两者兼有:

  1. 名称中包含奇怪/随机的拼写,或者名称纯粹或主要由数字组成。符合这些标准的账户名称示例包括:128, 127, h4rugz4sx383a6n64hpo, tt, t66, t65, asdfds

  2. 名称有两个组成部分(假设名称永远不会超过两个组成部分),且这两个组成部分的拼写和发音非常相似。符合这些标准的账户名称示例包括:Jala Haja, Hata Yaha, Faja Kaja

如果一个账户名称同时满足上述两个标准(例如 ‘asdfs lsdfs’, ‘332 333’),也应被视为可疑。

另一方面,合法的账户名称不需要同时包含名字和姓氏。它们通常是来自流行语言的名称,例如罗马/拉丁语系(如西班牙语、德语、葡萄牙语、法语、英语)、中文和日文。

合法的账户名称示例包括(这些名称是虚构的,但确实反映了现实世界中合法账户名称的类似风格):Michael, sara, jose colmenares, Dimitar, Jose Rafael, Morgan, Eduardo Medina, Luis R. Mendez, Hikaru, SELENIA, Zhang Ming, Xuting Liu, Chen Zheng

我在Stackoverflow上看到了一些稍微相似的问题,这些问题询问如何检测无意义文本。但那些问题不适合我的情况,因为合法的文本和单词实际上是有意义的,而人的名字通常没有意义。我还希望仅基于账户名称来实现这一点,而不依赖其他信息。

目前,我的脚本负责查找可疑账户名称的第二种特征(名称中相似的组成部分),使用Python的Fuzzy Wuzzy包,并以50%作为相似度阈值。脚本如下所示:

from fuzzywuzzy import fuzzfrom fuzzywuzzy import processimport pandas as pdimport numpy as npaccounts = pd.read_csv('dataset_with_names.csv', encoding = 'ISO-8859-1', sep=None, engine='python').replace(np.nan, 'blank', regex=True)pd.options.mode.chained_assignment = Noneaccounts.columns = ['name', 'email', 'akon_id', 'acct_creation_date', 'first_time_city', 'first_time_ip', 'label']accounts['name_simplified']=accounts['name'].str.replace('[^\w\s]','')accounts['name_simplified']=accounts['name_simplified'].str.lower()sim_name = []for index, row in accounts.iterrows():            if ' ' in row['name_simplified']:        row['name_simplified']=row['name_simplified'].split()        if len(row['name_simplified']) > 1:            #print(row['name_simplified'])            if fuzz.ratio(row['name_simplified'][0], row['name_simplified'][1]) >= 50:                sim_name.append('True')            else:                sim_name.append('False')        else:            sim_name.append('False')    else:        sim_name.append('False')        accounts['are_name_components_similar'] = sim_name 

该结果对于脚本设计的功能来说是可靠的,但我还希望能够识别出符合第一种特征(奇怪/随机拼写或名称纯粹或主要由数字组成)的无意义账户名称。到目前为止,我还没有找到解决方案。

有谁能帮忙吗?任何反馈/建议将不胜感激!


回答:

对于第一种特征,您可以训练一个基于字符的n-gram语言模型,并将所有平均每个字符概率低的名称视为可疑。

下面是一个快速而粗糙的语言模型示例。这是一个由1-gram、2-gram和3-gram语言模型混合而成的模型,训练于布朗语料库。我相信您可以找到更相关的训练数据(例如,所有演员的名字列表)。

from nltk.corpus import brownfrom collections import Counterimport numpy as nptext = '\n  '.join([' '.join([w for w in s]) for s in brown.sents()])unigrams = Counter(text)bigrams = Counter(text[i:(i+2)] for i in range(len(text)-2))trigrams = Counter(text[i:(i+3)] for i in range(len(text)-3))weights = [0.001, 0.01, 0.989]def strangeness(text):    r = 0    text = '  ' + text + '\n'    for i in range(2, len(text)):        char = text[i]        context1 = text[(i-1):i]        context2 = text[(i-2):i]        num = unigrams[char] * weights[0] + bigrams[context1+char] * weights[1] + trigrams[context2+char] * weights[2]         den = sum(unigrams.values()) * weights[0] + unigrams[context1] * weights[1] + bigrams[context2] * weights[2]        r -= np.log(num / den)    return r / (len(text) - 2)

现在您可以将此“怪异度”测量应用于您的示例。

t1 = '128, 127, h4rugz4sx383a6n64hpo, tt, t66, t65, asdfds'.split(', ')t2 = 'Michael, sara, jose colmenares, Dimitar, Jose Rafael, Morgan, Eduardo Medina, Luis R. Mendez, Hikaru, SELENIA, Zhang Ming, Xuting Liu, Chen Zheng'.split(', ')for t in t1 + t2:    print('{:20} -> {:9.5}'.format(t, strangeness(t)))

您会发现无意义的名称在大多数情况下比正常名称更“怪异”。您可以在这里使用例如3.9作为阈值。

128                  ->    5.5528127                  ->    5.6572h4rugz4sx383a6n64hpo ->    5.9016tt                   ->    4.9392t66                  ->    6.9673t65                  ->    6.8501asdfds               ->    3.9776Michael              ->    3.3598sara                 ->    3.8171jose colmenares      ->    2.9539Dimitar              ->    3.4602Jose Rafael          ->    3.4604Morgan               ->    3.3628Eduardo Medina       ->    3.2586Luis R. Mendez       ->     3.566Hikaru               ->    3.8936SELENIA              ->    6.1829Zhang Ming           ->    3.4809Xuting Liu           ->    3.7161Chen Zheng           ->    3.6212

当然,一个更简单的解决方案是收集您目标语言中所有流行名称的列表,完全不使用机器学习 – 只进行查找。

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注