Python 图像的核密度估计

Python 图像的核密度估计,python,numpy,matplotlib,scikit-learn,Python,Numpy,Matplotlib,Scikit Learn,我有一组点[x1,y1][x2,y2]…[xn,yn]。我需要在2D图像中使用核密度估计来显示它们。如何执行此操作?我指的是下面的代码,它有点混乱。寻找一个简单的解释 我将继续沿着相同的路径绘制核密度估计的PDF轮廓。但是,这可能无法提供所需的信息,因为PDF的值信息量不大。相反,我宁愿计算最小卷级别集。从给定的概率水平来看,最小水平集是包含该分布部分的域。如果我们考虑由PDF的给定值定义的域,则这必须对应于未知的PDF值。查找此PDF值的问题是通过反演完成的 基于给定的样本,自然的想法是基于

我有一组点[x1,y1][x2,y2]…[xn,yn]。我需要在2D图像中使用核密度估计来显示它们。如何执行此操作?我指的是下面的代码,它有点混乱。寻找一个简单的解释


我将继续沿着相同的路径绘制核密度估计的PDF轮廓。但是,这可能无法提供所需的信息,因为PDF的值信息量不大。相反,我宁愿计算最小卷级别集。从给定的概率水平来看,最小水平集是包含该分布部分的域。如果我们考虑由PDF的给定值定义的域,则这必须对应于未知的PDF值。查找此PDF值的问题是通过反演完成的

基于给定的样本,自然的想法是基于核平滑计算近似分布,就像您所做的那样。然后,对于中的任何分发,computeMinimumVolumeLevelSetWithThreshold方法计算所需的级别集和相应的PDF值

让我们看看它在实践中是如何进行的。为了得到一个有趣的例子,我从两个高斯分布的混合中创建了一个2D分布

import openturns as ot
# Create a gaussian
corr = ot.CorrelationMatrix(2)
corr[0, 1] = 0.2
copula = ot.NormalCopula(corr)
x1 = ot.Normal(-1., 1)
x2 = ot.Normal(2, 1)
x_funk = ot.ComposedDistribution([x1, x2], copula)

# Create a second gaussian
x1 = ot.Normal(1.,1)
x2 = ot.Normal(-2,1)
x_punk = ot.ComposedDistribution([x1, x2], copula)

# Mix the distributions
mixture = ot.Mixture([x_funk, x_punk], [0.5,1.])

# Generate the sample
sample = mixture.getSample(500)
这就是你的问题开始的地方。从多维Scott规则创建二元核平滑只需要两行

factory = ot.KernelSmoothing()
distribution = factory.build(sample)
只要画出这个估计分布的轮廓就很简单了

distribution.drawPDF()
产生:

这显示了分布的形状。然而,PDF的轮廓并没有传达关于初始样本的很多信息

计算最小体积水平集的反演需要一个初始样本,当维度大于1时,该样本由蒙特卡罗方法生成。默认的样本量(接近16000)是可以的,但我通常自己设置它,以确保我了解我所做的事情

ot.ResourceMap.SetAsUnsignedInteger(
    "Distribution-MinimumVolumeLevelSetSamplingSize", 1000
)
alpha = 0.9
levelSet, threshold = distribution.computeMinimumVolumeLevelSetWithThreshold(alpha)
threshold
变量包含问题的解决方案,即对应于最小音量设置的PDF值

最后一步是绘制样本和相应的最小体积水平集

def drawLevelSetContour2D(
    distribution, numberOfPointsInXAxis, alpha, threshold, sample
):
    """
    Compute the minimum volume LevelSet of measure equal to alpha and get the
    corresponding density value (named threshold).
    Draw a contour plot for the distribution, where the PDF is equal to threshold.
    """
    sampleSize = sample.getSize()
    X1min = sample[:, 0].getMin()[0]
    X1max = sample[:, 0].getMax()[0]
    X2min = sample[:, 1].getMin()[0]
    X2max = sample[:, 1].getMax()[0]
    xx = ot.Box([numberOfPointsInXAxis], ot.Interval([X1min], [X1max])).generate()
    yy = ot.Box([numberOfPointsInXAxis], ot.Interval([X2min], [X2max])).generate()
    xy = ot.Box(
        [numberOfPointsInXAxis, numberOfPointsInXAxis],
        ot.Interval([X1min, X2min], [X1max, X2max]),
    ).generate()
    data = distribution.computePDF(xy)
    graph = ot.Graph("", "X1", "X2", True, "topright")
    labels = ["%.2f%%" % (100 * alpha)]
    contour = ot.Contour(xx, yy, data, ot.Point([threshold]), ot.Description(labels))
    contour.setColor("black")
    graph.setTitle(
        "%.2f%% of the distribution, sample size = %d" % (100 * alpha, sampleSize)
    )
    graph.add(contour)
    cloud = ot.Cloud(sample)
    graph.add(cloud)
    return graph
我们最后绘制水平集的轮廓,每个轴上有50个点

numberOfPointsInXAxis = 50
drawLevelSetContour2D(mixture, numberOfPointsInXAxis, alpha, threshold, sample)
下图绘制了样本和域的轮廓,其中包含根据核平滑分布估计的90%总体。该区域之外的任何点都可以被视为异常值,尽管我们可能会为此使用更高的alpha=0.95值

完整示例在中详细介绍。本文将其应用于随机过程。这里使用的思想在:Rob J Hyndman和Han Lin Shang中有详细介绍。功能数据的彩虹图、BagPlot和BoxPlot。计算和图形统计杂志,19:29-452009

numberOfPointsInXAxis = 50
drawLevelSetContour2D(mixture, numberOfPointsInXAxis, alpha, threshold, sample)