오랑우탄의 반란

[ML] 의사결정나무, 랜덤포레스트, KNN, 부스팅 알고리즘 (회귀/분류 모델링 알고리즘) 본문

PYTHON/머신러닝

[ML] 의사결정나무, 랜덤포레스트, KNN, 부스팅 알고리즘 (회귀/분류 모델링 알고리즘)

5&2 2024. 8. 14. 14:16
반응형

 

 

선형회귀, 로지스틱회귀 외의 대표적인 회귀/분류 모델을 추가적으로 살펴보겠습니다. 

 

의사결정나무 Decision Tree

의사결정 규칙을 트리 구조로 나누어 전체 데이터를 n개의 소집다능로 분류하거나 예측을 수행하는 분석법 

장점 - 쉽고 해석하기 용이
- 다중분류, 회귀에 모두 적용 가능
- 이상치에 견고하고 데이터 스케일링 불필요 (데이터의 상대적 순위를 고려하기 때문)
단점 - 과적합 오류: 나무 성장이 너무 많으면 과적합 오류
- 불안정성: 훈련데이터에 민감하게 반응해 작은 노이즈에도 나무 구조가 크게 달라짐
라이브러리 sklearn.tree.DecisionTreeClassifier
sklearn.tree.DecisionTreeRegressor

 

 

name details
루트노드 root node DT 시작점, 1차 분류조건
리프노드 leaf node 루트로부터 파생된 노드
분류기준 criteria 루트노드에서의 분류조건, 아래 예시에서는 여성 0 남성 1로 인코딩 후 0.5 기준으로 분류
불순도 impurity gini 계수로 측정 (0~1), 낮을수록 분류가 잘 된 것, 리프로 갈수록 낮아짐 
0 = 완벽한 순도 =모든 샘플이 하나의 클래스
1 = 완전한 불순도 = 노드 샘플이 균등하게 분포됨 
샘플 samples 해당 노드의 샘플 개수
값 values Y변수에 대한 배열, 아래 예시에서는 사망0 549, 생존 1 342
클래스 class 가장 많은 샘플을 차지하는 클래스

 

 

타이타닉 성별 기준의 DT

from sklearn.preprocessing import LabelEncoder
from sklearn.tree import DecisionTreeClassifier, plot_tree

# 데이터 전처리
X_features = ['Pclass','Sex','Age','Fare','Embarked']
# Pclass: LabelEncoder
# Sex: LabelEncoder
# Age: 결측치 평균으로 대치

le = LabelEncoder()
titanic_df['Sex'] = le.fit_transform(titanic_df['Sex'])

le2 = LabelEncoder()
titanic_df['Pclass'] = le2.fit_transform(titanic_df['Pclass'])

age_mean = titanic_df['Age'].mean()
titanic_df['Age'] = titanic_df['Age'].fillna(age_mean)

le3 = LabelEncoder()
titanic_df['Embarked'] = titanic_df['Embarked'].fillna('S')
titanic_df['Embarked'] = le3.fit_transform(titanic_df['Embarked'])

X = titanic_df[X_features]
y = titanic_df['Survived']

# 의사결정나무
model_dt = DecisionTreeClassifier(max_depth=1) # 리프노드 1개만 생성
model_dt = DecisionTreeClassifier(random_state=42) # 랜덤하게 생성
model_dt.fit(X,y)

plt.figure(figsize=(10,7))

plot_tree(model_dt, feature_names=X_features, class_names=('Not Survived', 'Survived'), filled=True)
plt.show()

max_depth = 1 vs random_state = 42

 

 

랜덤포레스트 Random Forest

DT의 과적합과 불안정성 문제를 해결하기 위해 만들어진 분류법으로 나무 여러 개로 숲을 만든 것

DT의 장점은 수용하고 단점은 보완했기 때문에 성능이 뛰어나고 자주 쓰임

장점 - Bagging 과정으로 과적합 피함
- 이상치에 견고, 데이터 스케일링 불필요
- 변수 중요도 추출이 가능해 모델 해석에 중요한 특징 파악 가능 
단점 - 컴퓨터 리소스 비용 큼
- 앙상블 적용으로 해석이 어려움
라이브러리 sklearn.ensemble.RandomForestClassifer
sklearn.ensemble.RandomForestRegressor

 

각 트리에 대해 다수결 법칙에 따라 or 평균으로 결론을 냄

 

데이터 샘플은 배깅 Bagging 의 원리로 생성됩니다. 

name details
Bagging 머신러닝 데이터 부족 문제를 해결하기 위한 bootstrapping + aggregating 방법론
Bootstrapping 데이터를 복원 추출해 유사하지만 다른 데이터 집단 생성하는 것
Aggregating 데이터의 예측/분류 결과를 합치는 것
Ensemble 여러 개의 모델을 만들어 합치는 것

 

Bagging

 

 

로지스틱회귀 vs 의사결정나무 vs 랜덤포레스트 

from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score, f1_score

model_lor = LogisticRegression()
model_dt = DecisionTreeClassifier(random_state=42)
model_rf = RandomForestClassifier(random_state=42)

model_lor.fit(X,y)
model_dt.fit(X,y)
model_rf.fit(X,y)

y_lor_pred = model_lor.predict(X)
y_dt_pred = model_dt.predict(X)
y_rf_pred = model_rf.predict(X)

def get_score(model_name, y_true, y_pred):
    acc = accuracy_score(y_true, y_pred)
    f1 = f1_score(y_true, y_pred)
    print(model_name, 'acc score: ',acc,'f1_score: ',f1)

get_score('lor',y,y_lor_pred)
get_score('dt',y,y_dt_pred)
get_score('rf',y,y_rf_pred)

일반적으로 랜덤포레스트가 가장 좋음

 

print(X_features)
model_rf.feature_importances_

각 변수 별 중요도를 알 수 있는 것이 장점

 

 

최근접 이웃 K-Nearest Neighbor (KNN) 

주변 데이터에 대해 거리 기준으로 가장 많은 데이터가 알고 싶은 데이터라고 예측하는 방법 

장점 - 이해하기 쉽고 직관적
- 모집단의 가정이나 형태를 고려하지 않음
- 회귀/분류 모두 적용 가능
단점 - 차원 수가 많을수록 계산량 많아짐
- 거리 기반 알고리즘이어서(단위 영향 많이 받음) 피처의 표준화 필수 
라이브러리 sklearn.neighbors.KNeighborsClassifier
sklearn.neighbors.KNeighborsRegressor

 

? 가 K=3 이면 세모로 예측, K=7이면 별로 예측

 

name details
파라미터 Parameter 머신러닝 모델이 학습 과정에서 추정하는 내부 변수, 자동으로 결정되는 값 (ex. 선형회귀에서 가중치와 편향)
하이퍼 파라미터
Hyper Parameter
데이터 사이언티스트가 기계학습 모델 훈련을 관리하는데 사용하는 외부 구성변수로, 모델 학습과정이나 구조에 영향을 미침
하이퍼 파라미터 변수를 바꾸면서 좋은 평가가 나올때까지 실험하고 그 원리는 밝혀내는 것이 데이터 사이언스의 기반 (근래 ml 모델은 정확성과 동시에 복잡성도 증가해서 왜 좋은 결과가 나왔는지 알기 어려움) 

 

 

부스팅 Boosting 알고리즘

여러 개의 약한 학습기 weak learner 를 순차적으로 학습하면서 잘못 예측한 데이터에 가중치를 부여해 오류를 개선하는 분석법 

아래 분석의 경우 1개의 선 (learner) 로 구별되지 않는 경우가 있기 때문에 여러 learner 를 합친 ensemble를 통해 성능을 올리는 방법 

 

 

Boosting Algorithms details
Gradient Boosting Model - 가중치 업데이트를 경사하강법으로 진행

sklearn.ensemble.GradientBoostingClassifier
sklearn.ensemble.GradientBoostingRegressor
XGBoost - 트리기반 앙상블 기법으로, 가장 각광받으며 Kaggle의 상위 알고리즘
- 병렬학습이 가능해 속도가 빠름

xgboost.XGBRegressor
xgboost.XGBRegressor
LightGBM - XGBoost와 함께 가장 각광받는 알고리즘
- XGBoost보다 학습시간이 짧고 메모리 사용량이 작음
- 작은 데이터(10,000건 이하)의 경우 과적합 발생

lightgbm.LGBMClassifier
lightgbm.LGBMRegressor

 

 

전체 모델링 비교

from sklearn.neighbors import KNeighborsClassifier
from sklearn.ensemble import GradientBoostingClassifier
from xgboost import XGBClassifier
from lightgbm import LGBMClassifier

model_knn = KNeighborsClassifier()
model_gbm = GradientBoostingClassifier(random_state=42)
model_xbg = XGBClassifier(random_state=42)
model_lgb = LGBMClassifier(random_state=42)

model_knn.fit(X,y)
model_gbm.fit(X,y)
model_xbg.fit(X,y)
model_lgb.fit(X,y)

y_knn_pred = model_knn.predict(X)
y_gbm_pred = model_gbm.predict(X)
y_xbg_pred = model_xbg.predict(X)
y_lgb_pred = model_lgb.predict(X)

get_score('lor',y,y_lor_pred)
get_score('dt',y,y_dt_pred)
get_score('rf',y,y_rf_pred)
get_score('knn',y,y_lor_pred) # 스케일링 안해서 낮게 나옴 
get_score('gbm',y,y_dt_pred)
get_score('xbg',y,y_rf_pred) # 부스팅모델은 데이터가 너무 작아서 과적합 일어날 수 있음 
get_score('lgb',y,y_rf_pred)

 

반응형