#python #entropy #information-theory #probability-distribution #scipy.stats
#python #энтропия #теория информации #распределение вероятности #scipy.stats
Вопрос:
Каждое непрерывное распределение в scipy.stats
поставляется с атрибутом, который вычисляет его дифференциальную энтропию : .entropy
. В отличие от нормального распределения ( norm
) и других, которые имеют решение для энтропии в закрытой форме, другие распределения должны полагаться на численное интегрирование.
Пытаясь выяснить, какую функцию .entropy
атрибут вызывает в этих случаях, я обнаружил вызываемую функцию _entropy
scipy.stats._distn_infrastructure.py
, которая выполняет это с integrate.quad(pdf)
помощью (числовое интегрирование).
Но когда я пытаюсь сравнить два подхода (атрибут .entropy
и численное интегрирование с функцией _entropy
), функция выдает ошибку:
AttributeError: 'rv_frozen' object has no attribute '_pdf'
Почему атрибут распределения .entropy
вычисляется нормально, но функция _entropy
выдает ошибку?
import numpy as np
from scipy import integrate
from scipy.stats import norm, johnsonsu
from scipy.special import entr
def _entropy(self, *args): #from _distn_infrastructure.py
def integ(x):
val = self._pdf(x, *args)
return entr(val)
# upper limit is often inf, so suppress warnings when integrating
# _a, _b = self._get_support(*args)
_a, _b = -np.inf, np.inf
with np.errstate(over='ignore'):
h = integrate.quad(integ, _a, _b)[0]
if not np.isnan(h):
return h
else:
# try with different limits if integration problems
low, upp = self.ppf([1e-10, 1. - 1e-10], *args)
if np.isinf(_b):
upper = upp
else:
upper = _b
if np.isinf(_a):
lower = low
else:
lower = _a
return integrate.quad(integ, lower, upper)[0]
Использование атрибута работает нормально:
print(johnsonsu(a=2.55,b=2.55).entropy())
ВОЗВРАТ 0.9503703091220894
Но функция не:
print(_entropy(johnsonsu(a=2.55,b=2.55)))
возвращает ошибку AttributeError: 'rv_frozen' object has no attribute '_pdf'
, хотя johnsonsu
имеет этот атрибут:
def _pdf(self, x, a, b):
# johnsonsu.pdf(x, a, b) = b / sqrt(x**2 1) *
# phi(a b * log(x sqrt(x**2 1)))
x2 = x*x
trm = _norm_pdf(a b * np.log(x np.sqrt(x2 1)))
return b*1.0/np.sqrt(x2 1.0)*trm
Какую функцию .entropy
тогда вызывает атрибут в случае johnsonsu
?
Ответ №1:
Вы хотите либо johnsonsu(a=2.55,b=2.55).entropy()
использовать замороженные дистрибутивы, либо johnsonsu.entropy(a=2.55,b=2.55)
иным образом.
Почему часть вашего вопроса в основном заключается в том, что начальное подчеркивание в _entropy означает «детали реализации, не вызывайте напрямую». Более длинный ответ заключается в том, что замороженные дистрибутивы оборачивают экземпляр дистрибутива (self.dist) и делегируют ему вызовы _pdf, _pmf и т.д.
РЕДАКТИРОВАТЬ: выполнение johnsonsu(a=2.55,b=2.55)
создает замороженный дистрибутив, rv_frozen. Не делайте этого, если вы не хотите повторно использовать экземпляр несколько раз: просто укажите параметры формы a, b в качестве аргументов функции энтропии.
Комментарии:
1. итак, как я могу заставить работать ручную
_entropy
функцию? и действительно ли это то, что.entropy
вызывает атрибут? Я не знаю, использую ли я замороженные дистрибутивы, поскольку я не знаю, что это такое. Все, что я думал, что я делаю, это оцениваюjohnsonsu
. Два примера кода, которые вы написали, не помогают различать замороженные и незамороженные, поскольку они оба работают так же хорошо, как и друг с другом