자기계발/Python

[빅데이터분석기사] 19 랜덤포레스트

호등 2022. 6. 22. 20:14
반응형

랜덤포레스트(Random Forest)

학습 데이터로 여러 의사결정트리를 구성하여 분석하고 이를 종합하는 앙상블(ensemble) 기법이다.

의사결정나무 수십~수백개가 예측한 분류나 회귀값을 평균낸 모델로 이해하면 된다.

랜덤포레스트 과정은

① 데이터에서 부트스트래핑 과정을 통해 N개의 샘플링 데이터 셋 생성

② 각 샘플링된 데이터셋에서 임의의 변수 선택 후, M개의 총 변수들 중에서 sqrt(M) 또는 M/3개

③ 의사결정트리들을 종합하여 앙상블 모델을 만들고 OOB error를 통해 오분류율을 평가

이다.

 

scikt-learn

랜덤포레스트는 사이킷런의 ensemble 안에 있다.

이 중 RandomForestClassifier가 분류 알고리즘,

RandomForestRegressor가 회귀 알고리즘이다.

 

분류와 회귀의 디폴트 옵션은 거의 동일하며 의사결정나무와 마찬가지로 분류의 경우 기준(criterion)은 'gini', 회귀 기준은 'mse'라는 것이 다르다. 

 

다양한 하이퍼파라미터 중 핵심 파라미터는 n_estimators와 max_features이다.

n_estimators : 디폴트값은 100, 의사결정나무 모델을 몇 개 구성할 것인지 정한다.

max_features : 특성치를 얼마나 반영할 것인지 정한다.

 

Part1. 분류(Classification)

1) 데이터셋 분리, 정규화 적용

import warnings
warnings.filterwarnings("ignore")

import pandas as pd

data=pd.read_csv('breast-cancer-wisconsin.csv', encoding='utf-8')
X=data[data.columns[1:10]]
y=data[["Class"]]

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, stratify=y, random_state=42)

#min-max 정규화
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
scaler.fit(X_train)

X_scaled_train = scaler.transform(X_train)
X_scaled_test = scaler.transform(X_test)

유방암 데이터를 불러와 데이터셋을 train , test로 분리해주고,

MinMax 정규화를 시켜주었다.

 

2) 기본모델 적용

#Part1. 분류(Classification) : RandomForestClassifier
from sklearn.ensemble import RandomForestClassifier
model = RandomForestClassifier()
model.fit(X_scaled_train, y_train)

pred_train = model.predict(X_scaled_train)
model.score(X_scaled_train, y_train)

sklearn.ensemble로부터 RandomForestClassifier 라이브러리를 불러왔다.

model에 RandomForestClassifier()을 넣어 사용하기 편하게 만들었다.

 

model의 정확도를 측정했더니 100%의 정확도를 보였다.

 

3) 오차행렬과 분류예측 레포트

from sklearn.metrics import confusion_matrix
confusion_train = confusion_matrix(y_train, pred_train)
print("훈련데이터 오차행렬:\n", confusion_train)

from sklearn.metrics import classification_report
cfreport_train = classification_report(y_train, pred_train)
print("분류예측 레포트:\n", cfreport_train)

훈련데이터의 모델성능에 대한 다양한 지표를 보았더니 전부 100% 결과를 보이고 있다.

반면 테스트 데이터도 위와 같은 방식으로 확인해보았더니 예측 결과는 96~97%정도의 정확도를 보였다.

 

4) Grid Search

#Grid Search
param_grid = {'n_estimators':range(100,1000,100),
             'max_features':['auto', 'sqrt', 'log2']}
from sklearn.model_selection import GridSearchCV
grid_search = GridSearchCV(RandomForestClassifier(), param_grid, cv=5)
grid_search.fit(X_scaled_train, y_train)

print("Best Parameter:{}".format(grid_search.best_params_))
print("Best Score:{:.4f}".format(grid_search.best_score_))
print("TestSet Score:{:.4f}".format(grid_search.score(X_scaled_test, y_test)))

하이퍼파라미터 중 n_estimators와 max_features를 세팅해주었다.

max_features 중 'auto'와 'sqrt'는 동일한 방법이다. (동일한 방법인데 왜 굳이 저렇게 세팅하는진 모르겠다.)

 

최적의 하이퍼파라미터는 n_estimators = 100, max_features = log2로 나왔다. (교재와 다른 결과 나옴)

 

5) Random Search

#Random Search
from scipy.stats import randint
param_distribs = {'n_estimators': randint(low=100, high=1000),
                  'max_features': ['auto', 'sqrt', 'log2']}
from sklearn.model_selection import RandomizedSearchCV
random_search = RandomizedSearchCV(RandomForestClassifier(), param_distributions=param_distribs, cv=5, n_iter=20)
random_search.fit(X_scaled_train, y_train)

print("Best Parameter:{}".format(random_search.best_params_))
print("Best Score:{:.4f}".format(random_search.best_score_))
print("TestSet Score:{:.4f}".format(random_search.score(X_scaled_test, y_test)))

랜덤탐색에서는 n_estimators는 100~1000, max_features는 세 가지 방법에서 무작위로 20개의 모델을 분석했다.

최적의 하이퍼파라미터는 n_estimators = 841, max_features = sqrt 일때 최적의 결과를 보였다.


Part2. 회귀(Regression) : RandomForestRegressor

기본 디폴트 모델에선 굉장히 과대적합되는 경향을 보였다. 하지만 적절한 모델수와 특성치를 탐색한 결과는 꽤 괜찮은 결과를 나타냈다. 개별 알고리즘보다 더 좋은 성능을 보이며 다른 앙상블 기법에 비해 심플하고 강력하다.

그렇기 때문에 실전에서 가장 많이 사용되는 것은 랜덤 포레스트이다.

 

1) 데이터셋 분리와 정규화

import pandas as pd 

data2 = pd.read_csv('house_price.csv', encoding='utf=8')
X=data2[data2.columns[1:5]]
y=data2[["house_value"]]

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state = 42)

from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
scaler.fit(X_train)

X_scaled_train = scaler.transform(X_train)
X_scaled_test = scaler.transform(X_test)

데이터셋은 주택가격꺼 코드 그대로 가져왔다.

 

2) 기본모델 적용

#Part2. 회귀(Regression) : RandomForestRegressor
from sklearn.ensemble import RandomForestRegressor
model = RandomForestRegressor()
model.fit(X_scaled_train, y_train)

pred_train = model.predict(X_scaled_train)
model.score(X_scaled_train, y_train)

pred_test = model.predict(X_scaled_test)
model.score(X_scaled_test, y_test)

랜덤포레스트 회귀자는 sklearn.ensemble에서 RandomForestRegressor 라이브러리를 가져왔다.

model을 RandomForestRegressor()로 하고 분석한 결과 93% 정확도를 보였고,

테스트데이터에서의 정확도는 58%정도로 나타났다. 

 

훈련데이터, 테스트데이터의 격차가 큰 이유는 역시 과대적합때문이다.

 

3) RMSE 오차 계산

#RMSE(Root Mean Squared Error)
import numpy as np
from sklearn.metrics import mean_squared_error
MSE_train = mean_squared_error(y_train, pred_train)
MSE_test = mean_squared_error(y_test, pred_test)
print("훈련데이터 RMSE:", np.sqrt(MSE_train))
print("테스트데이터 RMSE:", np.sqrt(MSE_test))

오차는 훈련데이터 RMSE가 테스트데이터보다 현저히 낮게 확인된다.

 

4) Grid Search

#Grid Search
param_grid = {'n_estimators': range(100,500,100),
             'max_features': ['auto', 'sqrt', 'log2']}
from sklearn.model_selection import GridSearchCV
grid_search = GridSearchCV(RandomForestRegressor(), param_grid, cv=5)
grid_search.fit(X_scaled_train, y_train)

print("Best Parameter:{}".format(grid_search.best_params_))
print("Best Score:{:.4f}".format(grid_search.best_score_))
print("TestSet Score:{:.4f}".format(grid_search.score(X_scaled_test, y_test)))

회귀에서도 n_estimators와 max_features를 그리드탐색 기준과 동일하게 설정했다.

최적의 하이퍼파라미터는 'max_features=sqrt, n_estimators = 400' 으로 나타났다.

 

5) Random Search

#Random Search
param_ditribs = {'n_estimators': randint(low=100, high=500),
             'max_features': ['auto', 'sqrt', 'log2']}
from sklearn.model_selection import RandomizedSearchCV
random_search = RandomizedSearchCV(RandomForestRegressor(), param_distributions=param_ditribs, cv=5, n_iter=20)
random_search.fit(X_scaled_train, y_train)

print("Best Parameter:{}".format(random_search.best_params_))
print("Best Score:{:.4f}".format(random_search.best_score_))
print("TestSet Score:{:.4f}".format(random_search.score(X_scaled_test, y_test)))

랜덤탐색에서도 분류와 마찬가지로 하이퍼파라미터를 설정했다.

다만 n_estimators는 100~500에서 무작위 추출하였다. (분류 분석에선 100~1000으로 했었음)

 

최적의 하이퍼파라미터는 'max_features=log2 , n_estimators=328 ' 으로 나타났다.

반응형