Eu sou bastante novo nisso e não posso dizer que tenho uma compreensão completa dos conceitos teóricos por trás disso. Estou tentando calcular a divergência KL entre várias listas de pontos em Python. Estou usando http://scikit-learn.org/stable/modules/generated/sklearn.metrics.mutual_info_score.html para tentar fazer isso. O problema que eu estou enfrentando é que o valor retornado é o mesmo para quaisquer 2 listas de números (seu 1.3862943611198906). Sinto que estou cometendo algum tipo de erro teórico aqui, mas não consigo identificá-lo.
values1 = [1.346112,1.337432,1.246655]
values2 = [1.033836,1.082015,1.117323]
metrics.mutual_info_score(values1,values2)
Esse é um exemplo do que estou executando - apenas que estou obtendo a mesma saída para qualquer 2 entradas. Qualquer conselho / ajuda seria apreciada!
python
clustering
scikit-learn
Nanda
fonte
fonte
sklearn.metrics.mutual_info_score([1.346112,1.337432,1.246655], [1.033836,1.082015,1.117323])
, recebo o valor1.0986122886681096
.Respostas:
Em primeiro lugar,
sklearn.metrics.mutual_info_score
implementa informações mútuas para avaliar os resultados do agrupamento, não a divergência pura de Kullback-Leibler!A divergência de KL (e qualquer outra medida) espera que os dados de entrada tenham uma soma de 1 . Caso contrário, elas não são distribuições de probabilidade adequadas . Se seus dados não tiverem a soma de 1, provavelmente não é apropriado usar a divergência de KL! (Em alguns casos, pode ser admissível ter uma soma menor que 1, por exemplo, no caso de dados ausentes.)
Observe também que é comum usar logaritmos da base 2. Isso gera apenas um fator de escala constante na diferença, mas os logaritmos da base 2 são mais fáceis de interpretar e têm uma escala mais intuitiva (0 a 1 em vez de 0 a log2 = 0,69314 ..., medindo as informações em bits em vez de nats).
como podemos ver claramente, o resultado do MI do sklearn é escalado usando logaritmos naturais em vez de log2. Esta é uma escolha infeliz, como explicado acima.
Infelizmente, a divergência entre Kullback e Leibler é frágil. No exemplo acima, não está bem definido:
KL([0,1],[1,0])
causa uma divisão por zero e tende ao infinito. Também é assimétrico .fonte
scipy.stats.entropy
usado, normalizará as probabilidades para um. Nos documentos ( scipy.github.io/devdocs/generated/scipy.stats.entropy.html ): "Esta rotina normalizará pk e qk se não somarem 1."A função de entropia de Scipy calculará a divergência de KL se alimentar dois vetores peq, cada um representando uma distribuição de probabilidade. Se os dois vetores não forem PDFs, ele será normalizado primeiro.
As informações mútuas estão relacionadas, mas não são iguais , à KL Divergence.
"Essas informações mútuas ponderadas são uma forma de divergência KL ponderada, que é conhecida por receber valores negativos para algumas entradas, e há exemplos em que as informações mútuas ponderadas também assumem valores negativos"
fonte
Não tenho certeza da implementação do ScikitLearn, mas aqui está uma rápida implementação da divergência de KL no Python:
Saída:
0.775279624079
Pode haver conflito de implementação em algumas bibliotecas, portanto, leia os documentos antes de usar.
fonte
0.775279624079
para suas entradas e as métricas do sklearn retornam1.3862943611198906
. Confuso ainda! Mas, parece que incluindo os cheques de valor de acordo com o qn, no script deve fazer :)Esse truque evita código condicional e, portanto, pode fornecer melhor desempenho.
fonte
Considere as três seguintes amostras de uma (s) distribuição (ões).
Claramente, os valores1 e os valores2 estão mais próximos, por isso esperamos que a medida
surprise
ou a entropia seja menor quando comparado aos valores3.Vemos a seguinte saída:
Vemos que isso faz sentido porque os valores entre os valores1 e os valores3 e os valores 2 e os valores 3 são simplesmente mais drásticos na mudança do que os valores1 para os valores 2. Essa é minha validação para entender o KL-D e os pacotes que podem ser aproveitados para isso.
fonte