2015-06-18 16 views
13

Ich versuche, einen Dokumentklassifikator mit Apache Spark MLlib zu implementieren, und ich habe einige Probleme, die Daten darzustellen. Mein Code ist der folgende:Von DataFrame zu RDD [LabeledPoint]

import org.apache.spark.sql.{Row, SQLContext} 
import org.apache.spark.sql.types.{StringType, StructField, StructType} 
import org.apache.spark.ml.feature.Tokenizer 
import org.apache.spark.ml.feature.HashingTF 
import org.apache.spark.ml.feature.IDF 

val sql = new SQLContext(sc) 

// Load raw data from a TSV file 
val raw = sc.textFile("data.tsv").map(_.split("\t").toSeq) 

// Convert the RDD to a dataframe 
val schema = StructType(List(StructField("class", StringType), StructField("content", StringType))) 
val dataframe = sql.createDataFrame(raw.map(row => Row(row(0), row(1))), schema) 

// Tokenize 
val tokenizer = new Tokenizer().setInputCol("content").setOutputCol("tokens") 
val tokenized = tokenizer.transform(dataframe) 

// TF-IDF 
val htf = new HashingTF().setInputCol("tokens").setOutputCol("rawFeatures").setNumFeatures(500) 
val tf = htf.transform(tokenized) 
tf.cache 
val idf = new IDF().setInputCol("rawFeatures").setOutputCol("features") 
val idfModel = idf.fit(tf) 
val tfidf = idfModel.transform(tf) 

// Create labeled points 
val labeled = tfidf.map(row => LabeledPoint(row.getDouble(0), row.get(4))) 

Ich muss Datenframes verwenden, um die Token zu generieren und die TF-IDF-Features zu erstellen. Das Problem tritt auf, wenn ich versuche, diesen Datenrahmen in eine RDD [LabeledPoint] umzuwandeln. Ich ordnet die Datenframezeilen zu, aber die get-Methode von Row gibt einen beliebigen Typ zurück, nicht den Typ, der im Datenrahmenschema (Vector) definiert ist. Daher kann ich die RDD nicht bauen, die ich brauche, um ein ML-Modell zu trainieren.

Was ist die beste Option, um nach der Berechnung einer TF-IDF eine RDD [LabeledPoint] zu erhalten?

Antwort

6

Casting das Objekt für mich verwenden gearbeitet.

Versuchen:

// Create labeled points 
val labeled = tfidf.map(row => LabeledPoint(row.getDouble(0), row(4).asInstanceOf[Vector])) 
1

Sie benötigen getAs[T](i: Int): T

// Create labeled points 
val labeled = tfidf.map(row => LabeledPoint(row.getDouble(0), row.getAs[Vector](4))) 
+3

ich diesen Fehler: Fehler: Arten der Typargumente (Vector) entsprechen nicht den erwarteten Arten der Typparameter (Typ T). Parameter des Vektors stimmen nicht mit den erwarteten Parametern von Typ T überein: Typ Vektor hat einen Typparameter, aber Typ T hat keine – Miguel

+2

@Miguel Ich habe den gleichen Fehler erhalten und eine gute Lösung von [hier] gefunden (https: //community.hortonworks .com/questions/6020/type-error-when-trying-linear-regression.html) Sie müssen die Spark Vector-Klasse explizit importieren, da Scala standardmäßig den eingebauten Vector-Typ importiert. 'import org.apache.spark.mllib.linalg. {Vektor, Vektoren}' und dann Chris Code funktioniert. – Ben

Verwandte Themen