[C02 머신러닝 프로젝트 AtoZ]10 모델 선택과 훈련
지금까지 한 작업
- 문제 정의
- 데이터 읽고 탐색
- 훈련 세트와 테스트 세트 나누기
- 데이터를 자동으로 정제하고 준비하는 변환 파이프라인 작성
# 데이터 불러오기
import pandas as pd
import numpy as np
housing_prepared = pd.read_csv("housing_prepared.csv", index_col=0).reset_index(drop=True)
housing_labels = pd.read_csv("housing_labels.csv", index_col=0).reset_index(drop=True)
housing = pd.read_csv("housing.csv", index_col=0).reset_index(drop=True)
print(housing_labels.iloc[:5])
class로 만들어둔 파이프라인 객체 만들기
from functions.full_pipeline import FullPipeline
full_pipeline = FullPipeline()
housing_prepared = full_pipeline.fit_transform(housing)
선형 회귀 모델 시도해보기
# 선형 회귀 모델 훈련
from sklearn.linear_model import LinearRegression
lin_reg = LinearRegression()
lin_reg.fit(housing_prepared, housing_labels)
# 훈련 세트에 있는 몇 개 샘플에 대해 적용
some_data = housing.iloc[:5]
some_labels = housing_labels.iloc[:5]
# some_labels to list
some_labels = some_labels.values.tolist()
some_data_prepared = full_pipeline.transform(some_data)
print("예측:", lin_reg.predict(some_data_prepared))
print("레이블:", some_labels)
선형 회귀 모델 RMSE 측정
from sklearn.metrics import mean_squared_error
housing_predictions = lin_reg.predict(housing_prepared)
lin_mse = mean_squared_error(housing_labels, housing_predictions)
lin_rmse = np.sqrt(lin_mse)
print("선형 회귀 모델의 RMSE:", lin_rmse)
해석
- 대부분 구역의 중간 주택 가격은 120,000 ~ 265,000 사이
- 68000가량의 오차는 예측이 전혀 수행되지 못하고 있다는 뜻
- 모델이 훈련 데이터에 과소적합된 것
- 특성들이 좋은 예측을 만들 만큼 충분한 정보를 제공하지 못했거나
-
모델이 충분히 강력하지 않았다는 것
- 과소적합을 해결하려면
- 더 강력한 모델을 선택하거나
- 훈련 알고리즘에 더 좋은 특성을 주입하거나
- 규제를 감소시키는 것
여기서는 규제를 도입한 적이 없으므로 일단 더 복잡한 모델을 선택하는 것으로 시도해보자
Decision Tree Regressor
- 데이터에서 복잡한 비선형 관계를 찾을 수 있는 모델
from sklearn.tree import DecisionTreeRegressor
tree_reg = DecisionTreeRegressor(random_state=42)
tree_reg.fit(housing_prepared, housing_labels)
housing_predictions = tree_reg.predict(housing_prepared)
tree_mse = mean_squared_error(housing_labels, housing_predictions)
tree_rmse = np.sqrt(tree_mse)
print("결정 트리 모델의 RMSE:", tree_rmse)
결과 해석
- 오차가 전혀 없음
- 모델이 데이터에 너무 심하게 과대적합된 것으로 보임
- 교차 검증을 시도해봐야 함
K-fold 교차 검증
- 예를 들어 10겹 교차 검증은 아래와 같음
- 훈련 세트를 10개의 서브셋으로 무작위 분할
- 결정 트리 모델을 10번 훈련하고 평가함
- 매 번 하나의 다른 폴드를 선택해 평가에 사용
- 나머지 9개 폴드는 훈련에 사용
- 10개의 평가 점수가 담긴 배열이 결과로 나옴
from sklearn.model_selection import cross_val_score
scores = cross_val_score(tree_reg, housing_prepared, housing_labels, cv=10)
rmse_scores = cross_val_score(tree_reg, housing_prepared, housing_labels,
scoring="neg_mean_squared_error", cv=10)
def display_rmse_scores(rmsescores):
rmse_adj = np.sqrt(-rmsescores)
print("rmse_scores:", rmse_adj)
print("rmse 평균:", rmse_adj.mean())
print("rmse 표준편차:", rmse_adj.std())
print('r2_scores: ', scores)
display_rmse_scores(rmse_scores)
해석
- 기본적으로 scoring에 아무 매개변수가 없다면 r2_score를 계산한다
- rmse를 계산하면 값이 음수로 나오기 때문에 양수로 바꾸고 표준편차를 구했다.
- rmse score와 평균, 표준편차를 print하는 것은 뒤에서 더 사용할 예정이므로 함수로 구현했다
- 결과는 선형회귀보다도 나빴다
RandomForest
- 특성을 무작위로 선택해서 많은 결정 트리를 만들고 그 예측을 평균 냄
- 여러 다른 모델을 모아서 하나의 모델을 만드는 것을 앙상블 학습이라고 함
- 머신러닝 알고리즘의 성능을 극대화할 수 있음
print(housing_labels)
from sklearn.ensemble import RandomForestRegressor
forest_reg = RandomForestRegressor(n_estimators=100, random_state=42)
forest_reg.fit(housing_prepared, housing_labels)
forest_scores = cross_val_score(forest_reg, housing_prepared, housing_labels, cv=10)
forest_rmse_scores = cross_val_score(forest_reg, housing_prepared, housing_labels,
scoring="neg_mean_squared_error", cv=10)
print('r2_scores: ', forest_scores)
display_rmse_scores(forest_rmse_scores)
모델 저장
- 실험한 모델을 모두 저장해두면 필요할 때 쉽게 복원 가능
- 하나의 알고리즘을 깊게 파기 전에 여러 종류의 알고리즘으로, 하이퍼파라미터 튜닝에 너무 큰 시간을 들이지 않으면서 다양한 모델을 시도해봐야 함
- 그리고 가능성 있는 2~5개의 모델을 선정하고, 그것들을 깊게 파는 것
import joblib
joblib.dump(forest_reg, "forest_reg.pkl")
joblib.dump(lin_reg, "lin_reg.pkl")
# 모델 불러오기
# forest_reg_loaded = joblib.load("forest_reg.pkl")
# lin_reg_loaded = joblib.load("lin_reg.pkl")
Leave a comment