scipy.stats.differential_entropy

scipy.stats.differential_entropy(values, *, window_length=None, base=None, axis=0, method='auto')[源代码]

给定一个分布样本,估计微分熵。

有几种估算方法可以使用 method 参数。默认情况下,根据样本大小选择方法。

参数
values序列

连续分布的样本。

window_length整型,可选

用于计算Vasicek估计的窗口长度。必须是介于样本大小1和一半之间的整数。如果 None (默认值),它使用启发式的值

\[\Left\lFloor\sqrt{n}+0.5\Right\r Floor\]

哪里 \(n\) 是样本大小。这个启发式最初是在#年提出的。 [2] 并在文学作品中变得普遍。

base浮动,可选

要使用的对数底,默认为 e (自然对数)。

axis整型,可选

沿其计算微分熵的轴。默认值为0。

method{‘Vasicek’,‘van es’,‘Ebrahimi’,‘Correa’,‘auto’},可选

用于从样本中估计微分熵的方法。默认值为 'auto' 。有关详细信息,请参阅注释。

退货
entropy浮动

计算出的微分熵。

注意事项

此函数将在极限内收敛到真正的微分熵

\[n\to\infty,\quad m\to\infty,\quad\frac{m}{n}\to 0\]

最优选择 window_length 给定样本的大小取决于(未知)分布。通常,分布密度越平滑, window_length [1].

以下选项可用于 method 参数。

  • 'vasicek' 使用中提供的估计器 [1]. 这是最早也是最有影响力的微分熵估计器之一。

  • 'van es' 中给出的经偏差校正的估计器 [3], 这不仅是一致的,而且在某些条件下是渐近正态的。

  • 'ebrahimi' 使用中提供的估计器 [4], 仿真结果表明,该方法比Vasicek估计器具有更小的偏差和均方误差。

  • 'correa' 使用中提供的估计器 [5] 基于局部线性回归。在一项模拟研究中,它的均方误差始终比Vasiceck估计器小,但计算成本更高。

  • 'auto' 自动选择方法(默认)。目前,此选项选择 'van es' 对于非常小的样本(<10), 'ebrahimi' 适用于中等样本量(11-1000),以及 'vasicek' 用于更大的样本,但此行为可能会在将来的版本中更改。

所有估计器都按照中所述实现 [6].

参考文献

1(1,2)

Vasicek,O.(1976)。基于样本熵的正态性检验。“皇家统计学会学报:B辑(方法论)”,第38(1),54-59页。

2

书名/作者:Reinessi,and Wirczorkowski,R.(1999)。基于熵的指数拟合优度检验。统计通讯-理论与方法,28(5),1183-1202。

3

范斯,B.(1992)。用一类基于间距的统计量估计与密度有关的泛函。斯堪的纳维亚统计杂志,61-72。

4

张建民,N,Pflughoeft,K.,&Soofi,E.S.(1994)。样本熵的两个度量。统计与概率通讯,20(3),225-234。

5

Correa,J.C.(1995)。一种新的熵估计器。统计通讯-理论与方法,24(10),2439-2449。

6

Noughabi,H.A.(2015)。使用数值方法进行熵估计。数据科学年鉴,2(2),231-241。https://link.springer.com/article/10.1007/s40745-015-0045-9

示例

>>> from scipy.stats import differential_entropy, norm

标准正态分布的熵:

>>> rng = np.random.default_rng()
>>> values = rng.standard_normal(100)
>>> differential_entropy(values)
1.3407817436640392

与真实熵进行比较:

>>> float(norm.entropy())
1.4189385332046727

对于5到1000之间的几个样本大小,比较 'vasicek''van es' ,以及 'ebrahimi' 方法。具体地说,比较估计和分布的真实微分熵之间的均方根误差(超过1000次试验)。

>>> from scipy import stats
>>> import matplotlib.pyplot as plt
>>>
>>>
>>> def rmse(res, expected):
...     '''Root mean squared error'''
...     return np.sqrt(np.mean((res - expected)**2))
>>>
>>>
>>> a, b = np.log10(5), np.log10(1000)
>>> ns = np.round(np.logspace(a, b, 10)).astype(int)
>>> reps = 1000  # number of repetitions for each sample size
>>> expected = stats.expon.entropy()
>>>
>>> method_errors = {'vasicek': [], 'van es': [], 'ebrahimi': []}
>>> for method in method_errors:
...     for n in ns:
...        rvs = stats.expon.rvs(size=(reps, n), random_state=rng)
...        res = stats.differential_entropy(rvs, method=method, axis=-1)
...        error = rmse(res, expected)
...        method_errors[method].append(error)
>>>
>>> for method, errors in method_errors.items():
...     plt.loglog(ns, errors, label=method)
>>>
>>> plt.legend()
>>> plt.xlabel('sample size')
>>> plt.ylabel('RMSE (1000 trials)')
>>> plt.title('Entropy Estimator Error (Exponential Distribution)')
../../_images/scipy-stats-differential_entropy-1.png