Энтропия Шеннона на массиве, содержащем нули

Я использую следующий код, чтобы вернуть энтропию Шеннона для массива, представляющего распределение вероятностей.

A = np.random.randint(10, size=10)

pA = A / A.sum()
Shannon2 = -np.sum(pA*np.log2(pA))

Это отлично работает, если массив не содержит нулей.

Пример:

Input: [2 3 3 3 2 1 5 3 3 4]
Output: 3.2240472715

Однако, если массив содержит нули, энтропия Шеннона дает nan

Пример:

Input:[7 6 6 8 8 2 8 3 0 7]
Output: nan

Я получаю два RuntimeWarnings:

1) RuntimeWarning: деление на ноль встречается в log2

2) RuntimeWarning: недопустимое значение, обнаруженное при умножении

Есть ли способ изменить код, чтобы включить нули? Я просто не уверен, что их полное удаление повлияет на результат. В частности, если вариация будет больше из-за большей частоты в распределении.


person Community    schedule 23.04.2018    source источник
comment
Удаление нулей в более поздней части вычисления не равнозначно игнорированию нулей. Влияние нуля исходит от pA = A / A.sum(). Результат A.sum() меньше из-за присутствия нулей.   -  person fasta    schedule 23.04.2018


Ответы (2)


Я думаю, вы хотите использовать nansum для подсчета нанов как нуля:

A = np.random.randint(10, size=10)
pA = A / A.sum()
Shannon2 = -np.nansum(pA*np.log2(pA))
person basaundi    schedule 23.04.2018
comment
Для Python 2.7 этот код также требует: from __future__ import division для принудительного нецелочисленного деления. См.: заголовок stackoverflow.com/questions/1267869/ - person fasta; 23.04.2018

Самый простой и часто используемый способ — игнорировать нулевые вероятности и вычислять энтропию Шеннона на оставшихся значениях.

Попробуйте следующее:

import numpy as np
A = np.array([1.0, 2.0, 0.0, 5.0, 0.0, 9.0])
A = np.array(filter(lambda x: x!= 0, A))
pA = A / A.sum()
Shannon2 = -np.sum(pA * np.log2(pA))
person Arpit Kathuria    schedule 23.04.2018