【问题标题】:java.lang.IllegalArgumentException: Field "label" does not exist using SparkMLjava.lang.IllegalArgumentException:使用 SparkML 的字段“标签”不存在
【发布时间】:2018-01-13 06:34:21
【问题描述】:

我正在使用 Spark 和 Scala 进行时间序列分析。我有一个来自 Cassandra 数据库的数据集,如下所示:

scala> train.printSchema
root
 |-- timestamp: timestamp (nullable = true)
 |-- vx: double (nullable = true)
 |-- speed: double (nullable = true)

我尝试了线性回归,如here 所示,只是为了看看它是如何工作的。

scala> val lr = new LinearRegression().
 |   setMaxIter(10).
 |   setRegParam(0.3).
 |   setElasticNetParam(0.8)
scala> val lrModel = lr.fit(train)

但是,我收到一个错误:

java.lang.IllegalArgumentException:字段“功能”不存在。
在 org.apache.spark.sql.types.StructType$$anonfun$apply$1.apply(StructType.sca 拉:266)在 org.apache.spark.sql.types.StructType$$anonfun$apply$1.apply(StructType.sca 拉:266)在 scala.collection.MapLike$class.getOrElse(MapLike.scala:128) 在 scala.collection.AbstractMap.getOrElse(Map.scala:59) 在 org.apache.spark.sql.types.StructType.apply(StructType.scala:265) 在 org.apache.spark.ml.util.SchemaUtils$.checkColumnType(SchemaUtils.scala:40)

在 org.apache.spark.ml.PredictorParams$class.validateAndTransformSchema(预测 tor.scala:51) 在 org.apache.spark.ml.Predictor.validateAndTransformSchema(Predictor.scala:82 ) 在 org.apache.spark.ml.Predictor.transformSchema(Predictor.scala:144)
在 org.apache.spark.ml.PipelineStage.transformSchema(Pipeline.scala:74)
在 org.apache.spark.ml.Predictor.fit(Predictor.scala:100) ... 66 省略了

看来我必须使用VectorAssembler 来创建包含预测变量的特征列,

scala> val assembler = new VectorAssembler().
 |   setInputCols(Array("timestamp","speed")).
 |   setOutputCol("features")
scala> val output = assembler.transform(train)

但它会引发错误TimestampType is not supported

java.lang.IllegalArgumentException:数据类型 TimestampType 不是 支持的。在 org.apache.spark.ml.feature.VectorAssembler$$anonfun$transformSchema$1.appl y(VectorAssembler.scala:121) 在 org.apache.spark.ml.feature.VectorAssembler$$anonfun$transformSchema$1.appl y(VectorAssembler.scala:117) 在 scala.collection.IndexedSeqOptimized$class.foreach(IndexedSeqOptimized.scal 答:33)在 scala.collection.mutable.ArrayOps$ofRef.foreach(ArrayOps.scala:186)
在 org.apache.spark.ml.feature.VectorAssembler.transformSchema(VectorAssembler .scala:117) 在 org.apache.spark.ml.PipelineStage.transformSchema(Pipeline.scala:74)
在 org.apache.spark.ml.feature.VectorAssembler.transform(VectorAssembler.scala :54) ... 66 省略

如果我忽略时间戳并仅使用 VectorAssembler 中的一列,它会再次引发错误。见下文,

scala> val assembler = new VectorAssembler().
     |   setInputCols(Array("speed")).
     |   setOutputCol("features")
scala> val output = assembler.transform(train)
scala> val lrModel = lr.fit(output)

java.lang.IllegalArgumentException:字段“标签”不存在。在 org.apache.spark.sql.types.StructType$$anonfun$apply$1.apply(StructType.sca 拉:266)在 org.apache.spark.sql.types.StructType$$anonfun$apply$1.apply(StructType.sca 拉:266)在 scala.collection.MapLike$class.getOrElse(MapLike.scala:128) 在 scala.collection.AbstractMap.getOrElse(Map.scala:59) 在 org.apache.spark.sql.types.StructType.apply(StructType.scala:265) 在 org.apache.spark.ml.util.SchemaUtils$.checkNumericType(SchemaUtils.scala:71 ) 在 org.apache.spark.ml.PredictorParams$class.validateAndTransformSchema(预测 tor.scala:53) 在 org.apache.spark.ml.Predictor.validateAndTransformSchema(Predictor.scala:82 ) 在 org.apache.spark.ml.Predictor.transformSchema(Predictor.scala:144)
在 org.apache.spark.ml.PipelineStage.transformSchema(Pipeline.scala:74)
在 org.apache.spark.ml.Predictor.fit(Predictor.scala:100) ... 66 省略了

当我单独输入 speed 作为预测变量时,我不知道为什么它会显示 Field "label" does not exist。任何帮助深表感谢。

【问题讨论】:

    标签: scala linear-regression apache-spark-ml apache-spark-dataset apache-spark-2.0


    【解决方案1】:

    您需要定义用作特征和类标签的列。如果将多个列用作特征,则使用 VectorAssembler() 是合适的,就像您所做的那样。否则,只需使用带有列名的setFeaturesCol() 方法就足够了。注意这里的输入列必须包含向量,不能是双精度数。

    对于类标签(属于哪个类),可以使用setLabelCol()来定义使用哪一列。在您的情况下,由于 timestampspeed 列是预测变量,我会假设 vx 列是标签。

    要使用时间戳,您可以简单地将其转换为 Unix 纪元时间;

    df2 = df.withColumn("unix_time", unix_timestamp(df("timestamp")))
    

    这将为您提供自 1970 年 1 月 1 日以来的秒数。

    希望对你有帮助!

    【讨论】:

    • 您好,谢谢。我是这样做的,val lr = new LinearRegression().setMaxIter(10).setRegParam(0.3).setElasticNetParam(0.8).setFeaturesCol("speed").setLabelCol("vx"),当我适合它lrModel = lr.fit(trainData) 时,它会抛出向量类型的错误java.lang.IllegalArgumentException: requirement failed: Column speed must be of type org.apache.spark.ml.linalg.VectorUDT@3bfc3ba7 but was actually DoubleType. 如何将此列速度转换为向量 UDT 类型。
    • @DhivyaNarayanasamy 错过了列类型为双精度。最简单的方法是像以前一样继续使用VectorAssembler。或者,您可以使用 UDT 来转换列。
    • @DhivyaNarayanasamy 稍微更新了答案。希望对您有所帮助!
    • 嗨,我得到了这样的答案` val tr = output.withColumn("label", output("vx")).select("features", "label")`。谢谢。
    • @DhivyaNarayanasamy 如果对您有帮助,请接受答案
    猜你喜欢
    • 2017-12-10
    • 2021-09-24
    • 2013-04-25
    • 1970-01-01
    • 1970-01-01
    • 2017-11-14
    • 2017-11-30
    • 1970-01-01
    • 2021-07-21
    相关资源
    最近更新 更多