관리 메뉴

DeseoDeSeo

[Machine Learning] ex04. mushroom 실습 본문

Python

[Machine Learning] ex04. mushroom 실습

deseodeseo 2023. 8. 30. 18:06

목표

  • 버섯의 특징을 활용해 독/식용 이진 분류하기
  • 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 제외한 나머지 컬럼 -> x
x = 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))