精度評価指標について調べてみた(後半)
先日記載したとおり、精度評価指標の後半部分としてコードで各精度評価指標を実装したまとめです。
長いので全文は記載しません、全文を確認される場合はこちらをご覧ください。
前半の理論部分は下記リンクからご覧ください。
概要:
データセット:HousePriceコンペ
学習モデル:LightGBM
評価指標:MSE、MAE、決定係数、RSME
以降の精度結果は、train データをホールドアウト法で分割した30%部分の検証用データの予測値と実績値を比較しています。
- 1.欠損値を含まない数値データを特徴量とする
- 2.1 に加え、欠損値処理を行った数値データを特徴量とする
- 3.2 に加え、ラベルエンコーディングしてカテゴリデータも特徴量とする
- 4.3 に加え、外れ値を処理する
- まとめ
- 参考サイト
1.欠損値を含まない数値データを特徴量とする
単純に欠損値を含まず、カテゴリデータを除く数値データのみを特徴量とします。
LightGBMは欠損値を含んでいても回せるのですが、他の欠損値処理が必要なモデルで回す場合も考慮して対象外としています。
結果は以下のとおりでした。
MSE :718051766.5529627 MAE :16540.0487430681 決定係数 :0.8970991518382367 RMSE :26796.48795183732
2.1 に加え、欠損値処理を行った数値データを特徴量とする
欠損値の割合が2割超の項目は特徴量から除外します。
欠損値の割合が2割以下の項目については、trainデータについては行を削除し、testデータについては中央値に置換します。
train_miss_ratio ...トレインデータの欠損値の割合
test_miss_ratio ... テストデータの欠損値の割合
NaN ... トレインデータ、テストデータいずれかに欠損値があり、一方には欠損値がない
# 欠損値の割合 train_miss_ratio = pd.DataFrame(train.isnull().sum()[train.isnull().sum() != 0]/train.isnull().count()[train.isnull().sum() != 0]*100, columns=["train_miss_ratio"]) test_miss_ratio = pd.DataFrame(test.isnull().sum()[test.isnull().sum() != 0]/test.isnull().count()[test.isnull().sum() != 0]*100, columns=["test_miss_ratio"]) # trainデータとtestデータで比較 pd.concat([train_miss_ratio, test_miss_ratio], axis=1)
MSE :1050826489.8539871 MAE :19378.48196261921 決定係数 :0.8685064360941711 RMSE :32416.45399876407
特徴量を増やしすぎたこと、数値データの欠損値を中央値で置き換えたことが悪影響したのか、精度が悪化してしまいました。
なお、前述のとおりLightGBMは欠損値を含んでいても回せるのですが、他の欠損値処理が必要なモデルで回す場合も考慮して欠損値処理しています。
3.2 に加え、ラベルエンコーディングしてカテゴリデータも特徴量とする
ラベルエンコーディングすることでカテゴリデータも特徴量に追加しています。
# ラベルエンコーディング from sklearn import preprocessing encorder = preprocessing.LabelEncoder() # object型のカテゴリデータのリストを作成 cat_list = list(train.select_dtypes(include=object).isnull().sum()[train.select_dtypes(include=object).isnull().sum() > 0].index) # ラベルエンコーディングは欠損値があるとできないので missing に置き換える for i in cat_list: train3[i].fillna("missing", inplace=True) for i in cat_list: test3[i].fillna("missing", inplace=True) # ラベルエンコーディングを実施 for i in cat_list: train3[i] = encorder.fit_transform(train3[i]) test3[i] = encorder.fit_transform(test3[i])
2 と同様に、欠損値が2割超の項目は特徴量から除外しています。
MSE :716059827.242882 MAE :16895.93255402717 決定係数 :0.8973846079209897 RMSE :26759.29422168832
若干ではありますが、精度は1と比べてもおおむね改善ました。
4.3 に加え、外れ値を処理する
目的変数である"SalePrice"と各項目の相関関係を散布図で確認し、外れ値を削除しました。
LotAreaの処理のみ抜粋
# LotArea が 30,000未満、かつ、SalePriceが600,000超の項目を除外 train = train.drop(train[(train['LotArea']<30000) & (train['SalePrice']>600000)].index) # LotArea が 100,000超の項目を除外 train = train.drop(train[train['LotArea']>100000].index)
外れ値除外前
外れ値除外後
MSE :444408261.28365076 MAE :14892.964374929155 決定係数 :0.9052214999301952 RMSE :21080.992891314458
外れ値を除外することで、精度を向上させることができました。
まとめ
特徴量選択 1 欠損値を含まない数値データを特徴量とする
MSE :718051766.5529627 MAE :16540.0487430681 決定係数 :0.8970991518382367 RMSE :26796.48795183732
特徴量選択 2 欠損値を削除した数値データを特徴量とする
MSE :1050826489.8539871 MAE :19378.48196261921 決定係数 :0.8685064360941711 RMSE :32416.45399876407
特徴量選択3 ラベルエンコーディングしてカテゴリデータも対象にした場合
MSE :716059827.242882 MAE :16895.93255402717 決定係数 :0.8973846079209897 RMSE :26759.29422168832
特徴量選択4 外れ値を除外した場合
MSE :444408261.28365076 MAE :14892.964374929155 決定係数 :0.9052214999301952 RMSE :21080.992891314458
外れ値を除外することで、精度が向上しました!
以上になります、最後までお読みいただきありがとうございました。