Machine Learning - #4 붓꽃/결정트리 실습

임다이·2023년 12월 7일
0

Machine Learning

목록 보기
5/15

실습

붓꽃 품종 예측하기
  • petal : 꽃잎 / sepal : 꽃받침

  • 사이킷런에서 제공하는 데이터 세트 생성하는 모듈
from sklearn.datasets import load_iris
iris_data = load_iris()
iris_data # Bunch 클래스 객체(딕셔너리와 유사함)
# iris_dataset의 키 값
iris_data.keys()

# DESCR 키에는 데이터셋에 대한 설명
print(iris_data['DESCR'])

# target_names : 예측하고자 하는 붓꽃 품종의 이름을 문자열 배열로 가지고 있음
iris_data['target_names']

# feature_names : 각 특성을 설명하는 문자열
iris_data['feature_names']

# 꽃잎의 길이, 폭, 꽃받침의 길이, 폭 -> 2차원 Numpy 배열의 형태
iris_data['data']

# target은 1차원 Numpy배열
# 0은 setosa, 1은 versocolor, 2는 virginica
iris_data['target']








데이터셋 구성
  • 문제와 답데이터 분리
  • 훈련세트와 평가세트로 분리
  • 훈련세트/데이터 : 머신러닝 모델을 학습할 때 사용
  • 평가세트/데이터 : 모델이 얼마나 잘 작동하는지 측정하는데 사용

  • 훈련데이터와 테스트데이터로 분리해주는 기능
from sklearn.model_selection import train_test_split
  • 문제데이터 2차원 데이터프레임 생성
# 컬럼 이름 설정 (iris_data['feature_names'])
# iris_df라는 변수에 담아주기
iris_df = pd.DataFrame(iris_data['data'], columns = iris_data['feature_names'])
iris_df

  • 문제와 답 데이터로 분리
X = iris_df.values
y = iris_data['target']
  • 훈련세트와 평가세트로 분리
# train_test_split : 데이터를 나누기 전에 유사 난수 생성기를 사용해
# 데이터셋을 무작위로 섞어준다.

X_train, X_test, y_train, y_test = train_test_split(X, y,
                                                   test_size=0.3,
                                                   random_state=65)
# random_state 매개변수 : 함수를 여러번 실행해도 결과가 똑같이 나오게 된다.

# 훈련용 세트 크기 확인
print(X_train.shape)
print(y_train.shape)

# 테스트 세트 크기 확인


모델링
  • 사이킷런 라이브러리 가져오기
from sklearn.neighbors import KNeighborsClassifier
from sklearn import metrics
  • 모델생성
knn = KNeighborsClassifier(n_neighbors=3)
  • 훈련 / 학습
# 모델명.fit(훈련용 문제, 훈련용 답)
knn.fit(X_train, y_train)

  • 예측
# 모델명.predict(테스트용 문제)
pre = knn.predict(X_test)
  • 평가하기
metrics.accuracy_score(pre, y_test)


하이퍼파라미터 튜닝
test_list = []
train_list = []

for k in range(1, 105, 2):
    # 모델생성
    knn = KNeighborsClassifier(n_neighbors=k)

    # 학습
    knn.fit(X_train, y_train)
    
    # test 데이터
    # 예측
    test_pre = knn.predict(X_test)

    # 평가
    test_score = metrics.accuracy_score(test_pre, y_test)
    
    # test_list라는 리스트에 평가값을 담아주기
    test_list.append(test_score)
    
    # train 데이터
    # 예측
    train_pre = knn.predict(X_train)
    
    # 평가
    train_score = metrics.accuracy_score(train_pre, y_train)
    
    # train_list라는 리스트에 평가값 담아주기
    train_list.append(train_score)
  • test_list
test_list

  • train_list
train_list

  • 글꼴
plt.rcParams['font.family'] = 'Malgun Gothic'
  • 그래프로 시각화하기
plt.figure(figsize=(10,10))
plt.plot(range(1, 105, 2), train_list, label='train')
plt.plot(range(1, 105, 2), test_list, label='test')
plt.legend()

plt.xlabel("이웃의 수")
plt.ylabel("정확도")
plt.show()



Decision tree 활용 버섯데이터 분류
  • 필요한 라이브러리 불러오기
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

from sklearn.model_selection import train_test_split # 훈련과 테스트용 셋트 분리
from sklearn.metrics import accuracy_score # 평가를 진행할 때 정확도 측정
from sklearn.tree import DecisionTreeClassifier # 결정트리모델 가져오기
  • 데이터를 로드하기(가져오기)
data = pd.read_csv('mushroom.csv')
data

  • 데이터 크기 확인
data.shape

  • 결측치 여부, 타입 확인
data.info()

  • 문제(X)와 답데이터(y)로 분리
X= data.loc[:,'cap-shape':]
y = data.loc[:,'poisonous']
data.describe()

  • 답 데이터의 개수 구하기
# e(edible) : 식용버섯
# p(poisonous) : 독버섯
y.value_counts()


레이블 인코딩
  • 단순 수치 값으로 maping하는 작업
  • 숫자 값의 크고 작음에 대한 특성으로 인해 예측 성능이 떨어지는 경우가 발생할 수 있음

X['habitat']

  • 데이터를 연결할 딕셔너리 생성
habitat_dic = {
    'u':0,
    'g':1,
    'm':2,
    'd':3,
    'p':4,
    'w':5,
    'l':6
}
  • 재대입 통해 범주형 -> 수치형으로 변경
X['habitat'].map(habitat_dic)

  • 재대입
X['habitat']=X['habitat'].map(habitat_dic)

  • 결과
X['habitat']


원한이코딩
  • 단어를 표현하는 가장 기본적인 표현방법
  • 특성을 세부적으로 나눠서 생각할 수 있음
  • 필요한 공간이 계속 늘어나 저장공간 측면에서는 비효율적인 방법

  • get_dummies() 메소드 활용
X_one_hot = pd.get_dummies(X)
X_one_hot.head()

print("원본 특성 : \n", list(X.columns), "\n")
print("원 핫 인코딩 이후 특성 : \n", list(X_one_hot.columns))

X_one_hot


모델링
  • 훈련용 세트와 평가용 세트로 분리
# X_one_hot, y
# train_test_split 함수 사용

X_train, X_test, y_train, y_test = train_test_split(X_one_hot, y, test_size=0.3)
print(X_train.shape)
print(y_train.shape)

print(X_test.shape)
print(y_test.shape)

  • 모델생성
tree = DecisionTreeClassifier(max_depth=3)
tree1 = DecisionTreeClassifier()
  • 학습 (fit)
tree.fit(X_train, y_train)
tree1.fit(X_train, y_train)

  • 예측 (predict)
pre = tree.predict(X_test)
  • 실제 답
y_test

  • 평가
print("예측 정확도 : {0: .4f}".format(accuracy_score(pre, y_test)))


시각화하기
  • Decision Tree 시각화 도구
!pip install graphviz

  • graphviz 경로 잡기
import os
os.environ["PATH"]+=os.pathsep+'C:/Program Files/Graphviz/bin/'
  • 원핫인코딩 변수명 : X_one_hot
    DT 변수명 : tree
from sklearn.tree import export_graphviz
export_graphviz(tree, out_file='tree.dot',
               class_names=['p','e'],
               feature_names=X_one_hot.columns,
               impurity=False,
               filled=True)
  • 원핫인코딩 변수명 : X_one_hot
    DT 변수명 : tree1
from sklearn.tree import export_graphviz
export_graphviz(tree1, out_file='tree1.dot',
               class_names=['p','e'],
               feature_names=X_one_hot.columns,
               impurity=False,
               filled=True)
import graphviz

with open('tree1.dot', encoding='UTF8') as f:
    dot_graph = f.read()

display(graphviz.Source(dot_graph))

  • tree
from subprocess import check_call
check_call(['dot','-Tpng','tree.dot','-o','tree.png'])

  • tree1
from subprocess import check_call
check_call(['dot','-Tpng','tree1.dot','-o','tree1.png'])


특성 선택
  • 특성 중요도
# 0~1사이의 숫자로 표현
# 1에 가까울수록 중요, 0에 가까울수록 중요하지 않음
# 전체 합이 1
fi = tree1.feature_importances_
# 2.80252522e-03 : 부동소수점 표현 방법
# 2.80252522 : 무조건 일의 자리 숫자로 표현
# e-03 : 10의 -3제곱
fi

X_one_hot.columns

df = pd.DataFrame(fi, index = X_one_hot.columns)
# by = 정렬 기준(컬럼이름을 지정안하면 0부터 붙음)
df.sort_values(by = 0, ascending=False)


교차검증
  • 고정된 데이터로 학습을 계속 하다보면 train뿐만 아니라 test에도 과대적합이 생김
  • 이런 현상을 방지하기 위한 방법
  • 데이터를 바꿔가며 학습/평가를 반복한다 → 여러번 결과를 보기 때문에 결과에 신뢰가 높음

from sklearn.model_selection import cross_val_score
# 사용 할 모델, 문제데이터, 답데이터, cv = 데이터 분할 수(주로 5 사용. train:test = 4:1)
score = cross_val_score(tree, X_train, y_train, cv = 5)
  • tree
tree.score(X_train, y_train)

  • tree1
tree1.score(X_test, y_test)

  • train과 test를 바꿔가며 5번 학습한 결과
# 5번 학습한 결과
score


profile
노는게 제일 좋아~!

0개의 댓글