커널 밀도 추정
1. 개요
커널 밀도 추정(Kernel density estimation, KDE)은 주어진 표본 데이터를 바탕으로 확률 밀도 함수의 형태를 추정하는 비모수적 방법이다. KDE는 각 표본에 커널 함수로 결정된 덩어리를 부여하여 부드러운 추정값을 얻으며, 대역폭(bandwidth)은 추정 결과에 큰 영향을 미치는 중요한 매개변수이다. 대역폭 선택은 평균 적분 제곱 오차(MISE)를 최소화하는 것을 목표로 하며, 플러그인 선택기나 교차 검증 선택기가 널리 사용된다. KDE는 특성 함수 밀도 추정량과 관련이 있으며, C++, Python, R 등 다양한 프로그래밍 언어 및 통계 소프트웨어 패키지에서 구현되어 활용된다.
| 분야 | 통계학 |
|---|---|
| 하위 분야 | 밀도 추정 비모수 통계 |
| 다른 이름 | 파젠 창 파젠-로젠블라트 창 |
| 정의 | 주어진 데이터에 대한 확률 밀도 함수를 추정하는 비모수적 방법임 커널을 가중치로 사용하여 데이터 포인트 주변에 부드러운 함수를 구성하는 방식으로 동작함 |
|---|
| 특징 | 모수적 방법에 비해 데이터에 대한 사전 지식이나 가정이 덜 필요함 시각화 및 데이터 탐색에 유용함 밀도 추정, 분류, 군집화 등 다양한 분야에 응용 가능함 |
|---|
| 장점 | 데이터 분포에 대한 가정이 적음 다양한 형태의 분포 추정 가능 |
|---|---|
| 단점 | 계산 비용이 많이 들 수 있음 커널 함수 및 대역폭 선택에 민감함 |
| 관련 개념 | 히스토그램 밀도 추정 비모수 통계 커널 (통계학) 대역폭 (통계학) |
|---|
| 활용 분야 | 데이터 마이닝 패턴 인식 기계 학습 컴퓨터 비전 지리 정보 시스템 |
|---|
| 참고 문헌 | M. Rosenblatt (1956). "Remarks on Some Nonparametric Estimates of a Density Function". The Annals of Mathematical Statistics 27 (3): 832–837. E. Parzen (1962). "On Estimation of a Probability Density Function and Mode". The Annals of Mathematical Statistics 33 (3): 1065–1076. Hastie, Trevor; Tibshirani, Robert; Friedman, Jerome H. (2001). The Elements of Statistical Learning : Data Mining, Inference, and Prediction : with 200 full-color illustrations. New York: Springer. |
|---|
2. 정의
(x1, x2, ..., xn)를 임의의 지점 x에서 알 수 없는 확률 밀도 함수 ƒ를 갖는 어떤 일변량 분포에서 추출된 독립 동일 분포 표본이라고 할 때, 함수 ƒ의 형태를 추정하는 데 사용되는 커널 밀도 추정기는 다음과 같이 정의된다.
:
여기서 K는 커널 (음이 아닌 함수)이고, h는 대역폭(bandwidth) 또는 평활화(smoothing) 매개변수이다. Kh(x) = 1/h K(x/h)는 스케일링된 커널(scaled kernel)로 정의된다.
커널 함수로는 표준 가우스 함수(평균이 0이고 분산이 1)를 채용하는 경우가 많다.
:
3. 커널 함수
균일, 삼각, 이중 가중, 삼중 가중, 에파네치니코프(포물선), 정규 등 다양한 커널 함수가 일반적으로 사용된다. 에파네치니코프 커널은 평균 제곱 오차 측면에서 최적이지만, 이전에 나열된 커널을 사용했을 때의 효율성 손실은 작다. 편리한 수학적 속성으로 인해 정규 커널이 자주 사용되며, 이는 K(x) = ϕ(x)임을 의미하며, 여기서 ϕ는 표준 정규 분포 밀도 함수이다.
4. 대역폭 선택
커널 밀도 추정에서 대역폭 h는 결과에 큰 영향을 미치는 중요한 자유 매개변수이다. 대역폭은 커널 함수의 폭을 결정하며, 추정치의 매끄러운 정도를 조절한다.
* 과소 평활 (Undersmoothing): 대역폭이 너무 작으면 (h = 0.05, 빨간색 곡선) 데이터의 개별적인 변동에 너무 민감하게 반응하여, 실제로는 존재하지 않는 여러 개의 작은 봉우리(가짜 데이터 아티팩트)들이 나타나는 과소 평활 문제가 발생한다.
* 과대 평활 (Oversmoothing): 대역폭이 너무 크면 (h = 2, 녹색 곡선) 데이터의 중요한 특징들을 지나치게 뭉뚱그려, 데이터의 실제 구조(예: 봉우리)를 제대로 파악하기 어렵게 만드는 과대 평활 문제가 발생한다.
* 최적 평활 (Optimal Smoothing): 적절한 대역폭 (h = 0.337, 검은색 곡선)을 선택하면 실제 밀도 함수에 근접한 부드러운 추정치를 얻을 수 있다.
최적의 대역폭을 결정하기 위해, 평균 적분 제곱 오차(MISE)를 최소화하는 값을 찾는다. MISE는 추정된 밀도 함수와 실제 밀도 함수 간의 차이를 나타내는 지표이다.
:
일반적인 경우, 실제 밀도 함수 ƒ는 알려져 있지 않기 때문에, MISE를 직접 계산할 수 없다. 따라서, 점근적 MISE (AMISE)를 최소화하는 대역폭을 사용한다.
:
하지만, AMISE 공식에도 알 수 없는 실제 밀도 함수 의 2차 도함수 가 포함되어 있어, 이를 직접 사용하기는 어렵다.
이러한 문제를 해결하기 위해, 데이터 기반의 다양한 자동 대역폭 선택 방법들이 개발되었다. 대표적인 방법으로는 플러그인(plug-in) 선택기와 교차 검증 선택기가 있으며, 여러 연구에서 이 방법들이 다양한 데이터 세트에서 효과적이라는 것이 확인되었다.
일반적으로, 커널 밀도 추정기의 수렴 속도는 n−4/5으로, 모수적 방법의 수렴 속도 n−1보다 느리다.
4.1. 경험적 대역폭 추정 (Rule-of-Thumb)
실버먼의 규칙(Silverman's rule of thumb)은 추정되는 기본 밀도가 가우시안(정규 분포)에 가깝다고 가정할 때 사용하는 경험적 대역폭 추정 방법이다. 계산이 간단하지만, 밀도가 정규 분포와 거리가 멀 경우 부정확한 추정치를 생성할 수 있어 주의가 필요하다.
실버먼의 경험 법칙에 따른 대역폭(h)은 다음과 같이 계산한다.
:
* : 표본의 표준 편차.
* IQR: 사분위간 범위 (Interquartile Range). 데이터의 3사분위수(75번째 백분위수)에서 1사분위수(25번째 백분위수)를 뺀 값.
* n: 표본 크기.
꼬리가 길거나 왜곡된 분포, 또는 이중 모드(봉우리가 두 개인) 혼합 분포의 경우, 표준 편차 대신 다음 값을 사용해 적합도를 높이기도 한다.
:
이 방법은 가우시안 근사라고도 불리며, 밀도가 정규 분포에 가까울 때는 유용하지만, 그렇지 않으면 과도하게 평활화된 추정치를 생성할 수 있다. 예를 들어 이중 모드 가우시안 혼합 모델을 추정할 때, 규칙에 따른 대역폭은 실제 밀도의 두 봉우리를 제대로 표현하지 못하고 과도하게 평활화된 결과를 낼 수 있다.
5. 특성 함수 밀도 추정량과의 관계
표본 (x1, x2, ..., xn)이 주어졌을 때, 특성 함수는 다음과 같이 추정할 수 있다.
:
특성 함수를 알면, 푸리에 변환 공식을 통해 해당 확률 밀도 함수를 찾을 수 있다. 이 반전 공식을 적용하는 데 한 가지 어려움은 추정치 가 큰 t에 대해 신뢰할 수 없기 때문에 발산하는 적분으로 이어진다는 것이다. 이 문제를 해결하기 위해 추정량 에 원점에서 1이고 무한대에서 0으로 떨어지는 감쇠 함수를 곱한다. "대역폭 매개변수" h는 함수 를 얼마나 빠르게 감쇠시키려고 하는지를 제어한다. 특히 h가 작을 때, ψh(t)는 광범위한 t에 대해 대략 1이 될 것이며, 이는 가 t의 가장 중요한 영역에서 사실상 변경되지 않음을 의미한다.
함수 ψ에 대한 가장 일반적인 선택은 적분 구간을 로 효과적으로 잘라내는 균등 함수 또는 가우스 함수 중 하나이다. 함수 ψ가 선택되면 반전 공식을 적용할 수 있으며, 밀도 추정량은 다음과 같다.
:
여기서 K는 감쇠 함수 ψ의 푸리에 변환이다. 따라서 커널 밀도 추정량은 특성 함수 밀도 추정량과 일치한다.
6. 기하학적 및 위상적 특징
(전역) 최빈값의 정의를 지역적 의미로 확장하여 지역 최빈값을 정의할 수 있다.
:
즉, 은 밀도 함수가 지역적으로 최대화되는 점들의 집합이다. 의 자연스러운 추정량은 커널 밀도 추정(KDE)에서 플러그인 방식으로 얻을 수 있다. 여기서 와 는 와 의 KDE 버전이다. 완만한 가정 하에서, 는 의 일관된 추정량이다. 수치적으로 추정량 를 계산하기 위해 평균 이동 알고리즘을 사용할 수 있다.
7. 통계적 구현
C/C++ 환경에서 커널 밀도 추정을 지원하는 라이브러리는 다음과 같다.
* [https://github.com/vmorariu/figtree FIGTree]: 정규 커널을 사용하며 MATLAB 인터페이스를 제공한다.
* [https://libagf.sf.net libagf]: 가변 커널 밀도 추정을 지원한다.
* mlpack: 다양한 커널을 사용하며, 빠른 계산을 위해 오차 허용 범위를 설정할 수 있다. Python 및 R 인터페이스를 제공한다.
C# 및 F#에서는 Math.NET Numerics 오픈소스 라이브러리가 [https://numerics.mathdotnet.com/api/MathNet.Numerics.Statistics/KernelDensity.htm 커널 밀도 추정] 기능을 제공한다.
CrimeStat은 정규, 균일, 4차, 음의 지수, 삼각 커널 등 5가지 커널 함수를 사용한 단일 및 이중 커널 밀도 추정 루틴을 제공하며, Head Bang 루틴 보간, 2차원 Journey-to-crime 밀도 함수 추정, 3차원 베이시안 Journey-to-crime 추정에도 사용된다.
ELKI에서 커널 밀도 함수는 `de.lmu.ifi.dbs.elki.math.statistics.kernelfunctions` 패키지에서 찾을 수 있다.
ESRI 제품에서 커널 밀도 매핑은 Spatial Analyst 도구 상자에서 Quartic(biweight) 커널을 사용하여 관리된다.
Excel에서 왕립 화학회는 [http://www.rsc.org/Membership/Networking/InterestGroups/Analytical/AMC/Software/kerneldensities.asp 분석 방법 위원회 기술 브리프 4]를 기반으로 커널 밀도 추정 추가 기능을 제공한다.
gnuplot에서 커널 밀도 추정은 `smooth kdensity` 옵션으로 구현되며, 데이터 파일은 각 지점의 가중치와 대역폭을 포함하거나, 대역폭은 "Silverman의 경험 법칙"에 따라 자동 설정 가능하다.
Haskell에서 커널 밀도는 [http://hackage.haskell.org/package/statistics statistics] 패키지에서 구현된다.
IGOR Pro에서 커널 밀도 추정은 `StatsKDE` 연산(Igor Pro 7.00에 추가됨)으로 구현된다. 대역폭은 사용자 지정 또는 Silverman, Scott, Bowmann 및 Azzalini 방법을 통해 추정 가능하며, 커널 유형은 Epanechnikov, Bi-weight, Tri-weight, Triangular, Gaussian, Rectangular이다.
Java에서 Weka는 [http://weka.sourceforge.net/doc.stable/weka/estimators/KernelEstimator.html weka.estimators.KernelEstimator]를 제공한다.
JavaScript에서 시각화 패키지 D3.js는 science.stats 패키지에서 KDE 패키지를 제공한다.
JMP에서 Graph Builder 플랫폼은 커널 밀도 추정을 통해 이변량 밀도 등고선 플롯 및 고밀도 영역(HDR), 단변량 밀도 바이올린 플롯 및 HDR을 제공하며, 슬라이더로 대역폭 변경이 가능하다. 이변량 및 단변량 커널 밀도 추정은 Fit Y by X 및 Distribution 플랫폼에서도 제공된다.
Julia에서 커널 밀도 추정은 [https://github.com/JuliaStats/KernelDensity.jl KernelDensity.jl] 패키지에서 구현된다.
KNIME에서 1D 및 2D 커널 밀도 분포는 Vernalis 커뮤니티 기여 노드를 사용하여 생성 및 플롯할 수 있다([https://hub.knime.com/vernalis/extensions/com.vernalis.knime.feature/latest/com.vernalis.knime.plot.nodes.kerneldensity.KernelDensity1DPlotNodeFactory/ 1D 커널 밀도 플롯] 등). 기본 구현은 Java로 작성되었다.
MATLAB에서 커널 밀도 추정은 `ksdensity` 함수(Statistics Toolbox)로 구현된다. MATLAB 2018a부터 대역폭과 커널 스무더를 모두 지정 가능하며, 커널 밀도 범위 지정 등 다른 옵션도 포함된다. 자동 대역폭 선택 방법을 구현하는 무료 MATLAB 소프트웨어 패키지는 MATLAB Central File Exchange에서 제공된다.([http://www.mathworks.com/matlabcentral/fileexchange/14034-kernel-density-estimator 1차원 데이터], [http://www.mathworks.com/matlabcentral/fileexchange/17204-kernel-density-estimation 2차원 데이터], [http://www.mathworks.com/matlabcentral/fileexchange/58312-kernel-density-estimator-for-high-dimensions n차원 데이터]) 커널 회귀, 커널 밀도 추정, 위험 함수 커널 추정 등을 구현하는 무료 MATLAB 도구 상자는 [http://www.math.muni.cz/english/science-and-research/developed-software/232-matlab-toolbox.html 이 페이지]에서 제공된다(이 도구 상자는 책의 일부이다.).
Mathematica에서 수치 커널 밀도 추정은 `SmoothKernelDistribution` 함수, 기호 추정은 `KernelMixtureDistribution` 함수로 구현되며, 둘 다 데이터 기반 대역폭을 제공한다.
Minitab에서 왕립 화학회는 분석 방법 위원회 기술 브리프 4를 기반으로 커널 밀도 추정 매크로를 제공한다.
NAG Library에서 커널 밀도 추정은 `g10ba` 루틴을 통해 구현된다(Fortran 및 C 버전 모두 사용 가능).
[http://nuklei.sourceforge.net/ Nuklei]에서 C++ 커널 밀도 방법은 특수 유클리드 군 데이터에 중점을 둔다.
Octave에서 커널 밀도 추정은 `kernel_density` 옵션(계량 경제학 패키지)으로 구현된다.
Origin에서 2D 커널 밀도 플롯은 사용자 인터페이스에서 생성 가능하며, 1D Ksdensity 및 2D Ks2density 함수는 [http://wiki.originlab.com/~originla/ltwiki/index.php?title=Category:LabTalk_Programming LabTalk], Python, C 코드에서 사용 가능하다.
Perl에서 구현은 [http://search.cpan.org/~janert/Statistics-KernelEstimation-0.05 Statistics-KernelEstimation 모듈]에서 제공된다.
PHP에서 구현은 [https://github.com/markrogoyski/math-php MathPHP 라이브러리]에서 제공된다.
Python에서 커널 밀도 추정은 다양한 패키지에서 지원된다.
* [http://pythonhosted.org/PyQt-Fit/mod_kde.html pyqt_fit.kde Module] ([https://pypi.python.org/packages/source/P/PyQt-Fit/PyQt-Fit-1.3.4.tar.gz PyQt-Fit 패키지])
* SciPy (scipy.stats.gaussian_kde)
* Statsmodels (KDEUnivariate 및 KDEMultivariate)
* scikit-learn (KernelDensity) (비교 참조)
* [https://kdepy.readthedocs.io/en/latest/ KDEpy]: 가중 데이터 및 FFT 구현을 지원하며, 다른 구현보다 빠르다.
* pandas 라이브러리[https://pandas.pydata.org/]: plot 메서드(df.plot(kind='kde')[https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.plot.kde.html])를 통해 kde 플롯을 지원한다.
* [https://getdist.readthedocs.io getdist] 패키지: 가중 및 상관 MCMC 샘플을 위한 1D 및 2D 분포에 대해 최적화된 대역폭, 경계 보정 및 고차 방법을 지원한다.
* seaborn (import seaborn as sns, sns.kdeplot())
* KDE의 GPU 구현
R에서 커널 밀도 추정은 다음과 같이 구현된다.
* 기본 배포의 `density`
* stats 패키지의 `bw.nrd0` 함수 (Silverman 책의 최적화 공식 사용)
* [https://cran.r-project.org/web/packages/KernSmooth/index.html KernSmooth 라이브러리]의 `bkde`
* [https://CRAN.R-project.org/package=DataVisualizations DataVisualizations 라이브러리]의 `ParetoDensityEstimation` (파레토 분포 밀도 추정)
* [https://cran.r-project.org/web/packages/ks/index.html ks 라이브러리]의 `kde`
* [https://cran.r-project.org/web/packages/evmix/index.html evmix 라이브러리]의 `dkden` 및 `dbckden` (경계 보정 커널 밀도 추정)
* [https://cran.r-project.org/web/packages/np/index.html np 라이브러리]의 `npudens` (수치 및 범주형 데이터)
* [https://cran.r-project.org/web/packages/sm/index.html sm 라이브러리]의 `sm.density`
* 패키지 설치 없이 `kde.R` 함수 구현: [http://web.maths.unsw.edu.au/~zdravkobotev/kde.R kde.R]
* 도시 분석에 전념하는 [https://cran.r-project.org/web/packages/btb/index.html btb 라이브러리]의 `kernel_smoothing`
SAS에서 `proc kde`는 단변량 및 이변량 커널 밀도 추정에 사용된다.
Apache Spark에서 `KernelDensity()` 클래스를 제공한다.
Stata에서 `kdensity`로 구현된다(예: `histogram x, kdensity`). 또는, 1D 또는 2D 밀도 함수 추정을 위한 무료 Stata 모듈 KDENS를 사용할 수 있다.
Swift에서 오픈 소스 통계 라이브러리 [https://github.com/r0fls/swiftstats SwiftStats]의 `SwiftStats.KernelDensityEstimation`을 통해 구현된다.
MATLAB , Origin,[http://folk.uio.no/ohammer/past/ PAST], R 언어, Stata, SAS 에서도 커널 밀도 추정기능을 제공한다.