본문 바로가기
개발/빅데이터

머신러닝 decision tree 실습(feat. data 전처리)

by 자유로운 코끼리 2020. 7. 11.
728x90

우리가 이때까지 가설을 세우고, 검증하는 걸 해봤었죠.

https://free-eunb.tistory.com/34?category=916108

 

[데이터 분석] 캐글 첫 시작, 타이타닉 문제 풀어보기(구글 스프레드 시트)

오늘은 구글 스프레드 시트를 이용해서 아주 간단한 빅데이터 분석을 해보려 합니다. https://www.kaggle.com/c/titanic Titanic: Machine Learning from Disaster Start here! Predict survival on the Titanic a..

free-eunb.tistory.com

이번에는 이 타이타닉 데이터를 가지고 decision tree 알고리즘을 통해 해보겠습니다.

Feature , Lable이 필요합니다.

Feature은 정답을 맞추는데 중요한 데이터입니다.

Lable은 찾고자 하는 데이터입니다.

 

0. 의사결정트리를 이용하는 이유

이를 이용하는 이유는

1) 해상사고에 대한 지식이 없어도, 데이터를 전처리만 해주면 트리가 알아서 해줍니다.

 =>  Feature, Lable만 가지고 모든 분야에서 사용할 수 있는 범용적인 방식입니다.

2) (구현체를 이용하면)데이터를 다뤄보는 경험을 쉽게 할 수 있습니다.

 

등등이 있습니다.

이런 의사결정트리에 대해

직접 만들어도 되지만,

만들어놓은 구현체를 가져다 쓰면 됩니다.

 

scikit-learn에 있는 방대한 패키지에서 decision tree를 이용해볼께요.

 

우선! 준비를 해볼까요?

데이터를 불러와주고-

import pandas as pd

train = pd.read_csv("data/train.csv") #데이터 부르기
train.head()

test = pd.read_csv("data/test.csv")

1. Seaborn을 이용한 시각화

import seaborn as sns

sns.countplot(data=train, x="Pclass",hue="Survived") #데이터 시각화

시각화 하면서 한번 스윽 데이터가 잘 불러왔는지 봤구용! 

이렇게 시각화된 데이터를 통해서 클래스가 높을수록 살아남을 확률이 높다는 것을 확인할 수 있었습니다.

 

이제 머신러닝 모델을 이용해서 가설을 검증해보겠습니다.

2. DecisionTreeClassifier

의사결정트리는 fit(Train)으로 학습한 다음, 이를 바탕으로 predict(test) 예측합니다.

feature_name =["Pclass"]
x=train[feature_name]
label_name="Survived"
y=train[label_name]
x.head()
y.head()

왼(x.head())  오(y.head())

이제 의사결정트리를 이용하기 위해

scikit에 있는 구체화된 트리를 가져올 겁니다.

pip install -U scikit-learn 으로 sklearn 사용할 준비해주시구~

from sklearn.tree import DecisionTreeClassifier

model = DecisionTreeClassifier()

이제 학습만 시켜주면 되는데요-

model.fit(x,y)

이렇게 하면 학습이 된겁니다.

이제 이를 시각화 해보면 되는데요-

 

3. Graphviz

모듈을 설치해주시고, 

conda install graphiz

pip install graphiz

 

오류가 나면 다음 내용을 참고해주세요:-)

https://free-eunb.tistory.com/14?category=916108

 

[파이썬,머신러닝] graphviz 설치/실행 에러 해결

Decision tree를 하는 과정에서 graphviz관련 오류가 날 때가 있습니다. 1. ModuleNotFoundError: No module named 'graphviz' 에러 파이썬에서 해당 라이브러리가 설치되지 않았다는 것을 의미합니다. 그럼 설치..

free-eunb.tistory.com

import 해준다음 export_graphviz라는 함수를 이용해주면 시각화할 수 있습니다:>.

import graphviz
from sklearn.tree import export_graphviz

tree = export_graphviz(model,feature_names=feature_name,
                      class_names=["Perish","Survived"])
graphviz.Source(tree)

이렇게 학습시켜보았습니다.

다음 그림을 해석해보자면 2.5class보다 낮을 경우, 즉 1,2등급 class일 경우 살아남고, 3등급일경우 죽을거라는 것을 트리 스스로 판단한 것입니다.

 

이제 test 데이터를 가져와서 학습한 모델을 적용해볼 차례입니다.

x_test=test[feature_names]
model.predict(x_test)

자 이제 이를 캐글에 제출하면 되는데요!

그에 앞서 어떻게 제출해야되는 지 그 양식을 한번 확인해보겠습니다.

submit = pd.read_csv("data/gender_submission.csv")
submit

이는 성별로 예측한 것으로 이미 survived에 값이 들어가 있는데요.

남자면 0 영자면 1이 들어가게 예측한 예제라고 보시면 됩니다.

 

이제 이 예제에 맞추어 우리가 예측한 값을 넣어볼까요?

prediction_list=model.predict(x_test)
submit = pd.read_csv("data/gender_submission.csv")
submit["Survived"] = prediction_list

그리고 다시 엑셀 파일로 만들어 주는데, 이때 앞에 번호가 적인 index도 같이 저장하면 오류가 나기때문에

submit.to_csv("decision-tree.csv",index=False)

이제 이 파일을 캐글에 제출만하면 끝-!

그렇게 높은 점수가 나오지는 않았어요!

이제 feature에 요소를 넣어주면서 예측률이 높아지도록 만들면 되겠죠?

 

5. data 전처리 - 글자로된 data 숫자로 바꾸어주기!

pclass외에도 Sex라는 요소를 추가하여 만들어보겠습니다.

Sex와 같은 숫자가 아닌 데이터는 숫자화 시켜주어야

의사결정나무와 같은 수학적 알고리즘이 이해할 수 있습니다.

train["Sex_encode"] = train["Sex"].replace("male",0).replace("female",1)
test["Sex_encode"] = test["Sex"].replace("male",0).replace("female",1)

 

전처리를 통해 숫자로 바꾸어준 성별을 feature_name에 넣어줍니다.

feature_name =["Pclass","Sex_encode"]

그 다음 실행시켜보면 다음과 같은 결과를 볼 수 있습니다.

터음에 성별로 나누어진 이유는, 의사결정나무가 성별을 더 중요한 요소로 생각했기 때문입니다.

왼쪽부터 남자 1등급 - 2등급 - 3등급, 여자 1등급 - 2등급 - 3등급인데요.

남자는 다 죽,,,ㅠ 여자는 1,2 등급은 사네요...!!

이를 또 캐글에 올려볼 수 있습니다:)

 

 

6. Nan data, 비어있는 data

train["Age"].isnull() #값이 있으면 false, 없으면 true
train[train["Age"].isnull()]

 

다시 train으로 다시 감싸주면 Age 컬럼중 비어있는 열들이 나옵니다.

비어있으니 nan 값으로 보이는 거죠.

train[train["Fare"].isnull()]

이렇게 니오는 이유는 nan값이 없기 때문인데요.

 

 

test값을 보면 nan값을 확인할 수 있죠.

test[test["Fare"].isnull()]

그리고 우리가 이런 nan값 때문에 제대로 예측하지 못하게 되는겁니다.

 

이때 nan값을 채우는 여러가지 방법이 있는데,

그 중 하나가 train data의 fare의 평균을 넣어주는 방법입니다.

또  0으로 해줄 수도 있는데, 우선 0으로 넣어볼까요?

test["Fare"]=test["Fare"].fillna(0)
test[test["Fare"].isnull()]

 이제 Fare을 이용할 수 있습니다.

 

이를 넣어 tree를 계산해보면 가지가 엄청 많아지게 되는데요. 

이 가지를 적당하게 주기 위해서는 max_depth를 통해 그 가지에 제한을 줄 수 있습니다.

model = DecisionTreeClassifier(max_depth=5)

댓글