2016-03-21 4 views
3

abbildet Ich habe das OneHotEncoder-Beispiel geändert, um eine LogisticRegression zu trainieren. Meine Frage ist, wie man die generierten Gewichte wieder auf die kategorialen Variablen abbildet.Wie man Variablennamen nach der Pipeline nach

def oneHotEncoderExample(sqlContext: SQLContext): Unit = { 

val df = sqlContext.createDataFrame(Seq(
    (0, "a", 1.0), 
    (1, "b", 1.0), 
    (2, "c", 0.0), 
    (3, "d", 1.0), 
    (4, "e", 1.0), 
    (5, "f", 0.0) 
)).toDF("id", "category", "label") 
df.show() 

val indexer = new StringIndexer() 
    .setInputCol("category") 
    .setOutputCol("categoryIndex") 
    .fit(df) 
val indexed = indexer.transform(df) 
indexed.select("id", "categoryIndex").show() 

val encoder = new OneHotEncoder() 
    .setInputCol("categoryIndex") 
    .setOutputCol("features") 
val encoded = encoder.transform(indexed) 
encoded.select("id", "features").show() 


val lr = new LogisticRegression() 
    .setMaxIter(10) 
    .setRegParam(0.01) 

val pipeline = new Pipeline() 
    .setStages(Array(indexer, encoder, lr)) 

// Fit the pipeline to training documents. 
val pipelineModel = pipeline.fit(df) 

val lorModel = pipelineModel.stages.last.asInstanceOf[LogisticRegressionModel] 
println(s"LogisticRegression: ${(lorModel :LogisticRegressionModel)}") 
// Print the weights and intercept for logistic regression. 
println(s"Weights: ${lorModel.coefficients} Intercept: ${lorModel.intercept}") 
} 

Ausgänge

Gewichte: [1,5098946631236487, -5.509833649232324,1.5098946631236487,1.5098946631236487, -5,509833649232324] Intercept: 2,6679020381781235

+0

Siehe quasi doppelte Frage: https://Stackoverflow.com/q/42935914/166686 – mjv

Antwort

5

Ich gehe davon aus, was Sie hier wollen, ist ein Zugriff auf die Funktionen von Metadaten . Fangen wir mit DataFrame bestehenden Transformation: lässt

val meta: org.apache.spark.sql.types.Metadata = transformedDF 
    .schema(transformedDF.schema.fieldIndex("features")) 
    .metadata 

Schließlich Extrakt Attribute:

val transformedDF = pipelineModel.transform(df) 

Weiter Sie Metadatenobjekt extrahieren

meta.getMetadata("ml_attr").getMetadata("attrs") 
// org.apache.spark.sql.types.Metadata = {"binary":[ 
// {"idx":0,"name":"e"},{"idx":1,"name":"f"},{"idx":2,"name":"a"}, 
// {"idx":3,"name":"b"},{"idx":4,"name":"c"}]} 

Diese verwendet werden können Gewichte wieder auf das beziehen ursprüngliche Eigenschaften.

+0

danke! und Hinweis für andere ist dies, was ich brauchte, um auf den Feature-Namen zuzugreifen: val featureMeta = meta.getMetadata ("ml_attr"). getMetadata ("attrs") featureMeta.getMetadataArray ("numerisch") (0) .getString (" name ") – lapolonio

+0

Der Teil nach' .getMetadata ("attrs") 'wird sich von Fall zu Fall unterscheiden. Sie können dort verschiedene Gruppen haben ('binary',' numeric' usw.) – zero323

Verwandte Themen