강력한 공분산 추정 및 마할라노비스 거리의 중요성

Beginner

This tutorial is from open-source community. Access the source code

소개

이 실습에서는 가우시안 분포 데이터에 대한 멀하나비스 거리 (Mahalanobis distance) 를 사용한 강력한 공분산 추정을 탐색합니다. 멀하나비스 거리는 점과 분포 사이의 거리를 측정하는 지표입니다. 분포의 평균과 점 사이의 거리에 분포의 공분산 행렬의 역행렬을 곱하여 척도화한 값으로 정의됩니다. 가우시안 분포 데이터의 경우, 멀하나비스 거리는 관측치와 분포의 최빈값 (mode) 사이의 거리를 계산하는 데 사용될 수 있습니다. 이 실습에서는 오염된 데이터 집합의 멀하나비스 거리를 계산하는 데 있어, 강력한 공분산 추정량인 최소 공분산 행렬 (MCD) 추정량과 표준 공분산 최대 가능도 추정량 (MLE) 의 성능을 비교합니다.

VM 팁

VM 시작이 완료되면 왼쪽 상단 모서리를 클릭하여 Notebook 탭으로 전환하여 연습을 위한 Jupyter Notebook에 접근합니다.

때때로 Jupyter Notebook 이 완전히 로드되기까지 몇 초 정도 기다려야 할 수 있습니다. Jupyter Notebook 의 제한으로 인해 작업의 유효성 검사를 자동화할 수 없습니다.

학습 중 문제가 발생하면 Labby 에게 문의하십시오. 세션 후 피드백을 제공하면 문제를 신속하게 해결해 드리겠습니다.

데이터 생성

먼저, 125 개의 샘플과 2 개의 특징을 가진 데이터 집합을 생성합니다. 두 특징 모두 평균이 0 인 가우시안 분포를 따릅니다. 그러나 특징 1 의 표준 편차는 2 이고, 특징 2 의 표준 편차는 1 입니다. 다음으로, 특징 1 의 표준 편차가 1 이고 특징 2 의 표준 편차가 7 인 가우시안 이상치 샘플로 25 개의 샘플을 대체합니다.

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 공분산 추정기를 데이터에 적용

MCD 및 MLE 기반 공분산 추정기를 데이터에 적용하고 추정된 공분산 행렬을 출력합니다. MLE 기반 추정기의 특징 2 의 추정된 분산 (7.5) 은 MCD 강력 추정기 (1.2) 보다 훨씬 높습니다. 이는 MCD 기반 강력 추정기가 특징 2 에서 훨씬 큰 분산을 갖도록 설계된 이상치 샘플에 훨씬 더 강건하다는 것을 보여줍니다.

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.pyplot as plt

fig, ax = plt.subplots(figsize=(10, 5))
## 데이터 집합 플롯
inlier_plot = ax.scatter(X[:, 0], X[:, 1], color="black", label="inliers")
outlier_plot = ax.scatter(
    X[:, 0][-n_outliers:], X[:, 1][-n_outliers:], color="red", label="outliers"
)
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(
    [
        emp_cov_contour.collections[1],
        robust_contour.collections[1],
        inlier_plot,
        outlier_plot,
    ],
    ["MLE 거리", "MCD 거리", "내부 점", "이상치"],
    loc="upper right",
    borderaxespad=0,
)

plt.show()

MLE 및 MCD 마할라노비스 거리 비교

이상치를 구분하는 MCD 기반 마할라노비스 거리의 능력을 강조합니다. 마할라노비스 거리의 세제곱근을 취하여 대략 정규 분포를 얻습니다. 그런 다음, 상자 그림으로 내부 및 외부 샘플의 값을 플롯합니다. 강력한 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(("inliers", "outliers"), size=15)
ax1.set_ylabel(r"$\sqrt[3]{\rm{(Mahal. dist.)}}$", 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(("inliers", "outliers"), size=15)
ax2.set_ylabel(r"$\sqrt[3]{\rm{(Mahal. dist.)}}$", size=16)
ax2.set_title("강력 추정 사용\n(최소 공분산 행렬)")

plt.show()

요약

이 실험에서 우리는 가우시안 분포 데이터에 대한 마할라노비스 거리로 강력한 공분산 추정에 대해 배웠습니다. 오염된 데이터 집합의 마할라노비스 거리를 계산하는 데 사용되는 MCD 및 MLE 기반 공분산 추정기의 성능을 비교했습니다. MCD 기반 강력 추정기가 이상치 샘플에 훨씬 더 강건하며 MCD 기반 마할라노비스 거리가 이상치를 더 잘 구분한다는 것을 관찰했습니다.