본문으로 바로가기

커널 밀도 추정: 이론에서 실전까지

커널 밀도 추정은 고정된 모델을 가정하지 않고 데이터 분포의 형태를 추정하는 비모수 방법입니다. 공식, 대역폭 선택, Python과 R에서의 실습 구현을 알아보세요.
업데이트됨 2026년 6월 16일  · 11분 읽다

AI로 탐색하기

ChatGPT에서 열기Claude에서 열기Perplexity에서 열기

분포를 시각화하려다, 구간 개수만 바꿨는데 히스토그램 모양이 매번 달라진 경험이 있나요?

흔히 이렇게 진행됩니다. 구간을 10개로 두면 곡선이 매끈해 보입니다. 30개로 바꾸면 봉우리가 여러 개 생깁니다. 데이터는 그대로인데, 구간 개수에 따라 해석이 달라집니다. 이것이 히스토그램의 가장 큰 문제입니다. 분포 자체를 보여주는 것이 아니라, 그중 한 가지 버전만 보여줍니다. 그리고 그 버전은 임의로 지정한 매개변수의 영향을 받습니다.

KDE는 다른 방식을 취합니다. 데이터를 구간으로 나누는 대신, 각 데이터 포인트에 작은 매끄러운 곡선을 얹고 이를 모두 합칩니다. 이렇게 하면 배후 분포에 대한 하나의 연속적인 추정치를 얻을 수 있습니다.

이 글에서는 KDE의 직관, 공식 풀이, 대역폭이 매끄러움에 미치는 영향, 그리고 Python과 R의 실용 예제를 다룹니다.

히스토그램이 처음이신가요? 시작에 도움이 되는 도수 히스토그램 종합 가이드를 확인하세요.

커널 밀도 추정이란?

커널 밀도 추정은 데이터셋의 확률 밀도 함수를 추정하는 비모수 방법입니다.

비모수라는 점이 차별점입니다.

모수적 방법은 데이터가 특정 분포(정규, 지수 등)를 따른다고 가정하고, 그에 맞추어 모수를 적합합니다. 가정이 틀리면 모델도 틀립니다. KDE는 그런 가정을 하지 않습니다. 데이터가 스스로 이야기하도록 두고, 관측치로부터 직접 분포를 추정합니다.

출력은 값이 어디에 얼마나 분포하는지를 보여주는 매끄러운 곡선입니다. 곡선의 높은 지점은 밀도가 높은 구간, 낮은 지점은 드문 구간을 의미합니다.

왜 커널 밀도 추정을 사용할까요?

히스토그램은 분포 시각화의 기본 도구지만 문제점이 있습니다. 보이는 모양이 선택한 구간 개수에 따라 달라집니다. 그리고 그 구간 개수는 사용자가 임의로 정합니다. 같은 데이터셋을 보고도 서로 다른 구간 수를 고르면 완전히 다른 결론을 내릴 수 있습니다.

KDE는 데이터를 구간에 밀어 넣지 않고, 임의의 매개변수에 좌우되지 않는 매끄럽고 연속적인 곡선을 생성합니다.

그 덕분에 다음과 같은 데 유용합니다:

  • 구간 크기 편향 없이 분포의 전반적 형태 시각화
  • 다봉성, 비대칭, 두터운 꼬리 등 패턴 감지
  • 같은 도표에서 그룹 간 분포 비교
  • 모델링 전에 데이터를 더 깔끔하게 파악

KDE의 직관

각 데이터 포인트마다 작고 매끄러운 곡선을 하나 얹습니다. 이 곡선을 커널이라고 합니다. 그런 다음 이 개별 곡선들을 모두 합칩니다.

결과적으로 데이터의 밀도를 보여주는 하나의 매끄러운 곡선을 얻게 됩니다. 포인트들이 모여 있는 곳에서는 커널이 겹쳐 쌓이며 곡선이 상승합니다. 데이터가 드문 곳에서는 커널이 거의 겹치지 않아 곡선이 낮게 유지됩니다. 모든 포인트가 최종 추정에 동일하게 기여합니다.

예를 들어 한 반의 기말고사 점수를 기록했다고 상상해 보세요. 히스토그램으로 구간을 나누는 대신, KDE는 각 점수에 작은 매끄러운 곡선을 배치합니다. 점수가 몰린 70~75점대에서는 곡선이 겹쳐 추정치가 상승합니다. 95점을 받은 학생 한 명은 꼬리 부분에 작은 봉우리만 더합니다.

아래 시각화가 정확히 이를 보여줍니다. 대부분의 학생은 평균 부근에 분포했고, 한 학생은 훨씬 높은 점수를 받았습니다:

KDE visualized

KDE 시각화

커널 밀도 추정 공식

KDE 공식은 겉보기보다 덜 어렵습니다.

KDE 공식

각 기호의 의미는 다음과 같습니다:

  • n 은 데이터 포인트의 개수입니다

  • x_i 는 데이터셋의 개별 데이터 포인트입니다

  • K 는 커널 함수로, 각 포인트에 얹는 매끄러운 곡선입니다

  • h 는 대역폭으로, 각 커널의 너비를 제어합니다

  • x 는 밀도를 평가하는 지점입니다

쉽게 말해, 공식은 다음을 뜻합니다. 임의의 점 x 에 대해 모든 데이터 포인트 x_i 가 그 점에 얼마나 가까운지 살펴보고, 그 가까움을 커널 함수 K 로 가중한 뒤, 모든 n 개의 포인트에 대해 평균을 냅니다. 이 작업을 범위 전반의 모든 x 에 대해 수행하면 전체 밀도 곡선을 얻습니다.

대역폭 hK 내부 분수의 분모에 있습니다. h 가 작을수록 커널이 좁아져 아주 가까운 점들만 추정에 영향을 줍니다. h 가 클수록 영향이 넓게 퍼집니다. 이에 대해서는 글의 뒷부분에서 더 다룹니다.

커널 함수란?

커널은 각 데이터 포인트에 얹는 매끄러운 곡선입니다. 해당 포인트의 영향이 이웃으로 어떻게 퍼지는지를 정의합니다.

모든 커널은 데이터 포인트를 중심으로 하며, 거리에 따라 가중치를 부여합니다. 중심에 가까운 점은 높은 가중치를, 먼 점은 낮은 가중치 또는 0을 받습니다. 그 가중치 모양은 선택한 커널에 따라 달라집니다.

일반적인 선택지는 세 가지입니다:

  • 가우시안: 종(bell) 모양 곡선입니다. 데이터셋의 모든 점에 가중치를 부여하며, 거리가 멀어질수록 영향이 감소합니다. 대부분의 라이브러리에서 기본값이며 실무에서 잘 작동합니다.
  • 균일: 납작한 직사각형입니다. 일정 거리 이내의 모든 점에 동일한 가중치를 주고, 그 밖은 0입니다. 단순하지만 덜 매끄러운 추정치를 만듭니다.
  • Epanechnikov: 평균제곱오차 면에서 수학적으로 최적에 가까운 포물선형 모양입니다. 가우시안보다 효율적이지만, 실무에서는 눈에 띄는 차이를 내는 경우가 드뭅니다.

대부분의 경우 커널 선택은 큰 차이를 만들지 않습니다. 같은 대역폭으로 두 커널을 같은 데이터에 적용하면 거의 동일한 곡선을 얻게 됩니다. 훨씬 더 중요한 것은 대역폭이며, 다음에서 살펴보겠습니다.

KDE에서 대역폭의 역할

대역폭은 KDE 결과에 가장 큰 영향을 주는 단일 매개변수로, 커널 선택보다도 중요합니다.

대역폭은 각 커널의 너비를 제어합니다. 좁은 커널은 주변의 가까운 점들만 끌어들이고, 넓은 커널은 훨씬 넓은 범위로 영향을 퍼뜨립니다. 결과적으로 데이터에 촘촘히 반응하는 곡선 또는 데이터를 부드럽게 덮는 곡선이 나옵니다.

작은 대역폭

대역폭이 작으면 각 커널이 타이트하고 좁아집니다. 추정치는 모든 데이터 포인트에 예민하게 반응해 데이터의 실제 구조를 잡아내지만, 노이즈도 함께 포착합니다.

실무에서는 작은 봉우리가 많은 들쭉날쭉한 곡선처럼 보입니다. 그중 일부는 실제 클러스터를 나타내지만, 일부는 과소평활화로 인한 인공 산물일 뿐입니다. 어떤 것이 어느 쪽인지 구분하기 어렵다는 점이 문제입니다.

KDE with small bandwidth

작은 대역폭의 KDE

큰 대역폭

대역폭이 크면 각 커널이 넓게 퍼집니다. 이웃한 커널들이 겹치며 최종 곡선은 매끄럽게 나옵니다.

너무 매끄러워지면 실제 구조를 잃기 시작합니다. 구분되는 두 클러스터가 하나의 곡선으로 뭉개질 수 있습니다. 두터운 꼬리를 가진 분포가 대칭적으로 보일 수도 있습니다. 시각화가 중요한 정보를 숨길 수 있습니다.

KDE with large bandwidth

큰 대역폭의 KDE

적절한 대역폭 찾기

보편적으로 정답인 대역폭은 없습니다. 노이즈는 걸러내되 실제 패턴은 지우지 않을 만큼의 적절한 값을 찾는 것이 목표입니다.

대부분의 라이브러리는 대역폭 자동 선택 방법을 제공합니다. 가장 흔한 것은 Silverman의 경험법칙 입니다. 표본 크기와 표준편차를 바탕으로 대역폭을 선택합니다. 대략 정규 분포에는 잘 작동하지만, 다봉 분포에서는 과도하게 평활화할 수 있습니다.

확신이 없다면 여러 대역폭 값을 시도해 곡선을 비교해 보세요. 차이를 통해 데이터에 대해 많은 것을 배울 수 있습니다.

KDE vs. 히스토그램

히스토그램과 KDE 모두 데이터의 분포를 보여주지만, 접근 방식이 크게 다릅니다.

히스토그램

히스토그램은 데이터를 이산 구간으로 나누고 각 구간에 몇 개의 포인트가 속하는지 셉니다. 빠르고 직관적이며 비전문가에게도 설명하기 쉽습니다.

문제는 구간 민감도입니다. 구간 수를 바꾸면 모양이 달라집니다. 객관적으로 옳은 구간 수가 없기 때문에, 같은 데이터를 보고도 이 선택 하나만으로 다른 결론을 내릴 수 있습니다.

히스토그램은 또한 계단형의 불연속적인 모양을 만듭니다. 대충 훑어보기에는 괜찮지만, 실제 기저 분포를 가릴 수 있습니다.

KDE

KDE는 구간 없이 매끄럽고 연속적인 곡선을 제공합니다. 분포의 실제 형태—비대칭, 여러 봉우리, 두터운 꼬리 등—를 드러내는 데 더 유리합니다. 히스토그램은 구간 선택에 따라 이를 놓치거나 왜곡할 수 있습니다.

단점은 KDE도 자체 매개변수(대역폭)를 도입하고 계산량이 더 크다는 점입니다. 또한 y축이 개수가 아닌 확률 밀도를 나타내므로 개념에 익숙하지 않은 독자에게는 덜 직관적일 수 있습니다.

언제 무엇을 쓸까

빠르고 해석하기 쉬운 요약이 필요하거나, 독자가 밀도 추정에 익숙하지 않다면 히스토그램을 사용하세요. 분포의 형태가 중요하다면—예를 들어 그룹을 비교하거나 데이터에서 여러 모드를 탐지하려는 경우—KDE가 더 적합합니다.

Histogram compared to KDE

히스토그램과 KDE 비교

실무에서는 종종 함께 사용합니다. 개수는 히스토그램으로, 형태는 위에 KDE 곡선을 겹쳐서 봅니다.

Python에서의 커널 밀도 추정

Python에서는 빠른 차트를 원할지, 추정 자체에 더 많은 제어가 필요할지에 따라 여러 방식으로 KDE를 계산하고 그릴 수 있습니다.

seaborn으로 KDE 시각화

가장 빠르게 KDE 플롯을 얻는 방법은 seaborn.kdeplot() 입니다. 다음 코드면 충분합니다:

import seaborn as sns
import numpy as np

np.random.seed(42)
scores = np.concatenate([
    np.random.normal(65, 4, 60),
    np.random.normal(80, 3, 40)
])

sns.kdeplot(scores, bw_adjust=1)

KDE with seaborn

seaborn으로 그린 KDE

bw_adjust 매개변수는 자동으로 선택된 대역폭을 스케일합니다. 1보다 작으면 곡선이 빡빡해지고, 1보다 크면 더 평활해집니다. seaborn이 내부적으로 선택한 대역폭에 곱해지는 계수이므로, 원시 대역폭 값을 직접 지정할 필요가 없습니다.

y축은 개수가 아니라 확률 밀도를 나타냅니다. 곡선은 다른 값들에 비해 어떤 값이 더 나올 법한지를 알려줍니다. 높을수록 그 구간에 데이터가 더 집중되어 있다는 뜻입니다.

scipy로 KDE 계산

플롯만이 아니라 실제 밀도 값을 원한다면 scipy.stats.gaussian_kde 를 사용하세요. 임의의 지점에서 평가할 수 있는 호출 가능한 객체를 제공합니다.

from scipy.stats import gaussian_kde
import numpy as np
import matplotlib.pyplot as plt

kde = gaussian_kde(scores, bw_method="scott")
x = np.linspace(45, 100, 500)
density = kde(x)

plt.plot(x, density)

bw_method="scott" 는 Scott의 규칙을 사용해 대역폭을 자동으로 고릅니다. 대부분의 경우에 좋은 기본값입니다. 스칼라 값을 전달하여 대역폭을 수동으로 설정할 수도 있습니다.

KDE with scipy and matplotlib

scipy와 matplotlib로 그린 KDE

R에서의 커널 밀도 추정

R에서는 KDE가 기본으로 제공됩니다. 추가 패키지가 필요 없습니다.

density()로 KDE 계산

density() 함수는 숫자형 벡터를 받아 KDE 객체를 반환합니다.

set.seed(42)
scores <- c(rnorm(60, mean = 65, sd = 4),
            rnorm(40, mean = 80, sd = 3))

kde <- density(scores, bw = "SJ")

bw 인자는 대역폭 선택을 제어합니다. "SJ" 는 Sheather-Jones 방법을 사용하며, 기본값보다 다봉 분포를 더 잘 처리합니다. 숫자 값을 전달하여 대역폭을 수동으로 설정할 수도 있습니다.

결과는 두 가지 핵심 구성 요소를 가진 리스트 객체입니다:

  • kde$x: 밀도를 평가한 지점들의 순서열
  • kde$y: 해당 지점들의 밀도 값

곡선 그리기

결과를 그대로 plot() 에 전달하면 됩니다.

plot(kde,
     main = "Exam Score Distribution",
     xlab = "Score",
     ylab = "Density")

R에서 그린 KDE

KDE를 히스토그램 위에 겹치려면 먼저 hist()freq = FALSE 로 호출하고, 이후 lines() 로 곡선을 추가하세요.

hist(scores, freq = FALSE, main = "Histogram + KDE", xlab = "Score")
lines(kde, col = "blue", lwd = 2)

R에서의 히스토그램 + KDE

freq = FALSE 는 히스토그램을 밀도 기준으로 스케일링해 막대와 곡선이 동일한 y축을 공유하도록 합니다.

KDE의 장단점

KDE는 정말 유용한 시각화 도구지만, 히스토그램을 대체하기 전에 알아둘 만한 트레이드오프가 있습니다.

장점

가장 큰 장점은 KDE가 데이터의 분포에 대한 가정을 하지 않는다는 점입니다. 데이터가 정규인지, 지수인지 등을 미리 정할 필요가 없습니다. 형태는 데이터 자체에서 나옵니다. 덕분에 KDE는 다봉 분포 등 표준 모수적 형태에 맞지 않는 경우에도 유연하게 대응합니다.

출력은 계단형 근사가 아닌 매끄럽고 연속적인 곡선입니다. 히스토그램이 구간 선택에 따라 숨길 수 있는 여러 봉우리나 긴 꼬리 같은 패턴을 더 쉽게 포착할 수 있습니다.

또한 KDE는 먼저 모델을 적합할 필요 없이 원시 데이터에 바로 적용되므로, 탐색적 분석의 첫 단계로 적합합니다.

제한사항

대역폭 선택이 핵심 약점입니다. 잘못 선택하면 추정치는 노이즈를 쫓거나, 반대로 데이터의 실제 패턴을 지나치게 평활화해 버립니다. Silverman의 규칙 같은 자동 방법은 대략 정규 데이터에는 잘 맞지만, 복잡한 분포에서는 오해를 낳을 수 있습니다. 결과를 신뢰하기 전에 보통은 몇 가지 대역폭을 수동으로 확인해 보는 것이 좋습니다.

규모가 커지면 성능 문제가 생길 수 있습니다. KDE는 평가 지점마다 모든 데이터 포인트에 대해 커널 함수를 계산하므로, 데이터셋이 커질수록 계산량이 빠르게 증가합니다. 대부분의 탐색 작업에는 문제가 없지만 수십만 포인트 이상의 데이터셋에서는 느릴 수 있습니다.

경계 효과는 더 미묘한 문제입니다. 표준 KDE는 데이터가 양쪽으로 무한히 뻗을 수 있다고 가정합니다. 0 미만으로 내려갈 수 없는 값처럼 경계가 뚜렷한 데이터의 경우, 유효 범위를 넘어서 확률 질량이 새어 나가며 경계 부근에서 곡선이 인위적으로 낮아집니다. 경계 보정된 KDE도 있으나, 표준 라이브러리에는 덜 구현되어 있고 추가 설정이 필요합니다.

맺음말

KDE는 히스토그램보다 데이터를 더 깔끔하게 볼 수 있는 방법을 제공합니다. 구간 선택도, 모수적 가정도 없습니다. 데이터셋에 실제로 무엇이 있는지 보여주는 매끄러운 곡선만 있습니다.

대역폭은 진짜로 중요한 하나의 매개변수입니다. 몇 가지 값을 시도하고, 곡선을 비교하고, 자동 옵션도 활용하여, 결론을 내리기 전에 추정치가 데이터에 대한 기존 지식과 부합하는지 확인하세요.

KDE에 대한 직관을 기르는 가장 좋은 방법은 실제 데이터에 적용해 보는 것입니다. 잘 아는 데이터셋을 골라 KDE를 적용하고, 히스토그램과 비교해 그동안 놓친 점이 무엇인지 확인해 보세요.

데이터 시각화에 관심이 있으신가요? Python을 사용한다면 Seaborn으로 하는 데이터 시각화 강좌를, R을 사용한다면 ggplot2로 하는 데이터 시각화 강좌를 확인해 보세요.

FAQs

커널 밀도 추정은 무엇에 사용되나요?

KDE는 데이터가 정규 분포나 지수 분포처럼 특정 형태를 따른다고 가정하지 않고, 데이터셋의 확률 분포를 추정하는 데 사용됩니다. 보통 모델링에 앞서 데이터가 어떻게 분포하는지 시각화하는 탐색적 데이터 분석에서 많이 쓰입니다. 이상치 탐지, 그룹 간 분포 비교, 통계 파이프라인에서의 평활화 단계 등에도 활용됩니다.

KDE는 히스토그램과 어떻게 다른가요?

히스토그램은 데이터를 이산 구간으로 나누고 각 구간에 몇 개의 포인트가 들어가는지 셉니다. 얻어지는 형태는 구간 수 선택에 따라 달라지므로 임의 매개변수에 민감합니다. KDE는 각 데이터 포인트에 매끄러운 곡선을 배치해 합산함으로써, 구간 수에 좌우되지 않는 연속적 추정치를 제공합니다.

KDE를 사용하려면 큰 데이터셋이 필요한가요?

KDE는 소규모 데이터셋에서도 동작하지만, 포인트가 아주 적으면 추정의 신뢰도가 떨어집니다. 데이터가 제한적이면 개별 관측치의 영향력이 커져 최종 곡선이 노이즈와 구조를 구분하기 어려워집니다. 데이터셋이 커질수록 추정은 안정화되며 실제 분포를 더 정확히 반영합니다.

잘못된 대역폭을 선택하면 어떻게 되나요?

대역폭이 너무 작으면 각 포인트에 과민하게 반응하는 들쭉날쭉한 곡선이 되어, 데이터의 전체 형태를 파악하기 어렵습니다. 대역폭이 너무 크면 과도하게 평활화되어 구분되는 봉우리가 하나의 융기처럼 합쳐져 실제 구조를 숨길 수 있습니다. 대부분의 라이브러리는 Silverman의 규칙 같은 자동 대역폭 선택을 제공하지만, 결론을 내리기 전에는 몇 가지 값을 수동으로 시험해 보는 것이 좋습니다.

KDE는 데이터 경계 근처에서도 잘 작동하나요?

표준 KDE는 데이터가 양쪽으로 무한히 확장될 수 있다고 가정하므로, 나이, 수입, 0 미만이 될 수 없는 카운트처럼 하한 또는 상한이 있는 변수에서는 문제가 발생합니다. 경계 근처에서 유효 범위를 넘어 확률 질량이 새어 나가 곡선이 가장자리에서 인위적으로 낮아집니다. 경계 보정 KDE 방법이 있긴 하지만 모든 라이브러리에 구현되어 있지는 않고, 추가 설정이 필요합니다.

주제

DataCamp와 함께 학습하세요

courses

R에서의 Support Vector Machine

4
11.1K
이 강의는 직관적이고 시각적인 방식으로 서포트 벡터 머신(SVM)을 소개합니다.
자세히 보기Right Arrow
강좌 시작
더 보기Right Arrow