2015-06-18 12 views
13

Sto cercando di implementare un classificatore di documenti utilizzando Apache Spark MLlib e sto riscontrando alcuni problemi nella rappresentazione dei dati. Il mio codice è il seguente:Da DataFrame a 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))) 

ho bisogno di usare dataframes per generare i token e creare le caratteristiche TF-IDF. Il problema si presenta quando provo a convertire questo dataframe in un RDD [LabeledPoint]. Mappo le righe del dataframe, ma il metodo get di Row restituisce un tipo Any, non il tipo definito nello schema dataframe (Vector). Pertanto, non riesco a costruire l'RDD di cui ho bisogno per addestrare un modello ML.

Qual è l'opzione migliore per ottenere un RDD [LabeledPoint] dopo aver calcolato un TF-IDF?

risposta

6

Casting l'oggetto ha lavorato per me.

Prova:

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

è necessario utilizzare getAs[T](i: Int): T

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

ottengo questo errore: Errore: tipi di argomenti tipo (Vector) non sono conformi al tipo attesi dei parametri di tipo (tipo T). I parametri del tipo di vettore non corrispondono ai parametri previsti di tipo T: tipo Vector ha un parametro di tipo, ma il tipo T non ne ha – Miguel

+2

@Miguel Ho ricevuto lo stesso errore e ho trovato una buona correzione da [qui] (https: //community.hortonworks .com/questions/6020/type-error-when-attempting-linear-regression.html) È necessario importare la classe Spark Vector in modo esplicito poiché Scala importa il suo tipo di vettore incorporato per impostazione predefinita. 'importa org.apache.spark.mllib.linalg. {Vector, Vectors}' e il codice di Chris funzionerà. – Ben

Problemi correlati