核密度估计KDE(kernel density estimation)理论及python实现

前言

pdf和cdf:https://zhuanlan.zhihu.com/p/644575445

核密度估计

核密度估计(kernel density estimation,KDE)是一种非参数方法,用于估计数据的概率密度函数。KDE基于核函数,以一定的带宽参数,通过对每个数据点附近的核函数进行加权平均来估计数据点的概率密度,即根据有限的数据样本对总体进行推断。

核函数通常选择高斯核函数(Gaussian kernel),它是KDE中最常用的核函数之一。高斯核函数的公式如下:

其中,是输入值,表示高斯核函数的值。

其中,是在处估计的概率密度函数,是样本大小,是核函数,是带宽。

KDE的基本思想是,假设数据点是从未知概率密度函数(PDF)中独立采样产生的,我们的目标是估计这个未知的概率密度函数。KDE不依赖于任何特定的概率分布假设,因此可以适用于任何类型的数据。

KDE的估计过程如下:

  • 对于每个数据点,以该点为中心,使用核函数(如高斯核函数)构建一个核密度函数。

  • 通过计算每个数据点的核密度函数值,并对它们进行加权平均,得到整体的概率密度函数估计值。

带宽(bandwidth)是一个重要的参数,带宽的选择会影响估计的平滑性和敏感性。较大的带宽会导致平滑的估计结果,但可能会掩盖细节。较小的带宽会导致更精细的估计结果,但可能会引入噪声和过拟合。

KDE可以提供关于数据分布的重要信息,例如数据的峰值、数据的分布形状。此外,KDE还可以作为其他机器学习和统计方法的基础,例如聚类、异常检测等。

python实现

import numpy as np
import matplotlib.pyplot as plt

def kde(x, data, bandwidth, kernel_func):
    n = len(data)

    # 计算核函数的值
    kernel_values = kernel_func((x - data) / bandwidth)

    # 计算概率密度估计值
    density_estimation = np.sum(kernel_values) / (n * bandwidth)

    return density_estimation

def gaussian_kernel(x):
    """
    高斯核函数
    """
    return (1 / np.sqrt(2 * np.pi)) * np.exp(-0.5 * x**2)

# 生成一些随机数据
np.random.seed(0)
data = np.concatenate((np.random.normal(0, 1, 1000), np.random.normal(5, 1, 1000)))

# 生成一些测试数据
x = np.linspace(-5, 10, 1000)

# 设置带宽参数
bandwidth = 0.5

# 计算估计的概率密度函数
density_estimation = np.array([kde(xi, data, bandwidth, gaussian_kernel) for xi in x])

# 绘制概率密度函数图像
plt.figure(1)
plt.hist(data, bins=40, density=True)
plt.plot(x, density_estimation, color='red', linestyle='-')
plt.show()
38f837f164dc545aa67c809c71615f96.png

使用 sklearn实现KDE

import numpy as np
import matplotlib.pyplot as plt
from sklearn.neighbors import KernelDensity


def kde(x, data, bandwidth, kernel_func):
    n = len(data)

    # 计算核函数的值
    kernel_values = kernel_func((x - data) / bandwidth)

    # 计算概率密度估计值
    density_estimation = np.sum(kernel_values) / (n * bandwidth)

    return density_estimation

def gaussian_kernel(x):
    """
    高斯核函数
    """
    return (1 / np.sqrt(2 * np.pi)) * np.exp(-0.5 * x**2)

# 生成一些随机数据
np.random.seed(0)
data = np.concatenate((np.random.normal(0, 1, 1000), np.random.normal(5, 1, 1000)))

# 生成一些测试数据
x = np.linspace(-5, 10, 1000)

# 设置带宽参数
bandwidth = 0.5

# # 计算估计的概率密度函数
# density_estimation = np.array([kde(xi, data, bandwidth, gaussian_kernel) for xi in x])

model = KernelDensity(kernel='gaussian', bandwidth=bandwidth)
model.fit(np.array(data).reshape(-1, 1))

log_dens = model.score_samples(np.array(x).reshape(-1, 1))
density_estimation = [dens for dens in np.exp(log_dens)]
# 绘制概率密度函数图像
plt.figure(1)
plt.hist(data, bins=40, density=True)
plt.plot(x, density_estimation, color='red', linestyle='-')
plt.show()
a4cf476858cf8554aff0db5628add17a.png

推荐阅读:

我的2022届互联网校招分享

我的2021总结

浅谈算法岗和开发岗的区别

互联网校招研发薪资汇总

公众号:AI蜗牛车

保持谦逊、保持自律、保持进步

651945cc3ff175654bcd43ebecaa9674.jpeg

发送【蜗牛】获取一份《手把手AI项目》(AI蜗牛车著)

发送【1222】获取一份不错的leetcode刷题笔记

发送【AI四大名著】获取四本经典AI电子书

猜你喜欢

转载自blog.csdn.net/qq_33431368/article/details/134977592