実践多クラス分類 kaggle ottoから学んだこと

129
実践 多クラス分類 西尾 泰和

Upload: nishio

Post on 24-Jul-2015

3.339 views

Category:

Education


0 download

TRANSCRIPT

Page 1: 実践多クラス分類 Kaggle Ottoから学んだこと

実践 多クラス分類

西尾泰和

Page 2: 実践多クラス分類 Kaggle Ottoから学んだこと

この資料の目的

Kaggleのコンペに参加することで色々な実践的ノウハウを学んだので

そのノウハウを共有する

p.3~53 コンペ中に自分がやったことp.54~99 ハイランカーがやっていたことp.100~ハイランカーかやっていたことを

自分も実際にやってみる

2

Page 3: 実践多クラス分類 Kaggle Ottoから学んだこと

kaggle

Otto Group Product Classification Challenge

IN:93個の特徴量、OUT:9クラスに分類

train.csv 61878行 test.csv 144368行

各クラスである確率を提出し、log lossで評価

3

Page 4: 実践多クラス分類 Kaggle Ottoから学んだこと

クロスバリデーション

回答の投稿は1日に3回まで

手元でいろいろ試してよさそうなものを選びたい

train.csvでのクロスバリデーション

4

Page 5: 実践多クラス分類 Kaggle Ottoから学んだこと

Stratified K Fold

train.csvは各クラスごとにデータが並んでいた→単純に分割してテストデータにしてはいけない→Scikit-learnが色々な方法を提供している例: StratifiedKFold:クラス比率を保つように分割

5

def do_cross_validation():model = make_model()cv = cross_validation.StratifiedKFold(ys)scores = cross_validation.cross_val_score(

model, xs, ys, cv=cv, scoring='log_loss')print("Accuracy: %0.2f (+/- %0.2f)“

% (scores.mean(), scores.std() * 2))

http://scikit-learn.org/stable/modules/cross_validation.html#cross-validation

Page 6: 実践多クラス分類 Kaggle Ottoから学んだこと

とりあえずロジスティック回帰

Accuracy: 0.76±0.01

所要時間 4分

6

Page 7: 実践多クラス分類 Kaggle Ottoから学んだこと

とりあえずロジスティック回帰2

2個ずつの組み合わせで(93 * 92 / 2)の特徴を追加0が多いのでscipy.sparse.lil_matrixを使ったそのままLRに食わせられる/stdはない

Accuracy: 0.79±0.01 (0.03アップ)

所要時間 45分

未解決課題:掛け算で大きな値に。スケール調整が有効ではないかと思うが、スパース行列だから「平均を引く」とかやると台無し。どうする?

7

Page 8: 実践多クラス分類 Kaggle Ottoから学んだこと

sklearn.joblib

train.csvをnumpy.arrayにするだけで9秒かかる

作ったarrayをjoblib.dumpでファイルに書き出す

joblib.loadは1.5秒。

学習済みモデルとかもダンプできる!便利!

(注意点:大量のファイルができるので保存用のディレクトリを作るべきだった)

8

Page 9: 実践多クラス分類 Kaggle Ottoから学んだこと

とりあえずRandomForest

複数の特徴量を組み合わせたい→決定木

Kaggleでは決定木の仲間のRandomForestとGBDT(Gradient Boosted Decision Tree)が人気らしい(gbm, xgboostなど)

両方試してみよう

9

10 R Packages to Win Kaggle Competitionshttp://www.slideshare.net/DataRobot/final-10-r-xc-36610234

Page 10: 実践多クラス分類 Kaggle Ottoから学んだこと

RF/GBDT

trainの1/100のデータAと全データBとで比較

LR 0.76±0.01 -

RF(A) 0.62±0.02 2秒RF(B) 0.78±0.01 22秒GBDT(A) 0.70±0.02 50秒GBDT(B) 0.78±0.00 1時間15分!

GBDTは勾配を推定してその情報を利用するため2クラス分類しかできず、この例だと36回の2クラス分類が行われて時間がかかる。

LRよりは良い性能になった。

10

Page 11: 実践多クラス分類 Kaggle Ottoから学んだこと

submitしてみる

スコアはLog lossなので小さい方がよい

1次のLR 0.66674

2次のLR 0.65391(best)

RF 3.99786(えっ)

ここまでAccuracyでモデルを評価していたけど、ここでLog lossで評価しないとKaggleのスコアとの食い違いが大きいことに気が付く

11

Page 12: 実践多クラス分類 Kaggle Ottoから学んだこと

scoringオプション

cross_val_scoreはデフォルトでは正解率を返す

scoringオプションでlog lossなど色々なものを選ぶことができる

12

def do_cross_validation():model = make_model()cv = cross_validation.StratifiedKFold(ys)scores = cross_validation.cross_val_score(

model, xs, ys, cv=cv, scoring='log_loss')print("LogLoss: %0.2f (+/- %0.2f)"

% (scores.mean(), scores.std() * 2))

http://scikit-learn.org/stable/modules/model_evaluation.html#scoring-parameter

Page 13: 実践多クラス分類 Kaggle Ottoから学んだこと

Log lossでのLRとRFの比較

RFはデフォルトで木が10本。変えて試す。

RF(10) -1.57±0.08 30秒RF(20) -0.97±0.08 43秒RF(40) -0.72±0.02 1分25秒RF(100) -0.63±0.02 3分50秒RF(200) -0.60±0.02 11分RF(400) -0.59±0.01 14分RF(600) -0.59±0.01 22分RF(800) -0.59±0.01 -

RF(1000) -0.60±0.02 -

1次のLR -0.67±0.00 1分30秒

13

Page 14: 実践多クラス分類 Kaggle Ottoから学んだこと

Log lossでのLRとRFの比較

RF(400)Log loss -0.59±0.01

Accuracy 0.80±0.00

1次のLR

Log loss -0.67±0.00

Accuracy 0.76±0.01

RF(400)は1次のLRよりは良いはずだ!

14

Page 15: 実践多クラス分類 Kaggle Ottoから学んだこと

submitしてみる2

スコアはLog lossなので小さい方がよい

1次のLR 0.66674

2次のLR 0.65391(best)

RF(10) 3.99786

RF(100) 1.27508RF(400) 1.21971(あれれ?)

Log lossを最適化する問題*にRFを使うのが筋悪なのかな??

15

*追記:Kaggle Ottoは各クラスの確率値を提出させ、そのLog lossでランキングする課題

Page 16: 実践多クラス分類 Kaggle Ottoから学んだこと

合体

未解決課題:Log Lossを最適化する問題には何を使うのがよいのだろうか?→RFよりはLRの方がマシかな?

RFは「特徴量が閾値以上か」という二値分類機を多段で組み合わせて決定木を作ってくれる。

LRは「特徴量をどんな重みで足し合わせるとLog Lossが最小になるか」を求めてくれる

→この2つを合体!

16

Page 17: 実践多クラス分類 Kaggle Ottoから学んだこと

合体:GBDT+LR

GBDT(10)の予測した確率を特徴量に追加してLRを学習(以下GBCLR)

LR -0.67±0.00

GBCLR -0.54±0.01 (大躍進!)

Submitしてみた

LR 0.666742次のLR 0.65391

GBCLR 0.58467 (大躍進!)

17

(2次のLRのCVの結果がないのはexpがoverflowして計算できなかったため)

Page 18: 実践多クラス分類 Kaggle Ottoから学んだこと

LRの弱点をRFが補う

LRは与えられた特徴量の線形結合なので複数の特徴のANDの情報を使うには掛け合わせるなどした特徴を作る必要がある

決定木系は閾値関数のANDを人間の代わりに試行錯誤してくれる

作られた特徴量を入れる代わりに9次元に潰された情報を入れただけで性能がかなりアップした

18

Page 19: 実践多クラス分類 Kaggle Ottoから学んだこと

LRの弱点をRFが補う2

LRは重みつき足し合わせなのでスケールを適切に調整する必要がある

RFは閾値でぶった切るのでスケールは無意味

今回のtrainデータは実は0に鋭いピークがあって指数的に頻度が下がり大きい方の値は50とかもあるような「全然正規分布じゃない」分布

どうスケール調整するかは悩ましい問題だった

19

Page 20: 実践多クラス分類 Kaggle Ottoから学んだこと

合体路線の今後の案

GBRTの木の数を増やす(つまらない)

GBRT全体での推測結果ではなく、GBRTの各木の推測結果を特徴量にする

GBRTの各木の各リーフをバイナリ特徴量にする(特徴量の数がとんでもないことになる)

20

Page 21: 実践多クラス分類 Kaggle Ottoから学んだこと

土台固め

モデルの改善よりも土台周りで色々見えてきた問題を先に解決しておこう

21

Page 22: 実践多クラス分類 Kaggle Ottoから学んだこと

--after複数同時に走らせるとメモリが心配

次のを走らせるために、今走っている処理が終わるのを人間が待つのは嫌

そこで--after=<pid>オプションを指定するとそのPIDのプロセスが死ぬまで待ってから自分自身の処理を続行するようにした

22

def wait(pid):while True:

try:os.kill(pid, 0)

except OSError:return

else:time.sleep(60)

その後プロセスIDを手で打つのもたるいので--after=autoで一番新しいPythonを対象にするようにした

if args.after == "auto":pid = int(subprocess.check_output("pgrep python", shell=True

).split()[-2])

Page 23: 実践多クラス分類 Kaggle Ottoから学んだこと

joblib再び

joblibの保存先をソースフォルダから分けた

data/fooに保存するとdata/foo_2000.npyとか(特にRFだと)2000個のファイルが作られる

保存されたモデルを一覧で見づらい *

不要なものを削除するのも不安 **

data/foo/indexに保存して、消すときにはfooをディレクトリごと消すのが吉かな(でも今から変えるのは既存の保存データの扱いが面倒。次回やる***)

23

* ls data | grep –v npy** 富豪的に「消さない」ってのもありか*** forest-coverでやった。

Page 24: 実践多クラス分類 Kaggle Ottoから学んだこと

保存データの名前空間今はフラットな名前空間にモデルも学習データも混在して直置きされているが…

24

41252

43563

46334

GBC

GBCLR

LABELLR

cross_lr

rfc

rfc10

rfc100

test_cross_data

test_data

train_GBC

train_cross_data

train_data

train_labeled

←PIDで自動保存されたモデル、リネームされてないのはいらないやつだから消してもいいはずだが…

←自動保存されたモデルをリネームしたもの

←モデルの保存名をソースにハードコードしてた時代

←モデルの種類とパラメータからモデルの保存名を生成しようとしていた時代(データを変え始めて破綻)

←変換済みテストデータ(保存し忘れがある模様)(PIDでの自動保存をこっちにも追加すべきか)

←変換済み学習データ

カオス!

Page 25: 実践多クラス分類 Kaggle Ottoから学んだこと

保存データの名前空間

「なんとなくな命名規則」で今まで進んできたがデータの側をいじり始めて:

「モデルM1」「モデルM1で特徴量を付加したtrain_M1」「train_M1で学習したモデルM2…の名前は…」

きな臭いにおいがし始めている…。

(--train=train_foobar ってオプションも微妙)

25

Page 26: 実践多クラス分類 Kaggle Ottoから学んだこと

--name

--name=<name>が指定されているとき、そのプロセスが作るすべてのファイル名に<name>が入る(例: 学習済みモデル<name>.npy, 投稿用データsubmit_<name>.csv)

指定されない時、モデル種別・元データ・PIDから一意な名前を生成して使う

・わかりやすい名前を付けることができる・名前を付けなくても後から探しやすい・事後的にmvで分かりやすい名前に変えられる・適当にやっても既存のファイルを壊さないが実現される

26

Page 27: 実践多クラス分類 Kaggle Ottoから学んだこと

データの指定

学習データをオプションで指定するのは正しい設計だろうか??

ユースケース「-c --train=train_fooでクロスバリデーション」「うん、いい成果だ、submitしよう」「-s --train=train_foo」→テストデータが指定されていないため、デフォルトのものを使おうとして次数ミスマッチで死亡

27

Page 28: 実践多クラス分類 Kaggle Ottoから学んだこと

データではなく変換を指定

オプションでデータを指定するのではなく変換方法を指定すべきでは?(変換済みデータがない場合は生成・保存)

28

Page 29: 実践多クラス分類 Kaggle Ottoから学んだこと

と思ったのだけど

ユースケース:4000次元×60000行のtrainデータは作れて学習もできたが、4000次元×140000行のtestデータは作るときか使用するときにメモリ不足で死ぬ

メモリ不足で死んだときには自動で少しずつ作るモードにフォールバックすべき?

今は手書き個別対処(どうせ1日に3件しかsubmitできないので)

29

追記:その後write_submit関数がテストデータのイテレータを取る設計に変更した

Page 30: 実践多クラス分類 Kaggle Ottoから学んだこと

行列の分割

arrayを少しずつ処理するためにnp.arrayを分割するコード。numpy.array_splitという便利なものがあるのに今気づいた…。

30

def split_array(xs):

N = len(xs)

for start, end in split(N):

yield xs[start:end]

……# deflate(inflate(xs))相当

new_xs = np.r_[tuple(

deflate(inflate(xs_))

for xs_ in split_array(xs))]

self.model.fit(new_xs, ys)

def split(N, divide=10):

M = N / divide

for i in range(divide):

start = i * M

end = (i + 1) * M

if i == divide - 1:

end = N

yield start, end

Page 31: 実践多クラス分類 Kaggle Ottoから学んだこと

LabelBinarizer

特徴量に名義尺度のものが混ざっているという噂

分布を眺めてみたけどそれらしき分布は見つからない…(でも名義尺度の頻度順ソートかも)

全特徴量をLabelBinarizer#fitしてLRしたら改善LR -0.67±0.00 0.66674

LABELLR -0.61±0.00 0.59759

確かに名義尺度が混ざっているのかも…。

31

for i in range(NUM_FEATURES):

lb = preprocessing.LabelBinarizer()

lb.fit(xs[:,i])

labels[i] = lb.transform(xs[:,i])

xs = np.c_[tuple([xs] + labels)]追記:np.c_[tuple(…)]はnp.hstackがよさそう→

Page 32: 実践多クラス分類 Kaggle Ottoから学んだこと

4053次元

全特徴を名義尺度とみなしたものを追加すると特徴量は4053次元になる

GBDT(10)元データ -0.78±0.00 1時間15分名義尺度 -1.08±0.01 2時間33分

GBDT(20)名義尺度 -0.85±0.01 5時間04分

決定木の眷属は特徴量が多くなると「うまい組み合わせを選べる確率」が下がって性能が出なくなる?→LRをL1でつかう

32

Page 33: 実践多クラス分類 Kaggle Ottoから学んだこと

L1による特徴選択

LogisticRegression(penalty=‘l1’, C=0.01)で4053次元の名義尺度データを学習

model.transform(xs)で4053次元のデータを低次元に投影→179次元になった

33

Page 34: 実践多クラス分類 Kaggle Ottoから学んだこと

LB→LR(L1)→GBDT

元データA、LabelBinarizerしたデータB、それをLR(L1)で圧縮したデータCについて:

GBDT(10)A -0.78±0.00 1時間15分B -1.08±0.01 2時間33分C -1.08±0.01 7分14

GBDT(20)B -0.85±0.01 5時間04分C -0.85±0.01 15分5

GDBT(40)C -0.71±0.01 26分49

34

時間の差の大きさに一瞬戸惑ったが、データの次元が22倍で15分の22倍は5時間半だから変というほどではないか?むしろGBDT(10)のAが変?

Page 35: 実践多クラス分類 Kaggle Ottoから学んだこと

全部入り(ICHI)

「オリジナルのtrain.csv

+GBDT(100)で予測したクラス+LB→LR(L1)→GBDT(40)で予測したクラス」を全部まとめてLRで学習させたモデル

略してICHI

LR -0.67±0.00 0.66674

GBCLR -0.54±0.01 0.58467

LABELLR -0.61±0.00 0.59759

ICHI -0.53±0.00 0.55831

35

Page 36: 実践多クラス分類 Kaggle Ottoから学んだこと

全部入り(NII)

ICHIの特徴量にRF(400)での推定結果を加えて学習させたLR、略してNII

RF(400) -0.59±0.01

ICHI -0.53±0.00

NII -0.01±0.00 (えっ?!)

Submitしてみた

ICHI 0.55831NII 0.63648 (悪化…。)

アンサンブル学習のやり方がまずい?保留。

36

Page 37: 実践多クラス分類 Kaggle Ottoから学んだこと

PCAの効果

「PCAで次元削減して~するとよい」という噂

93次元しかないデータなのに、いきなり「分散が小さい」って理由で何軸かの情報を捨ててしまうとか、悪くなる気がする……。

でも、検証してみよう。

37

Page 38: 実践多クラス分類 Kaggle Ottoから学んだこと

PCAの効果2

0:オリジナル 1:PCA掛けただけ2:PCAで白色化 3:PCAで50次元に削減4:30次元に削減 5:10次元に削減

RF(10) LR0 -1.57±0.08 -0.67±0.001 -1.67±0.08 -0.67±0.002 -1.68±0.09 -0.68±0.003 -1.65±0.03 -0.71±0.004 -1.77±0.03 -0.78±0.005 -2.36±0.03 -1.06±0.01

次元削減のダメージは大きい

38

Page 39: 実践多クラス分類 Kaggle Ottoから学んだこと

PCAの効果3

次元削減ではなく軸を回転することによって「軸方向の分割」で構成されている決定木は性能が向上する可能性がある。確かめてみよう。

RF(400)PCAなし -1.57±0.08

PCAあり -1.59±0.01

→目立った効果はない「PCA→RF(400)」の結果を追加した「SAN」を作るつもりだったけどやめた

39

Page 40: 実践多クラス分類 Kaggle Ottoから学んだこと

分離が難しいクラス

クラス2とクラス3の分離が難しいという噂・どうすれば自分でそれに気づけるか・どう対処するか

作ったモデルで分類して、間違えて分類したものに関する統計データが手軽に得られるべき

・クラス2と3だけのデータでモデルを学習したら分離に適切な特徴量が出てくるのでは・間違えて分類したものだけ選んで学習したらどうか(手動AdaBoostもどき)

40

Page 41: 実践多クラス分類 Kaggle Ottoから学んだこと

sklearn.svm.SVC

当初、木やリーフの情報を特徴量にするつもりでRFをチョイスしていたけど、結局、推定結果を特徴量にしているのでRFである必要はない

RFで軸に沿ってまっすぐ切るのは既にやったからどうせなら曲線で切りたい

→じゃあサポートベクターマシン!

41

Page 42: 実践多クラス分類 Kaggle Ottoから学んだこと

SVC

「SVCの計算量はデータの二乗よりでかいオーダーだから10000以上だとつらいかもね」(意訳)

とマニュアルに書いてある。測ってみる。

N=100 16ms

N=200 54ms

N=400 191ms

N=1000 1.08s

N=2000 3.7s

N=4000 17s

N=10000 102s

42

Page 43: 実践多クラス分類 Kaggle Ottoから学んだこと

YON

ICHIでtrain.csvをpredictしてLog Lossの大きい方から10000件のデータを選んでSVCし、そのpredict結果を特徴量として追加。

ICHI -0.53±0.00 0.55831

NII -0.01±0.00 0.63648

YON -0.47±0.01 0.54944 (改善!)

43

# 2行目もっとうまく書ける?

lp = model.predict_proba(xs)

logloss = np.array([lp[i, ys[i] - 1] for i in range(len(xs))])

bad_items = logloss.argsort()[:N_BEST]

Page 44: 実践多クラス分類 Kaggle Ottoから学んだこと

アンサンブル学習

アンサンブル学習について調べていたら [1][2][3] 、僕と同じLRによるアンサンブルをやっているソースコード [4] を発見。彼は711

人中17位になったそうな。対象コンペ [5] は2クラス分類でLog

Lossで評価される、今回のによく似たタイプ。

[1] How to ensemble different models? - Africa Soil Property Prediction Challenge | Kaggle

https://www.kaggle.com/c/afsis-soil-properties/forums/t/10753/how-to-ensemble-different-models

[2] Best Ensemble References? - Africa Soil Property Prediction Challenge | Kaggle

https://www.kaggle.com/c/afsis-soil-properties/forums/t/10391/best-ensemble-references/54305

[3] Question about the process of ensemble learning - Predicting a Biological Response | Kaggle

http://www.kaggle.com/c/bioresponse/forums/t/1889/question-about-the-process-of-ensemble-

learning/10945

[4] kaggle_pbr/blend.py at master · emanuele/kaggle_pbr

https://github.com/emanuele/kaggle_pbr/blob/master/blend.py

[5] Description - Predicting a Biological Response | Kaggle

http://www.kaggle.com/c/bioresponse

44

Page 45: 実践多クラス分類 Kaggle Ottoから学んだこと

アンサンブラーの実装

given X, Y, Xsub, make YsubM: モデルの個数 pp: Predict Probability

45

Page 46: 実践多クラス分類 Kaggle Ottoから学んだこと

GO

Ensamble(LR, GBDT(100), LB→LR(L1)→GBDT(40),

RF(400), ICHI→LogLoss Top10000→SVC)

をやりたいのだけど、スモールスタートで

Ensamble(LR, GBDT(100), LB→LR(L1)→GBDT(40),

RF(100), ICHI→LogLoss Top1000→SVC)

をやった。2時間36分。

ICHI -0.53±0.00 0.55831

YON -0.47±0.01 0.54944

GO - 0.47977 (すごい改善!)

46

Page 47: 実践多クラス分類 Kaggle Ottoから学んだこと

ROKU

Ensamble(LR, GBDT(100), LB→LR(L1)→GBDT(40),

RF(400), ICHI→LogLoss Top10000→SVC)

機械学習勉強会までに計算が終わるか終わらないか微妙なところ(朝9時現在)

10時間3分

GO 0.47977ROKU 0.46783 (改善)

Top10% 0.44371 (目標)

47

順位的には2301人中 631位→513位

Page 48: 実践多クラス分類 Kaggle Ottoから学んだこと

アンサンブラーの高速化

個別のモデルに関する部分はメモ化できる。

少し手を加えれば普通のクロスバリデーションとしても使える。

クロスバリデーションで色々なモデルを試す過程で、ブレンド用のデータを吐き出して置けば、それを束ねてLRするだけで良いのでは?

48

Page 49: 実践多クラス分類 Kaggle Ottoから学んだこと

以下追記49

Page 50: 実践多クラス分類 Kaggle Ottoから学んだこと

写真150

Page 51: 実践多クラス分類 Kaggle Ottoから学んだこと

写真151

93*6万次元のXと1*6万次元のYと93*14万次元のXsubから9*14万次元のYsubを作る。9はクラス数。10foldで9割のtrainと1割のtestにわけ、trainXとtrainYでモデルMを学習。モデルMにtestXを入れて確率推定したものPを10個並べて9*6万のQができる。それぞれのモデルにそれをしてM個並べて(9*M)*6万のRができ、RとYとでLRを学習。またモデルMにXsubを入れて9*16万のS、SをM個平均してT、Tを並べてUを作る。先ほど学習したLRにUを入れて確率推定したものがYsub。

Page 52: 実践多クラス分類 Kaggle Ottoから学んだこと

僕のアンサンブラー

ICHIやNIIで使った僕のアンサンブラーも各モデルの推定結果を特徴量にしてLRを学習するところは同じ。

Foldしてないのが違い(過学習の原因)

52

アンサンブルしない普通のをこの記法で描くとこう

Page 53: 実践多クラス分類 Kaggle Ottoから学んだこと

写真253

M個並べるのよりも手前はモデルごとに計算できるので、メモ化可能。モデルにはKNNや各種カーネルのSVM、NBなど色々突っ込める。後段で学習しているLRは各モデルの予測結果と正解から予測結果の良さを得てアンサンブルの際の混ぜあわせ重みを決定する役割を果たしている。

Page 54: 実践多クラス分類 Kaggle Ottoから学んだこと

追記2

コンペが終わったので・最終的にどうなったか・上位ランカーはどういう方法を使っていたか・新しく知った手法を試してみるを追記

54

Page 55: 実践多クラス分類 Kaggle Ottoから学んだこと

1ページで前回のおさらい

Kaggle Otto Group Product Classification Challenge

IN:93個の特徴量、OUT:9クラスに分類train.csv 61878行 test.csv 144368行各クラスである確率を提出し、log lossで評価

西尾の戦略RandomForestとかSVMとかで予測した結果を特徴量としてLRでアンサンブル。特徴量を5-fold CVで作るようにしたら性能0.54→0.47

55

Page 56: 実践多クラス分類 Kaggle Ottoから学んだこと

成果発表

西尾:

public 0.45545 799位private 0.45715 838位/3512

1位のチーム:

public 0.38055

private 0.38243

アンサンブラ改善に匹敵する大きな差が。上位入賞者がモデルを公開しているのでよく読んで技術を盗もう!

56

Page 57: 実践多クラス分類 Kaggle Ottoから学んだこと

1位のチーム

Gilberto Titericz & Stanislav Semenov

3層構造

1層目:33個のモデル(これの予測結果を2層目の特徴量として使う)と8個の追加特徴量

2層目:

GDBT(XGBoost)

NN(Lasagna)AdaBoost(ScikitのExtraTree)

3層目:重み付き平均

57

https://www.kaggle.com/c/otto

-group-product-classification-

challenge/forums/t/14335/1st-

place-winner-solution-gilberto-

titericz-stanislav-semenov

Page 58: 実践多クラス分類 Kaggle Ottoから学んだこと

1層目のモデル

-Model 1: RandomForest(R). Dataset: X

-Model 2: Logistic Regression(scikit). Dataset: Log(X+1)

-Model 3: Extra Trees Classifier(scikit). Dataset: Log(X+1)

(but could be raw)

-Model 4: KNeighborsClassifier(scikit). Dataset:

Scale( Log(X+1) )

-Model 7: Multinomial Naive Bayes(scikit). Dataset:

Log(X+1)

Log(X+1)。これ計算してplotまではしたけど形がイマイチで特徴量として採用してなかった…

58

Page 59: 実践多クラス分類 Kaggle Ottoから学んだこと

1層目のモデル:FM

-Model 5: libfm. Dataset: Sparse(X). Each feature

value is a unique level.

libfm*はSVDなどのような行列分解系の方法をSVMと組み合わせることによって、SVMが苦手なスパースなデータに対してよい性能を出すFactorization Machines**の実装。

59

* http://www.libfm.org/

** http://www.ismll.uni-hildesheim.de/pub/pdfs/Rendle2010FM.pdf

Page 60: 実践多クラス分類 Kaggle Ottoから学んだこと

1層目のモデル:NN

-Model 6: H2O NN. Bag of 10 runs. Dataset:

sqrt( X + 3/8)

H2Oは多層のNN(いわゆるディープラーニング)

の実装を容易にするライブラリ。

60

http://0xdata.com/product/

Page 61: 実践多クラス分類 Kaggle Ottoから学んだこと

1層目のモデル:NN

-Model 8: Lasagne NN(CPU). Bag of 2 NN runs.

First with Dataset Scale( Log(X+1) ) and second

with Dataset Scale( X )

-Model 9: Lasagne NN(CPU). Bag of 6 runs.

Dataset: Scale( Log(X+1) )

Lasagneは多層のニューラルネットを実装することを容易にするライブラリ。Python。

61

http://lasagne.readthedocs.org/en/latest/index.html

Page 62: 実践多クラス分類 Kaggle Ottoから学んだこと

1層目のモデル:t-SNE

-Model 10: T-sne. Dimension reduction to 3

dimensions. Also stacked 2 kmeans features

using the T-sne 3 dimensions. Dataset: Log(X+1)

t-SNEは” t-distributed stochastic neighbor

embedding”の略。次元削減の方法。

62

t-distributed stochastic neighbor embedding - Wikipedia, the free encyclopedia

http://en.wikipedia.org/wiki/T-distributed_stochastic_neighbor_embedding

sklearn.manifold.TSNE — scikit-learn 0.16.1 documentation

http://scikit-learn.org/stable/modules/generated/sklearn.manifold.TSNE.html

Page 63: 実践多クラス分類 Kaggle Ottoから学んだこと

1層目のモデル:Sofia-Model 11: Sofia(R). Dataset: one against all with learner_type="logreg-pegasos" and loop_type="balanced-stochastic". Dataset: Scale(X)-Model 12: Sofia(R). Trainned one against all with learner_type="logreg-pegasos" and loop_type="balanced-stochastic". Dataset: Scale(X, T-sne Dimension, some 3 level interactions between 13 most important features based in randomForestimportance )-Model 13: Sofia(R). Trainned one against all with learner_type="logreg-pegasos" and loop_type="combined-roc". Dataset: Log(1+X, T-sneDimension, some 3 level interactions between 13 most important features based in randomForestimportance )

63

Page 64: 実践多クラス分類 Kaggle Ottoから学んだこと

Sofia

Sofia*色々なアルゴリズムの詰め合わせ。パラメータでlogreg-pegasosを指定しているから

>Logistic Regression (with Pegasos Projection)を使っているのだろう。

Pegasos**はSVMのSGDによる最適化部分を置き換えることで収束速度を改善するもの。ここではLRの最適化に流用している。

64

* https://code.google.com/p/sofia-ml/

** Pegasos: Primal Estimated sub-GrAdient SOlver for SVM

http://www.ee.oulu.fi/research/imag/courses/Vedaldi/ShalevSiSr07

.pdf

Page 65: 実践多クラス分類 Kaggle Ottoから学んだこと

1層目のモデル:xgboost

-Model 14: Xgboost(R). Trainned one against all. Dataset: (X, feature sum(zeros) by row ). Replaced zeros with NA.-Model 15: Xgboost(R). Trainned Multiclass Soft-Prob. Dataset: (X, 7 Kmeans features with different number of clusters, rowSums(X==0), rowSums(Scale(X)>0.5), rowSums(Scale(X)< -0.5) )-Model 16: Xgboost(R). Trainned Multiclass Soft-Prob. Dataset: (X, T-sne features, Some Kmeans clusters of X)-Model 17: Xgboost(R): Trainned Multiclass Soft-Prob. Dataset: (X, T-sne features, Some Kmeans clusters of log(1+X) )-Model 18: Xgboost(R): Trainned Multiclass Soft-Prob. Dataset: (X, T-sne features, Some Kmeans clusters of Scale(X) )

65

xgboostはGBDTの実装の一つ

https://github.com/dmlc/xgboost

Page 66: 実践多クラス分類 Kaggle Ottoから学んだこと

1層目のモデル:NN(GPU)

-Model 19: Lasagne NN(GPU). 2-Layer. Bag of 120

NN runs with different number of epochs.

-Model 20: Lasagne NN(GPU). 3-Layer. Bag of 120

NN runs with different number of epochs.

Lasagnaを使ってNNをGPU実装。

66

Page 67: 実践多クラス分類 Kaggle Ottoから学んだこと

1層目のモデル:xgboost

-Model 21: XGboost. Trained on raw features.

Extremely bagged (30 times averaged).

特に工夫なくxgboostを30回走らせて結果を平均したもの。

データをダウンロードして、まず真っ先に「xgboostを繰り返すプログラム」を走らせてから他の実装を始めたと憶測

67

Page 68: 実践多クラス分類 Kaggle Ottoから学んだこと

1層目の特徴量:KNN

-Model 22: KNN on features X + int(X == 0)

-Model 23: KNN on features X + int(X == 0) +

log(X + 1)

-Model 24: KNN on raw with 2 neighbours

-Model 25: KNN on raw with 4 neighbours

:

-Model 33: KNN on raw with 1024 neighbours

モデル4にKNN(Scale( Log(X+1) ))があったけど特徴量としても追加している。異なるチームメンバーが別個に実装したと憶測。

68

Page 69: 実践多クラス分類 Kaggle Ottoから学んだこと

1層目の特徴量:Distance

-Feature 1: Distances to nearest neighbours of

each classes

-Feature 2: Sum of distances of 2 nearest

neighbours of each classes

-Feature 3: Sum of distances of 4 nearest

neighbours of each classes

-Feature 4: Distances to nearest neighbours of

each classes in TFIDF space

-Feature 5: Distances to nearest neighbours of

each classed in T-SNE space (3 dimensions)

最寄りクラスタまでの距離

69

Page 70: 実践多クラス分類 Kaggle Ottoから学んだこと

1層目の特徴量:謎

-Feature 6: Clustering features of original dataset

何を意味しているのかよくわからない

70

Page 71: 実践多クラス分類 Kaggle Ottoから学んだこと

1層目の特徴量:非ゼロ

-Feature 7: Number of non-zeros elements in

each row

非ゼロの特徴の数

-Feature 8: X (That feature was used only

in NN 2nd level training)

生データ

71

Page 72: 実践多クラス分類 Kaggle Ottoから学んだこと

2層目3層目

XGBOOST(GDBT): 250 runs.

Lasagna(NN): 600 runs.

ExtraTree(ADABOOST): 250 runs.

3層目でXGBOOSTとNNを0.65:0.35で幾何平均その後ETと0.85:0.15で算術平均

平均の種類を変えてパラメータサーチすることがかえって過学習の原因にならないか疑問。

72

Page 73: 実践多クラス分類 Kaggle Ottoから学んだこと

自分の方法との比較

SVMがない(改善しないので捨てたらしい)→おそらくFMで十分カバーされている

PCAがない(これも捨てたらしい)→おそらくt-SNEで十分カバーされている

非ゼロ個数を特徴に追加→同じ

距離を特徴に追加→その発想はなかった

73

Page 74: 実践多クラス分類 Kaggle Ottoから学んだこと

1層目は弱い学習機でもよい

1層目でPoorでも2層目の改善に貢献する

> Interestingly some of our models scored very

poorly at 1st level. But contributed in 2nd level. ex.

Model 2 CV ~ 0.65, Model 5 CV ~ 0.55.

Model2はLR、Model5はFM

74

Page 75: 実践多クラス分類 Kaggle Ottoから学んだこと

計算コスト

> I used AWS Amazon CPU server with 32 cores

for calculating XGboost, etc. And used AWS

Amazon GPU server with 4 Nvidia Grid K520 for

calculating NNs. Models on 2nd level is really

computationally hard.

32コアなのはc3.8xlarge。1時間$1.68。スポットインスタンスを利用して$0.256。何時間走らせたのかは不明。

75

Page 76: 実践多クラス分類 Kaggle Ottoから学んだこと

Leakage

CVの際のLeakageを気にする声

一方、Leakageしない別のアプローチでは計算コストが高くなりすぎることから「悪くないトレードオフ」との指摘もある。

これはコードが公開されてから再確認が必要そう

76

Page 77: 実践多クラス分類 Kaggle Ottoから学んだこと

6位チーム

“it seems like this competition was all about two

things: finding ways to get different biases in

the individual models, and having a good

method for ensembling beyond just

averaging.”

77

https://www.kaggle.com/c/otto-group-product-classification-

challenge/forums/t/14296/competition-write-up-optimistically-convergent

Page 78: 実践多クラス分類 Kaggle Ottoから学んだこと

アンサンブル

5-fold stratifiedでモデルを学習して、trainデータ全体に対するpredictionを作る。

→ケース1: 5つでBaggingしてtestに対して使う

→ケース2: 使わずに別途全データでtraining

→最終的に: そのpred.を使ってアンサンブルのパラメータをfitting

大枠では僕のと同じ。彼らのアンサンブラはNN

78

Page 79: 実践多クラス分類 Kaggle Ottoから学んだこと

ニューラルネット全部ReLU。出力層はSoftmax。

LB=0.446: Input -> 0.13 Dropout -> 2500 -> 0.77 Dropout -> 1300 -> 0.35 Dropout -> 40 -> 0.1 Dropout -> Output (AdaGrad, 600 epochs, batch=1024, linear decreasing learning rate starting at 0.04, ending at 0.005)

LB=0.441: Input -> 0.15 Drop -> 2000 -> 0.7 Drop -> 1200 -> 0.4 Drop -> 40 -> Output (AdaGrad, 400 epochs, batch = 512, learning rate from 0.04 to 0.001)

LB=0.463: Input -> 0.15 Drop -> 180 -> 0.1 GaussianNoise-> 0.1 Drop -> 180 -> 0.05 Drop -> 180 -> 0.05 Drop -> 140 -> 0.05 Drop -> 140 -> 0.05 Drop -> 140 -> 0.1 Drop -> 140 -> 0.1 GaussianNoise -> 160 -> Output (AdaGrad, 100 epochs, batch=512, rate = 0.03 to 0.005)

79

Page 80: 実践多クラス分類 Kaggle Ottoから学んだこと

ニューラルネット

>One thing is that even though the network with

2000 nodes in the first layer had a better LB score,

it ensembled significantly worse than the one

with 2500 nodes.

入力層が2000個の方がLBでのスコアはよかったが、アンサンブル結果は2500個の方がよかった→2500個の側が運よくいい特徴を拾っていただけではないかと憶測

80

Page 81: 実践多クラス分類 Kaggle Ottoから学んだこと

Boosted Neural Nets

Input→0.15→2000→0.7→1200→0.4→40→Outputをrate=0.02 .. 0.005で25エポックだけ学習

→Log lossが平均Log lossの2%より小さいRowを削除して学習しなおす(僕がモデルYONでLogLoss

の大きい方から1万件だけでSVCを学習したのと同じようなアプローチ)

→これを16回繰り返す(!)

→0.433のNNができた(僕のスコアを超えた)

81

Page 82: 実践多クラス分類 Kaggle Ottoから学んだこと

SGDで特徴探し

SGDは最高で0.58程度だけど、シンプルな仕組みであるがゆえに「よい特徴を追加した」時に性能が大きく上がるので特徴探しに便利。

「大きい方から4件の特徴の位置に1が立っている93次元ベクトル」

特徴AとBのインタラクションを「A*B」ではなく「1 if A > B else 0」にした方がよい成績。

82

Page 83: 実践多クラス分類 Kaggle Ottoから学んだこと

SVM

カラムごとにスケールを調整するとよい。

83

Page 84: 実践多クラス分類 Kaggle Ottoから学んだこと

キャリブレーション

NNに対してCalibratedClassifierCVを使ってキャリブレーションをすると大きく改善する。

10-fold isotonic calibrationで、0.443→0.435

84

http://scikit-

learn.org/stable/modules/generated/sklearn.calibration.CalibratedClassifierCV.html

Page 85: 実践多クラス分類 Kaggle Ottoから学んだこと

アンサンブル

アンサンブルの手法が最も重要

このコンペはLog lossを問うものだからもしたくさんのものを平均しすぎると平均回帰によってLog lossが悪化する→NN-basedアンサンブラ→0.58!

85

Page 86: 実践多クラス分類 Kaggle Ottoから学んだこと

アンサンブル

2つのモデルをブレンドする際に、まずその2つのモデルが同じクラスを返す確率pXYを求め、モデル1の重みをbとして

Pb = pXY * (P1*b + P2*(1-b) ) + (1-

pXY)*( P1^(2*b) * P2^(2*(1-b)) ) / ( P1^(2*b) *

P2^(2*(1-b)) + (1-P1)^(2*b) * (1-P2)^(2*(1-b)) )

でブレンド後の確率を求める。

この有用性に関してはよくわからない。0.0007の改善になったらしい。

86

Page 87: 実践多クラス分類 Kaggle Ottoから学んだこと

FE不要論

“Minimal feature engineering was needed, as all

the features were count of some events not

disclosed to participants”

「特徴量がイベントの回数である」という説明を読み落としていた…。

これだとラベル化は筋悪ということになる。

87

https://kaggle2.blob.core.windows.net/forum-message-

attachments/79384/2507/summary.pdf?sv=2012-02-12&se=2015-05-

28T02%3A29%3A24Z&sr=b&sp=r&sig=GSMFMgUpNYb%2B4xZaWtxF%2BNzT3s%2F

Ve3kwvoHjHdqS9qM%3D

Page 88: 実践多クラス分類 Kaggle Ottoから学んだこと

モデル

XGBoost: scikit-learnの他のモデルとの一貫性のためにラッパーを実装、0.44x

NN: Lasagne使ってReLUとDropout、GPU。Sparse AutoencoderとReLUで多層Perceptronとも書いてあるけど、Lasagneでやったか不明* 0.44x

SVM: RBFカーネルが一番 0.45x

RF, Extra Trees: ETがRFよりも良い成績。キャリブレーションがとても有効。0.44x

あと2次のLRとKNN

88

* Referenceにkerasが載ってるからそっちかも

Page 89: 実践多クラス分類 Kaggle Ottoから学んだこと

パラメータサーチ

・人力GD

→収束カーブを見て「もっとDropoutが必要だ」などと判断できるメリット

・グリッドサーチパラメータの少ないSVCとかRFに有効

・ランダムサーチ何が重要なパラメータかわからない時に有用

89

Bergstra and Bengio(2012)“Random Search for Hyper-Parameter Optimization”

http://www.jmlr.org/papers/volume13/bergstra12a/bergstra12a.pdf

Page 90: 実践多クラス分類 Kaggle Ottoから学んだこと

ランダムサーチ

寄与の小さいパラメータがある場合、Grid Layoutではその軸方向のサンプルが無駄になってしまう

90

[Bergastra and Bengio 2012]から引用

Page 91: 実践多クラス分類 Kaggle Ottoから学んだこと

ガウス過程によるパラメータサーチ

「良い結果が得られるパラメータを探す」は関数の最大値を探す最適化問題

関数が滑らかである仮定をガウス過程として導入することで、未探索の値に対してのUCBが計算できるようになる

UCBが最大となる点を探索していくことでRegret

最小の探索ができる(強化学習的発想)

91

Srinivas+ (2010) “Gaussian Process Optimization in the Bandit

Setting:

No Regret and Experimental Design”

http://las.ethz.ch/files/srinivas10gaussian.pdfhttp://www.robots.ox.ac.uk/seminars/Extra/2012_30_08_MichaelOsborne.pdf p.82から

Page 92: 実践多クラス分類 Kaggle Ottoから学んだこと

Random Direction

現在の最良のパラメータを中心として正規分布で適当に選んで実験、良くなっていたら採用、悪くなっていたら捨てるだんだん正規分布の分散を狭める

(局所解にはまりそうな…)

92

Page 93: 実践多クラス分類 Kaggle Ottoから学んだこと

実験

XGBoostは5つのパラメータがある。- 木の最大数 5..35

- shrinkage 0.4..1- 最大深さ 4..10

- 行サブサンプリング 0.4..1

- 列サブサンプリング 0.4..1

これを上記4手法でパラメータサーチ

93

Page 94: 実践多クラス分類 Kaggle Ottoから学んだこと

結果94

RDが意外といいけど、予想通りLocal Minimumにはまるケースが多く分散が大きくなっている。GPは安定しているが、平均的にはRDに負けてる。GP自体にハイパーパラメータがあり、それのチューニングはされていない。

Page 95: 実践多クラス分類 Kaggle Ottoから学んだこと

アンサンブル

まず単純平均を試してみた→まあまあ

シグモイドの逆関数で変換(IST)してからLR→改善

最終的に:ISTしてから隠れ層1枚のNNでFittting

NNのハイパーパラメータはGP UCBで決めた。

何度か異なる乱数シードで走らせると0.00xぐらい改善する

比較:自分のやったのは「ISTしないでLR」

95

Page 96: 実践多クラス分類 Kaggle Ottoから学んだこと

25位?

xgboostでモデルを作ってGAでアンサンブル

特徴量:総和、非ゼロの個数、 1,2,3の個数、最大値、最大値の場所、t-SNE、距離

今までで最良のモデルによる推定結果を特徴量として追加する(僕と同じ)

96

https://www.kaggle.com/c/otto-group-product-classification-

challenge/forums/t/14315/strategy-for-top-25-score

Page 97: 実践多クラス分類 Kaggle Ottoから学んだこと

距離

各行に対して、各クラスの中のすべての行との距離を計算して、距離の分布を求め、その分布の10, 25, 50, 75, 90th percentileを45次元の特徴量として加える

1位チームの「各クラスの最も近い点への距離」は0パーセンタイルだけを使っていることに相当する。階層的クラスタリングでの、ある点がどのクラスタに最も近いかを判定する上で最も近い点か最も遠い点かそれとも平均かセントロイドか…

という議論*に似ている。

97

* http://en.wikipedia.org/wiki/Hierarchical_clustering のLinkage criteriaの節

Page 98: 実践多クラス分類 Kaggle Ottoから学んだこと

GAでアンサンブル

DEAP* を使う

the gene was a vector length 20 composed of

different model numbers.

20個以上あるモデルの中から20個のモデルをどう選ぶかを遺伝子にコーディングし、選んだモデルを平均したののスコアを最適化する

98

* https://github.com/deap/deap

Page 99: 実践多クラス分類 Kaggle Ottoから学んだこと

112位相当:Meta-bagging

“Meta-bagging”によって112位相当のスコアが出せるという主張。“Meta-bagging”という言葉は広く使われているものではない。

第1層でSVM、RF、GBM*などを学習した後、その結果の幾何平均と元データとを入力とするNN

を50個学習してそれらをBaggingする

99

https://www.kaggle.com/c/otto-group-product-classification-

challenge/forums/t/14295/41599-via-tsne-meta-bagging/79084

* GBM=Gradient Boosting Machine, たとえばxgboost

Page 100: 実践多クラス分類 Kaggle Ottoから学んだこと

やってみる

xgboost

Lasagne

Gaussian Process

t-SNE

100

Page 101: 実践多クラス分類 Kaggle Ottoから学んだこと

xgboost

R用だけどPythonからでも叩ける

xgb.train叩くだけ、予想外に楽&早かった

Ottoのデータに対してCVして他の方法と比べてみよう→Sklearnのインターフェイスと揃えるためにラッパーを自分で書いて少しトラぶった。すでに書いて公開している人もいる。これを使うのでもよかったかも。

101

https://gist.github.com/slaypni/b95cb69fd1c82ca4c2ff

Page 102: 実践多クラス分類 Kaggle Ottoから学んだこと

xgboost

Log Loss: -0.48 (+/- 0.01)

Fit time: 2730.05 (+/- 548.52)

Predict time: 769.46 (+/- 202.69)

elapse 09h54m23s

参考ICHI -0.53±0.00 0.55831

YON -0.47±0.01 0.54944 *

GO - 0.47977

* アンサンブラ改良前最高性能と同程度

102

Page 103: 実践多クラス分類 Kaggle Ottoから学んだこと

Lasagne

ラザニアだからLasagnaと思ってたけどeが正解

宣言的にニューラルネットの層の間の接続を記述すると中でTheanoが更新式を作り出して良しなに学習してくれるNN界の超高級言語

バージョン0.1devだけどKaggleで使われているのをよく見かけるライブラリの一つ

ドキュメントがPoorなのでサンプルコードを読む

103

Page 104: 実践多クラス分類 Kaggle Ottoから学んだこと

サンプル: mnist.py104

この図に描いてあるようなことがほぼそのままbuild_model関数の中に書いてある

Page 105: 実践多クラス分類 Kaggle Ottoから学んだこと

実行

Epoch 1 of 500 took 144.361straining loss: 1.344822validation loss: 0.466205validation accuracy: 87.58 %%

Epoch 2 of 500 took 140.929straining loss: 0.592950validation loss: 0.332910validation accuracy: 90.45 %%

500ステップのうちの1ステップに2分掛かるということは単純計算で全部終わるまでに17時間かかるよな…。

105

Page 106: 実践多クラス分類 Kaggle Ottoから学んだこと

実行中

約1時間後Epoch 30 of 500 took 154.024straining loss: 0.130883validation loss: 0.089886validation accuracy: 97.31 %%

約2時間半後Epoch 60 of 500 took 160.892straining loss: 0.077516validation loss: 0.067623validation accuracy: 97.86 %%

約3時間半後Epoch 170 of 500 took 80.355straining loss: 0.026319validation loss: 0.056770validation accuracy: 98.43 %%

106

Page 107: 実践多クラス分類 Kaggle Ottoから学んだこと

学習終了

約15時間後Epoch 500 of 500 took 157.920straining loss: 0.007425validation loss: 0.064233validation accuracy: 98.48 %%

python mnist.py 40219.81s user 130.37s system 74% cpu 14:58:08.57 total

でも一番性能がいいのはEpoch 397 of 500 took 94.733straining loss: 0.010540validation loss: 0.061012validation accuracy: 98.59 %%

107

Page 108: 実践多クラス分類 Kaggle Ottoから学んだこと

ハイパーパラメータ

Nesterov Momentumなんだか重要な役割をしているみたい近いうちに調べておく

学習率、レイヤーのサイズ、ドロップアウト率うーん、パラメータだらけだぞ

108

Page 109: 実践多クラス分類 Kaggle Ottoから学んだこと

考察

成績を見て適当なところで打ち切るか、一番良いものを取っておくように実装する必要がある

割と時間的コストが高い。しかも、これたぶん並列に走らない

ハイパーパラメータがたくさんあるのでパラメータを変えて何度も走らせる必要がある。ここを並列でやるのがよいか。

なんにせよラップトップにはつらい。

109

Page 110: 実践多クラス分類 Kaggle Ottoから学んだこと

サンプル: mnist_conv.py110

Page 111: 実践多クラス分類 Kaggle Ottoから学んだこと

サンプル: mnist_conv_dnn.py

Conv2DLayerがdnn.Conv2DDNNLayer

MaxPool2DLayerがdnn.MaxPool2DDNNLayer

になっている(ネーミングセンス…)

これはNVIDIAの出しているcuDNNライブラリをTheano経由で叩く実装、つまりGPUを使う

cnDNNではConvとPoolとSoftmaxしか実装されてなさげ→画像処理でないDNNには有用でない

111

sandbox.cuda.dnn – cuDNN — Theano 0.7 documentation

http://deeplearning.net/software/theano/library/sandbox/cuda/dnn.html

Page 112: 実践多クラス分類 Kaggle Ottoから学んだこと

言及されていたもの色々fchollet/keras

同じくTheanoベースのNNライブラリLasagneと比べてどうなの?ドキュメントどこ?

https://github.com/fchollet/keras/tree/master/ker

as

IssamLaradji/NeuralNetworks

SklearnベースのNNライブラリ、Sparse Autoencoderの実装がある

https://github.com/IssamLaradji/NeuralNetworks

112

Page 113: 実践多クラス分類 Kaggle Ottoから学んだこと

Gaussian Process UCB

GPはsklearnに実装がある

fitしてpredictすると平均と分散が返ってくるのであらかじめ計算しておいた定数βを掛けてargmax

113

http://scikit-learn.org/stable/modules/gaussian_process.html

http://scikit-

learn.org/stable/modules/generated/sklearn.gaussian_process.GaussianProcess.html

Page 114: 実践多クラス分類 Kaggle Ottoから学んだこと

GP-UCB-PE, TPE

GP-UCBを改良したGP-UCB-PE*の実装が改良した本人によって公開**されている(Matlab)

Tree of Parzen Estimators (TPE)***がhyperoptというハイパーパラメータ最適化用のライブラリで実装されている****(Python)

114

* Contal et al. (2013) “Parallel Gaussian Process Optimization with Upper Confidence

Bound and Pure Exploration”

http://arxiv.org/abs/1304.5350

** Emile Contal - Homepage

http://econtal.perso.math.cnrs.fr/software/

*** Bergstra et al. (2011) “Algorithms for Hyper-Parameter Optimization”

http://papers.nips.cc/paper/4443-algorithms-for-hyper-parameter-optimization.pdf

**** Hyperopt by hyperopt

http://hyperopt.github.io/hyperopt/

Page 115: 実践多クラス分類 Kaggle Ottoから学んだこと

ハイパーパラメータサーチ

パラメータサーチしない <<<< グリッドサーチ<<< Randomized Grid < (GP-UCBとかTPEとか)

という感じなのでTPEをツールとして使うのでいいかなーと思っている

115

Page 116: 実践多クラス分類 Kaggle Ottoから学んだこと

hyperopt

git cloneしてsetup.py installだけだと動かないpip install networkxが必要

MongoDBが必要と書いてあるが、単一プロセスで使う上では必要でない

116

Page 117: 実践多クラス分類 Kaggle Ottoから学んだこと

実験

scipy.optimize.fmin(downhill simplex)と比較

目的関数を3次元

sin(x) + cos(y) + sin(0.123 + 0.456 * z)

+ 0.1 * ((x - 1) ** 2 + (y - 2) ** 2 + (z - 3) ** 2)

scipyは(-10, -10, -10)から探索開始hyperoptは(-10, 10)を各変数の値の範囲と指定

117

Page 118: 実践多クラス分類 Kaggle Ottoから学んだこと

結果118

←DS

↑TPE

num trial

func value

Page 119: 実践多クラス分類 Kaggle Ottoから学んだこと

疑問

-10と10の中点0はわりと正解に近い位置scipyを(0, 0, 0)から探索開始したらどうなる?

119

Page 120: 実践多クラス分類 Kaggle Ottoから学んだこと

結果120

↑DS (0,0,0)スタート

Page 121: 実践多クラス分類 Kaggle Ottoから学んだこと

さらに疑問

では逆に答えが(-9,-8,-7)のあたりの場合は?目的関数を3次元

sin(x) + cos(y) + sin(0.123 + 0.456 * z)

+ 0.1 * ((x + 9) ** 2 + (y + 8) ** 2 + (z + 7) ** 2)

121

Page 122: 実践多クラス分類 Kaggle Ottoから学んだこと

結果122

↓local minimum に引っかかった

↑近くから探索を始めれば成果は出る

↓答えの場所によらず似たような成果

Page 123: 実践多クラス分類 Kaggle Ottoから学んだこと

まとめ

hyperoptのTree of Parzen Estimatorsとscipyのdownhill simplexとを比較すると

・TPEは答えの位置によらず似たような成果・DSは初期値が正解から離れていたり運悪くLocal Minimumに引っかかったりするとTPEに比べてひどい結果になる

TPEの方が時間はかかるけど現実的スケール試行あたりの時間コストが高い最適化にはTPEを使うのがいいんじゃないかな

123

Page 124: 実践多クラス分類 Kaggle Ottoから学んだこと

t-SNE

sklearnに実装がある。Manifold learningについての解説ページもある。見た目的にはt-SNEは確かにきれいだが、軸に深い意味はないので後段にDTやKNNなどの空間を分割するタイプの分類機を伴わないとイマイチじゃなかろうか。

2~3次元用とのことなので「新しいデータはとりあえずt-SNEで2次元にして眺めてみる→

きれいなら特徴量にも使う」がよいかも。

124

sklearn.manifold.TSNE — scikit-learn 0.16.1 documentation

http://scikit-learn.org/stable/modules/generated/sklearn.manifold.TSNE.html

2.2. Manifold learning — scikit-learn 0.16.1 documentation

http://scikit-learn.org/stable/modules/manifold.html

Page 125: 実践多クラス分類 Kaggle Ottoから学んだこと

t-SNE

fitなしのtransformメソッドがない学習データでfitしてテストデータをtransform

することはどうすればできるのだろうか?*

61878*93のデータ→MemoryError

10分の1に削った(StratifiedKFold)→遅い

100分の1に削った

125

* こっちを使うべき? http://lvdmaaten.github.io/tsne/

Page 126: 実践多クラス分類 Kaggle Ottoから学んだこと

結果126

Page 127: 実践多クラス分類 Kaggle Ottoから学んだこと

まとめ、振り返り、次回に向けて

RFには無用だからとスケール調整を無視して、その後SVMとかやるときにも忘れたままだった。

データの解説は一字一句しっかり読む。

sklearnのGBDTが遅くて使うことをあきらめたがとりあえずXGBoostを一晩走らせるべき。

スパースなのでSVMの代わりにFMという案。次元削減の目的にはPCAの代わりにmanifold系を使う案。Isomapとか。今度試す。

127

Page 128: 実践多クラス分類 Kaggle Ottoから学んだこと

まとめ、振り返り、次回に向けて

アンサンブラは今ので悪くないがISTする。余裕があればLRをNNに変えてhyperopt。

単体ではPoorな性能でもアンサンブルで化けるかもしれないので捨てない。

Boosted Neural Netsなど、うまくできないものだけを取り出して学習するアプローチ。

距離、TopN、max、min、などの特徴量の追加。

128

Page 129: 実践多クラス分類 Kaggle Ottoから学んだこと

まとめのまとめ

Lasagne、XGBoost、hyperopt

129