ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [sklearn / python / pandas] 선형, 이차, 삼차, 로그 모델 RMSE, R2 비교
    python 데이터 분석 2024. 4. 8. 15:19

    (1) 모델 불러오기

    import numpy as np
    
    import pandas as pd
    from sklearn.metrics import mean_squared_error, r2_score
    
    from sklearn.model_selection import train_test_split
    from sklearn.linear_model import LinearRegression, Lasso, Ridge, LassoCV, BayesianRidge
    import statsmodels.formula.api as sm
    import matplotlib.pylab as plt
    
    from dmba import regressionSummary, exhaustive_search
    from dmba import backward_elimination, forward_selection, stepwise_selection
    from dmba import adjusted_r2_score, AIC_score, BIC_score

     

    (2) 데이터 불러오기

    df_Q1= pd.read_excel('./과제1.xlsx', sheet_name="Q1")
    df_Q1 = df_Q1.iloc[:, [0,1]]
    df_Q1 = df_Q1[4:23]
    df_Q1.columns = ['Y','X']
    X = df_Q1['X']
    type(X) # 확인 결과 Series 임
    X = X.to_frame() 
    type(X) # df 로 변환됨
    y = df_Q1['Y']

     

    데이터를 불러오고, sklearn 를 사용하기 위해, 전처리 하는 과정이다.

    다음 과정인, train_test_split (훈련-테스트 셋) 으로 데이터를 나누기 위해서, 형변환을 해줘야 한다.

     

    (3) 훈련 - 테스트 데이터 셋 나누기

    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.4, random_state=1)

    관련 에러

    https://shartarc.tistory.com/18

     

    ValueError: x and y must be the same size 에러 해결

    plt.scatter() 함수에서 x와 y 인자로 전달된 데이터의 길이가 서로 다를 때 발생한다. 해결방안 1. 길이 확인 print(len(X_test), len(y_test), len(y_test_pred)) 2. 인덱스 재설정 X_test = X_test.reset_index(drop=True) y_tes

    shartarc.tistory.com

     

    (4) 각 회귀 모델에 fitting 하기

    (4-1)  선형, 이차, 삼차 모델 fitting 

    # 선형 회귀 모델
    linear_model = LinearRegression()
    linear_model.fit(X_train, y_train)
    
    # 이차 모델
    quadratic = PolynomialFeatures(degree=2)
    X_quad_train = quadratic.fit_transform(X_train)
    X_quad_test = quadratic.transform(X_test)
    quad_model = LinearRegression()
    quad_model.fit(X_quad_train, y_train)
    
    # 삼차 모델
    cubic = PolynomialFeatures(degree=3)
    X_cubic_train = cubic.fit_transform(X_train)
    X_cubic_test = cubic.transform(X_test)
    cubic_model = LinearRegression()
    cubic_model.fit(X_cubic_train, y_train)

     

    로그 함수의 경우 데이터 셋이 로그 변환하였을 때, 0 또는 음수 값을 사진 요소에 대해서 로그 변환을 하지 못한다.

    따라서, 로그 모델을 학습 전에 여러 방법으로 데이터를 만져줘야 한다.

    (4-2-1)  양수가 아닌 값을 처리하기 위한 방법 1

    X_log = np.log(X + small_positive_number)

    (4-2-2) 양수가 아닌 값을 처리하기 위한 방법 2

    X_train['X'] = X_train['X'].apply(lambda x: np.log(x) if x > 0 else np.log(x + 1e-6))
    X_test['X'] = X_test['X'].apply(lambda x: np.log(x) if x > 0 else np.log(x + 1e-6))

    조건문을 사용하여 x가 0보다 클 경우에는 np.log(x)를 계산하고, 그렇지 않은 경우에는 x + 1e-6에 대해 로그를 취함

     

     

    (4-2-3) 형변형 및 로그함수 회귀 모델 fitting 

    X_log_train = np.log(X_train['X']).to_frame()
    X_log_test = np.log(X_test['X']).to_frame()
    
    log_model = LinearRegression()
    log_model.fit(X_log_train, y_train)

     

    (5) 각 모델의 성능 평가

    for name, model, X_train, X_test in [('Linear', linear_model, X_train, X_test),
                                          ('Quadratic', quad_model, X_quad_train, X_quad_test),
                                          ('Cubic', cubic_model, X_cubic_train, X_cubic_test),
                                          ('Logarithmic', log_model, X_log_train, X_log_test)]:
        y_train_pred = model.predict(X_train)
        y_test_pred = model.predict(X_test)
        
        print(f'{name} Model Performance:')
        print('Train RMSE:', np.sqrt(mean_squared_error(y_train, y_train_pred)))
        print('Test RMSE:', np.sqrt(mean_squared_error(y_test, y_test_pred)))
        print('Train R^2:', r2_score(y_train, y_train_pred))
        print('Test R^2:', r2_score(y_test, y_test_pred))
        print()

     

    결과

    Linear Model Performance:
    Train RMSE: 0.9502110450668287
    Test RMSE: 1.3433255865520894
    Train R^2: 0.09839394280091873
    Test R^2: -0.37996060676463594
    
    Quadratic Model Performance:
    Train RMSE: 0.9121287351241912
    Test RMSE: 1.0959923990731575
    Train R^2: 0.16921442437041123
    Test R^2: 0.08141531674638058
    
    Cubic Model Performance:
    Train RMSE: 0.8567623013548376
    Test RMSE: 1.0655669736505267
    Train R^2: 0.26701114776650703
    Test R^2: 0.13170836322401247
    
    Logarithmic Model Performance:
    Train RMSE: 0.9842747833692908
    Test RMSE: 1.2637050299118417
    Train R^2: 0.03259263393296463
    Test R^2: -0.22122459807554384
    

     

    전체 코드

    import numpy as np
    
    import pandas as pd
    from sklearn.metrics import mean_squared_error, r2_score
    
    from sklearn.model_selection import train_test_split
    from sklearn.linear_model import LinearRegression, Lasso, Ridge, LassoCV, BayesianRidge
    import statsmodels.formula.api as sm
    import matplotlib.pylab as plt
    
    from dmba import regressionSummary, exhaustive_search
    from dmba import backward_elimination, forward_selection, stepwise_selection
    from dmba import adjusted_r2_score, AIC_score, BIC_score
    
    df_Q1= pd.read_excel('./과제1.xlsx', sheet_name="Q1")
    df_Q1 = df_Q1.iloc[:, [0,1]]
    df_Q1 = df_Q1[4:23]
    df_Q1.columns = ['Y','X']
    X = df_Q1['X']
    type(X) # 확인 결과 Series 임
    X = X.to_frame() 
    type(X) # df 로 변환됨
    y = df_Q1['Y']
    
    from sklearn.preprocessing import PolynomialFeatures
    
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.4, random_state=1)
    X_test = X_test.reset_index(drop=True)
    y_test = y_test.reset_index(drop=True)
    
    # 선형 회귀 모델
    linear_model = LinearRegression()
    linear_model.fit(X_train, y_train)
    
    # 이차 모델
    quadratic = PolynomialFeatures(degree=2)
    X_quad_train = quadratic.fit_transform(X_train)
    X_quad_test = quadratic.transform(X_test)
    quad_model = LinearRegression()
    quad_model.fit(X_quad_train, y_train)
    
    # 삼차 모델
    cubic = PolynomialFeatures(degree=3)
    X_cubic_train = cubic.fit_transform(X_train)
    X_cubic_test = cubic.transform(X_test)
    cubic_model = LinearRegression()
    cubic_model.fit(X_cubic_train, y_train)
    
    # 로그 모델
    # 로그 변환을 수행하기 전에 모든 X 값이 양수인지 확인해야 합니다.
    # np.log0(X)는 X의 각 요소에 대한 자연 로그를 반환합니다.
    # X_train, X_test가 DataFrame이고, 'X'라는 컬럼이 있다고 가정했을 때
    # print(type(X_train)) # Pandas.core.frame.DataFrame 이다.
    X_train['X'] = X_train['X'].apply(lambda x: x if x > 0 else x + 1e-6)
    X_test['X'] = X_test['X'].apply(lambda x: np.log(x) if x > 0 else np.log(x + 1e-6))
    
    X_log_train = np.log(X_train['X']).to_frame()
    X_log_test = np.log(X_test['X']).to_frame()
    
    log_model = LinearRegression()
    log_model.fit(X_log_train, y_train)
    
    # 각 모델의 성능 평가
    for name, model, X_train, X_test in [('Linear', linear_model, X_train, X_test),
                                          ('Quadratic', quad_model, X_quad_train, X_quad_test),
                                          ('Cubic', cubic_model, X_cubic_train, X_cubic_test),
                                          ('Logarithmic', log_model, X_log_train, X_log_test)]:
        y_train_pred = model.predict(X_train)
        y_test_pred = model.predict(X_test)
        
        print(f'{name} Model Performance:')
        print('Train RMSE:', np.sqrt(mean_squared_error(y_train, y_train_pred)))
        print('Test RMSE:', np.sqrt(mean_squared_error(y_test, y_test_pred)))
        print('Train R^2:', r2_score(y_train, y_train_pred))
        print('Test R^2:', r2_score(y_test, y_test_pred))
        print()

     

Designed by Tistory.