Estimação de Densidade por Núcleo 1D Simples

Beginner

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

Introdução

A Estimativa de Densidade Kernel é uma técnica estatística usada para estimar a função de densidade de probabilidade de uma variável aleatória. Neste laboratório, usaremos a biblioteca Python scikit-learn para demonstrar os princípios da Estimativa de Densidade Kernel em uma dimensão.

Dicas da Máquina Virtual

Após o início da VM, clique no canto superior esquerdo para mudar para a aba Notebook para acessar o Jupyter Notebook para praticar.

Às vezes, pode ser necessário aguardar alguns segundos para que o Jupyter Notebook termine de carregar. A validação das operações não pode ser automatizada devido a limitações no Jupyter Notebook.

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

Plotando Histogramas e Núcleos

Primeiro, plotamos histogramas e núcleos para demonstrar a diferença entre os dois. Usaremos uma estimativa de densidade de núcleo gaussiana para mostrar a diferença entre os dois. Também compararemos outros núcleos disponíveis no scikit-learn.

## Importar bibliotecas necessárias
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import norm
from sklearn.neighbors import KernelDensity

## Gerar dados
np.random.seed(1)
N = 20
X = np.concatenate(
    (np.random.normal(0, 1, int(0.3 * N)), np.random.normal(5, 1, int(0.7 * N)))
)[:, np.newaxis]
X_plot = np.linspace(-5, 10, 1000)[:, np.newaxis]
bins = np.linspace(-5, 10, 10)

## Criar figura e eixos
fig, ax = plt.subplots(2, 2, sharex=True, sharey=True)
fig.subplots_adjust(hspace=0.05, wspace=0.05)

## Plotar histograma 1
ax[0, 0].hist(X[:, 0], bins=bins, fc="#AAAAFF", density=True)
ax[0, 0].text(-3.5, 0.31, "Histograma")

## Plotar histograma 2
ax[0, 1].hist(X[:, 0], bins=bins + 0.75, fc="#AAAAFF", density=True)
ax[0, 1].text(-3.5, 0.31, "Histograma, bins deslocados")

## Plotar KDE tophat
kde = KernelDensity(kernel="tophat", bandwidth=0.75).fit(X)
log_dens = kde.score_samples(X_plot)
ax[1, 0].fill(X_plot[:, 0], np.exp(log_dens), fc="#AAAAFF")
ax[1, 0].text(-3.5, 0.31, "Densidade do Núcleo Tophat")

## Plotar KDE gaussiano
kde = KernelDensity(kernel="gaussian", bandwidth=0.75).fit(X)
log_dens = kde.score_samples(X_plot)
ax[1, 1].fill(X_plot[:, 0], np.exp(log_dens), fc="#AAAAFF")
ax[1, 1].text(-3.5, 0.31, "Densidade do Núcleo Gaussiano")

## Plotar pontos de dados
for axi in ax.ravel():
    axi.plot(X[:, 0], np.full(X.shape[0], -0.01), "+k")
    axi.set_xlim(-4, 9)
    axi.set_ylim(-0.02, 0.34)

## Definir rótulo do eixo y para a coluna esquerda
for axi in ax[:, 0]:
    axi.set_ylabel("Densidade Normalizada")

## Definir rótulo do eixo x para a linha inferior
for axi in ax[1, :]:
    axi.set_xlabel("x")

## Mostrar o gráfico
plt.show()

Plotando Núcleos Disponíveis

Plotaremos todos os núcleos disponíveis para mostrar suas formas.

## Gerar dados
X_plot = np.linspace(-6, 6, 1000)[:, None]
X_src = np.zeros((1, 1))

## Criar figura e eixos
fig, ax = plt.subplots(2, 3, sharex=True, sharey=True)
fig.subplots_adjust(left=0.05, right=0.95, hspace=0.05, wspace=0.05)

## Função de formatação para rótulos do eixo x
def format_func(x, loc):
    if x == 0:
        return "0"
    elif x == 1:
        return "h"
    elif x == -1:
        return "-h"
    else:
        return "%ih" % x

## Plotar núcleos disponíveis
for i, kernel in enumerate(
    ["gaussian", "tophat", "epanechnikov", "exponential", "linear", "cosine"]
):
    axi = ax.ravel()[i]
    log_dens = KernelDensity(kernel=kernel).fit(X_src).score_samples(X_plot)
    axi.fill(X_plot[:, 0], np.exp(log_dens), "-k", fc="#AAAAFF")
    axi.text(-2.6, 0.95, kernel)

    axi.xaxis.set_major_formatter(plt.FuncFormatter(format_func))
    axi.xaxis.set_major_locator(plt.MultipleLocator(1))
    axi.yaxis.set_major_locator(plt.NullLocator())

    axi.set_ylim(0, 1.05)
    axi.set_xlim(-2.9, 2.9)

## Definir título para a segunda linha
ax[0, 1].set_title("Núcleos Disponíveis")

## Mostrar o gráfico
plt.show()

Exemplo de Densidade 1D

Plotaremos um exemplo de densidade 1D com 100 amostras em uma dimensão. Compararemos três diferentes estimativas de densidade de núcleo: tophat, gaussiano e epanechnikov.

## Gerar dados
N = 100
np.random.seed(1)
X = np.concatenate(
    (np.random.normal(0, 1, int(0.3 * N)), np.random.normal(5, 1, int(0.7 * N)))
)[:, np.newaxis]

X_plot = np.linspace(-5, 10, 1000)[:, np.newaxis]

true_dens = 0.3 * norm(0, 1).pdf(X_plot[:, 0]) + 0.7 * norm(5, 1).pdf(X_plot[:, 0])

## Criar figura e eixos
fig, ax = plt.subplots()

## Plotar a distribuição de entrada
ax.fill(X_plot[:, 0], true_dens, fc="black", alpha=0.2, label="distribuição de entrada")

## Definir cores e núcleos
cores = ["navy", "cornflowerblue", "darkorange"]
núcleos = ["gaussian", "tophat", "epanechnikov"]
lw = 2

## Plotar estimativas de densidade de núcleo
for cor, núcleo in zip(cores, núcleos):
    kde = KernelDensity(kernel=núcleo, bandwidth=0.5).fit(X)
    log_dens = kde.score_samples(X_plot)
    ax.plot(
        X_plot[:, 0],
        np.exp(log_dens),
        color=cor,
        lw=lw,
        linestyle="-",
        label="núcleo = '{0}'".format(núcleo),
    )

ax.text(6, 0.38, "N={0} pontos".format(N))

## Definir legenda e plotar pontos de dados
ax.legend(loc="upper left")
ax.plot(X[:, 0], -0.005 - 0.01 * np.random.random(X.shape[0]), "+k")

## Definir limites x e y
ax.set_xlim(-4, 9)
ax.set_ylim(-0.02, 0.4)

## Mostrar o gráfico
plt.show()

Resumo

Neste laboratório, aprendemos como usar a biblioteca Python scikit-learn para demonstrar os princípios da Estimativa de Densidade por Núcleo em uma dimensão. Plotamos histogramas e núcleos, núcleos disponíveis e um exemplo de densidade 1D. Também comparamos diferentes estimativas de densidade por núcleo.