Posts 와인데이터로 해보는 부스팅 알고리즘(Boosting Algorithm)
Post
Cancel

와인데이터로 해보는 부스팅 알고리즘(Boosting Algorithm)

1. 앙상블


1.1 앙상블이란

  • 앙상블은 전통적으로 Voting, Bagging, Boosting, 스태깅으로 나뉨
  • 보팅과 배깅은 여러개의 분류기가 투표를 통해 최종 예측 결과를 결정하는 방식임
  • 보팅과 배깅의 차이점은 보팅은 각각 다른 분류기, 배깅은 같은 분류기를 사용함
  • 대표적인 배깅은 랜덤 포레스트


1.2 Boosting의 개요

  • 여러개의 분류기가 순차적으로 학습을 하면서, 앞에서 학습한 분류기가 예측이 틀린 데이터에 대해 다음 분류기가 가중치를 인가해서 학습을 이어 진행하는 방식
  • 예측 성능이 뛰어나서 앙상블 학습을 주도함
  • 그래디언트 부스트(Gradient Boost), XGBoost, LightGBM 등이 있음


1.3 배깅과 부스팅의 차이

  • 배깅 : 한번에 병렬적으로 결과를 얻음
  • 부스팅 : 순차적으로 진행이 됨


1.4 Adaboost

  • 순차적으로 가중치를 부여해서 최종 결과를 얻음
  • AdaBoost는 Decision Tree기반의 알고리즘임
  • 여러 Step을 거치며 각 Step에서 틀린 데이터에 가중치를 인가하며 경계선을 결정함
  • 마지막으로 앞의 Step들에서 결정한 경계들을 모두 합침


1.5 부스팅 기법

  • GBM Gradient Boosting : AdaBoost 기법과 비슷하지면 가중치를 업데이트할때 경사하강법(Gradient Descent)을 사용
  • XGBoost : GBM에서 PC의 파워를 효율적으로 사용하기 위해 다양한 기법에 채택되어 빠른 속도와 효율을 가짐
  • LigthGBM : XGBoost보다 빠른 속도를 가짐


1.6 Bagging = Bootstrap AGGregatING


1.7 Bagging과 Boosting의 차이


2. Wine 데이터로 실습


2.1 Data load

1
2
3
4
5
6
7
8
9
import pandas as pd

wine_url = 'https://raw.githubusercontent.com/hmkim312/datas/main/wine/wine.csv'

wine = pd.read_csv(wine_url, index_col=0)
wine['taste'] = [1. if grade > 5 else 0. for grade in wine['quality']]

X = wine.drop(['taste','quality'],  axis = 1)
y = wine['taste']
  • 데이터를 불러오고, quality를 기준으로 taste 컬럼까지 생성


2.2 Scaler 적용 후 데이터 나누기

1
2
3
4
from sklearn.preprocessing import StandardScaler

sc = StandardScaler()
X_sc = sc.fit_transform(X)
1
2
3
4
from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(
    X_sc, y, test_size=0.2, random_state=13)


2.3 모든 컬럼의 히스토그램 확인

1
2
3
4
5
import matplotlib.pyplot as plt
%matplotlib inline

wine.hist(bins = 10, figsize=(24, 24))
plt.show()


2.4 Quality 별 다른 특성이 어떤지 확인

1
2
3
4
5
colum_names = ['fixed acidity', 'volatile acidity', 'citric acid', 'residual sugar',
               'chlorides', 'free sulfur dioxide', 'total sulfur dioxide', 'density',
               'pH', 'sulphates', 'alcohol']
df_pivot_table = wine.pivot_table(colum_names, ['quality'], aggfunc='median')
df_pivot_table
alcoholchloridescitric aciddensityfixed acidityfree sulfur dioxidepHresidual sugarsulphatestotal sulfur dioxidevolatile acidity
quality
310.150.05500.330.9959007.4517.03.2453.150.505102.50.415
410.000.05050.260.9949957.0015.03.2202.200.485102.00.380
59.600.05300.300.9961007.1027.03.1903.000.500127.00.330
610.500.04600.310.9947006.9029.03.2103.100.510117.00.270
711.400.03900.320.9924006.9030.03.2202.800.520114.00.270
812.000.03700.320.9918906.8034.03.2304.100.480118.00.280
912.500.03100.360.9903007.1028.03.2802.200.460119.00.270
  • quaity를 기준으로 pivot 테이블을 만들어봄
  • free sulfur dioxide가 quality 별로 차이가 나 보인다.


2.5 Quality에 대한 나머지 특성들의 상관관계

1
2
corr_matrix = wine.corr()
print(corr_matrix['quality'].sort_values(ascending = False))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
quality                 1.000000
taste                   0.814484
alcohol                 0.444319
citric acid             0.085532
free sulfur dioxide     0.055463
sulphates               0.038485
pH                      0.019506
residual sugar         -0.036980
total sulfur dioxide   -0.041385
fixed acidity          -0.076743
color                  -0.119323
chlorides              -0.200666
volatile acidity       -0.265699
density                -0.305858
Name: quality, dtype: float64
  • quality의 상관관계를 확인해보니, alcohol, free sulfur dioxide가 양의 상과관계를, density가 음의 상관관계를 보인다
  • 당연히 quality 기준으로 taste를 만들었으니, 이 둘은 상관관계가 높을수 밖에 없으니 제외함


2.6 Taste 컬럼의 분포

1
2
3
4
import seaborn as sns

sns.countplot(wine['taste'])
plt.show()

  • Taste 컬럼은 맛있음(1)이 더 많다.


2.7 다양한 모델을 한번에 테스트해보기

1
2
3
4
5
6
7
8
9
10
from sklearn.ensemble import AdaBoostClassifier, GradientBoostingClassifier, RandomForestClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.linear_model import LogisticRegression

models = []
models.append(('RandomForestClassifier',RandomForestClassifier()))
models.append(('DecisionTreeClassifier',DecisionTreeClassifier()))
models.append(('AdaBoostClassifier',AdaBoostClassifier()))
models.append(('GradientBoostingClassifier',GradientBoostingClassifier()))
models.append(('LogisticRegression',LogisticRegression(solver = "liblinear")))
  • 여러가지 모델을 불러와서 model이라는 리스트에 넣어줌, 하이퍼 파라미터는 설정하지 않음


2.8 결과를 확인

1
2
3
4
5
6
7
8
9
10
11
12
13
from sklearn.model_selection import KFold, cross_val_score

results  = []
names = []

for name, model in models :
    kfold = KFold(n_splits= 5, random_state=13, shuffle=True)
    cv_results = cross_val_score(model, X_train, y_train, cv=kfold, scoring='accuracy')
    
    results.append(cv_results)
    names.append(name)
    
    print(name, cv_results.mean(), cv_results.std())
1
2
3
4
5
RandomForestClassifier 0.8185420522691939 0.018560021121147078
DecisionTreeClassifier 0.7498519286295995 0.013712535378522434
AdaBoostClassifier 0.7533103205745169 0.02644765901536818
GradientBoostingClassifier 0.7663959428444511 0.021596556352125432
LogisticRegression 0.7425394240023693 0.015704134753742827
  • Kfold를 적용하여 각 모델별로 검증


2.9 Cross-Validation의 결과를 그래프로 보기

1
2
3
4
5
6
fig = plt.figure(figsize=(14,8))
fig.suptitle('Algorithm Comparison')
ax = fig.add_subplot(111)
plt.boxplot(results)
ax.set_xticklabels(names)
plt.show()

  • 랜덤포레스트가 좋아보임
  • Boxplot으로 보는 이유는 각 데이터의 accuray의 분포와 outlier를 한번에 볼수 있기 때문


2.10 같은 방식으로 test 데이터 대입

1
2
3
4
5
6
from sklearn.metrics import accuracy_score

for name, model in models:
    model.fit(X_train, y_train)
    pred = model.predict(X_test)
    print(name, accuracy_score(y_test, pred))
1
2
3
4
5
RandomForestClassifier 0.8392307692307692
DecisionTreeClassifier 0.7784615384615384
AdaBoostClassifier 0.7553846153846154
GradientBoostingClassifier 0.7876923076923077
LogisticRegression 0.7469230769230769
  • 마찬가지로 랜덤포레스트의 결과가 좋음
This post is licensed under CC BY 4.0 by the author.

Beautiful Soup을 이용한 시카고 샌드위치 맛집 정보 추출

HAR 데이터로 해보는 GBM, XGBoost, LightGBM