最近在用python复现fluxrank(根因定位)论文,其中用到了核密度估计KDE来计算KPI的变化程度,需要计算累计概率值,网上教程还是挺少的,对于核密度估计算法的原理和实现方式网上教程很多,这里引用一篇,通俗易懂,从零开始实现核密度估计,也有python中sklearn和scipy中自带的API可以直接使用,这里主要记录下怎么实现累积概率函数,分别从sklearn、scipy以及自己实现的方式来讨论下这三种方式实现累积概率
- 自己实现的方式
def get_kde(x, data_array, bandwidth=0.1):
def gauss(x):
import math
return (1 / math.sqrt(2 * math.pi)) * math.exp(-0.5 * (x ** 2))
N = len(data_array)
res = 0
if len(data_array) == 0:
return 0
for i in range(len(data_array)):
res += gauss((x - data_array[i]) / bandwidth)
res /= (N * bandwidth)
return res
get_kde是简单版本的概率密度函数,可以输入x,得到对应的概率密度,累计概率是对概率密度的积分,所以要计算一个区间[a,b]的累计概率,以一个较小的值离散化得到一个序列,并将这个值乘以概率值,然后求和,就是一个近似求积分的过程,得到累计概率。
∫ a b f ( x ) = 1 n h ∑ i = 1 n [ ∫ a b K ( x − x i h ) d x ] \int_{a}^{b}f(x) = \frac{1}{nh}\sum_{i=1}^{n}[\int_{a}^{b}K(\frac{x-x_i}{h})dx] ∫abf(x)=nh1i=1∑n[∫abK(hx−xi)dx]
-
sklearn的api
sklearn中提供sklearn.neighbors.KernelDensity类,可以传入对应的核函数,而且提供score_samples函数计算概率密度,但是很奇怪的是没有提供计算累计概率的API,如果需要实现可以按照1中来实现
-
scipy的api
scipy中的stats.gaussian_kde可以计算高斯核函数的密度函数,而且提供了直接计算区间的累计密度函数,integrate_box_1d(low=-np.Inf, high=x)