단순 1 차원 커널 밀도 추정

Beginner

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

소개

커널 밀도 추정 (Kernel Density Estimation) 은 확률 변수의 확률 밀도 함수를 추정하는 통계적 기법입니다. 이 실습에서는 scikit-learn 파이썬 라이브러리를 사용하여 1 차원에서 커널 밀도 추정의 원리를 보여줍니다.

VM 팁

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

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

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

히스토그램 및 커널 플롯

먼저 히스토그램과 커널을 플롯하여 두 가지 간의 차이점을 보여줍니다. 가우시안 커널 밀도 추정을 사용하여 두 가지 간의 차이점을 보여주고, scikit-learn 에서 사용 가능한 다른 커널들도 비교합니다.

## 필요한 라이브러리 가져오기
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import norm
from sklearn.neighbors import KernelDensity

## 데이터 생성
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)

## 그림 및 축 생성
fig, ax = plt.subplots(2, 2, sharex=True, sharey=True)
fig.subplots_adjust(hspace=0.05, wspace=0.05)

## 히스토그램 1 플롯
ax[0, 0].hist(X[:, 0], bins=bins, fc="#AAAAFF", density=True)
ax[0, 0].text(-3.5, 0.31, "히스토그램")

## 히스토그램 2 플롯
ax[0, 1].hist(X[:, 0], bins=bins + 0.75, fc="#AAAAFF", density=True)
ax[0, 1].text(-3.5, 0.31, "이동된 구간의 히스토그램")

## 톱햇 KDE 플롯
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, "톱햇 커널 밀도")

## 가우시안 KDE 플롯
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, "가우시안 커널 밀도")

## 데이터 포인트 플롯
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)

## 왼쪽 열의 y 축 레이블 설정
for axi in ax[:, 0]:
    axi.set_ylabel("정규화된 밀도")

## 아래 행의 x 축 레이블 설정
for axi in ax[1, :]:
    axi.set_xlabel("x")

## 플롯 표시
plt.show()

사용 가능한 커널 플롯

모든 사용 가능한 커널의 모양을 보여주는 플롯을 생성합니다.

## 데이터 생성
X_plot = np.linspace(-6, 6, 1000)[:, None]
X_src = np.zeros((1, 1))

## 그림 및 축 생성
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)

## 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

## 사용 가능한 커널 플롯
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)

## 두 번째 행의 제목 설정
ax[0, 1].set_title("사용 가능한 커널")

## 플롯 표시
plt.show()

1 차원 밀도 예시 플롯

1 차원 공간에 100 개의 샘플을 사용하여 1 차원 밀도 예시를 플롯합니다. 톱햇, 가우시안, 에파네치니코프 세 가지 다른 커널 밀도 추정을 비교합니다.

## 데이터 생성
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])

## 그림 및 축 생성
fig, ax = plt.subplots()

## 입력 분포 플롯
ax.fill(X_plot[:, 0], true_dens, fc="black", alpha=0.2, label="입력 분포")

## 색상 및 커널 설정
colors = ["navy", "cornflowerblue", "darkorange"]
kernels = ["gaussian", "tophat", "epanechnikov"]
lw = 2

## 커널 밀도 추정 플롯
for color, kernel in zip(colors, kernels):
    kde = KernelDensity(kernel=kernel, bandwidth=0.5).fit(X)
    log_dens = kde.score_samples(X_plot)
    ax.plot(
        X_plot[:, 0],
        np.exp(log_dens),
        color=color,
        lw=lw,
        linestyle="-",
        label="커널 = '{0}'".format(kernel),
    )

ax.text(6, 0.38, "N={0}개의 점".format(N))

## 범례 및 데이터 포인트 플롯
ax.legend(loc="upper left")
ax.plot(X[:, 0], -0.005 - 0.01 * np.random.random(X.shape[0]), "+k")

## x 및 y 축 범위 설정
ax.set_xlim(-4, 9)
ax.set_ylim(-0.02, 0.4)

## 플롯 표시
plt.show()

요약

이 실험에서 우리는 scikit-learn 파이썬 라이브러리를 사용하여 1 차원에서 커널 밀도 추정의 원리를 보여주는 방법을 배웠습니다. 히스토그램과 커널, 사용 가능한 커널, 그리고 1 차원 밀도 예시를 플롯하고, 서로 다른 커널 밀도 추정을 비교했습니다.