2017-09-05 3 views
-1

J'essaie d'exécuter le modèle countVectorizer de Spark. Dans le cadre de cette exigence, je suis en train de lire un fichier csv et de créer un Dataframe (inp_DF) à partir de celui-ci.Spark - Comment créer une image Spark contenant un tableau de valeurs dans l'une de ses colonnes pour le modèle countVectorizer

Il dispose de 3 colonnes comme indiqué ci-dessous

+--------------+--------+-------+ 
|   State|Zip Code|Country| 
+--------------+--------+-------+ 
|  kentucky| 40205|  us| 
|  indiana| 47305|  us| 
|greater london| sw15|  gb| 
| california| 92707|  us| 
|  victoria| 3000|  au| 
|   paris| 75001|  fr| 
|  illinois| 60608|  us| 
|  minnesota| 55405|  us| 
| california| 92688|  us| 
+--------------+--------+-------+ 

Je dois créer une 4ème colonne dans la même trame de données qui contient le tableau de valeurs de toutes ces 3 colonnes telles que

|  kentucky| 40205|  us| "kentucky","40205","us" 
|  indiana| 47305|  us| "indiana","47305","us" 
|greater london| sw15|  gb| "greater london","sw15","gb" 
| california| 92707|  us| "california","92707","us" 
|  victoria| 3000|  au| "victoria","3000","au" 
|   paris| 75001|  fr| "paris","75001","fr" 
|  illinois| 60608|  us| "illinois","60608","us" 
|  minnesota| 55405|  us| "minnesota","55405","us" 
| california| 92688|  us| "california","92688","us" 

Question 1: Y at-il une commande facile comme .concat pour réaliser ceci?

Ce tableau est nécessaire car l'entrée du modèle countVectorizer doit être une colonne contenant un tableau de valeurs. Il ne devrait pas être un type de chaîne comme mentionné dans le message d'erreur ci-dessous:

Exception dans le thread « principal » java.lang.IllegalArgumentException: exigence a échoué: Etat colonne doit être de type égal à l'un des types suivants: [ArrayType (StringType, true), ArrayType (StringType, false)] mais était en fait de type StringType. à scala.Predef .require de $ (Predef.scala: 224) à org.apache.spark.ml.util.SchemaUtils $ .checkColumnTypes (SchemaUtils.scala: 58) à org.apache.spark.ml.feature .CountVectorizerParams $ class.validateAndTransformSchema (CountVectorizer.scala: 75) à org.apache.spark.ml.feature.CountVectorizer.validateAndTransformSchema (CountVectorizer.scala: 123) à org.apache.spark.ml.feature.CountVectorizer .transformSchema (CountVectorizer.scala: 188) à org.apache.spark.ml.PipelineStage.transformSchema (Pipeline.scala: 74) à org.apache.spark.ml.feature.CountVectorizer.fit (CountVectorizer.scala : 155) à org.apache.spark.examples.ml.CountVectorizerExample $ .main (CountVectorizerExample.scala: 54) à org.apache.spark.examples.ml.CountVectorizerExample.main (CountVectorizerExample.scala) à sun.reflect.NativeMethodAccessorImpl .invoke0 (méthode native) à sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62) à sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43) à java.lang.reflect.Method.invoke (Method.java:498) à com.intellij.rt.execution.application.AppMain.main (AppMain.java:147) Avertissement de machine virtuelle Java HotSpot (TM): option ignorante MaxPermSize = 300m; support a été éliminé sous 8,0

I essayé de créer un tableau à partir de ces 3 colonnes de trame de données d'entrée, mais les éléments de réseau sont enfermés entre crochets [].

extrait de code d'échantillon est donné ci-dessous pour votre référence

// Read Input Dataset for countVectorizer Logic 
val inp_data = spark.read.format("com.databricks.spark.csv").option("header", "True").option("inferSchema", "true") 
     .option("treatEmptyValuesAsNulls", "true").option("nullValue", "") 
     .load("Input.csv") 

// Creating a Spark Dataframe from the Input Data 
val inp_DF = inp_data.toDF() 

// Creating an array from Spark Dataframe Columns 
val inp_array = inp_DF.select("State","Zip Code","Country").collect() 
     println(inp_array.mkString(",")) 

// fit a CountVectorizerModel from the corpus 
val cvModel: CountVectorizerModel = new CountVectorizer() 
     .setInputCol("State") 
     .setOutputCol("features") 
     .setVocabSize(4) 
     .setMinDF(2) 
     .fit(inp_DF) 

Question 2: Comment supprimer les crochets [] à partir de ces éléments de tableau et de créer une nouvelle colonne dans une trame de données avec les valeurs du tableau?Question 3: Pouvons-nous fournir une valeur de colonne unique en entrée du modèle countVectorizer et obtenir des caractéristiques en sortie?

Répondre

1

vous pouvez utiliser la fonction array pour créer le array column comme

import org.apache.spark.sql.functions._ 
val inp_array = inp_DF.withColumn("arrayColumn", array("State", "Zip Code", "Country")) 

qui devrait vous donner la sortie comme

+-------------+--------+-------+-------------------------+ 
|State  |Zip Code|Country|arrayColumn    | 
+-------------+--------+-------+-------------------------+ 
|kentucky  |40205 |us  |[kentucky, 40205, us] | 
|indiana  |47305 |us  |[indiana, 47305, us]  | 
|greaterlondon|sw15 |gb  |[greaterlondon, sw15, gb]| 
|california |92707 |us  |[california, 92707, us] | 
|victoria  |3000 |au  |[victoria, 3000, au]  | 
|paris  |75001 |fr  |[paris, 75001, fr]  | 
|illinois  |60608 |us  |[illinois, 60608, us] | 
|minnesota |55405 |us  |[minnesota, 55405, us] | 
|california |92688 |us  |[california, 92688, us] | 
+-------------+--------+-------+-------------------------+ 

et vous pouvez utiliser cette dataframe dans votre CountVectorizerModel comme

val cvModel: CountVectorizerModel = new CountVectorizer() 
    .setInputCol("arrayColumn") 
    .setOutputCol("features") 
    .setVocabSize(4) 
    .setMinDF(2) 
    .fit(inp_array) 

que répond à vos deux premières questions.

maintenant répondre à votre troisième question. OUI vous pouvez utiliser une seule colonne dans CountVectorizerModel mais pour cela vous devrez convertir la colonne en ArrayType(StringType,true) ce qui peut être fait en utilisant la fonction array comme ci-dessus.

Supposons que vous souhaitez utiliser State colonne CountVectorizerModel. alors vous pouvez modifier le type de données State colonne array en faisant

val single_arrayDF = inp_DF.withColumn("State", array("State")) 

et l'utiliser comme

val cvModel: CountVectorizerModel = new CountVectorizer() 
    .setInputCol("State") 
    .setOutputCol("features") 
    .setVocabSize(4) 
    .setMinDF(2) 
    .fit(single_arrayDF) 

J'espère que la réponse est utile.