보스턴 주택 데이터 회귀분석

2024. 6. 14. 13:42Machine Learning

 


✅ 목표 설정

  • 특성 변수를 활용해서 회귀예측을 진행해보자
  • 특성곱이라는 특성 공학을 진행해보자
# 필요한 라이브러리 불러오기

import pandas as pd
import numpy as np

from matplotlib import pyplot as plt
# 데이터 로딩

data = pd.read_csv('data/boston_housing.csv')
data

 

# 필요없는 컬럼 제거하기

data.drop('Unnamed: 0', axis=1, inplace=True)
data
# 데이터 프레임 간략한 정보 확인하기

data.info()
# 데이터의 컬럼을 살펴보기

data.columns

✅ 설명 변수(특성변수, 문제데이터, 특성값)

  • 원인 : 예측을 설명할 수 있는 변수 / 종속변수에 영향을 미치는 변수
  • 'CRIM' : 범죄율
  • 'ZN' : 25,000평방 피트를 초과한 거주 지역의 비율
  • 'INDUS' :비 소매 상업 지역의 비율
  • 'CHAS' : 찰스강의 경계선에 위치하는가? 경계에 위치한 경우 1 / 아니면 0
  • 'NOX' : 대기중 일산화 질소의 농도
  • 'RM' : 방의 갯수
  • 'AGE' : 1940년 이전에 지어진 주택의 비율
  • 'DIS' : 직업센터와의 거리
  • 'RAD' : 방사형 도로와의 접근성
  • 'TAX' : 재산세의 비율
  • 'PTRATIO' : 학생/교사의 비율
  • 'B' : 인구 중 흑인의 비율
  • 'LSTAT' : 인구 중 하위 계층의 비율

✅ 반응변수(예측값, 정답 데이터)

  • 결과 : 우리가 예측하고자 하는 값 / 독립변수의 영향을 받아 변화하는 값
  • 'MEDV' : 주택 가격
# 데이터 분할

X = data.loc[ : , 'CRIM' : 'LSTAT']
y = data['MEDV']
​
X.info()

# train / test 셋으로 분리
# 비율 7 : 3 / 랜덤 시드 = 0

from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(X, y,
                                                   train_size=0.7,
                                                   random_state=0
                                                   # test_size=0.3
                                                   )
X_train.shape, X_test.shape, y_train.shape, y_test.shape

 

✅ 선형 회귀 모델 사용해보기

# 모델 import

from sklearn.linear_model import LinearRegression # LinearRegression : 선형 회귀
linear_model = LinearRegression()
# 모델 학습

linear_model.fit(X_train, y_train)

# 실제 가격 예측해보기

pre = linear_model.predict(X_test)
pre

# 회귀 평가 지표 확인해보기

from sklearn.metrics import r2_score, mean_absolute_error, mean_squared_error
# 평균 제곱 오차

mean_squared_error(pre, y_test)
# 27만 달러 정도의 오차가 나온다 -> 현재 오차는 제곱이 되어있는 상태이다

# 평균 제곱근 오차
# 제곱된 오차를 원래 사이즈로 바꿔주자

np.sqrt(mean_squared_error(pre, y_test))
r2_score(y_test, pre)

  • ✅ 결정계수
    • 추정한 선형 모델이 주어진 자료에 적합한지를 판단하는 척도
    • 독립변수(특성값)가 종속변수(예측값)의 분산을 판단하는 척도
    • R2의 범위 : 0 ~ 1(값이 심하게 틀어지면 -(음수)값이 나오기도 한다.)
    • R2 스코어가 1이 나온 경우 독립변수를 이용해서 종속변수를 100% 완벽하게 예측했다.
    • R2 스코어가 0이 나온 경우 독립변수가 종속변수를 예측하는데 도움이 되지 않았다.
# 평균 절대 오차

mean_absolute_error(y_test, pre)
# 모델 자체 스코어 점수

linear_model.score(X_train, y_train)
linear_model.score(X_test, y_test)

  • ✅ 현재 선형 모델은 성능이 좋지 않다. 모델의 성능을 향상시키는 방법을 찾아보자.
  • 선형모델의 성능은 데이터가 많을수록 좋아진다.
  • 성능이 좋다라는 개념은 훈련 데이터의 성능이 조금 떨어지더라도 새로운 데이터 반응을 잘하는 것을 이야기한다.

✅ 특성 확장

  • 모델의 성능을 올려보기 위해 새로운 특성을 추가시켜 보자!
# 특성 확장을 위해 데이터를 가지고 오자

data
# 원본 데이터는 잘못 건드릴시 데이터 오염으로 인해 사용하기 어려울 수 있다.
# 원본 데이터와 똑같은 형태로 새로운 객체를 만들어주자(복사)

data_copy = data.copy()
data_copy

 

✅ 상관계수

# 집 값과 연관관계가 높은 특성을 찾아봅시다!
# 상관관계(상관계수)
# 1 or -1 : 절대적인 상관관계가 있음(한 값이 커지면 똑같은 비율로 커지거나 작아지는 경우)
# 0.7이상 or -0.7이하 : 강한 상관관계가 있음
# 0.3이하 or -0.3이상 : 약한 상관관계가 있음
# 0 : 전혀 상관 없음

data_copy.corr()

 

# abs() : 절대값을 구하는 함수

data_copy.corr().abs()

# 우리가 확인해야하는 MEDV라는 컬럼의 상관계수를 내림차순 정렬
data_copy.corr().abs().sort_values(by='MEDV', ascending = False)
# 상관관계가 높은 특성에 대해 특성 확장을 진행해보자
# LSTAT 확인
# Before) 일반 LSTAT만 가지고 학습시킨 후 예측을 확인해보자

model = LinearRegression()

model.fit(X_train[['LSTAT']], y_train)

pre = model.predict(X_train[['LSTAT']])

plt.scatter(X_train['LSTAT'], y_train) # 산점도
plt.scatter(X_train['LSTAT'], pre, color = 'red') # 예측선

plt.show()
# 특성 확장 진행

X_train['LSTAT X LSTAT'] = X_train['LSTAT'] * X_train['LSTAT']

model = LinearRegression()

model.fit(X_train[['LSTAT', 'LSTAT X LSTAT']], y_train)

pre = model.predict(X_train[['LSTAT', 'LSTAT X LSTAT']])

plt.scatter(X_train['LSTAT'], y_train) # 산점도
plt.scatter(X_train['LSTAT'], pre, color = 'red')

plt.show()
X_test['LSTAT X LSTAT'] = X_test['LSTAT'] * X_test['LSTAT']

# 특성 확장한 데이터를 추가해서 성능을 체크해보자

linear_model = LinearRegression()

linear_model.fit(X_train, y_train)

linear_model.score(X_test, y_test)
# 약 2% 성능 상승
# 상관관계가 높은 특성에 대해 특성 확장을 진행해보자
# RM 확인
# Before) 일반 RM만 가지고 학습시킨 후 예측을 확인해보자

model = LinearRegression()

model.fit(X_train[['RM']], y_train)

pre = model.predict(X_train[['RM']])

plt.scatter(X_train['RM'], y_train) # 산점도
plt.scatter(X_train['RM'], pre, color = 'red') # 예측선

plt.show()
# 특성 확장 진행

X_train['RM X RM'] = X_train['RM'] * X_train['RM']

model = LinearRegression()

model.fit(X_train[['RM', 'RM X RM']], y_train)

pre = model.predict(X_train[['RM', 'RM X RM']])

plt.scatter(X_train['RM'], y_train) # 산점도
plt.scatter(X_train['RM'], pre, color = 'red')

plt.show() # 곡선 모양

X_test['RM X RM'] = X_test['RM'] * X_test['RM']

# 특성 확장한 데이터를 추가해서 성능을 체크해보자

linear_model = LinearRegression()

linear_model.fit(X_train, y_train)

linear_model.score(X_test, y_test)
# 약 5% 성능 상승

# 전체 특성 확장 진행

X_train.drop(['LSTAT X LSTAT', 'RM X RM'], axis=1, inplace=True)
X_test.drop(['LSTAT X LSTAT', 'RM X RM'], axis=1, inplace=True)
X_train.info() # 확장 컬럼 존재 확인
X_test.info() # 확장 컬럼 존재 확인
# 경고창 지우기

import warnings

warnings.filterwarnings('ignore')
# 기존 확장 특성을 지우고 반복문을 이용해서 전체 컬럼 특성 확장 진행

extend_X_train = X_train.copy()

for col1 in X_train.columns : # 13번 반복
    for col2 in X_train.columns : # 13번 반복
        extend_X_train[col1 + ' x ' + col2] = X_train[col1] * X_train[col2]
extend_X_test = X_test.copy()

for col1 in X_test.columns :
    for col2 in X_test.columns :
        extend_X_test[col1 + ' x ' + col2] = X_test[col1] * X_test[col2]
extend_X_train.info() # 컬럼이 너무 많아서 정보 생략

extend_X_test.info()

linear_model.fit(extend_X_train, y_train)

linear_model.score(extend_X_test, y_test)
# 74% -> 64%

linear_model.score(extend_X_train, y_train) # 과대적합

✅ 결과!

  • 특성이 너무 많아져서 과대적합에 걸렸다
  • 테스트 데이터에 제대로 반응하지 못하는 모습을 보이고 있다.
  • 선형회귀 모델은 과대적합을 제어할 수 있는 하이퍼 파라미터가 없다.
  • 하이퍼 파라미터 튜닝 역할을 대신해주는 규제 기능이 달린 모델을 사용해보자.

✅ 규제란?

 

'Machine Learning' 카테고리의 다른 글

Logistic Regression  (0) 2024.06.14
규제  (1) 2024.06.14