python:找到两个gaussian_kde函数(对象)的交集

科幻小说

我有两个python gaussian_kde对象,我想找到交叉点。有没有简单的方法可以做到这一点?

请注意,这些函数没有很好地参数化,请参见图。 在此处输入图片说明

这是一种幼稚的方法(假设只有一个路口,但是鉴于指定的init_interval中不超过一个路口,可以很容易地为范围中的所有路口修改它):

def find_intersection(kde1, kde2, init_interval=0.01, scope =[0,1], convergence=0.0001):
x_left = scope[0]
x_right = scope[0]+init_interval
while x_right < scope[1]:
    left = kde1(x_left)[0]-kde2(x_left)[0]
    right = kde1(x_right)[0]-kde2(x_right)[0]
    if left*right < 0: #meaning the functions intersected (an odd number of times) in the interval
        if init_interval <= convergence:
            return x_right
        else: 
            return find_intersection(kde1, kde2, init_interval/10, scope=[x_left, x_right])
    else: #no intersection or an even number of intersections in the interval
        x_left = x_right
        x_right+=init_interval
return scope[0]-1 #out of scope means no intersection

对于地块的KDE,我们得到:

>>>from scipy.stats import gaussian_kde
>>>data1 = d_sp.values()
>>>density1 = gaussian_kde(data1)
>>>data2 = d_xp.values()
>>>density2 = gaussian_kde(data2)
>>>xs = np.linspace(0,.2,200)
>>>print find_intersection(density1, density2) 
0.0403   
>>>print find_intersection(density1, density2, convergence=0.000001)
0.0403 

我想知道是否存在一种利用KDE功能和对象的“封闭形式”,可以提供正确的解决方案。

谢谢!

萨沙

如果没有代码,很难提供帮助,但是我实现了一个完整的示例,其中包括:

  • 数据生成,包括随机抽样
  • 拟合
  • 交叉发现

方法

基本思想是使用一些通用的寻根算法。为此,我们正在使用brentq从SciPy的。

代码

import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import norm
from scipy.optimize import brentq
from sklearn.neighbors.kde import KernelDensity

# Generate normal functions
x_axis = np.linspace(-3, 3, 100)
gaussianA = norm.pdf(x_axis, 2, 0.5)  # mean, sigma
gaussianB = norm.pdf(x_axis, 0.1, 1.5)

# Random-sampling from functions
a_samples = norm.rvs(2, 0.5, size=100)
b_samples = norm.rvs(0.1, 1.5, size=100)

# Fit KDE
def kde_sklearn(x, x_grid, bandwidth=0.2, **kwargs):
    """Kernel Density Estimation with Scikit-learn"""
    kde_skl = KernelDensity(bandwidth=bandwidth, **kwargs)
    kde_skl.fit(x[:, np.newaxis])
    # score_samples() returns the log-likelihood of the samples
    log_pdf = kde_skl.score_samples(x_grid[:, np.newaxis])
    return kde_skl, np.exp(log_pdf)

kdeA, pdfA = kde_sklearn(a_samples, x_axis, bandwidth=0.25)
kdeB, pdfB = kde_sklearn(b_samples, x_axis, bandwidth=0.25)

# Find intersection
def findIntersection(fun1, fun2, lower, upper):
    return brentq(lambda x : fun1(x) - fun2(x), lower, upper)

funcA = lambda x: np.exp(kdeA.score_samples([[x]][0]))
funcB = lambda x: np.exp(kdeB.score_samples([[x]][0]))

result = findIntersection(funcA, funcB, -3, 3)

# Plot
f, (ax1, ax2) = plt.subplots(1, 2, sharey=True)
ax1.plot(x_axis, gaussianA, color='green')
ax1.plot(x_axis, gaussianB, color='blue')
ax1.set_title('Original Gaussians')
ax2.plot(x_axis, pdfA, color='green')
ax2.plot(x_axis, pdfB, color='blue')
ax2.set_title('KDEs of subsampled Gaussians')
ax2.axvline(result, color='red')
plt.show()

输出

输出

评论

  • brentq似乎是最常见的根查找算法(因为它稳定且快速),但是根据您的数据,可能需要进行参数调整
  • 可以切换到其他优化算法
  • (出于建模目的,有一些简化;例如,通常应该对kde-bandwith选择进行交叉验证,以获得比我的示例更好的东西)

编辑:从fsolve切换到brentq,它应该更快,更稳定

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何找到两个函数的交集

来自分类Dev

找到两个双向链表的交集

来自分类Dev

序言:找到两个列表的交集?

来自分类Dev

Python:列表的两个列表的交集

来自分类Dev

如何找到两个git commit之间的交集?

来自分类Dev

在公差范围内找到两个矩阵的交集?

来自分类Dev

在tensorflow中找到两个边界框的交集?

来自分类Dev

基于值的两个对象数组的交集

来自分类Dev

如何获得两个jQuery对象的交集

来自分类Dev

获得两个对象的关键点交集的最佳方法?

来自分类Dev

TS中两个对象类型的深交集类型

来自分类Dev

通过对象属性两个列表的交集

来自分类Dev

检查两个对象之间的交集的算法

来自分类Dev

根据字段查找两个对象数组之间的交集

来自分类Dev

scipy gaussian_kde和循环数据

来自分类Dev

使用Mathematica查找两个函数的交集

来自分类Dev

返回两个TShape(包括TPath)的交集的函数?

来自分类Dev

使用Mathematica查找两个函数的交集

来自分类Dev

如何使用 scipy gaussian_kde 获得概率密度函数?

来自分类Dev

两个选择的交集

来自分类Dev

将二维gaussian_kde输出/网格保存到csv python

来自分类Dev

两个列表的Python交集保持重复

来自分类Dev

Python中两个嵌套列表的交集

来自分类Dev

Python-列表的两个列表的交集

来自分类Dev

Python中两个嵌套列表的交集

来自分类Dev

如何使用Python查找两个列表交集的索引?

来自分类Dev

Java,找到两个数组的交集

来自分类Dev

找到两个字典的交集

来自分类Dev

Python:两个函数之间的重叠(kde和normal的PDF)