05-04. ボストン住宅価格予測


これはWekibooksのPythonマシン学習パーフェクトガイドに基づいて学んだ内容です.

1.線形回帰クラス-Ordinary Least Squares


LinearRegressionクラスは、予測値と実績値のRSS(Resideual Sum of Squares)を最小化し、OLS(Ordinary Least Squares)推定で実現したクラスであり、fit()メソッドでX、Y配列を入力すると回帰係数W(Coefficients)がCoef属性に格納される.
 class sklearn.linear_model.LinearRegression(fit_intercept=True, normalize=Flase, copy_X=True, n_jobs=1)
  • 입력 파라미터
    • fit_intercept : boolean 값으로 default는 True이다. Intercept(절편) 값을 계산할 것인지 말지를 지정하고, 만일 False로 지정하면 intercept가 사용되지 않고 0으로 지정된다.
    • normalize : boolean 값으로 default는 False이다. fit_intercept가 False인 경우에는 이 파라미터가 무시되고, True이면 회귀를 수행하기 전에 입력 dataset을 정규화한다.
  • 속성
    • coef_ : fit() method를 수행했을 때 회귀 계수가 배열 형태로 저장하는 속성이며, Shape은 (Targt 값 개수, feature 개수)이다.
    • intercept_ : intercept 값

Ordinary Least Squares 기반의 회귀 계수 계산은 입력 feature의 독립성에 많은 영향을 받는다. feature 간의 상관관계가 매우 높은 경우 분산이 커져서 오류에 매우 민감해진다. 이러한 현상으 공신성(multi-collinearity) 문제라고 한다. 일반적으로 상관관계가 높은 feature가 많은 경우 독립적인 중요한 feature만 남기고 제거하거나 규제를 적용한다. 또한 매우 많은 feature가 다중 공선성 문제를 가지고 있다면 PCA를 통해 차원 축소를 수행하는 것도 고려해 볼 수 있다.


2.回帰評価指標


회귀의 평가를 위한 지표는 실제 값과 예측 값의 차이를 기반으로 한 지표가 중심이다.

평가 지표설명수식
MAE
Mean Absolute Error이며 실제 값과
예측 값의 차이를 절댓값으로 변환해
평균한 것이다.
 MAE=1ni=1nYiYi^MAE={1 \over n}\sum_{i=1}^n \left\vert Y_i- \hat{Y_i} \right\vert
MSE
Mean Squared Error이며 실제 값과
예측 값의 차이를 제곱해 평균한
것이다.
 MSE=1ni=1n(YiYi^)2MSE={1 \over n}\sum_{i=1}^n (Y_i- \hat{Y_i})^2
RMSE
MSE 값은 오류의 제곱을 구하므로 실제
오류 평균보다 더 커지는 특성이
있으므로 MSE에 루트를 씌운 것이
Root Mean Squared Error이다.
 RMSE=1ni=1n(YiYi^)2RMSE=\sqrt{{1 \over n}\sum_{i=1}^n (Y_i- \hat{Y_i})^2}
R2^2
분산 기반으로 예측 성능을 평가한다.
실제 값의 분산 대비 예측값의 분산
비율을 지표로 하며, 1에 가까울수록
예측 정확도가 높다.
 R2=예측값 Variance실제값 VarianceR^2={예측값 \ Variance \over 실제값 \ Variance}

이 밖에 MSE나 RMSE에 로그를 적용한 MSLE(Mean Squared Log Error)와 RMSLE(Root Mean Squared Log Error)도 사용한다.


3.線形回帰によるボストン住宅価格回帰


사이킷런은 보스턴 주택 가격 dataset을 load_boston()을 통해 제공한다. 각 feature의 의미를 설명한 후 dataset을 로드하고 DataFrame으로 변경하겠다.

  • feature 설명
    • CRIM: 지역별 범죄 발생률
    • ZN: 25,000평방피트를 초과하는 거주 지역의 비율
    • NDUS: 비상업 지역 넓이 비율
    • CHAS: 찰스강에 대한 더미 변수(강의 경계에 위치한 경우는 1, 아니면 0)
    • NOX: 일산화질소 농도
    • RM: 거주할 수 있는 방 개수
    • AGE: 1940년 이전에 건축된 소유 주택의 비율
    • DIS: 5개 주요 고용센터까지의 가중 거리
    • RAD: 고속도로 접근 용이도
    • TAX: 10,000달러당 재산세율
    • PTRATIO: 지역의 교사와 학생 수 비율
    • B: 지역의 흑인 거주 비율
    • LSTAT: 하위 계층의 비율
    • MEDV: 본인 소유의 주택 가격(중앙값)
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns
from scipy import stats
from sklearn.datasets import load_boston
%matplotlib inline

# boston 데이타셋 로드
boston = load_boston()

# boston 데이타셋 DataFrame 변환 
bostonDF = pd.DataFrame(boston.data , columns = boston.feature_names)

# boston dataset의 target array는 주택 가격임. 이를 PRICE 컬럼으로 DataFrame에 추가함. 
bostonDF['PRICE'] = boston.target
print('Boston 데이타셋 크기 :',bostonDF.shape)
bostonDF.head()
[output] datasetのfeatureにはNull値がなく、すべてフローティングです.次いで,回帰結果に及ぼす各feature(column)の影響の程度を可視化することによって理解した.
# 2개의 행과 4개의 열을 가진 subplots를 이용. axs는 4x2개의 ax를 가짐.
fig, axs = plt.subplots(figsize=(16,8) , ncols=4 , nrows=2)
lm_features = ['RM','ZN','INDUS','NOX','AGE','PTRATIO','LSTAT','RAD']
for i , feature in enumerate(lm_features):
    row = int(i/4)
    col = i%4
    # 시본의 regplot을 이용해 산점도와 선형 회귀 직선을 함께 표현
    sns.regplot(x=feature , y='PRICE',data=bostonDF , ax=axs[row][col])
[output]RMおよびLSTATのPRICEの影響はの他の特性と比較して最も顕著であった.RM(部屋数)の2方向での線形度が最大です.つまり、部屋が大きければ大きいほど、値段が高くなります.低層比(LSTAT)は負の線形性で最大であった.現在,LinearRegressionクラスを用いてボストンの住宅価格の回帰モデルを構築し,学習/予測を行い,MSEとR 2 Scoreを測定する.
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error , r2_score

y_target = bostonDF['PRICE']
X_data = bostonDF.drop(['PRICE'],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=156)

# Linear Regression OLS로 학습/예측/평가 수행. 
lr = LinearRegression()
lr.fit(X_train ,y_train )
y_preds = lr.predict(X_test)
mse = mean_squared_error(y_test, y_preds)
rmse = np.sqrt(mse)

print('MSE : {0:.3f} , RMSE : {1:.3F}'.format(mse , rmse))
print('Variance score : {0:.3f}'.format(r2_score(y_test, y_preds)))
[output] coef属性は回帰係数値のみを有するため、各特徴の回帰係数をより高い値に出力しようと試みる.
# 회귀 계수를 큰 값 순으로 정렬하기 위해 Series로 생성. index가 컬럼명에 유의
coeff = pd.Series(data=np.round(lr.coef_, 1), index=X_data.columns )
coeff.sort_values(ascending=False)
[output] RMは正の値であり、回帰係数が最大であり、NOX featureの回帰係数−値が最大である.クロス検証によりMSEとRMSEを測定した.
from sklearn.model_selection import cross_val_score

y_target = bostonDF['PRICE']
X_data = bostonDF.drop(['PRICE'],axis=1,inplace=False)
lr = LinearRegression()

# cross_val_score( )로 5 Fold 셋으로 MSE 를 구한 뒤 이를 기반으로 다시  RMSE 구함. 
neg_mse_scores = cross_val_score(lr, X_data, y_target, scoring="neg_mean_squared_error", cv = 5)
rmse_scores  = np.sqrt(-1 * neg_mse_scores)
avg_rmse = np.mean(rmse_scores)

# cross_val_score(scoring="neg_mean_squared_error")로 반환된 값은 모두 음수 
print(' 5 folds 의 개별 Negative MSE scores: ', np.round(neg_mse_scores, 2))
print(' 5 folds 의 개별 RMSE scores : ', np.round(rmse_scores, 2))
print(' 5 folds 의 평균 RMSE : {0:.3f} '.format(avg_rmse))
[output]