본문 바로가기

머신러닝

04. 지도 학습 (회귀) - 선형회귀 : 보험료 예측하기

[공부 자료 : Must Have 데싸노트의 실전에서 통하는 머신러닝]

# 선형 회귀 (Linear Regression)

- 선형 회귀

종속변수연속형 변수(키, 몸무게 등)일 때 사용되는 알고리즘

      종속형 변수 : 나이, 키, 몸무게, 만족도, 가격 등 연속적으로 이어지는 변수 (크고 작음, 사칙연산 등 O) → 회귀

      범주형 변수 : 성별, 혈액형, 계절 등 구별하기 위한 변수 (크고 작음, 사칙연산 등 X) → 분류

장점

      간단한 모델

      짧은 모델링 시간

단점

      낮은 예측력

      독립변수와 예측변수의 선형 관계를 전제로 하기 때문에, 해당 전제를 벗어나는 데이터는 예측하기 어렵다

- 손실 함수 (Loss Function)

손실 함수 : 예측값과 실제값의 차이 (오차) 를 평가하는 방법

      MSE, RMSE 등도 손실 함수

- 선형 회귀 모델

# 선형 회귀 - 보험료 예측하기

1- . 데이터 불러오기

import pandas as pd

file_url = 'https://media.githubusercontent.com/media/musthave-ML10/data_source/main/insurance.csv'
data = pd.read_csv(file_url)

- 2. 데이터 확인하기

info( ) : 데이터에 결측치가 있는가, 문자형 데이터가 있는가

describe( ) : 데이터의 min, max, mean 등을 확인

data.head()

data.info()
# 데이터에 null값이 있는가?
# 데이터에 int나 float가 아닌 다른 타입이 있는가?
# RangeIndex: 1338 entries, 0 to 1337
# Data columns (total 6 columns):
#  #   Column    Non-Null Count  Dtype  
# ---  ------    --------------  -----  
#  0   age       1338 non-null   int64  
#  1   sex       1338 non-null   int64  
#  2   bmi       1338 non-null   float64
#  3   children  1338 non-null   int64  
#  4   smoker    1338 non-null   int64  
#  5   charges   1338 non-null   float64

round(data.describe(), 2)

- 3. 데이터 전처리 : trian set, test set

데이터 클리닝 : 지저분한 데이터를 정리 (결측치 처리, 오탈자 수정, 불필요한 문자 제거 등)

피쳐 엔지니어링 : 주어진 독립변수를 활용하여 더 유용한 독립 변수를 생성

데이터 나누기 : 독립변수(X)와 종속변수(y)로 분리 → 각각을 train settest set으로 분리

      독립변수와 종속변수 : 지도 학습 모델은 독립변수를 통해 종속변수를 예측

      train set과 test set : 학습에 사용하는 데이터와 평가에 사용하는 데이터는 달라야 한다 (일반적으로 7:3 or 8:2)

# 독립변수
X = data[['age', 'sex', 'bmi', 'children', 'smoker']]
X

#  종속변수
y = data['charges']
y

# 왜 독립변수는 대문자이고, 종속변수는 소문자?
# 변수가 여러 개 있는 DataFrame은 대문자
# 변수가 하나인 Series는 소문자

sklearn-train_test_split 모듈을 이용하여 train set과 test set으로 나누기

      random sampling : 데이터를 특정 비율로 나눌 때 마구잡이로 뒤섞어서 나누는 것

            random sampling을 사용하지 않으면, 주어진 데이터의 앞에서부터 train set이 된다

            → 특정 기준에 따라 정렬된 데이터일 경우, 문제가 될 수 있다

            random sampling을 사용하면 무작위로 train set과 test set을 만든다

            → 학습을 할 때마다 다른 결과를 얻는다 

      train_test_split 모듈은 기본적으로 random sampling을 지원한다

            단, random_state에 동일한 숫자를 넣으면 학습을 할 때마다 동일한 결과를 얻는다

            (항상 train set과 test set에 동일한 데이터가 들어간다)

            random_state에 들어가는 숫자가 달라지면 학습의 결과가 달라진다

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 = 100) # train set 비중 0.8, test set 비중 0.2

- 4. 모델링

모델링 : 알고리즘을 이용하여 모델을 학습시켜 머신러닝 모델을 생성

      알고리즘 선택 

      모델 생성

      모델 학습

fit( ) : 학습 

      데이터를 모델 안에 넣어서 독립변수-종속변수 간의 관계를 분석 → 새로운 데이터를 예측할 수 있는 상태로 만든다

# 선형 회귀 알고리즘 가져오기
from sklearn.linear_model import LinearRegression

# 모델 만들기
model = LinearRegression()

# 모델 학습하기
model.fit(X_train, y_train) # fit(독립변수, 종속변수)

- 5. 예측하기

predict( ) : 독립변수의 test set (X_test) 를 활용하여 예측

pred = model.predict(X_test)

-- 6. 평가하기

평가 방법 : 종속변수의 test set(y_test) 과 독립변수의 test set의 예측값 (pred = model.predict(X_test)) 을 비교

      테이블로 평가

      그래프로 평가

      통계적 방법으로 평가

(1) 테이블로 평가

# 테이블로 평가하기
comparison = pd.DataFrame({'actual' : y_test, 'prediction' : pred})
comparison
# 	actual		prediction
# 12	1826.84300	4765.249466
# 306	20177.67113	4957.730865
# 318	7421.19455	8298.988153
# 815	1877.92940	3078.811868
# 157	15518.18025	24165.956542
# ...	...	...
# 713	1984.45330	5776.764928
# 1282	14283.45940	23102.847340
# 531	14043.47670	14280.732585
# 537	8825.08600	10527.417291
# 1015	12124.99240	11638.260006

(2) 그래프로 평가

import matplotlib.pyplot as plt
import seaborn as sns

plt.figure(figsize = (10, 10)) # 그래프의 크기 정의
sns.scatterplot(x = 'actual', y = 'prediction', data = comparison) # 산점도

(3) 통계적 방법으로 평가

- MAE (Mean Absloute Error, 평균 절대 오차)

      "예측값 - 실제값"의 절대값을 합산하여 평균 (0에 가까울수록 좋다)

- MSE (Mean Squared Error, 평균 제곱 오차)

      mean_squared_error(실제값, 예측값)

      "예측값 - 실제값"의 제곱을 합산하여 평균 (0에 가까울수록 좋다)

      오차가 클수록 더 큰 패널티를 줄 수 있다       

- RMSE (Root Mean Squared Error, 루트 평균 제곱 오차, 평균 제곱근 오차)

      mean_squared_error(실제값, 예측값, squared = False)

      mean_squared_error(실제값, 예측값) ** 0.5

      제곱으로 인해 값이 너무 커지는 것을 막아준다 (0에 가까울수록 좋다)

from sklearn.metrics import mean_squared_error # MSE 라이브러리

mean_squared_error(y_test, pred) # MSE : 32318403.822139356
mean_squared_error(y_test, pred, squared = False) # RMSE : 5684.927776334485

- R² 지표 : 독립변수로 설명되는 종속변수의 분산 비율

      score(독립변수, 종속변수)

      1에 가까울수록 좋은 모델

model.score(X_train, y_train) # R^2 지표 : 0.7368220127747351

model.score(X_test, y_test) # R^2 지표 : 0.7938983522335603

- 6. 선형 회귀 모델 분석

coef_ : 모델의 계수(w, weight, 가중치) 확인하기

# model의 계수
model.coef_
# array([2.64799803e+02, 1.73446608e+01, 2.97514806e+02, 4.69339602e+02,
#        2.34692802e+04])

pd.Series(model.coef_, index = X.columns)
# age           264.799803
# sex            17.344661
# bmi           297.514806
# children      469.339602
# smoker      23469.280173
# dtype: float64

intercept_ : 모델의 절편(b, bias) 확인하기

# model의 절편
model.intercept_
# -11576.999976112367

# 여러가지 선형 회귀 모델

- 릿지 회귀 (Ridge Regression)

선형 회귀 + L2 정규화 : 오버피팅 억제

from sklearn.linear_model import Ridge

- 라쏘 회귀 (Lasso Regression)

선형 회귀 + L1 정규화 : 피처 셀렉션 + 오버피팅 억제

from sklearn.linear_model import Lasso

- 엘라스틱 넷 (Elastic Net)

릿지 회귀와 라쏘 회귀의 단점을 절충

from sklearn.linear_model import ElasticNet