Estimação Robusta de Covariância e Distâncias de Mahalanobis: Relevância

Beginner

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

Introdução

Neste laboratório, exploraremos o uso da estimativa robusta de covariância com distâncias de Mahalanobis em dados distribuídos gaussianamente. A distância de Mahalanobis é uma medida da distância entre um ponto e uma distribuição. É definida como a distância entre um ponto e a média da distribuição, escalonada pelo inverso da matriz de covariância da distribuição. Para dados distribuídos gaussianamente, a distância de Mahalanobis pode ser usada para calcular a distância de uma observação à moda da distribuição. Compararemos o desempenho do estimador Minimum Covariance Determinant (MCD), um estimador robusto de covariância, com o estimador padrão de máxima verossimilhança (MLE) de covariância no cálculo das distâncias de Mahalanobis de um conjunto de dados contaminado.

Dicas da Máquina Virtual

Após o término do arranque da VM, clique no canto superior esquerdo para mudar para a aba Notebook para aceder ao Jupyter Notebook para a prática.

Por vezes, pode ser necessário esperar alguns segundos para o Jupyter Notebook terminar de carregar. A validação das operações não pode ser automatizada devido a limitações no Jupyter Notebook.

Se tiver problemas durante o aprendizado, sinta-se à vontade para perguntar ao Labby. Forneça feedback após a sessão e resolveremos prontamente o problema para si.

Gerar Dados

Primeiro, geramos um conjunto de dados com 125 amostras e 2 características. Ambas as características são distribuídas gaussianamente com uma média de 0. No entanto, a característica 1 tem um desvio padrão igual a 2 e a característica 2 tem um desvio padrão igual a 1. Em seguida, substituímos 25 amostras por amostras de valores discrepantes gaussianos onde a característica 1 tem um desvio padrão igual a 1 e a característica 2 tem um desvio padrão igual a 7.

import numpy as np

## para resultados consistentes
np.random.seed(7)

n_samples = 125
n_outliers = 25
n_features = 2

## gerar dados gaussianos de forma (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)
## adicionar alguns valores discrepantes
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)

Ajustar Estimadores de Covariância MCD e MLE aos Dados

Ajustaremos os estimadores de covariância baseados em MCD e MLE aos nossos dados e imprimiremos as matrizes de covariância estimadas. Note que a variância estimada da característica 2 é muito maior com o estimador baseado em MLE (7,5) do que com o estimador robusto MCD (1,2). Isto demonstra que o estimador robusto baseado em MCD é muito mais resistente às amostras de valores discrepantes, que foram concebidas para ter uma variância muito maior na característica 2.

from sklearn.covariance import EmpiricalCovariance, MinCovDet

## ajustar um estimador robusto MCD aos dados
robust_cov = MinCovDet().fit(X)
## ajustar um estimador MLE aos dados
emp_cov = EmpiricalCovariance().fit(X)
print(
    "Matriz de covariância estimada:\nMCD (Robusto):\n{}\nMLE:\n{}".format(
        robust_cov.covariance_, emp_cov.covariance_
    )
)

Plotar Contornos das Distâncias de Mahalanobis

Plotaremos os contornos das distâncias de Mahalanobis calculadas por ambos os métodos. Note-se que as distâncias de Mahalanobis robustas baseadas em MCD ajustam-se muito melhor aos pontos internos pretos, enquanto as distâncias baseadas em MLE são mais influenciadas pelos pontos discrepantes vermelhos.

import matplotlib.pyplot as plt

fig, ax = plt.subplots(figsize=(10, 5))
## Plotar o conjunto de dados
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("Distâncias de Mahalanobis de um conjunto de dados contaminado")

## Criar malha de valores das características 1 e 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()]
## Calcular as distâncias de Mahalanobis baseadas em MLE da malha
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"
)
## Calcular as distâncias de Mahalanobis baseadas em 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"
)

## Adicionar legenda
ax.legend(
    [
        emp_cov_contour.collections[1],
        robust_contour.collections[1],
        inlier_plot,
        outlier_plot,
    ],
    ["Dist MLE", "Dist MCD", "inliers", "outliers"],
    loc="upper right",
    borderaxespad=0,
)

plt.show()

Comparar Distâncias de Mahalanobis MLE e MCD

Destacaremos a capacidade das distâncias de Mahalanobis baseadas em MCD de distinguir valores discrepantes. Tomamos a raiz cúbica das distâncias de Mahalanobis, obtendo distribuições aproximadamente normais. Em seguida, plotamos os valores das amostras internas e externas com diagramas de caixa. A distribuição das amostras externas está mais separada da distribuição das amostras internas para as distâncias de Mahalanobis baseadas em MCD robustas.

fig, (ax1, ax2) = plt.subplots(1, 2)
plt.subplots_adjust(wspace=0.6)

## Calcular a raiz cúbica das distâncias de Mahalanobis MLE para as amostras
emp_mahal = emp_cov.mahalanobis(X - np.mean(X, 0)) ** (0.33)
## Plotar diagramas de caixa
ax1.boxplot([emp_mahal[:-n_outliers], emp_mahal[-n_outliers:]], widths=0.25)
## Plotar amostras individuais
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("Utilizando estimativas não robustas\n(Máxima Verossimilhança)")

## Calcular a raiz cúbica das distâncias de Mahalanobis MCD para as amostras
robust_mahal = robust_cov.mahalanobis(X - robust_cov.location_) ** (0.33)
## Plotar diagramas de caixa
ax2.boxplot([robust_mahal[:-n_outliers], robust_mahal[-n_outliers:]], widths=0.25)
## Plotar amostras individuais
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("Utilizando estimativas robustas\n(Determinante Mínimo de Covariância)")

plt.show()

Resumo

Neste laboratório, aprendemos sobre a estimação robusta de covariância com distâncias de Mahalanobis em dados distribuídos gaussianamente. Comparámos o desempenho dos estimadores de covariância baseados em MCD e MLE no cálculo das distâncias de Mahalanobis de um conjunto de dados contaminado. Observámos que o estimador robusto baseado em MCD é muito mais resistente às amostras discrepantes e que as distâncias de Mahalanobis baseadas em MCD são melhores na distinção de valores discrepantes.