5

SCALAのランダムフォレストクラシファイアモデルを使用して5倍交差検証を使用して精度を検索しようとしています。RandomForestClassifierがApache Sparkで無効なラベル列エラーで入力されました

java.lang.IllegalArgumentExceptionがを:実行している間しかし、私は次のエラーを取得していますRandomForestClassifierは、指定したクラスの番号なし、無効なラベル列のラベルの付いた入力を与えられました。 StringIndexerを参照してください。次のようにiがランダムフォレストを使用してデータ・セットの相互検証のために使用

線に上記のエラーを取得--->ヴァルcvModel = cv.fit(trainingData)

コードは次のとおり

import org.apache.spark.ml.Pipeline 
import org.apache.spark.ml.tuning.{ParamGridBuilder, CrossValidator} 
import org.apache.spark.ml.classification.RandomForestClassifier 
import org.apache.spark.ml.evaluation.MulticlassClassificationEvaluator 
import org.apache.spark.mllib.linalg.Vectors 
import org.apache.spark.mllib.regression.LabeledPoint 

val data = sc.textFile("exprogram/dataset.txt") 
val parsedData = data.map { line => 
val parts = line.split(',') 
LabeledPoint(parts(41).toDouble, 
Vectors.dense(parts(0).split(',').map(_.toDouble))) 
} 


val splits = parsedData.randomSplit(Array(0.6, 0.4), seed = 11L) 
val training = splits(0) 
val test = splits(1) 

val trainingData = training.toDF() 

val testData = test.toDF() 

val nFolds: Int = 5 
val NumTrees: Int = 5 

val rf = new  
RandomForestClassifier() 
     .setLabelCol("label") 
     .setFeaturesCol("features") 
     .setNumTrees(NumTrees) 

val pipeline = new Pipeline() 
     .setStages(Array(rf)) 

val paramGrid = new ParamGridBuilder() 
      .build() 

val evaluator = new MulticlassClassificationEvaluator() 
    .setLabelCol("label") 
    .setPredictionCol("prediction") 
    .setMetricName("precision") 

val cv = new CrossValidator() 
    .setEstimator(pipeline) 
    .setEvaluator(evaluator) 
    .setEstimatorParamMaps(paramGrid) 
    .setNumFolds(nFolds) 

val cvModel = cv.fit(trainingData) 

val results = cvModel.transform(testData) 
.select("label","prediction").collect 

val numCorrectPredictions = results.map(row => 
if (row.getDouble(0) == row.getDouble(1)) 1 else 0).foldLeft(0)(_ + _) 
val accuracy = 1.0D * numCorrectPredictions/results.size 

println("Test set accuracy: %.3f".format(accuracy)) 

上記のコードの間違いを教えてください。

答えて

8

RandomForestClassifierは、他の多くのMLアルゴリズムと同じように、ラベル列に特定のメタデータを設定する必要があり、二重で表される[0,1,2 ...、#classes]の整数値に値をラベル付けする必要があります。通常、これはのようなアップストリームTransformersによって処理されます。ラベルを手動で変換するので、メタデータフィールドは設定されず、分類子はこれらの要件が満たされていることを確認できません。 StringIndexerを使用して

val df = Seq(
    (0.0, Vectors.dense(1, 0, 0, 0)), 
    (1.0, Vectors.dense(0, 1, 0, 0)), 
    (2.0, Vectors.dense(0, 0, 1, 0)), 
    (2.0, Vectors.dense(0, 0, 0, 1)) 
).toDF("label", "features") 

val rf = new RandomForestClassifier() 
    .setFeaturesCol("features") 
    .setNumTrees(5) 

rf.setLabelCol("label").fit(df) 
// java.lang.IllegalArgumentException: RandomForestClassifier was given input ... 

次のいずれかを行うことができ、再エンコード・ラベル列:

import org.apache.spark.ml.feature.StringIndexer 

val indexer = new StringIndexer() 
    .setInputCol("label") 
    .setOutputCol("label_idx") 
    .fit(df) 

rf.setLabelCol("label_idx").fit(indexer.transform(df)) 

またはset required metadata manually

val meta = NominalAttribute 
    .defaultAttr 
    .withName("label") 
    .withValues("0.0", "1.0", "2.0") 
    .toMetadata 

rf.setLabelCol("label_meta").fit(
    df.withColumn("label_meta", $"label".as("", meta)) 
) 

ラベルはを使用して作成PySpark

indexer.labels 
// Array[String] = Array(2.0, 0.0, 1.0) 

:周波数ではない値に依存Pythonのメタデータ・フィールドで

スキーマに直接設定することができる。

from pyspark.sql.types import StructField, DoubleType 

StructField(
    "label", DoubleType(), False, 
    {"ml_attr": { 
     "name": "label", 
     "type": "nominal", 
     "vals": ["0.0", "1.0", "2.0"] 
    }} 
) 
関連する問題