differential_entropy#
- scipy.stats.differential_entropy(values, *, window_length=None, base=None, axis=0, method='auto', nan_policy='propagate', keepdims=False)[source]#
給定分佈的樣本,估計微分熵。
有幾種估計方法可使用 method 參數。預設情況下,會根據樣本大小選擇方法。
- 參數:
- values序列
來自連續分佈的樣本。
- window_lengthint,選用
用於計算 Vasicek 估計值的視窗長度。必須是介於 1 和樣本大小一半之間的整數。如果為
None
(預設值),則使用啟發式值\[\left \lfloor \sqrt{n} + 0.5 \right \rfloor\]其中 \(n\) 是樣本大小。此啟發式方法最初在 [2] 中提出,並且已在文獻中變得常見。
- basefloat,選用
要使用的對數底數,預設為
e
(自然對數)。- axisint 或 None,預設值:0
如果為整數,則為沿其計算統計量的輸入軸。輸入的每個軸切片(例如,列)的統計量將出現在輸出的對應元素中。如果為
None
,則輸入將在計算統計量之前被展平。- method{‘vasicek’, ‘van es’, ‘ebrahimi’, ‘correa’, ‘auto’},選用
用於從樣本估計微分熵的方法。預設值為
'auto'
。有關更多資訊,請參閱註釋。- nan_policy{‘propagate’, ‘omit’, ‘raise’}
定義如何處理輸入的 NaN。
propagate
:如果在軸切片(例如,列)中存在 NaN,則沿該軸切片計算統計量,則輸出的對應條目將為 NaN。omit
:在執行計算時將省略 NaN。如果軸切片中剩餘的資料不足以計算統計量,則輸出的對應條目將為 NaN。raise
:如果存在 NaN,將引發ValueError
。
- keepdimsbool,預設值:False
如果將其設定為 True,則縮減的軸將保留在結果中,作為大小為 1 的維度。使用此選項,結果將正確地廣播到輸入陣列。
- 返回:
- entropyfloat
計算出的微分熵。
註釋
此函數將在以下極限中收斂到真實的微分熵
\[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'
自動選擇方法(預設值)。目前,這會為非常小的樣本(<10)選擇'van es'
,為中等樣本大小(11-1000)選擇'ebrahimi'
,為較大樣本選擇'vasicek'
,但此行為可能會在未來版本中更改。
所有估計器均按照 [6] 中的描述實作。
從 SciPy 1.9 開始,
np.matrix
輸入(不建議用於新程式碼)在執行計算之前會轉換為np.ndarray
。在這種情況下,輸出將是純量或適當形狀的np.ndarray
,而不是 2Dnp.matrix
。同樣地,雖然會忽略遮罩陣列的遮罩元素,但輸出將是純量或np.ndarray
,而不是mask=False
的遮罩陣列。參考文獻
[1] (1,2)Vasicek, O. (1976). A test for normality based on sample entropy. Journal of the Royal Statistical Society: Series B (Methodological), 38(1), 54-59.
[2]Crzcgorzewski, P., & Wirczorkowski, R. (1999). Entropy-based goodness-of-fit test for exponentiality. Communications in Statistics-Theory and Methods, 28(5), 1183-1202.
[3]Van Es, B. (1992). Estimating functionals related to a density by a class of statistics based on spacings. Scandinavian Journal of Statistics, 61-72.
[4]Ebrahimi, N., Pflughoeft, K., & Soofi, E. S. (1994). Two measures of sample entropy. Statistics & Probability Letters, 20(3), 225-234.
[5]Correa, J. C. (1995). A new estimator of entropy. Communications in Statistics-Theory and Methods, 24(10), 2439-2449.
[6]Noughabi, H. A. (2015). Entropy Estimation Using Numerical Methods. Annals of Data Science, 2(2), 231-241. https://link.springer.com/article/10.1007/s40745-015-0045-9
範例
>>> import numpy as np >>> 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)')