threshold.js 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. // 阈值管理与异常识别
  2. class ThresholdManager {
  3. constructor() {
  4. this.normalCycles = [];
  5. this.stageThresholds = [];
  6. }
  7. // 收集一轮正常周期数据
  8. addNormalCycle(cycle, stageDurations) {
  9. this.normalCycles.push({ cycle, stageDurations });
  10. // 只保留最近10轮
  11. if (this.normalCycles.length > 10) this.normalCycles.shift();
  12. this._recalculateThresholds();
  13. }
  14. // 重新计算每阶段的上下阈值(均值±3倍标准差)
  15. _recalculateThresholds() {
  16. if (this.normalCycles.length === 0) return;
  17. // 以最新一轮的阶段分布为准
  18. const { stageDurations } = this.normalCycles[this.normalCycles.length - 1];
  19. const stageCount = stageDurations.length;
  20. this.stageThresholds = [];
  21. for (let s = 0, idx = 0; s < stageCount; s++) {
  22. let values = [];
  23. for (const { cycle, stageDurations: sd } of this.normalCycles) {
  24. // 兼容不同轮阶段长度
  25. let start = sd.slice(0, s).reduce((a, b) => a + b, 0);
  26. let end = start + sd[s];
  27. values = values.concat(cycle.slice(start, end));
  28. }
  29. const mean = values.reduce((a, b) => a + b, 0) / values.length;
  30. const std = Math.sqrt(values.reduce((a, b) => a + (b - mean) ** 2, 0) / values.length);
  31. this.stageThresholds.push({ lower: mean - 3 * std, upper: mean + 3 * std });
  32. }
  33. }
  34. // 根据当前index判断属于哪个阶段
  35. getStageByIndex(index, stageDurations) {
  36. let sum = 0;
  37. for (let i = 0; i < stageDurations.length; i++) {
  38. sum += stageDurations[i];
  39. if (index < sum) return i;
  40. }
  41. return stageDurations.length - 1;
  42. }
  43. // 判断异常
  44. checkAbnormal(value, index, stageDurations) {
  45. const stage = this.getStageByIndex(index, stageDurations);
  46. if (!this.stageThresholds[stage]) return { isAbnormal: false, lower: null, upper: null };
  47. const { lower, upper } = this.stageThresholds[stage];
  48. return {
  49. isAbnormal: value < lower || value > upper,
  50. lower,
  51. upper
  52. };
  53. }
  54. }
  55. module.exports = { ThresholdManager };