선형 회귀 모델을 사용해서 주택 임대료 예측해보기

1. 실습 주제

이 실습은 주택의 여러 속성을 바탕으로 월 임대료를 예측하는 회귀 문제를 다룬다.

예측 대상은 다음과 같다.

Rent

즉, 입력 변수로는 주택의 구조, 크기, 위치, 가구 상태, 선호 세입자 유형, 연락 방식 등이 사용되고,
출력은 해당 주택의 월 임대료이다.

전체 흐름은 다음과 같다.

데이터 로드
↓
데이터 구조 확인
↓
분포 및 이상치 탐색
↓
결측치 및 범주형 컬럼 확인
↓
불필요 컬럼 제거
↓
원-핫 인코딩
↓
학습 / 테스트 데이터 분리
↓
선형 회귀 학습
↓
이상치 제거 후 재학습
↓
로그 변환 적용
↓
앙상블 모델 비교

2. 데이터셋 컬럼 정리

이 데이터셋의 주요 컬럼은 다음과 같다.

컬럼명 의미
BHK 침실, 거실, 주방 등을 포함한 주택 구성 개수
Rent 월 임대료
Size 주택 면적
Floor 현재 층수와 전체 층수 정보
Area Type 면적 산정 방식
Area Locality 상세 지역 정보
City 도시
Furnishing Status 가구 구비 상태
Tenant Preferred 선호 세입자 유형
Bathroom 욕실 수
Point of Contact 연락 담당 방식
Posted On 게시 날짜

이 중에서 목표 변수는 Rent이고, 나머지는 예측을 위한 독립변수로 사용된다.


3. 라이브러리 불러오기

실습에서는 NumPy, Pandas, Seaborn을 먼저 불러온다.

import numpy as np
import pandas as pd
import seaborn as sns

각 라이브러리의 역할은 다음과 같다.

  • NumPy: 수치 연산과 로그 변환, 역변환 처리
  • Pandas: 데이터프레임 기반 데이터 처리
  • Seaborn: 분포와 이상치 시각화

4. pd.read_csv()

개요

pd.read_csv()는 CSV 파일을 읽어 Pandas DataFrame으로 변환하는 함수이다.
실습에서는 주택 임대료 데이터셋을 메모리로 불러오는 시작점으로 사용된다.


실습 코드

rent_df = pd.read_csv('/content/drive/MyDrive/.../House_Rent_Dataset.csv')
rent_df

주요 역할

  • CSV 파일을 데이터프레임으로 변환
  • 이후 EDA, 전처리, 모델 학습의 입력 데이터 준비
  • 표 형태의 원본 데이터를 Pandas 객체로 다룰 수 있게 함

주요 파라미터

파라미터 설명
filepath_or_buffer 읽을 파일 경로
sep 구분자
header 컬럼명 위치
encoding 인코딩 방식

반환값

pandas.DataFrame

ai가 추천하는 심화 예제

df = pd.read_csv("House_Rent_Dataset.csv")

print(df.shape)

# 결과
# (행 개수, 열 개수)

5. DataFrame.info()

개요

info()는 데이터프레임의 전체 구조를 요약해서 보여주는 메서드이다.

확인 가능한 정보는 다음과 같다.

  • 전체 행 수
  • 컬럼 수
  • 각 컬럼의 non-null 개수
  • 데이터 타입
  • 메모리 사용량

실습에서는 데이터 로드 직후 구조를 점검하고, 결측치 여부를 빠르게 확인하는 데 사용된다.


실습 코드

rent_df.info()

주요 역할

  • 결측치 존재 여부 확인
  • 수치형과 문자형 컬럼 구분
  • 전처리 방향 결정
  • 불필요 컬럼 제거 전 구조 파악

반환값

None

출력 전용 메서드이기 때문에 별도 객체를 반환하지 않는다.


ai가 추천하는 심화 예제

print(rent_df.dtypes)

# 결과
# 각 컬럼의 자료형 출력

6. DataFrame.describe() 와 round()

개요

describe()는 수치형 컬럼에 대한 기초 통계량을 반환하는 메서드이다.
평균, 표준편차, 최솟값, 분위수, 최댓값 등을 한 번에 확인할 수 있다.

실습에서는 describe() 결과를 그대로 확인한 뒤,
round()를 함께 사용해 소수점 둘째 자리까지 보기 좋게 정리한다.


실습 코드

rent_df.describe()
round(rent_df.describe(), 2)

주요 역할

  • 수치형 데이터의 분포 파악
  • 변수별 범위 확인
  • 이상치 후보 탐색
  • 데이터 스케일 감각 확인

describe() 반환값

pandas.DataFrame

round() 반환값

pandas.DataFrame

ai가 추천하는 심화 예제

print(rent_df["Rent"].describe())

# 결과
# Rent 컬럼의 통계량만 출력

7. Series 선택과 sort_values()

개요

특정 컬럼 하나를 선택하면 Pandas Series 형태로 다룰 수 있다.
실습에서는 BHK와 Rent 컬럼을 직접 확인하고,
Rent 값은 sort_values()로 정렬하여 임대료 분포와 이상치 가능성을 점검한다.


실습 코드

rent_df['BHK']
rent_df['Rent'].sort_values()

주요 역할

  • 특정 컬럼만 개별적으로 확인
  • 임대료 값의 정렬 상태 확인
  • 극단적으로 큰 값 존재 여부 탐색

sort_values() 반환값

pandas.Series

ai가 추천하는 심화 예제

print(rent_df["Rent"].sort_values(ascending=False).head(10))

# 결과
# 임대료가 높은 상위 10개 값 출력

8. sns.displot()

개요

displot()은 변수의 분포를 시각화하는 함수이다.
히스토그램 기반으로 값이 어떤 구간에 많이 몰려 있는지 확인할 수 있다.

실습에서는 다음 변수들의 분포를 확인한다.

  • BHK
  • Rent
  • Size

실습 코드

sns.displot(rent_df['BHK'])
sns.displot(rent_df['Rent'])
sns.displot(rent_df['Size'])

주요 역할

  • 각 변수의 분포 형태 확인
  • 치우친 분포 여부 확인
  • 이상치 존재 가능성 탐색
  • 로그 변환 필요성 판단

반환값

seaborn.axisgrid.FacetGrid

해석 포인트

임대료와 면적처럼 오른쪽으로 긴 꼬리를 가진 분포는
큰 값이 일부 존재해 평균과 회귀 모델에 강하게 영향을 줄 수 있다.

이런 경우 로그 변환이 도움이 될 수 있다.


ai가 추천하는 심화 예제

sns.displot(rent_df["Bathroom"])

# 결과
# 욕실 수 분포 시각화

9. boxplot과 sns.boxplot()

개요

박스플롯은 데이터의 중앙값, 사분위수, 이상치를 시각적으로 표현하는 그래프이다.
실습 노트북에서는 박스플롯의 기본 개념을 먼저 정리한 뒤 실제 데이터에 적용한다.

박스플롯에서 중요한 개념은 다음과 같다.

  • 중앙값: 데이터를 크기순으로 정렬했을 때 가운데 값

  • Q1: 하위 25% 지점

  • Q3: 상위 75% 지점

  • IQR: Q3 - Q1

  • 이상치 기준:

    [
    \text{Lower Bound} = Q1 - 1.5 \times IQR
    ]

    [
    \text{Upper Bound} = Q3 + 1.5 \times IQR
    ]

이 범위를 벗어나는 값은 일반적으로 이상치로 본다.


실습 코드

sns.boxplot(rent_df['Rent'])
sns.boxplot(rent_df['Size'])
sns.boxplot(rent_df['BHK'])

주요 역할

  • 중앙값과 분포 범위 확인
  • 이상치 확인
  • 분포의 비대칭성 확인
  • 이후 이상치 제거 여부 판단

반환값

matplotlib.axes.Axes

ai가 추천하는 심화 예제

sns.boxplot(x=rent_df["Bathroom"])

# 결과
# 욕실 수의 이상치 여부 시각화

10. isna(), sum(), mean()

개요

isna()는 결측치 여부를 True 또는 False로 반환한다.
여기에 sum()을 적용하면 결측치 개수, mean()을 적용하면 결측치 비율을 구할 수 있다.


실습 코드

rent_df.isna().sum()
rent_df.isna().mean()

주요 역할

  • 컬럼별 결측치 개수 확인
  • 컬럼별 결측치 비율 확인
  • 결측치 처리 필요성 판단

반환값

pandas.Series

ai가 추천하는 심화 예제

na_ratio = rent_df.isna().mean().sort_values(ascending=False)
print(na_ratio)

# 결과
# 결측치 비율이 높은 순서대로 출력

11. unique(), nunique(), select_dtypes()

개요

범주형 변수의 종류와 개수를 확인하기 위해 unique(), nunique(), select_dtypes()가 사용된다.

unique()

해당 컬럼이 실제로 어떤 값을 가지는지 배열 형태로 반환한다.

nunique()

해당 컬럼의 고유값 개수를 반환한다.

select_dtypes(include='object')

문자열 타입 컬럼만 선택한다.


실습 코드

rent_df['Area Type'].unique()
rent_df['Area Type'].nunique()
for i in ['Floor','Area Type','Area Locality', 'City', 'Furnishing Status', 'Tenant Preferred', 'Point of Contact']:
    print(i, rent_df[i].nunique())
obj_cols = rent_df.select_dtypes(include='object').columns
for col in obj_cols:
    print(col, rent_df[col].nunique())

주요 역할

  • 범주형 변수 종류 파악
  • 고유값이 지나치게 많은 컬럼 탐색
  • 인코딩 전 처리 전략 결정
  • 제거할 컬럼 후보 탐색

반환값

  • unique() → NumPy 배열
  • nunique() → 정수
  • select_dtypes() → DataFrame

해석 포인트

고유값 개수가 지나치게 많은 컬럼은
원-핫 인코딩 시 차원이 과도하게 커질 수 있다.

이 실습에서는 Floor, Posted On, Area Locality를 제거하는 방향으로 정리한다.


ai가 추천하는 심화 예제

obj_cols = rent_df.select_dtypes(include='object').columns
print(obj_cols.tolist())

# 결과
# 문자열형 컬럼 목록 출력

12. drop()

개요

drop()은 특정 행이나 열을 제거하는 메서드이다.
실습에서는 모델에 직접 넣기 어려운 컬럼이나 고유값이 너무 많은 컬럼을 제거하는 데 사용된다.

제거된 컬럼은 다음과 같다.

  • Floor
  • Posted On
  • Area Locality

Floor는 층수 정보가 문자열 형태이고,
Posted On은 날짜 문자열이며,
Area Locality는 지역 종류가 너무 많아 원-핫 인코딩 시 차원이 과도하게 커질 수 있다.


실습 코드

rent_df.drop(['Floor','Posted On', 'Area Locality'], axis=1, inplace=True)

주요 역할

  • 불필요한 컬럼 제거
  • 모델 입력 단순화
  • 고차원 희소 행렬 문제 완화
  • 전처리 부담 감소

주요 파라미터

파라미터 설명
labels 삭제할 행 또는 열
axis 0은 행, 1은 열
inplace 원본을 직접 수정할지 여부

반환값

inplace=True일 때는 반환값이 없다.

None

ai가 추천하는 심화 예제

reduced_df = rent_df.drop(["City"], axis=1)

print(reduced_df.head())

# 결과
# City 컬럼이 제거된 데이터프레임 출력

13. pd.get_dummies()

개요

pd.get_dummies()는 범주형 변수를 원-핫 인코딩하는 함수이다.
문자열 범주를 0과 1의 여러 컬럼으로 분리하여 수치형 모델에 넣을 수 있게 만든다.

실습에서는 object 타입 컬럼 전체를 인코딩한다.


실습 코드

rent_df = pd.get_dummies(rent_df, columns=rent_df.select_dtypes(include='object').columns)
rent_df

주요 역할

  • 범주형 데이터를 수치형으로 변환
  • 선형 회귀, 랜덤 포레스트, XGBoost 등에 입력 가능하도록 준비
  • 범주 정보를 유지한 채 모델 학습 가능 상태로 변경

주요 파라미터

파라미터 설명
data 대상 데이터프레임
columns 인코딩할 컬럼 목록
drop_first 첫 번째 범주 제거 여부

반환값

pandas.DataFrame

ai가 추천하는 심화 예제

encoded_df = pd.get_dummies(rent_df, columns=["City"])

print(encoded_df.head())

# 결과
# City가 여러 더미 컬럼으로 변환됨

14. Feature와 Label 분리

개요

머신러닝에서는 입력 데이터와 정답 데이터를 분리해야 한다.

  • X: 입력 데이터
  • y: 정답 데이터

이 실습에서는 Rent가 목표 변수이므로,
X에서는 Rent를 제거하고 y에는 Rent만 저장한다.


실습 코드

X = rent_df.drop('Rent', axis=1)
y = rent_df['Rent']
X.head()
y.head()

주요 역할

  • 독립변수와 목표변수 분리
  • 모델 입력 형식 구성
  • train_test_split 전처리 준비

ai가 추천하는 심화 예제

print(X.shape)
print(y.shape)

# 결과
# X와 y의 크기 확인

15. train_test_split()

개요

train_test_split()은 데이터를 학습용과 테스트용으로 나누는 함수이다.

모델은 학습 데이터로 훈련하고,
테스트 데이터로 실제 예측 성능을 평가한다.

실습에서는 test_size를 0.3으로 설정하여 전체 데이터의 30%를 테스트셋으로 사용한다.


실습 코드

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=2026)
X_train.shape, X_test.shape
y_train.shape, y_test.shape

주요 역할

  • 데이터 분리
  • 과적합 여부 점검
  • 재현 가능한 실험 환경 구성

주요 파라미터

파라미터 설명
X 입력 데이터
y 정답 데이터
test_size 테스트 데이터 비율
random_state 난수 시드

반환값

X_train, X_test, y_train, y_test

ai가 추천하는 심화 예제

print(len(X_train), len(X_test))

# 결과
# 학습 데이터 개수와 테스트 데이터 개수 출력

16. 선형 회귀 이론

개요

선형 회귀는 입력 변수와 목표 변수 사이의 선형 관계를 학습하는 대표적인 회귀 알고리즘이다.

기본 형태는 다음과 같다.

[
y = w_1x_1 + w_2x_2 + \cdots + b
]

여기서 각 가중치와 절편은 예측값과 실제값 사이의 오차가 가장 작아지도록 결정된다.


최소제곱법

사이킷런의 선형 회귀는 최소제곱법을 기반으로 학습한다.

최소제곱법은 잔차의 제곱합을 최소화하는 방식으로 최적의 직선을 찾는 방법이다.

잔차는 다음과 같이 정의할 수 있다.

[
\text{Residual} = y - \hat{y}
]

그리고 모델은 다음 값을 최소화하려고 한다.

[
SSE = \sum (y_i - \hat{y}_i)^2
]

실습에 사용된 LinearRegression은 내부적으로 수치적으로 더 안정적인 SVD 기반 계산을 사용한다.


17. LinearRegression(), fit(), predict()

개요

LinearRegression()은 선형 회귀 모델 객체를 생성하고,
fit()은 학습 데이터를 사용해 모델을 학습시키며,
predict()는 학습된 모델로 테스트 데이터의 예측값을 만든다.


실습 코드

from sklearn.linear_model import LinearRegression
lr = LinearRegression()
lr.fit(X_train, y_train)
pred = lr.predict(X_test)

각 메서드의 역할

LinearRegression()

선형 회귀 모델 생성

fit(X_train, y_train)

학습 데이터와 실제 임대료를 이용해 회귀계수와 절편을 학습

predict(X_test)

테스트 데이터에 대한 예측 임대료 생성


반환값

  • LinearRegression() → 모델 객체
  • fit() → self
  • predict() → NumPy 배열

ai가 추천하는 심화 예제

lr = LinearRegression()
lr.fit(X_train, y_train)

print(lr.coef_)
print(lr.intercept_)

# 결과
# 각 feature의 계수와 절편 출력

18. mean_squared_error() 와 root_mean_squared_error()

개요

회귀 문제에서는 예측값과 실제값의 차이를 측정하기 위해 오차 지표를 사용한다.

mean_squared_error()

오차를 제곱해서 평균낸 값

[
MSE = \frac{1}{n}\sum (y_i - \hat{y}_i)^2
]

root_mean_squared_error()

MSE에 제곱근을 적용한 값

[
RMSE = \sqrt{\frac{1}{n}\sum (y_i - \hat{y}_i)^2}
]

RMSE는 원래 타깃 변수와 같은 단위를 가지므로 해석이 더 직관적이다.


실습 코드

from sklearn.metrics import mean_squared_error, root_mean_squared_error
print(mean_squared_error(y_test, pred))
print(root_mean_squared_error(y_test, pred))

주요 역할

  • 회귀 모델 성능 측정
  • 예측 오차의 크기 확인
  • 모델 간 성능 비교

반환값

float

ai가 추천하는 심화 예제

mse = mean_squared_error(y_test, pred)
rmse = root_mean_squared_error(y_test, pred)

print(mse)
print(rmse)

# 결과
# MSE와 RMSE 출력

19. 특정 행 조회와 이상치 제거

개요

실습에서는 학습 데이터 중 특정 인덱스 1837에 해당하는 샘플을 직접 확인한 뒤 제거한다.

이 과정은 모델 성능에 큰 영향을 주는 특이 샘플이나 이상치를 점검하는 흐름으로 볼 수 있다.


실습 코드

X_train.loc[1837]
y_train.loc[1837]
X_train.drop(1837, inplace=True)
y_train.drop(1837, inplace=True)

주요 역할

  • 특정 이상치 샘플 직접 확인
  • 이상치 제거 후 모델 재학습
  • RMSE 개선 여부 확인

ai가 추천하는 심화 예제

print(X_train.shape)
print(y_train.shape)

# 결과
# 이상치 제거 후 학습 데이터 크기 확인

20. 이상치 제거 후 선형 회귀 재학습

개요

이상치 제거 후 동일한 선형 회귀 모델을 다시 학습시키고 RMSE를 재계산한다.
이 과정은 특정 극단값이 회귀 모델에 얼마나 큰 영향을 주는지 확인하는 좋은 예시이다.


실습 코드

lr = LinearRegression()
lr.fit(X_train, y_train)
new_pred = lr.predict(X_test)
root_mean_squared_error(y_test, new_pred)

주요 역할

  • 이상치 제거 효과 확인
  • 선형 회귀 민감도 점검
  • 전처리의 성능 개선 여부 검증

ai가 추천하는 심화 예제

old_rmse = root_mean_squared_error(y_test, pred)
new_rmse = root_mean_squared_error(y_test, new_pred)

print(old_rmse, new_rmse)

# 결과
# 이상치 제거 전후 RMSE 비교

21. 로그 변환의 개념

개요

임대료 데이터는 보통 오른쪽으로 긴 꼬리를 가진 분포를 보인다.
즉, 대부분은 비교적 낮은 임대료 구간에 몰려 있고 일부 값은 매우 크게 튀는 구조를 가진다.

이런 데이터에 그대로 선형 회귀를 적용하면 큰 임대료 값들이 손실에 과도한 영향을 줄 수 있다.
이를 완화하기 위해 로그 변환을 사용한다.

로그 변환의 장점은 다음과 같다.

  • 큰 값의 범위를 축소
  • 왜곡된 분포를 더 완만하게 만듦
  • 이상치 영향 감소
  • 정규 분포에 가까운 형태 유도
  • RMSE 개선 가능

정규 분포

정규 분포는 평균을 중심으로 좌우 대칭인 종 모양 분포이다.
많은 통계 모델은 데이터가 정규 분포에 가까울수록 더 안정적으로 작동한다.


데이터 변환의 핵심 의미

로그 변환은 데이터의 절대 차이보다 비율 차이에 더 집중하게 만든다.

예를 들어 원본 값이 다음과 같을 때

  • 1,000
  • 10,000
  • 100,000

로그 변환 후에는 큰 값들 사이의 차이가 압축된다.
값은 바뀌지만, 값 사이의 관계 자체가 사라지는 것은 아니다.

모델은 변환된 데이터로 학습하고, 최종 예측은 다시 원래 스케일로 되돌린다.


22. np.log1p() 와 np.expm1()

개요

로그 변환과 역변환에는 NumPy의 log1p와 expm1이 사용된다.

np.log1p(x)

[
\log(1 + x)
]

0이 포함된 데이터에도 안전하게 로그를 적용할 수 있다.

np.expm1(x)

[
e^x - 1
]

log1p로 변환한 값을 원래 스케일로 복원할 때 사용한다.


실습 코드

y_train = np.log1p(y_train)
y_test = np.log1p(y_test)
lr = LinearRegression()
lr.fit(X_train,y_train)
y_pred_log = lr.predict(X_test)
log_pred = np.expm1(y_pred_log)
y_test_original = np.expm1(y_test)
root_mean_squared_error(y_test_original, log_pred)

주요 역할

  • 타깃 값 분포 압축
  • 큰 임대료 값의 영향 완화
  • 예측 후 원래 임대료 단위로 복원

반환값

  • log1p() → NumPy 배열 또는 Series
  • expm1() → NumPy 배열 또는 Series

ai가 추천하는 심화 예제

sample = np.array([1000, 10000, 100000])

log_sample = np.log1p(sample)
restored = np.expm1(log_sample)

print(log_sample)
print(restored)

# 결과
# 로그 변환 값과 원래 값 복원 결과 출력

23. 앙상블 모델 개념

개요

앙상블 모델은 여러 개의 모델을 결합해 하나의 더 강한 예측 모델을 만드는 방식이다.

대표적인 장점은 다음과 같다.

  • 개별 모델의 약점 보완
  • 예측 안정성 향상
  • 성능 향상 가능
  • 복잡한 데이터 패턴 학습 가능

대표적인 앙상블 방식은 다음과 같다.

  • 배깅
  • 부스팅
  • 스태킹

이 실습에서는 랜덤 포레스트와 XGBoost를 비교한다.


24. RandomForestRegressor()

개요

랜덤 포레스트는 여러 개의 결정트리를 결합한 회귀 앙상블 모델이다.
각 트리는 무작위로 선택된 데이터와 특성을 이용해 학습되며,
회귀 문제에서는 여러 트리의 예측 평균을 최종 출력으로 사용한다.

장점은 다음과 같다.

  • 과적합 완화
  • 비선형 관계 학습 가능
  • 이상치에 비교적 강함
  • 변수 중요도 제공

실습 코드

from sklearn.ensemble import RandomForestRegressor
'Random Forest': RandomForestRegressor(n_estimators=100, random_state=2026)

주요 파라미터

파라미터 설명
n_estimators 트리 개수
random_state 난수 고정
max_depth 각 트리의 최대 깊이

ai가 추천하는 심화 예제

rf = RandomForestRegressor(n_estimators=200, random_state=2026)
rf.fit(X_train, y_train)

pred_rf = rf.predict(X_test)
print(root_mean_squared_error(y_test, pred_rf))

# 결과
# 랜덤 포레스트 RMSE 출력

25. XGBRegressor()

개요

XGBoost는 Gradient Boosting 계열의 강력한 앙상블 모델이다.
여러 약한 학습기를 순차적으로 학습시키면서, 앞선 모델의 오차를 뒤의 모델이 보정하는 방식으로 성능을 끌어올린다.

장점은 다음과 같다.

  • 높은 예측 성능
  • 복잡한 비선형 패턴 학습
  • 과적합 제어 기능
  • 대규모 데이터셋에서 강력한 성능

실습 코드

from xgboost import XGBRegressor
'XGBoost': XGBRegressor(n_estimators=100, random_state=2026)

주요 파라미터

파라미터 설명
n_estimators 부스팅 단계 수
random_state 난수 고정
max_depth 트리 깊이
learning_rate 학습률

ai가 추천하는 심화 예제

xgb = XGBRegressor(n_estimators=200, random_state=2026)
xgb.fit(X_train, y_train)

pred_xgb = xgb.predict(X_test)
print(root_mean_squared_error(y_test, pred_xgb))

# 결과
# XGBoost RMSE 출력

26. 여러 모델을 딕셔너리로 관리하기

개요

실습에서는 여러 모델을 딕셔너리에 넣고 반복문으로 한 번에 학습과 평가를 수행한다.
이 방식은 모델 비교 실험을 깔끔하게 정리할 때 매우 유용하다.


실습 코드

models = {
    'Linear Regression': LinearRegression(),
    'Random Forest': RandomForestRegressor(n_estimators=100, random_state=2026),
    'XGBoost': XGBRegressor(n_estimators=100, random_state=2026)
}

주요 역할

  • 여러 모델을 한 구조에 저장
  • 반복문으로 일괄 학습 및 평가
  • 실험 코드 단순화

ai가 추천하는 심화 예제

for name, model in models.items():
    print(name, type(model))

# 결과
# 모델 이름과 객체 타입 출력

27. 반복문 기반 모델 평가

개요

실습에서는 for 문을 사용해 모델별로 학습, 예측, RMSE 계산을 자동화한다.

먼저 로그 변환된 타깃으로 학습한 경우를 비교하고,
그 다음에는 로그 변환을 제거한 원본 타깃 기준으로 다시 비교한다.


로그 변환 상태에서의 비교 코드

results = {}
for model_name , model in models.items():
    model.fit(X_train,y_train)
    y_pred_log = model.predict(X_test)

    y_pred = np.expm1(y_pred_log)
    y_test_original = np.expm1(y_test)

    rmse = np.sqrt(mean_squared_error(y_test_original, y_pred))
    results[model_name] = rmse
    print(f'{model_name} RMSE: {rmse:.2f}')

best_model = min(results, key=results.get)
print(f'Best Model: {best_model} RMSE: {results[best_model]:.2f}')

원본 타깃 기준 비교 코드

X_train, X_test, y_train, y_test = train_test_split(X, y,
                                                    test_size=0.3,
                                                    random_state=2025)

results = {}
for model_name, model in models.items():
    model.fit(X_train, y_train)
    y_pred = model.predict(X_test)

    rmse = root_mean_squared_error(y_test, y_pred)
    results[model_name] = rmse
    print(f'{model_name} RMSE: {rmse:.2f}')

best_model = min(results, key=results.get)
print(f'Best Model: {best_model} RMSE: {results[best_model]:.2f}')

주요 역할

  • 모델별 학습 자동화
  • RMSE 결과 저장
  • 최고 성능 모델 선택
  • 실험 결과 표준화

사용된 핵심 메서드

items()

딕셔너리의 키와 값을 함께 순회

min(results, key=results.get)

RMSE가 가장 작은 모델 이름 선택


ai가 추천하는 심화 예제

best_model = min(results, key=results.get)
print(best_model)
print(results[best_model])

# 결과
# 가장 좋은 모델 이름과 RMSE 출력

28. 실습 전체 흐름 요약

pd.read_csv()
↓
info()
↓
describe() / round()
↓
Series 선택 / sort_values()
↓
sns.displot()
↓
sns.boxplot()
↓
isna().sum() / isna().mean()
↓
unique() / nunique() / select_dtypes()
↓
drop()
↓
pd.get_dummies()
↓
X, y 분리
↓
train_test_split()
↓
LinearRegression()
↓
fit() / predict()
↓
mean_squared_error() / root_mean_squared_error()
↓
이상치 제거 후 재학습
↓
np.log1p() / np.expm1()
↓
LinearRegression 재평가
↓
RandomForestRegressor() / XGBRegressor()
↓
반복문 기반 모델 비교