이번에는 데이터 크기 즉, 샘플 개수와 특징 개수에 따른 적절한 모델을 알아볼려고 한다.

 

샘플 개수와 특징 개수에 따른 적절한 모델

샘플 개수를 기본적으로 10,000개로 보고 샘플 개수가 10,000개 미만이면 샘플이 적다고 볼것이고 샘플 개수가 10,000개 이상이면 샘플이 많다고 볼것이다.

특징 개수는 샘플 개수를 30으로 나누었을 때 그 값보다 많으면 특징이 많다고 볼 것이고 그렇지 않으면 적다고 볼것이다.

(단, 10000개는 임의로 설정한 값이지 무조건적이지 않다->특징 개수와 샘플 개수를 같이 고려해야한다)

위의 그림은 일반적으로 경향이 이렇다고 말하며 항상 그렇지 않다는 것에 주의한다. 다시 말해 매우 단순한 모델 및 파라미터에서 라쏘/릿지, 나이브베이즈가 아닌 SVM이 좋을 수도 있기 때문에 참고만 한다.

->특징 개수와 샘플 개수에 따라서 모델의 복잡도를 어느정도로 설정할 것인지 감을 가지고 가는 것이 이번 시간의 핵심이다.

 

# 코드 실습 #

이 문제는 예측 문제이다.

import os
os.chdir(r"C:\Users\82102\Desktop\데이터 전처리\지도학습 주요모델 및 개념\데이터")

import numpy as np
import pandas as pd
  • 특징 개수가 매우 적은 경우
## 데이터 크기에 따른 모델 선택: 특징 개수가 매우 적은 경우
df = pd.read_csv("Combined_Cycle_Power_Plant.csv")
df.shape
# 샘플: 9568개 / 특징: 5개 -> 샘플은 적당히 많은편, 특징은 샘플 대비 매우 적음
X = df.drop('EP', axis=1)
Y = df['EP']

SVR이나 신경망 같은 경우는 파라미터에 영향을 많이 받는 모델이기 때문에 공정한 비교를 위해 전부 default 값을 사용하기로 결정했다. 우연성에 영향을 받는 모델인 신경망, 의사결정나무, 랜덤포레스트의 random_state는 다 같은 값으로 고정시킬 것이다. 그리고 각 모델을 학습시키고 평가하는 것을 for문을 돌게 하기 위해서 model_list를 정의하고 각 모델의 결과를 손쉽게 확인하기 위해서  model_name_list를 만든다.

from sklearn.svm import SVR
from sklearn.neural_network import MLPRegressor as MLP
from sklearn.linear_model import LinearRegression as LR
from sklearn.tree import DecisionTreeRegressor as DTR
from sklearn.ensemble import RandomForestRegressor as RFR
from sklearn.neighbors import KNeighborsRegressor as KNR

SVR_model = SVR()
MLP_model = MLP(random_state=1004)
LR_model = LR()
DTR_model = DTR(random_state=1004)
RFR_model = RFR(random_state=1004)
KNR_model = KNR()

model_list = [SVR_model, MLP_model, LR_model, DTR_model, RFR_model, KNR_model]
model_name_list = ['SVR', 'MLP', 'LR', 'DTR', 'RFR', 'KNR']

train data와 test data를 따로 나누지 않은 이유는 k겹 교차검증을 하기 위함이다.(좀 더 공정한 비교를 하기 위해 학습 데이터와 평가 데이터로 나눠져서 성능 차이가 나는 것을 방지할려고 k겹 교차검증 사용) -> 특별한 전처리가 필요없는 경우 쓸 수 있는 cross_val_score 함수를 사용한다.

cross_val_score는 학습되지 않은 모델을 입력으로 받고, X와 Y를 통으로 입력으로 받고, cv(폴드의 개수)를 입력으로 받고, scoring값을 입력으로 받는다. scoring에서 'neg_mean_absolute_error'를 입력한 이유는 사이킷런에서 평가를 할 때 score는 크면 클수록 좋게 설계가 되어있다. 그런데 MAE(예측 평가지표)는 작으면 작을수록 좋은 score이기 때문에 그런 충돌을 방지하기 위해서 앞에 'negative' 즉, -를 붙혀 놓은것 뿐이지 특별한 의미가 있지는 않다.

그리고 각 평가에 대한 점수를 평균을 내고 그 점수가 -가 붙어 있기 때문에 앞에 -를 붙혀서 각 모델의 score를 낸다. 

 

참고링크:https://www.inflearn.com/questions/35479/scoring%EC%97%90-%EB%8C%80%ED%95%9C-%EC%A7%88%EB%AC%B8

 

# 모델별 k 겹 교차검증 기반(k=5)의 MAE값 계산
from sklearn.model_selection import cross_val_score
for (model, model_name) in zip(model_list, model_name_list):
    score = -cross_val_score(model, X, Y, cv=5, scoring='neg_mean_absolute_error').mean()
    print(model_name, score)

->인사이트: 특징이 적으면 복잡한 모델을 쓰는게 특별한 의미가 없다. 하지만 SVR과 MLP에 대한 파라미터 튜닝을 잘 한다면 좋은 성능을 얻었을 가능성이 크다. 

 

 

  • 샘플이 매우 적고, 특징이 상대적으로 많은 경우
import os
os.chdir(r"C:\Users\82102\Desktop\데이터 전처리\지도학습 주요모델 및 개념\데이터")

import numpy as np
import pandas as pd
## 샘플이 매우 적고, 특징이 상대적으로 많은 경우
df = pd.read_csv("baseball.csv")
df.shape
# 샘플: 337개 / 특징: 17개
X = df.drop('Salary', axis=1)
Y = df['Salary']
from sklearn.svm import SVR
from sklearn.neural_network import MLPRegressor as MLP
from sklearn.linear_model import LinearRegression as LR
from sklearn.tree import DecisionTreeRegressor as DTR
from sklearn.ensemble import RandomForestRegressor as RFR
from sklearn.neighbors import KNeighborsRegressor as KNR

SVR_model = SVR()
MLP_model = MLP(random_state=1004)
LR_model = LR()
DTR_model = DTR(random_state=1004)
RFR_model = RFR(random_state=1004)
KNR_model = KNR()

model_list = [SVR_model, MLP_model, LR_model, DTR_model, RFR_model, KNR_model]
model_name_list = ['SVR', 'MLP', 'LR', 'DTR', 'RFR', 'KNR']

SVR과 MLP 같은 경우 기본적으로 많은 데이터, 특징이 필요하기 때문에 성능이 안좋은 것을 확인했고,

MLP의 경우 convergence warning이 떴는데 이는 학습 데이터가 부족하다 보니 제대로 수렴하지 못하고 끝난 상황이라고 볼 수 있다.(특징이 많다 보니까 거기에 추정할 가중치가 많고 가지고 있는 데이터로는 수렴하지 못하고 끝난 상황)

# 모델별 k겹 교차검증 기반(k=5)의 MAE값 계산
# SVR의 성능이 최악
# MLP에서 max_iter 이슈 발생
from sklearn.model_selection import cross_val_score
for (model, model_name) in zip(model_list, model_name_list):
    score = -cross_val_score(model, X, Y, cv=5, scoring='neg_mean_absolute_error').mean()
    print(model_name, score)

 

+ Recent posts