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

如何从statsmodels的KDEMultivariate构建的KDE中重采样?

从KDEMultivariate构建的KDE中重采样的方法

你提到的问题确实很常见——statsmodels的KDEMultivariate在带宽选择上更灵活(支持交叉验证),但遗憾的是没有内置的重采样方法。不过我们可以通过两种简单高效的方式实现重采样,完全贴合KDE的核心原理:


方法一:手动实现重采样(推荐,高效且直观)

KDE的本质是每个原始样本点作为核的中心,再用指定带宽的核函数生成分布,所以重采样的逻辑很直接:

  1. 从原始样本中随机抽取若干个点作为核中心(带放回抽样)
  2. 以每个中心为均值,以KDE的带宽为标准差,从高斯核(KDEMultivariate默认核)中生成新样本

一维案例代码

import numpy as np
from statsmodels.nonparametric.kernel_density import KDEMultivariate

# 生成双高斯混合样本
sampled = np.concatenate((np.random.normal(loc=-3, scale=1, size=1000),
                          np.random.normal(loc=3, scale=1, size=1000)))
# 用交叉验证拟合KDE
kde = KDEMultivariate(sampled, 'c', bw='cv_ml')

def resample_kdemultivariate(kde, n_samples):
    # 1. 从原始样本中随机选择核中心(带放回)
    selected_centers = np.random.choice(kde.data.flatten(), size=n_samples)
    # 2. 获取KDE的带宽(一维场景取第一个元素)
    bw = kde.bw[0]
    # 3. 从每个中心的高斯核生成样本
    resampled = selected_centers + np.random.normal(loc=0, scale=bw, size=n_samples)
    return resampled

# 生成1000个重采样点
resampled_data = resample_kdemultivariate(kde, 1000)

高维案例代码

如果处理的是高维数据,只需要稍作调整,适配多维高斯噪声的生成:

# 生成二维双高斯混合样本
sampled_2d = np.concatenate((np.random.multivariate_normal([-3, -3], [[1,0],[0,1]], 1000),
                             np.random.multivariate_normal([3, 3], [[1,0],[0,1]], 1000)))
# 拟合二维KDE
kde_2d = KDEMultivariate(sampled_2d, 'cc', bw='cv_ml')

def resample_kdemultivariate_highdim(kde, n_samples):
    # 1. 随机选择核中心
    center_indices = np.random.choice(kde.data.shape[0], size=n_samples)
    selected_centers = kde.data[center_indices]
    # 2. 获取各维度的带宽
    bw = kde.bw
    # 3. 生成对应维度的高斯噪声并叠加到中心上
    noise = np.random.normal(loc=0, scale=bw, size=(n_samples, kde.data.shape[1]))
    resampled = selected_centers + noise
    return resampled

# 生成1000个二维重采样点
resampled_2d = resample_kdemultivariate_highdim(kde_2d, 1000)

这种方法的优势是:完全遵循KDE的数学定义,速度快(全向量化numpy操作),且能适配任意维度。


方法二:转换为scipy.stats.gaussian_kde复用resample方法

如果你更习惯用scipy的API,可以把KDEMultivariate得到的带宽传递给gaussian_kde,然后直接调用它的resample()方法。需要注意的是,scipy的带宽缩放逻辑和statsmodels略有不同,需要做简单的转换:

from scipy.stats import gaussian_kde

# 基于KDEMultivariate的带宽初始化scipy的KDE
scipy_kde = gaussian_kde(sampled)
# 调整带宽为KDEMultivariate的最优带宽
scipy_kde.set_bandwidth(bw_method=kde.bw[0] / scipy_kde.factor)

# 直接调用resample方法
resampled_scipy = scipy_kde.resample(1000)

这种方法的优势是不用自己写重采样逻辑,但需要注意带宽的转换细节,避免出现偏差。


注意事项

  • 以上方法默认KDEMultivariate使用的是高斯核(这是它的默认设置),如果你指定了其他核(如Epanechnikov),需要对应调整采样的分布逻辑。
  • 交叉验证得到的带宽已经是最优的,重采样时直接复用即可,无需额外调整。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 06:41:46