| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114 |
- package com.example.model.classification
- import java.util
- import com.example.SparkConnect
- import com.example.entity.Model
- import com.example.model.helper.Utils
- import org.apache.spark.ml.classification.{DecisionTreeClassificationModel, DecisionTreeClassifier, LogisticRegression, LogisticRegressionModel}
- import org.apache.spark.ml.evaluation.MulticlassClassificationEvaluator
- import org.apache.spark.ml.feature.{IndexToString, StringIndexer, VectorIndexer}
- import org.apache.spark.ml.{Pipeline, PipelineModel, PipelineStage}
- import org.apache.spark.sql.{Dataset, Row}
- import org.springframework.beans.factory.annotation.Autowired
- import org.springframework.stereotype.Component
- import com.example.util.Constant
- import scala.collection.mutable
- /**
- * 分类方法的默认实现
- * @author fanyanpeng
- * @date 2023/3/22 16:15
- */
- class DefaultClassification extends SparkConnect {
- @Autowired
- val utils: Utils = null
- @throws(classOf[Exception])
- def training(libsvmFileUri: String,
- params: util.Map[String,Object]): (PipelineModel,util.Map[String, String]) = {
- val trainSet = sparkSession.read.format("libsvm").load(libsvmFileUri)
- trainSet.show()
- val maxCategories = params.get(Constant.TRAIN_PARAM_MAX_CATEGORY).asInstanceOf[Int]
- val featureIndexer = new VectorIndexer()
- .setInputCol("features")
- .setOutputCol("indexedFeatures")
- .setMaxCategories(maxCategories)
- .fit(trainSet)
- trainSet.show()
- // Split the data into training and test sets (30% held out for testing).
- //为了对训练效果进行评估,将训练集进一步划分为子训练集与子测试集
- var Array(subTrainSet:Dataset[Row], subTestSet:Dataset[Row]) = trainSet.randomSplit(Array(0.7, 1 - 0.7))
- /*******************************************/
- //需要由子类实现
- val classifier = buildClassifier(params)
- /*******************************************/
- val pipeline = new Pipeline()
- .setStages(Array(featureIndexer, classifier))
- // Train model. This also runs the indexers.
- val pipelineModel:PipelineModel = pipeline.fit(subTrainSet)
- val resultMap:util.Map[String,String] = new util.HashMap[String,String]()
- // Make predictions.
- val predictions = pipelineModel.transform(subTestSet)
- // Select (prediction, true label) and compute test error.
- //为了简便,使用了多分类
- val evaluator = new MulticlassClassificationEvaluator()
- .setLabelCol("label")
- .setPredictionCol("prediction")
- val weightedRecall = evaluator.setMetricName("weightedRecall").evaluate(predictions);
- val accuracy = evaluator.setMetricName("accuracy").evaluate(predictions)
- log.info("Test Error = " + (1.0 - accuracy))
- val weightedPrecision = evaluator.setMetricName("weightedPrecision").evaluate(predictions);
- val f1 = evaluator.setMetricName("f1").evaluate(predictions);
- val model = pipelineModel.stages(1).asInstanceOf[LogisticRegressionModel]
- //println("Learned classification tree model:\n" + treeModel.toDebugString)
- log.info("\n\nLearned classification Logistic model:\n" + model.toString());
- resultMap.put("Accuracy: ", accuracy.toString)
- resultMap.put("weightedPrecision", weightedPrecision.toString)
- resultMap.put("weightedRecall", weightedRecall.toString)
- resultMap.put("f1", f1.toString)
- return (pipelineModel, resultMap)
- }
- /**
- * 默认实现:逻辑回归
- * @author fanyanpeng
- * @date 2023/3/22 16:44
- * @param params 参数列表
- * @return org.apache.spark.ml.PipelineStage
- */
- def buildClassifier(params:util.Map[String,Object]):PipelineStage = {
- val maxIter = params.get(Constant.TRAIN_PARAM_MAX_ITER).asInstanceOf[Int]
- val regParam = params.get(Constant.TRAIN_PARAM_REG_PARAM).asInstanceOf[Float]
- val elasticNetParam = params.get(Constant.TRAIN_PARAM_ELASTICNET_PARAM).asInstanceOf[Float]
- val lr = new LogisticRegression()
- .setLabelCol("label")
- .setFeaturesCol("indexedFeatures")
- .setMaxIter(maxIter)
- .setRegParam(regParam)
- .setElasticNetParam(elasticNetParam)
- lr
- }
- }
|