См. Ошибки прогнозирования различных параметров из CrossValidator Spark MLlib (в Scala) [дубликат]

JFrame.setVisible(true);

Вы можете использовать метод setVisible(false) или dispose() для исчезновения текущей формы.

0
задан Theophile Champion 26 June 2018 в 11:33
поделиться

1 ответ

Вот возможное решение для конкретного случая LinearRegression и любого другого алгоритма, поддерживающего объективную историю (в этом случае И LinearRegressionTrainingSummary выполняет задание).

Сначала создадим минимальный проверяемый и полный пример :

import org.apache.spark.ml.param.ParamMap
import org.apache.spark.ml.regression.{LinearRegression, LinearRegressionModel}
import org.apache.spark.ml.tuning.{ParamGridBuilder, TrainValidationSplit}
import org.apache.spark.mllib.util.{LinearDataGenerator, MLUtils}
import org.apache.spark.sql.SparkSession

val spark: SparkSession = SparkSession.builder().getOrCreate()

import org.apache.spark.ml.evaluation.RegressionEvaluator
import spark.implicits._

val data = {
  val tmp = LinearDataGenerator.generateLinearRDD(
    spark.sparkContext,
    nexamples = 10000,
    nfeatures = 4,
    eps = 0.05
  ).toDF

  MLUtils.convertVectorColumnsToML(tmp, "features")
}

Как вы заметили, когда вы хотите генерировать данные для целей тестирования для spark-mllib или spark-ml, рекомендуется использовать генераторы данных.

Теперь давайте тренируем линейный регресс:

// Create model of linear regression.
val lr = new LinearRegression().setMaxIter(1000)

// The following line will create two sets of parameters
val paramGrid = new ParamGridBuilder().addGrid(lr.regParam, Array(0.001)).addGrid(lr.fitIntercept).addGrid(lr.elasticNetParam, Array(0.5)).build()

// Create trainer using validation split to evaluate which set of parameters performs the best.
// I'm using the regular RegressionEvaluator here
val trainValidationSplit = new TrainValidationSplit()
  .setEstimator(lr)
  .setEvaluator(new RegressionEvaluator)
  .setEstimatorParamMaps(paramGrid)
  .setTrainRatio(0.8) // 80% of the data will be used for training and the remaining 20% for validation.

// To retrieve subModels, make sure to set collectSubModels to true before fitting.
trainValidationSplit.setCollectSubModels(true)
// Run train validation split, and choose the best set of parameters.
var model = trainValidationSplit.fit(data)

Теперь, когда наша модель обучена, все, что нам нужно, это получить объективную история.

Следующая часть нуждается в некоторой части гимнастики между параметрами объекта модели и подмодели.

Если у вас есть Pipeline или так, этот код необходимо изменить, поэтому используйте его внимательно. Это просто пример:

val objectiveHist = spark.sparkContext.parallelize(
  model.subModels.zip(model.getEstimatorParamMaps).map {
    case (m: LinearRegressionModel, pm: ParamMap) =>
      val history: Array[Double] = m.summary.objectiveHistory
      val idx: Seq[Int] = 1 until history.length
      // regParam, elasticNetParam, fitIntercept
      val parameters = pm.toSeq.map(pair => (pair.param.name, pair.value.toString)) match {
        case Seq(x, y, z) => (x._2, y._2, z._2)
      }
      (parameters._1, parameters._2, parameters._3, idx.zip(history).toMap)
  }).toDF("regParam", "elasticNetParam", "fitIntercept", "objectiveHistory")

Теперь мы можем проверить эти показатели:

objectiveHist.show(false)
// +--------+---------------+------------+-------------------------------------------------------------------------------------------------------+
// |regParam|elasticNetParam|fitIntercept|objectiveHistory                                                                                       |
// +--------+---------------+------------+-------------------------------------------------------------------------------------------------------+
// |0.001   |0.5            |true        |[1 -> 0.4999999999999999, 2 -> 0.4038796441909531, 3 -> 0.02659222058006269, 4 -> 0.026592220340980147]|
// |0.001   |0.5            |false       |[1 -> 0.5000637621421942, 2 -> 0.4039303922115196, 3 -> 0.026592220673025396, 4 -> 0.02659222039347222]|
// +--------+---------------+------------+-------------------------------------------------------------------------------------------------------+

Вы можете заметить, что процесс обучения фактически останавливается после 4 итераций.

Если вы хотите просто количество итераций, вы можете сделать следующее:

val objectiveHist2 = spark.sparkContext.parallelize(
  model.subModels.zip(model.getEstimatorParamMaps).map {
    case (m: LinearRegressionModel, pm: ParamMap) =>
      val history: Array[Double] = m.summary.objectiveHistory
      // regParam, elasticNetParam, fitIntercept
      val parameters = pm.toSeq.map(pair => (pair.param.name, pair.value.toString)) match {
        case Seq(x, y, z) => (x._2, y._2, z._2)
      }
      (parameters._1, parameters._2, parameters._3, history.size)
  }).toDF("regParam", "elasticNetParam", "fitIntercept", "iterations")

Я изменил количество функций в генераторе (nfeatures = 100) для демонстрации:

objectiveHist2.show
// +--------+---------------+------------+----------+
// |regParam|elasticNetParam|fitIntercept|iterations|
// +--------+---------------+------------+----------+
// |   0.001|            0.5|        true|        11|
// |   0.001|            0.5|       false|        11|
// +--------+---------------+------------+----------+
3
ответ дан eliasah 17 August 2018 в 12:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: