La façon la plus rapide pour calculer l'entropie en Python
Dans mon projet j'ai besoin de calculer l'entropie de 0-1 vecteurs de nombreuses fois. Voici mon code:
def entropy(labels):
""" Computes entropy of 0-1 vector. """
n_labels = len(labels)
if n_labels <= 1:
return 0
counts = np.bincount(labels)
probs = counts[np.nonzero(counts)] / n_labels
n_classes = len(probs)
if n_classes <= 1:
return 0
return - np.sum(probs * np.log(probs)) / np.log(n_classes)
Est-il un moyen plus rapide?
- Qu'est ce qu'une longueur typique de
labels
? - La longueur n'est pas fixe..
- Il serait utile pour l'analyse comparative de connaître les valeurs typiques de
labels
. Silabels
est trop court, un pur python de la mise en œuvre pourrait être plus rapide que l'utilisation de NumPy.
Vous devez vous connecter pour publier un commentaire.
@Sanjeet Gupta réponse est bonne, mais pourrait être condensé. Cette question est précisément de demander à propos de la "plus Rapide" chemin, mais je ne vois que des fois sur une réponse donc je vais poster une comparaison de l'utilisation de scipy et numpy à l'affiche originale du entropy2 réponse avec de légères modifications.
Quatre approches différentes: scipy/numpy, numpy/math, pandas/numpy, numpy
Timeit opérations:
Timeit résultats:
Gagnant: numpy/math (entropy2)
Il est également intéressant de noter que le
entropy2
la fonction ci-dessus peut traiter numérique ET des données de texte. ex:entropy2(list('abcdefabacdebcab'))
. L'affiche originale de la réponse est à partir de 2013 et a un cas d'utilisation pour binning ints mais il ne fonctionne pas pour le texte.Method: eta, Avg.: 10.461799
. Comme quelqu'un l'a suggéré, je me demande si vous avez fait les tests de temps système de l'appel ici.numpy
+scipy
est le plus propre pour moi.Avec les données comme un
pd.Series
etscipy.stats
, le calcul de l'entropie d'une quantité donnée est assez simple:Remarque:
scipy.stats
permettra de normaliser les données fournies, donc ce n'est pas nécessaire de le faire de manière explicite, c'est à dire le passage d'un tableau de numération fonctionne très bien.À la suite de la suggestion de unutbu je crée un pur python de mise en œuvre.
Le point qui me manquait était que les étiquettes est un grand tableau, cependant probs est de 3 ou 4 éléments de long. À l'aide de pure python mon application est maintenant deux fois plus vite.
Une réponse qui ne repose pas sur numpy, soit:
Ce acceptons n'importe quel type de données vous pouvez jeter à elle:
La réponse fournie par @Jarad suggéré timings ainsi. À cette fin:
Timeit résultats: (je crois que c'est ~4x plus rapide que la meilleure numpy approche)
Ma fonction préférée pour l'entropie est la suivante:
Je suis toujours à la recherche d'une jolie manière à éviter le dict -> valeurs -> liste -> np.tableau de conversion. Commentaires à nouveau si je l'ai trouvé.
labels.count(x)/len(labels)
devrait êtrelabels.count(x)/float(len(labels))
Voici ma démarche:
Uniformément répartie de données (haute entropie):
Entropie de Shannon de calcul étape par étape:
One-liner (en supposant que
import collections
):Une fonction appropriée:
Des cas de Test - texte en anglais prises de CyberChef estimateur de l'entropie:
prendre un coup d'oeil ici aussi, il est un classique de l'Entropie de Shannon, devrait être un peu plus rapide, puis un par JohnEntropy http://pythonfiddle.com/shannon-entropy-calculation/
La réponse ci-dessus est bonne, mais si vous avez besoin d'une version qui peut fonctionner selon différents axes, voici un travail de mise en œuvre.