본문 바로가기
AI/머신러닝

11. 다양한 모델 성능비교 | Air Quality UCI

by 사라리24 2024. 6. 17.
SMALL

1. Air Quality UCI 데이터셋

 

 

  • 작업파일

AirQualityUCI.csv
0.74MB

 

 

  • import

       
        import numpy as np
        import pandas as pd
        import seaborn as sns
        import matplotlib.pyplot as plt


 

 

  • 데이터 불러오기

       
      air_df = pd.read_csv('/content/drive/MyDrive/1. KDT/6. 머신러닝 딥러닝/데이터/AirQualityUCI.csv')
      air_df


 

 

  • 정보보기

     
        air_df.info()

 

 

 

  • 필요없는 열 삭제 

       
        air_df.drop(['Unnamed: 15','Unnamed: 16'], axis=1, inplace=True)
        air_df.info()

 

 

 

  • air_df 결측치(NaN)를 포함한 모든 행을 제거

       
        air_df.dropna(inplace=True)

 
 

 

 

  • Date 컬럼의 타입을 datetime으로 변경

       
          air_df['Date'] = pd.to_datetime(air_df.Date, format='%d-%m-%Y')

          air_df.head()

        air_df.info()






 

  • Date 컬럼에 의한 Month 파생변수를 생성

       
        air_df['Month'] = air_df['Date'].dt.month
        air_df.head()


 

 

  • Time 컬럼에 의한 Hour 파생변수를 생성
    

        air_df['Hour'] = air_df['Time'].str.split(':').str[0].fillna(0).astype(int)
        air_df.head()


 

  • Date와 Time 컬럼을 제거

       
        air_df.drop(['Date', 'Time'], axis=1, inplace=True)
        air_df.info()


 
 * 파생변수[ Month ] [ Hour ] 열 생성
 
 



 

  • air_df의 열들 간의 상관 관계를 시각적으로 보여주는 히트맵을 생성
더보기

  • plt.figure(figsize=(12, 12)):
    • plt.figure() 함수를 사용하여 새로운 figure(도표)를 생성합니다.
    • figsize=(12, 12)는 figure의 크기를 가로 12인치, 세로 12인치로 설정합니다. 즉, 큰 사이즈의 히트맵을 그리기 위한 준비입니다.
  • sns.heatmap(air_df.corr(), annot=True, cmap='coolwarm', vmax=1, vmin=-1):
    • sns.heatmap() 함수를 사용하여 히트맵(heatmap)을 그립니다.
    • air_df.corr()는 데이터프레임 air_df의 모든 열간의 상관계수를 계산한 후, 이를 히트맵으로 표현합니다.
    • annot=True는 각 셀에 숫자 값을 표시할지 여부를 나타내며, 여기서는 상관계수 값을 표시합니다.
    • cmap='coolwarm'는 히트맵의 색상 맵을 지정합니다. 여기서는 'coolwarm'을 사용하여 상관계수가 낮은 값은 파란색으로, 높은 값은 빨간색으로 표시합니다.
    • vmax=1과 vmin=-1은 색상 맵의 범위를 지정합니다. 상관계수의 최대값은 1이고, 최소값은 -1입니다.
  • plt.title('Correlation Heatmap'):
    • plt.title() 함수를 사용하여 그림의 제목을 설정합니다. 여기서는 'Correlation Heatmap'이라는 제목을 지정합니다.
  • plt.show():
    • plt.show() 함수를 호출하여 그림을 화면에 출력합니다.

       
        plt.figure(figsize=(12, 12))
        sns.heatmap(air_df.corr(), annot=True, cmap='coolwarm', vmax=1, vmin=-1)
        plt.title('Correlation Heatmap')
        plt.show()

 

 

 

  • 데이터 전처리(나누기, 정규화 등)와 모델 평가(오차 측정)에 필수적으로 사용되는 함수와 클래스 

      

        # 종속변수 (RH)를 제외한 모든 컬럼을 StandardScaler로 정규화
        from sklearn.model_selection import train_test_split
        from sklearn.preprocessing import StandardScaler
        from sklearn.metrics import mean_squared_error


  • StandardScaler: 데이터의 특성(feature)들을 평균이 0이고 표준편차가 1이 되도록 변환하는 것을 말합니다. 이는 각 변수들이 비슷한 스케일을 가지도록 만들어 주어, 모델이 효과적으로 학습할 수 있도록 돕습니다.
  • train_test_split: 데이터를 훈련 세트와 테스트 세트로 분할하는 함수입니다. 주어진 데이터를 훈련에 사용하고, 이를 테스트하여 모델의 성능을 평가하는 데 사용됩니다.
  • mean_squared_error: 회귀 모델에서 예측값과 실제 값 사이의 평균 제곱 오차(MSE)를 계산하는 함수입니다. 모델의 예측 정확도를 평가하는 데 사용됩니다.



  • air_df의 'RH' 열을 제외한 모든 열을 정규화하여 Xss 변수에 저장하는 과정

     
        ss = StandardScaler()

        X = air_df.drop('RH', axis=1)
        y = air_df['RH']

        Xss = ss.fit_transform(X)

        Xss



 

  • 학습시키기


        X_train, X_test, y_train, y_test = train_test_split(Xss, y, test_size=0.2, random_state=2024)

        X_train.shape, y_train.shape
        X_test.shape, y_test.shape


 

 

2. 모델별 성능 확인하기

RMSE로 확인하기
# Linear Regression
# Decision Tree Regression
# Random Forest Regression
# Support Vector (Machine) Regression
# lightGBM Regression

어떤 모델이 현재 데이터에 가장 적합한가?

 

  • 예측 결과 딕셔너리 생성, 색상 리스트 정의

       
        my_predictions = {}

        colors = ['r', 'c', 'm', 'y', 'k', 'khaki', 'teal', 'orchid', 'sandybrown',
                  'greenyellow', 'dodgerblue', 'deepskyblue', 'rosybrown', 'firebrick',
                  'deeppink', 'crimson', 'salmon', 'darkred', 'olivedrab', 'olive',
                  'forestgreen', 'royalblue', 'indigo', 'navy', 'mediumpurple', 'chocolate',
                  'gold', 'darkorange', 'seagreen', 'turquoise', 'steelblue', 'slategray',
                  'peru', 'midnightblue', 'slateblue', 'dimgray', 'cadetblue', 'tomato']


 

 

  • 예측값과 실제값을 비교하는 산점도를 그리는 함수
    데이터프레임을 만들어 정렬하고, 예측값과 실제값을 다른 색상과 마커로 시각화

     
        def plot_predictions(name_, pred, actual):
          df = pd.DataFrame({'prediction': pred, 'actual': y_test})
          df = df.sort_values(by='actual').reset_index(drop=True)
         
          plt.figure(figsize=(12, 9))
          plt.scatter(df.index, df['prediction'], marker='x', color='r')
          plt.scatter(df.index, df['actual'], alpha=0.7, marker='o', color='black')
          plt.title(name_, fontsize=15)
          plt.legend(['prediction', 'actual'], fontsize=12)
          plt.show()


 

 

  • 주석
더보기

       
 
          def plot_predictions(name_predactual):
            # 예측값과 실제값을 포함하는 데이터프레임 생성
            df = pd.DataFrame({'prediction': pred, 'actual': actual})
           
            # 실제값을 기준으로 데이터프레임 정렬 및 인덱스 재설정
            df = df.sort_values(by='actual').reset_index(drop=True)
           
            # 그림의 크기 설정
            plt.figure(figsize=(12, 9))
           
            # 예측값 산점도
            plt.scatter(df.index, df['prediction'], marker='x', color='r')
           
            # 실제값 산점도
            plt.scatter(df.index, df['actual'], alpha=0.7, marker='o', color='black')
           
            # 그래프 제목 설정
            plt.title(name_, fontsize=15)
           
            # 범례 설정
            plt.legend(['prediction', 'actual'], fontsize=12)
           
            # 그래프 표시
            plt.show()

 

 

 

  • 주어진 예측값과 실제값의 평균 제곱 오차(Mean Squared Error, MSE)를 계산하고, 이를 시각화하는 함수

       
        def mse_eval(name_, pred, actual):
          global my_predictions
          global colors
          plot_predictions(name_, pred, actual)
          mse = mean_squared_error(pred, actual)
          my_predictions[name_] = mse
          y_value = sorted(my_predictions.items(), key=lambda x: x[1], reverse=True)
          df = pd.DataFrame(y_value, columns=['model', 'mse'])
          print(df)
          min_ = df['mse'].min() - 10
          max_ = df['mse'].max() + 10
          length = len(df)
          plt.figure(figsize=(10, length))
          ax = plt.subplot()
          ax.set_yticks(np.arange(len(df)))
          ax.set_yticklabels(df['model'], fontsize=15)
          bars = ax.barh(np.arange(len(df)), df['mse'])
          for i, v in enumerate(df['mse']):
            idx = np.random.choice(len(colors))
            bars[i].set_color(colors[idx])
            ax.text(v + 2, i, str(round(v, 3)), color='k', fontsize=15, fontweight='bold')
          plt.title('MSE Error', fontsize=18)
          plt.xlim(min_, max_)
          plt.show()



 

 

  • 주석
더보기

 


       
          def mse_eval(name_predactual):
            global my_predictions
            global colors

            # 예측값과 실제값을 시각화하는 함수 호출
            plot_predictions(name_, pred, actual)
           
            # 평균 제곱 오차(MSE) 계산
            mse = mean_squared_error(pred, actual)
           
            # MSE 값을 딕셔너리에 저장
            my_predictions[name_] = mse
           
            # MSE 값을 기준으로 모델을 내림차순으로 정렬
            y_value = sorted(my_predictions.items(), key=lambda x: x[1], reverse=True)
           
            # 정렬된 값을 데이터프레임으로 변환
            df = pd.DataFrame(y_value, columns=['model', 'mse'])
           
            # 데이터프레임 출력
            print(df)
           
            # MSE 값의 최소값과 최대값을 구해 그래프의 x축 범위를 설정
            min_ = df['mse'].min() - 10
            max_ = df['mse'].max() + 10
            length = len(df)
           
            # 그래프 크기 설정
            plt.figure(figsize=(10, length))
            ax = plt.subplot()
           
            # y축 눈금과 눈금 레이블 설정
            ax.set_yticks(np.arange(len(df)))
            ax.set_yticklabels(df['model'], fontsize=15)
           
            # 수평 막대 그래프 생성
            bars = ax.barh(np.arange(len(df)), df['mse'])
           
            # 막대 그래프의 색상 설정 및 텍스트 추가
            for i, v in enumerate(df['mse']):
              idx = np.random.choice(len(colors))
              bars[i].set_color(colors[idx])
              ax.text(v + 2, i, str(round(v, 3)), color='k', fontsize=15, fontweight='bold')
           
            # 그래프 제목 설정
            plt.title('MSE Error', fontsize=18)
           
            # x축 범위 설정
            plt.xlim(min_, max_)
           
            # 그래프 표시
            plt.show()



 

 

 

1. Linear Regression

  • 선형 회귀 모델을 생성하고 학습

       
      from sklearn.linear_model import LinearRegression

      model = LinearRegression()
      model.fit(X_train, y_train)


 

  • 선형 회귀 모델을 사용하여 테스트 데이터에 대한 예측을 수행하고,
    예측값과 실제값 간의 루트 평균 제곱 오차(RMSE)를 계산

       
        pred1 = model.predict(X_test)
        pred1

        rs1 = np.sqrt(mean_squared_error(y_test, pred1))
        rs1


 

  • mse_eval 함수를 사용하여 "Linear Regression" 모델의 예측 성능을 평가하는 과정

       
      mse_eval('Linear Regression', pred1, y_test)


 

 

2. DecisionTreeRegressor

  • 결정 트리 회귀 모델(Decision Tree Regressor)을 생성하고 학습

       
        from sklearn.tree import DecisionTreeRegressor

        model2 = DecisionTreeRegressor()
        model2.fit(X_train, y_train)



 

  • 결정 트리 회귀 모델을 사용하여 테스트 데이터에 대한 예측을 수행하고,
    예측값과 실제값 간의 루트 평균 제곱 오차(RMSE)를 계산

       
      pred2 = model2.predict(X_test)
      pred2

      rs2 = np.sqrt(mean_squared_error(y_test, pred2))
      rs2


 

  • mse_eval 함수를 사용하여 " Decision Tree Regressor" 모델의 예측 성능을 평가하는 과정

       
        mse_eval('Decision Tree Regression', pred2, y_test)

 

 

 

3. Random Forest Regression

  • 랜덤 포레스트 회귀 모델(Random Forest Regressor)을 생성하고 학습


         from sklearn.ensemble import RandomForestRegressor

         model3 = RandomForestRegressor()


         model3.fit(X_train, y_train)



 

  • 랜덤 포레스트 회귀 모델을 사용하여 테스트 데이터에 대한 예측을 수행하고,
    그 결과로 계산된 루트 평균 제곱 오차(RMSE)를 계산

       
        pred3 = model3.predict(X_test)
        pred3

        rs3 = np.sqrt(mean_squared_error(y_test, pred3))
        rs3


 

  • mse_eval 함수를 사용하여 랜덤 포레스트 회귀 모델의 성능을 평가

       
        mse_eval('Random Forest Regression', pred3, y_test)


 

 

4. Support Vector Machine

  • SVM(Support Vector Machine)의 회귀 모델 SVR(Support Vector Regressor)을 생성하고 학습

       
        from sklearn.svm import SVR

        model4 = SVR()

        model4.fit(X_train, y_train)



 

  • SVR(Support Vector Regressor) 모델을 사용하여 테스트 데이터에 대한 예측을 수행하고,
    그 결과로 계산된 루트 평균 제곱 오차(RMSE)를 계산

       
        pred4 = model4.predict(X_test)
        pred4

        rs4 = np.sqrt(mean_squared_error(y_test, pred4))
        rs4



 

  • mse_eval 함수를 사용하여 SVR(Support Vector Regressor) 모델의 예측 성능을 평가

       
        mse_eval('Supprt Vector Machine', pred4, y_test)

 

 

5. lightGBM

  • LGBMRegressor를 사용하여 회귀 모델을 생성하고, 주어진 데이터를 학습

       
        from lightgbm import LGBMRegressor

        model5 = LGBMRegressor(random_state=2024)

        model5.fit(X_train, y_train)


 

  • LightGBM(Light Gradient Boosting Machine)을 사용하여 학습된 회귀 모델 model5을
    테스트 데이터 X_test에 적용하여 예측을 수행하고,
    그 결과로 계산된 루트 평균 제곱 오차(RMSE)를 계산하는 과정

       

          pred5 = model5.predict(X_test)
          pred5

          rs5 = np.sqrt(mean_squared_error(y_test, pred5))
          rs5

 

 

  • mse_eval 함수를 사용하여 LightGBM(Light Gradient Boosting Machine) 모델의 예측 성능을 평가

       
        mse_eval('lightGBM', pred5, y_test)

 

 

 

  • 다양한 회귀 모델들이 예측한 결과의 평균 제곱근 오차(RMSE) 값을 비교하고,
    그 중에서 가장 성능이 좋은 모델을 찾기

       
          dic = {'LinearRegression': rs1,
                'Decision Tree Regression': rs2,
                'Random Forest Regression': rs3,
                'Support Vector (Machine) Regression': rs4,
                'lightGBM': rs5}

          res = [key for key in dic if all(dic[temp] >= dic[key] for temp in dic)]
          print(res)
          min = {k: dic[k] for k in dic.keys() & set(res)}
          print(min)


['Random Forest Regression']
{'Random Forest Regression': 0.6098131693360906}
* 'Random Forest Regression' 모델이 예측 성능이 가장 우수하다는 것을 의미합니다.
* 이 모델이 테스트 데이터에 대해 가장 정확한 예측을 수행했으며, 다른 모델들보다 RMSE 값이 낮다는 것을 나타냅니다.

 

  • '회귀 모델들의 이름' :  'RMSE 값' 출력

       
        dic


{'Linear Regression': 7.140495660974789,
 'Decision Tree Regression': 1.2480048179558545,
 'Random Forest Regression': 0.625866736620942,
 'Support Vector (Machine) Regression': 19.947041499162168,
 'lightGBM Regression': 0.740171951644305}

 

  • 여러 회귀 모델들을 학습하고 그 성능을 평가하여 비교하는 과정

       

        X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=2024)

        models = {
            "Linear Regression": LinearRegression(),
            "Decision Tree": DecisionTreeRegressor(),
            "Random Forest": RandomForestRegressor(),
            "Gradient Boosting": GradientBoostingRegressor()
        }

        # Train and evaluate the models
        results = {}

        for name, model in models.items():
            model.fit(X_train, y_train)
            predictions = model.predict(X_test)
            mse = mean_squared_error(y_test, predictions)
            results[name] = mse

        results


  • 데이터 분할:
    • train_test_split 함수를 사용하여 데이터셋 X와 y를 훈련 세트(X_train, y_train)와 테스트 세트(X_test, y_test)로 분할합니다.
    • test_size=0.2는 테스트 세트의 비율을 20%로 설정합니다.
    • random_state=2024는 재현 가능한 결과를 얻기 위해 설정된 랜덤 시드입니다.
  • 모델 정의:
    • 다양한 회귀 모델들을 models 딕셔너리에 정의합니다.
    • 각 모델의 이름과 해당 모델 객체가 포함됩니다:
      • "Linear Regression": 선형 회귀 모델 (LinearRegression)
      • "Decision Tree": 결정 트리 회귀 모델 (DecisionTreeRegressor)
      • "Random Forest": 랜덤 포레스트 회귀 모델 (RandomForestRegressor)
      • "Gradient Boosting": 그래디언트 부스팅 회귀 모델 (GradientBoostingRegressor)
  • 모델 학습 및 평가:
    • 각 모델에 대해 반복문을 통해 다음 과정을 수행합니다:
      • model.fit(X_train, y_train): 훈련 데이터를 사용하여 모델을 학습시킵니다.
      • predictions = model.predict(X_test): 학습된 모델을 사용하여 테스트 데이터에 대한 예측을 수행합니다.
      • mse = mean_squared_error(y_test, predictions): 예측값과 실제값 사이의 평균 제곱 오차(MSE)를 계산합니다.
      • results[name] = mse: 계산된 MSE 값을 results 딕셔너리에 저장합니다. name은 모델의 이름("Linear Regression", "Decision Tree", 등)이며, mse는 해당 모델의 성능을 나타내는 값입니다.
  • 결과 반환:
    • results 딕셔너리에는 각 모델의 이름과 그에 해당하는 MSE 값이 저장되어 있습니다.
    • 이 딕셔너리는 모델들의 성능을 비교하고, 최종적으로 출력되거나 다양한 시각화나 분석에 활용될 수 있습니다.