본문 바로가기

Python/Machine Learning

<파이썬 머신러닝> 선형 회귀(Linear Regression)

선형 회귀란 무엇인가?

선형 회귀는 간단히 말해서, 한 가지 변수가 다른 변수에 어떤 영향을 주는지 알아보는 방법이다. 예를 들어, 카드 한도를 정하는 기준을 만들기 위해서는, 소득 수준이 어떤 영향을 미치는지 알아볼 수 있다. 아래 그래프는 카드사용량과 소득 수준 간의 상관관계를 보여주는 산점도이다.

 

 

 

고객 B와 고객A의 소득 수준에 따른 카드 사용량

아래 그림을 보면 대부분의 고객들이 소득 수준에 따라 소득이 높을 수록 카드 사용량이 많아지고, 소득 수준이 낮을 수록 카드 사용량이 적어지는 선형적인 모습을 보인다.

 

 

고객 B와 고객 A의 소득 수준과 카드 사용량에 따른 카드 한도

소득 수준과 카드 사용량은 종속 변수와 독립 변수로 사용될 수 있다. 이러한 변수들을 활용해 선형 회귀 기법을 사용하여 카드 한도를 결정하는 기준을 만들 수 있다. 이 방법을 사용하여, 고객 A의 카드 한도는 1000만원으로, 고객 B의 카드 한도는 100만원으로 결정되었다.

 

 

 y = ax + b 공식

y = ax + b 공식은 선형 회귀에서 사용하는 방정식이다. 이 방정식은 자료를 통해 구한 두 변수(독립 변수 x와 종속 변수 y) 간의 관계를 나타낼 수 있다. 이 경우 y는 종속 변수이며, x는 독립 변수이다. b는 y절편이며, x가 0일 때 y의 값이다. a는 x의 계수이며, x가 1 증가할 때마다 y가 a만큼 증가한다. 예를 들어, x가 2일 때 y = 3x + 1 이라면, y는 3 * 2 + 1로 계산되어 7이 됩니다.

이 공식을 사용하여 두 변수 간의 관계를 계산할 수 있다. 기본적인 카드 한도는 50만원으로 설정하고, 고객의 수준이 100만원 증가할 때마다 30만원씩 한도를 높이는 것을 전제로 한다. 만약 고객의 소득 수준 x가 1,000만원이라면, 카드 한도 y는 30 * 10 + 50이 된다. 이 공식을 사용하여 기본적인 카드 한도를 설정하고, 소득 수준이 100만원씩 증가할 때마다 30만원씩 더 높이는 방식으로 카드 한도를 결정할 수 있다.

 

 

 

 카드 한도 테이블

선형 회귀를 사용하여 카드 한도 테이블을 만들 수 있다.

 

 

파이썬을 활용한 선형 회귀 실습 (50cm의 농어 예측)

50cm의 농어는 어떻게 예측을 하게 될지 한번 알아보자.

아래 코드는 데이터 분석과 머신러닝을 위한 파이썬 라이브러리를 import하고 있다. 이 중 numpy와 matplotlib는 데이터 처리와 시각화를 위한 라이브러리이고, sklearn.model_selection, sklearn.neighbors, sklearn.metrics, sklearn.linear_model은 머신러닝 모델링을 위한 라이브러리이다. 해당 코드에서는 KNeighborsRegressor와 LinearRegression 머신러닝 모델을 사용할 수 있다.

>>> import numpy as np
>>> import matplotlib.pyplot as plt
>>> from sklearn.model_selection import train_test_split
>>> from sklearn.neighbors import KNeighborsRegressor
>>> from sklearn.metrics import mean_absolute_error
>>> from sklearn.linear_model import LinearRegression

 

 

k-최근접 이웃을 사용한 50cm 농어의 무게 예측

>>> perch_length = np.array([8.4, 13.7, 15.0, 16.2, 17.4, 18.0, 18.7, 19.0, 19.6, 20.0, 21.0,
       21.0, 21.0, 21.3, 22.0, 22.0, 22.0, 22.0, 22.0, 22.5, 22.5, 22.7,
       23.0, 23.5, 24.0, 24.0, 24.6, 25.0, 25.6, 26.5, 27.3, 27.5, 27.5,
       27.5, 28.0, 28.7, 30.0, 32.8, 34.5, 35.0, 36.5, 36.0, 37.0, 37.0,
       39.0, 39.0, 39.0, 40.0, 40.0, 40.0, 40.0, 42.0, 43.0, 43.0, 43.5,
       44.0])
>>> perch_weight = np.array([5.9, 32.0, 40.0, 51.5, 70.0, 100.0, 78.0, 80.0, 85.0, 85.0, 110.0,
       115.0, 125.0, 130.0, 120.0, 120.0, 130.0, 135.0, 110.0, 130.0,
       150.0, 145.0, 150.0, 170.0, 225.0, 145.0, 188.0, 180.0, 197.0,
       218.0, 300.0, 260.0, 265.0, 250.0, 250.0, 300.0, 320.0, 514.0,
       556.0, 840.0, 685.0, 700.0, 700.0, 690.0, 900.0, 650.0, 820.0,
       850.0, 900.0, 1015.0, 820.0, 1100.0, 1000.0, 1100.0, 1000.0,
       1000.0])

perch_lengthperch_weight는 농어의 길이와 무게 데이터를 담고 있는 넘파이 배열이다. 넘파이 배열은 파이썬에서 사용되는 배열이다. 넘파이를 사용하면 다차원 배열을 쉽게 다룰 수 있다. 넘파이 배열은 파이썬 리스트와 비슷하지만, 더 빠르고 메모리를 효율적으로 사용한다.

 

 

train/test set 생성

>>> train_input, test_input, train_target, test_target = train_test_split(
         perch_length, perch_weight, random_state=42)

>>> train_input = train_input.reshape(-1,1)
>>> test_input = test_input.reshape(-1,1)

위 코드는 농어의 길이와 무게 데이터를 훈련 세트와 테스트 세트로 나누는 과정이다. 훈련 세트와 테스트 세트로 나뉘어진 데이터는 입력값인 농어의 길이를 나타내는 train_inputtest_input 배열과 농어의 무게를 나타내는 train_targettest_target 배열로 저장된다. reshape() 함수를 이용해 이후 머신 러닝 알고리즘에 사용하기 적합한 형태로 변환된다.

 

 

선형회귀

선형회귀 모델을 훈련해보자.

이제 선형 회귀에 대해 알아보겠다. 선형 회귀는 특성을 잘 나타낼 수 있는 직선을 학습하는 알고리즘이다. 각 점들의 집합에서 y = a * x + b를 찾아내는 과정이다. 더 자세한 정보는 구글을 참고하자. 사이킷런은 sklearn.linear_model 패키지 아래의 LinearRegression 클래스를 사용하여 농어에 대한 선형 회귀를 진행해보겠다.

>>> lr = LinearRegression()

# 선형회귀 모델 훈련
>>> lr.fit(train_input, train_target)

LinearRegression()

 

길이가 50일때, 몸무게가 몇인가? 예측을 해보자.

>>> print(lr.predict([[50]]))
[1241.83860323]

 

lr.coef는 기울기, lr.intercept는 절편. 해석을 하자면, 농어의 길이가 1cm 증가할 때마다 무게는 39g 증가하게 된다.

>>> print(lr.coef_, lr.intercept_)
[39.01714496] -709.0186449535477

 

훈련된 모델을 시각화 해보자.

아래 코드는 훈련된 모델을 시각화하는 코드이다. scatter() 함수를 사용하여 훈련 세트의 산점도를 그린 후, plot() 함수를 사용하여 15~50cm의 길이를 가지는 농어에 대한 예측값을 직선으로 그린다. 마지막으로 scatter() 함수를 사용하여 50cm 길이를 가지는 농어에 대한 예측값을 삼각형으로 표시한다.

# 훈련 세트의 산점도 
>>> plt.scatter(train_input, train_target)

# 15~50의 1차 방적식
>>> plt.plot([15,50], [15*lr.coef_ + lr.intercept_, 50*lr.coef_ + lr.intercept_])

# 50cm 농어 데이터
>>> plt.scatter(50, 1241.8, marker = '^')
>>> plt.show()

 

 

결과 해석

R2 score

r2는 회귀 모델의 예측력을 나타내는 지표 중 하나이다. 1에 가까울수록 모델이 데이터를 잘 설명한다는 것을 의미하며, 0에 가까울수록 모델이 데이터를 설명하지 못한다는 것을 의미한다.

 

Train R2

>>> print(lr.score(train_input, train_target))
0.939846333997604

 

train 데이터셋에 대한 R2 score를 출력한다. 이 값은 0.9398로, 모델이 train 데이터셋의 93.98%의 변동성을 설명한다는 것을 의미한다.

 

Test R2

>>> print(lr.score(test_input, test_target))
0.8247503123313558

 

test 데이터셋에 대한 R2 score를 출력한다. 이 값은 0.8247로, 모델이 test 데이터셋의 82.47%의 변동성을 설명한다는 것을 의미한다.

 

 

출처 : "혼자공부하는 머신러닝 + 딥러닝"