Количество бинов при вычислении взаимной информации

10

Я хочу количественно определить отношения между двумя переменными, A и B, используя взаимную информацию. Способ вычислить его - связать наблюдения (см. Пример кода Python ниже). Однако какие факторы определяют, какое количество лотков является разумным? Мне нужно, чтобы вычисления были быстрыми, поэтому я не могу просто использовать много контейнеров, чтобы быть в безопасности.

from sklearn.metrics import mutual_info_score

def calc_MI(x, y, bins):
    c_xy = np.histogram2d(x, y, bins)[0]
    mi = mutual_info_score(None, None, contingency=c_xy)
    return mi
PIR
источник

Ответы:

15

Не существует лучшего числа бинов для оценки взаимной информации (МИ) с гистограммами. Лучший способ - выбрать его через перекрестную проверку, если можете, или полагаться на эмпирическое правило. По этой причине было предложено много других оценок МИ, которые не основаны на гистограммах.

Количество бинов будет зависеть от общего количества точек данных . Вы должны стараться избегать слишком большого количества бинов, чтобы избежать ошибок оценки для совместного распределения между двумя переменными. Вам также следует избегать слишком малого количества корзин, чтобы можно было зафиксировать взаимосвязь между двумя переменными. Учитывая, что генерирует 2D гистограмму с одинаковыми значениями ширины для обоих, и я бы лично выбрал: В этом случае в среднем для двух равномерно распределенных случайных величин у вас будет не менее точек для каждая ячейка гистограммы: D = nnp.histogram2d(x, y, D)Dxy5 н

D=n/5
5
nDXDY5nD25D2n/5D=n/5
Это один из возможных вариантов, который имитирует подход адаптивного разделения, предложенный в (Cellucci, 2005) . Последний подход часто используется для оценки ИМ, чтобы вывести генетические сети: например, в MIDER .

Если у вас много точек данных и нет пропущенных значений, вам не стоит слишком беспокоиться о поиске наилучшего количества бинов; например, если . Если это не так, вы можете исправить MI для конечных выборок. (Steuer et al., 2002) обсуждает некоторую коррекцию инфаркта миокарда для задачи вывода из генетической сети.п = 100 , 000nn=100,000


Оценка количества бинов для гистограммы - старая проблема. Вас может заинтересовать этот доклад Лауритца Дикмана об оценке количества бинов для ИМ. Этот доклад основан на главе в книге Майка X Коэна о нейронных временных рядах.

Вы можете выбрать и независимо и использовать эмпирическое правило, используемое для оценки количества бинов в 1D гистограммах.D YDXDY

Правило Фридмана-Диакониса (без предположений о распределении): где - это разница между 75-квантилем и 25-квантилем. Посмотрите на этот связанный вопрос в SE .

DX=maxXminX2IQRn1/3
IQR

Правило Скотта (предположение о нормальности): где - стандартное отклонение для .

DX=maxXminX3.5sXn1/3
sXX

Правило Стерджеса (может недооценивать количество бинов, но хорошо для больших ): n

DX=1+log2n

Трудно правильно оценить МИ по гистограммам. Затем вы можете выбрать другой оценщик:

  • Оценка Краскова NN, которая немного менее чувствительна к выбору параметров: или ближайших соседей часто используется по умолчанию. Бумага: (Красков, 2003)kk=4k=6
  • Оценка МИ с ядрами (Moon, 1995) .

Существует множество пакетов для оценки MI:

  • Непараметрический инструментарий оценки энтропии для Python. сайт .
  • Информационно-динамический инструментарий на Java, но доступен и для Python. сайт .
  • ITE инструментарий в Matlab. сайт .
Симона
источник
1

Я предпочитаю minepyполучать и оценивать взаимную информацию на питоне.

Вы можете увидеть детали реализации пакета здесь и пример кода здесь . Для удобства я скопировал и вставил пример, и он выводится здесь:

import numpy as np
from minepy import MINE

def print_stats(mine):
    print "MIC", mine.mic()
    print "MAS", mine.mas()
    print "MEV", mine.mev()
    print "MCN (eps=0)", mine.mcn(0)
    print "MCN (eps=1-MIC)", mine.mcn_general()

x = np.linspace(0, 1, 1000)
y = np.sin(10 * np.pi * x) + x
mine = MINE(alpha=0.6, c=15)
mine.compute_score(x, y)

print "Without noise:"
print_stats(mine)
print

np.random.seed(0)
y +=np.random.uniform(-1, 1, x.shape[0]) # add some noise
mine.compute_score(x, y)

print "With noise:"
print_stats(mine)

Что дает это в качестве вывода:

Without noise:
MIC 1.0
MAS 0.726071574374
MEV 1.0
MCN (eps=0) 4.58496250072
MCN (eps=1-MIC) 4.58496250072

With noise:
MIC 0.505716693417
MAS 0.365399904262
MEV 0.505716693417
MCN (eps=0) 5.95419631039
MCN (eps=1-MIC) 3.80735492206

По моему опыту, результаты чувствительны alpha, и значение по умолчанию .6является разумным. Тем не менее, по моим реальным данным alpha=.3намного быстрее, и предполагаемая взаимная информация имеет действительно высокую корреляцию с тем, что alpha=.6. Поэтому, если вы используете MI для выбора alphaзначений с высоким MI, вы можете просто использовать меньшее и использовать самые высокие значения в качестве замены с хорошей точностью.

Adrin
источник
Спасибо! Вы сравнивали minepy со sklearn для оценки MI?
пир
Нет, не имею Я не уверен, почему нет, хотя!
Адрин
Я только что сделал сравнение sklearn и minepy (и alpha = 0.3, и alpha = 0.6). Результаты очень разные! Так как это так просто, вы, вероятно, должны также проверить свои результаты, используя обе библиотеки :)
pir
2
MIC не равен взаимной информации (MI). Это две совершенно разные вещи.
Симона
1
Да, конечно. В оригинальной статье MIC есть много сравнений между MI и MIC: uvm.edu/~cdanfort/csc-reading-group/… MIC показывает, что его можно использовать в качестве показателя количества шума для функциональных отношений - свойство, которое называется «справедливость» в оригинальной статье. Тем не менее, ИМ по-прежнему является очень хорошей мерой зависимости для многих задач: например, отбор признаков или вывод генетической сети. Это также быстрее оценить, чем MIC.
Симона