import pandas as pd
import matplotlib.pyplot as plt
from sklearn import metrics
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
목표
- 버섯의 특징을 활용해 독/식용 버섯을 분류
- Decision tree 시각화 & 과대적합 제어
- 특성선택(Feature selection) 해보기
data = pd.read_csv('./data/mushroom.csv')
data
poisonous cap-shape cap-surface cap-color bruises odor gill-attachment gill-spacing gill-size gill-color ... stalk-surface-below-ring stalk-color-above-ring stalk-color-below-ring veil-type veil-color ring-number ring-type spore-print-color population habitat
0 p x s n t p f c n k ... s w w p w o p k s u
1 e x s y t a f c b k ... s w w p w o p n n g
2 e b s w t l f c b n ... s w w p w o p n n m
3 p x y w t p f c n n ... s w w p w o p k s u
4 e x s g f n f w b k ... s w w p w o e n a g
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
8119 e k s n f n a c b y ... s o o p o o p b c l
8120 e x s n f n a c b y ... s o o p n o p b v l
8121 e f s n f n a c b n ... s o o p o o p b c l
8122 p k y n f y f c n b ... k w w p w o e w v l
8123 e x s n f n a c b y ... s o o p o o p o c l
8124 rows × 23 columns
X = data.iloc[:,1:] # 문제
y = data.iloc[:,0] # y = data['poisonous'] 정답
y.value_counts()
e 4208
p 3916
Name: poisonous, dtype: int64
# cap shape가 x인 cap color 행의 수는?
X[X['cap-shape']=='x']['cap-color'].value_counts() # cap-color로 굳이 한번 더 인덱싱 안해도 같은 숫자
n 920
g 920
e 596
y 528
w 512
p 84
b 64
c 16
r 8
u 8
Name: cap-color, dtype: int64
# cap-surface가 f와 같고 gill-size가 b인 cap-shape컬럼값을 value_counts() 해보자
X[(X['cap-surface']=='f')&(X['gill-size']=='b')]['cap-shape'].value_counts()
x 996
f 948
b 48
k 48
Name: cap-shape, dtype: int64
Object형을 숫자형으로 바꿔줘야 할때 -> 인코딩
S -> 0 / C->1 / Q-> 2로 표현
표현하고 싶은 컬럼을 1로 나머지는 0으로 변경
One-hot 인코딩을 할 수록 특징이 늘어나고 -> 많아지면 과대적합이 된다.
원 핫 인코딩
X_one_hot = pd.get_dummies(X) #문제 X변수 원 핫 인코딩
# 각 컬럼별로 전부 원핫 인코딩
cap-shape_b cap-shape_c cap-shape_f cap-shape_k cap-shape_s cap-shape_x cap-surface_f cap-surface_g cap-surface_s cap-surface_y ... population_s population_v population_y habitat_d habitat_g habitat_l habitat_m habitat_p habitat_u habitat_w
0 0 0 0 0 0 1 0 0 1 0 ... 1 0 0 0 0 0 0 0 1 0
1 0 0 0 0 0 1 0 0 1 0 ... 0 0 0 0 1 0 0 0 0 0
2 1 0 0 0 0 0 0 0 1 0 ... 0 0 0 0 0 0 1 0 0 0
3 0 0 0 0 0 1 0 0 0 1 ... 1 0 0 0 0 0 0 0 1 0
4 0 0 0 0 0 1 0 0 1 0 ... 0 0 0 0 1 0 0 0 0 0
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
8119 0 0 0 1 0 0 0 0 1 0 ... 0 0 0 0 0 1 0 0 0 0
8120 0 0 0 0 0 1 0 0 1 0 ... 0 1 0 0 0 1 0 0 0 0
8121 0 0 1 0 0 0 0 0 1 0 ... 0 0 0 0 0 1 0 0 0 0
8122 0 0 0 1 0 0 0 0 0 1 ... 0 1 0 0 0 1 0 0 0 0
8123 0 0 0 0 0 1 0 0 1 0 ... 0 0 0 0 0 1 0 0 0 0
8124 rows × 117 columns
라벨인코딩
X['habitat'].unique()
array(['u', 'g', 'm', 'd', 'p', 'w', 'l'], dtype=object)
dic = {
'u': 2,
'g': 1,
'm': 3,
'd': 5,
'p': 4,
'w': 6,
'l': 7
}
X['habitat'].map(dic)
0 2
1 1
2 3
3 2
4 1
..
8119 7
8120 7
8121 7
8122 7
8123 7
Name: habitat, Length: 8124, dtype: int64
X_train,X_test,y_train,y_test = train_test_split(X_one_hot,y,test_size=0.3,random_state=1)
print(X_train.shape)
print(X_test.shape)
print(y_train.shape)
print(y_test.shape)
(5686, 117)
(2438, 117)
(5686,)
(2438,)
t_model = DecisionTreeClassifier()
t_model.fit(X_train,y_train)
DecisionTreeClassifier()
t_model.score(X_test,y_test)
1.0
!pip install graphviz # 시각화 할때 쓰는 라이브러리
from sklearn.tree import export_graphviz
# class_names -> 정답 이름, feature_names -> 문제이름 (컬럼명들을 넣는다),
# filled -> 색깔,impurity -> 불순도값 표시 여부
export_graphviz(t_model, out_file = 'tree.dot',class_names = ['독', '식용'],
feature_names= X_one_hot.columns, filled=True, impurity=False )
# graphviz형태로 tree.dot으로 파일을 내보냈는데 이를 가져와서 시각화 한다
import graphviz
with open('./tree.dot', encoding='UTF-8') as f:
dot_graph = f.read()
# graphviz.Source(소스값)
display(graphviz.Source(dot_graph))
#이때 pip install로 경로를 못 잡아서 직접 graphviz 다운받고 ,
환경변수 -> 사용자변수 path에 설치된 graphviz 경로추가 ,
시스템변수 path에 설치된 graphviz경로 + dot.exe 추가 후 재실행
value = [0, X] or [X,0]인것 : 순수노드들
질문을 통해 순수노드만 나올때까지 질문을 한다.
t_model = DecisionTreeClassifier( max_depth = 4) # max_dept =4로 지정한 후 다시 돌려본 결과
질문이 4개까지로 제한되어 나온다.
질문을 제한하여 순수노드가 아닌 leaf_node가 (value=[76,62]) 나온다
impurity = True로 바꾸면 gini의 값도 나온다
min_samples_leaf=30으로 samples가 30이상인 질문들만 가능하게 제한한다.
특성선택
fi = t_model.feature_importances_ #특성이 영향을 끼친 정도를 알 수 있다.
fi
df = pd.DataFrame(fi, index = X_one_hot.columns)
df.sort_values(by = 0, ascending=False) # ascending = false-> 내림차순
0
odor_n 0.627391
stalk-root_c 0.170885
stalk-surface-below-ring_y 0.091794
spore-print-color_r 0.033148
gill-spacing_w 0.027991
... ...
gill-color_e 0.000000
gill-color_b 0.000000
gill-size_b 0.000000
gill-spacing_c 0.000000
habitat_w 0.000000
117 rows × 1 columns
특성이 영향을 끼친 정도를 알 수 있다. -> 중요한 특성만을 가지고 모델에 넣거나
다른 모델에 적용 시킬 수 있다.
'빅데이터 서비스 교육 > 머신러닝' 카테고리의 다른 글
예제 타이타닉 생존자 예측분석 (0) | 2022.06.24 |
---|---|
Cross validation (0) | 2022.06.24 |
Decision Tree (0) | 2022.06.23 |
머신러닝 데이터 예측 (KNN모델) (0) | 2022.06.23 |
KNN 모델 (0) | 2022.06.22 |