의사결정나무(Decision Tree, DT)
- 의사결정규칙을 나무 구조로 나타내어 전체 자료를 몇 개의 소집단으로 분류하거나 예측을 수행하는 분석 방법
- 타이타닉 예시
- 성별 기준으로 의사결정나무 시각화
- 명칭
- 루트 노드(Root Node) : 의사결정나무의 시작점, 최초의 분할 조건
- 리프 노드(Leaf Node) : 루트 노드로부터 파생된 중간 혹은 최종 노드
- 분류기준(criteria) : sex는 여성인 경우 0, 남성인 경우 1로 인코딩하고 각각 좌측, 우측 노드로 분류
- 불순도(impurity)
▪️ 불순도 측정 방법 중 하나인 지니 계수는 0과 1 사이의 값으로 0이 완벽한 순도(모든 샘플이 하나의 클래스), 1은 불순도(노드의 샘플이 균등하게 분포)를 나타냄
▪️ 리프 노드로 갈수록 불순도가 작아지는 방향으로 나무가 자람 - 샘플(samples) : 해당 노드의 샘플 개수
- 값(value) : Y변수에 대한 배열
- 클래스(class)
▪️ 가장 많은 샘플을 차지하는 클래스를 표현
▪️ 위에서는 주황색(Y=0 다수), 파란색(Y=1 다수)를 표현
- 성별 기준으로 의사결정나무 시각화
- 장점
- 쉽고 해석하기 용이
- 다중분류와 회귀에 모두 적용 가능
- 이상치에 견고하며 데이터 스케일링 불필요(데이터의 상대적인 순서를 고려해서)
- 단점
- 나무가 성장을 너무 많이 하면 과대 적합의 오류에 빠질 수 있음
- 훈련 데이터에 민감하게 반응하여 작은 변화에도 나무의 구조가 크게 달라짐(불안정성)
- Python 라이브러리
- sklearn.tree.DecisionTreeClassifier
- sklearn.tree.DecisionTreeRegressor
의사결정나무 실습
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.preprocessing import LabelEncoder
from sklearn.tree import DecisionTreeClassifier, plot_tree
titanic_df = pd.read_csv('파일 경로')
X_features = ['Pclass', 'Sex', 'Age']
# 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)
X = titanic_df[X_features]
y = titanic_df['Survived']
model_dt = DecisionTreeClassifier(max_depth=1)
model_dt.fit(X, y)
plt.figure(figsize = (10,5))
plot_tree(model_dt, feature_names=X_features, class_names=['Not Survived', 'Survived'], filled=True)
plt.show()
랜덤 포레스트 이론
▪️ 배깅(Bagging)의 원리
- 머신러닝은 언제나 데이터 부족이 문제
➡️ 이를 해결하기 위한 Bootsrapping + Aggregating 방법론- Bootstrapping : 데이터를 복원 추출해서 유사하지만 다른 데이터 집단을 생성하는 것
- Aggregating : 데이터의 예측, 분류 결과를 합치는 것
- Ensemble : 여러 개의 모델을 만들어 결과를 합치는 것

▪️ Tree를 Forest로 만들기
- 여러 개의 데이터 샘플에서 각자 의사결정트리를 만들고 다수결 법칙에 따라 결론을 냄
- 의사결정모델이 훈련 데이터에 민감한 점을 극복
▪️ 장점
- Bagging 과정을 통해 과적합을 피할 수 있다
- 이상치에 견고하며 데이터 스케일링 불필요
- 변수 중요도를 추출하여 모델 해석에 중요한 특징을 파악할 수 있다
▪️ 단점
- 컴퓨터 리소스 비용이 크다
- Ensemble 적용으로 해석이 어렵다
▪️ Python 패키지
- sklearn.ensemble.RandomForestClassifer
- sklearn.ensemble.RandomForest
랜덤 포레스트 실습
# 로지스틱회귀, 의사결정나무, 랜덤포레스트
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).round(2)
f1 = f1_score(y_true, y_pred).round(2)
print(model_name, 'acc 스코어는:', acc, 'f1 스코어는:', f1)
get_score('lor', y, y_lor_pred)
get_score('dt', y, y_dt_pred)
get_score('rf', y, y_rf_pred)
## lor acc 스코어는: 0.8 f1 스코어는: 0.73
## dt acc 스코어는: 0.88 f1 스코어는: 0.83
## rf acc 스코어는: 0.88 f1 스코어는: 0.84
X_features
## ['Pclass', 'Sex', 'Age']
model_rf.feature_importances_
## array([0.17077185, 0.40583981, 0.42338834])
'스파르타 코딩클럽 > [강의] 머신러닝' 카테고리의 다른 글
[머신러닝 심화] 데이터 분석 프로세스 - 교차 검증과 GridSearch (1) | 2024.02.01 |
---|---|
[머신러닝 심화] 데이터 분석 프로세스 - 데이터 분리 (0) | 2024.01.31 |
[머신러닝 심화] 데이터 분석 프로세스 - 데이터 전처리(인코딩&스케일링) (0) | 2024.01.31 |
[머신러닝 심화] 데이터 분석 프로세스 - 데이터 전처리(결측치) (0) | 2024.01.31 |
[머신러닝 심화] 데이터 분석 프로세스 - 데이터 전처리(이상치) (0) | 2024.01.31 |