-2

J'essaie d'exécuter Random Forest Classifier et d'évaluer le modèle en utilisant la validation croisée. Je travaille avec pySpark. Le fichier CSV d'entrée est chargé en format Spark DataFrame. Mais je suis confronté à un problème lors de la construction du modèle.pyspark.sql.utils.IllegalArgumentException: les «fonctionnalités» d'u'Field n'existent pas. '

Ci-dessous le code.

from pyspark import SparkContext 
from pyspark.sql import SQLContext 
from pyspark.ml import Pipeline 
from pyspark.ml.classification import RandomForestClassifier 
from pyspark.ml.tuning import CrossValidator, ParamGridBuilder 
from pyspark.ml.evaluation import MulticlassClassificationEvaluator 
from pyspark.mllib.evaluation import BinaryClassificationMetrics 
sc = SparkContext() 
sqlContext = SQLContext(sc) 
trainingData =(sqlContext.read 
     .format("com.databricks.spark.csv") 
     .option("header", "true") 
     .option("inferSchema", "true") 
     .load("/PATH/CSVFile")) 
numFolds = 10 
rf = RandomForestClassifier(numTrees=100, maxDepth=5, maxBins=5, labelCol="V5409",featuresCol="features",seed=42) 
evaluator = MulticlassClassificationEvaluator().setLabelCol("V5409").setPredictionCol("prediction").setMetricName("accuracy") 
paramGrid = ParamGridBuilder().build() 

pipeline = Pipeline(stages=[rf]) 
paramGrid=ParamGridBuilder().build() 
crossval = CrossValidator(
    estimator=pipeline, 
    estimatorParamMaps=paramGrid, 
    evaluator=evaluator, 
    numFolds=numFolds) 
model = crossval.fit(trainingData) 
print accuracy 

Je reçois ci-dessous erreur

Traceback (most recent call last): 
    File "SparkDF.py", line 41, in <module> 
    model = crossval.fit(trainingData) 
    File "/usr/local/spark-2.1.1/python/pyspark/ml/base.py", line 64, in fit 
    return self._fit(dataset) 
    File "/usr/local/spark-2.1.1/python/pyspark/ml/tuning.py", line 236, in _fit 
    model = est.fit(train, epm[j]) 
    File "/usr/local/spark-2.1.1/python/pyspark/ml/base.py", line 64, in fit 
    return self._fit(dataset) 
    File "/usr/local/spark-2.1.1/python/pyspark/ml/pipeline.py", line 108, in _fit 
    model = stage.fit(dataset) 
    File "/usr/local/spark-2.1.1/python/pyspark/ml/base.py", line 64, in fit 
    return self._fit(dataset) 
    File "/usr/local/spark-2.1.1/python/pyspark/ml/wrapper.py", line 236, in _fit 
    java_model = self._fit_java(dataset) 
    File "/usr/local/spark-2.1.1/python/pyspark/ml/wrapper.py", line 233, in _fit_java 
    return self._java_obj.fit(dataset._jdf) 
    File "/home/hadoopuser/anaconda2/lib/python2.7/site-packages/py4j/java_gateway.py", line 1160, in __call__ 
    answer, self.gateway_client, self.target_id, self.name) 
    File "/usr/local/spark-2.1.1/python/pyspark/sql/utils.py", line 79, in deco 
    raise IllegalArgumentException(s.split(': ', 1)[1], stackTrace) 
pyspark.sql.utils.IllegalArgumentException: u'Field "features" does not exist.' 
[email protected]:~/workspace/RandomForest_CV$ 

S'il vous plaît, aidez-moi à résoudre ce problème dans pySpark. Merci.

Je montre les détails de l'ensemble de données ici. Non Je n'ai pas de colonne de fonctionnalités en particulier. Voici la sortie de trainingData.take (5) qui affiche les 5 premières lignes de l'ensemble de données.

[Row (V4366 = 0,0, V4460 = 0,232, V4916 = -0,017, -0,104 = V1495, V1639 = 0,005, V1967 = -0,008, V3049 = 0,177, V3746 = -0,675, -3,451 = V3869, V524 = 0,004, V5409 = 0), rangée (V4366 = 0,0, V4460 = 0,111, V4916 = -0,003, V1495 = -0,137, V1639 = 0,001, V1967 = -0,01, V3049 = 0,01, V3746 = -0,867, V3869 = -2,759, V524 = 0,0, V5409 = 0), rangée (V4366 = 0,0, V4460 = -0,391, V4916 = -0,003, V1495 = -0,155, V1639 = -0,006, V1967 = -0,019, V3049 = -0,706, V3746 = 0,166, V3869 = 0,189, V524 = 0,001, V5409 = 0), rangée (V4366 = 0,0, V4460 = 0,098, V4916 = -0,012, V1495 = -0,108, V1639 = 0,005, V1967 = -0,002, V3049 = 0,033, V3746 = -0,787, V3869 = -0,926, V524 = 0,002, V5409 = 0), rangée (V4366 = 0,0, V4460 = 0,026, V4916 = -0,004, V1495 = -0,139, V1639 = 0,003, V1967 = -0,006, V3049 = -0,045, V3746 = -0.208, V3869 = -0,782, V524 = 0,001, V5409 = 0)]

où V433 à V524 sont exploit ures. V5409 est l'étiquette de classe.

+3

nous avons besoin d'une idée de la mise à jour de data - pls avec la sortie de 'trainingData.show()'. Y a-t-il une colonne nommée 'features' dans votre fichier csv? – desertnaut

+0

La colonne NO features n'est pas présente. J'ai les noms d'attributs dans les données. –

+0

J'ai mis à jour ma question. Merci –

Répondre

0

Les données Spark ne sont pas utilisées comme dans Spark ML; toutes vos fonctionnalités doivent être des vecteurs dans une colonne simple, généralement appelée features. Voici comment vous pouvez le faire en utilisant les 5 lignes que vous avez fournies à titre d'exemple:

spark.version 
# u'2.2.0' 

from pyspark.sql import Row 
from pyspark.ml.linalg import Vectors 

# your sample data: 
temp_df = spark.createDataFrame([Row(V4366=0.0, V4460=0.232, V4916=-0.017, V1495=-0.104, V1639=0.005, V1967=-0.008, V3049=0.177, V3746=-0.675, V3869=-3.451, V524=0.004, V5409=0), Row(V4366=0.0, V4460=0.111, V4916=-0.003, V1495=-0.137, V1639=0.001, V1967=-0.01, V3049=0.01, V3746=-0.867, V3869=-2.759, V524=0.0, V5409=0), Row(V4366=0.0, V4460=-0.391, V4916=-0.003, V1495=-0.155, V1639=-0.006, V1967=-0.019, V3049=-0.706, V3746=0.166, V3869=0.189, V524=0.001, V5409=0), Row(V4366=0.0, V4460=0.098, V4916=-0.012, V1495=-0.108, V1639=0.005, V1967=-0.002, V3049=0.033, V3746=-0.787, V3869=-0.926, V524=0.002, V5409=0), Row(V4366=0.0, V4460=0.026, V4916=-0.004, V1495=-0.139, V1639=0.003, V1967=-0.006, V3049=-0.045, V3746=-0.208, V3869=-0.782, V524=0.001, V5409=0)]) 

trainingData=temp_df.rdd.map(lambda x:(Vectors.dense(x[0:-1]), x[-1])).toDF(["features", "label"]) 
trainingData.show() 
# +--------------------+-----+ 
# |   features|label| 
# +--------------------+-----+ 
# |[-0.104,0.005,-0....| 0| 
# |[-0.137,0.001,-0....| 0| 
# |[-0.155,-0.006,-0...| 0| 
# |[-0.108,0.005,-0....| 0| 
# |[-0.139,0.003,-0....| 0| 
# +--------------------+-----+ 

après quoi, votre pipeline devrait fonctionner (je suppose qu'en effet, vous avez la classification multi-classe, depuis votre l'échantillon ne contient que des 0 comme des étiquettes) avec seulement changer la colonne d'étiquettes dans votre rf et evaluator comme suit:

rf = RandomForestClassifier(numTrees=100, maxDepth=5, maxBins=5, labelCol="label",featuresCol="features",seed=42) 
evaluator = MulticlassClassificationEvaluator().setLabelCol("label").setPredictionCol("prediction").setMetricName("accuracy") 

Enfin, print accuracy ne fonctionnera pas - vous aurez besoin model.avgMetrics à la place.

+0

Quand je donne spark.createDataFrame() comme mentionné ci-dessus, il montre NameError: le nom 'spark' n'est pas défini. Comment résoudre ceci? Merci pour cette réponse. C'était très utile. –

+0

@LokeswariVenkataramana Vous utilisez probablement une ancienne version de Spark (1.x). Vous n'avez pas besoin de cette commande - lisez simplement votre fichier csv initial comme vous le faites dans votre code, mais dans une base de données nommée 'temp_df', puis continuez à définir' trainingData' comme je le montre. – desertnaut

+1

Ajout des lignes ci-dessous résolues NameError: name Spark n'est pas défini. à partir de pyspark.context importer SparkContext à partir de pyspark.sql.session d'importation SparkSession sc = SparkContext ('local') spark = SparkSession (sc) –