타이타닉 생존자 예측이라는 주재를 가지고 신경망으로 분류를 했던 적이 있습니다. 당시엔 Keras를 사용했는데요. 이번에는 결정트리 Decision Tree 기법을 이용하려고 합니다. 그리고 사이킷런 Scikit Learn을 이용할 거구요^^ 먼저 데이터는 이전에 했던 [Keras] 타이타닉 생존자 예측에서 사용한 엑셀로된 데이터 입니다.
import pandas as pd import numpy as np import matplotlib.pyplot as plt %matplotlib inline raw_data = pd.read_excel('titanic.xls') raw_data.info()
필요한 모듈과 데이터를 읽었습니다.
데이터가 1300개 정도로 보이지만, 중요 데이터인 age가 null이 있어서 살짝 손을 봐줘야 합니다.
tmp = [] for each in raw_data['sex']: if each == 'female': tmp.append(1) elif each == 'male': tmp.append(0) else: tmp.append(np.nan) raw_data['sex'] = tmp raw_data['survived'] = raw_data['survived'].astype('int') raw_data['pclass'] = raw_data['pclass'].astype('float') raw_data['sex'] = raw_data['sex'].astype('float') raw_data['sibsp'] = raw_data['sibsp'].astype('float') raw_data['parch'] = raw_data['parch'].astype('float') raw_data['fare'] = raw_data['fare'].astype('float') raw_data = raw_data[raw_data['age'].notnull()] raw_data = raw_data[raw_data['sibsp'].notnull()] raw_data = raw_data[raw_data['parch'].notnull()] raw_data = raw_data[raw_data['fare'].notnull()] raw_data.info()
이렇게 필요한 데이터들은 숫자로 변경하고, NaN이 아닌 데이터들만 가져오는 겁니다. 저기처럼 다 notnull() 처리할 필요 없이 사실 age 컬럼에만 해주면 되는데.. 어쩌다 저렇게 네 줄짜리가 되었는지.ㅠㅠ. 아마 코드 돌려막기와 확인하기 귀차니즘 때문이겠죠~
그리고 나면 저렇게 데이터가 만들어 집니다. 흠.. 그러고 보니... age의 데이터보다 하나가 더 적네요... 그렇다면 나머지 어딘가에도 null이 있었다는 거군요^^
데이터 head()를 보면 저렇습니다.~
train_pre = raw_data[['pclass','sex','age','sibsp','parch','fare']] train_pre.head()
필요한 컬럼만 다시 가져옵니다. 변수 이름 작업법이라는 교육이 있으면 꼭 들어야겠습니다. ㅠㅠ.
이제... 이렇게 만들고 난 후~
from sklearn.model_selection import train_test_split X_train, X_test, y_train, y_test = train_test_split(train_pre, raw_data[['survived']], test_size=0.1, random_state=13)
흠 훈련용 데이터와 테스트용 데이터로 나눕니다. sklearn에서 제공하는 train_test_split을 사용했고, 세상에서 가장 완벽한 숫자인 13을 random_state로 결정했습니다. 1
X_train = X_train.reset_index() X_train = X_train.drop(['index'], axis=1) X_test = X_test.reset_index() X_test = X_test.drop(['index'], axis=1) y_train = y_train.reset_index() y_train = y_train.drop(['index'], axis=1) y_test = y_test.reset_index() y_test = y_test.drop(['index'], axis=1)
그리고 가장 마음에 안 드는 코드인 인덱스를 좀 정리하는 곳입니다. 생각해보니... 데이터를 나누기 전에 저걸하고, 나누면 저렇게 네 번 복사한듯 한 무식함은 없을텐데.ㅠㅠ. 뭐 아무튼 그러합니다.
from sklearn.tree import DecisionTreeClassifier tree_clf = DecisionTreeClassifier(max_depth=3, random_state=13) tree_clf.fit(X_train, y_train) print('Score: {}'.format(tree_clf.score(X_train, y_train)))
이제.. 드디어 결정트리 DecisionTreeClassifier 분류기를 사용합니다. depth는 3단계 정도로 보고... random_state는 가장 완벽하다는 그 숫자 13을 사용합니다.^^. 아무튼~ 훈련 성과를 볼까요?
80%가 넘네요... 그냥 만족할렵니다.^^.
from sklearn.tree import export_graphviz export_graphviz( tree_clf, out_file="titanic.dot", feature_names=['pclass', 'sex', 'age', 'sibsp', 'parch', 'fare'], class_names=['Unsurvived','Survived'], rounded=True, filled=True ) import graphviz with open("titanic.dot") as f: dot_graph = f.read() dot = graphviz.Source(dot_graph) dot.format = 'png' dot.render(filename='titanic_tree', directory='images/decision_trees', cleanup=True) dot
이제 sklearn에서 Decision Tree를 사용할때의 가장 큰 장점인... 트리 구조를 보겠습니다.
와우~ 제일 상층부에서... 성별이 여성이면 오른쪽으로 ... 선실 등급이 1 혹은 2등급이면 그 밑으로 두개가 있지만, 뭐 둘다 살아남는군요... ㅎㅎ^^ 여하튼... 결정트리와 같은 알고리즘의 장점은 역시 저렇게 결정되는 과정을 쉽게 눈으로 확인할 수 있다는 거죠. 2
from sklearn.metrics import accuracy_score y_pred = tree_clf.predict(X_test) print("Test Accuracy is ", accuracy_score(y_test, y_pred)*100)
이제 테스트 데이터 셋에 적용해볼까요?
84.76%군요... max_depth를 높이면 과적합 위험성이 있죠.. 이 정도 선에서 마무리하는 것고 좋겠습니다. 사실.. recall이나 precision도 확인해야겠지만... 오늘은 여기까지^^
# pclass, sex, age, sibsp, parch, fare dicaprio = [3., 0., 19., 0., 0., 5.] winslet = [1., 1., 17., 1., 2., 100.] def isSurvived(name, person): isSurvive = 'not survived' if tree_clf.predict([person])[0] == 0 else 'survived' print(name, ' is ', isSurvive, ' --> ', max(tree_clf.predict_proba([person])[0])) isSurvived('Dicaprio', dicaprio) isSurvived('Winslet', winslet)
아... 디카프리오나 윈슬릿의 데이터를 넣어봐야죠~
흠... 디카프리오 형님 생존하지 못할 확율이 87.5%, 윈슬릿의 생존확률이 97.58%가 나오는군요... 뭐 아무튼.. Toy 프로젝트니까요...^^
'Theory > MachineLearning' 카테고리의 다른 글
전처리와 학습 과정을 하나의 과정으로 실행하는 sklearn의 pipeline (10) | 2020.04.06 |
---|---|
머신러닝을 이용한 Human Activity Recognition 실습 (12) | 2019.10.29 |
Scikit Learn을 이용한 라벨인코딩 - LabelEncode (6) | 2019.09.30 |
Scikit Learn (sklearn) SGDRegressor 사용할 떄 Loss 그래프 확인하는 방법 (10) | 2019.09.23 |
연습삼아 해보는 비트코인(bitcoin) 시세 예측하기 - 그런데 비트코인이랑 목요일이 뭔 관계가 있나??? (34) | 2018.01.08 |
주가 예측? 나도 해보자~ Forecast 수행에 적합한 Prophet (20) | 2017.08.03 |