6

Ich benutze RandomForest.featureImportances, aber ich verstehe nicht das Ergebnis der Ausgabe.Understanding Spark RandomForest featureImportances Ergebnisse

Ich habe 12 Funktionen, und das ist die Ausgabe, die ich bekomme.

Ich bekomme, dass dies keine apache-spark spezifische Frage sein kann, aber ich kann nirgends finden, dass die Ausgabe erklärt.

// 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]) 

Antwort

12

ein Baummodell ensemble Gegeben berechnet RandomForest.featureImportancesdie Bedeutung jedes verfügen.

Dies verallgemeinert die Idee von "Gini" Bedeutung für andere Verluste, nach der Erklärung von Gini Bedeutung aus "Random Forests" Dokumentation von Leo Breiman und Adele Cutler, und nach der Implementierung von scikit-learn.

Für Sammlungen von Bäumen, einschließlich Boosting und Absackung, Hastie et al. schlägt vor, den Durchschnitt einzelner Baumimporte über alle Bäume im Ensemble zu verwenden.

Und diese Funktion Bedeutung wird wie folgt berechnet:

  • Durchschnitt über Bäume:
    • Bedeutung (Merkmal j) = Summe (über Knoten, die auf Funktion j aufgeteilt) der Verstärkung, wo Gewinn die durch Knoten
    • Normalisieren Wichtigkeiten für Baum zu 1.
  • Normalisieren featur Summe wird durch die Anzahl der Instanzen skaliert e Bedeutung Vektor 1.

Referenzen zusammenzufassen: -Hastie, Tibshirani, Friedman. "The Elements of Statistical Learning, 2nd Edition." 2001. 15.3.2 Variable Bedeutung Seite 593.

zu deinem Bedeutung Vektor Gehen wir zurück:

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)) 

Erste , sortieren wir diese Funktionen nach Wichtigkeit:

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 

Was bedeutet das?

Dies bedeutet, dass Ihr erstes Merkmal (Index 0) das wichtigste Merkmal mit einem Gewicht von ~ 0,19 ist und Ihr 11. Merkmal (Index 10) in Ihrem Modell am wenigsten wichtig ist.

+0

Große, detaillierte antwort, danke! Ich mache eine Klassenklassifikation - 4 Klassen, würde es eine Möglichkeit geben, Feature-Wichtigkeit für jede Klasse zu berechnen? – other15

+0

Es scheint jetzt nicht so. – eliasah

+0

@ other15, wäre mein erster Gedanke, einen binären Klassifikator für jede Ihrer 4 Klassen zu trainieren. Dann hätten Sie Feature-Importance für jeden. Keine Ahnung, ich weiß, aber es sollte funktionieren. –

2

auf die vorherige Antwort hinzu:

Eines der Probleme, die ich konfrontiert war das Ergebnis in Form von (Feature, Bedeutung) in Dumping als csv.Man kann die Metadaten für den Eingangsvektor von Merkmalen wie

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

bekommen Dies ist die json Struktur für diese Metadaten:

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

-Code zum Extrahieren der Bedeutung:

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)