데이터 한 그릇

캐글)House prices : Advanced Regression Techniques 본문

머신러닝/캐글 예제 연습

캐글)House prices : Advanced Regression Techniques

장사이언스 2021. 5. 5. 17:31

 

캐글에 있는 고급회귀 기법으르 사용한 집값 예측 데이터를 분석해 봤다. train 데이터 만으로 분석을 해봤다.

 

House prices ,Advanced Regression Techniques.ipynb
1.08MB

 


데이터 셋 변수 설명 

 

 

#  Features description

SalePrice - the property's sale price in dollars. This is the target variable that you're trying to predict.
MSSubClass: The building class
MSZoning: The general zoning classification
LotFrontage: Linear feet of street connected to property
LotArea: Lot size in square feet
Street: Type of road access
Alley: Type of alley access
LotShape: General shape of property
LandContour: Flatness of the property
Utilities: Type of utilities available
LotConfig: Lot configuration
LandSlope: Slope of property
Neighborhood: Physical locations within Ames city limits
Condition1: Proximity to main road or railroad

Condition2: Proximity to main road or railroad (if a second is present)
BldgType: Type of dwelling
HouseStyle: Style of dwelling
OverallQual: Overall material and finish quality
OverallCond: Overall condition rating
YearBuilt: Original construction date
YearRemodAdd: Remodel date
RoofStyle: Type of roof
RoofMatl: Roof material
Exterior1st: Exterior covering on house
Exterior2nd: Exterior covering on house (if more than one material)
MasVnrType: Masonry veneer type
MasVnrArea: Masonry veneer area in square feet
ExterQual: Exterior material quality
ExterCond: Present condition of the material on the exterior
Foundation: Type of foundation
BsmtQual: Height of the basement
BsmtCond: General condition of the basement
BsmtExposure: Walkout or garden level basement walls
BsmtFinType1: Quality of basement finished area
BsmtFinSF1: Type 1 finished square feet
BsmtFinType2: Quality of second finished area (if present)
BsmtFinSF2: Type 2 finished square feet
BsmtUnfSF: Unfinished square feet of basement area
TotalBsmtSF: Total square feet of basement area
Heating: Type of heating
HeatingQC: Heating quality and condition
CentralAir: Central air conditioning
Electrical: Electrical system
1stFlrSF: First Floor square feet
2ndFlrSF: Second floor square feet
LowQualFinSF: Low quality finished square feet (all floors)
GrLivArea: Above grade (ground) living area square feet
BsmtFullBath: Basement full bathrooms
BsmtHalfBath: Basement half bathrooms
FullBath: Full bathrooms above grade
HalfBath: Half baths above grade
Bedroom: Number of bedrooms above basement level
Kitchen: Number of kitchens
KitchenQual: Kitchen quality
TotRmsAbvGrd: Total rooms above grade (does not include bathrooms)
Functional: Home functionality rating
Fireplaces: Number of fireplaces
FireplaceQu: Fireplace quality
GarageType: Garage location
GarageYrBlt: Year garage was built
GarageFinish: Interior finish of the garage
GarageCars: Size of garage in car capacity
GarageArea: Size of garage in square feet
GarageQual: Garage quality
GarageCond: Garage condition
PavedDrive: Paved driveway
WoodDeckSF: Wood deck area in square feet
OpenPorchSF: Open porch area in square feet
EnclosedPorch: Enclosed porch area in square feet
3SsnPorch: Three season porch area in square feet
ScreenPorch: Screen porch area in square feet
PoolArea: Pool area in square feet
PoolQC: Pool quality
Fence: Fence quality
MiscFeature: Miscellaneous feature not covered in other categories
MiscVal: $Value of miscellaneous feature
MoSold: Month Sold
YrSold: Year Sold
SaleType: Type of sale
SaleCondition: Condition of sale

 


데이터 불러오기  

 

import warnings
warnings.filterwarnings('ignore')
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
%matplotlib inline

house_df_org = pd.read_csv('C:\ca_da\DataHandling\House_prices\house_price.csv')
house_df = house_df_org.copy()
house_df.head(3)

 

  필요한 패키지와 모듈들을 임포트하고 캐글에 있는 데이터를 주피터 노트북에 불러온다.

 


데이터 셋 구조 확인과 결측치 값 확인

 

house_df.shape

print('이 데이터 셋은 {} 개의 행과 {}개의 열을 가지고 있습니다.'.format(house_df.shape[0],house_df.shape[1]))
print('\n각 데이터 타입 개수\n',house_df.dtypes.value_counts())
isnull_series = house_df.isnull().sum()
print('\nnull 칼럼과 그 개수\n',isnull_series[isnull_series>0].sort_values(ascending = False))

 

  데이터 셋의 구조를 shape함수를 통해서 살펴본 결과 1460개의 행과 81개의 열을 가지고 있으며 데이터 타입의 유형을 살펴보니 float, int, object의 세 개의 자료형을 가지고 있었다. 각각의 데이터 유형별 개수를 value_counts() 통해서 살펴보니 다음과 같은 개수를 가지고 있다. (object 43 int64 35 float64 3 dtype: int64) 그리고 각 각 변수별 null 값의 개수를 알고 싶어서 house_df.isnull().sum()을 통해서 Series 구조로 각 변수별 null 값의 개수를 반환하였다. 여기서 null 값 있는 변수 정보만을 추출하고 싶었기 때문에 시리즈 value값에서 0이 상의 값만 반환하고 내림차순을 하였다. 결과는 다음과 같다.

 

null 칼럼과 그 개수

PoolQC 1453

MiscFeature 1406

Alley 1369

Fence 1179

FireplaceQu 690

LotFrontage 259

GarageYrBlt 81

GarageType 81

GarageFinish 81

GarageQual 81

GarageCond 81

BsmtFinType2 38

BsmtExposure 38

BsmtFinType1 37

BsmtCond 37

BsmtQual 37

MasVnrArea 8

MasVnrType 8

Electrical 1 dtype: int64


타겟 데이터 분포 확인

 

  회귀 분석을 하기 앞서서 우리가 구하려고 하는 타겟 데이터가 정규분포 형태를 가지고 있는지 아니면 비대칭 분포를 가지고 있는지 파악했다. 우리가 구하려고 하는 것은 집 값(SalePrice)

 

plt.title('Original target data dstribution')
sns.distplot(house_df['SalePrice'])

#정규분포가 아님

 

house_df target data distribution

 

  타겟 데이터는 가우스 분포, 정규분포 모양의 대칭 분포가 아니라 비대칭 분포임을 알 수 있다.

 

plt.title('transformed taget data distribution')
log_SalePrice = np.log1p(house_df['SalePrice'])
sns.distplot(log_SalePrice)

#타겟 데이터 정규분포화 하기
original_SalePrice = house_df['SalePrice']
house_df['SalePrice'] = np.log1p(house_df['SalePrice'])

 

 transformed house_df target data distribution

  위에서 타겟 데이터가 비대칭 분포를 가지고 있는 것을 확인했기 때문에 높은 성능의 회귀 모형을 만들기 위해서 정규분포화 해야만 한다. 그 방식으로 데이터에 로그를 취해서 정규분포화 하였다. 파이썬의 넘파이 log1p를 이용하여 기존 SalePrice에 로그를 취한다. 그리고 그 값을 house_df['SalePrice'] 값으로 대체한다.

 


각 변수별 null 값 처리

 

#null 값이 너무 많은 피처 삭제, null 값을 평균으로 대체
house_df.drop(['Id','PoolQC','MiscFeature','Alley','Fence','FireplaceQu'], axis = 1 , inplace = True)
house_df.fillna(house_df.mean(), inplace = True)

 

  id는 단순 등록된 데이터 순서이기 때문에 변수를 제거한다. 그리고 위에서 house_df.isnull().sum()[house_df.isnull().sum()>0].sort_values(ascending = False) 로 확인해본 결과 밑의 변수들은 null 값이 너무 많아 제거하기로 결정.

 

PoolQC 1453

MiscFeature 1406

Alley 1369

Fence 1179

FireplaceQu 690

 

  그리고 나머지 null 값들은 각 변수의 평균 값으로 대체한다.  (fillna 함수를 이용, house_df.fillna(house_df.mean(), inplace = True) 이용)

 

a = house_df.isnull().sum()
a
b = a[a>0]
house_df[b.index]
house_df.dtypes[b.index]

 

  하지만 이는 int 형과 float형들의 null 값이 대체된 것이지 object 자료형의 null 값은 제거된 것이 아니다. 따라서 어떤 object형 변수들이 null 값이 제거가 되지 않았는지 확인한다. 다음과 같은 object형 변수들이 null 값이 계산되지 않았다.

 

MasVnrType object

BsmtQual object

BsmtCond object

BsmtExposure object

BsmtFinType1 object

BsmtFinType2 object

Electrical object

GarageType object

GarageFinish object

GarageQual object

GarageCond object

dtype: object

 

 

  지금까지 데이터의 구조를 확인하고 타켓 데이터의 분포를 확인한 후, int, float형 변수들의 null 값을 평균으로 대체하여 제거했다.

 

#문자열 자료형은 원핫 코딩을 통해서 널값 처리를 하려고 함
#원핫코딩을 하면 Null 값은 None으로 바뀜

print('원핫 코딩을 실행하기 전 데이터 프레임 구조', house_df.shape)
house_df_ohe = pd.get_dummies(house_df)
print('원핫 코딩을 실행한 이후의 데이터 프레임 구조', house_df_ohe.shape)

a = house_df_ohe.isnull().sum()[house_df_ohe.isnull().sum()>0]
print('null 값 피처의 데이터 타입', house_df_ohe.dtypes[a])

 

  처리되지 않은 문자형 자료형의 null 값 처리는 판다스의 원핫코딩을 통해서 진행했다. 원핫코딩을 하게 되면 기존의 null 값은 None 데이터로 변환이 된다. 원핫 코딩 -> pd.get_dummies(house_df)


기준이 되는 평가 함수 생성

 

  본격적인 분석에 앞서서 앞으로 만들어질 모델을 평가할 평가 함수를 생성한다. 이번 회귀 분석 같은 경우 "rmse" 를 이용하여 모델을 평가하려고 한다.

 

def get_rmse(model):
    pred = model.predict(x_test)
    mse  = mean_squared_error(y_test, pred)
    rmse = np.sqrt(mse)
    print(model.__class__.__name__,' 로그 변환된 RMSE:', np.round(rmse,3))
    return rmse

def get_rmses(models):
    rmses = []
    for model in models:
        rmse = get_rmse(model)
        rmses.append(rmse)
    return rmses

 

  rmse같은 경우에는 사이킷런 패키지에 자체적으로 존재하지 않기 때문에 넘파이의 sqrt함수를 통해서 직접적으로 루트를 씌워준다.

 


1차 모델 생성과 모델 평가

 

 

from sklearn.linear_model import LinearRegression, Ridge, Lasso
from sklearn.metrics import mean_squared_error
from sklearn.model_selection import train_test_split

y_target = house_df_ohe['SalePrice']
x_data = house_df_ohe.drop('SalePrice', axis = 1, inplace = False)
x_train, x_test, y_train, y_test = train_test_split(x_data, y_target, test_size = 0.3, random_state = 1)

#LinearRegression Ridge Lasso 학습, 예측 평가

linear = LinearRegression()
linear.fit(x_train, y_train)
lasso  = Lasso()
lasso.fit(x_train, y_train)
ridge = Ridge()
ridge.fit(x_train, y_train)

 

  타겟 데이터와 기존 데이터를 분류하고 LinearRegression, Lasso, Ridge 모델에 학습시킨다.

 

models = [linear,lasso,ridge]
get_rmses(models)

 

  모델 평가 결과는 아래와 같다. 라쏘 규제 회귀 모형 같은 경우 타 모형에 비해서 오차제곱합이 크기 때문에 성능이 떨어진다고 할 수 있다. 그렇다면 규제 하이퍼파라미터인 alpha값을 조정하면서 성능을 개선시켜야 할 것처럼 보인다.

 

LinearRegression 로그 변환된 RMSE: 0.138

Lasso 로그 변환된 RMSE: 0.199

Ridge 로그 변환된 RMSE: 0.141

 

 

 


어떤 변수가 회귀 모형의 변수에 포함이 되었는지,

회귀 계수는 어느정도인지 그래프

 

def get_top_bottom_coef(model, n=10):
    coef = pd.Series(model.coef_, index = x_data.columns)
    
    coef_high = coef.sort_values(ascending = False).head(n)
    coef_low = coef.sort_values(ascending=False).tail(n)
    return coef_high, coef_low

def visualize_coefficient(models):
    fig, axs = plt.subplots(figsize=(24,10), nrows=1, ncols=3)
    fig.tight_layout()
    
    for i_num, model in enumerate(models):
        
        coef_high, coef_low = get_top_bottom_coef(model)
        coef_concat = pd.concat([coef_high,coef_low])
        
        axs[i_num].set_title(model.__class__.__name__+'Coefficients', size = 25)
        axs[i_num].tick_params(axis="y", direction="in", pad =-120)
        for label in (axs[i_num].get_xticklabels()+axs[i_num].get_yticklabels()):
            label.set_fontsize(22)
        sns.barplot(x=coef_concat.values, y=coef_concat.index, ax=axs[i_num])
        

 

  그래프 생성 코드 작성

 

models = [linear,ridge, lasso]
visualize_coefficient(models)

 

 

LinearRegression, Lasso, Ridge 회귀 계수 정도

 

  사진이 잘렸지만, 왼쪽에서부터, LinearRegression, Ridge, Lasso를 의미한다. Lasso의 각각의 변수들의 회귀 계수 값이 너무 작은 것을 확인할 수 있다.

 


규제 회귀 모형 하이퍼 파라미터 값 최적화 하기

 

 

  앞서 Lasso 모형의 RMSE값이 다른 모델에 비해서 높게 나온 것을 확인했다. 따라서, 하이퍼 파라미터 값을 수정하여 Lasso 모형을 최적화 시켜야만 한다. 방식은 분류모형의 하이퍼 파라미터 값을 수정하는 방식과 같이 GridSearchCV를 이용하여 alpha 값을 수정해본다. 먼저 cross_val_score를 통해서 alpha값을 수정하기 전의 각 cv의 rmse값을 구하고, 5개의 cv의 평균 rmse값을 도출한다. 결과는 아래와 같다.

 

from sklearn.model_selection import cross_val_score

def get_avg_rmse_cv(models):
    
    for model in models:
        rmse_list = np.sqrt(-cross_val_score(model, x_data, y_target, scoring = "neg_mean_squared_error", cv=5))
        rmse_avg = np.mean(rmse_list)
        print('\n{} CV RMSE 값 리스트: {}'.format(model.__class__.__name__,np.round(rmse_list,3)))
        print('\n{} CV 평균 RMSE 값 : {}'.format(model.__class__.__name__,np.round(rmse_avg,3)))
        
        

 

models = [linear, ridge, lasso]
get_avg_rmse_cv(models)

 

LinearRegression CV RMSE 값 리스트: [0.135 0.165 0.168 0.111 0.198]

LinearRegression CV 평균 RMSE 값 : 0.155

Ridge CV RMSE 값 리스트: [0.117 0.154 0.142 0.117 0.189]

Ridge CV 평균 RMSE 값 : 0.144

Lasso CV RMSE 값 리스트: [0.161 0.204 0.177 0.181 0.265]

Lasso CV 평균 RMSE 값 : 0.198

 

from sklearn.model_selection import GridSearchCV

def print_best_params(model, params):
    grid_model = GridSearchCV(model, param_grid = params, scoring = "neg_mean_squared_error", cv=5)
    grid_model.fit(x_data, y_target)
    rmse = np.sqrt(-1 * grid_model.best_score_)
    print('{0} 5 CV 시 최적 평균 RMSE 값 : {1}, 최적 alpha : {2}'.format(model.__class__.__name__,np.round(rmse,4),grid_model.best_params_))
    

 

  

  일괄적으로 각각의 모델들의 최적화 하기 위해서 GridSearchCV함수를 제작한다.

 

ridge_params = {'alpha':[0.05,0.1,1,5,8,10,12,15,20]}
lasso_params = {'alpha':[0.001,0.005,0.008,0.05,0.03,0.1,0.5,1,5,10]}
print_best_params(ridge, ridge_params)
print_best_params(lasso, lasso_params)

 

  Ridge, Lasso가 규제 회귀 모형이기 때문에 각 모델의 alpha값 리스트를 만들어 놓는다. 그리고 이 값을 gridsearchcv의 param_grid 하이퍼 파라미터 값으로 집어 넣는다. 그리고 grid_model을 통해서 best_params_ 와 best_score_를 통해서 최적의 하이퍼 파라미터 값과, 그에 따른 rmse값을 도출한다.

 

linear = LinearRegression()
linear.fit(x_train, y_train)
ridge = Ridge(alpha = 12)
ridge.fit(x_train, y_train)
lasso = Lasso(alpha = 0.001)
lasso.fit(x_train, y_train)

models = [linear, ridge, lasso]
get_rmses(models)
visualize_coefficient(models)

 

  도출된 최적의 alpha값으로 모델을 만들고 rmse값을 구하고 어떤 변수가 모델에 포함되어 있고 회귀 계수는 어떻게 되어 있는지 그래프를 그려본다.

 

LinearRegression, Lasso, Ridge 회귀 계수 정도

 

 

  Lasso 모델이 하이퍼 파라미터 값을 수정하니 회귀 계수들이 수정 전의 계수 값보다 크게 도출되었음을 확인할 수 있다. 하지만 하이퍼 파라미터 값을 최적화 해도 ridge에 비해서 상관계수가 여전히 상대적으로 낮음을 확인할 수 있다. 다음으로 할 작업은 변수 데이터의 분포를 조정하는 일이다.

 


변수 데이터의 분포도 조정

 

  scipy 패키지의 stats 모듈의 skew() 함수를 통해서 변수의 왜곡된 정도를 파악할 수 있다. skew()를 통해서 얼마나 왜곡되었는지 수치가 도출됐는데 수치 값이 1이상이 나왔을 경우 왜곡이 심한 것으로 간주하기로 했다. 하지만 주의해야 할 점이 있다. 어떤 변수가 왜곡되었는지 skew() 함수로 확인할 경우 원핫 코딩으로 전처리된 변수는 제외시켜야만 한다. 따라서, 원핫 코딩 하기 이전의 데이터 셋에서 왜곡된 변수를 찾아야만 한다.

 

features_index = house_df.dtypes[house_df.dtypes != 'object'].index

skew_features = house_df[features_index].apply(lambda x : skew(x))

 

 

features_index = house_df.dtypes[house_df.dtypes != 'object'].index

skew_features = house_df[features_index].apply(lambda x : skew(x))

 

  house_df_ohe가 아니라 house_df에서 문자형 자료형을 제외한 숫자형 자료형 변수만을 추출하여 feature_index에 담는다. 그리고 그 변수들의 왜곡된 수치를 skew(x) 로 파악한다.

 

skew_features_top = skew_features[skew_features > 1]
print(skew_features_top.sort_values(ascending = False))

 

  각 변수의 왜곡된 정도의 수치가 나타났을텐데 이 중에서 1이상인 것을 수정하기로 판단 내렸으므로 1이상의 변수명만 추출한다. 결과는 아래와 같다.

 

MiscVal 24.451640

PoolArea 14.813135

LotArea 12.195142

3SsnPorch 10.293752

LowQualFinSF 9.002080

KitchenAbvGr 4.483784

BsmtFinSF2 4.250888

ScreenPorch 4.117977

BsmtHalfBath 4.099186

EnclosedPorch 3.086696

MasVnrArea 2.673661

LotFrontage 2.382499

OpenPorchSF 2.361912

BsmtFinSF1 1.683771

WoodDeckSF 1.539792

TotalBsmtSF 1.522688

MSSubClass 1.406210

1stFlrSF 1.375342

GrLivArea 1.365156

 

 

house_df[skew_features_top.index] = np.log1p(house_df[skew_features_top.index])

 

  앞서 skew_features_top은 시리즈 형태로 왜곡된 수치를 반환했기 때문에 .index를 하여 그 변수명들을 추출한다. 그ㅡ리고 house_df에서 인덱싱할 때 사용하여 그 변수들만 정규분포화 시킨다.(넘파이 log1p를 활용)

 

house_df_ohe = pd.get_dummies(house_df)

 

  피처들을 정규분포화 시킨 이후에 다시 원핫 코딩을 하여 문자형 데이터들의 null 값을 처리한다.

 

y_target = house_df_ohe['SalePrice']
x_data = house_df_ohe.drop('SalePrice', axis = 1, inplace = False)
x_train, x_test, y_train, y_test = train_test_split(x_data, y_target, test_size = 0.3, random_state = 2)

ridge_params = {'alpha':[0.05,0.1,1,5,8,10,12,15,20]}
lasso_params = {'alpha' : [0.001,0.005,0.008,0.05,0.03,0.1,0.5,1,5,10]}

print_best_params(ridge, ridge_params)
print_best_params(lasso, lasso_params)

 

  다시 girdsearchcv를 이용하여 최적의 alpha 하이퍼 파라미터 값을 도출하고 최적의 score를 찾는다. 결과는 다음과 같다.

 

Ridge 5 CV 시 최적 평균 RMSE 값 : 0.1275, 최적 alpha : {'alpha': 10}

Lasso 5 CV 시 최적 평균 RMSE 값 : 0.1252, 최적 alpha : {'alpha': 0.001}

 

 

linear = LinearRegression()
linear.fit(x_train, y_train)
ridge = Ridge(alpha = 10)
ridge.fit(x_train, y_train)
lasso = Lasso(alpha = 0.001)
lasso.fit(x_train, y_train)

models = [linear, ridge, lasso]
visualize_coefficient(models)

 

  도출한 최적의 하이퍼 파라미터 값으로 모델을 수정해주고 그래프를 다시 그린다. 그래프의 결과는 다음과 같다.

 

LinearRegression, Lasso, Ridge 회귀 계수 정도

 

  드디어 세 개의 모델에서 GrLivArea, 즉 주거 공간 크기가 회귀 계수가 가장 높은 피처로 도출이 되었다. 이는 상식적으로 이해가 갈만한 수치이다.


회귀 계수가 높은 값들의 이상치 제거

 

집값과 주거 grlivarea 상관관계

 

  둘은 양의 상관관계를 가지고 있음에도 불구하고 그래프 오른쪽에 존재하는 두 개의 데이터는 그 관계에서 크게 벗어나 있다. 즉, 4000~5000의 값을 기록하고도 500000 미만의 값을 기록하고 있다. 따라서 이 두 개의 데이터를 이상치로 간주하고 제거 하려고 한다. 

 

 

#로그 처리되었으므로 로그 처리하여 삭제 해야 한다.

cond1 = house_df_ohe['GrLivArea'] > np.log1p(4000)
cond2 = house_df_ohe['SalePrice'] <= np.log1p(500000)
drop_index = house_df_ohe[cond1&cond2].index
house_df_ohe.drop(drop_index, axis=0, inplace=True)

 

그 조건으로 grlivarea가 4000 이상이면서 주택 가격이 500000미만으로 설정하고 이 값에 true인 값들은 제거하기로 한다. null 값을 제거하기 위해서 데이터 프레임에 로그를 취했으므로 기준의 값들도 로그를 취한다.

 

#이상치가 제거된 데이터를 통해서 다시 데이터 분할

y_target = house_df_ohe['SalePrice']
x_data = house_df_ohe.drop('SalePrice', axis = 1, inplace = False)

x_train, x_test, y_train, y_test = train_test_split(x_data, y_target, test_size = 0.3, random_state = 4)

ridge_params = {'alpha':[0.05,0.1,1,5,8,10,12,15,20]}
lasso_params = {'alpha':[0.001,0.005,0.008,0.05,0.03,0.1,0.5,1,5,10]}
print_best_params(ridge,ridge_params)
print_best_params(lasso,lasso_params)

 

  이상치가 제거된 데이터 셋에서 다시 데이터를 분리하고 GridSearchCV를 통해서 최적의 하이퍼 파라미터 값과 BEST SCORE를 찾는다. 결과는 다음과 같다.

 

Ridge 5 CV 시 최적 평균 RMSE 값 : 0.1125, 최적 alpha : {'alpha': 8}

Lasso 5 CV 시 최적 평균 RMSE 값 : 0.1122, 최적 alpha : {'alpha': 0.001}

 

linear = LinearRegression()
linear.fit(x_train, y_train)
ridge = Ridge(alpha = 8)
ridge.fit(x_train, y_train)
lasso = Lasso(alpha = 0.001)
lasso.fit(x_train, y_train)

models = [linear,ridge,lasso]
get_rmses(models)

 

  최적의 하이퍼 파라미터 값을 이용하여 다시 모델을 만들고 그 모델의 RMSE값을 도출한다. 결과는 다음과 같다. 단지 두 개의 이상치를 제거한 것 뿐인데 모델의 성능이 굉장히 개선되어 있는 것을 확인할 수 있다.

 

LinearRegression 로그 변환된 RMSE: 0.114

Ridge 로그 변환된 RMSE: 0.106

Lasso 로그 변환된 RMSE: 0.106

 

visualize_coefficient(models)

 

LinearRegression, Lasso, Ridge 회귀 계수 정도

 


정리

 

데이터 구조를 파악 -> null 값 파악 후 null 값 제거 (평균대체, 원핫 코딩) -> 타겟 데이터 분포도 확인(넘파이 로그로 정규분포화) -> 모델 성능 파악 (rmse값 파악) -> 성능이 좋지 않은 모델 하이퍼 파라미터 값 조정(GridSearchCV) ->  성능이 여전히 개선이 필요하다고 생각이 들면 타겟 데이터말고 데이터 변수들의 분포도 조정 (SCIPY.STATS.SKEW 함수 이용, 1이상의 수치만 수정, 원핫코딩에는 적용하지 않기) -> 그래도 성능이 별로라고 생각이 들면 이상치 제거

 

'머신러닝 > 캐글 예제 연습' 카테고리의 다른 글

자전거 대여 수요 예측  (1) 2021.05.03
분류연습)Credit Card Fraud Data 분석  (0) 2021.04.15
Comments