Número de posições ao calcular informações mútuas

10

Quero quantificar o relacionamento entre duas variáveis, A e B, usando informações mútuas. A maneira de calculá-lo é impedindo as observações (veja o código Python de exemplo abaixo). No entanto, quais fatores determinam qual número de posições é razoável? Eu preciso que a computação seja rápida, então não posso simplesmente usar muitas caixas para estar do lado seguro.

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
fonte

Respostas:

15

Não existe o melhor número de posições para estimar informações mútuas (MI) com histogramas. A melhor maneira é escolhê-lo via validação cruzada, se puder, ou confiar em uma regra de ouro. Esta é a razão pela qual muitos outros estimadores de IM que não são baseados em histogramas foram propostos.

O número de posições dependerá do número total de pontos de dados . Você deve evitar muitos compartimentos para evitar erros de estimativa para a distribuição conjunta entre as duas variáveis. Você também deve evitar muito poucos compartimentos para poder capturar o relacionamento entre as duas variáveis. Dado que gera um histograma 2D com compartimentos de largura igual para ambos e eu escolheria pessoalmente: Nesse caso, em média, para duas variáveis ​​aleatórias distribuídas uniformemente, você terá pelo menos pontos para cada célula do histograma: nnp.histogram2d(x, y, D)Dxy

D=n/5
5
nDXDY5nD25D2n/5D=n/5
Essa é uma opção possível que simula a abordagem de particionamento adaptativo proposta em (Cellucci, 2005) . A última abordagem é frequentemente usada para estimar o IM para inferir redes genéticas: por exemplo, no MIDER .

Se você tiver muitos pontos de dados nenhum valor em falta, não se preocupe muito em encontrar o melhor número de posições; por exemplo, se . Se não for esse o caso, considere corrigir o MI para amostras finitas. (Steuer et al., 2002) discute alguma correção para o MI para a tarefa de inferência de redes genéticas.nn=100,000


Estimar o número de posições para um histograma é um problema antigo. Você pode estar interessado nesta palestra de Lauritz Dieckman sobre a estimativa do número de caixas para MI. Essa palestra é baseada em um capítulo do livro de Mike X Cohen sobre séries temporais neurais.

Você pode escolher e independente e usar a regra geral usada para estimar o número de posições nos histogramas 1D.DXDY

Regra de Freedman-Diaconis (sem suposição sobre a distribuição): onde é a diferença entre o quantil 75 e o quantil 25. Veja esta questão relacionada no SE .

DX=maxXminX2IQRn1/3
IQR

Regra de Scott (suposição de normalidade): que é o desvio padrão para .

DX=maxXminX3.5sXn1/3
sXX

Regra de (pode subestimar o número de posições, mas é bom para grandes ): n

DX=1+log2n

É difícil estimar corretamente o IM com histogramas. Você pode então escolher um estimador diferente:

  • O estimador NN de Kraskov , que é um pouco menos sensível à escolha de parâmetros: ou vizinhos mais próximos é frequentemente usado como padrão. Artigo : (Kraskov, 2003)kk=4k=6
  • Estimativa de MI com Kernels (Moon, 1995) .

Existem muitos pacotes para estimar o MI:

  • Caixa de ferramentas de estimativa de entropia não paramétrica para Python. site .
  • Kit de ferramentas de dinâmica da informação em Java, mas também disponível para Python. site .
  • Caixa de ferramentas ITE no Matlab. site .
Simone
fonte
1

Eu prefiro minepyobter e estimar informações mútuas em python.

Você pode ver os detalhes de implementação do pacote aqui e um código de exemplo aqui . Para facilitar a referência, copio e colo o exemplo e sua saída aqui:

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)

O que fornece isso como saída:

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

Minha experiência é que os resultados são sensíveis alphae o valor padrão .6é razoável. No entanto, meus dados reais alpha=.3são muito mais rápidos e as informações mútuas estimadas têm uma correlação muito alta com o caso alpha=.6. Portanto, caso você esteja usando o MI para selecionar aqueles com um IM alto, basta usar um menor alphae usar os valores mais altos como substituto, com uma boa precisão.

adrin
fonte
Obrigado! Você comparou o minepy com o sklearn para estimativa de MI?
Pir 4/15
Não, eu não tenho. Não sei por que não!
adrin
Acabei de fazer uma comparação entre sklearn e minepy (alfa = 0,3 e alfa = 0,6). Os resultados são muito diferentes! Uma vez que é tão fácil que você provavelmente deve também verificar os seus resultados usando ambas as bibliotecas :)
pir
2
MIC não é igual à informação mútua (MI). São duas coisas completamente diferentes.
Simone
11
Sim claro. No artigo original do MIC, há muitas comparações entre MI e MIC: uvm.edu/~cdanfort/csc-reading-group/… MIC mostra que ele pode ser usado como proxy da quantidade de ruído para um relacionamento funcional - propriedade que é chamada 'equitabilidade' no artigo original. No entanto, o IM ainda é uma medida muito boa de dependência para muitas tarefas: por exemplo, seleção de recurso ou inferência de rede genética. Também é mais rápido estimar do que o MIC.
Simone