тип TimestampType столбца не поддерживается - PullRequest
0 голосов
/ 31 мая 2018

я использую искры со scala и имею проблему с типом TimestampType

 object regressionLinear {
  case class X(
                time:String,nodeID: Int, posX: Double,posY: Double,
                speed: Double,period: Int)

  def main (args: Array[String]) {

Logger.getLogger("org").setLevel(Level.OFF)
Logger.getLogger("akka").setLevel(Level.OFF)

/**
  * Read the input data
  */
var dataset = "C:\\spark\\A6-d07-h08.csv"
if (args.length > 0) {
  dataset = args(0)
}

val spark = SparkSession
  .builder
  .appName("regressionsol")
  .master("local[4]")
  .getOrCreate()

import spark.implicits._


val data = spark.sparkContext.textFile(dataset)
     .map(line=>line.split(","))
.map(userRecord => (userRecord(0).trim.toString,
      userRecord(1).trim.toInt, userRecord(2).trim.toDouble,userRecord(3).trim.toDouble,userRecord(4).trim.toDouble,userRecord(5).trim.toInt))
.toDF("time","nodeID","posX", "posY","speed","period").withColumn("time", $"time".cast("timestamp"))


val assembler = new VectorAssembler()
  .setInputCols( Array(
    "time","nodeID","posX", "posY","speed","period"))
  .setOutputCol("features")


val lr = new LinearRegression()
  .setLabelCol("period")
  .setFeaturesCol("features")
   .setRegParam(0.1)
  .setMaxIter(100)
  .setSolver("l-bfgs")

val steps = 
  Array(assembler, lr)

val pipeline = new Pipeline()
  .setStages(steps)

val Array(training, test) = data.randomSplit(Array(0.75, 0.25), seed = 12345)


val model = pipeline.fit {
  training
}

val holdout = model.transform(test)
holdout.show(20)

val prediction = holdout.select("prediction", "period","nodeID").orderBy(abs(col("prediction")-col("period")))
prediction.show(20)


val rm = new RegressionMetrics(prediction.rdd.map{
  x =>  (x(0).asInstanceOf[Double], x(1).asInstanceOf[Double])
})
println(s"RMSE = ${rm.rootMeanSquaredError}")
println(s"R-squared = ${rm.r2}")

spark.stop()
  }

}

это ошибка

Исключение в потоке "main" java.lang.IllegalArgumentException:Тип данных TimestampType времени столбца не поддерживается.в org.apache.spark.ml.feature.VectorAssembler.transformSchema (VectorAssembler.scala: 124) в org.apache.spark.ml.Pipeline $$ anonfun $ transformSchema $ 4.apply (Pipeline.scala: 184) в org.apache.spark..scala: 66) в scala.collection.mutable.ArrayOps $ ofRef.foldLeft (ArrayOps.scala: 186) в org.apache.spark.ml.Pipeline.transformSchema (Pipeline.scala: 184) в org.apache.spark.ml.PipelineStage.transformSchema (Pipeline.scala: 74) в org.apache.spark.ml.Pipeline.fit (Pipeline.scala: 136) в regressionLinear $ .main (regressionLinear.scala: 100) в regressionLinear.main (regressionLinear.scala)

1 Ответ

0 голосов
/ 31 мая 2018

VectorAssembler принимает только числовые столбцы.Другие типы столбцов должны быть закодированы в первую очередь.И, учитывая, что вы применяете LinearRegression, данные должны быть закодированы в любом случае.

Точные шаги будут зависеть от знаний в конкретной области:

  • Если вы ожидаете линейный тренд, основанный на поле временисначала в числовое значение.
  • Если вы ожидаете какой-либо сезонный эффект, вам, возможно, придется извлечь отдельные компоненты (день недели, час / время дня, месяц и т. д.) и, как правило, применить StringIndexer + `OneHotEncoder.
...