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

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


前回はStatoil/C-CORE Iceberg Classifier Challengeという、
画像分類のコンペに出場し、それについてレポートしました!

kysmo.hatenablog.jp



以降、仕事のかたわら数々のコンペに出ました!

・Toxic Comment Classification Challenge 361位/4551
 →bronze medal
・2018 Data Science Bowl 312位/3634
 →まだ順位確定していませんが、おそらくbronze medal
・TalkingData AdTracking Fraud Detection Challenge 413位/3967
 →終了12時間前までシルバー争っていたのですが、
  諸々の事情で一気にメダル圏外にはじかれました。。。涙

TalkingDataはシルバーを狙い、
常に圏内で推移していただけにとても悔しい結果となりました。

しかし、めちゃくちゃ勉強になりました。

おかげさまでKaggle Expertの称号と、
Kaggleランキング2383位(2018年5月8日現在)に入っています!

どれくらいすごいのかわからないと思いますが、自分もわかりません。
Kaggleの登録者は100万人、ランキング参加者に絞っても8万人以上おり、
その上位2%の位置ではあるので、結構すごいのではと。笑

ですが、上にはたくさんの方々がいて、
TalkingDataでは日本の方も上位に名を連ねていたので、
少しでも追いつけるようこれからも精進していきます。


さて、ブログですが、前回までは参加した際のアプローチを書いてきました。
今回は少し趣向を変えて、
これまで参加した中で使えたテクニックについて書きたいと思います。

今回注目するのは アンサンブル!

The Good, the Bad and the Blended
https://www.kaggle.com/c/jigsaw-toxic-comment-classification-challenge/discussion/51058
An easy way to calculate model correlations
https://www.kaggle.com/c/jigsaw-toxic-comment-classification-challenge/discussion/50827

どちらもKaggleのDiscussionで、Tiliiさんが書いた記事なのですが、
とても参考になるテクニックや考え方が書かれているので、
このテクニックについて書きたいと思います。


アンサンブルとは?

アンサンブルというのは、たくさんの機械学習モデルを作った後、
それを全部利用して究極のモデルを作ろうというものです。
例えば精度95%のモデルと90%のモデルを使って、
精度98%の新しいモデルを作る。みたいな感じです。

アンサンブルの方法

予測の平均をとる

f:id:mishimanatsuki:20180509114007p:plain

この方法では作ったモデルの予測の平均をとり、新しい予測とします。
画像の例では3つのモデルの平均から、犬である確率が70%であると予測します。
この時に平均値でなく中央値を使う方法や、重み付けする方法もあります。

stacking

f:id:mishimanatsuki:20180509114013p:plain

この方法では学習を2段階にわけて行うのが特徴です。
1段階目は交差検証という方法を使い、データを分割し、
それぞれのセットで学習予測を繰り返します。
その結果を使い、2段階目ではシンプルなモデルで予測を行います。
こうすることで
1段階目の各モデルより高精度な2段階モデルを作ることができます。



アンサンブルするモデルはどう決めるのか?

今回書きたかったのはこの部分で、
単に高精度なモデルを寄せ集めても、似たような予測結果のモデルでは
精度があがらないことが多いということです。

一方、
高精度なモデルと、中程度の精度のモデルをアンサンブルすると
精度がめちゃくちゃあがるというケースもあります。

自分は最初、とりあえずアンサンブルの組みを試しまくって、
結果がよかったものを最終的な提出にしていました。
しかし、試行回数が多くなる分、時間がかかり非効率的でした。

それを解消したのがTiliiさんのDiscussionの内容で、
相関が高すぎないモデルを精度がいい順でアンサンブルしていく方法です。

import pandas as pd
import sys
from scipy.stats import ks_2samp

first_file = sys.argv[1]
second_file = sys.argv[2]

def corr(first_file, second_file):
    # assuming first column is `class_name_id`
    first_df = pd.read_csv(first_file, index_col=0)
    second_df = pd.read_csv(second_file, index_col=0)
    class_names = ['toxic', 'severe_toxic', 'obscene', 'threat', 'insult', 'identity_hate']

    for class_name in class_names:
        # all correlations
        print('\n Class: %s' % class_name)
        print(' Pearson\'s correlation score: %0.6f' %
              first_df[class_name].corr(
                  second_df[class_name], method='pearson'))
        print(' Kendall\'s correlation score: %0.6f' %
              first_df[class_name].corr(
                  second_df[class_name], method='kendall'))
        print(' Spearman\'s correlation score: %0.6f' %
              first_df[class_name].corr(
                  second_df[class_name], method='spearman'))
        ks_stat, p_value = ks_2samp(first_df[class_name].values,
                                    second_df[class_name].values)
        print(' Kolmogorov-Smirnov test:    KS-stat = %.6f    p-value = %.3e\n'
              % (ks_stat, p_value))

corr(first_file, second_file)

このスクリプトを使うと、各csvファイルの各種相関を見ることができます。

Tiliiさん曰く、
"A very loose rule-of-thumb: Pearson < 0.95 (< 0.9 is even better) and a K-S statistic > 0.05 (> 0.1 is even better).""
ということですので、あくまで目安ですが
Pearson's correlation scoreが0.95以下かつ、KS-statが0.05以上のものを
精度の高い順にアンサンブルすると、いい感じのアンサンブルモデルが作れます。

実際に自分もだいたいこのルールに従ってアンサンブルを行い、
Kaggleでメダルを獲得しています。

みなさんもぜひ試してみてください!

今後に向けて

抱負をひとこと。
kysmo 2周年を迎える来年5月までにKaggleマスターを目指します!

 

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

www.kysmo.tech