🏡 California Housing 집값 예측
# 라이브러리 불러오기
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# California 데이터 불러오기
from sklearn.datasets import fetch_california_housing
X = fetch_california_housing(as_frame = True)['data']
y = fetch_california_housing(as_frame = True)['target']
# as_frame = True : 데이터프레임 형식으로 바꾸어주는 코드(디폴트값 : False)
data = pd.concat([X, y], axis = 1)
display(data)
1) 결측치 확인
2) feature selection
data.info()
1) feature distribute
2) target distribute
- 데이터셋의 각 컬럼의 분포를 이해하고 시각화 하는 과정입니다.
- 데이터의 특성이 어떻게 분포되어있는지 통계적으로 파악할 수 있습니다.
sns.histplot(data = data, x = "AveRooms")
plt.figure(figsize = (8, 6))
sns.boxplot(data = data.loc[:, ["MedInc", "HouseAge", "AveRooms", "AveBedrms",
"AveOccup", "Latitude", "Longitude", "MedHouseVal"]])
sns.boxplot(data = data.loc[:, ["AveRooms", "AveBedrms", "AveOccup"]])
plt.figure(figsize = (10, 6))
sns.heatmap(data.corr(),annot=True)
🔎 코드 정리
sns.histplot(data = data name, x or y ='column_name') -> 해당 컬럼에 대한 히스토그램(빈도분포) -> 데이터의 범위, 중심 경향, 이상치, 빈도 등을 파악 -------------------------------------------------------------------- sns.boxplot([column name]) -> 데이터의 분포와 이상치를 시각화하는 데 사용 -> 매개변수(선택) * boxplot은 생소해서 나중에 따로 다뤄봐야겠다. ``
data.loc[data.AveRooms > 100, :] #1914, 1979 row 제거
data.loc[data.AveOccup>200, :] # 3364, 13034, 16669, 19006 row 제거
# AveBedrms, Longitude column 제거 -> 다중공선성 제거
data = data.drop(index = [1914, 1979, 3364, 13034, 16669, 19006]) ##remove outlier
data = data.drop(columns = ['AveBedrms', 'Longitude']) ## remove collinearity(다중공선성)
sns.histplot(data=data, x = "MedHouseVal")
data.MedHouseVal.value_counts()
1) train-test split
2) Standardization
3) Model training
4) Hyper-parameter tuning
# 학습을 위한 training / test dataset 나누기
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2, random_state=0xC0FFEE)
X_train, X_val, y_train, y_val = train_test_split(X_train, y_train, test_size = 0.25, random_state=0xC0FFEE)
# 6:2:2 = train : validation : test
feature scaling
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_val = scaler.transform(X_val)
X_test = scaler.transform(X_test)
📃학습을 위한 라이브러리 세팅
# 1. Linear Regression from sklearn.linear_model import LinearRegression # 2. Lasso from sklearn.linear_model import Lasso # 3. Ridge from sklearn.linear_model import Ridge # 4. XGBoost from xgboost.sklearn import XGBRegressor # 5. LightGBM from lightgbm.sklearn import LGBMRegressor # 5. LightGBM from sklearn.metrics import mean_squared_error
- 총 5가지의 회귀모델을 사용합니다.
- 평가지표는 MSE를 사용합니다.
## training
reg = LinearRegression()
reg2 = Lasso()
reg3 = Ridge()
reg4 = XGBRegressor()
reg5 = LGBMRegressor()
reg.fit(X_train, y_train)
reg2.fit(X_train, y_train)
reg3.fit(X_train, y_train)
reg4.fit(X_train, y_train)
reg5.fit(X_train, y_train)
pred_train = reg.predict(X_train)
pred_train2 = reg2.predict(X_train)
pred_train3 = reg3.predict(X_train)
pred_train4 = reg4.predict(X_train)
pred_train5 = reg5.predict(X_train)
pred_val = reg.predict(X_val)
pred_val2 = reg2.predict(X_val)
pred_val3 = reg3.predict(X_val)
pred_val4 = reg4.predict(X_val)
pred_val5 = reg5.predict(X_val)
mse_train = mean_squared_error(y_train, pred_train)
mse_val = mean_squared_error(y_val, pred_val)
mse_train2 = mean_squared_error(y_train, pred_train2)
mse_val2 = mean_squared_error(y_val, pred_val2)
mse_train3 = mean_squared_error(y_train, pred_train3)
mse_val3 = mean_squared_error(y_val, pred_val3)
mse_train4 = mean_squared_error(y_train, pred_train4)
mse_val4 = mean_squared_error(y_val, pred_val4)
mse_train5 = mean_squared_error(y_train, pred_train5)
mse_val5 = mean_squared_error(y_val, pred_val5)
print("l. Linear Regression,\t train/val = %.4f, %.4f" % (mse_train, mse_val))
print("2. Lasso,\t\t train/val = %.4f, %.4f" % (mse_train2, mse_val2))
print("3. Ridge,\t\t train/val = %.4f, %.4f" % (mse_train3, mse_val3))
print("4. XGBoost,\t\t train/val = %.4f, %.4f" % (mse_train4, mse_val4))
print("5. LightGBM,\t\t train/val = %.4f, %.4f" % (mse_train5, mse_val5))
결과
l. Linear Regression, train/val = 0.5336, 0.5241 2. Lasso, train/val = 1.3490, 1.2857 3. Ridge, train/val = 0.5336, 0.5241 4. XGBoost, train/val = 0.0603, 0.2247 5. LightGBM, train/val = 0.1474, 0.2167
🔎 MSE(평균제곱 오차) : 실제 정답값과 예측값의 차이를 제곱한 뒤 평가하는 지표. 점수가 낮을수록 좋습니다.
- 정답값은 target value(y)이며, 예측값은 pred_train, pred_val입니다.
- validation data 중 LightGBM 모델이 가장 성능이 좋게 나왔습니다.
💡 튜닝 방법 몇 가지...
- Human Search
- Grid Search(Grid SearchCV) : 주어진 하이퍼파라미터의 조합을 모두 돌려보는 방식.
- Byesian Optimizataion(hyperopt, optuna, ...) : hyper-parameter를 최적화하는 베이지안 방식을 사용.
# GridSearchCV
from sklearn.model_selection import GridSearchCV
param_grid = {
"max_depth" : [3, 5, -1], # 3개
"learning_rate" : [0.1, 0.01], # 2개
"n_estimators" : [50, 100] # 2개
} # -> 3x3x2 = 12번을 수행
gcv = GridSearchCV(reg5, param_grid, scoring = 'neg_mean_squared_error', verbose=1)
gcv.fit(X_train, y_train)
# prediction!
result5 = reg5.predict(X_test)
print("---------- LightGBM ---------")
print('MSE in training: %.4f' % mean_squared_error(y_test, result5))
-----------------------------------------------------------------
---------- LightGBM ---------
MSE in training: 0.2151
💡 시사점
- 여러 회귀모델 중 가장 많이 쓰이고 성능이 좋은 편에 속하는 LightGBM이 역시 성능이 좋게 나왔다.
- 미니 프로젝트를 하다보니 EDA과정과 전처리 과정이 정말 중요하다는 것을 깨달았다.
- 코드만 잘 짠다고 해서 될 것이 아니라 데이터를 잘 다루고, 의미있는 해석을 잘해야되는 것 같다.
- 사실 아직 많이 모르겠다. 이제 어느정도 프로세스 느낌만 알 거 같은 상태이다. 계속해서 미니 프로젝트와 공부를 하며 실력을 키워야겠다.