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

如何为散点图中每个点设置不同带宽进行核密度估计?

可变带宽核密度估计的实现方法

scipy和sklearn的默认核密度估计(KDE)确实只支持全局固定带宽。如果要给每个样本点设置不同带宽,你需要实现自适应/可变带宽核密度估计,下面是具体的实现思路和代码:

核心原理

可变带宽KDE的公式为:
$\hat{f}(x) = \frac{1}{n} \sum_{i=1}^n \frac{1}{h_i^d} K\left( \frac{x - X_i}{h_i} \right)$
其中:

  • $h_i$是第i个样本点的带宽(可手动指定,也可根据数据自适应计算)
  • $K$是核函数(这里以常用的高斯核为例)
  • $d$是数据的维度

1. 手动实现可变带宽KDE

下面是基于numpy的通用实现,支持手动指定每个样本的带宽:

import numpy as np

def variable_bandwidth_kde(x, X, h):
    """
    计算可变带宽核密度估计值
    参数:
        x: 待预测的点,形状(m, d)
        X: 样本数据,形状(n, d)
        h: 每个样本点的带宽,形状(n,)(单维度带宽)或(n, d)(各维度独立带宽)
    返回:
        每个x点的密度估计值,形状(m,)
    """
    n, d = X.shape
    m, _ = x.shape
    
    # 扩展维度实现广播计算
    x_expanded = x[:, np.newaxis, :]  # 形状(m, 1, d)
    X_expanded = X[np.newaxis, :, :]  # 形状(1, n, d)
    
    # 处理带宽的维度
    if h.ndim == 1:
        h_expanded = h[np.newaxis, :, np.newaxis]  # 扩展为(1, n, 1)
    else:
        h_expanded = h[np.newaxis, :, :]  # 扩展为(1, n, d)
    
    # 高斯核计算
    kernel = np.exp(-0.5 * np.sum(((x_expanded - X_expanded) / h_expanded)**2, axis=2))
    # 高斯核的归一化因子:(2π)^(d/2) * 带宽乘积
    norm_factor = (2 * np.pi)**(d/2) * np.prod(h_expanded, axis=2)
    # 求和并取平均得到密度
    density = np.sum(kernel / norm_factor, axis=1) / n
    return density

2. 自适应计算带宽(常用方案)

如果不想手动指定每个带宽,可以基于全局带宽和样本局部密度自适应生成:

  1. 先用全局带宽(比如Scott规则)计算每个样本点的密度估计
  2. 根据局部密度调整带宽:密度低的区域用更大带宽(避免欠平滑),密度高的区域用更小带宽(避免过平滑)

示例代码:

from scipy.stats import gaussian_kde

# 生成测试样本
X = np.random.multivariate_normal([0, 0], [[1, 0.5], [0.5, 1]], 1000)

# 1. 计算全局带宽(Scott规则)
kde_global = gaussian_kde(X.T)
h_global = kde_global.factor

# 2. 计算每个样本点的全局密度估计
f_hat = kde_global(X.T)

# 3. 自适应调整带宽:h_i = h_global * (f_hat / f_mean)^(-alpha)
# alpha通常取0.5,平衡平滑程度
alpha = 0.5
f_mean = np.mean(f_hat)
h_i = h_global * (f_hat / f_mean)**(-alpha)

# 4. 使用可变带宽KDE计算新点的密度
x = np.random.multivariate_normal([0, 0], [[1, 0.5], [0.5, 1]], 100)
density = variable_bandwidth_kde(x, X, h_i)

注意事项

  • 高维数据下,这种实现的计算量会随样本量增长而显著增加,大样本场景可以考虑用KD树加速最近邻计算
  • 手动指定带宽时,要确保所有带宽值为正数,避免出现除零错误

内容的提问来源于stack exchange,提问作者happy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 10:05:24