速度計測シリーズBookmarkTwitterFacebook読者になるはじめに表題の通りなのですが、サンプル数が多いデータに対してランダムフォレストを使うと思いの外メモリを食います。ストレージにダンプしようとすると、ストレージ容量も消費します。現象なにはともあれやってみましょう。main()サンプル数は10**5です。ビッグデータというほどでもないけど、大抵の機械学習が問題なく使えるだけのデータがあるとします。結果の善し悪しにはさほど興味がないのですが、一応見ておきます。25000まあ、こんなものでしょう。問題はメモリ消費量です。実行中に数百MBを消費します。データそのものは10**5行50列ですから、64bit浮動小数点数型としても40MBくらいで済むはずです。ランダムフォレスト本体がやたらメモリを消費しています。これで出力されるrfc.pickleの容量は約210MBです。原因ランダムフォレストは決定木です。デフォルトの設定では、枝は伸び放題で過学習気味です。ためしに総ノード数を見てみます。この方法は正しいのかどうかはわかりませんが、スタックオーバーフローに書いてありました。21193けっこうたくさんノードがありますね。これが諸悪の根源で、各ノードごとに数byte~数十byte程度は消費するでしょうから、木全体では意外と大きな記憶領域を必要とし、そんな木を100本も500本も使うランダムフォレストはとても記憶領域の消費量が大きくなる......ということです。なるとメモリを無駄に食うしキャッシュも効かないし遅いし、なかなか憂慮すべき事態です。性能を損なわない程度に木の複雑性を下げてノード数を減らす性能を損なわない程度に木の本数を下げるの2通りがありえます。今回みたいなデータの場合、木の本数はなかなか減らしづらいと思うので、木の複雑性を下げる方でやります。これなら上手くすれば過学習対策的に働き、ほとんど性能を損なわずに容量を減らせ、更に速くなります。やることは普通の過学習対策です。25000この状態で出力されるrfc.pickleは約100MBです。ほとんど性能を損なわずに(むしろ汎化性能をあげつつ)半分になりました。メモリ空間をやたら消費する現象への対策にはならないものの、ストレージへの保存ではjoblibを使って圧縮することも可能です。上の対策を施した上で、更に圧縮も行います。3)これで約21MBになりました。まとめこのようにランダムフォレストは意外とメモリに優しくない手法なので、使い方を気をつけようという話です。データ数が多いときの話で、1000未満でやるときとかは気にする必要は(ほとんど)ありません。ランダムフォレストってなんとなくもっさりする(すごく遅くはないけどあまり速くもない)印象でしたが、ただでさえifの嵐なのに決定木全体がキャッシュに乗らないのか......ということに気づけたのが今回の発見でした。このブログについてスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。