nykergoto’s blog

機械学習とpythonをメインに、雑多な内容をとりとめなく扱うブログです。

勾配ブースティングを実装してみた

勾配ブースティングとは

機械学習アルゴリズムはいろいろなものがありますが、その中でも木構造を使ったアンサンブル学習の一つとして勾配ブースティング法と呼ばれるものがあります。

勾配ブースティング法は学習器を一つづつ追加していく加法的モデルと呼ばれるモデルに分類されます。ざっくりとしたアルゴリズムとしては

  1. 今ある学習器の結果と目的の値との差を縮めるような学習器を作り
  2. それを今ある学習器に追加する

ということを何回も繰り返して、段々と目的の値を得られるような学習器を生成します。

勾配ブースティング法は、ブースティングの学習の時に目的関数の勾配およびヘシアン情報を使うもので

  • 学習ステップを増やしても過学習を起こしにくい
  • 非常に柔軟な予測モデルを生成できる
  • 木構造ゆえ変数の正規化が必要ない

という特徴から人気者です。実際自分で使っていても大概の問題でうまく行ってる印象があります。

高速な実装としては、xgboostなどが有名です。(内部でC++で実装されているようです

普通に使う文にはxgboost使いましょうという話なんですが思い立って実装してみました。

github.com

使い方

基本的にはreadme.mdに書いてあるのでそちらを見てほしいのですが、

の二値分類であればgbdtreeフォルダを実行ファイルと同じ階層に置いて

import gbdtree as gb

clf = gb.GradientBoostedDT()
x_train,t_train = ~~ # 適当なトレーニングデータ
clf.fit(x=x_train,t=t_train)

pred = clf.predict(x_test) # x_test の予測を出力

というような感じで学習ができます。

やってみた

連続変数に対する回帰問題をやってみます

import pandas as pd
import numpy as np
import gbdtree as gb
import matplotlib.pyplot as plt

sample_size = 100
x_train = np.linspace(-np.pi,np.pi,sample_size)
t_train = np.sin(x_train) + np.random.normal(scale=.5,size=sample_size)

# xの形は(N,feature_dim)の形に直す
x_train = x_train.reshape(sample_size,1)

regobj = gb.LeastSquare()
loss = gb.leastsquare

clf = gb.GradientBoostedDT(regobj,loss)
clf.fit(x=x_train,t=t_train,num_iter=20)

pred = clf.predict(x_train)
plt.plot(x_train,t_train,'o')
plt.plot(x_train,np.sin(x_train))
plt.plot(x_train,pred)
plt.show()

f:id:dette:20160624075124p:plain

いい感じですね。適当にclf.fitに与えるパラメータを変えて挙動がどういうふうに変わるかを見るのも面白いかもしれません。

二値分類に関しては先程のgithubの中に2つ

  • sample.pyに適当なガウス分布に対する分類問題
  • mnist.pyにMNISTの手書き文字(3と8)の二値分類問題

のサンプルが入っているのでよければどうぞ。