Невозможно обнаружить имена, используя Python - PullRequest
0 голосов
/ 02 июня 2018

Я пытаюсь построить модель Python, которая могла бы классифицировать имена учетных записей как законные, так и бессмысленные.В данном конкретном случае использование заглавных букв не имеет значения, поскольку некоторые допустимые имена учетных записей могут состоять из букв верхнего или нижнего регистра.

Отказ от ответственности: это просто внутреннее исследование / эксперимент, и никаких реальных действий в отношении результатов классификатора предприниматься не будет.

В частности, есть 2 возможные характеристики, которыеможет показывать имя учетной записи как подозрительное, бессмысленное или и то и другое:

  1. Странное / случайное написание имени или имени состоит из чисто или в основном чисел.Примеры имен учетных записей, которые соответствуют этим критериям: 128, 127, h4rugz4sx383a6n64hpo, tt, t66, t65, asdfds .

  2. Имя имеет 2 компонента (предположим,что ни одно имя никогда не будет иметь более 2 компонентов), а написание и произношение этих 2 компонентов очень похожи.Примеры имен учетных записей, которые соответствуют этим критериям: Jala Haja, Hata Yaha, Faja Kaja .

Если имя учетной записи соответствует обоим вышеуказанным критериям (т. Е. 'asdfs lsdfs ',' 332 333 ') это также следует считать подозрительным.

С другой стороны, законное имя учетной записи не обязательно должно содержать имя и фамилию.Обычно это имена из популярных языков, таких как римский / латинский (например, испанский, немецкий, португальский, французский, английский), китайский и японский.

Примеры допустимых имен учетных записей включают (эти имена составлены, но отражают аналогичные стили допустимых имен учетных записей в реальном мире): Майкл, Сара, Хосе Кольменарес, Димитар, Хосе Рафаэль, Морган, ЭдуардоМедина, Луис Р. Мендес, Хикару, СЕЛЕНИЯ, Чжан Мин, Сютинг Лю, Чэнь Чжэн .

Я видел несколько схожих вопросов о Stackoverflow, в котором спрашивались способы обнаружения бессмысленных текстов.Но они не соответствуют моей ситуации, потому что законные тексты и слова действительно имеют значения, тогда как человеческие имена обычно не имеют.Я также хочу иметь возможность сделать это только на основе имен учетных записей и ничего больше.

Прямо сейчас мой сценарий позаботится о том, чтобы найти вторую характеристику подозрительных имен учетных записей (схожие компоненты в названии), используя пакет Fuzzy Wuzzy в Python и используя 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-й характеристикой (странное / случайное написание)или имя состоит из чисто или в основном чисел).Пока что я не нашел решения этого вопроса.

Кто-нибудь может помочь?Любые отзывы / предложения будут с благодарностью!

1 Ответ

0 голосов
/ 03 июня 2018

Для 1-го признака вы можете обучить основанную на символах языковую модель n-граммы и рассматривать все имена с низкой средней вероятностью на символ как подозрительные.

Быстрый и грязный пример такогоязыковая модель ниже.Это смесь 1-граммовой, 2-граммовой и 3-граммовой языковых моделей, обученных на корпусе Брауна.Я уверен, что вы можете найти более подходящие учебные данные (например, список всех имен актеров).

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

Конечно, более простое решение - собрать список популярных имен на всех ваших целевых языках и вообще не использовать машинное обучение - просто поиск.

...