import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from scipy import stats
from sklearn.datasets import load_boston
import warnings
warnings.filterwarnings('ignore')
%matplotlib inline
# boston 데이터 세트 로드
boston = load_boston()
# boston 데이터 세트 DataFrame 변환
bostonDF = pd.DataFrame(boston.data, columns=boston.feature_names)
# boston 데이터 세트의 target array는 주택 가격. 이를 PRICE 컬럼으로 DataFrame에 추가
bostonDF['PRICE'] = boston.target
bostonDF.head()

변수 설명
- CRIM: 지역별 범죄 발생률
- ZN: 25,000평방 피트를 초과하는 거주 지역의 비율
- INDUS: 비상업 지역 넓이 비율
- CHAS: 찰스강에 대한 더미변수(강의 경계에 위치한 경우1, 아니면 0)
- NOX:일산화질소 농도
- RM: 거주할 수 있는 방 개수
- AGE: 1940년 이전에 건축된 소유 주택의 비율
- DIS: 5개 주요 고용센터까지의 가중 거리
- RAD: 고속도로 접근 용이도
- TAX: 10,000달러당 재산세율
- PTRATIO: 지역의 교사와 학생 수 비율
- B: 지역의 흑인 거주 비율
- LSTAT: 하위 계층의 비율
bostonDF.info()

bostonDF.isnull().sum()

결측값은 없으며 피처들이 모두 float형이다.
다음으로 각 피처와 타겟값 사이의 상관관계를 살펴보자.(참고로 seaborn의 regplot() 함수는 x, y 축 값의 산점도와 함께 선형 회귀 직선을 그려줌)
# 2X4 subplots 이용. axs는 4*2개의 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 # 나머지
sns.regplot(x=feature, y='PRICE', data=bostonDF, ax=axs[row][col])

타겟값(주택 가격)과 가장 상관관계가 있는 피처는 RM, LSTAT이다.
RM은 양의 상관관계를 보이며, 방의 크기가 클수록 주택 가격이 커짐
LSTAT는 음의 상관관계를 보이며, 하위 계층의 비율이 높아질수록 주택 가격이 낮아짐
이제 train, test 데이터 분리하고 학습/예측/평가를 수행하자.
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_features = bostonDF.drop(['PRICE'], axis=1, inplace=False)
X_train, X_test, y_train, y_test = train_test_split(X_features, y_target, test_size=0.3, random_state=156)
# LinearRegression으로 학습/예측/평가 수행
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)))

선형회귀로 학습한 주택가격 모델의 평가 결과를 보면 만족스러운 결과는 아니다.
일단, 선형회귀로 학습한 주태가격 모델의 절편과 회귀계수를 보자.
print('절편:', lr.intercept_)
print('회귀계수:', np.round(lr.coef_, 1))

# 각 피처와 매핑하여 정렬
coeff = pd.Series(data=np.round(lr.coef_, 1), index=X_features.columns)
coeff.sort_values(ascending=False)

NOX 피처의 회귀계수가 음으로 너무 커 보인다. 이는 나중에 규제를 공부한 뒤 최적화를 수행하자.
이번에는 교차검증을 통해 MSE와 RMSE를 측정해보자.
from sklearn.model_selection import cross_val_score
y_target = bostonDF['PRICE']
X_features = bostonDF.drop(['PRICE'], axis=1, inplace=False)
lr = LinearRegression()
mse_scores = -cross_val_score(lr, X_features, y_target, scoring='neg_mean_squared_error', cv=5)
rmse_scores = np.sqrt(mse_scores)
avg_rmse = np.mean(rmse_scores)
print('5folds의 개별 mse scores:', np.round(mse_scores, 2))
print('5folds의 개별 rmse scores:', np.round(rmse_scores, 2))
print('5folds의 평균 rmse:{0:.3f}'.format(avg_rmse))

'파이썬 머신러닝 완벽가이드 > [5장] 회귀' 카테고리의 다른 글
| 규제 선형 모델 - 릿지, 라쏘, 엘라스틱넷 (0) | 2023.04.16 |
|---|---|
| 다항회귀(Polynomial Regression) (0) | 2023.04.10 |
| LinearRegression, 회귀 평가 지표 (0) | 2023.03.19 |
| 경사 하강법(Gradient Descent) (0) | 2023.03.10 |
| 단순 선형 회귀를 통한 회귀 이해 (0) | 2023.03.08 |