Pythonではじめる機械学習を読んでいるので、その学習メモ。

  • Pythonではじめる機械学習 ―scikit-learnで学ぶ特徴量エンジニアリングと機械学習の基礎: Andreas C. Muller
  • https://amzn.to/3d4gJ16

今日は、決定木について。前回の線形回帰のように、kaggleの問題を解いてみた。

家に帰るまでが、遠足です!

Kaggleするまでが、勉強です!

決定木

Yes/Noで答えられる質問で構成された階層的な木構造を学習する。

  • 過剰適合を防ぐには、構築過程で木の生成を早めに止める事前枝刈りと、

    一度木を構築してから、情報の少ないノードを削除する事後枝刈りがある。

  • scikit-learnには、DecisionTreeRegressorクラスと、DecisionTreeClassifierクラスに実装されている。scikit-learnには事前枝刈りしか実装されていない。

  • 決定木の深さに制約を与えないと、決定木はいくらでも深く、複雑になる。したがって、枝刈りされていない木は過剰適合になりやすく、新しいデータに対する汎化性能が低い傾向にある。

  • 決定木から、特徴量の重要度(feature importance)が導出できる。個々の特徴量かどの程度重要かを示す割合である。

  • 利点は、結果のモデルが容易に可視化可能で、専門家でなくても理解可能であること。

  • 別の利点は、データのスケールに対して完全に不変であること、つまり特徴量の正規化や標準化は必要ない。

  • 最大の問題点は、事前枝狩りを行っても、過剰適合しやすく、汎化性能が低い傾向がある。そのため、単体でつかうのではなくアンサンブル法が用いられる。

アンサンブル法は、複数の機械学習モデルを組み合わせることで、より強力なモデルを構築する手法だ。ランダムフォレストと勾配ブースティング決定木がある。

ランダムフォレスト(RandomForest)

ランダムフォレストとは、少しずつ異なる決定木をたくさん集めたもの。それぞれ異なった方向に過剰適合した決定木をたくさん作れば、その結果の平均を取ることで過剰適合の度合いを減らすことができる。

個々の決定木が互いに異なるように、決定木の構築過程で乱数を導入している。導入方法は、データポイントを選択する方法と、分枝テストに用いる特徴を選択する2つの方法がある。

  • 構築する決定木の数をまず決める。
  • データからブートストラップサンプリングを行う。これは、重複可でデータポイントをランダムにn_samples回選びだす手法(復元抽出)このデータセットを用いて決定木を作る。
  • ただし、個々のノードで最適なテスト(基準値)を選ぶのではなく、特徴量のサブセット(max_features)をランダムに選び、その特徴量を使うものの中から最適なテストを選ぶ。
  • max_featuresが重要なパラメータ。max_featuresを大きくすると、決定木が似たようなものになり、最も識別性の高い特徴量をつかうので、訓練データに容易に適合できる。
  • max_featuresを小さくすると、ランダムフォレスト内の決定木は相互に大幅に異なるものとなるが、それぞれの決定木をかなり深く作らないと、データに適合できない。
  • しかし多くの場合、ランダムフォレストはデフォルトのパラメータで、十分よく機能する。
  • 回帰でもクラス分類でも、非常に強力。多くの場合、それほどパラメータチューニングせずに使える。スケール変換する必要もない。
  • テキストデータなどの、非常に高次元で疎なデータに対しては、うまく機能しない傾向にある。このようなデータに対しては線形モデルのほうが適している。
  • 線形モデルよりも、多くのメモリを消費するし、訓練も予測も遅い。実行時間やメモリが重要なアプリケーションでは、線形モデルをつかったほうがよい。

Kaggle digit-recognizer

これでScore 0.93729。

CNNにはかなわない。問題が悪かったかな??

勾配ブースティング回帰木(gradient boosting regression tree, GBRT)

勾配ブースティングでは、1つ前の決定木の誤りを次の決定木が修正するようにして、決定木を順番に作っていく。

  • モデルの占めるメモリが小さくなり、予測も早くなる。
  • 浅い決定木のような、簡単なモデル(弱学習機)を多数組み合わせるところがポイント。
  • パラメータ設定の影響を受けやすいが、こっちのほうが性能が良い。
  • learning_rate という重要なパラメータがある。
  • 過剰適合を低減するためには、深さの最大値を制限してより強力な事前枝刈りを行うか、学習率をさげればよい。
  • ランダムフォレストを先に試したほうかいい。こっちのほうが頑強だから。予測時間が非常に重要な場合や、kaggleのコンペで最後の1%を絞り出したいときは、勾配ブースティングを試すと良い。
  • xgboostはscikit-learnよりも、高速で、チューニングも容易。
  • 長所は、教師あり学習の中で最も強力なところ。
  • 短所は、パラメータチューニングに細心の注意が必要なところと、訓練にかかる時間が長いこと。

scikit-learnよりも、xgboostをつかったほうがいいよということで、使ってみた。

XGBoost の使い方。

kaggle digit-recognizer

Scoreは、0.93157。RandomForestよりも精度が低かった。