ML.NET DetectSpikeBySsa预测异常,如何解决误报问题?
问题
我正在使用ML.NET检测带对应日期的数值列表中的峰值。据我理解,预测输出包含以下内容:
0.0, (是否为峰值?) 5.23, (得分 = 实际值 - 预测值) 0.20028081299669430182, (P值)
大多数时候峰值检测效果良好,但很多情况下会得到错误的预测,仿佛输入数据完全不同。例如,当输入值为"2"时,得到如下预测结果:
1.0, 11.739639282226563, (这显然不合理,因为得分远大于输入值本身!) 0.00028081299669430182
相关代码如下:
MLContext machineLearningContext = new(); IDataView dataView = machineLearningContext.Data.LoadFromEnumerable(aggregationEvents); string inputColumnName = nameof(EventsData.Value); string outputColumnName = nameof(EventsPrediction.Prediction); IDataView transformedData = machineLearningContext.Transforms .DetectSpikeBySsa(outputColumnName, inputColumnName, confidence: aggregationDefinition.MinimumConfidenceForAnomalyDetection, trainingWindowSize: aggregationDefinition.TrainingWindowSizeForAnomalyDetection, seasonalityWindowSize: 30, pvalueHistoryLength: 30) .Fit(dataView).Transform(dataView); List<EventsPrediction> predictions = machineLearningContext.Data.CreateEnumerable<EventsPrediction>(transformedData, reuseRowObject: false).ToList();
对应的类定义:
public class EventsData { [LoadColumn(0)] public DateTime FromTime { get; set; } [LoadColumn(1)] public float Value { get; set; } } public class EventsPrediction { [VectorType(2)] public double[] Prediction { get; set; } }
这些错误预测导致大量峰值误报,请问哪里操作出错了?
问题排查与解决建议
VectorType定义错误:EventsPrediction的Prediction属性标注了[VectorType(2)],但DetectSpikeBySsa的输出是长度为3的向量(对应是否异常、得分、P值三个结果),向量长度不匹配会引发解析错误,直接导致预测值混乱。将[VectorType(2)]修改为[VectorType(3)]即可。- 时序数据未按时间排序:
DetectSpikeBySsa是时序异常检测算法,要求输入数据必须严格按时间升序排列。如果aggregationEvents列表未按FromTime排序,算法会基于错误的时序窗口训练和预测,生成完全不符的结果。加载数据前务必执行排序:aggregationEvents = aggregationEvents.OrderBy(x => x.FromTime).ToList(); - 算法参数配置不合理:
seasonalityWindowSize设为30,需确认数据是否存在周期为30的规律。若数据无明显周期,该值过大将导致模型无法正确学习正常模式,建议根据数据实际周期调整,或尝试缩小该值。trainingWindowSize若过小,模型无法积累足够正常样本;若过大,会引入过时模式。建议设置为数据总长度的1/3到1/2(确保覆盖至少几个完整周期)。
- 缺失数据预处理:若输入数据存在极端异常值,未做清洗就用于训练,会导致模型学习错误的基准线。可先对数据做清洗,比如移除超出3σ范围的孤立点,或用移动中位数填充异常值。
内容的提问来源于stack exchange,提问作者Reginiano
相关产品推荐
相关产品推荐

