feature_importances_ について調べてみた

経緯

授業でランダムフォレストを使ってみる課題が出たが,いまいち feature_importances_ の算出方法がわからずモニョったので調べてみた.

 

想定する読者

  • sklearn を使う人
  • 決定木がなんとなくわかる人
  • ランダムフォレストが主に分類に用いられるアルゴリズムであると知っている人

 

 

sklearn.ensemble.RandomForestClassifierのfeature_importances_ について

概要

from sklearn.ensemble import RandomForestClassifier
model
= RandomForestClassifier()
model.fit(train_data, train_label)

importances = model.feature_importances_

すっごく色々はしょるが,こうすると特徴量ごとの重要度が出てくる.

詳しくはこの辺のサイトを参考にしてください.

mayokoex.hatenablog.com

 

feature_importances_ の算出方法

では,この feature_importances_ はどのようにして算出されているのだろうか?

これを知るにはまずランダムフォレストのアルゴリズムをおさらいする必要がある.

決定木のアルゴリズム

ランダムフォレストは決定木の集まりでできている.決定木とは以下のようなもののことである.

f:id:ensyu3-141592653589793238:20180605233109p:plain

決定木そのものは訓練データを用いて構築される.

あるノードにおいて分類にもっとも効果的な特徴量を選択し,データ集合の乱雑さが0になるまで,つまりそのノードにおける全てのデータが同じラベルを持つまで,順次ノードを作っていく.ここで言う効果的な特徴量とは,その特徴量によってデータ集合を分割した際にクラスラベルの乱雑さがもっとも減少するものを差す.乱雑さは gini係数やエントロピーなど様々な式で定義でき,sklearn ではデフォルトで gini係数を用いている.

sklearn.tree.DecisionTreeClassifier — scikit-learn 0.19.1 documentation

ランダムフォレストのアルゴリズム

決定木は過学習を起こしやすいとされ,これを避けるのがランダムフォレストである.

ランダムフォレストではまず,訓練データからいくつかの部分データ集合をランダムサンプリングによって生成する.この部分データ集合ごとに決定木を構築することを考える.ただしあるノードにおいて特徴量は,全ての特徴量のうちランダムにサンプリングされたものの中から選択される.こうすることによって全ての決定木が同じような挙動をすることを避ける.

こうして得られた決定木それぞれが分類を行い,その投票によって分類結果が決定される. 

feature_importances_ の算出方法

決定木ではある特徴量による分類の前後で乱雑さがどれほど減少するかで特徴量の選定を行っていた.この減少幅を利得と言うことにする.利得は木の構築時に計算されていることになる.

ざっくり言えば,feature_importances_ はこの利得の特徴量ごとの平均である.ただし,決定木の構築に使われたデータのうちいくつのデータがそのノードへ到達したかで重み付けがなされている.たくさんのデータをさばくノードは重要度が高くなると考えれば,この定義は直感的に納得がいく.

詳しい説明はこのサイトを参考にしてください.ベストアンサーの Gilles Louppe 氏は sklearn の開発メンバーの1人です.

stackoverflow.com

 

あとがき

今回は sklearn.ensemble.RandomForestClassifier の feature_importances_ の算出方法を調べた.ランダムフォレストをちゃんと理解したら自明っちゃ自明な算出だった.今までランダムフォレストをなんとなくのイメージでしか認識していなかったことが浮き彫りなった.この執筆を通してランダムフォレストを分かった気になれたのでスッキリですわ.

ところで開発者本人から回答が来るって羨ましすぎるよ...

ここまで読んでいただきありがとうございました.私の理解が足りていないところなどがあれば,なにとぞ優しくまさかりを投げてください.ちょっとした質問などもいただけると嬉しいです.

今回の執筆にあたって,一緒に調べたり考えたりしてくれた同研究室のT氏にはお世話になりました.

 

参考にさせていただいたサイト

scikit learn - How are feature_importances in RandomForestClassifier determined? - Stack Overflow

Random Forestで計算できる特徴量の重要度 - なにメモ

http://scikit-learn.org/stable/modules/generated/sklearn.tree.DecisionTreeClassifier.html

http://scikit-learn.org/stable/modules/generated/sklearn.ensemble.RandomForestClassifier.html

HMMとCRFとの違いについて調べてみた

経緯

系列ラベリングの代表的な手法として HMM と CRF はそれぞれ聞いたことあるし概要は本を読んでわかったつもりになっているけど,どうもそれらの違いがわからないなぁ...と思ってちょっと調べてみた.意外と日本語の記事が見つからず,英語の記事でいいものがあったのでそれの翻訳兼要約としてまとめる.英語に抵抗感がない人は元記事へ.

 

想定する読者

以下の用語を聞いたことがあるかた

ちなみにこの辺りのことは自然言語処理概論サポートベクトルマシンを参考にしてください.

 

 

HMM と CRF との違いは何か

ざっくり言えば

HMMはナイーブベイズを,CRFはロジスティック回帰を用いる.

 

以下詳細

以下では入力系列をX=(x1, x2, ..., xi, ..., xn),ラベル列をY=(y1, y2, ..., yi, ..., yn)とする.

 モデリング対象としている確率分布

HMM: XとYとの共起確率 P(X, Y)

CRF: Xが与えられた時のYの条件付き確率 P(Y|X)

 学習の仕方

HMM: 学習データ中の出現頻度をカウント.またはEMアルゴリズムなどを用いて出現確率や遷移確率を推定.

CRF: 勾配効果法 (SGD) などの最適化アルゴリズム

 HMMの方がCRFよりも早く学習されるが,CRFの方が推定精度や偏りのある学習データへの頑健性などの面で強い.

 系列全体の依存関係への挙動

(単純な)HMM: Xとyiとの依存関係を直接モデル化できない.

(単純な)CRF: Xとyiとの依存関係を直接モデル化できる.

CRFはラベル全体の分布Yをモデル化するだけであり,入力系列全体の分布Xを考慮しない.これに対しHMMは共起確率をモデル化する際にXとYの両方を考慮する必要がある.したがって,CRFはXのyiへの影響を直接モデル化することができる. 

ほかの記事では

HMMはP(X, Y)をモデル化しているのに対してCRFはP(Y|X)をモデル化している.このためHMMでは P(X) = ΣP(X, Y) を行うことで,P(X)を求めることができる.P(X)は入力系列Xの確からしさを表しており,つまりはXに対する全てのYのスコアを足し合わせることで言語モデルとして使うこともできる.

 

あとがき

今回HMMとCRFとの違いという観点から両手法への理解を深めた.HMMは共起確率を,CRFは条件付き確率をそれぞれモデリングの対象としていることが全ての違いの中心にあると感じた.

余談であるがこのブログが私の初めてのブログである.間違ったことはいえねぇと,色々な書籍を引っ張り出して復習した.ブログむずい....

ここまで読んでいただきありがとうございました.私の理解が足りていないところなどがあれば,なにとぞ優しくまさかりを投げてください.

今回の執筆にあたって,一緒にCRFのことを調べたり考えたりしてくれた同研究室のT氏とT氏には大変にお世話になりました.

参考にさせていただいたサイト

What is the difference between HMM and conditional random field? - Quora

きまぐれ日記: CRF と HMM

https://www.cs.cmu.edu/~epxing/Class/10701-08s/recitation/em-hmm.pdf