FastRGFはじめました@rgf_python2.3.0
rgf_pythonですが、ありがたいことにPorto Seguro’s Safe Driver Prediction Competitionを中心にkaggleで使ったよ、という報告が増えてきました。
https://www.kaggle.com/scirpus/regularized-greedy-forest/code
RGF単体でXGBやLightGBMを越えない場合でも、アンサンブルのお供には有力な選択肢です。
さて、rgf_pythonは現在も継続的に更新を続けており、デプロイ方法の変更や、docker imageの配布、内部的な変更も大きい物がいくつか入っていますが、なんといっても最近ではFastRGFの導入が大きいでしょう。
今日はFastRGFについて書きます。
FastRGFとは
FastRGFとは、RGFの作者である
GitHub - baidu/fast_rgf: Multi-core implementation of Regularized Greedy Forest
・ロス関数の近似法をシンプルにした
・マルチスレッド
などの方法をつかって高速化しています。
rgf_pythonでも多クラス問題では、ラッパーで頑張ってマルチスレッドにしているのですが、One-VS-Restの学習機を同時に回しているだけであり、クラス数より大きなスレッドで動かすことはできません。
また、回帰問題はシングルスレッドでしか動きません。
ですが、FastRGFはそれ自体がOpenMPをつかってマルチスレッドで書かれており、2クラス問題だろうが回帰問題だろうがコア数を使い切ることができます(学習器の規模にもよると思いますが。)。
ただし、近似をシンプルしたことによりFastRGFはRGF並の予測精度が出ない可能性があります。
速度の比較
小さいデータセットでは、FastRGFによる高速化の効果は出ない、というかむしろ遅くなるので、boston_datasetをhstackして比較してみます。
406系列 x 40625次元のサンプルで回帰問題について比較しました。
スクリプト全文はPerformance comparision RGF VS FastRGF · GitHubに置きました。
速度を比較したところ、
time [s] | MSE | |
RGF | 262.1 | 0.9095 |
FastRGF | 129.6 | 0.9035 |
Random Forest | 64.06 | 0.883 |
大体倍くらい速くなりました。私の環境は4コアなので、よりコア数が多い環境では差が顕著になるでしょう。
本家FastRGFの状況について
FastRGFのgithubリポジトリを見るに、あまり更新されておらず、activeであるとは言いがたい状況です。作者が多忙なためだそう。
また、私が試す限りでも闇っぽい挙動があり、FastRGF起因のトラブルはラッパー部のrgf_pythonでは対応できない可能性があります。
とまあやや微妙な状況ではありますが、RGFの速度を速くしてくれ!という要望は少なからずあり、sklearnライクのAPIを提供することにより、FastRGFの使用者が増えてその中からメンテしてくれる勇者もいるのかなという希望的観測もあり、リリースすることに決めました。
インストール
$ pip install -U rgf_python
すれば、FastRGFも含めてインストールされます。(rgf_python>=2.3.0にて)
自分でビルドする場合g++のバージョンは5.0以上である必要があります。またcmakeとWindowsではmingw32-makeのインストールが必要になります。Visual StudioによるFastRGFのビルドは現在サポートされておりません(本家がサポートしていないため)。
使い方
例によって、データサイエンティスト達の手によって何回分類されたかわからないiris使います。
from sklearn import datasets from rgf.sklearn import FastRGFClassifier iris = datasets.load_iris() iris.data = iris.data[perm] iris.target = iris.target[perm] clf = FastRGFClassifier() clf.fit(iris.data, iris.target) score = clf.score(iris.data, iris.target)
まあ、scikit-learnユーザーには特に難しいことはないでしょう。
パラメータについて
RGFには丁寧に書かれたユーザーガイドがあったのですが、FastRGFでは、本家githubのここにパラメータチューニングに関する記述があるのみです。
また、rgf_python2.2.0では、FastRGFに忠実なパラメータ名をつけていましたが、わかりづらい変数名もあったので、2.3.0ではscikit-learnぽい名前に変更しました。
以下、対応表。
パラメータ名 | 本家でのパラメータ名 | 説明 |
n_estimators | forest.ntrees | 決定木の本数 |
max_depth | dtree.max_level | 決定木一本の最大の深さ |
max_leaf | dtree.max_nodes | 最良優先探索において調べる枝の数? |
tree_gain_ratio | dtree.new_tree_gain_ratio | 新しく出来た木のゲイン。ゲインが小さいと、予測に及ぼす影響が小さい。 |
min_samples_leaf | dtree.min_sample | 学習時に各枝で使う最小サンプル数。floatの場合、全体のサンプル数に対する割合。 |
l1 | dtree.lamL1 | l1正則化係数 |
l2 | dtree.lamL2 | l2正則化係数 |
opt_algorithm | forest.opt | 最適化アルゴリズムを”rgf”か”epsillon-greedy”か選べる |
learning_rate | forest.stepsize | 学習係数。”epsillon-greedy”のときのみ有効。 |
max_bin | discretize.(sparse/dense).max_buckets | 離散化後の区間数 |
min_child_weight | discretize.(sparse/dense).min_bucket_weights | xgboostのmin_child_weightと同様? |
data_l2 | discretize.(sparse/dense).lamL2 | 離散化時のl2正則化係数 |
sparse_max_features | discretize.sparse.max_features | 決定木の各枝が一度に何種類の特徴量を使うか?入力データがスパースのときのみ有効。 |
sparse_min_occurences | discretize.sparse.min_occrrences | ある特徴量の最小出現回数。入力データがスパースのときのみ有効。 |
既知のイシュー
・サンプル数(100未満)が極端に少ない場合、クラッシュします。RGFではなく、FastRGFをご使用ください。
・極端に小さい値をsample_weightに設定した場合、クラッシュする可能性があります。
というわけで、FastRGFぜひご利用くださいませ。