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)')