DefaultClassification.scala 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. package com.example.model.classification
  2. import java.util
  3. import com.example.SparkConnect
  4. import com.example.entity.Model
  5. import com.example.model.helper.Utils
  6. import org.apache.spark.ml.classification.{DecisionTreeClassificationModel, DecisionTreeClassifier, LogisticRegression, LogisticRegressionModel}
  7. import org.apache.spark.ml.evaluation.MulticlassClassificationEvaluator
  8. import org.apache.spark.ml.feature.{IndexToString, StringIndexer, VectorIndexer}
  9. import org.apache.spark.ml.{Pipeline, PipelineModel, PipelineStage}
  10. import org.apache.spark.sql.{Dataset, Row}
  11. import org.springframework.beans.factory.annotation.Autowired
  12. import org.springframework.stereotype.Component
  13. import com.example.util.Constant
  14. import scala.collection.mutable
  15. /**
  16. * 分类方法的默认实现
  17. * @author fanyanpeng
  18. * @date 2023/3/22 16:15
  19. */
  20. class DefaultClassification extends SparkConnect {
  21. @Autowired
  22. val utils: Utils = null
  23. @throws(classOf[Exception])
  24. def training(libsvmFileUri: String,
  25. params: util.Map[String,Object]): (PipelineModel,util.Map[String, String]) = {
  26. val trainSet = sparkSession.read.format("libsvm").load(libsvmFileUri)
  27. trainSet.show()
  28. val maxCategories = params.get(Constant.TRAIN_PARAM_MAX_CATEGORY).asInstanceOf[Int]
  29. val featureIndexer = new VectorIndexer()
  30. .setInputCol("features")
  31. .setOutputCol("indexedFeatures")
  32. .setMaxCategories(maxCategories)
  33. .fit(trainSet)
  34. trainSet.show()
  35. // Split the data into training and test sets (30% held out for testing).
  36. //为了对训练效果进行评估,将训练集进一步划分为子训练集与子测试集
  37. var Array(subTrainSet:Dataset[Row], subTestSet:Dataset[Row]) = trainSet.randomSplit(Array(0.7, 1 - 0.7))
  38. /*******************************************/
  39. //需要由子类实现
  40. val classifier = buildClassifier(params)
  41. /*******************************************/
  42. val pipeline = new Pipeline()
  43. .setStages(Array(featureIndexer, classifier))
  44. // Train model. This also runs the indexers.
  45. val pipelineModel:PipelineModel = pipeline.fit(subTrainSet)
  46. val resultMap:util.Map[String,String] = new util.HashMap[String,String]()
  47. // Make predictions.
  48. val predictions = pipelineModel.transform(subTestSet)
  49. // Select (prediction, true label) and compute test error.
  50. //为了简便,使用了多分类
  51. val evaluator = new MulticlassClassificationEvaluator()
  52. .setLabelCol("label")
  53. .setPredictionCol("prediction")
  54. val weightedRecall = evaluator.setMetricName("weightedRecall").evaluate(predictions);
  55. val accuracy = evaluator.setMetricName("accuracy").evaluate(predictions)
  56. log.info("Test Error = " + (1.0 - accuracy))
  57. val weightedPrecision = evaluator.setMetricName("weightedPrecision").evaluate(predictions);
  58. val f1 = evaluator.setMetricName("f1").evaluate(predictions);
  59. val model = pipelineModel.stages(1).asInstanceOf[LogisticRegressionModel]
  60. //println("Learned classification tree model:\n" + treeModel.toDebugString)
  61. log.info("\n\nLearned classification Logistic model:\n" + model.toString());
  62. resultMap.put("Accuracy: ", accuracy.toString)
  63. resultMap.put("weightedPrecision", weightedPrecision.toString)
  64. resultMap.put("weightedRecall", weightedRecall.toString)
  65. resultMap.put("f1", f1.toString)
  66. return (pipelineModel, resultMap)
  67. }
  68. /**
  69. * 默认实现:逻辑回归
  70. * @author fanyanpeng
  71. * @date 2023/3/22 16:44
  72. * @param params 参数列表
  73. * @return org.apache.spark.ml.PipelineStage
  74. */
  75. def buildClassifier(params:util.Map[String,Object]):PipelineStage = {
  76. val maxIter = params.get(Constant.TRAIN_PARAM_MAX_ITER).asInstanceOf[Int]
  77. val regParam = params.get(Constant.TRAIN_PARAM_REG_PARAM).asInstanceOf[Float]
  78. val elasticNetParam = params.get(Constant.TRAIN_PARAM_ELASTICNET_PARAM).asInstanceOf[Float]
  79. val lr = new LogisticRegression()
  80. .setLabelCol("label")
  81. .setFeaturesCol("indexedFeatures")
  82. .setMaxIter(maxIter)
  83. .setRegParam(regParam)
  84. .setElasticNetParam(elasticNetParam)
  85. lr
  86. }
  87. }