본문 바로가기
머신러닝

[머신러닝][파이썬] Random Forest Regressor(회귀)

by 방구석 데이터사이언티스트 2022. 1. 26.
728x90
반응형

안녕하세요. 오늘은 파이썬을 통해 RandomForestRegressor를 구현해 보도록하겠습니다.

데이터는 야구 데이터이며, 종속변수는 팀의 득점입니다. 

 

사실 득점을 예측하는 것은 안타수나 타점이나 기타 등등 다른 변수와 상관관계가 높아 쉽게 예측할 수 있을 것이라고 생각하실 수도 있습니다. 하지만 여기서 팀의 득점은 앞으로의 미래, 즉 아직 경기정보가 없는 팀의 득점을 예측하는 것입니다. 따라서 그날의 경기정보로 그날의 결과를 학습하는 것이 아니라 이전의 경기정보로 그 후의 결과를 매칭해서 학습하는 것입니다. 이렇게 하면 전날 경기정보로 다음날 혹은 그 후 미래의 예측값을 뽑아낼 수 있습니다. 

 

1. 모듈 불러오기

1
2
3
4
5
6
7
8
from sklearn.ensemble import RandomForestRegressor
from sklearn.model_selection import cross_val_score
import pandas as pd
import numpy as np
from sklearn.model_selection import GridSearchCV
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
import math
cs

가장 먼저 해야할 일은 필요한 모듈을 불러오는 것입니다.

1번째 줄 : RandomForestRegressor

2번째 줄 : 교차검증 라이브러리

3번째 줄 : pandas

4번째 줄 : numpy

5번째 줄 : GridSearchCV

6번째 줄 : 데이터 분리 라이브러리

7번째 줄 : 모델 성능 지표(mse) -> 추후 루트를 씌어 rmse로 성능 평가를 할 예정

8번째 줄 : 파이썬에서 수식 연산을 하기 위한 라이브러리 -> mse에 루트를 씌우기 위함

 

sklearn에서는 회귀성능지표 중 하나인, rmse를 제공하고 있지 않습니다. 하지만 rmse는 mse에 루트를 씌어 계산할 수 있습니다. 여기서 제가 mse가 아닌 rmse를 적용하는 이유는 mse는 오차를 제곱한 값이기 때문에 직관적으로 성능을 평가하기는 조금 어렵습니다. 따라서 조금 더 직과적으로 볼 수 있는 rmse를 사용할 예정입니다. 

 

2. 데이터 분리 및 필요없는 변수 삭제

1
2
3
4
5
6
7
8
9
RUN_ONE =pd.read_csv('RUN_END.csv' , encoding = 'ms949' , index_col=0)
RUN_ONE1 = RUN_ONE.iloc[0:4642, :]
RUN_END = RUN_ONE.iloc[4642:4900, :] # 실제 예측해야하는 데이터
RUN_1 = RUN_ONE1.iloc[0:2680, :]
RUN_2 = RUN_ONE1.iloc[2680:2940, :]# test셋
RUN_3 = RUN_ONE1.iloc[2940:4642, :]
df = [RUN_1, RUN_3]
RUN_ONE= pd.concat(df)
RUN_ONE_1 = RUN_ONE.drop(['HIT_TARGET','G_ID','T_ID','VS_T_ID''TB_SC''AB_TARGET','GDAY_DS'], axis =1)
cs

그 다음 데이터를 불러오고 데이터를 필요에 맞게 분리했습니다.  RUN_END의 경우 실제 예측해야하는 데이터셋입니다.

그리고 RUN_2를 test 셋으로 분리해놨습니다. RUN_2는 2018년도 시즌 후반의 데이터입니다. 

실제 예측해야하는 데이터 : 2020년 9월 28일 이후 -> 코로나로 인해 개막이 늦어져 시즌일정이 뒤로 미뤄짐

test 셋 ; 2018년 시즌 후반의 데이터 -> 아시안 게임 일정으로 인해 시즌 일정이 뒤로 미뤄짐

따라서 실제 예측해야하는 데이터와 가장 유사한 2018년 시즌 후반의 데이터를 test 데이터로 선정

 

마지막 줄은 필요없는 변수들을 제거하는 코드입니다. drop문을 사용하여 경기아이디, 팀아이디, 상대팀 아이디 등을 포함해 7개의 변수를 제거했습니다.

 

3. 랜덤포레스트 파라미터 최적화(GridSearchCV)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#GRIDSEARCH를 이용한 최적화
X_11 = RUN_ONE_1.iloc[:, :-1]
y_11 = RUN_ONE_1.iloc[:, -1]
X_train11, X_valid11, y_valid11, y_valid11=train_test_split(X_11, y_11,
                                                  test_size=0.2, random_state=0)
 
 
params = {
    'n_estimators':(100200),
    'max_depth' : (58),
    'min_samples_leaf' : (818),
    'min_samples_split' : (816)
}
rf_run = RandomForestRegressor(random_state=0, n_jobs=-1)
grid_cv = GridSearchCV(rf_run, param_grid=params, cv=2, n_jobs=-1)
grid_cv.fit(X_train11, y_train11)
 
 
print('최적 하이퍼 파라미터:', grid_cv.best_params_)
print('최적 예측 정확도: {0:.4f}'.format(grid_cv.best_score_))
cs

데이터를 train과 validation 데이터로 나눴습니다. 

그 후 GridSearchCV를 통해 파라미터를 조절했습니다.

 

4. 모델 학습

1
2
3
# 랜덤포레스트 득점모델 학습
rf_run = RandomForestRegressor(random_state=0, max_depth=5, min_samples_leaf=8, min_samples_split=8,n_estimators=200)
rf_run.fit(X_train11, y_train11)
cs

GridSearchCV를 통해 파라미터를 찾았다면 이를 적용해 랜덤포레스트 모델을 만든후 학습데이터를 넣어서 모델을 학습시킵니다. 

 

5. 모델 성능 측정

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# train rmse
train_predict = rf_run.predict(X_train11)
print("RMSE':{}".format(math.sqrt(mean_squared_error(train_predict, y_train11))) )
 
# validation rmse
valid_predict = rf_run.predict(X_valid11)
print("RMSE':{}".format(math.sqrt(mean_squared_error(valid_predict, y_valid11))) )
 
# test rmse
RUN_T= RUN_2.drop(['HIT_TARGET','G_ID','T_ID','VS_T_ID''TB_SC''AB_TARGET','GDAY_DS'], axis =1)
a11 = RUN_T.iloc[:, :-1]
b11 = RUN_T.iloc[:, -1]
rf_run_predict = rf_run.predict(a11)
print("RMSE':{}".format(math.sqrt(mean_squared_error(rf_run_predict, b11))) )
cs
1번-3번 : Train rmse
5번-7번 : Validation rmse
9번-14번 : Test rmse
보통은 Train 성능은 크게 신경쓰지 않지만 validation 성능과 차이를 보며 과적합을 판단하기 위해 사용되기도 합니다. 그리고 통상적으로 validation을 사용안하고 train/test만 사용하는 경우가 많지만
정석은 train: 학습, validation : 검정 , test : 평가 순으로 진행합니다.   

 

6. 변수중요도 시각화

1
2
3
4
5
6
7
8
9
10
11
import matplotlib.pyplot as plt # 득점모델 변수 중요도
import seaborn as sns
%matplotlib inline
 
ftr_importances_values = rf_run.feature_importances_
ftr_importances = pd.Series(ftr_importances_values, index=X_train11.columns)
ftr_top = ftr_importances.sort_values(ascending=False)[:20]
 
plt.figure(figsize=(86))
sns.barplot(x=ftr_top, y=ftr_top.index)
plt.show()
cs

 

마지막은 변수중요도 시각화 코드입니다. 

 

보통 데이터를 탐색하기 전에 feature_engineering을 하지 않은 데이터를 랜덤포레스트에 적용해 변수중요도를 먼저 본 다음 그 변수에 대해 탐색하고 활용하는 분석사례도 많습니다. 

728x90
반응형

댓글