J'ai commencé à utiliser sklearn.naive_bayes.GaussianNB pour la classification de textes, et j'ai obtenu de bons résultats initiaux. Je veux utiliser la probabilité renvoyée par le classificateur comme une mesure de confiance, mais le système de classification de l predict_proba() renvoie toujours "1.0" pour la classe choisie, et "0.0" pour toutes les autres.
Je sais (d'après ici ) que " ...les sorties de probabilité de predict_proba ne doivent pas être prises trop au sérieux ", mais jusqu'à quel point ? ! Le classificateur peut se tromper finance-investissement o accords-cordes mais le predict_proba() La sortie ne montre aucun signe d'hésitation...
Un peu de contexte :
- J'ai utilisé sklearn.feature_extraction.text.TfidfVectorizer pour l'extraction de caractéristiques, sans, pour commencer, restreindre le vocabulaire avec mots-clés o min/max_df --> J'ai obtenu de très gros vecteurs.
- J'ai entraîné le classifieur sur un arbre hiérarchique de catégories (peu profond : pas plus de 3 couches) avec 7 textes (catégorisés manuellement) par catégorie. Pour l'instant, c'est le cas, flat
la formation : Je ne tiens pas compte de la hiérarchie.
Le résultat GaussianNB est très gros (~300MB), et la prédiction est plutôt lente : environ 1 seconde pour un texte.
Cela peut-il être lié ? Les énormes vecteurs sont-ils à l'origine de tout cela ?
Comment obtenir des prédictions significatives ? Dois-je utiliser un classificateur différent ?
Voici le code que j'utilise :
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.naive_bayes import GaussianNB
import numpy as np
from sklearn.externals import joblib
Vectorizer = TfidfVectorizer(input = 'content')
vecs = Vectorizer.fit_transform(TextsList) # ~2000 strings
joblib.dump(Vectorizer, 'Vectorizer.pkl')
gnb = GaussianNB()
Y = np.array(TargetList) # ~2000 categories
gnb.fit(vecs.toarray(), Y)
joblib.dump(gnb, 'Classifier.pkl')
...
#In a different function:
Vectorizer = joblib.load('Vectorizer.pkl')
Classifier = joblib.load('Classifier.pkl')
InputList = [Text] # One string
Vec = Vectorizer.transform(InputList)
Probs = Classifier.predict_proba([Vec.toarray()[0]])[0]
MaxProb = max(Probs)
MaxProbIndex = np.where(Probs==MaxProb)[0][0]
Category = Classifier.classes_[MaxProbIndex]
result = (Category, MaxProb)
Mise à jour :
En suivant les conseils ci-dessous, j'ai essayé MultinomialeNB & Régression logistique . Ils renvoient tous deux des probabilités variables, et sont meilleurs à tous égards pour ma tâche : classification beaucoup plus précise, objets plus petits en mémoire et vitesse beaucoup plus élevée ( MultinomialeNB est rapide comme l'éclair !).
J'ai maintenant un nouveau problème : les probabilités renvoyées sont très faibles - généralement de l'ordre de 0,004-0,012. Cela concerne la catégorie prédite/gagnante (et la classification est précise).