정형 : 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해버리고 원래 성능과 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번째 특성이 중요하다는 걸 알수 있다.
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
미리 분류가 어려운 데이터를 다루는 경우, 학습할 타겟이 없게된다. 군집과 차원축소가 있다.
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()