파이썬 머신러닝 #3 - 스팀잇 아이디로 성별 예측하기

반응형

안녕하세요. @anpigon 입니다.

이전에 "파이썬 형태소 분석"이란 제목으로 시리즈를 시작했는데, 시리즈 제목을 머신러닝으로 변경했습니다. 형태소 분석은 스팀잇에 작성한 글로 "단어구름"를 만들어보고 싶어서 시작했습니다. 하지만, 형태소 분석만 하고 끝내기엔 아쉬워 머신러닝을 공부해서 재미난 걸 만들어 보려고 합니다.

이번에는 머신러닝을 사용하여 스팀잇 아이디의 성별을 예측해보겠습니다.

참고로, 단어구름 만들기 포스팅에 댓글을 남기시면 여러분이 스팀잇에 작성한 글을 분석하여 단어구름를 만들어 드립니다. 현재 봇이 돌고 있습니다. 하지만, 노트북에서 봇을 돌리고 있어서 분석 시간은 조금 걸립니다.

 


나이브 베이즈 분류

나이브 베이즈 분류(Naïve Bayes Classification)는 텍스트 분류에 사용됩니다. 대표적으로 스팸 메일을 필터링하는 데 사용되고 있습니다.

자세한 설명은 조대협님 블로그에 설명이 잘 되어있어 링크로 대신합니다.
[조대협의 블로그] 나이브 베이즈 분류 (Naive Bayesian classification) #1 - 소개


아래 나이브 베이즈 분류 예제는 https://www.nltk.org/book/를 참고 했습니다.

 


이름 성별 분류하기

남성과 여성의 이름에는 몇 가지 독특한 특성이 있다. a, e, i 로 끝나면 여성이고 k, o, r, s, t 로 끝나면 남성일 가능성이 크다. 이러한 차이를 이용하여 데이터를 학습하는 머신러닝을 구현해 보자.

먼저 이름에서 맨 마지막 알파벳을 가져오는 함수를 구현한다. 이 함수는 feature set이라고 불리는 데이터를 반환한다.

import re

def gender_features(word):
    return {'last_letter': re.sub('[0-9]', '', word)[-1].lower()}


구현된 gender_features() 함수를 실행하고 결과를 확인해보자.

 

학습 데이터 준비하기

머신러닝을 학습할 데이터를 준비하자. male.txt 파일과 female.txt 파일에서 머신러닝이 학습할 데이터를 가져온다. 해당 파일은 <github.com/tomazas>에서 가져왔다.

labeled_names = ([(name, 'male') for name in open('male.txt').read().split('\n')] +
[(name, 'female') for name in open('female.txt').read().split('\n')])

import random
random.shuffle(labeled_names)
결과

 

분류기 학습시키기

gender_features() 함수로 학습 데이터 처리하여 feature set를 만든다. 그리고 feature set에서 학습 세트(train set)와 테스트 세트(test set)로 나눈다. 학습 세트는 나이브 베이즈 분류 머신러닝을 학습시키는 데 사용된다. 그리고 테스트 세트는 학습된 머신러닝을 검증하는 데 사용한다.

import nltk

featuresets = [(gender_features(n), gender) for (n, gender) in labeled_names]
train_set, test_set = featuresets[500:], featuresets[:500]

classifier = nltk.NaiveBayesClassifier.train(train_set)

 

머신러닝 테스트하기

학습 데이터에 없는 이름을 가지고 테스트해보자. Neo는 남성, Trinity는 여성이라는 결과가 나왔다.


테스트 세트를 이용하여 나이브 베이즈 분류기의 정확도를 확인해보자. 이 학습된 분류기의 정확도는 74.2%이다.

nltk.classify.accuracy(classifier, test_set)
0.742


마지막으로 show_most_informative_features() 함수를 사용하면 이름의 성별을 구별하는 기준을 확인할 수 있다. a로 끝나는 이름은 여성일 확률이 35.8%이다. 그리고 k로 끝나는 이름은 남성일 확률이 32.8%이다.

classifier.show_most_informative_features()

 

스팀잇 아이디로 성별 알아내기

성별을 분류해주는 머신러닝 학습이 완료되었습니다. 이제 이 포스팅의 목적인 스팀잇 아이디로 성별을 예측해보겠습니다.

아래와 같이 성별을 예측하여 결과를 반환하는 함수를 구현합니다.

def predict(usernames):
    return [{u: classifier.classify(gender_features(u))} for u in usernames]


성별을 알고 싶은 스팀잇 아이디 데이터를 준비합니다. 아래 데이터는 나의 팔로우에서 무작위로 가져왔습니다. 익숙한 아이디가 많이 보이네요.

input_data = [
    'ned', 
    'etainclub',
    'codingart',
    'codingman',
    'ksc',
    'imrahelk', 
    'newbijohn', 
    'coinfarmer165', 
    'ponzipanda',
    'blockchainstudio',
    'jisoooh0202',
    'jamieinthedark',
    'xinnong',
    'bbooaae',
    'onehand',            
    'osyvv',
    'bluengel',
    'jungjunghoon',
    'duplicate',
    'lucky2',       
]


앞에서 구현한 predict() 함수를 실행하니, 아래와 같은 결과가 나왔습니다.

머신러닝 학습 데이터가 스팀잇 아이디가 아니었고, 정확도가 74%인 것을 참작하면 만족한 결과가 나왔습니다. 성별이 반대로 나오신 분들께는 죄송합니다.


여기까지 읽어주셔서 감사합니다.

반응형