DeseoDeSeo
[Machine Learning] ex04. mushroom 실습 본문
목표
- 버섯의 특징을 활용해 독/식용 이진 분류하기
- Decision Tree 모델 활용하기
- Decision Tree 학습현황 시각화 & 과대적합 제어 (하이퍼 파라미터 튜닝)
- 특성의 중요도를 파악, 확인하기 (불순한 정도를 파악하는 것: 지니 불순도)
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# train, test 랜덤 샘플링 도구
from sklearn.model_selection import train_test_split
# knn 모델 : from sklearn.neighbors import KNeighborsClassifier
# tree 분류 모델
from sklearn.tree import DecisionTreeClassifier
data 변수에 담아주기
# 생략된 모든 컬럼을 표시해줌
<==> pd.set_option('display.max_columns', None)
pd.options.display.max_columns = None
data = pd.read_csv("./data/mushroom.csv")
data
정보 확인
data.info() # 데어터 타입 object, 결측치x
< 모든 컬럼에는 문자열 데이터만 들어있다 >
데이터 전처리 및 탐색
- 문제(특성)와 답(레이블) 분리
- x, y 통계량 확인
- 머신러닝 모델은 숫자만을 인식할 수 있음 : 문자 -> 숫자
- 훈련셋, 테스트셋 분리
♧ poisonous -> y
♧ poisonous 제외한 나머지 컬럼 -> xx = data.iloc[:,1:]
# 동일 값 나옴. data.loc[:,'cap-shape':] data.drop('poisonous', axis =1) # 데이터 변수에 초기화 되지 않는다.
y = data['poisonous']
# data.loc[:,'poisonous']
y
통계량 확인해보기
- 문자 데이터(범주데이터)에 대한 통계는 최빈값, 유니크한 값을 표현해줌.
x.describe()
y 클래스(카테고리) 개수 확인
# 식용 버섯에 대한 클래스가 300여개 정도 더 많은 상황
y.value_counts()
- 문자를 숫자로 변환 과정 => 인코딩(encoding)
- 값의 크고 작음의 의미가 없을 때 : one hot encoding
=> 분류하고자 하는 범주(종류) 만큼의 자릿수를 만들고
단 한개의 1과 나머지 0으로 - 채워서 숫자화 하는 방식
- 값의 크고 작음의 의미가 있을 때: 레이블 인코딩
x는 특성이라서 학습하기 위해서 숫자로 인코딩 필요.
: x_one_hot = pd.get_dummies(인코딩 대상)
x_one_hot = pd.get_dummies(x)
x_one_hot
# 크기확인
print(x_one_hot.shape)
y
훈련 셋, 데이터 셋 분리(7:3)
: 7:3이니까 test_size = 0.3임.
: 랜덤 스테이트 7
: 1. 랜덤 섞는 기능 2. 비율따라 분리하는 기능 => train_test_split
x_train, x_test, y_train, y_test =train_test_split(x_one_hot,y,test_size =0.3, random_state=7)
# 크기확인
print('훈련용 셋: ', x_train.shape, y_train.shape)
print('테스트용 셋: ', x_test.shape, y_test.shape)
모델링
- 모델 생성
- 모델 학습
- 교차 검증 진행해보기
- 모델 예측 및 평가
- 특성의 중요도 확인
- 학습 현황 시각화 (tree-white box)
- 과대 적합을 제어하는 파라미터 연결해보기
- 하이퍼 파라미터를 별도 정의 하지 않고
기본값으로 연결 # tree-model 변수에 모델 생성해보자.
tree_model =DecisionTreeClassifier()
모델 학습
# fit(훈련문제, 훈련답)
tree_model.fit(x_train,y_train)
< 교차검증 >
: 모델의 일반화 성능 확인
- 모든 데이터에 대해 모델이 얼마나 잘 맞추는지 평가.
- 한 번 나눠서 평가하는 것보다 여러번 하기 때문에 더 안정적인 통계적 평가 방법
- 방법론 : 훈련세트와 테스트 세트로 여러번 나눠서 평가
- 진행시점 : 모델을 생성하고 학습하기 전에도 진행 가능.
도구 불러오기 ( 모델 교차 검증 확인)
from sklearn.model_selection import cross_val_score
estimator :예측기 - > 모델명
x,y : 문제, 답데이터
cv (cross validation) : 교차검증 횟수(테스트를 분리할 횟수)
( tree_model한테 x_train, y_train활용해서 5번의 교차검증 함. (=cv) )
# cross_val_score(estimator,x,y=none,cv=5)
cv_result =cross_val_score(tree_model,x_train,y_train,cv=5)
print('교차검증 결과: ', cv_result)
print('교차검증 평균: ',cv_result.mean())
- 5번 진행한 후의 결과가 대부분 100% 성능을 내고 있음
- 나름대로 신뢰할만한 모델임.
- 모델이 학습을 잘했음. -> 모델의 하이퍼 파라미터를 제어하지 않아도 내부 규칙 생성이 알맞게 됨.
- p인지 e인지 판단하기 위한 특성 설명이 충분했음(= 데이터 좋았음.)
- 하이퍼 파라미터를 제어하지 않아도 되는 상황
test 평가
pre = tree_model.predict(x_test)
pre
< 정확도 >
# 방법1
from sklearn.metrics import accuracy_score
# 평가 : accuracy_score
test_acc= accuracy_score(y_test, pre)
test_acc
# 방법2
# 모델.score(테스트문제, 테스트답)
tree_model.score(x_test,y_test) # accuracy 정확도
# 교재 p.183
특성 중요도
- 모델 특성 선택 확인하기
- feature importances 확인하기
x_train.columns
fi = tree_model.feature_importances_
fi
특성 중요도 np배열-> df변환하면서 컬럼명 연결하기
fi_df = pd.DataFrame(fi, index=x_train.columns, columns=['feature importances'])
# 내림차순 정렬(높은 -> 낮은 값)
# 방법1
fi_df['feature importances'].sort_values(ascending=False)
# 방법2
fi_df.sort_values(by='feature importances', ascending=False)
학습시킨 트리모델의 현황을 추출하는 코드
from sklearn.tree import export_graphviz
export_graphviz(tree_model, # 추출할 모델
out_file='tree.dot', # 저장 경로 및 파일명
class_names=['독','식용'], # 클래스 이름 표현 설정
feature_names=x_one_hot.columns, # 컬럼명 이름 표현 설정
impurity=False,
filled=True) # 색상을 채움.
tree.dot 불러오면서 시각화(그래프화)
import graphviz
파일 다루는 파이썬 코드
with open('tree.dot', encoding ='UTF8') as f:
dot_graph =f.read()
display(graphviz.Source(dot_graph))
'Python' 카테고리의 다른 글
< Dataframe 인덱싱 > (0) | 2023.08.31 |
---|---|
[Machine Learning] Decision tree : 의사 결정 나무 (0) | 2023.08.30 |
[Machine Learning] iris_knn 분류실습 part.2 (0) | 2023.08.29 |
[Machine Learning] 일반화, 과소, 과대, knn (0) | 2023.08.29 |
[Python] 이미지 데이터 수집 (0) | 2023.08.29 |