6

私はRandomForest.featureImportancesを使用していますが、出力結果がわかりません。スパークランダムフォレストの特徴理解結果結果

私には12の機能がありますが、これは私が得られる出力です。

これはapache-spark固有の質問ではないかもしれませんが、出力を説明する場所を見つけることができません。木のアンサンブルモデルを考える

// org.apache.spark.mllib.linalg.Vector = (12,[0,1,2,3,4,5,6,7,8,9,10,11], 
[0.1956128039688559,0.06863606797951556,0.11302128590305296,0.091986700351889,0.03430651625283274,0.05975817050022879,0.06929766152519388,0.052654922125615934,0.06437052114945474,0.1601713590349946,0.0324327322375338,0.057751258970832206]) 

答えて

12

RandomForest.featureImportancesは、各機能の重要性を計算します。

これは、Leo BreimanとAdele Cutlerによる「ランダムフォレスト」ドキュメントのGiniの重要性の説明と、scikit-learnからの実装に続く、他の損失に対する "Gini"の重要性を一般化しています。

ブースティングと袋詰めを含む、木のコレクションについては、Hastie et al。アンサンブル内のすべてのツリーにわたって単一のツリーの平均値を使用することを示唆しています。

この機能の重要性は、以下のように計算される:

    木上
  • 平均:ゲインゲインの(特徴Jに分割ノード上)
    • 重要度(特徴J)=合計1.
  • ノーマライズfeaturに合計し、ツリーのノードを介して
  • ノーマライズ重要度を通過するインスタンスの数によってスケーリングされますさんが戻ってあなたの重要性ベクトルへ行こう15.3.2変数の重要性ページ593

    からHastie, Tibshirani, Friedman. "The Elements of Statistical Learning, 2nd Edition." 2001.

    まず
    val importanceVector = Vectors.sparse(12,Array(0,1,2,3,4,5,6,7,8,9,10,11), Array(0.1956128039688559,0.06863606797951556,0.11302128590305296,0.091986700351889,0.03430651625283274,0.05975817050022879,0.06929766152519388,0.052654922125615934,0.06437052114945474,0.1601713590349946,0.0324327322375338,0.057751258970832206)) 
    

    1.

参考に合計する電子の重要性ベクトルこの機能を重要度別に並べ替えてみましょう:

importanceVector.toArray.zipWithIndex 
      .map(_.swap) 
      .sortBy(-_._2) 
      .foreach(x => println(x._1 + " -> " + x._2)) 
// 0 -> 0.1956128039688559 
// 9 -> 0.1601713590349946 
// 2 -> 0.11302128590305296 
// 3 -> 0.091986700351889 
// 6 -> 0.06929766152519388 
// 1 -> 0.06863606797951556 
// 8 -> 0.06437052114945474 
// 5 -> 0.05975817050022879 
// 11 -> 0.057751258970832206 
// 7 -> 0.052654922125615934 
// 4 -> 0.03430651625283274 
// 10 -> 0.0324327322375338 

これはどういう意味ですか?

これは、最初の機能(インデックス0)が〜0.19の重要な機能であり、11番目(インデックス10)の機能がモデルで最も重要でないことを意味します。私は、CSVとして(FEATURENAME、重要度)の形で結果をダンプしていた直面する問題の

ワン:前の回答上に追加

+0

詳細なグレート、一つは、これは、このメタデータのJSON構造である

val featureMetadata = predictions.schema("features").metadata 

などの機能の入力ベクトルのメタデータを取得することができます答え、ありがとう!私はマルチクラスの分類を行っています - 4つのクラス、各クラスの特徴の重要度を計算する方法がありますか? – other15

+0

それは今のようには思われません。 – eliasah

+0

@ other15、私の最初の考えは、あなたの4つのクラスのそれぞれについてバイナリクラシファイアをトレーニングすることです。それでは、それぞれに特徴のあるものがあります。アイデアではない、わかっているが、うまくいくはずだ。 –

2

。重要性を抽出するための

{ 
"ml_attr": { 
       "attrs": 
        {"numeric":[{idx:I,name:N},...], 
        "nominal":[{vals:V,idx:I,name:N},...]}, 
        "num_attrs":#Attr 
        } 
      } 
}    

コード:

val attrs =featureMetadata.getMetadata("ml_attr").getMetadata("attrs") 
val f: (Metadata) => (Long,String) = (m => (m.getLong("idx"), m.getString("name"))) 
val nominalFeatures= attrs.getMetadataArray("nominal").map(f) 
val numericFeatures = attrs.getMetadataArray("numeric").map(f) 
val features = (numericFeatures ++ nominalFeatures).sortBy(_._1) 

val fImportance = pipeline.stages.filter(_.uid.startsWith("rfc")).head.asInstanceOf[RandomForestClassificationModel].featureImportances.toArray.zip(features).map(x=>(x._2._2,x._1)).sortBy(-_._2) 

//Save It now 
sc.parallelize(fImportance.toSeq, 1).map(x => s"${x._1},${x._2}").saveAsTextFile(fPath)