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

in #busy6 years ago (edited)

mindset3536805_1920.jpg

안녕하세요. @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%인 것을 참작하면 만족한 결과가 나왔습니다. 성별이 반대로 나오신 분들께는 죄송합니다.


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


이전글
Sort:  

크 멋지네요. @blockchainstudio@jamieinthedark 둘다 남자로 나오는 거 보니 성능이 아주 좋네요ㅋㅋ 아마 확률이 나올텐데 확률도 같이 보여주면 더 재밌을듯ㅎㅎ 앗 우리 곰돌이도 테스트해봐줘요ㅋㅋ

성능이 아주 좋아요~😁
그리고 곰도리 아이디 gomdory는 여성으로 나옵니다.ㅎㅎ

에잉 농담이시겠지만 다큐로 받자면 이건 아이디엔 적용 안되죠. 말 그대로 서구권 세례명에 적용되는 얘기. 가령 한국식 이름에도 아, 화, 희, 등이 끝자리면 여자이름일 확률이 높다는 식의 얘기인데 아이디는 그냥 사물일 수도 있고 짓는 사람이 맘대로 하는 거니까.

재미를 주려고 스팀잇 아이디를 끼워 넣었습니다.😁
한국식 이름도 끝자리로 성별을 예측할 수 있겠네요. 그리고 제이미님 말대로 아이디만으로 성별을 예측하는 것은 어렵습니다.

아이디가 지칭하는 사물의 종류를 기반으로 예측을 하도록 데이터를 넣으면 좀더 정답에 근접할 수 있겠죠. 그래도 이름에 비해선 정확도가 현저히 떨어지겠지만.

아이디만으로 성별을 예측하는 것을 힘듭니다. 아이디를 포함하여 스팀잇에 작성한 글이나 댓글을 분석해서 성별을 예측해야 정확도가 올라갈 것 같습니다.

네, 힘들다는건 제 원래 요지이기도 하죠. 제가 거기에 덧붙여서 얘기한건 아이디가 지칭하는 꽃, 고양이, 나무 등의 사물에서 확률을 조금 더 높여볼 수 있으리라는 얘기입니다. 아이디가 저나 뉴비존님처럼 세례명을 포함할 수도 있고요. 당연히 글, 댓글 등 기타 데이터를 추가 하면 더더욱 높아지겠지만, 원글에서도 아이디만 다루고 있으니 아이디에만 집중해봤죠. ㅎㅎ

곰돌이도 구해주셨군요ㅋㅋ

ㅋㅋ아 여기서 보니 뭐가 하나 생각났네요. 어제 자정쯤 쓴 글에 비지가 6시간 넘어서 왔는데 이런 경우 처음 봐요!

이럴수가 그런 경우는 계산을 어찌하려나. 20시간 안되어서 태그 안쓰고 글 하나 썼었는데 썼더라면 엉겹결에 보팅받았으려나ㅋㅋ

ㅋㅋ 재밌네여 소재가 다양하시군용😄

학습이 더 되면 80퍼이상으로 높일 수도 있는거네용?

아이디만으로 성별을 예측하는 것은 학습을 더 해도 80% 이상 올리기 힘들듯 합니다. 스팀잇 프로필 사진과 작성한 글,
댓글을 학습 데이터에 포함하면 정확도가 더 올라갈 수 있습니다.

하긴 우리 현실에서도 지현 수현 이런 이름은 애매하잖아요?

맞아요. 중성적인 이름은 성별을 예측하기가 애매합니다.

오 잼있어요! 나이 추측 안되나요? ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ

나이 추측까지... 하면 더 재미있겠어요. ㅎㅎ
재미있는 아이디어가 많네요.

형 나이 알 수 있는거야???ㅋㅋㅋㅋㅋ

응 그래서 너가 찌든 중년인걸 알게 되었지 ㅋㅋㅋㅋㅋㅋㅋ

아씨 왜케 형한테 밀리는거 같지.................ㅋㅋㅋㅋㅋ

날 이길 생각이였다니... 그게 더 놀랍다 ㅋㅋㅋㅋㅋ

ㅋㅋㅋㅋㅋ 아이디 적은건 농담이신듯
실제 이름갖고 하면 통계적으로 맞을듯 하군요

나이즈 베이즈 분류까지 스팀잇에서 보다니..ㅠㅠ
감격입니다. 안피곤님 안피곤하시면 한번 만나뵙고 싶습니다!

나이즈 베이즈 분류가 스팀잇에서는 처음 나왔나 보네요. 구글에서 참고할 수 있는 자료가 많아서 덕분에 쉽게 공부할 수 있었습니다. 저를 좋게 봐주셔서 감사합니다. 저도 감격입니다.😆

저는... 여성이었군요..........ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ

ㅋㅋㅋㅋ재미있는 결과에요.😁

Hi @anpigon!

Your post was upvoted by @steem-ua, new Steem dApp, using UserAuthority for algorithmic post curation!
Your UA account score is currently 0.983 which ranks you at #51929 across all Steem accounts.
Your rank has dropped 3941 places in the last three days (old rank 47988).

In our last Algorithmic Curation Round, consisting of 516 contributions, your post is ranked at #340.

Evaluation of your UA score:
  • Only a few people are following you, try to convince more people with good work.
  • The readers like your work!
  • You have already shown user engagement, try to improve it further.

Feel free to join our @steem-ua Discord server

@시리즈

@시리즈

아쉽게도 시리즈가 검색되지 않았네요. 관련 서비스가 이상하거나 추가 제안이 있다면 이 서비스 개발자 @nhj12311에게 문의해보면 좋지 않을까여?

@시리즈

@시리즈

@시리즈

@시리즈

@시리즈

아쉽게도 시리즈가 검색되지 않았네요. 관련 서비스가 이상하거나 추가 제안이 있다면 이 서비스 개발자 @nhj12311에게 문의해보면 좋지 않을까여?

아쉽게도 시리즈가 검색되지 않았네요. 관련 서비스가 이상하거나 추가 제안이 있다면 이 서비스 개발자 @nhj12311에게 문의해보면 좋지 않을까여?

아쉽게도 시리즈가 검색되지 않았네요. 관련 서비스가 이상하거나 추가 제안이 있다면 이 서비스 개발자 @nhj12311에게 문의해보면 좋지 않을까여?

아쉽게도 시리즈가 검색되지 않았네요. 관련 서비스가 이상하거나 추가 제안이 있다면 이 서비스 개발자 @nhj12311에게 문의해보면 좋지 않을까여?

아쉽게도 시리즈가 검색되지 않았네요. 관련 서비스가 이상하거나 추가 제안이 있다면 이 서비스 개발자 @nhj12311에게 문의해보면 좋지 않을까여?

아쉽게도 시리즈가 검색되지 않았네요. 관련 서비스가 이상하거나 추가 제안이 있다면 이 서비스 개발자 @nhj12311에게 문의해보면 좋지 않을까여?

아쉽게도 시리즈가 검색되지 않았네요. 관련 서비스가 이상하거나 추가 제안이 있다면 이 서비스 개발자 @nhj12311에게 문의해보면 좋지 않을까여?

잉...ㅜㅜ 한번 자세히 봐야겠습니다. 문제가 생긴거 같네요.

아쉽네요. 빨리 사용해보고 싶어요.😊
스팀잇에 멋진 기능이 생긴다고 생각하니 즐겁습니다.