Je suis plutôt nouveau dans ce domaine et je ne peux pas dire que j'ai une compréhension complète des concepts théoriques derrière cela. J'essaie de calculer la divergence KL entre plusieurs listes de points en Python. J'utilise http://scikit-learn.org/stable/modules/generated/sklearn.metrics.mutual_info_score.html pour essayer de le faire. Le problème que je rencontre est que la valeur retournée est la même pour 2 listes de nombres (son 1.3862943611198906). J'ai le sentiment que je fais une sorte d'erreur théorique ici, mais je ne peux pas la repérer.
values1 = [1.346112,1.337432,1.246655]
values2 = [1.033836,1.082015,1.117323]
metrics.mutual_info_score(values1,values2)
C'est un exemple de ce que j'exécute - juste que j'obtiens la même sortie pour n'importe quelle entrée. Tout conseil / aide serait apprécié!
sklearn.metrics.mutual_info_score([1.346112,1.337432,1.246655], [1.033836,1.082015,1.117323])
, j'obtiens la valeur1.0986122886681096
.Réponses:
Tout d'abord,
sklearn.metrics.mutual_info_score
implémente des informations mutuelles pour évaluer les résultats de clustering, et non une divergence Kullback-Leibler pure !La divergence KL (et toute autre mesure de ce type) s'attend à ce que les données d'entrée aient une somme de 1 . Sinon, ce ne sont pas des distributions de probabilité appropriées . Si vos données n'ont pas une somme de 1, il n'est probablement pas approprié d'utiliser la divergence KL! (Dans certains cas, il peut être admissible d'avoir une somme inférieure à 1, par exemple en cas de données manquantes.)
Notez également qu'il est courant d'utiliser des logarithmes en base 2. Cela ne donne qu'un facteur d'échelle constant dans la différence, mais les logarithmes en base 2 sont plus faciles à interpréter et ont une échelle plus intuitive (0 à 1 au lieu de 0 à log2 = 0,69314 ..., mesurant les informations en bits au lieu de nats).
comme nous pouvons le voir clairement, le résultat MI de sklearn est mis à l'échelle en utilisant des logarithmes naturels au lieu de log2. C'est un choix malheureux, comme expliqué ci-dessus.
La divergence Kullback-Leibler est fragile, malheureusement. Dans l'exemple ci-dessus, il n'est pas bien défini:
KL([0,1],[1,0])
provoque une division par zéro et tend vers l'infini. Il est également asymétrique .la source
scipy.stats.entropy
est utilisé, il normalisera les probabilités à un. À partir des documents ( scipy.github.io/devdocs/generated/scipy.stats.entropy.html ): "Cette routine normalisera pk et qk si elles ne totalisent pas 1."La fonction d'entropie de Scipy calculera la divergence KL si alimentent deux vecteurs p et q, chacun représentant une distribution de probabilité. Si les deux vecteurs ne sont pas des fichiers PDF, il se normalisera ensuite en premier.
Les informations mutuelles sont liées, mais pas identiques, à KL Divergence.
"Ces informations mutuelles pondérées sont une forme de divergence KL pondérée, qui est connue pour prendre des valeurs négatives pour certaines entrées, et il existe des exemples où les informations mutuelles pondérées prennent également des valeurs négatives"
la source
Je ne suis pas sûr de l'implémentation de ScikitLearn, mais voici une implémentation rapide de la divergence KL en Python:
Sortie:
0.775279624079
Il peut y avoir un conflit d'implémentation dans certaines bibliothèques, alors assurez-vous de lire leurs documents avant de les utiliser.
la source
0.775279624079
pour vos entrées et les métriques sklearn reviennent1.3862943611198906
. Toujours confus! Mais, semble inclure ces vérifications de valeur selon le qn, dans le script devrait faire :)Cette astuce évite le code conditionnel et peut donc fournir de meilleures performances.
la source
Considérez les trois échantillons suivants d'une distribution (s).
De toute évidence, les valeurs1 et les valeurs2 sont plus proches, nous nous attendons donc à ce que la mesure de l'
surprise
entropie soit plus faible par rapport aux valeurs3.Nous voyons la sortie suivante:
Nous voyons que cela a du sens parce que les valeurs entre les valeurs1 et les valeurs3 et les valeurs 2 et les valeurs 3 sont tout simplement plus drastiques dans le changement que les valeurs1 vers les valeurs 2. C'est ma validation pour comprendre KL-D et les packages qui peuvent être exploités pour cela.
la source