[혼자 공부하는 머신러닝+딥러닝] #3 트리 앙상블, 군집 알고리즘

Clay Ryu's sound lab·2022년 2월 4일
0

Note for 2022

목록 보기
3/47

13강.트리의 앙상블

정형 데이터와 비정형 데이터

정형 : csv 파일, 전처리와 특성공학을 적용
비정형 : 텍스트, 오디오, 이미지와 영상, 데이터의 양이 많다.

랜덤 포레스트

트리를 가지고 앙상블을 한다. 트리는 과대적합이 되기 쉽기 때문에 여러 트리들로 숲을 본다면, 앙상블을 사용한다면 이를 예방할 수 있다.

훈련방법

훈련세트에서 랜덤샘플링을 통해서(중복을 허용한다는 의미에서 부트스트랩 샘플) 원본만큼의 성능이 나오지 않는(과적합방지) 샘플들을 만들고 이들의 결정트리의 결과인 확률(분류) 또는 예측값(회귀)을 평균한다.
또한 특성개수를 루트특성개수만큼(회귀는 전부 사용) 랜덤하게 선택해서(과적합방지) 불순도를 가장 높게하는 최선의 노드를 만든다.
100개의 트리를 만들며 낮은 점수들을 조합해서 일반화 점수를 높이는 방식이다.

from sklearn.model_selection import cross_validate
from sklearn.ensemble import RandomForestClassifier

rf= RandomForestClassifier(n_jobs=-1, random_state=42)
scores = cross_validate(rf, train_input, train_target, return_train_score=True, n_jobs=-1)

print(np.mean(scores['train_score']), np.mean(scores['test_score'])) #train척도0.9973, 검증세트의 점수0.8905

rf.fit(train_input, train_target)
print(rf.feature_importances_)
#[0.2316 0.5003 0.2679] 전과 다르게 pH의 중요도가 낮아졌다. 여러 특성을 랜덤하게 사용해서

#트리를 뽑을때 남는 샘플 oob을 검증세트로 사용이 가능하다.
rf=RandomForestClassifier(oob_score=True, n_jobs=-1, random_state=42)
rf.fit(train_input, train_target)
print(rf.oob_score_) # 0.8934

엑스트라 트리

100개의 트리를 사용한다. 부트스트랩 샘플을 사용하지 않고 전체 샘플을 사용한다. 과대적합을 방지하기 위해 노드를 분할할때 특성분할을 랜덤하게 한다. 노드 분할을 무작위로 하기 때문에 속도가 빠르다.

from sklearn.ensemble import ExtraTreesClassifier

et= ExtraTreesClassifier(n_jobs=-1, random_state=42)
scores = cross_validate(et, train_input, train_target, return_train_score=True, n_jobs=-1)

print(np.mean(scores['train_score']), np.mean(scores['test_score'])) #train척도0.9974, 검증세트의 점수0.8887

그레이디언트 부스팅

가장 좋은 알고리즘 중에 하나
로지스틱 손실함수와 평균제곱오차를 손실함수를 사용하며 손실값이 낮아지도록 트리를 추가하는 알고리즘이다. 이전 트리의 손실을 보완하는 식으로 얕은 결정트리를 연속하여 추가한다. 학습성능이 너무 좋은 gradient는 최적점을 지나치게 된다. 따라서 트리를 계속해서 추가하기에 학습시간이 오래 걸린다.

from sklearn.ensemble import GradientBoostingClassifier

gb= GradientBoostingClassifier(random_state=42)
scores = cross_validate(gb, train_input, train_target, return_train_score=True, n_jobs=-1)

print(np.mean(scores['train_score']), np.mean(scores['test_score'])) #train척도0.8881, 검증세트의 점수0.8720

# 트리개수epoch를 500개, 걸음을 0.1에서 0.2로
gb= GradientBoostingClassifier(n_estimators=500, learning_rate=0.2, random_state=42)
scores = cross_validate(gb, train_input, train_target, return_train_score=True, n_jobs=-1)

print(np.mean(scores['train_score']), np.mean(scores['test_score'])) #train척도0.9464, 검증세트의 점수0.8780

히스토그램 기반 그레이디언트 부스팅

훈련 데이터를 255개의 구간과 누락된 값을 위한 1개의 구간으로 나누었다. 따라서 전처리에 유리하다.

from sklearn.experimental import enable_hist_gradient_boosting
from sklearn.ensemble import HistGradientBoostingClassifier

hgb= HistGradientBoostingClassifier(random_state=42)
scores = cross_validate(hgb, train_input, train_target, return_train_score=True, n_jobs=-1)

print(np.mean(scores['train_score']), np.mean(scores['test_score'])) #train척도0.9321, 검증세트의 점수0.8801

Permutation Importance

샘플의 특성이 하나의 열에 있다면 각각의 특성을 치환permutation해버리고 원래 성능과 1특성치환성능, 2특성치환성능을 비교하면 각 특성의 중요도를 알수 있다.

from sklearn.inspection import permutation_importance
hgb.fit(train_input, train_target)
result = permutation_importance(hgb, train_input, train_target, n_repeats=10, random_state=42, n_jobs=-1)

print(result.importances_mean)
# [0.0887, 0.2343 0.0802]
# 2번째 특성이 중요하다는 걸 알수 있다.

XGBoost vs LightGBM

gradient boosting 전용 라이브러리가 있다. 그만큼 유명하고 잘 쓰인다는 것이다. 둘다 histogram기반 GB이다.

from xgboost import XGBClassifier

xgb= XGBClassifier(tree_method='hist', random_state=42)
scores = cross_validate(xgb, train_input, train_target, return_train_score=True, n_jobs=-1)

print(np.mean(scores['train_score']), np.mean(scores['test_score'])) #train척도0.8824, 검증세트의 점수0.8726

from lightgbm import LGBMClassifier

lgb= LGBMClassifier(tree_method='hist', random_state=42)
scores = cross_validate(lgb, train_input, train_target, return_train_score=True, n_jobs=-1)

print(np.mean(scores['train_score']), np.mean(scores['test_score'])) #train척도0.9338, 검증세트의 점수0.8789

14강.흑백 이미지 분류 방법과 비지도 학습, 군집 알고리즘 이해하기

비지도 학습

미리 분류가 어려운 데이터를 다루는 경우, 학습할 타겟이 없게된다. 군집과 차원축소가 있다.

import numpy as np
import matplotlib.pyplot as plt

fruits = np.load('fruits_300.npy')
print(fruits.shape) # (300,100,100)
print(fruits[0,0,:])
# 사용할 컬러의 스케일을 지정
plt.imshow(fruits[0], cmap='gray_r')
plt.show()

샘플 차원 변경하기

apple = fruits[0:100].reshape(-1, 100*100)
pineapple = fruits[100:200].reshape(-1, 100*100)
banana = fruits[200:300].reshape(-1, 100*100)

샘플 평균의 히스토그램

plt.hist(np.mean(apple, axis=1), alpha=0.8)
plt.hist(np.mean(pineapple, axis=1), alpha=0.8)
plt.hist(np.mean(banana, axis=1), alpha=0.8)
plt.legend(['apple', 'pineapple', 'banana'])
plt.show()

픽셀 평균의 히스토그램

fig, axs = plt.subplots(1,3, figsize=(20,5))
axs[0].bar(range(10000), np.mean(apple, axis=0))
axs[1].bar(range(10000), np.mean(pineapple, axis=0))
axs[2].bar(range(10000), np.mean(banana, axis=0))
plt.show()

평균 이미지 그리기

apple_mean = np.mean(apple,axis=0).reshape(100,100)
pineapple_mean = np.mean(pineapple,axis=0).reshape(100,100)
banana_mean = np.mean(banana,axis=0).reshape(100,100)

fig, axs = plt.subplots(1,3, figsize=(20,5))
axs[0].imshow(apple_mean, cmap='gray_r')
axs[1].imshow(pineapple_mean, cmap='gray_r')
axs[3].imshow(banana_mean, cmap='gray_r')
plt.show()

평균과 가까운 사진 고르기

abs_diff = np.abs(fruits - apple_mean)
abs_mean = np.mean(abs.diff, axis=(1,2))
print(abs_mean.shape) #(300,)

apple_index = np.argsort(abs_mean)[:100]
fig, axs = plt.subplots(10, 10, figsize=(10,10))
for i in range(10):
	for j in range(10):
    	axs[i, j].imshow(fruits[apple_index[i*10+j]], cmap='gray_r')
        axs[i, j].axis('off')
plt.show()
profile
chords & code // harmony with structure

0개의 댓글