You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于两个高斯KDE估计值计算KL散度?

计算两个高斯KDE之间的KL散度及分布距离

先解决你疑惑的PDF值大于1的问题

概率密度(PDF)本身可以大于1,它不是概率,而是概率的变化率。比如均匀分布U(0, 0.5)的PDF恒为2,完全符合定义,所以你看到PDF大于1是正常现象,不影响后续计算。


两种可行的KL散度计算方法

KL散度的定义是:$D_{KL}(P||Q) = \mathbb{E}_P\left[\log\frac{P(x)}{Q(x)}\right] = \int P(x)\log\frac{P(x)}{Q(x)}dx$,对于KDE拟合的分布,我们可以用以下两种方法近似计算:

方法1:网格采样+数值积分

通过在覆盖数据范围的密集网格上计算PDF,再用数值积分近似KL散度:

import numpy as np
from scipy import stats
from scipy.integrate import trapezoid

# 生成示例数据
dataset1 = np.random.rand(50)
dataset2 = np.random.rand(49)

# 拟合KDE
kernel1 = stats.gaussian_kde(dataset1)
kernel2 = stats.gaussian_kde(dataset2)

# 确定采样范围(覆盖两个数据集的极值,适当扩展避免边界偏差)
min_val = min(dataset1.min(), dataset2.min()) - 0.1
max_val = max(dataset1.max(), dataset2.max()) + 0.1
# 生成密集采样点
x = np.linspace(min_val, max_val, 1000)

# 计算两个KDE在采样点上的PDF值(加极小值避免log(0))
pdf1 = kernel1(x) + 1e-12
pdf2 = kernel2(x) + 1e-12

# 用梯形法计算积分,近似KL散度
kl_div = trapezoid(pdf1 * np.log(pdf1 / pdf2), x)
print(f"KL散度(P||Q): {kl_div:.4f}")

方法2:蒙特卡洛采样

从P分布(kernel1)采样,通过样本均值近似期望:

# 从kernel1对应分布采样大量样本
samples = kernel1.resample(size=10000)[0]

# 计算采样点的PDF值
pdf1 = kernel1(samples) + 1e-12
pdf2 = kernel2(samples) + 1e-12

# 样本均值近似KL散度
kl_div_mc = np.mean(np.log(pdf1 / pdf2))
print(f"蒙特卡洛估计KL散度(P||Q): {kl_div_mc:.4f}")

对称分布距离:JS散度

KL散度是不对称的($D_{KL}(P||Q) \neq D_{KL}(Q||P)$),如果需要对称的分布距离,可以使用JS散度:

# 计算混合分布的PDF
pdf_mix = 0.5 * pdf1 + 0.5 * pdf2

# 计算JS散度
js_div = 0.5 * trapezoid(pdf1 * np.log(pdf1 / pdf_mix), x) + 0.5 * trapezoid(pdf2 * np.log(pdf2 / pdf_mix), x)
print(f"JS散度: {js_div:.4f}")

内容的提问来源于stack exchange,提问作者f.leno

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 19:15:24