APIController.java 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. package com.hb.proj.api.controller;
  2. import java.util.ArrayList;
  3. import java.util.Arrays;
  4. import java.util.Collections;
  5. import java.util.Date;
  6. import java.util.HashMap;
  7. import java.util.List;
  8. import java.util.Map;
  9. import org.springframework.beans.factory.annotation.Autowired;
  10. import org.springframework.validation.annotation.Validated;
  11. import org.springframework.web.bind.annotation.PostMapping;
  12. import org.springframework.web.bind.annotation.RequestBody;
  13. import org.springframework.web.bind.annotation.RequestMapping;
  14. import org.springframework.web.bind.annotation.RequestParam;
  15. import org.springframework.web.bind.annotation.RestController;
  16. import com.hb.proj.diagnose.FeatureExtractor;
  17. import com.hb.proj.diagnose.XGBoostDataUtil;
  18. import com.hb.proj.diagnose.XGBoostEngine;
  19. import com.hb.proj.model.DiagnoseStandard;
  20. import com.hb.proj.model.DiagramFeatureSample;
  21. import com.hb.proj.model.DiagramSample;
  22. import com.hb.proj.model.Hyperparam;
  23. import com.hb.proj.model.TrainLog;
  24. import com.hb.proj.model.TrainParam;
  25. import com.hb.proj.rep.DiagramSampleService;
  26. import com.hb.proj.third.RedisMsgProcessor;
  27. import com.hb.proj.utils.JacksonUtils;
  28. import com.hb.proj.utils.RespVO;
  29. import com.hb.proj.utils.RespVOBuilder;
  30. import com.hb.xframework.dao.util.PageModel;
  31. import com.hb.xframework.util.DateUtil;
  32. import com.hb.xframework.util.MapUtils;
  33. import jakarta.validation.Valid;
  34. import jakarta.validation.constraints.NotBlank;
  35. import jakarta.validation.constraints.NotNull;
  36. @RestController
  37. @RequestMapping("/api")
  38. @Validated
  39. public class APIController {
  40. @Autowired
  41. private DiagramSampleService sampleService;
  42. @Autowired
  43. private XGBoostEngine xgbEngine;
  44. @Autowired
  45. private RedisMsgProcessor msgProcessor;
  46. /**
  47. * 获得批量诊断队列的当前大小
  48. * @return
  49. */
  50. @RequestMapping("/buffer/size")
  51. public RespVO<Object> getBufferSize(){
  52. return RespVOBuilder.ok(msgProcessor.getQueueSize());
  53. }
  54. /**
  55. * 获得功图绘制数据(样本功图)
  56. * @param wellId
  57. * @param paramCode
  58. * @param action
  59. * @param refTime
  60. * @return
  61. */
  62. @RequestMapping("/sample/getDrawData")
  63. public RespVO<Object> getDrawData(@NotBlank(message = "缺少井名") String wellName,@NotNull(message = "缺少功图时间") Date diagramTime){
  64. DiagramFeatureSample sample=sampleService.find(wellName, diagramTime);
  65. if(sample==null) {
  66. return RespVOBuilder.error("无数据");
  67. }
  68. return RespVOBuilder.ok(buildData(sample));
  69. }
  70. private Map<String,Object> buildData(DiagramFeatureSample sample){
  71. String smpTime=DateUtil.format(sample.getDiagramTime(),"yyyy-MM-dd HH:mm:ss");
  72. String[] dtstr=smpTime.split(" ");
  73. Map<String,Object> base=new HashMap<String,Object>();
  74. base.put("xTitle", "位移");
  75. base.put("yTitle", "载荷");
  76. base.put("xUnit", "m");
  77. base.put("yUnit", "kN");
  78. base.put("title", "时间: "+dtstr[1]);
  79. base.put("type", "GT");
  80. base.put("upMax", null);
  81. base.put("downMax", null);
  82. base.put("glbMax", sample.getLoadMax());
  83. base.put("glbMin", sample.getLoadMin());
  84. base.put("balance", null);
  85. //base.put("stroke", 3);
  86. base.put("turnIndex", null);
  87. /*
  88. base.put("yFixedMax", wparam.getYaxisMax());
  89. base.put("yFixedMin", wparam.getYaxisMin());
  90. base.put("xFixedMax", wparam.getXaxisMax());
  91. base.put("xFixedMin", wparam.getXaxisMin());*/
  92. String[] descTxt= {"隶属单位:","井名:"+sample.getWellName(),"测试日期:"+dtstr[0],"冲次:"};
  93. Map<String,Object> serial=new HashMap<String,Object>();
  94. List<Float> serials=convert(sample.getDisps());
  95. Float stroke=Collections.max(serials);
  96. base.put("stroke", stroke);
  97. serial.put("xvals", serials);
  98. serial.put("yvals", convert(sample.getLoads()));
  99. serial.put("smpTime", smpTime);
  100. serial.put("dataId", sample.getSampleId());
  101. return MapUtils.build("base",base,"serial",serial,"descTxt",descTxt);
  102. }
  103. private List<Float> convert(String vals){
  104. String[] ary=vals.split(",");
  105. List<Float> datas=new ArrayList<>(ary.length);
  106. for(String d : ary) {
  107. datas.add(Float.parseFloat(d));
  108. }
  109. return datas;
  110. }
  111. /**
  112. * 加载指定诊断标准的样本功图
  113. */
  114. @RequestMapping("/sample/load")
  115. public RespVO<PageModel<DiagramFeatureSample>> load(@NotBlank(message="缺少诊断标准编号") String diagnoseId,
  116. @RequestParam(value = "currentPage", defaultValue = "1") Integer pageNum,
  117. @RequestParam(value = "pageSize", defaultValue = "20") Integer pageSize) {
  118. return RespVOBuilder.ok(sampleService.load(diagnoseId, pageNum, pageSize));
  119. }
  120. /**
  121. * 删除指定单个样本功图
  122. * @param sampleId
  123. * @return
  124. */
  125. @PostMapping("/sample/del")
  126. public RespVO<Object> del(@NotNull(message="缺少样本编号") Integer sampleId){
  127. sampleService.delSample(sampleId);
  128. return RespVOBuilder.ok();
  129. }
  130. /**
  131. * 增加样品功图
  132. * @param sample
  133. * @return
  134. */
  135. @PostMapping("/sample/add")
  136. public RespVO<Object> add(@Valid @RequestBody DiagramSample srcSample){
  137. if(sampleService.exists(srcSample.getWellName(),srcSample.getDiagramTime())) {
  138. return RespVOBuilder.error("该样本已添加过");
  139. }
  140. DiagramFeatureSample sample=FeatureExtractor.extract(srcSample);
  141. sampleService.add(sample);
  142. return RespVOBuilder.ok();
  143. }
  144. /**
  145. * 训练模型
  146. * @param trainParam
  147. * @return
  148. */
  149. @PostMapping("/sample/train")
  150. public RespVO<Object> train(@Valid TrainParam trainParam){
  151. List<DiagramFeatureSample> samples=sampleService.loadSamples();
  152. if(samples==null || samples.size()<5) {
  153. return RespVOBuilder.error("样本数据太少");
  154. }
  155. Map<String,Object> standardMapping=sampleService.loadDiagnoseStandard();
  156. //对样本的类别标签进行编号
  157. List<DiagramFeatureSample> trainSamples=new ArrayList<>();
  158. List<DiagramFeatureSample> validSamples=new ArrayList<>();
  159. int label=0;
  160. for(DiagramFeatureSample smp : samples) {
  161. if(!standardMapping.containsKey(smp.getDiagnoseId())) {
  162. continue;
  163. }
  164. label=((Number)standardMapping.get(smp.getDiagnoseId())).intValue();
  165. smp.setCategoryTag(label);
  166. if(DiagramFeatureSample.TYPE_VALID.equals(smp.getSampleType())) {
  167. validSamples.add(smp);
  168. }
  169. else {
  170. trainSamples.add(smp);
  171. }
  172. }
  173. if(trainSamples.size()==0) {
  174. return RespVOBuilder.error("未找到符合要求的样本数据");
  175. }
  176. //未明确指定验证样本集时,以训练集的前20%作为验证集,其余作为训练集
  177. if(validSamples.size()==0) {
  178. int vcount=(int)(Math.ceil(trainSamples.size()*0.2));
  179. validSamples.addAll(trainSamples.subList(0, vcount));
  180. trainSamples=trainSamples.subList(vcount,trainSamples.size());
  181. }
  182. Hyperparam hyperparam=new Hyperparam();
  183. hyperparam.setNumClass(standardMapping.size());
  184. hyperparam.setEta(trainParam.getEta());
  185. hyperparam.setMaxDepth(trainParam.getMaxDepth());
  186. xgbEngine.train(hyperparam, trainParam.getTrainRound(), XGBoostDataUtil.build(trainSamples, true), XGBoostDataUtil.build(validSamples, true));
  187. //存储训练日志
  188. TrainLog trainLog=new TrainLog(JacksonUtils.getJSON(standardMapping));
  189. sampleService.saveTrainLog(trainLog);
  190. return RespVOBuilder.ok();
  191. }
  192. /**
  193. * 预测样本
  194. * @return
  195. */
  196. @PostMapping("/sample/predict")
  197. public RespVO<Object> predict(){
  198. List<DiagramFeatureSample> testSamples=sampleService.loadSamples("test");
  199. float[][] rst=xgbEngine.predict(XGBoostDataUtil.build(testSamples, false));
  200. return RespVOBuilder.ok(rst);
  201. }
  202. /**
  203. * 单一功图诊断
  204. * @return
  205. */
  206. @PostMapping("/diagram/diagnose")
  207. public RespVO<Object> diagnose(@Valid @RequestBody DiagramSample srcSample){
  208. DiagramFeatureSample sample=FeatureExtractor.extract(srcSample);
  209. float[][] rst=xgbEngine.predict(XGBoostDataUtil.build(Arrays.asList(sample), false));
  210. int clsLabel=(int)rst[0][0];
  211. Map<Integer,DiagnoseStandard> labelStdMapping=sampleService.loadLabelStdMapping();
  212. return RespVOBuilder.ok(labelStdMapping.get(clsLabel));
  213. }
  214. @PostMapping("/sample/predict2")
  215. public RespVO<Object> diagnose2(){
  216. /*
  217. List<DiagramFeatureSample> trainSamples=sampleService.loadSamples("train");
  218. List<DiagramFeatureSample> validSamples=sampleService.loadSamples("valid");
  219. List<DiagramFeatureSample> testSamples=sampleService.loadSamples("test");
  220. float[][] rst=XGBootst.trainAndPredict(3, 20, XGBoostDataUtil.build(trainSamples, true), XGBoostDataUtil.build(validSamples, true), XGBoostDataUtil.build(testSamples, false));
  221. return RespVOBuilder.ok(rst);
  222. */
  223. return RespVOBuilder.ok();
  224. }
  225. }