看起来您的异常检测算法在处理不同输入测试用例时,由于数据分布的变化,导致无法使用统一的阈值进行有效判断。为了解决这个问题,可以考虑以下几种改进方法:
- 动态阈值:根据数据的统计特性动态调整阈值,而不是使用固定的阈值。
- 自适应方法:使用滑动窗口或自适应算法,根据最近的数据调整检测标准。
- 多指标融合:综合多个指标的统计特性,确定更为稳健的异常判定标准。
以下是针对您的 detectAnomaly
函数的具体修改建议和代码示例。
1. 动态阈值调整
将阈值根据数据的均值和标准差动态计算,而不是依赖于固定的阈值。这可以提高算法对不同数据分布的适应性。
func (d *TimeSeriesAnomalyDetector) detectAnomaly(newValue float64, recentValues []DataPoint, previousValue float64, windowSize int, impulseFactorParams ImpulseFactorParams, crestFactorParams CrestFactorParams, changeRateParams ChangeRateParams, rmsParams RMSParams, shapeFactorParams ShapeFactorParams) (bool, string, map[string]float64) {
metrics := make(map[string]float64)
reasons := make([]string, 0)
window := getWindowValues(recentValues, windowSize)
// 计算各项指标
metrics["ImpulseFactor"] = d.calculateImpulseFactor(window)
metrics["CrestFactor"] = d.calculateCrestFactor(window)
metrics["ChangeRate"] = d.calculateChangeRate(newValue, previousValue)
metrics["RMS"] = d.calculateRMS(window)
metrics["ShapeFactor"] = d.calculateShapeFactor(window)
// 动态计算阈值
dynamicThresholds := d.calculateDynamicThresholds()
// 判断各项指标是否超过动态阈值
if metrics["ImpulseFactor"] > dynamicThresholds["ImpulseFactor"] {
reasons = append(reasons, fmt.Sprintf("脉冲因子: %.3f > %.3f", metrics["ImpulseFactor"], dynamicThresholds["ImpulseFactor"]))
}
if metrics["CrestFactor"] > dynamicThresholds["CrestFactor"] {
reasons = append(reasons, fmt.Sprintf("峰值因子: %.3f > %.3f", metrics["CrestFactor"], dynamicThresholds["CrestFactor"]))
}
if metrics["ChangeRate"] > dynamicThresholds["ChangeRate"] {
reasons = append(reasons, fmt.Sprintf("变化率: %.3f > %.3f", metrics["ChangeRate"], dynamicThresholds["ChangeRat