如何基于标准差水平绘制多元正态分布的等高线?
解决方案:基于EllipticEnvelope的多元正态等高线绘制(指定标准差水平)
核心思路
EllipticEnvelope输出的稳健均值和协方差,对应多元正态分布的参数。要绘制1σ、2σ、3σ这类标准差水平的等高线,核心是利用马氏距离平方服从卡方分布的特性:对于d维数据,马氏距离平方$\chi^2 \sim \chi^2(d)$,不同标准差对应的置信水平(1σ→68.27%,2σ→95.45%,3σ→99.73%)对应卡方分布的分位数,以此作为contour的levels参数。
完整代码示例
import numpy as np import matplotlib.pyplot as plt from sklearn.covariance import EllipticEnvelope from scipy.stats import chi2 from scipy.spatial.distance import cdist # 替换为你的真实数据集 np.random.seed(42) n_samples = 200 X = np.random.multivariate_normal(mean=[2, 3], cov=[[1, 0.5], [0.5, 2]], size=n_samples) X[::20] = np.random.uniform(low=-1, high=6, size=(10, 2)) # 模拟异常值 # 拟合EllipticEnvelope获取稳健均值和协方差 ee = EllipticEnvelope(contamination=0.05) # 根据异常值比例调整 ee.fit(X) mean_robust = ee.location_ cov_robust = ee.covariance_ inv_cov = np.linalg.inv(cov_robust) # 生成绘图网格 x_min, x_max = X[:, 0].min()-1, X[:, 0].max()+1 y_min, y_max = X[:, 1].min()-1, X[:, 1].max()+1 xx, yy = np.meshgrid(np.linspace(x_min, x_max, 100), np.linspace(y_min, y_max, 100)) grid_points = np.c_[xx.ravel(), yy.ravel()] # 计算马氏距离平方(高效版) mahalanobis_sq = cdist(grid_points, [mean_robust], metric='mahalanobis', VI=inv_cov)[:, 0] ** 2 mahalanobis_sq = mahalanobis_sq.reshape(xx.shape) # 设定不同σ对应的levels df = X.shape[1] # 特征维度 confidence_levels = [0.6827, 0.9545, 0.9973] # 对应1σ、2σ、3σ levels = chi2.ppf(confidence_levels, df=df) # 绘图 plt.figure(figsize=(8, 6)) contour = plt.contour(xx, yy, mahalanobis_sq, levels=levels, colors=['#1f77b4', '#ff7f0e', '#d62728'], linewidths=1.5) plt.clabel(contour, inline=True, fontsize=10, fmt={l: f'{int(np.sqrt(l))}σ' for l in levels}) plt.scatter(X[:,0], X[:,1], c='gray', alpha=0.6, label='原始数据') plt.scatter(mean_robust[0], mean_robust[1], c='black', marker='x', s=100, label='稳健均值') plt.xlabel('特征1') plt.ylabel('特征2') plt.title('稳健多元正态等高线(1σ/2σ/3σ)') plt.legend() plt.grid(alpha=0.3) plt.show()
关键细节说明
- EllipticEnvelope参数:
contamination需匹配数据中异常值的大致比例,默认0.1,设置合理才能得到准确的稳健估计。 - 马氏距离计算:用
scipy.spatial.distance.cdist比循环更高效,适合大数据集。 - levels对应关系:如果需要自定义σ水平,只需调整
confidence_levels——比如要画1.5σ,先查对应置信水平(约86.64%),再传入chi2.ppf计算分位数。
内容的提问来源于stack exchange,提问作者8Simon8
相关产品推荐
相关产品推荐

