수업/머신러닝

[머신러닝] 4일차 - for문 사용하여 하이퍼 파라미터 튜닝, 결정 트리 (Decision tree)

분홍야자 2023. 4. 19. 09:45

수업정리

 

 

  • 학습이 끝난 모델링의 상태
    • 일반화 : train 상 test 상
    • 과대적합 : train 상 test 하
      • 훈련 데이터에만 과도하게 정확히 동작
    • 과소적합 : train 하 test 하
  • test 데이터 셋 은 미래데이터의 역할을 한다
  • 성능은 테스트셋의 스코어로 알수있다.
  • 새로운 데이터 포인트 - 예측 데이터
  • 가장 가까운 훈련 데이터셋의 데이터 - 훈련된 데이터
  • 분류 - 다수결 : classification
  • 회귀 - 평균 : regression
  • k값 소 -> 모델의 복잡도가 증가
  • k값 대 -> 모델의 복잡도가 감소

  • train_test_split
    • x,x,y,y 순으로 담아준다. train, test 순
    • 75:25 비율로 담아줌
  • train_test_split : 랜덤 샘플링

 

수업시작

 

 

하이퍼 파라미터 튜닝 (for문 사용)

# 비어있는 리스트 만들어주기
train_list = []
test_list = []

for k in range(1,105,2):
    # 이웃의 변화에 따른 모델 생성
    model = KNeighborsClassifier(n_neighbors=k)
    model.fit(X_train, y_train)
    
    train_score = model.score(X_train, y_train) # 정확도
    train_list.append(train_score)
    
    test_score = model.score(X_test, y_test)
    test_list.append(test_score)
  • metrics = 평가에 관련된 모듈이 담겨있음

 

그래프 그리기

# 그래프 그리기
plt.figure(figsize=(25, 5)) # (가로, 세로)
plt.plot(range(1, 105, 2), train_list,c='red')
plt.plot(range(1, 105, 2), test_list ,c='green')
plt.xticks(range(1, 105, 2))
plt.grid()

plt.show()
  • 어떤 k값을 이용하는게 좋을까

 

최적화된 모델 활용

final_model = KNeighborsClassifier(n_neighbors=9)
final_model.fit(X_train, y_train)
final_model.score(X_test, y_test)

 

예측해보기 - predict

my_dict = final_model.predict([[3.7,4,2.0,0.4]])
my_dict

 

예측한 붓꽃 이름 확인해보기

# 붓꽃 종류 확인하기
iris_data['target_names'][my_dict]

 

 


 

학습목표

  • Decision Tree 알고리즘 이해
  • Label 인코딩과 One-hot인코딩 이해
  • 교차 검증 기법 이해

결정 트리 (Decision tree)

  • 의사결정
  • Tree를 만들기 위해 예/아니오 질문을 반복하며 학습
  • 다양한 앙상블(ensemble) 모델이 존재
    • RandomForest, GradientBoosting, XGBoost, LightGBM
  • 분류와 회귀에 모두 사용 가능

 

 

 

  • 결정 트리가 뒤집어 놓으면 나무같다 하여 tree 라고 지칭하였다.
  • 시작부분은 root node
  • 끝부분은 leaf node
  • 한명의 타깃값이 있는 node를 순수 노드라고한다
  • tree 의 질문을 통해서 타겟값을 결정한다.
  • 업다운 게임처럼 1~100이라고 가정했을 때 처음에 외치는 값이 50인 이유는 절반을 날려버리기 위해
  • 절반의 타겟을 날리는 질문을 한다.

  • 불순도가 낮은 방향으로 가야 한다.
  • 질문을 던지고 규칙을 찾는다
  • 모든 노드가 순수 노드가 될 때까지 학습하면 복잡해지고 과대적합이 됨
  • 새로운 데이터 포인트가 들어오면 해당하는 노드를 찾아 분류라면 더 많은 클래스를 선택하고, 회귀라면 평균을 구함
  • 장점
    • 학습과정을 확인 가능하다
    • 질문을 볼 수 있음
    • 어떤 규칙을 통해 학습 되었는지 알 수 있음
  • 단점
    • 트리가 깊어지면 과대적합이 되기 쉬움

 

 

  • 깊이가 깊어질 수록 
  • 깊이를 선택한다.
  • 불순도를 계산을 디시션 트리가 한다.

 

 

 

장단점 및 주요 매개변수

  • 트리의 최대 깊이 : max_depth
  • 리프 노드의 최대 개수 : max_leaf_nodes

 

거리 기반 숫자스케일링

특성중요도 : 어떤 특성이 타겟값에 얼마만큼의 영향을 끼치는지

  • 디시션 트리는 거리가 아닌 질문이다.
  • 특성 중요도를 통해 질문을 뽑는다.
  • 정규화나 표준화가 필요 없다.
  • 훈련데이터 범위 밖의 포인트는 예측 할 수 없다.
  • 미래 시간에 대한 질문은 예측이 어렵다
  • 가지치기를 사용함에도 불구, 과대적합되는 경향이 있다.
  • 일반화 성능이 좋지 않다.

 

 

 

머쉬룸 데이터셋 사용하기

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# 데이터 가져오기
data = pd.read_csv('mushroom.csv')
data

결측치 확인

 

# 결측치 여부 확인 - 없당!
data.info()

# 데이터셋 나누기
X = data.loc[:,'cap-shape':] # data.drop('poisonous',axis=1) : poisonous 버리고
y = data.poisonous

 

라벨 인코딩

  • 컴퓨터가 이해할 수 있는 언어로 된 데이터를 줘야 학습하고 규칙을 찾는다.
    • 숫자 -> 인코딩
    • 단순 수치 값으로 mapping 하는 작업

이때 발생하는 문제

  • 수에는 크기가 있다. 대와 소...
  • 숫자로 표기해주었을 뿐인데 숫자 크기의 대소 관계로 인해 일반화된 학습이 아닌 학습이 잘 안될 수 있다.
  •  그래서 One-hot Encoding 을 해준다
    • 0 과 1의 값을 가진 여러개의 새로운 특성으로 변경하는 작업
    • 학습종류가 3개일 경우 3개의 컬럼을 만든다.
    • 해당 컬럼별로 값이 맞으면 1, 아니면 0

One-hot Encoding

  • 범주형 변수를 표현하는데 가장 널리 쓰이는 방법
  • 분류하고자 하는 범주(종류)만큼의 자릿수(컬럼)를 만들고 단 한 개의 1과 나머지 0으로 채워서 숫자로 표현하는 방식
  • 정답 라벨이 아닌 문제 라벨을 인코딩하는 작업
  • 컴퓨터는 숫자 데이터밖에 이해를 못하기 때문에 인코딩 필요
  • 특성 컬럼의 라벨 범주 갯수만큼 컬럼을 만든다

원핫 인코딩 처리 - pd.get_dummies(X)

X_one_hot = pd.get_dummies(X)
X_one_hot

 

 

모델링 나누기

from sklearn.model_selection import train_test_split
# 훈련, 테스트 데이터 나누기
# test_size - test셋의 비율 조정
X_train, X_test, y_train, y_test = train_test_split(X_one_hot, y, test_size = 0.3)

 

결정트리 모델 사용하기

from sklearn.tree import DecisionTreeClassifier
tree_model = DecisionTreeClassifier() # 하나의 모델객체 생성

 

# 트리 모델 학습
tree_model.fit(X_train, y_train)
tree_model.score(X_train,y_train)
  • 결과가 너무 잘되어도 의심해보자..
  • 이렇게 잘 나온 이유는 뭐지?