본문 바로가기

KHUDA

KHUDA ML 세션 4주차

chapter 5 트리 알고리즘 

 

데이터 불러오기
import pandas as pd

wine = pd.read_csv('https://bit.ly/wine_csv_data')
누락값 찾기
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 6497 entries, 0 to 6496
Data columns (total 4 columns):
 #   Column   Non-Null Count  Dtype  
---  ------   --------------  -----  
 0   alcohol  6497 non-null   float64
 1   sugar    6497 non-null   float64
 2   pH       6497 non-null   float64
 3   class    6497 non-null   float64
dtypes: float64(4)
memory usage: 203.2 KB
info() 메서드
이 메서드는 데이터 프레임의 각 열의 데이터 타입과 누락된 데이터가 있는지 확인하는데 유용
만약, 누락된 값이 있다면 버리거나 평균값으로 채운 후 사용할 수 있다. 
통계 출력 

 

6497.000000 6497.000000 6497.000000 6497.000000
10.491801 5.443235 3.218501 0.753886
1.192712 4.757804 0.160787 0.430779
8.000000 0.600000 2.720000 0.000000
9.500000 1.800000 3.110000 1.000000
10.300000 3.000000 3.210000 1.000000
11.300000 8.100000 3.320000 1.000000
14.900000 65.800000 4.010000 1.000000
describe()메서드 
열에 대한 간략한 통계를 출력해냄
평균, 표준편차, 최소, 최대, 중간값과 1,2,3사분위수를 알 수 있다.
사분위수 
데이터를 순서대로 4등분 한 것 
예를 들어 2사분위수는 데이터를 일렬로 늘어놓았을때 정중앙의 값 
훈련, 테스트세트 나누기 
data = wine[['alcohol', 'sugar', 'pH']].to_numpy()
target = wine['class'].to_numpy()
from sklearn.model_selection import train_test_split

train_input, test_input, train_target, test_target = train_test_split(
    data, target, test_size=0.2, random_state=42)
정규화 하기 
from sklearn.preprocessing import StandardScaler

ss = StandardScaler()
ss.fit(train_input)

train_scaled = ss.transform(train_input)
test_scaled = ss.transform(test_input)
로지스틱 회귀 모델 
from sklearn.linear_model import LogisticRegression

lr = LogisticRegression()
lr.fit(train_scaled, train_target)

print(lr.score(train_scaled, train_target))
print(lr.score(test_scaled, test_target))

0.7808350971714451

0.7776923076923077

 

점수가 모두 낮으니 모델이 과소적합 되었다고 판단할 수 있다

이를 해결하기 위해 규제 매개변수 C의 값을 변경 or 다항 특성을 만들어서 추가 or 다른 알고리즘 선택하기 

 

계수 출력 
[[ 0.51270274  1.6733911  -0.68767781]] [1.81777902]

계수의 값이 정확히 뭘 의미하는지 설명 X

대부분의 머신러닝은 결과를 설명하기 힘들다.

결정 트리 (Decision tree)
데이터의 분류를 할 수 있는 질문을 찾아 분류 정확도를 높일 수 있다. 
DecisionTreeClassifier() 클래스를 사용하여 결정 트리 모델을 훈련 
결정트리 훈련
 
0.996921300750433
0.8592307692307692

훈련세트는 높지만 테스트 세트의 점수가 낮아 과대적합된 모델이다 

결정트리 그림으로 나타내기 
from sklearn.tree import DecisionTreeClassifier

dt = DecisionTreeClassifier(random_state=42)
dt.fit(train_scaled, train_target)

print(dt.score(train_scaled, train_target))
print(dt.score(test_scaled, test_target))

노드(node)
훈련 데이터의 특성에 대한 테스트를 표현한다.
예를 들어 현재 샘플의 당도가 -0.245보다 작거나 같은지 테스트 한다. 
가지(branch)는 테스트의 결과(True, False)를 나타내며 하나의 노드는 2개의 가지를 가진다. 
결정트리는 위에서 아래로 자라므로 맨 위 노드를 루트 노드, 아래 노드를 리프 노드 부른다.
트리의 깊이 제한하여 출력
plt.figure(figsize=(10,7))
plot_tree(dt, max_depth=1, filled=True, feature_names=['alcohol', 'sugar', 'pH'])
plt.show()

max_depth 매개변수를 1로 주면 루트 노드를 제외하고 하나의 노드를 더 확장하여 그린다. 

왼쪽 노드
오른쪽 노드

음성클래스가 81, 양성클래스가 2194개로 대부분의 화이트 와인이 이 노드로 옮겨졌다.

plot_tree() 함수에서 filled_True 로 지정하면 클래스 마다 색을 부여하고, 어떤 클래스의 비율이 높아질 수록 색이 진해진다. 

 

결정트리에서 예측하는 방법
리프 노드에서 가장 많은 클래스가 예측 클래스가 된다. 
예를 들어, 위의 트리에서는 오른쪽, 왼쪽 노드 모두 양성 클래스의 갯수가 많기 때문에 결정 트리의 성장이 여기서 멈춘다면, 둘다 양성 클래스로 예측된다. 
불순도 
지니 불순도(Gini impurity)
DecisionTreeClassfier 클래스의 criterion 매개변수의 기본값이다. criterion 매개변수의 용도는 노드에서 데이터를 분활하는 기준을 정하는 것 이다. 
불순도 계산

루트 노드의 5197개의 샘플 중 1258개의 음성 클래스, 3939개의 양성 클래스를 계산하기

만약 100개의 샘플이 있는 노드에서 두 클래스의 비율이 정확이 1/2라면 지니 불순도는 0.5 가 되어 최악이 된다. 

지니 불순도는 0.5가 최대이다. 

노드에 하나의 클래스만 있다면 지니 불순도는 0이 된다. 

 

결정 트리 모델은 부모노드와 자식노드의 불순도 차이가 가능한 크도록 트리를 성장시킨다. 

부모노드와 자식노드의 불순도 계산법 

정보 이득(information gain)
부모노드와 자식 노드 사이에 불순도 차이를 정보 이득이라고 부른다
결정트리 알고리즘은 정보이득이 최대가 되도록 데이터를 나눈다. 
엔트로피 불순도 
엔트로피 불순도 
DecisionTreeClassfier 클래스의 crierion='entropy'를 지정해 엔트로피 불순도를 사용할 수 있다. 
결정트리 알고리즘 정리
  • 결정트리 알고리즘은 불순도를 기준으로 정보 이득이 최대가 되도록 노드를 분할합니다.
  • 노드를 순수하게 나눌수록 정보 이득이 커집니다.
  • 새로운 샘플에 대해 예측할 때 노드의 질문에 따라 트리를 이동합니다.
  • 그리고 마지막에 도달한 노드의 클래스 비율을 보고 예측을 만듭니다. 
가지치기

결정 트리에서 가지치는 방법은 자라날 수 있는 트리의 최대 깊이를 지정하는 것 입니다. 

dt = DecisionTreeClassifier(min_impurity_decrease=0.0005, random_state=42)
dt.fit(train_input, train_target)

print(dt.score(train_input, train_target))
print(dt.score(test_input, test_target))

0.8874350586877044

0.8615384615384616

plt.figure(figsize=(20,15))
plot_tree(dt, filled=True, feature_names=['alcohol', 'sugar', 'pH'])
plt.show()

깊이 1노드 당도를 기준으로 훈련세트를 나눔
깊이 2노드 맨 왼쪽만 당도를 기준으로 나누고 왼쪽에서 두 번째 노드는 알코올 도수를 기준으로 나눔
깊이 3 노드 왼쪽에서 3번째 노드만 음성 클래스가 더 많다. 이 노드에 도착해야 레드 와인으로 예측한다. 

 

훈련 데이터를 전처리한 상태이기 때문에 당도 값이 음수로 나타난다.
여기서, 결정 트리의 장점 중 하나는 특성값을 전처리 할 필요가 없다는 것이다. 

왜냐하면 각 특성이 개별적으로 처리되어 데이터를 분할하는 데 데이터 스케일의 영향을 받지 않으므로 결정 트리에서는 특성의 정규화나 표준화 같은 전처리 과정이 필요 없다.

 

dt = DecisionTreeClassifier(max_depth=3, random_state=42)
dt.fit(train_input, train_target)

print(dt.score(train_input, train_target))
print(dt.score(test_input, test_target))

0.8454877814123533

0.8415384615384616

 

plt.figure(figsize=(20,15))
plot_tree(dt, filled=True, feature_names=['alcohol', 'sugar', 'pH'])
plt.show()

특성 중요도 
각 노드의 정보 이득과 전체 샘플에 대한 비율을 곱한 후 특성별로 더하여 계산한다. 특성 중요도를 활용하면 결정 트리 모델을 특성 선택에 활용할 수 있다. 

 

chapter 5-2

교차검증과 그리드 서치 

 

테스트 세트를 사용해 성능을 확인하다 보면 결국 테스트 세트에 예측이 맞춰지게 된다.

검증 세트(validation set)ㄱ테스트 세트를 사용하지 않고 훈련 세트를 또 나눈 데이터 

보통 20~30%를 테스트 세트와 훈련 세트로 떼어 놓음

검증세트 만들기 
import pandas as pd

wine = pd.read_csv('https://bit.ly/wine_csv_data')
data = wine[['alcohol', 'sugar', 'pH']].to_numpy()
target = wine['class'].to_numpy()
from sklearn.model_selection import train_test_split

train_input, test_input, train_target, test_target = train_test_split(
    data, target, test_size=0.2, random_state=42)
sub_input, val_input, sub_target, val_target = train_test_split(
    train_input, train_target, test_size=0.2, random_state=42)

test_size의 매개 변수를 0.2로 지정하여 train_input의 약 20%를 val_input으로 만듦

크기 확인 
 
(4157, 3) (1040, 3)

 

모델 제작 후 평가6

 

0.9971133028626413
0.864423076923077

훈련 세트에 과적합 되어있다

 

교차 검증(cross validation)
검증 세트를 떼어 내어 평가하는 과정을 여러번 반복하여, 안정적인 검증 점수를 얻고 훈련에 더 많은 데이터를 사용한다.

3-폴드 교차 검증( 3 -ford cross vaildation)
훈련 세트를 세 부분으로 나눠서 교차 검증을 수행하는 것을 3-폴드 교차 검증이라 한다. 
k-겹 교차 검증이라고도 하며 k 값은 5,10이 들어갈 수 있다. 이렇게 하면 데이터의 80~90%까지 훈련에 사용할 수 있다. 

교차 검증 클래스 : cross_vaildate()
from sklearn.model_selection import cross_validate

scores = cross_validate(dt, train_input, train_target)
print(scores)
import numpy as np

print(np.mean(scores['test_score']))

0.855300214703487

 

from sklearn.model_selection import StratifiedKFold

scores = cross_validate(dt, train_input, train_target, cv=StratifiedKFold())
print(np.mean(scores['test_score']))

0.855300214703487

교차검증을 할때 훈련 세트를 섞으려면 분할기를 지정해야함 

  • 회귀 모델인 경우 KFold 분할기를 사용
  • 분류 모델인 경우 StratifiedKFold 분할기 사용
splitter = StratifiedKFold(n_splits=10, shuffle=True, random_state=42)
scores = cross_validate(dt, train_input, train_target, cv=splitter)
print(np.mean(scores['test_score']))

0.8574181117533719

그리드 서치(Grid search)
하이퍼파라미터 탐색과 교차 검증을 한 번에 수행할 수 있다. 
랜덤 서치(random search)
하이퍼파라미터 탐색을 자동으로 해주는 장치 
매개변수를 샘플링 할 수 있는 확률 분포 객체를 전달 
from sklearn.model_selection import GridSearchCV

params = {'min_impurity_decrease': [0.0001, 0.0002, 0.0003, 0.0004, 0.0005]}
gs = GridSearchCV(DecisionTreeClassifier(random_state=42), params, n_jobs=-1)
gs.fit(train_input, train_target)
dt = gs.best_estimator_
print(dt.score(train_input, train_target))
print(gs.best_params_)
print(gs.cv_results_['mean_test_score'])

 

 

chapter 5-3 트리의 앙상블 

 

앙상블 학습 (ensemble learning)
결정 트리 기반 알고리즘
랜덤 포레스트( random forest)
앙상블 학습의 대표 주자로 안정적인 성능 덕분에 널리 사용되고 있다 
결정 트리의 숲을 만들어 각 결정 트리의 예측을 사용해 최종 예측을 만든다.

부트스트랩 샘플(bootstrap sample)
데이터 세트에 중복을 허용하여 만든 샘플
이 샘플은 훈련 세트와 크기가 같다

클래스 소개 
RandomForestClassifier()
기본적으로 전체 특성 개수의 제곱근 만큼 특성을 선택
RandomForestRegressor()
회귀모델로 전체 특성을 사용 
매개 변수 return_train_score 
기본값이 False인 매개 변수로 
True로 지정하면 검증 점수 뿐만아니라 훈련 세트에 대한 점수도 같이 반환 합니다. 
featuer_importances_
각 결정트리의 중요도를 취합한 것 

 

OOB ( out of bag ) 샘플
부트스트랩 샘플에 포함되지 않고 남는 샘플 
남는 샘플을 사용하여 부트스트랩 샘플로 훈련한 결정트리 평가 
oob_score 매개변수 ( T / F )

 

엑스트라 트리(Extra trees)
전체 특성 중 일부 특성을 랜덤하게 선택하여 노드를 분할
랜텀포레스트와 다르게 부트스트랩 샘플을 사용하지 않음
전체 훈련 세트를 사용
노드를 분할할때 가장 좋은 분할을 찾지 않고 무작위로 분할한다. 
그레이디언트 부스팅(gradient boostiong)
깊이이가 얕은 결정 트리를 사용하여 이전 트리의 오차를 보완
깊이가 얕은 결정 트리를 사용하기 때문에 과대 적합에 강하고 높은 일반화 성능을 기대할 수 있음 
히스토그램 기반 그레이디언트 부스팅(histogram-gradient boostiong)
입력 특성을 256개로 나누어 최적의 분할 포인트를 찾음
트리 개수 조절(max_iter)

'KHUDA' 카테고리의 다른 글

KHUDA Data buisness 01  (0) 2024.03.13
KHUDA ML 세션 5주차  (1) 2024.02.27
KHUDA ML세션 3주차  (1) 2024.02.13
KHUDA ML세션 2주차  (1) 2024.02.05
KHUDA ML세션 1주차  (1) 2024.01.31