본문 바로가기

파이썬 & 머신러닝과 딥러닝

로지스틱 회귀, K-Fold 교차 검증, 비복원추출, 배깅(랜덤 포레스트), 부스팅(AdaBoost, Gradient Boosting), XGBoost

 

로지스틱 회귀(Logistic Regression) 

 

Iris 데이터셋을 사용하여 두 종(species) 간의 분류 문제

로지스틱 회귀(Logistic Regression) 모델을 적용

꽃잎의 길이를 기반으로 versicolorvirginica 종을 분류

 

import seaborn as sns
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
import sklearn.metrics as slt

# Iris 데이터셋 로드
iris_df = sns.load_dataset('iris')

# Versicolor와 Virginica 종만 선택
iris_df = iris_df[(iris_df['species'] == 'versicolor') | (iris_df['species'] == 'virginica')]

# 독립 변수(X)와 종속 변수(Y) 정의
X = iris_df[['petal_length']]
Y = iris_df['species'].map({'versicolor': 0, 'virginica': 1})

# 학습 데이터와 테스트 데이터로 분할
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.2, random_state=0)

# 로지스틱 회귀 모델 생성 및 학습
lr = LogisticRegression()
lr.fit(X_train, Y_train)

# 회귀 계수와 절편 출력
print("Coefficient = ", lr.coef_)
print("Intercept = ", lr.intercept_)

# 테스트 데이터에 대한 예측 수행
Y_pred = lr.predict(X_test)
print("Predictions: ", Y_pred)

# 정확도 및 정밀도 계산
accuracy_score = slt.accuracy_score(Y_test, Y_pred)
precision_score = slt.precision_score(Y_test, Y_pred)
recall_score = slt.recall_score(Y_pred, Y_test)
f1_score = slt.f1_score(Y_pred, Y_test
                       )
print('Accuracy : ', accuracy_score)
print('Precision : ', precision_score)
print('Recall : ', recall_score)
print('F1 : ', f1_score)

 

→  Coefficient (회귀 계수):

  • [[3.43226939]]는 독립 변수 petal_length에 대한 회귀 계수.
  • 이 값이 양수라는 것은 petal_length가 증가할수록, 즉 꽃잎의 길이가 길어질수록 virginica일 가능성이 높아짐.

 

 

→  Intercept (절편):

  • [-16.54483764]는 절편 값입니다.
  • 이 값은 모델이 petal_length가 0일 때의 예측 값을 조정하는 역할을 합니다. 절편이 음수라는 것은, 초기에는 versicolor로 분류될 가능성이 더 높다는 것을 시사

 

  Predictions (예측 결과):

  • [0 1 1 1 1 1 0 1 1 1 1 1 1 0 0 0 1 0 1 0]는 테스트 데이터에 대한 예측 결과를 나타냄.
  • 0은 versicolor, 1은 virginica로 예측된 경우를 의미. 예를 들어, 첫 번째 데이터 포인트는 versicolor로 예측되었고, 두 번째 데이터 포인트는 virginica로 예측되었음을 뜻함.

 

  Accuracy (정확도):

  • 0.85는 모델의 정확도로, 전체 테스트 데이터 중 85%가 올바르게 예측되었음을 의미.
  • 정확도는 전체 예측에서 맞춘 비율을 나타내며, 이 값이 높을수록 모델의 전반적인 성능이 좋다고 볼 수 있다.

 

Precision (정밀도):

  • 0.7692307692307693는 정밀도로, virginica로 예측된 샘플 중 실제로 virginica인 비율을 나타낸다.
  • 모델이 virginica로 예측한 것들 중 약 77%가 실제로 virginica였다는 것을 의미.

 

Recall (재현율):

  • 0.7692307692307693는 재현율로, 실제 virginica인 샘플 중에서 모델이 올바르게 virginica로 예측한 비율을 나타냄.
  • 즉, 실제 virginica인 샘플 중 77%를 모델이 잘 찾아냈다는 의미.

 

F1 Score (F1 점수):

  • 0.8695652173913044는 F1 점수로, 정밀도와 재현율의 조화 평균.
  • F1 점수는 정밀도와 재현율 사이의 균형을 나타내며, 두 값이 유사할 때 특히 유용함.
  • 이 모델의 F1 점수가 높은 것은 정밀도와 재현율 모두가 균형 있게 높은 수준임을 보여준다.

 

 


 

Titanic 데이터셋을 사용하여 생존 여부를 예측하는 모델을 생성하는 작업

import pandas as pd
import sklearn.tree as str
from sklearn.model_selection import train_test_split
import sklearn.metrics as slt

# Titanic 데이터셋 로드
titanic_df = pd.read_csv('titanic.csv')
# 'titanic.csv' 파일을 읽어와 DataFrame으로 저장합니다.

# 필요한 전처리 (결측치 처리, 필요없는 열 제거 등)
titanic_df['Age'].fillna(titanic_df['Age'].median(), inplace=True)
# 'Age' 열에서 결측치가 있는 경우, 그 값을 나이의 중앙값으로 채웁니다.

titanic_df['Embarked'].fillna('S', inplace=True)
# 'Embarked' 열에서 결측치가 있는 경우, 가장 많이 사용된 승선항(S)을 채웁니다.

titanic_df['Fare'].fillna(titanic_df['Fare'].median(), inplace=True)
# 'Fare' 열에서 결측치가 있는 경우, 그 값을 요금의 중앙값으로 채웁니다.

# 성별을 숫자로 변환
titanic_df['Sex'] = titanic_df['Sex'].map({'male': 0, 'female': 1})
# 'Sex' 열의 값을 'male'은 0, 'female'은 1로 변환합니다. 모델이 숫자로 처리할 수 있도록 하기 위함입니다.

# 필요없는 열 제거
titanic_df.drop(columns=['PassengerId', 'Name', 'Ticket', 'Cabin'], inplace=True)
# 모델 학습에 필요 없는 'PassengerId', 'Name', 'Ticket', 'Cabin' 열을 제거합니다.

# 독립 변수(X)와 종속 변수(Y) 정의
X = titanic_df[['Pclass', 'Sex', 'Age', 'SibSp', 'Parch', 'Fare', 'Embarked']]
# 독립 변수 X를 정의합니다. 생존 여부를 예측하는 데 중요한 정보라고 판단되는 열들만 선택합니다.

X = pd.get_dummies(X, columns=['Embarked'])
# 'Embarked' 열을 더미 변수로 변환합니다. 범주형 변수인 'Embarked'를 모델이 이해할 수 있는 형태로 바꿉니다.

Y = titanic_df['Survived']
# 종속 변수 Y를 정의합니다. 이 변수는 모델이 예측하려는 타깃 값, 즉 생존 여부입니다.

# 학습 데이터와 테스트 데이터로 분할
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.2, random_state=0)
# 데이터를 학습용 데이터(80%)와 테스트용 데이터(20%)로 분할합니다. 'random_state'를 설정하여 결과의 재현성을 보장합니다.

# 결정 트리 모델 생성 및 학습
DT_Model = str.DecisionTreeClassifier()
# 결정 트리 분류 모델을 생성합니다.

DT_Model.fit(X_train, Y_train)
# 학습 데이터를 사용하여 모델을 학습시킵니다.

# 학습 및 테스트 데이터의 점수(정확도) 계산
Train_score = DT_Model.score(X_train, Y_train)
# 학습 데이터에 대한 모델의 정확도를 계산합니다.

Test_score = DT_Model.score(X_test, Y_test)
# 테스트 데이터에 대한 모델의 정확도를 계산합니다.

print('Train Accuracy : ', Train_score)
print('Test Accuracy : ', Test_score)
# 학습 데이터와 테스트 데이터에 대한 정확도를 출력합니다. 이 값들을 비교하여 모델이 과적합(overfitting)되었는지 판단할 수 있습니다.

# 테스트 데이터에 대한 예측 수행
Y_pred = DT_Model.predict(X_test)
# 테스트 데이터를 사용해 생존 여부를 예측합니다.

# 정확도, 정밀도, 재현율 및 F1 점수 계산
accuracy_score = slt.accuracy_score(Y_test, Y_pred)
# 정확도(accuracy)를 계산합니다. 전체 예측에서 맞춘 비율을 의미합니다.

precision_score = slt.precision_score(Y_test, Y_pred)
# 정밀도(precision)를 계산합니다. 생존했다고 예측한 승객 중 실제로 생존한 승객의 비율을 의미합니다.

recall_score = slt.recall_score(Y_test, Y_pred)
# 재현율(recall)을 계산합니다. 실제 생존한 승객 중에서 모델이 생존했다고 예측한 비율을 의미합니다.

f1_score = slt.f1_score(Y_test, Y_pred)
# F1 점수를 계산합니다. 정밀도와 재현율의 조화 평균으로, 두 지표 간의 균형을 평가합니다.

print('Accuracy : ', accuracy_score)
print('Precision : ', precision_score)
print('Recall : ', recall_score)
print('F1 : ', f1_score)
# 정확도, 정밀도, 재현율 및 F1 점수를 출력합니다. 이를 통해 모델의 전반적인 성능을 평가할 수 있습니다.

 

 

 

  • Train Accuracy (학습 정확도): 95.22%
    • 모델이 학습 데이터에서 매우 높은 정확도를 보임. 이는 모델이 학습 데이터에 잘 맞춰져 있다는 것을 의미하지만, 과적합(overfitting) 가능성이 있다.
  • Test Accuracy (테스트 정확도): 66.79%
    • 테스트 데이터에서 모델의 성능이 66.79%로, 학습 데이터보다 정확도가 크게 낮아졌다. 이는 모델이 학습 데이터에 너무 과적합되어 새로운 데이터에 대한 일반화 성능이 떨어지는 것을 나타냄.
  • Precision (정밀도): 66.67%
    • 모델이 생존했다고 예측한 사람들 중 실제로 생존한 비율. 정밀도가 66.67%로, 예측이 완벽하지는 않다.
  • Recall (재현율): 61.90%
    • 실제로 생존한 사람들 중 모델이 생존했다고 올바르게 예측한 비율. 재현율이 낮아 실제 생존자를 놓칠 가능성이 있다.
  • F1 Score: 64.20%
    • 정밀도와 재현율 간의 균형을 나타내는 지표로, 두 값 모두 높지 않아 모델 성능이 개선될 여지가 있음을 시사.

 

 


 

K-Fold 교차 검증 (K-Fold Cross-Validation)과 비복원추출

K-Fold 교차 검증은 머신러닝에서 모델의 성능을 평가하기 위해 널리 사용되는 방법.

데이터를 여러 번 나누어 모델을 학습시키고 평가하는 과정에서

데이터의 분산을 줄이고, 과적합을 방지할 수 있도록 한다.

 

기본 개념

  1. 데이터 분할:
    • 데이터를 K개의 서로 다른 부분(fold)으로 나눈다. 예를 들어, K=5라면 데이터를 5개의 부분으로 나눔.
  2. 교차 검증 과정:
    • 각 fold를 한 번씩 테스트 데이터로 사용하고, 나머지 K-1개의 fold를 학습 데이터로 사용하여 모델을 학습시킴.
    • 이 과정을 K번 반복하여, K개의 모델을 학습시키고 각 모델의 성능을 측정한다.
  3. 평균 성능 평가:
    • K번의 교차 검증 결과로 얻은 성능(예: 정확도, 정밀도, 재현율 등)의 평균을 내어 최종 성능 평가 지표로 사용.

 

비복원추출 (Without Replacement Sampling)

K-Fold 교차 검증에서는 비복원추출이 사용된다. 비복원추출은 한 번 선택된 샘플을 다시 선택하지 않는 방식

  • 복원추출: 선택된 데이터가 다시 선택될 수 있는 방식. 예를 들어, 무작위로 데이터를 선택할 때 같은 데이터가 여러 번 선택될 수 있다.
  • 비복원추출: 선택된 데이터는 다시 선택되지 않는 방식. 한 번 선택된 데이터는 다음 선택에서 제외된다.

K-Fold 교차 검증에서의 비복원추출

K-Fold 교차 검증은 비복원추출을 기반으로 한다. 즉, 데이터를 여러 fold로 나눌 때 각 fold는 고유한 데이터 샘플을 포함. 어떤 데이터 샘플도 두 번 이상 사용되지 않으며, 이는 테스트 데이터가 항상 학습 데이터와 겹치지 않도록 보장한다.

 

예시

예를 들어, 10개의 데이터 포인트가 있다고 가정하고 K=5인 K-Fold 교차 검증을 수행한다고 가정:

  1. 데이터를 5개의 fold로 나눈다:
    • Fold 1: [1, 2]
    • Fold 2: [3, 4]
    • Fold 3: [5, 6]
    • Fold 4: [7, 8]
    • Fold 5: [9, 10]
  2. 교차 검증 과정:
    • 첫 번째 반복: Fold 1을 테스트 데이터로 사용하고, Fold 2-5를 학습 데이터로 사용.
    • 두 번째 반복: Fold 2를 테스트 데이터로 사용하고, Fold 1, 3-5를 학습 데이터로 사용.
    • 이 과정을 K번 반복
  3. 모든 fold가 테스트 데이터로 사용된 후, 각 fold에서 계산된 성능 지표의 평균을 구하여 최종 모델 성능을 평가.

 

K-Fold 교차 검증의 장점

  • 모델의 일반화 성능 평가: 모델이 다양한 데이터 세트에서 어떻게 동작하는지를 평가할 수 있다.
  • 데이터의 효율적 사용: 모든 데이터를 한 번씩 테스트 데이터로 사용하므로, 주어진 데이터의 활용도가 높다.
  • 편향 감소: 단일 훈련/테스트 분할보다 더 균형 잡힌 모델 평가를 제공한다.

 

 

Iris 데이터셋을 사용하여 K-Fold 교차 검증을 수행

sklearn의 KFold 클래스를 사용하여 데이터를 나누고,

각 폴드에 대해 모델을 결정 트리 모델을 사용하여 학습하고 평가

import pandas as pd
from sklearn.model_selection import KFold
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score
from sklearn.preprocessing import LabelEncoder

# Iris 데이터셋 로드
iris_df = sns.load_dataset('iris')

# 독립 변수(X)와 종속 변수(Y) 정의
X = iris_df.drop(columns='species')
Y = iris_df['species']

# species 열을 숫자로 변환
le = LabelEncoder()
Y = le.fit_transform(Y)

# K-Fold 교차 검증 설정
kf = KFold(n_splits=5, shuffle=True, random_state=50)  # 5-fold 교차 검증, 데이터 셔플

# 모델을 저장할 리스트
accuracies = []

# K-Fold 교차 검증 수행
for train_index, test_index in kf.split(X):
    X_train, X_test = X.iloc[train_index], X.iloc[test_index]
    Y_train, Y_test = Y[train_index], Y[test_index]
    
    # 모델 생성 및 학습
    model = DecisionTreeClassifier()
    model.fit(X_train, Y_train)
    
    # 예측 및 평가
    Y_pred = model.predict(X_test)
    accuracy = accuracy_score(Y_test, Y_pred)
    accuracies.append(accuracy)

# 평균 정확도 출력
print(f'K-Fold 교차 검증 평균 정확도: {sum(accuracies) / len(accuracies)}')

 

→  평균 정확도 0.96:

  • 정확도(Accuracy)가 96%라는 것은 모델이 데이터의 대부분을 올바르게 예측했음을 의미 → 모델이 매우 높은 성능
  • K-Fold 교차 검증을 통해 얻은 평균 정확도가 높으면, 모델이 데이터에 잘 맞추어져 있으며, 다양한 데이터 샘플에 대해 안정적인 성능을 보이는 것을 의미한다.

 


 

모델 성능 비교를 위한 K-Fold 교차 검증 및 앙상블 학습

import seaborn as sns
import pandas as pd
from sklearn.model_selection import train_test_split, KFold
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import f1_score
import numpy as np

# 데이터 로드
iris_df = sns.load_dataset('iris')  # Seaborn 라이브러리에서 Iris 데이터셋을 로드합니다.

# 종속 변수와 독립 변수 정의
X = iris_df.drop(columns='species')  # 'species' 열을 제외한 나머지 열들을 독립 변수로 설정합니다.
y = iris_df['species']  # 'species' 열을 종속 변수로 설정합니다.

# 종속 변수를 숫자 레이블로 변환
y = y.map({'setosa': 0, 'versicolor': 1, 'virginica': 2})  # 'species' 값을 숫자로 변환합니다.

# K-Fold 교차 검증 설정
kf = KFold(n_splits=5, shuffle=True, random_state=42)  # 5-Fold 교차 검증 설정, 데이터 무작위 섞기 및 재현 가능성을 위한 random_state 설정

# 모델 생성
dt_model = DecisionTreeClassifier(random_state=42)  # 결정 트리 모델 생성
rf_model = RandomForestClassifier(n_estimators=100, random_state=42)  # 랜덤 포레스트 모델 생성, 100개의 트리 사용

# 성능 평가를 위한 변수 초기화
dt_f1_scores = []  # 결정 트리 모델의 F1 점수를 저장할 리스트
rf_f1_scores = []  # 랜덤 포레스트 모델의 F1 점수를 저장할 리스트

# 각 폴드에 대해 모델 학습 및 평가
for train_index, test_index in kf.split(X):  # 각 폴드에 대해
    X_train, X_test = X.iloc[train_index], X.iloc[test_index]  # 훈련 데이터와 테스트 데이터 분할
    y_train, y_test = y.iloc[train_index], y.iloc[test_index]  # 훈련 레이블과 테스트 레이블 분할
    
    # 결정 트리 모델 학습 및 예측
    dt_model.fit(X_train, y_train)  # 결정 트리 모델 학습
    dt_y_pred = dt_model.predict(X_test)  # 테스트 데이터에 대한 예측 수행
    dt_f1 = f1_score(y_test, dt_y_pred, average='weighted')  # F1 점수 계산 (가중 평균)
    dt_f1_scores.append(dt_f1)  # 결정 트리 모델의 F1 점수를 리스트에 추가
    
    # 랜덤 포레스트 모델 학습 및 예측
    rf_model.fit(X_train, y_train)  # 랜덤 포레스트 모델 학습
    rf_y_pred = rf_model.predict(X_test)  # 테스트 데이터에 대한 예측 수행
    rf_f1 = f1_score(y_test, rf_y_pred, average='weighted')  # F1 점수 계산 (가중 평균)
    rf_f1_scores.append(rf_f1)  # 랜덤 포레스트 모델의 F1 점수를 리스트에 추가

# 평균 F1 점수 출력
dt_avg_f1 = np.mean(dt_f1_scores)  # 결정 트리 모델의 평균 F1 점수 계산
rf_avg_f1 = np.mean(rf_f1_scores)  # 랜덤 포레스트 모델의 평균 F1 점수 계산

print(f'결정 트리 모델 평균 F1 점수: {dt_avg_f1}')  # 결정 트리 모델의 평균 F1 점수 출력
print(f'랜덤 포레스트 모델 평균 F1 점수: {rf_avg_f1}')  # 랜덤 포레스트 모델의 평균 F1 점수 출력

 

 


 

결정 트리와 랜덤 포레스트 회귀 모델의 성능 비교

-> 두 개의 회귀 모델 (결정 트리와 랜덤 포레스트)을 사용하여 보스턴 주택 가격 데이터셋에서 예측 성능을 비교

import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeRegressor
from sklearn.ensemble import RandomForestRegressor
from sklearn.metrics import mean_squared_error, r2_score

# 데이터 로드
boston_df = pd.read_csv('boston.csv')

# 독립 변수(X)와 종속 변수(Y) 정의
X = boston_df.drop(columns='MEDV')  # MEDV를 종속 변수로 가정
y = boston_df['MEDV']

# 데이터 분할 (80% 학습 데이터, 20% 테스트 데이터)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 결정 트리 모델 생성 및 학습
dt_model = DecisionTreeRegressor(random_state=42)
dt_model.fit(X_train, y_train)

# 랜덤 포레스트 모델 생성 및 학습
rf_model = RandomForestRegressor(n_estimators=100, random_state=42)
rf_model.fit(X_train, y_train)

# 모델 평가
# 결정 트리
dt_train_score = dt_model.score(X_train, y_train)
dt_test_score = dt_model.score(X_test, y_test)
dt_y_pred = dt_model.predict(X_test)
dt_mse = mean_squared_error(y_test, dt_y_pred)
dt_r2 = r2_score(y_test, dt_y_pred)

# 랜덤 포레스트
rf_train_score = rf_model.score(X_train, y_train)
rf_test_score = rf_model.score(X_test, y_test)
rf_y_pred = rf_model.predict(X_test)
rf_mse = mean_squared_error(y_test, rf_y_pred)
rf_r2 = r2_score(y_test, rf_y_pred)

# 결과 출력
print(f"Decision Tree - Train_score : {dt_train_score}")
print(f"Decision Tree - Test_score : {dt_test_score}")
print(f"Decision Tree Mean Squared Error: {dt_mse}")
print(f"Decision Tree R^2 Score: {dt_r2}")

print(f"Random Forest - Train_score : {rf_train_score}")
print(f"Random Forest - Test_score : {rf_test_score}")
print(f"Random Forest Mean Squared Error: {rf_mse}")
print(f"Random Forest R^2 Score: {rf_r2}")

결정 트리 모델

  1. Train_score: 1.0
    • 결정 트리 모델이 학습 데이터에 대해 완벽하게 맞추었다는 것을 의미. 학습 데이터에 대해 100%의 R² 점수를 기록하고 있다. 이는 모델이 학습 데이터에 너무 잘 맞춰서 오버피팅(과적합)이 발생할 가능성을 시사함.
  2. Test_score: 0.8579634380978161
    • 결정 트리 모델이 테스트 데이터에 대해 R² 점수로 약 0.858을 기록. 이는 모델이 테스트 데이터에서도 비교적 좋은 성능을 보인다는 의미지만, 학습 데이터에 비해 성능이 떨어지는 것을 알 수 있다.
  3. Mean Squared Error (MSE): 10.416078431372549
    • 결정 트리 모델의 평균 제곱 오차가 약 10.416. 낮을수록 좋으며, 이 값은 예측값과 실제값 간의 평균 제곱 차이를 나타냄.
  4. R² Score: 0.8579634380978161
    • R² 점수는 모델이 종속 변수의 변동성을 얼마나 잘 설명하는지를 나타낸다. 0.858은 모델이 종속 변수의 약 85.8%의 변동성을 설명하고 있다는 의미.

랜덤 포레스트 모델

  1. Train_score: 0.9772267182453291
    • 랜덤 포레스트 모델이 학습 데이터에 대해 R² 점수로 약 0.977을 기록. 이는 학습 데이터에 대해 매우 높은 성능을 보이고 있음을 의미. 오버피팅의 가능성도 있지만, 결정 트리에 비해 높은 성능을 보인다.
  2. Test_score: 0.8922527442109116
    • 랜덤 포레스트 모델이 테스트 데이터에 대해 R² 점수로 약 0.892를 기록. 이는 모델이 테스트 데이터에 대해서도 좋은 성능을 보이고 있음을 의미. 결정 트리 모델보다 테스트 데이터에 대해 더 높은 R² 점수를 기록한다.
  3. Mean Squared Error (MSE): 7.901513892156864
    • 랜덤 포레스트 모델의 평균 제곱 오차가 약 7.902. 결정 트리 모델의 MSE보다 낮다. 이는 랜덤 포레스트 모델이 평균적으로 더 정확한 예측을 하고 있다는 것을 의미한다.
  4. R² Score: 0.8922527442109116
    • R² 점수는 랜덤 포레스트 모델이 종속 변수의 약 89.2%의 변동성을 설명하고 있다는 의미. 결정 트리보다 높은 성능을 보인다.

요약

  • 랜덤 포레스트 모델은 결정 트리 모델에 비해 테스트 데이터에 대해 더 높은 R² 점수와 낮은 MSE를 기록했다. 이는 랜덤 포레스트가 더 정확하고 일반화된 성능을 보인다는 것을 나타낸다.
  • 결정 트리는 학습 데이터에 대해 완벽하게 맞췄지만, 테스트 데이터에 대한 성능은 랜덤 포레스트보다는 낮다. 랜덤 포레스트는 여러 개의 결정 트리를 앙상블하여 성능을 개선하는 방식으로, 일반적으로 더 좋은 성능을 발휘한다.

 


 

앙상블 기법(Ensemble Methods)

앙상블 기법은 여러 개의 모델을 결합하여 성능을 향상시키는 방법

개별 모델의 예측 결과를 조합하여 더 정확하고 안정적인 예측을 얻는 것이 목표

앙상블 기법은 다음과 같은 방법들을 포함:

  1. 배깅 (Bagging): 여러 개의 동일한 모델을 훈련시켜 그 예측을 평균하거나 투표하여 최종 예측을 생성.
  2. 부스팅 (Boosting): 약한 모델들을 순차적으로 학습시켜, 이전 모델이 잘못 예측한 부분을 다음 모델이 보완하도록 함.
  3. 스태킹 (Stacking): 여러 모델을 학습시킨 후, 이 모델들의 예측을 기반으로 새로운 모델(메타 모델)을 학습시킴.

배깅 (Bagging)

  • 배깅Bootstrap Aggregating의 줄임말로, 평균화 또는 다수결 투표를 통해 여러 개의 약한 학습기를 결합하여 성능을 향상시키는 방법.
  • 데이터 샘플링: 원본 데이터셋에서 중복을 허용하여 여러 개의 서브셋을 무작위로 샘플링.
  • 병렬 학습: 여러 개의 서브셋에 대해 독립적으로 학습을 진행하고, 각 모델의 예측을 평균화하거나 다수결 투표를 통해 최종 예측을 생성.
  • 주요 목적: 모델의 분산을 줄이고, 과적합(overfitting)을 방지.
  • : 랜덤 포레스트(Random Forest)

 

부스팅 (Boosting)

  • 부스팅은 여러 개의 약한 학습기를 순차적으로 학습시키며, 각 단계에서 이전 단계에서 잘못 분류된 샘플에 더 많은 가중치를 부여하여 학습.
  • 데이터 샘플링: 각 단계에서 전체 데이터셋을 사용하지만, 잘못 분류된 샘플의 가중치를 증가시킴.
  • 순차적 학습: 각 약한 학습기가 이전 단계에서의 오류를 보정하도록 학습하며, 학습 결과를 결합하여 최종 모델을 생성
  • 주요 목적: 모델의 편향을 줄이고, 정확도를 높임.
  • : AdaBoost(Adaptive Boosting)와 Gradient Boosting Machines (GBM) 등.

 


 

AdaBoost (Adaptive Boosting)

앙상블 학습의 일종으로, 여러 개의 약한 학습기(weak learners)를 결합하여 강한 학습기(strong learner)를 만드는 기법

AdaBoost는 기본적으로 가중치 조정에러 보정을 통해 모델 성능을 향상시키는 방식으로 동작

 

주요 개념

  1. 약한 학습기 (Weak Learner):
    • AdaBoost는 성능이 약간 좋은 모델(약한 학습기)을 여러 개 결합.
    • 보통 약한 학습기는 단일 결정 트리(스텀프)와 같은 간단한 모델이 사용됨.
  2. 가중치 조정:
    • 각 학습 단계에서 잘못 분류된 샘플에 가중치를 부여.
    • 이전 단계에서 잘못 분류된 샘플의 가중치를 증가시키고, 올바르게 분류된 샘플의 가중치는 감소시킨다.
    • 이 방식은 모델이 이전 단계에서 어려움을 겪었던 샘플에 대해 더 많은 학습을 하도록 유도한다.
  3. 에러 보정:
    • 각 약한 학습기는 전체 모델의 예측에 기여하는 비율이 다릅니다. 성능이 좋은 학습기일수록 더 많은 비율을 차지
    • 각 약한 학습기의 가중치를 결정하여 최종 예측을 수행합
  4. 순차적 학습:
    • AdaBoost는 학습 데이터를 순차적으로 처리하면서 각 단계에서 약한 학습기를 추가
    • 각 단계에서 이전 단계의 오차를 보정하면서 학습을 진행한다.

 

AdaBoost의 작동 방식

  1. 초기화:
    • 모든 데이터 포인트에 대해 동일한 가중치를 부여.
  2. 학습:
    • 약한 학습기를 학습하고, 각 데이터 포인트의 가중치를 업데이트. 잘못 분류된 데이터 포인트는 가중치가 증가하고, 올바르게 분류된 데이터 포인트는 가중치가 감소한다.
  3. 모델 결합:
    • 각 약한 학습기의 성능에 따라 가중치를 부여하고, 최종 모델을 생성하기 위해 모든 약한 학습기의 예측을 결합
  4. 예측:
    • 모든 약한 학습기의 예측을 가중치에 따라 결합하여 최종 예측을 수행

 

 

AdaBoost를 사용한 Iris 데이터셋 분류 및 성능 평가

AdaBoost는 여러 약한 학습기(여기서는 기본 설정)들을 결합하여 강력한 분류기를 만드는 앙상블 방법

import pandas as pd
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.ensemble import AdaBoostClassifier

# Iris 데이터셋 로드
iris = load_iris()  # scikit-learn의 내장 Iris 데이터셋을 로드합니다.

# 데이터를 pandas DataFrame으로 변환
df = pd.DataFrame(iris.data, columns=iris.feature_names)  # 데이터셋의 feature(속성) 정보를 DataFrame으로 만듭니다.
df['species'] = [iris.target_names[x] for x in iris.target]  # target(종속 변수) 값을 species(종속 변수 이름)으로 변환하여 DataFrame에 추가합니다.

# 독립 변수(X)와 종속 변수(Y) 정의
x = df.drop('species', axis=1)  # 'species' 열을 제외한 나머지 열들을 독립 변수 X로 설정합니다.
y = df['species']  # 'species' 열을 종속 변수 Y로 설정합니다.

# 학습 데이터와 테스트 데이터로 분할
x_train, x_test, y_train, y_test = train_test_split(x, y, train_size=0.8, test_size=0.2, random_state=42)  
# 데이터를 학습 데이터와 테스트 데이터로 분할합니다. 학습 데이터는 80%, 테스트 데이터는 20%로 설정합니다.
# random_state=42는 결과의 재현성을 보장합니다.

# AdaBoost 모델 생성 및 학습
AD_Model = AdaBoostClassifier(n_estimators=50, random_state=42)  # AdaBoost 모델을 생성합니다. n_estimators는 weak learner의 수를 설정합니다.
AD_Model.fit(x_train, y_train)  # 학습 데이터를 사용하여 모델을 학습합니다.

# 학습 및 테스트 데이터에 대한 성능 평가
Train_score = AD_Model.score(x_train, y_train)  # 학습 데이터에 대한 정확도를 평가합니다.
Test_score = AD_Model.score(x_test, y_test)  # 테스트 데이터에 대한 정확도를 평가합니다.

# 결과 출력
print('AdaBoost - Train_score : ', Train_score, ', Test_score : ', Test_score)  
# 학습 데이터와 테스트 데이터에 대한 정확도를 출력합니다.

AdaBoost를 사용하여 Iris 데이터셋을 분류하고, 학습 데이터와 테스트 데이터에서 모델의 정확도를 평가

AdaBoost 모델이 Iris 데이터셋을 매우 잘 분류했음을 나타내며, 주어진 데이터셋에 대해 높은 성능을 보임.


 

AdaBoost를 사용한 Iris 데이터셋 분류 및 성능 평가 (기본 하이퍼파라미터 사용)

n_estimators와 random_state를 설정하지 않아서 기본값으로 n_estimators=50 사용.

import pandas as pd
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.ensemble import AdaBoostClassifier

# Iris 데이터셋 로드
iris = load_iris()  # scikit-learn의 내장 Iris 데이터셋을 로드합니다.

# 데이터를 pandas DataFrame으로 변환
df = pd.DataFrame(iris.data, columns=iris.feature_names)  # 데이터셋의 feature(속성) 정보를 DataFrame으로 만듭니다.
df['species'] = [iris.target_names[x] for x in iris.target]  # target(종속 변수) 값을 species(종속 변수 이름)으로 변환하여 DataFrame에 추가합니다.

# 독립 변수(X)와 종속 변수(Y) 정의
x = df.drop('species', axis=1)  # 'species' 열을 제외한 나머지 열들을 독립 변수 X로 설정합니다.
y = df['species']  # 'species' 열을 종속 변수 Y로 설정합니다.

# 학습 데이터와 테스트 데이터로 분할
x_train, x_test, y_train, y_test = train_test_split(x, y, train_size=0.8, test_size=0.2, random_state=42)  
# 데이터를 학습 데이터와 테스트 데이터로 분할합니다. 학습 데이터는 80%, 테스트 데이터는 20%로 설정합니다.
# random_state=42는 결과의 재현성을 보장합니다.

# AdaBoost 모델 생성 및 학습
AD_Model = AdaBoostClassifier()  # 기본 하이퍼파라미터를 사용하여 AdaBoost 모델을 생성합니다.
AD_Model.fit(x_train, y_train)  # 학습 데이터를 사용하여 모델을 학습합니다.

# 학습 및 테스트 데이터에 대한 성능 평가
Train_score = AD_Model.score(x_train, y_train)  # 학습 데이터에 대한 정확도를 평가합니다.
Test_score = AD_Model.score(x_test, y_test)  # 테스트 데이터에 대한 정확도를 평가합니다.

# 결과 출력
print('AdaBoost - Train_score : ', Train_score, ', Test_score : ', Test_score)  
# 학습 데이터와 테스트 데이터에 대한 정확도를 출력합니다.

 


 

Titanic 데이터셋을 사용한 AdaBoost 분류 모델을 통한 생존 예측

Titanic 데이터셋을 사용하여 AdaBoost 분류 모델을 학습하고,

학습된 모델을 통해 특정 개인의 생존 여부를 예측하는 코드.

import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.ensemble import AdaBoostClassifier
from sklearn.preprocessing import LabelEncoder
from sklearn.metrics import accuracy_score

# 데이터 로드
file_path = 'titanic.csv'  # Titanic 데이터셋의 파일 경로
df = pd.read_csv(file_path)  # CSV 파일에서 데이터 로드

# 필요한 열만 선택 ('Age', 'Sex', 'Survived')
df = df[['Age', 'Sex', 'Survived']]  # 'Age', 'Sex', 'Survived' 열만 선택

# 결측값 처리 (나이에서 결측값을 평균값으로 대체)
df['Age'].fillna(df['Age'].mean(), inplace=True)  # 나이의 결측값을 평균값으로 대체

# 성별을 숫자로 변환
le = LabelEncoder()
df['Sex'] = le.fit_transform(df['Sex'])  # 'male'을 1, 'female'을 0으로 변환

# 독립 변수(X)와 종속 변수(Y) 정의
X = df[['Age', 'Sex']]  # 독립 변수: 나이와 성별
y = df['Survived']  # 종속 변수: 생존 여부

# 학습 데이터와 테스트 데이터로 분할
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 80%를 학습 데이터로, 20%를 테스트 데이터로 분할

# AdaBoost 모델 생성 및 학습
AD_Model = AdaBoostClassifier(n_estimators=50, random_state=42)
# AdaBoostClassifier 모델 생성, 기본 학습기(DecisionTreeClassifier)를 사용, n_estimators=50
AD_Model.fit(X_train, y_train)  # 모델 학습

# 학습 및 테스트 데이터에 대한 성능 평가
y_train_pred = AD_Model.predict(X_train)  # 학습 데이터에 대한 예측
y_test_pred = AD_Model.predict(X_test)  # 테스트 데이터에 대한 예측
Train_score = accuracy_score(y_train, y_train_pred)  # 학습 데이터 정확도 계산
Test_score = accuracy_score(y_test, y_test_pred)  # 테스트 데이터 정확도 계산
print('AdaBoost - Train Accuracy: ', Train_score)  # 학습 데이터 정확도 출력
print('AdaBoost - Test Accuracy: ', Test_score)  # 테스트 데이터 정확도 출력

# 사용자 입력을 통한 생존 여부 예측
def predict_survival(age, sex):
    # 입력된 성별을 숫자로 변환
    sex_num = 1 if sex.lower() == 'male' else 0  # 'male'을 1, 'female'을 0으로 변환
    # 입력 데이터를 모델의 형식에 맞게 변환
    input_data = pd.DataFrame({'Age': [age], 'Sex': [sex_num]})
    # 생존 여부 예측
    prediction = AD_Model.predict(input_data)  # 모델을 사용하여 예측
    return 'Survived' if prediction[0] == 1 else 'Did not survive'  # 예측 결과 반환

# 예시: 사용자 입력
age = float(input("Enter age: "))  # 사용자로부터 나이 입력 받기
sex = input("Enter sex (male/female): ")  # 사용자로부터 성별 입력 받기
# 생존 여부 예측 및 출력
result = predict_survival(age, sex)  # 생존 여부 예측
print(f"The model predicts that this person would have: {result}")  # 예측 결과 출력

 

 

 

  • 학습 정확도는 약 71.06%로, 학습 데이터에 대해 모델이 71.06%의 정확도로 예측을 맞추었다는 의미.
  • 테스트 정확도는 약 66.79%로, 테스트 데이터에 대해 모델이 66.79%의 정확도로 예측을 맞추었다는 의미.

 

→ 입력된 나이와 성별에 기반하여 모델이 예측한 결과는 "Did not survive"

이는 이 모델이 제공된 정보를 바탕으로 해당 개인이 생존하지 않을 가능성이 높다고 판단

 


 

Gradient Boosting(그래디언트 부스팅)

  • Gradient Boosting은 각 모델이 이전 모델이 만든 오류를 개선할 수 있도록 설계된 일련의 약한 학습기들을 결합하여 강력한 예측 모델을 만드는 기법
  • Gradient Boosting은 이 약한 학습기들을 단계적으로 추가하면서 예측 오류를 줄여나가도록 설계됨
  • Gradient Boosting의 대표적인 구현으로는 XGBoost, LightGBM, CatBoost 등이 있다

 

주요 개념:

  1. 순차적 학습:
    • Gradient Boosting은 약한 학습기를 한 번에 하나씩 순차적으로 학습시킨다.
    • 이전 모델이 만든 예측 오류(잔차, residual)에 집중해서 새로운 모델을 학습시킨다.
  2. 잔차(residuals) 기반 학습:
    • 각 단계에서 새로 추가되는 약한 학습기는 현재까지의 모델이 예측하지 못한 잔차(residuals)를 예측하는 데 초점을 맞춘다.
    • 이렇게 함으로써 모델이 점점 더 나은 성능을 가지도록 개선된다.
  3. 그래디언트(Gradient):
    • Gradient Boosting에서의 "그래디언트"는 모델이 예측할 때 발생한 오류의 그래디언트(기울기)를 계산하여, 그 오류를 줄이는 방향으로 새로운 모델을 학습시키는 데 사용된다.
    • 이 그래디언트는 오차 함수의 기울기입니다. 학습 과정에서 이 기울기를 활용해 손실을 최소화하는 방향으로 모델을 업데이트함.
  4. 손실 함수(Loss Function):
    • 모델이 얼마나 잘못 예측했는지를 측정하는 함수. 회귀 문제에서는 일반적으로 평균 제곱 오차(MSE)를 사용하고, 분류 문제에서는 로그 손실(log loss) 등을 사용할 수 있다.
    • Gradient Boosting은 이 손실 함수를 최소화하는 방향으로 모델을 계속 개선해 나간다.

 

 

Gradient Boosting을 사용한 Iris 데이터셋 분류 및 성능 평가

import pandas as pd
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.ensemble import AdaBoostClassifier
from sklearn.ensemble import GradientBoostingClassifier

# Iris 데이터셋 로드
# Iris 데이터셋을 로드하여 DataFrame으로 변환
iris = load_iris()
df = pd.DataFrame(iris.data, columns=iris.feature_names)
df['species'] = [iris.target_names[x] for x in iris.target]

# 독립 변수(X)와 종속 변수(Y) 정의
# 'species' 컬럼을 종속 변수(y)로 설정하고 나머지 컬럼들을 독립 변수(X)로 설정
x = df.drop('species', axis=1)
y = df['species']

# 학습 데이터와 테스트 데이터로 분할
# 데이터셋을 학습용 데이터(80%)와 테스트용 데이터(20%)로 분할
x_train, x_test, y_train, y_test = train_test_split(x, y, train_size=0.8, test_size=0.2, random_state=42)

# Gradient Boosting 모델 생성 및 학습
# GradientBoostingClassifier를 사용하여 모델을 생성하고 학습 데이터로 학습시킴
GBM_Model = GradientBoostingClassifier()
GBM_Model.fit(x_train, y_train)

# 학습 및 테스트 데이터에 대한 정확도 평가
# 학습 데이터와 테스트 데이터에 대한 모델의 정확도(accuracy)를 계산
Train_score = GBM_Model.score(x_train, y_train)
Test_score = GBM_Model.score(x_test, y_test)

# 결과 출력
print('GBM - Train_score : ', Train_score, ', Test_score : ', Test_score)

 

→ 학습 데이터와 테스트 데이터 모두에서 100%의 정확도를 보였다는 의미

 


 

 

Gradient Boosting Regressor를 사용하여 Boston Housing 데이터셋에서 주택 가격 예측 모델을 학습하고 평가

MEDV(주택의 중위 가격)를 종속 변수로 사용하고, 다른 변수들(독립 변수)을 바탕으로 주택 가격을 예측

R^2 점수와 MSE를 통해 모델의 학습 및 테스트 데이터에 대한 성능을 측정

import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.ensemble import GradientBoostingRegressor
from sklearn.metrics import mean_squared_error, r2_score

# Boston 데이터셋 로드
file_path = 'boston.csv'
df = pd.read_csv(file_path)

# 독립 변수(X)와 종속 변수(Y) 정의
X = df.drop('MEDV', axis=1)  # 'MEDV'를 종속 변수로 사용
y = df['MEDV']

# 학습 데이터와 테스트 데이터로 분할
X_train, X_test, y_train, y_test = train_test_split(X, y, train_size=0.8, test_size=0.2, random_state=42)

# Gradient Boosting 모델 생성 및 학습
GBM_Model = GradientBoostingRegressor()  # Gradient Boosting Regressor 모델 생성
GBM_Model.fit(X_train, y_train)  # 모델 학습

# 학습 및 테스트 데이터에 대한 평가
Train_score = GBM_Model.score(X_train, y_train)  # 학습 데이터에 대한 R^2 점수
Test_score = GBM_Model.score(X_test, y_test)  # 테스트 데이터에 대한 R^2 점수

# MSE와 R^2 점수 계산
y_train_pred = GBM_Model.predict(X_train)  # 학습 데이터에 대한 예측값
y_test_pred = GBM_Model.predict(X_test)  # 테스트 데이터에 대한 예측값
train_mse = mean_squared_error(y_train, y_train_pred)  # 학습 데이터에 대한 평균 제곱 오차 (MSE)
test_mse = mean_squared_error(y_test, y_test_pred)  # 테스트 데이터에 대한 평균 제곱 오차 (MSE)
train_r2 = r2_score(y_train, y_train_pred)  # 학습 데이터에 대한 결정 계수 (R^2)
test_r2 = r2_score(y_test, y_test_pred)  # 테스트 데이터에 대한 결정 계수 (R^2)

print('GBM - Train_score (R^2) : ', Train_score, ', Test_score (R^2) : ', Test_score)
print('Train MSE: ', train_mse)
print('Test MSE: ', test_mse)
print('Train R^2 Score: ', train_r2)
print('Test R^2 Score: ', test_r2)

 

1. Train_score (R^2): 0.9800300447996301

  • 학습 데이터에 대한 결정 계수(R^2) 점수가 약 0.98
  • 이는 모델이 학습 데이터에서 주택 가격 변동의 98%를 설명할 수 있음을 의미
  • 학습 데이터에서 매우 높은 적합도를 보이는 것을 나타낸다.

2. Test_score (R^2): 0.9149106445660158

  • 테스트 데이터에 대한 결정 계수(R^2) 점수가 약 0.91
  • 테스트 데이터에서도 상당히 높은 성능을 나타내며, 주택 가격 변동의 약 91%를 설명할 수 있다.
  • 이는 모델이 새로운 데이터(테스트 데이터)에 대해서도 잘 일반화되었음을 시사한다.

3. Train MSE: 1.7348579826478066

  • 학습 데이터에 대한 평균 제곱 오차(MSE)가 약 1.73
  • 이는 학습 데이터에서 예측된 주택 가격이 실제 주택 가격과 평균적으로 약 1.73 단위만큼 차이가 난다는 것을 의미

4. Test MSE: 6.2399243406474465

  • 테스트 데이터에 대한 평균 제곱 오차(MSE)가 약 6.24
  • 이는 모델이 테스트 데이터에서 예측된 주택 가격이 실제 주택 가격과 평균적으로 약 6.24 단위만큼 차이가 난다는 것을 의미

5. Train R^2 Score: 0.9800300447996301

  • 학습 데이터에 대한 R^2 점수로, 학습 데이터에서 모델의 성능을 다시 확인할 수 있다. 이는 Train_score (R^2)과 동일한 값이다.

6. Test R^2 Score: 0.9149106445660158

  • 테스트 데이터에 대한 R^2 점수로, 테스트 데이터에서 모델의 성능을 다시 확인할 수 있다. 이는 Test_score (R^2)과 동일한 값이다.

 

타이타닉 생존 예측을 위한 Gradient Boosting 모델 학습 및 예측

import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.metrics import accuracy_score, f1_score
from sklearn.preprocessing import LabelEncoder

# 데이터 로드
file_path = 'titanic.csv'  # 타이타닉 데이터 파일 경로
df = pd.read_csv(file_path)

# 필요한 열만 선택 (예: 'Age', 'Sex', 'Survived')
df = df[['Age', 'Sex', 'Survived']]

# 결측값 처리
df['Age'].fillna(df['Age'].mean(), inplace=True)

# 성별을 숫자로 변환
le = LabelEncoder()
df['Sex'] = le.fit_transform(df['Sex'])  # 'male'을 1, 'female'을 0으로 변환

# 독립 변수(X)와 종속 변수(Y) 정의
X = df[['Age', 'Sex']]
y = df['Survived']

# 학습 데이터와 테스트 데이터로 분할
X_train, X_test, y_train, y_test = train_test_split(X, y, train_size=0.8, test_size=0.2, random_state=42)

# Gradient Boosting 모델 생성 및 학습
GBM_Model = GradientBoostingClassifier(n_estimators=50, random_state=42)
GBM_Model.fit(X_train, y_train)

# 학습 및 테스트 데이터에 대한 정확도 평가
y_train_pred = GBM_Model.predict(X_train)
y_test_pred = GBM_Model.predict(X_test)

# 정확도 및 F1 점수 계산
Train_score = accuracy_score(y_train, y_train_pred)
Test_score = accuracy_score(y_test, y_test_pred)
F1 = f1_score(y_test, y_test_pred, average='micro')

print('GBM - Train Accuracy: ', Train_score)
print('GBM - Test Accuracy: ', Test_score)
print('F1 Score (micro):', F1)

# 사용자 입력을 통한 생존 여부 예측
def predict_survival(age, sex):
    # 입력된 성별을 숫자로 변환
    sex_num = 1 if sex.lower() == 'male' else 0
    # 입력 데이터를 모델의 형식에 맞게 변환
    input_data = pd.DataFrame({'Age': [age], 'Sex': [sex_num]})
    # 생존 여부 예측
    prediction = GBM_Model.predict(input_data)
    return 'Survived' if prediction[0] == 1 else 'Did not survive'

# 예시: 사용자 입력
age = float(input("Enter age: "))
sex = input("Enter sex (male/female): ")
# 생존 여부 예측 및 출력
result = predict_survival(age, sex)
print(f"The model predicts that this person would have: {result}")

 

 

  • Train Accuracy: 0.7297
    • 학습 데이터에 대한 정확도는 약 72.97%. 이는 모델이 학습 데이터에서 약 73%의 정확도로 생존 여부를 예측하고 있다는 것을 의미.
  • Test Accuracy: 0.6679
    • 테스트 데이터에 대한 정확도는 약 66.79%. 이는 모델이 테스트 데이터에서 약 67%의 정확도로 생존 여부를 예측하고 있다는 것을 의미.
  • F1 Score (micro): 0.6679
    • F1 Score (micro)는 약 66.79%. F1 Score는 정확도와 재현율의 조화 평균으로, 클래스 불균형이 있는 경우에도 모델의 성능을 평가하는 데 유용하다. 'micro' 평균은 모든 클래스를 하나로 보고 전체적인 성능을 평가한다.
  • 사용자 입력 예측:
    • 사용자 입력: 나이 20세, 성별 여성
    • 예측 결과: 이 사람이 생존할 것으로 예측되었다.

 

 


 

XGBoost (Extreme Gradient Boosting)

 

Gradient Boosting의 향상된 버전으로,

정규화, 병렬 처리, 모델 저장 등 다양한 기능을 제공하여 성능과 효율성을 높인 알고리즘.

 

 XGBoost의 주요 특징과 개념:

1. Gradient Boosting 기반

  • Gradient Boosting: XGBoost는 기본적으로 Gradient Boosting 알고리즘을 기반으로 한다. Gradient Boosting은 약한 학습기(주로 결정 트리)를 순차적으로 학습시키는 방법으로 각 학습기는 이전 모델의 예측 오류를 줄이기 위해 학습함. 이 과정에서 오류를 잔여 오차로 계산하고, 이를 줄이기 위해 새로운 모델을 추가한다.

 

2. Boosting

  • Boosting: Boosting은 여러 약한 학습기를 결합하여 강력한 예측 모델을 만드는 기법. 각 학습기는 이전 모델의 오류를 보정하기 위해 학습되며, 모델의 성능을 점진적으로 향상시킨다. Boosting의 핵심은 여러 모델을 순차적으로 학습시키고, 각 모델이 잘못 예측한 데이터에 더 집중하게 만드는 것이다.

 

3. XGBoost의 주요 특징

  • 성능 최적화: XGBoost는 성능을 높이기 위해 다양한 최적화 기법을 사용함. 여기에는 효율적인 계산을 위한 병렬 처리, 메모리 사용을 줄이기 위한 데이터 압축, 빠른 학습을 위한 그라디언트 업데이트가 포함된다.
  • 정규화: XGBoost는 모델의 복잡성을 제어하기 위해 정규화 기법(예: L1, L2 정규화)을 적용한다. 이를 통해 과적합(overfitting)을 방지하고 모델의 일반화 능력을 향상시킨다.
  • 특성 중요도 평가: XGBoost는 각 특성(feature)의 중요도를 평가하여 모델의 해석 가능성을 높인다. 이를 통해 어떤 특성이 예측에 가장 중요한지를 이해할 수 있다.
  • 하이퍼파라미터 조정: XGBoost는 다양한 하이퍼파라미터를 조정할 수 있어, 모델의 성능을 최적화하기 위한 세밀한 조정이 가능하다. 주요 하이퍼파라미터에는 트리의 깊이, 학습률, 부스팅 라운드 수 등이 포함됨.
  • 다양한 손실 함수 지원: XGBoost는 회귀, 분류 등 다양한 문제에 적합한 손실 함수(loss function)를 지원한다. 이는 모델이 다양한 유형의 문제에 적용될 수 있도록 한다.

 

4. 하이퍼파라미터

XGBoost는 많은 하이퍼파라미터를 조정할 수 있어 모델을 세밀하게 조정할 수 있다. 

  • n_estimators: 부스팅 단계의 수, 즉 결정 트리의 개수.
  • learning_rate (또는 eta): 각 단계에서 모델이 학습하는 비율. 낮은 값을 사용하면 모델의 성능이 향상되지만 학습 시간이 길어질 수 있다.
  • max_depth: 결정 트리의 최대 깊이.
  • min_child_weight: 자식 노드를 분할하기 위한 최소 가중치.
  • subsample: 각 트리가 학습에 사용할 샘플의 비율.
  • colsample_bytree: 각 트리가 학습에 사용할 특징의 비율.
  • gamma: 추가적인 분할을 위해 필요한 최소 손실 감소.

 

5. 주요 알고리즘 및 기능

  • 기본 알고리즘: XGBoost는 기본적으로 결정 트리를 사용.
  • 회귀 및 분류: XGBoost는 회귀와 분류 문제를 모두 처리할 수 있다.
  • 특징 중요도: 모델의 각 특징이 예측에 기여하는 정도를 평가할 수 있는 기능이 제공된다.

 

6. 사용 예시

  • 회귀 문제: 집 값 예측, 판매량 예측 등
  • 분류 문제: 스팸 이메일 필터링, 이미지 분류 등

 

 

XGBoost를 활용한 Iris 데이터셋 분류 및 정확도 평가

import pandas as pd
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from xgboost import XGBClassifier

# Iris 데이터셋 로드
iris = load_iris()
# DataFrame으로 변환하여 feature_names와 target을 열로 추가
df = pd.DataFrame(iris.data, columns=iris.feature_names)
df['species'] = iris.target

# 독립 변수(X)와 종속 변수(Y) 정의
x = df.drop('species', axis=1)  # 'species' 열을 제외한 모든 열을 독립 변수로 사용
y = df['species']  # 'species' 열을 종속 변수로 사용

# 학습 데이터와 테스트 데이터로 분할
x_train, x_test, y_train, y_test = train_test_split(x, y, train_size=0.8, test_size=0.2, random_state=42)
# 80%의 데이터를 학습 데이터로, 20%를 테스트 데이터로 분할

# XGBoost 모델 생성 및 학습
# SGB_Model = XGBClassifier(use_label_encoder=False, eval_metric='mlogloss') # 이 줄은 주석 처리됨
SGB_Model = XGBClassifier(eval_metric='mlogloss')  # 'mlogloss' 손실 함수를 사용하는 XGBoost 분류기 생성
SGB_Model.fit(x_train, y_train)  # 학습 데이터로 모델을 학습

# 학습 및 테스트 데이터에 대한 정확도 평가
Train_score = SGB_Model.score(x_train, y_train)  # 학습 데이터에 대한 정확도 계산
Test_score = SGB_Model.score(x_test, y_test)  # 테스트 데이터에 대한 정확도 계산

# 결과 출력
print('SGB - Train_score : ', Train_score, ', Test_score : ', Test_score)  # 학습 데이터와 테스트 데이터에 대한 정확도 출력

 

→ 모델의 과적합 여부를 평가하기 위해 Cross-Validation을 수행해봄

 

from sklearn.model_selection import cross_val_score

# 5-Fold Cross-Validation 수행
cv_scores = cross_val_score(SGB_Model, x, y, cv=5)

# 각 폴드에서의 정확도 점수 출력
print("Cross-Validation Scores: ", cv_scores)

# Cross-Validation 점수의 평균 출력
print("Mean Cross-Validation Score: ", cv_scores.mean())

 

  모델이 과적합되지 않고 다양한 데이터 샘플에 대해 일관된 성능을 보이는 것으로 보인다.

Cross-Validation 점수가 안정적이고 높은 점수를 유지하고 있기 때문에, 과적합의 위험이 낮다고 할 수 있다.

 

 


 

XGBoost Regressor를 이용한 주택 가격 예측

import pandas as pd
from sklearn.model_selection import train_test_split
from xgboost import XGBRegressor
from sklearn.metrics import mean_squared_error, r2_score

# Boston 데이터셋 로드
file_path = 'boston.csv'  # Boston 주택 가격 데이터 파일 경로
df = pd.read_csv(file_path)

# 독립 변수(X)와 종속 변수(Y) 정의
X = df.drop('MEDV', axis=1)  # 'MEDV'는 주택 가격을 나타내는 열입니다.
y = df['MEDV']  # 'MEDV'는 종속 변수로 주택 가격을 나타냅니다.

# 학습 데이터와 테스트 데이터로 분할
X_train, X_test, y_train, y_test = train_test_split(X, y, train_size=0.8, test_size=0.2, random_state=42)

# XGBoost 모델 생성 및 학습
model = XGBRegressor(eval_metric='mlogloss')  # XGBRegressor 객체 생성, 'mlogloss'는 평가 지표로 설정됨
model.fit(X_train, y_train)  # 모델 학습

# 학습 및 테스트 데이터에 대한 예측값 생성
y_train_pred = model.predict(X_train)  # 학습 데이터에 대한 예측
y_test_pred = model.predict(X_test)  # 테스트 데이터에 대한 예측

# 학습 및 테스트 데이터에 대한 평가
train_mse = mean_squared_error(y_train, y_train_pred)  # 학습 데이터의 Mean Squared Error
test_mse = mean_squared_error(y_test, y_test_pred)  # 테스트 데이터의 Mean Squared Error
train_r2 = r2_score(y_train, y_train_pred)  # 학습 데이터의 R^2 점수
test_r2 = r2_score(y_test, y_test_pred)  # 테스트 데이터의 R^2 점수

print('XGB - Train MSE: ', train_mse)  # 학습 데이터의 MSE 출력
print('XGB - Test MSE: ', test_mse)  # 테스트 데이터의 MSE 출력
print('XGB - Train R^2 Score: ', train_r2)  # 학습 데이터의 R^2 점수 출력
print('XGB - Test R^2 Score: ', test_r2)  # 테스트 데이터의 R^2 점수 출력

 

  • Train MSE (Mean Squared Error)
    • 값: 0.0002620971899759447
    • 의미: 훈련 데이터에서 모델이 예측한 값과 실제 값 사이의 평균 제곱 오차가 매우 작다. 이는 모델이 훈련 데이터에 대해 거의 완벽하게 예측하고 있음을 나타낸다.
  • Test MSE (Mean Squared Error)
    • 값: 6.909231565384943
    • 의미: 테스트 데이터에서의 평균 제곱 오차는 훈련 데이터에 비해 훨씬 크다. 이는 모델이 새로운 데이터(테스트 데이터)에 대해 예측 성능이 떨어진다는 것을 의미.
  • Train R² Score
    • 값: 0.9999969829984965
    • 의미: 훈련 데이터에 대한 결정계수(R²)가 거의 1에 가까워, 모델이 훈련 데이터의 변동을 거의 완벽하게 설명하고 있음을 나타낸다. 매우 높은 값은 모델이 훈련 데이터에 과도하게 적합됐을 가능성을 시사한다.
  • Test R² Score
    • 값: 0.9057837838492537
    • 의미: 테스트 데이터에 대한 결정계수(R²)가 높은 편이지만, 훈련 데이터에서의 R²와 비교하면 낮다. 이는 모델이 테스트 데이터에 대한 예측 성능은 좋은 편이지만, 훈련 데이터에 비해 성능이 떨어진다는 것을 의미

-> 과적합일 수 있음