AI/실습

127. [Python] [Multiple Linear Regression] : 병원 진료비 예측 (Regression)

천재단미 2025. 1. 28. 11:24
728x90
반응형

반응형

 

 

 

 

 

 

 

 

 

문제: 병원 진료비 예측 (Regression)

데이터 설명

 

시나리오

병원의 진료 데이터를 분석하여 환자의 기본 정보를 기반으로 진료비(InsuranceClaim)를 예측하려고 합니다.

환자의 나이, 성별, BMI, 지역, 흡연 여부, 병원 방문 횟수 등의 정보를 활용합니다.

 

 

데이터 피처

  1. Age: 환자 나이 (정수, 0~100, 일부 결측치 있음)
  2. Gender: 성별 (Male, Female)
  3. BMI: 체질량지수(Body Mass Index, 실수, 일부 결측치 있음)
  4. Region: 환자가 거주하는 지역 (North, South, East, West)
  5. Smoker: 흡연 여부 (Yes, No)
  6. NumVisits: 연간 병원 방문 횟수 (정수, 일부 결측치 있음)
  7. InsuranceClaim: 진료비 청구 금액(단위: 만원, 타깃 변수)

 

데이터 다운로드 링크

 
 

다음 조건에서 진료비를 예측하시오

나이는 45세, 남자이며, BMI 27.5 이고 East에 삽니다. 담배를 피고 연간 12번 병원을 방문합니다.

 

 

 

 

 

풀이 

 

 

1. 데이터 로드 및 탐색

 

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd


# 데이터 로드
df = pd.read_csv('healthcare.csv',index_col = 0)
df

 

 


 

 

 

 

 

2. 데이터 전처리

 

2-1. 결측치 확인

df.isnull().sum()

결측치가 있음을 확인합니다.

 

df.dropna(inplace=True)

결측치를 삭제하고 새로 저장합니다. 

 

 

 

 

 

2-2. 입력 데이터(X)와 출력 데이터(y) 분리

y = df['InsuranceClaim']
y
# 초기화 
y = y.reset_index(drop = True)

X = df.loc[ : ,'Age': 'NumVisits']
X = X.reset_index(drop = True)
X

 

 

 

 

 

2-3. 카테고리형 데이터를 숫자로 변환

from sklearn.preprocessing import OneHotEncoder
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import LabelEncoder

 

Gender,smoker, region 컬럼을 수치형으로 변환합니다.

encoder_gender = LabelEncoder()
X['Gender'] = encoder_gender.fit_transform(X['Gender'])
X['Gender']

 

encoder_Smoker = LabelEncoder()
X['Smoker'] = encoder_gender.fit_transform(X['Smoker'])
X['Smoker']

 

# 정렬
sorted(X['Region'].unique())

 

 

 

  TIP💡 

문자의 경우 정렬을 하여 순서를 맞춰주는게 좋습니다. 

 

ct = ColumnTransformer(  [ ( 'encoder',OneHotEncoder(), [ 3 ] )],remainder = 'passthrough')

# 형태변환
X = ct.fit_transform(X)
X

 

출력

: X[ 0, ]

 

 

  TIP💡 

 

Region =>  원핫인코딩의 경우 왼쪽에 배치한다.

[ ( 'encoder',OneHotEncoder(), [ 3 ] )]

                                                           <----- 왼쪽      |

Age,Gender, BMI, <East , North, South, West>,Region,Smoker,NumVisits

  0        1          2                                                             3

 

 

 

 

 


 

 

 

 

 

3. 데이터 분할 

 

3-1. 데이터 분할

데이터를 훈련 데이터와 테스트 데이터로 나눕니다.

from sklearn.model_selection import train_test_split

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

 

 

 

 

 

4. 모델 훈련

 

4-1. 모델 생성 및 훈련 (LinearRegression)

from sklearn.linear_model import LinearRegression

# 모델 생성
regressor1 = LinearRegression() 

# 모델 훈련
regressor1.fit(X_train, y_train)

 

4-2. 모델 생성 및 훈련 (RandomForestRegressor)

from sklearn.ensemble import RandomForestRegressor
regressor2 = RandomForestRegressor (random_state = 27, n_estimators = 500)
regressor2.fit(X_train, y_train)

 

 


 

 

 

 

5. 모델 평가

5-1. 예측 값 계산

y_pred = model.predict(X_test)

 

 

 

y_pred2 = regressor2.predict(X_test)

 

 

 

 

5-2. 모델 성능 평가

평가 지표로 R² 점수와 평균 절대 오차(MAE)를 사용합니다.

from sklearn.metrics import mean_squared_error, r2_score, mean_absolute_error

# R² 점수
r2_score(y_test, y_pred1)


# 평균 절대 오차
mean_absolute_error(y_test, y_pred1)

 

 

출력

0.8005907563032704
31.623996125704352

 

 

 

from sklearn.metrics import mean_squared_error, r2_score, mean_absolute_error

# R² 점수
r2_score(y_test, y_pred2)


# 평균 절대 오차
mean_absolute_error(y_test, y_pred2)

 

 

출력

0.7964251599341357
32.284611456250964

 

 

 

 

<    결   론   >

LinearRegression 가 RandomForestRegressor 보다 예측 값이 높은것을 확인할수 있습니다. 

 

 

 

 

XGBooster

 

현업에서 많이 사용하는 오류 예측 성능평가 

from xgboost import XGBRegressor

# learning_rate = 0.05 숫자가 적을수록 더 천천히 작업한다 n_estimators = 500,learning_rate = 0.01 조합을 많이 사용한다.
regressor3 = XGBRegressor(random_state = 27, n_estimators = 500,learning_rate = 0.01)

regressor3.fit(X_train, y_train)

# 예측 값 계산

y_pred3 = regressor3.predict(X_test)


# 모델 성능 평가
mean_absolute_error(y_test, y_pred2)

r2_score(y_test, y_pred2)

출력

4.355581737167886
0.7964251599341357

 

 

 


 

 

 

5. 결과 시각화

5-1. 실제 값 vs 예측 값

import matplotlib.pyplot as plt

plt.scatter(y_test, y_pred1, alpha=0.6)
plt.show()

 

 

import matplotlib.pyplot as plt

plt.scatter(y_test, y_pred2, alpha=0.6)
plt.show()

 

 

 

 

5-2. 잔차 분석

잔차는 예측 값과 실제 값의 차이입니다.

residuals1 = y_test - y_pred1

plt.hist(residuals1, bins=20, rwidth = 0.9)
plt.show()

 

residuals2 = y_test - y_pred2

plt.hist(residuals2, bins=20, rwidth = 0.9)
plt.show()

 

 

728x90
반응형
home top bottom
}