代码之家  ›  专栏  ›  技术社区  ›  Stanleyrr

无法使用python检测乱七八糟的名称

  •  0
  • Stanleyrr  · 技术社区  · 8 年前

    我正在尝试构建一个python模型,它可以将帐户名分类为合法的或胡言乱语的。在这种特殊情况下,大写并不重要,因为一些合法的帐户名可能由所有大写或小写字母组成。

    免责声明:这只是一个内部研究/实验,不会对分类器结果采取实际行动。

    特别是,有两个可能的特征可以显示帐户名可疑、胡言乱语或两者兼而有之:

    1. 名字或名字的奇怪/随机拼写由纯数字或大部分数字组成。符合这些条件的帐户名示例如下: 128、127、H4RUGZ4SX383A6N64HPO、TT、T66、T65、ASDFDS .

    2. 这个名字有两个组成部分(假设没有一个名字有两个以上的组成部分),这两个组成部分的拼写和发音非常相似。符合这些条件的帐户名示例如下: 哈亚,哈亚,哈亚 .

    如果帐户名同时满足上述两个条件(即“asdfs lsdfs”、“332 333”),则也应视为可疑。

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

    合法帐户名的示例包括(这些名称是合成的,但确实反映了真实世界中合法帐户名的类似样式): 迈克尔、萨拉、何塞·科尔梅纳雷斯、迪米特尔、何塞·拉斐尔、摩根、爱德华多·梅迪纳、路易斯·门德斯、希卡鲁、赛琳娜、张明、刘旭婷、陈征 .

    我在stackoverflow上看到过一些类似的问题,它们要求找到检测乱七八糟文本的方法。但这些都不适合我的情况,因为合法的文本和文字实际上有意义,而人名通常没有意义。我也希望能够做的只是基于帐户名,而不是其他。

    现在,我的脚本使用python的fuzzy-wuzzy包并使用50%作为相似度阈值来查找可疑帐户名(名称中类似的组件)的第二个特征。脚本如下:

    from fuzzywuzzy import fuzz
    from fuzzywuzzy import process
    
    import pandas as pd
    import numpy as np
    
    accounts = 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 = None
    
    accounts.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 
    

    这个结果对于脚本的设计来说是可靠的,但是我也希望能够用第一个特征(奇怪的/随机的拼写或名称由纯粹的或大部分的数字组成)来显示乱七八糟的帐户名。到目前为止,我还没有找到解决办法。

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

    1 回复  |  直到 8 年前
        1
  •  2
  •   David Dale    8 年前

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

    下面是这种语言模型的一个快速而肮脏的例子。它是1-gram、2-gram和3-gram语言模型的混合体,在一个棕色的语料库上进行训练。我相信你能找到更多相关的培训数据(如所有演员名单)。

    from nltk.corpus import brown
    from collections import Counter
    import numpy as np
    
    text = '\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[char] + weights[1] + bigrams[context1] * 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)))
    

    你看,在大多数情况下,乱七八糟的名字比普通名字更“奇怪”。例如,这里可以使用5.9的阈值。

    128                  ->    5.9073
    127                  ->    6.0044
    h4rugz4sx383a6n64hpo ->    7.4261
    tt                   ->    6.3916
    t66                  ->    7.3553
    t65                  ->    7.2584
    asdfds               ->    6.1796
    Michael              ->    5.6694
    sara                 ->    5.5734
    jose colmenares      ->    4.9489
    Dimitar              ->    5.7058
    Jose Rafael          ->    5.8184
    Morgan               ->    5.5766
    Eduardo Medina       ->    5.5703
    Luis R. Mendez       ->    5.5337
    Hikaru               ->     6.439
    SELENIA              ->    7.1125
    Zhang Ming           ->    5.1594
    Xuting Liu           ->    5.5975
    Chen Zheng           ->    5.3341
    

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