马氏距离与高斯分布数据

在统计学中,马氏距离是一种衡量单个观测值与数据集分布模式之间距离的方法。对于高斯(正态)分布的数据,可以通过计算观测值的马氏距离来确定其与数据集中心的距离。具体来说,观测值x_i到分布均值\(\mu\)的距离可以通过下面的公式计算:

d_{(\mu,\Sigma)}(x_i)^2 = (x_i - \mu)^T\Sigma^{-1}(x_i - \mu)

其中,\(\mu\)代表数据集的均值向量,\(\Sigma\)是数据集的协方差矩阵。在实际应用中,这些参数通常通过样本数据来估计。然而,传统的最大似然估计(MLE)对于数据集中的异常值非常敏感,这会影响到马氏距离的准确性。因此,使用稳健的协方差估计方法,如最小协方差行列式(MCD)估计器,可以更好地抵抗异常值的影响,从而更准确地反映数据的真实结构。

最小协方差行列式估计器是一种高断裂点的稳健协方差估计方法,它可以用于估计高度污染的数据集的协方差矩阵,即使数据集中存在大量异常值。MCD的核心思想是找到一组观测值,其经验协方差矩阵的行列式最小,从而得到一个“纯净”的观测值子集,进而计算出均值和协方差的稳健估计。MCD估计器由P.J.Rousseuw提出。

通过比较使用MCD和MLE估计器计算的马氏距离,可以发现,当数据集中存在异常值时,基于MLE的马氏距离会受到这些异常值的影响,而基于MCD的马氏距离则能够更好地区分出异常值和正常观测值。这种区分能力在异常值检测、观测值排序和聚类等应用中非常有用。

生成数据

首先,生成一个包含125个样本和2个特征的数据集。这两个特征都是以0为均值的高斯分布,其中第一个特征的标准差为2,第二个特征的标准差为1。然后,将其中的25个样本替换为具有异常值的高斯样本,其中第一个特征的标准差为1,第二个特征的标准差为7。

import numpy as np # 为了结果的一致性 np.random.seed(7) n_samples = 125 n_outliers = 25 n_features = 2 # 生成形状为(125, 2)的高斯数据 gen_cov = np.eye(n_features) gen_cov[0, 0] = 2.0 X = np.dot(np.random.randn(n_samples, n_features), gen_cov) # 添加一些异常值 outliers_cov = np.eye(n_features) outliers_cov[np.arange(1, n_features), np.arange(1, n_features)] = 7.0 X[-n_outliers:] = np.dot(np.random.randn(n_outliers, n_features), outliers_cov)

结果比较

接下来,使用MCD和MLE估计器来拟合数据,并打印出估计的协方差矩阵。注意到,基于MLE的估计器估计的特征2的方差(7.5)比基于MCD的稳健估计器(1.2)高得多。这表明,基于MCD的稳健估计器对异常值样本的抵抗能力更强。

import matplotlib.pyplot as plt from sklearn.covariance import EmpiricalCovariance, MinCovDet # 使用MCD稳健估计器拟合数据 robust_cov = MinCovDet().fit(X) # 使用MLE估计器拟合数据 emp_cov = EmpiricalCovariance().fit(X) print("估计的协方差矩阵:\nMCD (稳健):\n{}\nMLE:\n{}".format(robust_cov.covariance_, emp_cov.covariance_))

为了更直观地展示差异,绘制了由两种方法计算的马氏距离的等高线图。可以注意到,基于MCD的稳健马氏距离更好地拟合了内部黑点,而基于MLE的距离则更多地受到异常值红点的影响。

import matplotlib.lines as mlines fig, ax = plt.subplots(figsize=(10, 5)) # 绘制数据集 inlier_plot = ax.scatter(X[:, 0], X[:, 1], color="black", label="内点") outlier_plot = ax.scatter(X[-n_outliers:, 0], X[-n_outliers:, 1], color="red", label="异常值") ax.set_xlim(ax.get_xlim()[0], 10.0) ax.set_title("污染数据集的马氏距离") # 创建特征1和特征2值的网格 xx, yy = np.meshgrid(np.linspace(plt.xlim()[0], plt.xlim()[1], 100), np.linspace(plt.ylim()[0], plt.ylim()[1], 100)) zz = np.c_[xx.ravel(), yy.ravel()] # 计算基于MLE的马氏距离 mahal_emp_cov = emp_cov.mahalanobis(zz) mahal_emp_cov = mahal_emp_cov.reshape(xx.shape) emp_cov_contour = plt.contour(xx, yy, np.sqrt(mahal_emp_cov), cmap=plt.cm.PuBu_r, linestyles="dashed") # 计算基于MCD的马氏距离 mahal_robust_cov = robust_cov.mahalanobis(zz) mahal_robust_cov = mahal_robust_cov.reshape(xx.shape) robust_contour = ax.contour(xx, yy, np.sqrt(mahal_robust_cov), cmap=plt.cm.YlOrBr_r, linestyles="dotted") # 添加图例 ax.legend([mlines.Line2D([], [], color="tab:blue", linestyle="dashed"), mlines.Line2D([], [], color="tab:orange", linestyle="dotted"), inlier_plot, outlier_plot], ["MLE距离", "MCD距离", "内点", "异常值"], loc="upper right", borderaxespad=0,) plt.show()

最后,强调了基于MCD的马氏距离在区分异常值方面的能力。取马氏距离的立方根,得到近似正态分布(如Wilson和Hilferty所建议),然后使用箱线图绘制内点和异常值样本的值。对于基于MCD的稳健马氏距离,异常值样本的分布与内点样本的分布更加分离。

fig, (ax1, ax2) = plt.subplots(1, 2) plt.subplots_adjust(wspace=0.6) # 计算基于MLE的马氏距离的立方根 emp_mahal = emp_cov.mahalanobis(X - np.mean(X, 0))**(0.33) # 绘制箱线图 ax1.boxplot([emp_mahal[:-n_outliers], emp_mahal[-n_outliers:]], widths=0.25) # 绘制单个样本 ax1.plot(np.full(n_samples-n_outliers, 1.26), emp_mahal[:-n_outliers], "+k", markeredgewidth=1,) ax1.plot(np.full(n_outliers, 2.26), emp_mahal[-n_outliers:], "+k", markeredgewidth=1,) ax1.axes.set_xticklabels(("内点", "异常值"), size=15) ax1.set_ylabel(r"$\sqrt[3]{\rm{(马氏距离)}}$", size=16) ax1.set_title("使用非稳健估计\n(最大似然)") # 计算基于MCD的马氏距离的立方根 robust_mahal = robust_cov.mahalanobis(X - robust_cov.location_)**(0.33) # 绘制箱线图 ax2.boxplot([robust_mahal[:-n_outliers], robust_mahal[-n_outliers:]], widths=0.25) # 绘制单个样本 ax2.plot(np.full(n_samples-n_outliers, 1.26), robust_mahal[:-n_outliers], "+k", markeredgewidth=1,) ax2.plot(np.full(n_outliers, 2.26), robust_mahal[-n_outliers:], "+k", markeredgewidth=1,) ax2.axes.set_xticklabels(("内点", "异常值"), size=15) ax2.set_ylabel(r"$\sqrt[3]{\rm{(马氏距离)}}$", size=16) ax2.set_title("使用稳健估计\n(最小协方差行列式)") plt.show()
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485