apache spark - Comprender los resultados de Spark RandomForest featureImportances
apache-spark classification (2)
Agregando a la respuesta anterior:
Uno de los problemas a los que me enfrenté fue el de arrojar el resultado en forma de (featureName, Importance) como csv.One puede obtener los metadatos para el vector de entrada de características como
val featureMetadata = predictions.schema("features").metadata
Esta es la estructura json para estos metadatos:
{
"ml_attr": {
"attrs":
{"numeric":[{idx:I,name:N},...],
"nominal":[{vals:V,idx:I,name:N},...]},
"num_attrs":#Attr
}
}
}
Código para extraer la importancia:
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)
Estoy usando RandomForest.featureImportances
pero no entiendo el resultado de la salida.
Tengo 12 funciones, y esta es la salida que obtengo.
Entiendo que esta podría no ser una pregunta específica de apache-spark, pero no puedo encontrar ningún lugar que explique la salida.
// 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])
Dado un modelo de conjunto de árbol, RandomForest.featureImportances
calcula la importancia de cada característica .
Esto generaliza la idea de la importancia de "Gini" para otras pérdidas, siguiendo la explicación de la importancia de Gini de la documentación de "Bosques Aleatorios" de Leo Breiman y Adele Cutler, y siguiendo la implementación de scikit-learn.
Para las colecciones de árboles, que incluye impulsar y embolsar, Hastie et al. sugiere utilizar el promedio de las importaciones de árboles individuales en todos los árboles del conjunto.
Y esta importancia de la función se calcula de la siguiente manera:
- Promedio sobre árboles:
- importancia (característica j) = suma (sobre los nodos que se dividen en la característica j) de la ganancia, donde la ganancia se escala por el número de instancias que pasan a través del nodo
- Normalice las importancias de árbol para sumar a 1.
- Normalice el vector de importancia de la característica para sumar a 1.
Referencias: Hastie, Tibshirani, Friedman. "Los elementos del aprendizaje estadístico, 2da edición". 2001. - 15.3.2 Importancia Variable página 593.
Regresemos a su vector de importancia:
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))
Primero, clasifiquemos estas características por importancia:
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
Entonces, qué significa esto ?
Significa que su primera característica (índice 0) es la característica más importante con un peso de ~ 0.19 y su característica número 11 (índice 10) es la menos importante en su modelo.