[파이썬 실습] Linear Regression 실습

 

 

Linear Regression(선형 회귀) 실습

선형회귀 모델 구축

 

 

1. 모듈 불러오기

  • load_boston : 패키지에서 제공하는 공공데이터로 1978년 보스턴 주택 가격에 대한 데이터이다.
  • 데이터 구조 : 관측치 개수 : 506개
  • 변수 개수 : 설명변수 : 13개 / 반응변수 : 1개

- 설명변수(원인 : 예측값을 설명할 수 있는 변수)

  • CRIM : 범죄율
  • INDUS : 비소매상업지역 면적비율
  • NOX : 일산화질소 농도
  • RM : 주택당 방 수
  • LSTAT : 인구 중 하위 계층 비율
  • B : 인구 중 흑인 비율
  • PTRATIO : 학생 / 교사 비율
  • ZN : 25,000 평방피트를 초과 거주지역 비율
  • CHAS : 찰스강의 경계에 위치한 경우 1, 아니면 0
  • AGE : 1940년 이전에 건축된 주택의 비율
  • RAD : 방사형 고속도로까지의 거리
  • DIS : 직업센터의 거리
  • TAX : 재산세율

- 반응변수(결과 : 예측하고자 하는 값)

  • MEDV : 주택가격

데이터 대한 설명, 링크 제공

 

- 데이터의 X의 변수 확인

 

- 데이터의 Y의 변수 확인 (주택 가격)

 

- 데이터의 변수명 확인, 데이터의 규격 확인

 

2. 데이터 전처리하기

X : 독립변수, 예측변수, 입력변수

Y : 종속변수, 반응변수, 출력변수

 

- 분석에 용이하기 위해 데이터 프레임 형태로 변환한 후, X, Y 값 확인

 

2.1 Train set / Test set 나누기

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2, random_state = 2021)

- 분석을 하기 위해 모델이 잘 구축되었는지 확인

- 새로운 문제를 잘 풀 수 있는지!

- 임의로 새로운 데이터를 만들어 주는 부분


3. 선형 회귀 모델 구축하기

  • OLS : 가장 기본적인 결정론적 선형 회귀 방법으로 잔차제곱합(RSS)를 최소화하는 가중치를 구하는 방법
  • 모델 선언 : model = sm.OLS(Y데이터, X데이터)
  • 모델 학습 : model_trained = model.fit()

3.1 선형 회귀 모델 가정 확인하기

X_train = sm.add_constant(X_train)
model = sm.OLS(y_train, X_train, axis = 1)
model_trained = model.fit()

 

- 선형회귀 모델 구축 완성

- 선형회귀 모델의 가정이 성립하는지 확인하는 것이 중요!


3.1.1 확률오차의 정규성 확인

model_residuals = model_trained.resid

plt.rcParams['axes.unicode_minus'] = False # 음수 폰트 깨짐 방지
fig, ax = plt.subplots(1, 1)
fig.set_figheight(12)
fig.set_figwidth(12)

sm.ProbPlot(model_residuals).qqplot(line = 's', color = '#1f77b4', ax = ax)
ax.title.set_text('QQ Plot')

 

위의 QQ플롯으로 보아 빨간 실선에 잘 따르는 것을 확인할 수 있다.

 


3.1.2 확률오차의 등분산성 확인

model_fitted_y = model_trained.fittedvalues

fig, ax = plt.subplots(1, 1)
fig.set_figheight(8)
fig.set_figwidth(12)

sns.residplot(model_fitted_y, y_train, data = X_train, lowess = True, scatter_kws = {'alpha' : 0.5},
             line_kws = {'color' : 'red'}, ax = ax)
ax.title.set_text('Residuals vs Fitted')
ax.set(xlabel = 'Fitted values', ylabel = 'Residuals')

 

위의 QQ플롯을 보아 어느 정도 일직선을 따라가는 경향을 보이기 때문에 등분산성을 확인했다고 볼 수 있다.


4.1 설명 : 통계적으로 해석하기

  • R-squared : 모형의 성능
  • coef(회귀계수) : X가 한 단위 증가할 때 Y의 변화량
  • P>[t] (p-value) : 0.05(유의 수준) 이하일 때 변수가 유의미
print(model_trained.summary())

 

 

summary 함수로 R-결정계수, 수정된 R-결정계수, 데이터와 모델에 대해 설명이 가능!


 

앞서 summary값에서 베타값에 대한 p-value 값이 나온다. p-value 값을 토대로 어느 정도 해석을 하고 설명을 했다고 하면, 그 설명을 바탕으로 개선을 해야 한다.

 

summary 값을 보면 INDUS, AGE 변수는 각각 p-value 값이 0.962, 0.476이 나왔다. 이 값은 상대적으로 유의하지 않다고 해석을 할 수 있기 때문에 이 두 가지 변수를 제거하고 다시 모델을 구축한다.

model = sm.OLS(y_train, X_train.drop(['INDUS', 'AGE'], axis = 1))
model_trained = model.fit()
print(model_trained.summary())

 

위의 결과값을 보면, 성능에는 큰 변화가 없지만 전 결과보다 통계적으로 유의미하다고 볼 수 있다.

 


4.2 예측 : 미래의 반응변수 값 예측하기

위의 과정을 토대로 설명을 했다면 이제 예측을 해야 한다.

학습에 사용된 값이 들어왔을 때 예측이 되는지 확인을 한다.

 

y_train_pred = model_trained.fittedvalues

plt.figure(figsize = (8,8))
plt.title('실제값 vs 모델 출력 값')
plt.scatter(y_train, y_train_pred)
plt.plot([-5, 55], [-5, 55], ls = '--', c = 'red')
plt.xlabel('실제값', size = 16)
plt.ylabel('모델 출력 값', size = 16)
plt.xlim(-5, 55)
plt.ylim(-5, 55)
plt.show()

빨간 점선을 따라야 올바른 예측이 된다고 해석할 수 있다. 위의 그래프를 보면 어느 정도 유사한 패턴으로 예측을 하고 있다고 볼 수 있다.

 

Test셋에 대해서도 예측값을 뽑아낼 수 있다.

 

위와 같이 예측값이 나오면 여러 가지 측도를 활용을 해서 해당 모델의 성능을 정량적인 지표로 도출할 수 있다.

 

4.2.1 Mean Squared Error (평균 제곱 오차)

4.2.2 Root Mean Squared Error (제곱근 평균 제곱 오차) : RMSE

4.2.3 Mean Absolute Error (평균 절대 오차)

4.2.4 Mean Absolute Precentage Error (평균 절대 백분율 오차)

4.2.5 R squared (결정 계수)


4.3 최종 결과 정리

print('Training MSE : {:.3f}'.format(mean_squared_error(y_train, y_train_pred)))
print('Training RMSE : {:.3f}'.format(np.sqrt(mean_squared_error(y_train, y_train_pred))))
print('Training MAE : {:.3f}'.format(mean_absolute_error(y_train, y_train_pred)))
print('Training MAPE : {:.3f}'.format(mean_absolute_percentage_error(y_train, y_train_pred)))
print('Training R2 : {:.3f}'.format(r2_score(y_train, y_train_pred)))

 

print('Testing MSE : {:.3f}'.format(mean_squared_error(y_test, y_test_pred)))
print('Testing RMSE : {:.3f}'.format(np.sqrt(mean_squared_error(y_test, y_test_pred))))
print('Testing MAE : {:.3f}'.format(mean_absolute_error(y_test, y_test_pred)))
print('Testing MAPE : {:.3f}'.format(mean_absolute_percentage_error(y_test, y_test_pred)))
print('Testing R2 : {:.3f}'.format(r2_score(y_test, y_test_pred)))

Testing에 대한 성능이 Training에 대한 성능보다 낮은데 이 이유는 일반적으로 Training셋은 학습에 사용된 데이터이기 때문에 비교적으로 Testing에 대한 성능이 높게 나온다.


 

 

TAGS.

Comments