|
|
@@ -1,295 +0,0 @@
|
|
|
-package com.controller;
|
|
|
-
|
|
|
-import com.annotation.IgnoreAuth;
|
|
|
-import com.annotation.SysLog;
|
|
|
-import com.baomidou.mybatisplus.mapper.EntityWrapper;
|
|
|
-import com.baomidou.mybatisplus.mapper.Wrapper;
|
|
|
-import com.entity.LoadForecastEntity;
|
|
|
-import com.entity.RainfalldataEntity;
|
|
|
-import com.entity.RainfalldataforecastEntity;
|
|
|
-import com.entity.SubLoadEntity;
|
|
|
-import com.entity.view.RainfalldataforecastView;
|
|
|
-import com.entity.view.SubLoadForecastView;
|
|
|
-import com.service.RainfalldataService;
|
|
|
-import com.service.RainfalldataforecastService;
|
|
|
-import com.service.SubLoadForecastService;
|
|
|
-import com.service.SubLoadService;
|
|
|
-import com.utils.DeSensUtil;
|
|
|
-import com.utils.MPUtil;
|
|
|
-import com.utils.PageUtils;
|
|
|
-import com.utils.R;
|
|
|
-import org.apache.commons.math3.stat.regression.OLSMultipleLinearRegression;
|
|
|
-//import org.apache.spark.api.java.JavaSparkContext;
|
|
|
-import org.springframework.beans.factory.annotation.Autowired;
|
|
|
-import org.springframework.transaction.annotation.Transactional;
|
|
|
-import org.springframework.web.bind.annotation.*;
|
|
|
-import weka.core.*;
|
|
|
-
|
|
|
-import javax.servlet.http.HttpServletRequest;
|
|
|
-import java.text.DecimalFormat;
|
|
|
-import java.util.*;
|
|
|
-import java.util.stream.Stream;
|
|
|
-
|
|
|
-/**
|
|
|
- * 变电站负荷预测
|
|
|
- * 后端接口
|
|
|
- * @author
|
|
|
- * @email
|
|
|
- * @date 2025-03-17 16:24:19
|
|
|
- */
|
|
|
-@RestController
|
|
|
-@RequestMapping("/loadforecast")
|
|
|
-public class LoadforecastController {
|
|
|
- @Autowired
|
|
|
- private RainfalldataforecastService rainfalldataforecastService;
|
|
|
- @Autowired
|
|
|
- private RainfalldataService rainfalldataService;
|
|
|
- @Autowired
|
|
|
- private SubLoadForecastService subLoadForecastService;
|
|
|
-
|
|
|
- @Autowired
|
|
|
- private SubLoadService subLoadService;
|
|
|
- /**
|
|
|
- * 后台列表
|
|
|
- */
|
|
|
- @RequestMapping("/page")
|
|
|
- public R page(@RequestParam Map<String, Object> params, LoadForecastEntity loadForecastEntity,
|
|
|
- HttpServletRequest request){
|
|
|
- //设置查询条件
|
|
|
- EntityWrapper<LoadForecastEntity> ew = new EntityWrapper<LoadForecastEntity>();
|
|
|
- //查询结果
|
|
|
- PageUtils page = subLoadForecastService.queryPage(params, MPUtil.sort(MPUtil.between(MPUtil.likeOrEq(ew, loadForecastEntity), params), params));
|
|
|
- Map<String, String> deSens = new HashMap<>();
|
|
|
- //给需要脱敏的字段脱敏
|
|
|
- DeSensUtil.desensitize(page,deSens);
|
|
|
- return R.ok().put("data", page);
|
|
|
- }
|
|
|
- /**
|
|
|
- * 查询
|
|
|
- */
|
|
|
- @RequestMapping("/query")
|
|
|
- public R query(LoadForecastEntity loadForecastEntity){
|
|
|
- EntityWrapper< LoadForecastEntity> ew = new EntityWrapper< LoadForecastEntity>();
|
|
|
- ew.allEq(MPUtil.allEQMapPre( loadForecastEntity, "forecast"));
|
|
|
- SubLoadForecastView rainfalldataforecastView = subLoadForecastService.selectView(ew);
|
|
|
- return R.ok("查询变电站负荷预测成功").put("data", rainfalldataforecastView);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 后台详情
|
|
|
- */
|
|
|
- @RequestMapping("/info/{id}")
|
|
|
- public R info(@PathVariable("id") Long id){
|
|
|
- LoadForecastEntity dataforecast = subLoadForecastService.selectById(id);
|
|
|
- Map<String, String> deSens = new HashMap<>();
|
|
|
- //给需要脱敏的字段脱敏
|
|
|
- DeSensUtil.desensitize(dataforecast,deSens);
|
|
|
- return R.ok().put("data", dataforecast);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 前台详情
|
|
|
- */
|
|
|
- @IgnoreAuth
|
|
|
- @RequestMapping("/detail/{id}")
|
|
|
- public R detail(@PathVariable("id") Long id){
|
|
|
- LoadForecastEntity dataforecast = subLoadForecastService.selectById(id);
|
|
|
- Map<String, String> deSens = new HashMap<>();
|
|
|
- //给需要脱敏的字段脱敏
|
|
|
- DeSensUtil.desensitize(dataforecast,deSens);
|
|
|
- return R.ok().put("data", dataforecast);
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- /**
|
|
|
- * 后台保存
|
|
|
- */
|
|
|
- @RequestMapping("/save")
|
|
|
- @SysLog("新增变电站负荷预测")
|
|
|
- public R save(@RequestBody LoadForecastEntity dataforecast, HttpServletRequest request){
|
|
|
- dataforecast.setUserid((Long)request.getSession().getAttribute("userId"));
|
|
|
- subLoadForecastService.insert(dataforecast);
|
|
|
- return R.ok().put("data",dataforecast.getId());
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 前台保存
|
|
|
- */
|
|
|
- @SysLog("新增变电站负荷预测")
|
|
|
- @RequestMapping("/add")
|
|
|
- public R add(@RequestBody LoadForecastEntity dataforecast, HttpServletRequest request){
|
|
|
- subLoadForecastService.insert(dataforecast);
|
|
|
- return R.ok().put("data",dataforecast.getId());
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- /**
|
|
|
- * 修改
|
|
|
- */
|
|
|
- @RequestMapping("/update")
|
|
|
- @Transactional
|
|
|
- @SysLog("修改变电站负荷预测")
|
|
|
- public R update(@RequestBody LoadForecastEntity dataforecast, HttpServletRequest request){
|
|
|
- //全部更新
|
|
|
- subLoadForecastService.updateById(dataforecast);
|
|
|
- return R.ok();
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 删除
|
|
|
- */
|
|
|
- @RequestMapping("/delete")
|
|
|
- @SysLog("删除变电站负荷预测")
|
|
|
- public R delete(@RequestBody Long[] ids){
|
|
|
- subLoadForecastService.deleteBatchIds(Arrays.asList(ids));
|
|
|
- return R.ok();
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 预测算法
|
|
|
- */
|
|
|
- @RequestMapping("/forecast")
|
|
|
- public R forecast(@RequestBody Map<String, Object> params) throws Exception {
|
|
|
- // 特征值
|
|
|
- String[] eigenValueArr = "main_capacity,peak_load,base_load,load_rate,electric_heating_load,users_num,pf_users_num,join_electric_heating_num".split(",");
|
|
|
- // 目标值
|
|
|
- String[] targetValueArr = "load_rate".split(",");
|
|
|
- String[] sqlSelectArr = Stream.of(eigenValueArr, targetValueArr).flatMap(Arrays::stream).toArray(String[]::new);
|
|
|
- // 模型训练
|
|
|
- Wrapper<SubLoadEntity> wrapper = new EntityWrapper<>();
|
|
|
- wrapper.setSqlSelect(sqlSelectArr);
|
|
|
- for (String arr : sqlSelectArr) {
|
|
|
- wrapper.isNotNull(arr).ne(arr, "");
|
|
|
- }
|
|
|
- // 从数据库获取需要元数据
|
|
|
- List<Map<String,Object>> list =subLoadService.selectMaps(wrapper);
|
|
|
- // 模型训练
|
|
|
- Instances instances = createInstances(list, sqlSelectArr);
|
|
|
- // 创建一个map来存储预测结果
|
|
|
- Map<String, Object> forecastRes = forecastRes(instances, params, eigenValueArr, targetValueArr);
|
|
|
-
|
|
|
- // 更新数据库或其他操作
|
|
|
- EntityWrapper<LoadForecastEntity> ew = new EntityWrapper<>();
|
|
|
- ew.eq("id", params.get("id"));
|
|
|
- for (Map.Entry<String, Object> entry : forecastRes.entrySet()) {
|
|
|
- String updateSet = entry.getKey() + "='" + entry.getValue().toString() + "'";
|
|
|
- subLoadForecastService.updateForSet(updateSet, ew);
|
|
|
- }
|
|
|
- params.putAll(forecastRes);
|
|
|
- return R.ok(params);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 预测结果
|
|
|
- * @param instances
|
|
|
- * @param params
|
|
|
- * @param eigenValueArr
|
|
|
- * @param targetValueArr
|
|
|
- * @return
|
|
|
- * @throws Exception
|
|
|
- */
|
|
|
- private Map<String, Object> forecastRes(Instances instances, Map<String, Object> params, String[] eigenValueArr, String[] targetValueArr) throws Exception {
|
|
|
- Map<String, Object> forecastRes = new HashMap<>();
|
|
|
- DecimalFormat df = new DecimalFormat("#.00");
|
|
|
-
|
|
|
- for (String targetValue : targetValueArr) {
|
|
|
- // 创建线性回归模型
|
|
|
- OLSMultipleLinearRegression regression = new OLSMultipleLinearRegression();
|
|
|
-
|
|
|
- // 准备数据
|
|
|
- double[][] x = new double[instances.numInstances()][eigenValueArr.length];
|
|
|
- double[] y = new double[instances.numInstances()];
|
|
|
-
|
|
|
- for (int i = 0; i < instances.numInstances(); i++) {
|
|
|
- Instance instance = instances.instance(i);
|
|
|
- for (int j = 0; j < eigenValueArr.length; j++) {
|
|
|
- x[i][j] = instance.value(instances.attribute(eigenValueArr[j]));
|
|
|
- }
|
|
|
- y[i] = instance.value(instances.attribute(targetValue));
|
|
|
- }
|
|
|
-
|
|
|
- // 训练模型
|
|
|
- regression.newSampleData(y, x);
|
|
|
-
|
|
|
- // 创建新的样本数据
|
|
|
- double[] sampleData = new double[eigenValueArr.length];
|
|
|
- for (int i = 0; i < eigenValueArr.length; i++) {
|
|
|
- Attribute attribute = instances.attribute(eigenValueArr[i]);
|
|
|
- if (attribute.isNominal()) {
|
|
|
- sampleData[i] = attribute.indexOfValue(params.get(eigenValueArr[i]).toString());
|
|
|
- } else {
|
|
|
- sampleData[i] = Double.parseDouble(params.get(eigenValueArr[i]).toString());
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 进行预测
|
|
|
- double predictedValue = regression.estimateRegressionParameters()[0]; // 截距
|
|
|
- for (int i = 1; i <= eigenValueArr.length; i++) {
|
|
|
- predictedValue += regression.estimateRegressionParameters()[i] * sampleData[i - 1];
|
|
|
- }
|
|
|
-
|
|
|
- // 添加预测结果
|
|
|
- forecastRes.put(targetValue, df.format(predictedValue));
|
|
|
- }
|
|
|
- return forecastRes;
|
|
|
-}
|
|
|
-
|
|
|
- /**
|
|
|
- * 训练模型
|
|
|
- */
|
|
|
- private Instances createInstances(List<Map<String, Object>> dataList, String[] attrs) throws Exception {
|
|
|
- // 遍历数据集以确定每个属性的类型
|
|
|
- Map<String, Set<Object>> uniqueValuesPerAttribute = new HashMap<>();
|
|
|
- for (Map<String, Object> data : dataList) {
|
|
|
- for (String attr : attrs) {
|
|
|
- uniqueValuesPerAttribute.computeIfAbsent(attr, k -> new HashSet<>()).add(data.get(attr));
|
|
|
- }
|
|
|
- }
|
|
|
- FastVector attributes = new FastVector();
|
|
|
- for (String attr : attrs) {
|
|
|
- Set<Object> uniqueValues = uniqueValuesPerAttribute.get(attr);
|
|
|
- if (isNominal(uniqueValues)) {
|
|
|
- // 如果是分类属性,创建分类属性
|
|
|
- FastVector nominalValues = new FastVector();
|
|
|
- uniqueValues.forEach(value -> nominalValues.addElement(value));
|
|
|
- nominalValues.add("unknown");
|
|
|
- attributes.addElement(new Attribute(attr, nominalValues));
|
|
|
- } else {
|
|
|
- attributes.addElement(new Attribute(attr));
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 创建 Instances 对象
|
|
|
- Instances dataset = new Instances("dataset-name", attributes, dataList.size());
|
|
|
- dataset.setClassIndex(dataset.numAttributes() - 1); // 设置类属性索引
|
|
|
- // 填充数据
|
|
|
- for (Map<String, Object> data : dataList) {
|
|
|
- double[] instanceValue = new double[dataset.numAttributes()];
|
|
|
- int i = 0;
|
|
|
- for (String attr : attrs) {
|
|
|
- Attribute attribute = dataset.attribute(attr);
|
|
|
- if (attribute.isNominal()) {
|
|
|
- instanceValue[i++] = attribute.indexOfValue(data.get(attr).toString());
|
|
|
- } else {
|
|
|
- instanceValue[i++] = Double.parseDouble(data.get(attr).toString());
|
|
|
- }
|
|
|
- }
|
|
|
- Instance instance = new DenseInstance(1.0, instanceValue);
|
|
|
- dataset.add(instance);
|
|
|
- }
|
|
|
- return dataset;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 检测数据类型是否为字符串
|
|
|
- */
|
|
|
- private boolean isNominal(Set<Object> values) {
|
|
|
- // 检查是否所有的值都是字符串,并且数量是否超过某个阈值(例如,如果超过50%的值是唯一的,则可能是分类属性)
|
|
|
- return values.stream().allMatch(v -> v instanceof String);
|
|
|
- }
|
|
|
-}
|