➕ Data Science/▹ ML

7. 보스턴주택가격예측

Ardor924 2025. 5. 15. 14:30

보스턴주택가격예측

1. 문제정의

🔶보스턴주택가격 데이터를 사용하여 집값을 예측하는 실습진행
🔶회귀모델 사용하기
🔶 LinearRegression , SGDRegression

2. 데이터수집

boston_housing.csv 파일 사용

📌fetch_openml : 사이킷런에서 제공하는 데이터셋 관련도구, DataFrame으로 변환하여 가져오는방법

컬럼설명

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

기술통계량 확인
![[Screenshot_276.png]]

--> 보아하니 수치가 들쭉날쭉 하기 때문에 스케일링이 필요

3. 전처리

Data Scaling

단위가 다 다를 경우에는 특성이 모델에 미치는 영향이 서로 달라지기때문에 사용

🔶Standard Scaler

  • 평균값에 얼마나 분산이 되어있는지를 단위로 변환하는 방법
  • 평균은 0. 분산은 1인 스케일로 변환
  • 즉 평균에 얼마나 멀리 떨어져있는가로 해서 판단

🔰주의! : 전처리 끝나고 하는것임

4. EDA

학습용으로 정제된 데이터라서 이번에는 생략

5. 모델링

# 선형회귀모델
linear_model = LinearRegression()

# 경사하강모델
sgd_model = SGDRegressor(eta0=4e-2,max_iter=5000,verbose=0,random_state=SEED)

6. 훈련

선형회귀모델

linear_model.fit(X_train,y_train)
r2_score = linear_model.score(X_test,y_test)

print(f'r2 score : {r2_score*100:.2f}%')

선형회귀모델

sgd_model.fit(X_train,y_train)

r2_score_SGD = sgd_model.score(X_test,y_test)
print(f'r2 score SGD : {r2_score_SGD*100:.2f}%')

7. 예측

선형모델

pred = linear_model.predict(X_test)
r2_score_test = linear_model.score(X_test,y_test)
mse_val = mean_squared_error(y_test,pred)
print(f'R2 score : {r2_score_test*100:.2f}%')
print(f'MSE : {mse_val:.2f}')

R2 score : 71.12%
MSE : 21.52

경사하강모델

pred = sgd_model.predict(X_test)
r2_score_test = sgd_model.score(X_test,y_test)
mse_val = mean_squared_error(y_test,pred)
print(f'R2 score : {r2_score_test*100:.2f}%')
print(f'MSE : {mse_val:.2f}')

R2 score : 71.22%
MSE : 21.44

---> 예측값이 높지는 않다.
---> 하이퍼파라미터 재설정 혹은 데이터 전처리를 다시 할필요가 있다.
---> 여기서는 데이터 전처리를 다시 해주도록 하자(피쳐 새로 추가)

3-2. 전처리

각 컬럼을 모두 곱한 값을 사용한 새로운 컬럼 생성

col = X.columns
for i in range(col.size):
    for j in range(i, col.size):
        X[col[i] + '*' + col[j]] = X[col[i]] * X[col[j]]

훈련용,테스트용 분할

X_train,X_test,y_train,y_test =  train_test_split(X_trans,y,test_size=0.3,random_state=32)#(,shuffle=True)
두번째 훈련및 예측 진행
linear_model2 = LinearRegression()
linear_model2.fit(X_train,y_train)

r2_score2 = linear_model2.score(X_test,y_test)

print(f'R2 score : {r2_score2*100:.2f}%')

R2 score : 86.91%

sgd_model2 = SGDRegressor(eta0=2e-2,max_iter=5000,verbose=0,shuffle=True,random_state=SEED)
sgd_model2.fit(X_train,y_train)

r2_score2 = sgd_model2.score(X_test,y_test)

print(f'R2 score : {r2_score2*100:.2f}%')

R2 score : 83.87%

--> 어느정도 정확도가 올라갔다.
---> 이대로 사용해도 될까?
훈련용,테스트용 분할

X_train,X_test,y_train,y_test =  train_test_split(X_trans,y,test_size=0.3,random_state=42)#(,shuffle=True)

R2 score : 66.10%

---> 하지만 Linear모델의 경우 SEED값만 변경해도 예측값이 들쑥날쑥하다.

---> 때문에 Linear모델의 경우 규제를 걸어줄 필요가 있다.

규제 : 선형모델에 가중치에 대해 영향을 주어서 잘 예측하지 못하는 모델이라면 규제를 통하여 모델성능 향상

🔶Ridge 모델 (Linear Regression L2규제를 가한 모델)

  • 모든 가중치에 특정 % 만큼의 규제를 가한다
  • 모든컬럼을 사용하기는 하지만 0이되는 컬럼은 없다.
  • 규제를 가하더라도, 전체 가중치를 전부 사용하기 때문에 전체 데이터가 주로 고루고루 중요할때 사용
  • 과대적합보다는 과소적합이거나 일반화에 가까울수록 많이 사용됨
  • ----> 특성별 중요도가 차이 없을때 사용(중요한 특정 컬럼이 없을때)

🔶Lasso 모델:(Linear Regression에 L1규제를 가한 모델)

  • 규제를 적용할수록 모델이 사용하는 특성의 수를 조절
  • 특정 데이터가 중요할 때 사용
  • 특성별로 중요도가 다를때, 특정 특성이 중요할 경우 가중치를 다르게 설정하여 특정 데이터가 중요하다 판단될때 사용
  • 가중치(기울기)가 0이되는 특성이 생셔서 특성 선택할때, 활용된다.
  • ----> 특성별 중요도가 다를때 사용(특정컬럼이 중요할때)

Ridge 모델사용

# 릿지
def ridge_alpha(alpha):
    # 모델생성
    ridge = Ridge(alpha=alpha)
    # 모델학습
    ridge.fit(X_train,y_train)
    # 훈련용 결과확인
    print("훈련결과 : ",ridge.score(X_train,y_train))
    # 테스트용 결과확인
    print("테스트 결과 : ",ridge.score(X_test,y_test))
ridge_alpha(0.1)

훈련결과 : 0.9402432727947878
테스트 결과 : 0.7352677202363309

alpha값을 증가시킬때는? => 규제를 늘리겠다.

  • 모델이 복잡해지는것을 막을때 사용(과대적합일때)

alpha값을 감소시킬때는? => 규제를 줄이겠다.

  • 모델이 단순해지는것을 막을때 사용(과소적합일때)

Lasso 모델사용

# 라쏘
def lasso_alpha(alpha):
    # 모델생성
    lasso = Lasso(alpha=alpha)
    # 모델학습
    lasso.fit(X_train,y_train)
    # 훈련용 결과확인
    print("훈련결과 : ",lasso.score(X_train,y_train))
    # 테스트용 결과확인
    print("테스트 결과 : ",lasso.score(X_test,y_test))
    print('사용한특성의수:',np.sum(lasso.coef_!=0))
lasso_alpha(1)    

훈련결과 : 0.735148659597438
테스트 결과 : 0.7001176175483983
사용한특성의수: 7

alpha값을 증가시킬때는? => 규제를 늘리겠다.

  • 모델이 복잡해지는것을 막을때 사용(과대적합일때)

alpha값을 감소시킬때는? => 규제를 줄이겠다.

  • 모델이 단순해지는것을 막을때 사용(과소적합일때)

---> alpha값=1 일때 사용한특성의수: 7개
---> alpha값=0.1 일때 사용한특성의수: 25개
---> alpha값=0.01 일때 사용한특성의수: 63개
---> alpha값=0.01 일때 사용한특성의수: 103개

🔰즉! alpha값으로 사용할 특성의 수를 조절할수있다.