世界一のデータサイエンティストを目指して 〜Kaggle参加レポート5〜

こんにちは!株式会社キスモのKaggler 大越です。

またまた嬉しい報告があります!
Kaggleで開かれていた、データ分析の世界大会”Home Credit Default Risk”で、史上最多の7198チームが参加する中で2位に入り、再びゴールドメダルを獲得しました。またそれに伴い、Kaggle Master※になりました!!
※Kaggle Master : メダルの数に応じて付与される称号の中で、最上位のGrandmasterに次ぐ2番目の称号のこと。

前回はAvitoでゴールドメダルを取った後に報告をさせていただきましたが、今回もまたまた良い報告ができ嬉しいです。

さて、今回のブログではそんなKaggleで開かれたKaggle insight challengeの内容を試したので、それをブログにします。

Kaggle insight challengeとは?

9月末に4日間の日程で開かれたデータ分析の説明性に関するLessonです。
4日間の内容は以下の通りです。

  • day1 PermutationImportanceを用いた特徴量の重要度の計算
  • day2 Partial Dependence Plots(pdp)を用いた、特徴量とtargetの関係の可視化
  • day3 SHAPを用いた個々の予測の構成可視化
  • day4 SHAPを用いた予測モデル全体の構成可視化

今回は上記のうち、day1, day2の内容を試しました。

使用したデータ

Kaggle Telcom Customer Churnのデータを使用しました。
そのため、コードはKaggleのkernel内に公開しています。

タスクとしては電気通信事業の顧客情報から、その人が1ヶ月以内に解約するかどうかを2値で分類するもので、target=1が解約した、0が解約しなかったとなっています。
サービスには以下のものがあり、どれを利用したかのデータが含まれています。
phone, multiple lines, internet, online security, online backup, device protection, tech support, and streaming TV and movies
また、その他に顧客の属性情報も含まれています。

今後の分析で登場する"TotalCharges"は請求した合計金額、"Contract"は契約期間(月間、1年、2年)、"Dependents"は顧客に扶養家族がいるか、"Partner"は顧客にパートナーがいるか、"DeviceProtection"はデバイス保護の契約をしたかを示しています。

モデリング

今回、特にモデリングには気を使わずこちらのカーネルから抜粋しました。
使用したモデルは木系のランダムフォレストです。
モデルの評価もカーネルに沿ってaccuracyとconfusion matrix, roc curveを使用しました。

f:id:mishimanatsuki:20181005134710p:plain

図はスコアを示したものです。accuracyは0.7927でした。

PermutationImportance

f:id:mishimanatsuki:20181005134702p:plain 図はPermutationImportanceの概要を示しています。
このように、ある特徴量についてランダムにシャッフルした時の精度の下がり方を使い、特徴量の重要度を算出しています。
この時、精度が大きく下がるようなら、その特徴は予測において重要であることを示しており、逆に精度が上がる場合は、予測にノイズ成分として悪影響を及ぼしていると判断できます。

今回はeli5というライブラリを使用して実験を行いました。

import eli5
from eli5.sklearn import PermutationImportance

perm = PermutationImportance(clf, random_state=1).fit(df_val[features], df_val["Churn"])
eli5.show_weights(perm, feature_names = list(features))

f:id:mishimanatsuki:20181005134656p:plain

図は結果を示しており、Featureが特徴量の名前、Weightが精度の推移を示しています。
一番左の列の数値を見てみると、+のものが”精度が下がった、つまり予測に重要な特徴量”、-のものが”精度が上がった、つまり予測に悪影響を及ぼす特徴量”を示していることが分かります。
真ん中の列の、+-で示されている数値は、ランダム性を持つ分析なので何回か行った際の標準偏差になっています。
これを見ると"TotalCharges", "Contract"が予測において重要な特徴であることがわかります。 また、"Dependents", "Partner", "DeviceProtection"は予測に悪影響を及ぼすノイズ成分になっていることがわかります。
そこで、これらを除いたモデルを作ってみました。

f:id:mishimanatsuki:20181005134715p:plain 結果は図の通りで、accuracyは0.7946でした。
元のモデルと比較して特徴量を3つ除いた結果、0.7927->0.7946とわずかな精度向上を実現しました。
ただ、何回かやってみると、ノイズ成分と示される特徴が変わったり、精度が悪化するケースがあったりしました。
今回の結果でも標準偏差を見るとノイズ成分もプラスに振れることもありそうですし、もう少しはっきりと負の影響を示すものは除くような処理になるのではと思っています。

Partial Dependence Plots(pdp)

f:id:mishimanatsuki:20181005134651p:plain 図はpdpの概要を示しています。
このように、ある行に着目し、1つの特徴量の値を上下させた時の出力の変化を見ます。
これを複数の行で行い、その平均を取ることで、ある特徴量の推移とtargetの値との関係を見ることができます。

from matplotlib import pyplot as plt
from pdpbox import pdp, get_dataset, info_plots

# Create the data that we will plot
features = df_val.drop(["Churn"], axis=1).columns.values
feature_to_plot = 'TotalCharges'
pdp_goals = pdp.pdp_isolate(model=clf, dataset=df_val[features], model_features=list(features), feature=feature_to_plot)

# plot it
pdp.pdp_plot(pdp_goals, feature_to_plot)
plt.show()

f:id:mishimanatsuki:20181005134643p:plain 今回はpdpboxというライブラリを使用して実際に分析しました。
PermutationImportanceで特に重要だった"TotalCharges"を対象にしています。
図は結果を示すもので、横軸が"TotalCharges"の推移、縦軸が”target”の推移になります。
青で示された範囲が信頼度を示しています。
これを見ると"TotalCharges"が0から2000付近までは”target”が急激に低下し、その後もなだらかに低下している様子がわかります。  

f:id:mishimanatsuki:20181005134648p:plain "Contract"についての結果を見ても、値の増加に伴い、”target”が下がっている様子が確認できました。

まとめ

今回はKaggle insight challengeの内容を応用し、「PermutationImportanceで重要度を算出->悪影響を及ぼす特徴を除いてモデリング/重要な特徴とtargetの関係をpdpを使って可視化」という流れを実施しました。
実装はKaggle kernelでも公開しましたのでよろしければご覧ください。
ランダムな要素の影響で多少結果が変わっていますが、ご容赦ください。

 

もっとキスモのことを知りたい方は
こちらをご覧ください!

www.kysmo.tech