column 설명
더보기
- CRIM: 지역별 범죄 발생률
- ZN: 25,000평방피트를 초과하는 거주 지역의 비율
- NDUS: 비상업 지역 넓이 비율
- CHAS: 찰스강에 대한 더미 변수(강의 경계에 위치한 경우는 1, 아니면 0)
- NOX: 일산화질소 농도
- RM: 거주할 수 있는 방 개수
- AGE: 1940년 이전에 건축된 소유 주택의 비율
- DIS: 5개 주요 고용센터까지의 가중 거리
- RAD: 고속도로 접근 용이도
- TAX: 10,000달러당 재산세율
- PTRATIO: 지역의 교사와 학생 수 비율
- B: 지역의 흑인 거주 비율
- LSTAT: 하위 계층의 비율
- PRICE: 본인 소유의 주택 가격(중앙값) - 종속변수 (위의 건 독립변수)
1. 데이터 살펴보기
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
import warnings
warnings.filterwarnings('ignore')
%matplotlib inline
# 보스턴 데이터 불러오기
boston = load_boston()
bostonDF = pd.DataFrame(boston.data, columns=boston.feature_names)
bostonDF['PRICE'] = boston.target # boston데이터셋의 target 배열은 주택가격
print(bostonDF.shape) # (506, 14)

bostonDF.info()

# 보스턴 데이터 시각화
# 4개의 열, 2개의 행
fig, axs = plt.subplots(figsize=(16,8), ncols=4, nrows=2)
lm_features = ['RM','ZN','INDUS','NOX','AGE','PTRATIO','LSTAT','RAD']
# i에는 인덱스가 feature에는 RM ~ RAD까지 순차적으로 들어감
for i, feature in enumerate(lm_features):
row = int(i/4) # 2행
col = i%4
# sns.regplot : 산점도와 선형 회귀 직선을 함께 표현
sns.regplot(x=feature, y='PRICE', data=bostonDF, ax=axs[row][col])

- 집 값 상승 : RM(방 갯수)는 양 방향의 선형성(Positive)이 가장 크다. 즉, 방 크기가 클수록 집값 상승
- 집 값 하락 : LSTAT(하위계층비율)은 음 방향의 선형성(Negative)이 가장 크다.
2. train / test 분리해서 학습과 예측을 수행
- 506개 데이터 -> 7:3 train/test 데이터 분리
- train : 학습 -> linear regression 학습/모델링 수행 -> 모델(W) 생성
- test : 평가(validation)-> 평가지표 (MSE, RMSE, ... )
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, r2_score
# m_s_e, r2(선형회귀모델 적합도 : 분산값, 1에 가까울수록 적합도 높음)
df = bostonDF
# feature, target 데이터 분리
y_target = df['PRICE'] # 레이블(종속변수)
X_data = df.drop(['PRICE'], axis=1, inplace=False) # 피처(독립변수)
# train, test 데이터 분리
X_train , X_test , y_train , y_test = train_test_split(X_data , y_target , test_size=0.3, random_state=156)
# 선형 회귀 OLS로 학습하기
lr = LinearRegression()
# fit 메소드 학습 : 주어진 데이터로 estimator(사이킷런이 제공) 알고리즘 학습
lr.fit(X_train, y_train)
print(X_train.shape, X_test.shape)
[out]
(354, 13) (152, 13)
# predict 메소드 : 학습된 모델로 예측을 수행
y_preds = lr.predict(X_test)
y_preds[0:5]
[out]
array([23.15424087, 19.65590246, 36.42005168, 19.96705124, 32.40150641])
# rmse를 활용한 평가
mse = mean_squared_error(y_test, y_preds)
rmse = np.sqrt(mse)
print(f'MSE : {mse:.3f}, RMSE: {rmse:.3f}')
print(f'Variance score : {r2_score(y_test, y_preds):.3f}')
[out]
MSE : 17.297, RMSE: 4.159
Variance score : 0.757
3. 주택 가격 모델의 intercept(절편)과 coefficients(회귀 계수)값 확인
print("절편 값:", lr.intercept_) # y축 절편값
# 회귀 계수(coefficient) : 독립변수의 변화에 따라 종속변수에 미치는 영향력이 크기
print("회귀계수:", np.round(lr.coef_,1))
[out]
절편 값: 40.995595172164336
회귀계수: [ -0.1 0.1 0. 3. -19.8 3.4 0. -1.7 0.4 -0. -0.9 0.
-0.6]
# 회귀계수 정렬 (내림차순, 큰 값부터)
coeff = pd.Series(data=np.round(lr.coef_, 1), index=X_data.columns)
coeff.sort_values(ascending=False)
[out]
RM 3.4
CHAS 3.0
RAD 0.4
ZN 0.1
INDUS 0.0
AGE 0.0
TAX -0.0
B 0.0
CRIM -0.1
LSTAT -0.6
PTRATIO -0.9
DIS -1.7
NOX -19.8
dtype: float64
RM의 양의 절대값이 제일 크고, NOX(일산화질소 농도)가 음의 절대값이 너무 크다.
4. cross_val_score를 이용해 교차검증
- 사이킷런의 지표 평가 기준은 높은 지표값일수록 좋은 모델이지만, 일반적으로 회귀는 MSE값이 낮을수록 좋은 회귀 모델이다.
- RMSE를 구하기 위해선 MSE 값에 -1을 곱한 후 평균을 내면 된다.
- 왜? scoring함수 호출하면 MSE값에 -1을 곱해서 반환하기 때문에
다시!! -1을 곱해야 양수인 원래 모델에서 계산된 MSE값이 된다.
- 왜? scoring함수 호출하면 MSE값에 -1을 곱해서 반환하기 때문에
from sklearn.model_selection import cross_val_score
# features, target 데이터 정의
y_target = df['PRICE']
X_data = df.drop(['PRICE'], axis=1)
# 선형회귀 객체 생성
lr = LinearRegression()
# 5 folds의 개별 Negative MSE scores (음수로 만들어 작은 오류 값이 더 큰 숫자로 인식됨)
neg_mse_scores = cross_val_score(lr, X_data, y_target, scoring="neg_mean_squared_error", cv = 5)
# RMSE를 구하기 위해선 MSE 값에 -1을 곱한 후 평균을 내면 된다
# 왜? scoring함수 호출하면 MSE값에 -1을 곱해서 반환하기때문에
rmse_scores = np.sqrt(-1*neg_mse_scores) # 그래서 다시!! -1을 곱해야 양수인 원래 모델에서 계산된 MSE값이 된다.
# 5 fold 의 평균 RMSE
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(f' 5 folds 의 평균 RMSE : {avg_rmse:.3f}')
[out]
5 folds 의 개별 Negative MSE scores: [-12.46 -26.05 -33.07 -80.76 -33.31]
5 folds 의 개별 RMSE scores : [3.53 5.1 5.75 8.99 5.77]
5 folds 의 평균 RMSE : 5.829
보스턴 주택가격 예측 RMSE값은 5.829가 나왔다.
5. KNN 모델과 비교해보기
from sklearn.neighbors import KNeighborsRegressor
from sklearn.linear_model import LinearRegression
knn_model = KNeighborsRegressor(n_neighbors=4).fit(X_train, y_train)
lr_model = LinearRegression().fit(X_train, y_train)
print('KNN 학습평가:', knn_model.score(X_train,y_train))
print('LR 학습평가:', lr_model.score(X_train,y_train))
[out]
KNN 학습평가: 0.7494788081365981
LR 학습평가: 0.7273505005599823
print('KNN 테스트평가:', knn_model.score(X_test,y_test))
print('LR 테스트평가:', lr_model.score(X_test,y_test))
[out]
KNN 테스트평가: 0.499306667207422
LR 테스트평가: 0.7572263323138921
학습평가 점수는 비슷하지만, 테스트 평가 점수는 Linear Regression모델이 0.75로 더욱 잘 나왔다.
- RMSE를 구하기 위해서 MSE 값에 -1을 곱한 후 평균을 내는 이유
scoring함수 호출하면 MSE값에 -1을 곱해서 반환하기 때문에
다시 -1을 곱해야 양수인 원래 모델에서 계산된 MSE값이 된다.
'Data Analytics > MachineLearning' 카테고리의 다른 글
[ML] 시계열(Timeseries)이란? / AR , MA, ARIMA 알아보기 (0) | 2022.11.07 |
---|---|
[ML] 지도학습의 회귀 - 규제선형 모델 알아보기(릿지, 라쏘, 엘라스틱넷) (0) | 2022.11.07 |
[ML] 머신러닝 모델의 성능을 향상시키는 방법 GridSearchCV (0) | 2022.11.07 |
[ML] 머신러닝 최적화 방법, 경사하강법(Gradient Descent) 알아보기 / 확률적 경사하강법 (0) | 2022.11.07 |
[ML] 머신러닝 지도학습의 회귀(regression)의 종류와 실습해보기 (0) | 2022.11.07 |
댓글