J'expliquerai l'algorithme du classifieur Naive Bayes (Basin filter) en utilisant des valeurs numériques concrètes. Je l'ai également implémenté en Python. Je l'ai rédigé comme mon propre mémo d'étude, mais j'espère qu'il sera utile à d'autres personnes.
C'est l'une des méthodes d'apprentissage supervisé de l'apprentissage automatique qui vous permet de déterminer à quelle catégorie appartient certaines données (phrase). Il est souvent utilisé pour les filtres de courrier indésirable et la catégorisation des articles de presse WEB.
C'est une méthode simple utilisant le théorème de Bayes, et le niveau de difficulté est faible. J'ai essayé d'expliquer sans utiliser autant que possible des formules mathématiques.
Je vais expliquer la logique de calcul pour déterminer dans quelle catégorie la phrase cible appartient, en utilisant des valeurs numériques concrètes.
Si les données d'apprentissage sont les suivantes, calculez dans quelle catégorie appartient la phrase cible.
** Données d'apprentissage **
*Football[Balle|Des sports|Coupe du monde|Balle] *base-ball[Balle|Des sports|Gants|chauve souris] *tennis[Balle|raquette|manteau]
Football [Ballon | Sports]
On suppose que l'intérieur de [] est un document connecté.
** Document cible ** "Sports de balle"
La valeur obtenue en divisant le nombre de documents dans chaque catégorie de données de formation par le nombre total de documents est définie comme «** Taux d'apparition de la catégorie P (C) **».
Football | base-ball | tennis | |
---|---|---|---|
Probabilité d'apparition de catégorie |
Comptez le nombre de mots de chaque catégorie dans les données d'entraînement. Les doublons ne sont pas exclus et le football est total.
Football | base-ball | tennis | |
---|---|---|---|
Nombre de mots |
Comptez le nombre d'occurrences dans chaque catégorie de «balle» et «sports» et divisez par le nombre de mots de chaque catégorie comptés ci-dessus. Soit "** taux d'occurrence de mot P (Wn | C) ** dans la catégorie".
Football | base-ball | tennis | |
---|---|---|---|
Balle | |||
Des sports |
La valeur obtenue en multipliant la «valeur de balle» et la «valeur sportive» calculées est définie comme «** taux d'apparition des documents dans la catégorie P (D | C) **».
Football | base-ball | tennis | |
---|---|---|---|
Taux d'apparition des documents dans la catégorie |
1 ci-dessus.Et 2.Émis en "Taux d'apparition de la catégorie P(C)"Quand"**Taux d'apparition des documents dans la catégorie P(D|C)**Probabilité que le produit de "" appartienne à chaque catégorie du document (文章内のTaux d'apparition de la catégorie P(C|D))est.
Celui avec la valeur la plus élevée est classé comme catégorie de document cible.
Football | base-ball | tennis | |
---|---|---|---|
Taux d'apparition de la catégorie dans les phrases | $\frac{2}{4} \times \frac{6}{36} $ | $\frac{1}{4} \times \frac{1}{16} $ | $\frac{1}{4} \times \frac{0}{9} $ |
Résultat du calcul |
En conséquence, les "sports de balle" ont été classés comme "football"! !!
(Puisqu'il ne s'agit que d'un exemple, c'est à travers que ce sont tous les sports de balle)
Dans cet exemple, la probabilité de tennis est maintenant de 0 $. C'est parce que le mot «sport» n'a pas été inclus dans les données d'apprentissage pour «tennis».
S'il y a un nouveau mot qui n'existe pas dans les données d'apprentissage, la probabilité de la catégorie sera de 0 $. C'est ce qu'on appelle le "** problème de fréquence zéro **".
Pour résoudre ce problème, nous utilisons une méthode appelée lissage additif pour recalculer.
Ajoutez simplement le traitement en gras ci-dessous à la partie de calcul "Taux d'apparition des mots P (Wn | C) en catégorie" en 2.
Comptez le nombre d'occurrences de chaque catégorie de "balle" et "sports" et ajoutez ** 1 **, et divisez par le nombre de mots dans chaque catégorie comptés ci-dessus plus ** le nombre total de mots de données d'apprentissage ** ..
Le nombre total de mots dans les données d'apprentissage est de 8 car il est dédupliqué.
Le "taux d'apparition des mots P (Wn | C) dans la catégorie" est à nouveau résumé dans le tableau.
Football | base-ball | tennis | |
---|---|---|---|
Balle | |||
Des sports |
Calculez la fraction.
Football | base-ball | tennis | |
---|---|---|---|
Balle | |||
Des sports |
Cela montre que même si le mot «sports» ne figure pas dans les données d'entraînement pour «tennis», la probabilité ne sera pas nulle.
Ensuite, calculez la suite telle qu'elle est.
Le «taux d'apparition de catégorie P (C)» calculé en 1. reste le même. «Taux d'apparition des documents P (D | C) dans la catégorie» est le produit des valeurs de «balle» et «sports» calculées ci-dessus.
Football | base-ball | tennis | |
---|---|---|---|
Probabilité d'apparition de catégorie | |||
Taux d'apparition des documents dans la catégorie | |||
Taux d'apparition de la catégorie dans les phrases | |||
Résultat du calcul |
Le résultat a été classé comme football, avec une probabilité de tennis de 0 $! !!
Cependant, je pense que la précision du lissage additif se détériore en raison du grand effet de la valeur du "taux d'apparition de catégorie P (C)". Il est nécessaire d'en tenir compte attentivement lors de la définition des données d'entraînement.
Par souci de clarté, nous avons réduit le nombre de mots et d'ensembles de données dans l'exemple, mais nous avons en fait plus de mots. Par conséquent, le dénominateur du résultat du calcul devient un très grand nombre et il y a une forte possibilité qu'un sous-débordement se produise.
La solution de contournement est la méthode de ** comparaison logarithmique **.
0,001 $ peut également être exprimé comme $ \ frac {1} {10} $ × $ \ frac {1} {10} $ × $ \ frac {1} {10} $, ce qui équivaut à 10 $ élevé à la puissance $ -3 $. Bon, ** -3 ** est le logarithmique de 0,001 $. (Le bas est de 10 $) $ 0,0001 $ peut également être exprimé comme $ \ frac {1} {10} $ × $ \ frac {1} {10} $ × $ \ frac {1} {10} $ × $ \ frac {1} {10} $ Oui, il est appelé 10 $ à la puissance de -4 $, et ** - 4 ** est le logarithme de 0,001 $. (Le bas est de 10 $)
La relation de grandeur de $ X $, $ Y $ et $ Z $ est la même que la relation de grandeur du logarithme de $ X $, du logarithme de $ Y $ et du logarithme de $ Z $. (Si le fond est le même et supérieur à 1) Le logarithme est supérieur à la valeur d'origine. (Si la valeur est inférieure à 1 et la base est supérieure à 1)
En outre, l'amplitude de la multiplication de la valeur est la même que celle de l'addition logarithmique. 2 x 2 x 2: bûche 3 2 x 2 x 2 ** x 2 **: Bûche 3 ** + 1 **
L'histoire revient à l'exemple "Taux d'apparition des documents dans la catégorie P(D|C)"Balle" et "Sports" "Taux d'apparition des mots dans la catégorie P"(Wn|C)Calculé comme l'addition du logarithme de "Probabilité d'apparition de catégorie P"(C)Je vais l'ajouter au logarithme de.
Football | base-ball | tennis | |
---|---|---|---|
Probabilité d'apparition de catégorie | |||
Taux d'apparition des mots dans la catégorie(Balle) | |||
Taux d'apparition des mots dans la catégorie(Des sports) | |||
Taux d'apparition de la catégorie dans les phrases |
Ceci complète le classificateur Naive Bayes! !!
Je l'ai en fait écrit en python en référence au site suivant. http://yaju3d.hatenablog.jp/entry/2016/10/31/222307
J'ai essayé de décrire dans les commentaires autant que possible où les valeurs expliquées ci-dessus correspondent. J'utilise janome pour l'analyse morphologique.
naivebayes.py
class NaiveBayes:
#constructeur
def __init__(self):
#Un ensemble de tous les mots de données d'entraînement(Pour un lissage supplémentaire)
self.vocabularies = set()
#Pour les ensembles de mots pour chaque catégorie de données d'entraînement
self.word_count = {}
#Pour un ensemble de documents pour chaque catégorie de données d'entraînement
self.category_count = {}
#Apprentissage
def train(self, document, category):
#Analyse morphologique des documents d'apprentissage
ma = MorphologicalAnalysis()
word_list = ma.get_word_list(document)
for word in word_list:
#Augmenter le nombre d'occurrences de mots dans une catégorie
self.__word_count_up(word, category)
#Augmenter le nombre de documents dans la catégorie
self.__category_count_up(category)
#Augmenter le nombre d'occurrences de mot dans la catégorie de données d'entraînement
def __word_count_up(self, word, category):
#Ajouter si nouvelle catégorie
self.word_count.setdefault(category, {})
#Ajouter de nouveaux mots dans la catégorie
self.word_count[category].setdefault(word, 0)
#Augmenter le nombre d'occurrences de mots dans une catégorie
self.word_count[category][word] += 1
#Ajouter à l'ensemble de mots de données d'entraînement(Déduplication)
self.vocabularies.add(word)
#Augmenter le nombre de documents dans la catégorie des données de formation
def __category_count_up(self, category):
#Ajouter si nouvelle catégorie
self.category_count.setdefault(category, 0)
#Augmenter le nombre de documents dans la catégorie
self.category_count[category] += 1
#Classification
def classifier(self, document):
#Catégorie la plus proche
best_category = None
#Définir la valeur entière minimale
max_prob = -sys.maxsize
#Analyse morphologique du document cible
ma = MorphologicalAnalysis()
word_list = ma.get_word_list(document)
#Taux d'apparition des catégories dans les documents pour chaque catégorie P(C|D)Cherchant
for category in self.category_count.keys():
#Taux d'apparition des catégories dans le document P(C|D)Cherchant
prob = self.__score(word_list, category)
if prob > max_prob:
max_prob = prob
best_category = category
return best_category
#Taux d'apparition des catégories dans le document P(C|D)Calculer
def __score(self, word_list, category):
#Taux d'apparition de la catégorie P(C)Avoir(Prenez une mesure logarithmique contre le sous-débit et ajoutez)
score = math.log(self.__prior_prob(category))
#Rechercher le taux d'occurrence des mots dans une catégorie pour tous les mots d'un document
for word in word_list:
#Taux d'apparition des mots dans la catégorie P(Wn|C)Calculer(Prenez une mesure logarithmique contre le sous-débit et ajoutez)
score += math.log(self.__word_prob(word, category))
return score
#Taux d'apparition de la catégorie P(C)Calculer
def __prior_prob(self, category):
#Nombre de documents dans la catégorie cible des données d'entraînement/Nombre total de documents de données de formation
return float(self.category_count[category] / sum(self.category_count.values()))
#Taux d'apparition des mots dans la catégorie P(Wn|C)Calculer
def __word_prob(self, word, category):
#Nombre d'occurrences dans une catégorie de mots+ 1 /Nombre de mots dans la catégorie+Nombre total de mots dans les données d'entraînement(Lissage d'addition)
prob = (self.__in_category(word, category) + 1.0) / (sum(self.word_count[category].values())
+ len(self.vocabularies) * 1.0)
return prob
#Renvoie le nombre de fois qu'un mot apparaît dans une catégorie
def __in_category(self, word, category):
if word in self.word_count[category]:
#Nombre d'occurrences dans une catégorie de mots
return float(self.word_count[category][word])
return 0.0
J'ai appelé l'apprentissage et la classification des classes ci-dessus de View.
view.py
def matching(request):
if request.method == 'POST':
#Acquisition du document cible
words = request.POST['words']
nb = NaiveBayes()
#Ensemble de données de formation
nb.train('Ballon de la Coupe du monde', 'Football')
nb.train('Batte de gant de sport de balle', 'base-ball')
nb.train('Terrain de raquette de balle', 'tennis')
nb.train('Sports de balle', 'Football')
#Obtenez le résultat de la classification
category = nb.classifier(words)
dictionary = {'category': category}
return render(request, 'matching.html', dictionary)
elif request.method == 'GET':
return render(request, 'matching.html')
L'apprentissage automatique ne fait que commencer à étudier et il y a beaucoup de choses que je ne comprends pas. De plus, depuis que j'utilise Python depuis quelques jours, le style d'écriture peut être étrange.
Si vous trouvez des erreurs dans l'explication ci-dessus, je vous serais reconnaissant de bien vouloir les signaler.
De plus, Janome n'a pas séparé les mots qui suivent Katakana. J'avais l'intention d'être une note personnelle, mais j'espère que cela aidera quelqu'un: rougissez: