Kaggleのデータセットを使って特徴量を観察する その2
前回の続き
特徴量の選択を終えたのでキノコが食用か毒ありかの判別を行うモデルを構築していく
コードはここ github.com
モデリング
作成したモデルは
Tensorflowを使ったNNのロジスティック回帰モデル
決定木を用いたツリーのモデル
流行りのXGboostを用いたツリーのモデル
3種類を作った
決定木は前回の記事で紹介した本で知ったので、理解も兼ねてメモを残す
ざっくりいうとこんな形式の構造(木)になっている
△の木が逆さまで根が上にある。ブランチ(枝、図で言うと矢印)は常に四角で囲ってある属性
ノードから出ている。このノードから出ているブランチは属性の値を表す。ブランチを最後まで辿ると必ず葉(ラベル、目的変数)が割り当てられる。
ここでは矢印には特に何も書かなかったが、あるデータのある属性の値が x
以上なら左に、x
未満なら右に移動する、といったような設定ができる。また葉の値の割り当てはラベルでもいいし確率としての数値を割り当てることもできる。
基本的には情報価値の高い属性から上(根の場所から)に割り当てていくようだ。
特徴的な部分として決定境界の定め方がある。
こんな感じのデータ分布があるとする。
クラス x とクラス △ を分離するような境界を引けと言われたら
上の図のように引くのが多いはず。線形分類器のSVMや線形回帰、ロジスティック回帰とかもこんな風に引く。
決定木の場合はこのような直線では引かず、属性に対して垂直になるように境界線を引く
超平面と言うらしい。理解は難しいが n-1次元で境界が表せると言うことでいいのかな。
線形分類器が任意の直線を引けるのはf(x) = w1*x1 + w2*x2^2 + ...
で境界が定義できることからわかるように一度に全ての属性を使うから表現力の高い直線が引けるけど逆に決定木では一度に一つの属性しか使わないから'y = 10' のような垂直な直線しか引けないわけだ。
決定木の深さに関しては特に制限はないけど深すぎると過適合を起こすっぽい。深すぎるとある一つのデータに適した葉がたくさんできてしまうからかな。それだと訓練データを丸暗記しているのと同じやん。
以上が決定木のメモで、次は噂のXGBoost
完璧には理解できなかったが勾配ブースティング
とランダムフォレスト
を組み合わせたものだそうで。
ランダムフォレスト
は訓練データをn分割して一つ一つを利用し、n個の決定木を作る。そして予測の時にn個の決定木の出力から分類だったら多数決、回帰だったら平均を取った値を予測値とする。アンサンブル学習と考えが似ている。決定木を複数作るから森ってつけたセンスむせび泣くほど好き。
勾配ブースティング
は勾配とついているように勾配降下法などで損失関数の値が小さくなるように重みを更新していくっぽい。つまり木が進化していく。
ここでいう重みは決定木のブランチの値のことであっているかな。
XGBoost
はこの2つを組み合わせたと言うことは複数の木を作って、それぞれを勾配降下法で調節していく決定木と言うことか。中々やるじゃん・・・。
C++でブースティングの方を高速化しているので速いそうで。
評価
そんなこんなで各モデルを作ってテストデータの損失の値を見ていく。
見ればわかる通り二乗誤差での損失の値。二値分類だから本当はLog_lossを用いたかったがエラーが出てしまう。困った・・・。
一応クリッピングして無理やりLog_lossでの値を出すと
二乗誤差ではロジスティック回帰のが損失値は小さかったがLog_lossでは決定木の方が小さくなった。
どっちにしてもモデル構築に必要な特徴量を選べたと言う点では成功したからおけおけおっけ。
ロジスティック回帰は柔軟性に乏しいのでデータセットが少ない時は適していて、逆に決定木は柔軟性が高いので少ないデータだと過適合を起こしやすくデータセットが多い時のが適している特徴があるようだ。
最後に決定木のツリー構造を可視化する。
かなり複雑な木になっていた。これをコンピューターが自動で計算するんだからすごいな。。