我想检测离群值(与平均值的标准偏差大于20倍),但我不想让3个以上的离群值影响平均值。我想到了这个:
SELECT d.* FROM
(
SELECT
d.*,
(amount - avg(amount_excl_3z) OVER(PARTITION BY productid)) / NULLIF(STDEV(amount_excl_3z) OVER(PARTITION BY productid), 0) AS zscore_ex
FROM
(
SELECT
d.*,
--when the amount zscore is 3x, null the amount else provide
CASE WHEN ABS(amount - avg(amount) OVER(PARTITION BY productid)) / NULLIF(STDEV(amount) OVER(PARTITION BY productid), 0) > 3
THEN NULL ELSE amount END AS amount_excl_3z
FROM sales d
WHERE --the past year's sales of product 1, but one day I will consider all prods hence why i left the partitions in
timestamp > GETUTCDATE()-365.0 AND
productid = 1
) d
) d
WHERE e.zscore_ex > 20
ORDER BY amount desc
数据担心的是,如果出现太多异常值,它们将严重影响平均值-可能有1000次出现的产品数量为1,然后出现了5次的产品数量为20,000。 '不想让20,000个影响平均值。.我真的不希望50次出现20,000个影响平均值。.但是,如果出现500次,那可以/代表一个新的规范。
我正在考虑这样做的方法是剔除少量出现的巨大异常值。如果它们开始出现的频率足够高,以至于它们足以影响平均值以进入范围,那么我将开始将它们包括在内。
上面的查询是我的最佳选择:“异常检测试图将少量野生异常值排除在影响范围之外”-SQL Server中是否有其他工具可以更有效地利用该算法?也许某些分析查询可以指示点在分布曲线上的位置?我查看了PERCENT_RANK,CUME_DIST,PERCENTILE_CONT / DISC,NTILE,但它们的输出分布似乎比zscore更线性。