首页 > 解决方案 > n维数据估计经验分布的累积概率

问题描述

问题

我有一个包含 4 个数字特征和 1000 个数据点的数据集。值的分布是未知的(numpy randint 生成统一的整数,但这只是为了说明)。给定新的数据点(4 个数字),我想找出这个特定数据点的累积概率(单个数字)。

import numpy as np

data = np.random.randint(1, 100, size=(1000, 4))
array([[28, 52, 91, 66],
       [78, 94, 95, 12],
       [60, 63, 43, 37],
       ...,
       [81, 68, 45, 46],
       [14, 38, 91, 46],
       [37, 51, 68, 97]])

new_data = np.random.randint(1, 100, size=(1, 4))
array([[75, 24, 39, 94]])

我试过了:

西皮

可以估计pdf,不知道怎么估计累积概率。可能的方法是 monte-carlo sim 或集成(scipy.integrate.nquad),这对于我的情况来说太慢了Integrate 2D kernel density estimation 。

import scipy.stats
kde = scipy.stats.gaussian_kde(data.T)
kde.pdf(new_data)

Scikit-学习

同上,不知道如何估计累积概率。

from sklearn.neighbors import KernelDensity
model = KernelDensity()
model.fit(data)
np.exp(model.score_samples(new_data))

统计模型

无法存档任何内容,因为它只接受一维数据。

from statsmodels.distributions.empirical_distribution import ECDF
ecdf = ECDF(data[:, 0])
ecdf(new_data[0][0])

问题是,是否有一种快速有效的方法来估计具有提供的 scipy 或 sklearn(最好)模型的 4 维数据点的累积概率?

我是朝着正确的方向前进还是有完全不同的方法来解决这个问题?也许变分自动编码器是要走的路?有没有简单的方法来解决这个问题?

标签: pythonscikit-learnscipyprobability-densitykernel-density

解决方案


一个点的多元 ecdf 只会计算值小于该点的观察值的分数。

类似于以下内容

np.random.seed(0)
data = np.random.randint(1, 100, size=(1000, 4))
new_data = np.random.randint(1, 100, size=(2, 4))

def ecdf_mv(new_data, data):
    new_data = np.atleast_2d(new_data)
    ecdf = []
    for row in new_data:
        ecdf.append((data <= row).all(1).mean())

    return np.asarray(ecdf)

ecdf_mv(new_data, data)

array([0.039, 0.002])

一些检查:

ecdf_mv(np.ones(4) * 100 / 2, data), 0.5**4
(array([0.067]), 0.0625)

marginal = 100 * np.ones((4, 4)) - 50 * np.eye(4)
ecdf_mv(marginal, data)
array([0.521, 0.515, 0.502, 0.54 ])

在单变量情况下,我们可以对数据进行排序以获得快速算法来计算原始点的 ecdf。
我不知道是否有一种数据结构或算法在计算上比蛮力比较更有效,如果 ecdf 必须在很多点上进行评估。


推荐阅读