[PYTHON - 머신러닝_선형회귀]★선형회귀★seaborn 타원만들기★모델 평가방법 RMSE , R**2★model.coef_(기울기)★model.intercept_(y절편)
1. 선형회귀
==> 가장 기초적인 머신러닝 모델
==> 여러가지 데이터를 연속형 변수인 목표 변수를 예측해 내는 것이 목적이다.
==> 몸무게, 나이 , BMI, 성별 등의 데이터를 활용하여 연속형 변수를 예측
==> 복잡한 알고리즘에 비해서는 예측력이 떨어지지만 데이터의 특성이 복잡하지 않을 때는 쉽고 빠른 예측이 가능하다.
2. 전처리 : 학습 set , Train set 나누기
독립변수 | 종속변수 | |
학습셋 | X_train | Y_train |
시험셋 | X_test | Y_test |
==> 데이터를 나누는 작업은 크게 2가지 차원으로 진행되어 총 4개 데이터셋으로 나눈다.
학습셋 과 시험셋 나누는 이유 :
==> 학습셋과 시험셋을 구분하지 않고 예측 모델을 만든다면, 학습에 사용한 데이터와 평가용으로 데이터가 동일하다는 것으로 모델을 만들고 나서 새로운 데이터에도 맞는지 검증이 안되기 때문이다.
==> 검증하지 않은 상태라는 불확실성을 줄일 목적으로 준비하는 것이 시험셋이다.
==> 학습셋 데이터는 모델을 학습시키는 데 사용하고, 나머지 데이터는 모델 학습이 완료된 이후에 평가용으로 사용할 수 있다.
==> 시험셋의 데이터는 처음 만나게 되는 데이터로 예측/평가를 했을 때도 예측력이 좋게 나타나면, 향후 예측하게 될 새로운 데이터에 대해서도 잘 작동할 수 있다.
==> 일반적으로 학습 셋 : 시험 셋을 각각 7:3 혹은 8:2 정도 비율로 나눈다.
==> 전체 데이터 크기가 작다면 학습셋 비율을 높여서 최대한 학습셋을 많이 확보해야한다.
file_url = 'https://media.githubusercontent.com/media/musthave-ML10/data_source/main/insurance.csv'
data = pd.read_csv(file_url)
data
data.info() # column(열) 정보 , 결측치 아닌것들 COUNT , 자료형
round(data.describe(), 2) #소수점 2자리까지만 통계정보량 출력
from sklearn.model_selection import train_test_split #사이킷런 import
X = data[['age' , 'sex' , 'bmi' , 'children' , 'smoker']] #독립변수
y = data['charges'] #종속변수
X_train , X_test , y_train , y_test = train_test_split(X , y , test_size=0.2 , random_state= 100) #데이터 셋 분할
# test_size (시험 셋) ==> 20% , random_state = 100 ==> 랜덤 샘플링
#랜덤 샘플링이란 데이터를 특정 비율로 나눌 때 마구잡이로 뒤섞어서 나누는 것
#랜덤 샘플링을 진행하지 않는다면 데이터가 특정 순서로 정렬될 수 도 있다.
==> Random Sampling ==> 랜덤 샘플링이란 데이터를 특정 비율로 나눌 때 마구잡이로 뒤섞어서 나누는 것 ==> 랜덤 샘플링을 진행하지 않는다면 데이터가 특정 순서로 정렬될 수 도 있다.
==> train_test_split() 함수는 기존 데이터의 순서와 상관없이 마구잡이로 섞어서 데이터를 분류시킨다.
==> random_state 옵션은 랜덤하게 샘플링하면서도 지속적으로 같은 데이터 분류가 가능하도록 한다.
3. 모델링
==> 모델링은 머신러닝 알고리즘으로 모델을 학습시키는 과정이며, 그 결과물이 머신러닝 모델이 된다. 모델링에 사용할 머신러닝 알고리즘을 선택하고, 독립녀수와 종속변수를 fit() 함수에 인수로 주어 학습한다.
from sklearn.linear_model import LinearRegression
==> sklearn.linear_model 모듈에서 LinearRegression 라이브러리를 불러온다.
model = LinearRegression() #선형회귀에 사용할 model 객체를 생성했으니 model 객체를 사용해서 선형 회귀로 학습하고 예측할 수 있게 된다.and
model.fit(X_train , y_train)
#객체.fit(독립변수, 종속변수)
학습시킨다 의 의미 : 데이터를 모델 안에 넣어서 독립변수와 종속변수 간의 관계들을 분석해 새로운 데이터를 예측할 수 있는 상태로 만드는 것이다.
4. 모델을 활용해 예측하기
pred = model.predict(X_test)
==> predict()함수로 예측을 할 수 있으며, 괄호 안에는 예측 대상을 넣어주면 된다.
5. 예측 모델 평가하기
==> 모델을 평가하는 방법으로 '테이블로 평가하기' , '그래프로 평가하기' , '통계(RMSE)적인 방법으로 평가하기'가 있다.
1> 테이블로 평가하기
comparison = pd.DataFrame({'actual' : y_test, 'pred' : pred})
comparison
예측한 값은 pred에 , 실제 정보는 y_test에 저장되어 있다.
예측값이 얼마나 정확한지는 pred와 y_test를 비교하는 것으로 단순하게 확인할 수 있다.
2> 그래프로 평가하기
fig = plt.figure(figsize=(15,8))
x = comparison.iloc[:, 0].tolist()
y = comparison.iloc[: ,1].tolist()
# ax = sns.set_style('whitegrid')
ax = sns.scatterplot(x= x , y = y)
# ax = sns.lineplot(x= 'actual' , y = 'pred' , data = comparison)
ax.set_title('예측값 , 관찰값 산정' , fontsize=15)
ax.set_xlabel('실제값', fontsize = 15 , fontweight = 'bold')
ax.set_ylabel('예측값' , fontsize = 15 , fontweight = 'bold' , rotation = 0 , labelpad=25)
#####1번째
g_ell_center = (10000, 11000)
g_ell_width = 30000
g_ell_height = 8000
angle = 45.
g_ellipse = patches.Ellipse(g_ell_center, g_ell_width, g_ell_height, angle=angle, fill=False, edgecolor='red', linewidth=2)
ax.add_patch(g_ellipse)
plt.annotate('' , xy=(25000, 3000), xytext=(18000 , 8000) , arrowprops = dict(facecolor = 'black'))
ax.text(25000 ,3000 , '실제값과 예측값이 비슷하다.' , fontsize = 13)
#####2번째
g_ell_center = (22000, 32000)
g_ell_width = 30000
g_ell_height = 8000
angle = 40.
g_ellipse = patches.Ellipse(g_ell_center, g_ell_width, g_ell_height, angle=angle, fill=False, edgecolor='green', linewidth=2)
ax.add_patch(g_ellipse)
plt.annotate('' , xy=(10000, 35000), xytext=(13000 , 30000) , arrowprops = dict(facecolor = 'black'))
ax.text(5000 ,37000 , '실제값보다 예측값이 더 높게 나타났다.' , fontsize = 13)
#####3번째
g_ell_center = (42000, 32000)
g_ell_width = 30000
g_ell_height = 8000
angle = 40.
g_ellipse = patches.Ellipse(g_ell_center, g_ell_width, g_ell_height, angle=angle, fill=False, edgecolor='blue', linewidth=2)
ax.add_patch(g_ellipse)
plt.annotate('' , xy=(50000, 25000), xytext=(48000 , 30000) , arrowprops = dict(facecolor = 'black'))
ax.text(45000 ,22000 , '실제값보다 예측값이 더 높게 나타났다.' , fontsize = 13)
==> patches 모듈로 다각형 그릴 수 있다.
3> 통계적인 방법으로 평가하기 : RMSE
==>연속형 변수를 예측하고 평가할 때 가장 흔하게 쓰이는 RMSE(Root Mean Squared Error) 루트 평균 제곱근 오차, 평균 제곱근 편차를 사용
https://knowallworld.tistory.com/224
==> 평균 제곱 오차 ==> 실제값과 예측값 사이의 오차를 제곱한 뒤 이에 대한 평균 계산
==> 루트 평균 제곱 오차 ==> MSE에 루트를 씌운 값으로 가장 릴반적으로 사용
from sklearn.metrics import mean_squared_error # MSE 라이브러리
mean_squared_error(y_test,pred)**0.5 # RMSE를 위한 루트 씌우기
mean_squared_error(y_test,pred, squared= False)
4> 통계적인 방법으로 평가하기 : R**2(결정계수)
==> 독립변수로 설명되는 종속변수의 분산비율 나타낸다.
SST(Sum of Squares Total) ==> 종속변수 y의 평균값과 관측치의 거리
SSR(Sum of Squares Regression) ==> 평균으로 대충 맞추었을 때와 우리가 만든 모델을 이용했을 때의 차이
SSE(Sum of Squares Error) ==> 선형 회귀 모델과 관측치와의 거리
R**2 = SSR/ SST
==> 대충 평균값으로 넣었을 때 , 예측값(평균 값) 과 실젯값의 차이 중 우리 모델이 얼마만큼의 비율로 실젯값에 가깝게 예측하는지를 의미.
model.score(X_train , y_train)
0.736822
==> R**2은 비율이므로 최대 1까지 나올 수 있으며, 좋은 모델일수록 1에 가깝다.
==> 0.7~0.8 이상이면 일반적으로 괜찮은 수치라고 할 수 있다.
6. 선형 회귀
==> 선형회귀(Linear Regression)은 독립변수와 종속변수 간에 선형 관계가 있음을 가정하여 최적의 선을 그려서 예측하는 방법.
==> 머신러닝에서는 손실 함수(Loss Function)을 최소화하는 선을 찾아서 모델을 만들어낸다.
==> 손실 함수란? : 예측값과 실제값의 차이, 즉 오차를 평가하는 방법
(ex.MSE 나 RMSE)
수식 표현 :
==> 독립변수가 'age' , 'sex' , 'bmi' , 'children' , 'smoker'로 5개의 모델을 생성.
==> 청구비용 = A * age + B * sex + C * bmi + D *children + E * smoker + i
pd.Series(model.coef_ , index = X.columns)
==> A,B,C,D,E는 각 독립변수에 대한 기울기이다.
==> 이 기울기 값을 계수라고도한다.
==> 종속변수(charges)는 age가 1만큼 증가하면 약 265만큼 증가한다.
==> 성별(sex)의 경우에는 0과 1로 구성된 명목데이터 이기 때문에 , 남자(1)의 경우 여자(0)보다 charges가 보통 17높다.
model.intercept_
-11576.99997611236
==> 모델의 y절편
charges = 264.799803 * age + 17.344661*sex + 297.514806*bmi + 469.339602*children + 23469.280173*smoker - 11576.99997611236
==> 데이터의 특정 행을 정해서 각 변수의 값을 위 수식에 넣으면 모델이 보여주는 예측값과 같은 결과를 얻을 수 있다!
==> 선형 회귀는 수식을 도출하기 매우 쉬워 그 해석도 직관적이다.
출처 : 데싸노트의 실전에서 통하는 머신러닝
(Golden Rabbit , 저자 : 권시현)
※혼자 공부용