73
55

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

回帰予測で多ラベル・複数項目を出力させたい!

Last updated at Posted at 2019-03-24

プロジェクトで「多ラベルの回帰予測」をしなければならないことになりました。
※機械の自動運転なのですが、調整する値が20個ほどある

ですが、多ラベル出力に対応していないregressorが結構あるので
その時に使ったscikit-learnのMultiOutputRegressorについて書いていきます!

ドキュメント

回帰予測で他ラベル出力するには

回帰予測で他ラベル出力するにはいくつか方法があります。

1. 元々他ラベル出力に対応しているRegressorを採用する
 →scikit-learnのRandomForestが代表的ですが、もともと他ラベル出力に対応しているものがあります。
  これを使えば、複数のラベルが入ったデータを学習データとして与えても大丈夫!

2. ニューラルネットワークを使う
 →ニューラルネットワークは隠れ層や出力層の数を変えられるため、当然出力層の数を変えれば多ラベル出力も可能です。
(私はニューラルネットワークを使ったことがないクソ雑魚のため、この案はスルーしました)

3. scikit-learnのMultiOutputRegressorを使う
 →これを使えば多ラベル出力に対応していないRegressorも出力させることができます。

RandomForest おっそ...

いや、これなんですよね...
上の方法を見たとき「いや、じゃあRandomForest使えよ」って思いませんでした?
私も最初RandomForestで頑張ってたわけなんですが学習遅くね...?ということなんですよ。
精度は別に悪くないと思うんですけどね。

そこで、kaggleで使ったことのあるLightGBMを使ってみたところ、クッソ爆速

「じゃあ、LightGBMに変えよー!」と思ったらLightGBMは多ラベル出力に対応してないんですね...
そのままデータを渡して学習させようとするとValueErrorになってしまいます。

ValueError: DataFrame for label cannot have multiple columns

そういう時にMultiOutputRegressorなんすわぁ

そういう「使いたいRegressorがあるけど多ラベル出力に対応してない」時に使えるのがMultiOutputRegressor!!
使い方は正直めちゃくちゃ簡単です。
例えばLightBGMで以下のように書いて、yがラベルだとしますよね?

import lightgbm as lgb

params={'learning_rate': 0.05,
        'objective':'mae',
        'metric':'mae',
        'num_leaves': 7,
        'verbose': 0,
        'bagging_fraction': 0.7,
        'feature_fraction': 0.7
       }

reg = lgb.LGBMRegressor(**params, n_estimators=500)
reg.fit(x, y)

これが、こう!

from sklearn.multioutput import MultiOutputRegressor
import lightgbm as lgb

params={'learning_rate': 0.5,
        'objective':'mae', 
        'metric':'mae',
        'num_leaves': 9,
        'verbose': 0,
        'bagging_fraction': 0.7,
        'feature_fraction': 0.7
       }
reg = MultiOutputRegressor(lgb.LGBMRegressor(**params, n_estimators=500))

reg.fit(x, y)

そう!LightGBMのオブジェクト作成するところをMultiOutputRegressor()で包むだけです。
これだけで、多ラベルデータを学習・予測できるようになります。やったぜ。

課題?

MultiOutputRegressor使っていて問題とまでは言いませんが感じたことを書いていきます。

各ラベルの予測モデルよりは精度が落ちている気がする

これ、当たり前といえば当たり前な気がしますがそんな気がします。
MultiOuputRegressorを使わずに、ラベルの数だけモデルを作って予測させた場合と比べると
やはり少しですが精度が落ちてます。

これは、モデルをひとつにすることで、本来必要ないデータも学習することになるからだと思います。
あるラベルでは必要ないデータでも、他のラベルの学習に必要なデータであれば全て学習データに含める必要があります。
結果的に、各ラベル単位で見ると無駄に多い学習データを使っていることになります。

MultiOuputRegressorの内部的な仕組みとしては、ラベルの数だけ独立して予測させているようなので
やはり不要なデータが増えているのが要因なんでしょうなあ。

feature_importanceが使えない

これも仕方ないのかもしれませんが、特徴量選択によく使うので使えないのは困ります。
私はfeature_importanceを見るためだけに各ラベルごとのモデルを作って見てました。二度手間。
(上でも書いたように、内部的にはラベルごとに独立で動いているので結果はほとんど同じはず)

for文ぶん回して放っておくだけなので言う程手間でもないんですが、
やはりMultiOuputRegressorで包んだやつから直接見れたらラクなのになーとは思っちゃいますね。

終わり

とはいえとはいえ、導入も物凄く簡単で便利なので、ぜひ使ってみてくださいー!

73
55
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
73
55

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?