北京網(wǎng)站案例谷歌廣告投放
問題
在項(xiàng)目中,需要對異常值進(jìn)行剔除,需要一種魯棒性比較好的方法,總結(jié)了一個實(shí)踐方法。
方法
基于中位數(shù)和MAD(中位數(shù)絕對偏差)的魯棒平均值計(jì)算算法的詳細(xì)過程,按照您要求的步驟分解:
算法過程
過程:
-
- 先使用中位數(shù)作為初始估計(jì)
-
- 計(jì)算MAD作為離散度度量
-
- 排除偏離中位數(shù)超過3倍MAD的數(shù)據(jù)點(diǎn)
-
- 對剩余數(shù)據(jù)計(jì)算平均值
輸入:
- 數(shù)據(jù)集
data = [x?, x?, ..., x?]
(可能包含異常值) - 異常值閾值
k
(默認(rèn)k=3
)
輸出:
- 魯棒平均值
robust_mean
- 被排除的異常值索引列表
outliers
步驟 1:計(jì)算中位數(shù)(初始估計(jì))
中位數(shù)對異常值不敏感,是數(shù)據(jù)中心的魯棒估計(jì)。
median = np.median(data) # 中位數(shù)
例子:
data = [10, 12, 11, 15, 10, 9, 11, 10, 100, 8, 9, 10, 12, -50]
排序后:[-50, 8, 9, 9, 10, 10, 10, 10, 11, 11, 12, 12, 15, 100]
中位數(shù) median = 10
(第7和第8個值的平均)
步驟 2:計(jì)算MAD(離散度度量)
MAD(Median Absolute Deviation)是數(shù)據(jù)與中位數(shù)絕對偏差的中位數(shù),對異常值魯棒。
deviations = np.abs(data - median) # 各點(diǎn)與中位數(shù)的絕對偏差
mad = np.median(deviations) # MAD
mad = mad * 1.4826 # 調(diào)整因子(使MAD≈標(biāo)準(zhǔn)差)
調(diào)整因子解釋:
- 對于正態(tài)分布,標(biāo)準(zhǔn)差
σ ≈ 1.4826 × MAD
。 - 調(diào)整后,
k=3
對應(yīng)正態(tài)分布的3σ準(zhǔn)則(覆蓋99.7%數(shù)據(jù))。
例子:
絕對偏差 deviations = [60, 2, 1, 5, 0, 1, 1, 0, 90, 2, 1, 0, 2, 40]
排序后:[0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 5, 40, 60, 90]
MAD = 1(中位數(shù))
調(diào)整后 mad = 1.4826
步驟 3:排除異常值(3×MAD準(zhǔn)則)
標(biāo)記所有滿足 |x? - median| > k × mad
的點(diǎn)為異常值。
outlier_mask = deviations > (k * mad) # 異常值掩碼
clean_data = data[~outlier_mask] # 清洗后的數(shù)據(jù)
例子(k=3
):
閾值 3 × 1.4826 ≈ 4.45
異常值條件:|x? - 10| > 4.45
100
:|100 - 10| = 90 > 4.45
→ 異常-50
:|-50 - 10| = 60 > 4.45
→ 異常
其他點(diǎn)均保留。
步驟 4:計(jì)算剩余數(shù)據(jù)的平均值
對清洗后的數(shù)據(jù)求算術(shù)平均。
robust_mean = np.mean(clean_data)
例子:
清洗后數(shù)據(jù):[10, 12, 11, 15, 10, 9, 11, 10, 8, 9, 10, 12]
魯棒平均值 robust_mean = 10.5
完整代碼實(shí)現(xiàn)
import numpy as npdef robust_mean(data, k=3):data = np.asarray(data)median = np.median(data)# 計(jì)算MAD并調(diào)整deviations = np.abs(data - median)mad = np.median(deviations) * 1.4826# 處理MAD為0的情況(所有數(shù)據(jù)相同)if mad == 0:return median, np.array([])# 標(biāo)記并排除異常值outlier_mask = deviations > (k * mad)clean_data = data[~outlier_mask]return np.mean(clean_data), np.where(outlier_mask)[0]# 示例
data = [10, 12, 11, 15, 10, 9, 11, 10, 100, 8, 9, 10, 12, -50]
mean, outliers = robust_mean(data)
print(f"魯棒平均值: {mean}, 異常值索引: {outliers}")
算法優(yōu)點(diǎn)
- 魯棒性:中位數(shù)和MAD均不受極端值影響。
- 自動閾值:
k=3
對應(yīng)正態(tài)分布的3σ準(zhǔn)則,可調(diào)整(如嚴(yán)格檢測用k=2.5
)。 - 適用性:適合傳感器數(shù)據(jù)(如雞秤)、金融數(shù)據(jù)等含離群點(diǎn)的場景。
可視化
數(shù)據(jù)分布: [-50, 8, 9, 9, 10, 10, 10, 10, 11, 11, 12, 12, 15, 100]↑______中位數(shù)=10______↑ ↑異常值(-50) 異常值(100)