ABOUT ME

공부한 것, 기억할 것들을 기록합니다.

  • [Machine Learning] Linear Regression - 다중선형회귀
    Data Science/Machine Learning & Deep Learning 2021. 2. 7. 14:12

     

     

     

     

     

     

    지난 포스팅에서는 단순선형회귀(Simple Linear Model) 모델을 사용해 보았는데요 

    이번에는 2가지 이상의 변수를 사용하는 다중 선형회귀모델(Multiple Linear Model)을 만들어보겠습니다.

     

     

     

     

     

     

    이전 단순선형회귀모델에 사용했던 보험료를 예측하기 위한 데이터를 사용하겠습니다. 

    (나이, 성별, BMI, 어린이, 흡연자, 지역, 요금 columns로 이루어진 데이터)

    www.kaggle.com/sonujha090/insurance-prediction

     

    import pandas as pd
    df = pd.read_csv('insurance.csv')

     

     

     

     

     

     

     

    모델을 만들기에 앞서 scikit-learn의 train_test_split 메소드를 사용하여 데이터를 훈련 데이터와 테스트 데이터로 나누어 주겠습니다. 

    학습에 사용하지 않은 데이터로 평가를 하여 더 정확한 성능 체크를 하기 위해 

    모델을 만들기 전 먼저 데이터를 훈련 데이터와 테스트 데이터로 나누어주는 것이 좋습니다.

     

    from sklearn.model_selection import train_test_split
    train, test = train_test_split(df, test_size =0.2, random_state=1)

     

     

     

     

     

    데이터가 잘 나누어졌는지 확인 해보겠습니다. 

     

    len(train), len(test)

     

     

     

     

    먼저 기준모델을 만들어 보겠습니다. 

    기준모델은 선형회귀모델의 경우 보통 타겟의 평균값을 사용합니다. 

     

    target = 'charges'
    y_train = train[target]
    y_test = test[target]
    
    # 'charges' 평균값으로 예측
    predict = y_train.mean()

     

     

     

     

    앞 포스팅에서 사용했던 단순선형회귀모델을 다시 만들어 보겠습니다.

     

    #scikit-learn LinearRegression import 
    from sklearn.linear_model import LinearRegression 
    
    model = LinearRegression()  
    
    feature = ['age']      
    target = ['charges']
    X_train = df[feature]
    Y_train = df[target]
    
    model.fit(X_train, Y_train)    # 모델 학습 

     

     

     

     

     

    테스트 데이터를 사용해서 에러도 알아보았습니다. 

     

    y_pred = model.predict(X_test)
    mae = mean_absolute_error(y_test, y_pred)

     

     

     

     

     

    이제 다중선형회귀모델을 만들어 보겠습니다.

    단순선형회귀모델에서 사용했던 특성인 age에 bmi를 하나 더 특성으로 선택하였습니다.

     

    features = ['age', 'bmi']    # 다중모델 특성 : age, bmi
    X_train = train[features]
    X_test = test[features]
    
    model.fit(X_train, y_train)  # 모델 학습

     

     

     

     

     

    다중회귀모델에도 테스트 데이터를 사용해 에러를 알아보았습니다.

     

    y_pred = model.predict(X_test)
    mae = mean_absolute_error(y_test, y_pred)

     

     

     

     

    테스트 데이터를 사용해서 단순선형회귀모델과 다중선형회귀모델의 오류를 체크해보면 

    해당 데이터에서는 아주 적은 차이이지만 단순모델에 비하여 다중모델의 오류가 줄어든 것을 확인할 수 있습니다.

     

     

     

     

    단순선형회귀모델과 다중선형회귀모델을 비교해볼 수 있습니다. 

    단순선형회귀에서는 특성이 하나(age)로 모델이 직선으로 표현되었지만,

    오늘 다중선형회귀모델에서는 특성이 두 개(age, bmi)이므로 평면으로 표현이 됩니다.

    이를 plotly 라이브러리를 이용하여 interactive한 시각화를 해보았습니다.

     

    import numpy as np
    import plotly.express as px
    import plotly.graph_objs as go
    import itertools
    
    def surface_3d(df, f1, f2, target, length=20, **kwargs):
        
        # scatter plot
        plot = px.scatter_3d(df, x=f1, y=f2, z=target, opacity=0.5, size_max=4, **kwargs)
        
        # 다중선형회귀모델 학습
        model = LinearRegression()
        model.fit(df[[f1, f2]], df[target])    
    
        # 좌표축 설정
        x_axis = np.linspace(df[f1].min(), df[f1].max(), length)
        y_axis = np.linspace(df[f2].min(), df[f2].max(), length)
        coords = list(itertools.product(x_axis, y_axis))  # itertools.product:중첩된 for loop에 해당하는 데카르트의 곱
        
        # 예측
        pred = model.predict(coords)
        z_axis = pred.reshape(length, length).T
        
        # plot 예측평면
        plot.add_trace(go.Surface(x=x_axis, y=y_axis, z=z_axis, colorscale='Electric'))
        
        return plot
        
    
    
    
    surface_3d(
        train,
        f1='age', 
        f2='bmi', 
        target='charges',  
        title='Insurance Charges'
    )

     

     

     

     

     

     

    이제 회귀계수를 통해 모델을 평가해보겠습니다. 

     

    model.intercept_, model.coef_

     

     

     

    두 특성 모두 회귀계수가 양수입니다.

    이를 통하여 나이(age)와 비만도(bmi)가 증가하면 보험청구금액이 증가한다는 것을 알 수 있습니다. 

     

     

     

     

     

    가상의 데이터를 모델을 이용해 예측해보겠습니다.

     

     

    1. 보험 청구 금액이 높을 것으로 예상되는 70세, 고도비만 케이스

    2. 보험 청구 금액이 낮을 것으로 예상되는 20세, 정상체중 케이스 

     

    model.predict([[70, 150]])  # 나이가 70세에 고도 비만인 경우 
    >> array([47695.24277763])
    
    model.predict([[20, 105]])   # 나이가 20세에 정상 체중인 경우  
    >> array([25657.51901641])

     

    예상했던 것과 같이 1번 케이스에서 보험 청구 금액이 높고, 2번 케이스에서 보험 청구 금액이 낮은 것을 확인할 수 있었습니다. 

Designed by Tistory.