À l'aide du classificateur Naive Bayes implémenté dans Python 3.3, calculez la similitude à partir de la fréquence de cooccurrence des mots dans les phrases et les chaînes.

** Cet article est l'article du troisième jour du Real Escape Advent Calendar 2013. ** **

Résumez le contenu de cette fois en 3 lignes

J'ai rassemblé le code sur Github. https://github.com/katryo/bing_search_naive_bayes_sim

Synopsis jusqu'à Dernière fois

J'ai fait un tel système.

Fonctions ajoutées cette fois

Plus de détails

--Calcul de la similitude cosinus des vecteurs (je préfère les appeler vecteur comme une fille mathématique) --Calcul de similitude par coefficient de Simpson de deux ensembles

Deux types de fonctions de calcul de similarité ont été ajoutés.

théorie

Deux types de méthodes de calcul de similarité

Similitude cosinus

Calculez le cosinus des deux vecteurs et utilisez la valeur cosinus comme similarité. Le nombre de dimensions du vecteur peut être de 2, 3 ou 100 (des exemples spécifiques seront décrits plus loin). Cependant, à mesure que le nombre de dimensions augmente, le coût de calcul augmente naturellement, il est donc préférable de trouver des moyens de réduire le nombre de dimensions (comme ne pas compter les mots qui apparaissent trop fréquemment dans tfidf). Au fait, je n'ai pas imaginé cette fois.

Coefficient de Simpson

Contrairement à la similarité cosinus, la similitude est calculée en comparant deux «sacs de mots» au lieu de vecteurs et en utilisant le nombre de mots qu'ils ont en commun. La fréquence n'a pas d'importance.

Comme vous pouvez le voir en regardant le code, que le même mot apparaisse 100 fois dans une catégorie (ou dans une chaîne de caractères d'entrée) ou une seule fois, il est calculé de la même manière (donc la fréquence n'a pas d'importance!) .. Même si le même mot apparaît à plusieurs reprises, cela n'augmente pas le score.

Probabilité d'occurrence et similitude de Naive Bayes

Probabilité d'occurrence

Supposons que vous vouliez calculer la probabilité qu'un mot qui est Naive Bayes (par exemple, «examen») tombe dans une catégorie (par exemple, «pollinose»).

Comme expliqué dans 1st, la probabilité est assez faible. Il est inférieur à 0,01 de la manière habituelle.

De plus, cette fois, l'entrée dans la classification est une phrase, pas un mot. Puisque l'analyse morphologique est effectuée avec MeCab pour créer un sac de mots et calculée comme un ensemble de mots, la probabilité est encore plus faible.

Dans Naive Bays, la probabilité que la phrase «Si vous avez une pollinose, vous devriez d'abord consulter une clinique d'oto-rhino-laryngologie» tombe dans la catégorie «pollinose» est d'environ 0,0000 ... 1.

Cependant, il est beaucoup plus élevé que la probabilité de tomber dans d'autres catégories (comme «fracture» et «penchement d'estomac»). Relativement, mais de loin le plus élevé. Par conséquent, il semble très probable que «Si vous avez une pollinose, vous devriez d'abord consulter une clinique d'oto-rhino-laryngologie» dans la catégorie «pollinose». Autrement dit, la probabilité est élevée.

Degré de similitude

La similitude est une idée complètement différente de la probabilité d'occurrence. La façon de définir et de calculer la similitude entre un ensemble de mots dépend de la méthode.

Pour plus de détails, consultez l'article du blog de Shoto-san et [page Data analysis / mining world by SAS Wiki](http: // wikiwiki) .jp / cattail /?% CE% E0% BB% F7% C5% D9% A4% C8% B5% F7% CE% A5) et Summary of Similarity Scale Je pense que vous devriez lire autour de .jp / naid / 110006440287).

Cette fois, la similitude a été calculée en utilisant la similitude cosinus et le coefficient de Simpson, mais il existe différentes méthodes pour calculer la similitude, comme l'utilisation du coefficient de Jaccard et du coefficient de Dice. Utilisons-le correctement en fonction du but et du montant du calcul.

code

  1. Calculateur de similarité
  2. Calculez la similitude en l'incorporant dans le système créé

Le code que j'ai créé peut être divisé en deux parties.

1. Calculateur de similarité

Tout d'abord, j'ai créé la classe SimCalculator suivante.

sim_calculator.py


import math


class SimCalculator():
    def _absolute(self, vector):
        #Renvoie la longueur ou la valeur absolue du vecteur v
        squared_distance = sum([vector[word] ** 2 for word in vector])
        distance = math.sqrt(squared_distance)
        return distance

    def sim_cos(self, v1, v2):
        numerator = 0
        #Lorsqu'il existe une clé commune à v1 et v2, le produit des valeurs est ajouté. C'est le produit interne de deux vecteurs.
        for word in v1:
            if word in v2:
                numerator += v1[word] * v2[word]
        
        denominator = self._absolute(v1) * self._absolute(v2)

        if denominator == 0:
            return 0
        return numerator / denominator

    def sim_simpson(self, v1, v2):
        intersection = 0
        #Comptage du nombre de clés communes à v1 et v2
        for word in v2:
            if word in v1:
                intersection += 1
        denominator = min(len(v1), len(v2))

        #Lorsque le contenu de v1 ou v2 est 0
        if denominator == 0:
            return 0
        return intersection / denominator

if __name__ == '__main__':
    sc = SimCalculator()
    print('La similitude cosinus est' + str(sc.sim_cos({'Piratage de la vie': 1, 'fracture': 2}, {'Piratage de la vie': 2, 'travaux': 1, 'loisir': 1})))
    print('La similitude calculée par le coefficient de Simpson est' + str(sc.sim_simpson({'Piratage de la vie': 1, 'fracture': 2}, {'Piratage de la vie': 2, 'travaux': 1, 'loisir': 1})))

Lorsqu'il est exécuté, le résultat est le suivant.

La similitude cosinus est de 0.3651483716701107
La similarité calculée par le coefficient de Simpson est 0.5

La méthode _absolute utilisée dans la méthode sim_cos qui calcule la similitude cosinus calcule la longueur (valeur absolue, magnitude) du vecteur. Le vecteur ici est représenté par des mots tels que "life hack" et "fracture". Par exemple dans le code ci-dessus

{«Life hack': 1, 'fracture': 2}

Est un vecteur bidimensionnel.

Référence http://www.rd.mmtr.or.jp/~bunryu/pithagokakutyou.shtml

2. Calculez la similitude en l'incorporant dans le système créé

Incorporez le calculateur de similarité créé en 1 dans le classificateur Naive Bayes créé la dernière fois.

En d'autres termes, une fonction pour calculer la similitude entre la chaîne de caractères d'entrée standard et la catégorie (Sac de mots des données d'apprentissage insérées) est ajoutée.

À propos, il ne classe pas par Naive Bayes, il utilise uniquement le résultat appris par l'objet Naive Bayes.

Exécutez le code suivant pour devenir un outil de terminal capable d'effectuer simultanément un calcul de classification et de similarité.

calc_similarity.py


from sim_calculator import SimCalculator
from naive_bayes import NaiveBayes
import constants
import pickle
import sys
import pdb
from collections import OrderedDict


if __name__ == '__main__':
    sc = SimCalculator()
    with open(constants.NB_PKL_FILENAME, 'rb') as f:
        nb_classifier = pickle.load(f)

    #Train et mot pour la chaîne de caractères d'entrée standard_Utilisation du compte{'input': {'Pollen Sugi': 4, 'médicament':3}}Je l'ai fait un objet NB pour le formater au format
    #Je ne l'utilise pas comme classificateur, donc je devrais créer une autre classe, mais c'est ennuyeux.
    nb_input = NaiveBayes()

    for query in sys.stdin:
        nb_input.word_count = {}  #Initialisation pour la deuxième entrée et les suivantes
        nb_input.train(query, 'input')  #La chaîne de caractères saisie dans l'entrée standard'input'Apprendre en tant que catégorie
        results = OrderedDict()
        for category in nb_classifier.word_count:
            # sim_sim au lieu de cos_Vous pouvez également utiliser simpson
            sim_cos = sc.sim_cos(nb_input.word_count['input'], nb_classifier.word_count[category])
            results[category] = sim_cos

        for result in results:
            print('Catégorie "%Le degré de similitude avec "s"%F' % (result, results[result]))

        # http://cointoss.hatenablog.com/entry/2013/10/16/Je ne peux pas obtenir la clé max même si je suis 123129(´ ・ ω ・`)
        best_score_before = 0.0
        best_category = ''
        for i, category in enumerate(results):
            if results[category] > best_score_before:
                best_category = category
                best_score_before = results[category]
        try:
            print('La catégorie présentant le degré de similitude le plus élevé est "%s "et la similitude est%F' % (best_category, results[best_category]))
        except KeyError:  #Lorsque l'entrée est vide
            continue

Faites ceci et insérez la chaîne appropriée.

Afin de surmonter même un peu la pollinose, il est important de prendre des mesures appropriées contre la pollinose. Présentation des mesures de base de la pollinose que vous pouvez faire vous-même, du journal de la pollinose et des mauvaises mesures de la pollinose.

Voici le résultat de la saisie de la chaîne de caractères tirée de Page appropriée.

La similitude avec la catégorie «penché de l'estomac» est 0.362058
La similitude avec la catégorie "dent de ver" est 0.381352
La similitude avec la catégorie «Contre-mesures contre la pollinose» est 0.646641
La similitude avec la catégorie «dépression» est 0.250696
La similitude avec la catégorie "machine" est 0.300861
La similitude avec la catégorie «fracture» est 0.238733
La similitude avec la catégorie «épaules raides» est 0.326560
La similitude avec la catégorie "Documents" est 0.333795
La catégorie présentant le degré de similitude le plus élevé est «Contre-mesures contre la pollinose» et le degré de similitude est de 0..646641

Ouais, c'est le résultat.

Entrez le texte tiré de ici.

Quand j'avais l'adolescence et la vingtaine, quand il s'agissait de viande grillée, il était naturel d'utiliser du calvi, du tonkatsu pour la longe et des ramen pour le tonkotsu. J'ai adoré, mais ça s'éloigne peu à peu

C'est une phrase qui semble me faire mal. Lorsque vous entrez ceci.

La similitude avec la catégorie «penché de l'estomac» est 0.398943
La similitude avec la catégorie "dent de ver" est 0.425513
La similitude avec la catégorie «Contre-mesures contre la pollinose» est 0.457718
La similitude avec la catégorie «dépression» est 0.300388
La similitude avec la catégorie "machine" est 0.340718
La similitude avec la catégorie «fracture» est 0.256197
La similitude avec la catégorie «épaules raides» est 0.339602
La similitude avec la catégorie "Documents" est 0.322423
La catégorie présentant le degré de similitude le plus élevé est «Contre-mesures contre la pollinose» et le degré de similitude est de 0..457718

Que ... je ne sens pas "l'estomac" ...?

Enfin, calculez la similitude des phrases de dents de ver tirées de ici.

Causes de la carie dentaire, traitements, méthodes de prévention, enfants(Dents de lait)Explication détaillée des dents de vers, des coûts de traitement, etc. Image de dents de ver(Photo)Et aussi sur le traitement de la carie dentaire précoce

Qu'est-ce que ce sera?

La similitude avec la catégorie «penché de l'estomac» est 0.404070
La similitude avec la catégorie "dent de ver" est 0.445692
La similitude avec la catégorie «Contre-mesures contre la pollinose» est 0.427097
La similitude avec la catégorie «dépression» est 0.306610
La similitude avec la catégorie "machine" est 0.381016
La similitude avec la catégorie «fracture» est 0.241813
La similitude avec la catégorie «épaules raides» est 0.346461
La similitude avec la catégorie "Documents" est 0.394373
La catégorie avec le degré de similitude le plus élevé est «dent de ver» et le degré de similitude est de 0..445692

C'était bien.

Il est probable que la raison pour laquelle le texte qui semble s'appuyer sur le ventre a été jugé comme une contre-mesure contre la pollinose était qu'il y avait beaucoup de bruit.

Des mots comme "o" et "ha" apparaissent dans n'importe quelle catégorie. Ceux-ci ne sont pas utiles pour la catégorisation du point de vue humain, mais comme la méthode ci-dessus calcule simplement la similitude en fonction de la fréquence de tous les mots qui apparaissent, elle est utilisée pour le calcul de similitude.

Les performances peuvent être améliorées en réduisant le poids des mots fréquemment utilisés et en augmentant le poids des mots les moins fréquemment utilisés, par exemple en utilisant tf-idf.

Supplément

Comme je l'ai écrit dans les commentaires, j'ai mis l'entrée standard dans l'objet NaiveBayes nb_input. En effet, il utilise la méthode train et la méthode word_count, mais comme il ne s'agit pas d'un classificateur NaiveBayes, il est préférable de créer une classe distincte afin que NaiveBayes hérite également de cette classe.

En passant, autour de la sortie du résultat final, j'ai essayé "d'obtenir la clé et la valeur de celle avec la valeur maximale du dict" et j'ai étudié une manière cool d'écrire. Cet article a écrit exactement ce qu'il voulait, mais cela n'a pas fonctionné. Je pense que c'est parce que les spécifications ont changé dans Python3.

De plus, lorsque j'utilise réellement l'apprentissage automatique, je pense que l'utilisation d'une bibliothèque comme scikit-learn est rapide et sans bogue. L'implémenter vous-même comme cet article est à des fins d'étude uniquement, et vous devriez vous sentir libre d'utiliser une bibliothèque qui maintient la qualité dans l'utilisation pratique.

Github J'ai posté le code sur Github. https://github.com/katryo/bing_search_naive_bayes_sim

référence

Blog personnel de Sucrose http://sucrose.hatenablog.com/entry/2012/11/30/132803

Aperçu de la prochaine fois

Ensuite, nous implémenterons tf-idf et viserons à améliorer les performances. Il serait intéressant de changer la méthode de calcul de similitude et d'utiliser le coefficient de Dice et le coefficient de Jaccard.

J'ai pensé, mais j'ai décidé de calculer tf-idf avec scicit-learn.

Suite ici

Recommended Posts

À l'aide du classificateur Naive Bayes implémenté dans Python 3.3, calculez la similitude à partir de la fréquence de cooccurrence des mots dans les phrases et les chaînes.
Notez que je comprends l'algorithme du classificateur Naive Bayes. Et je l'ai écrit en Python.
Visualisez la fréquence des occurrences de mots dans les phrases avec Word Cloud. [Python]
Découvrez Naive Bayes implémenté en Python 3.3 sur une page Web obtenue avec l'API Bing. Que les phrases soient classées
J'ai comparé la vitesse de la référence du python dans la liste et la référence de l'inclusion du dictionnaire faite à partir de la liste dans.
Implémentation de l'algorithme "Algorithm Picture Book" en Python3 (Heap Sort Edition)
Étude de Python Hour8: Utilisation de packages
Comment compter rapidement la fréquence d'apparition des caractères à partir d'une chaîne de caractères en Python?
Calculez des millions de chiffres dans la racine carrée de 2 avec python
Implémentation de l'algorithme de "Algorithm Picture Book" en Python3 (Bubble Sort)
Différentes façons de calculer la similitude entre les données avec python
Prédire le sexe à partir du nom à l'aide de l'API Gender et de Pykakasi en Python
[Astuces] Problèmes et solutions dans le développement de python + kivy
Jugement de la polarité émotionnelle des phrases à l'aide du classificateur de texte fastText
Implémentation de l'algorithme «Algorithm Picture Book» en Python3 (tri sélectif)
Implémenter Naive Bayes dans Python 3.3
Comptez bien le nombre de caractères thaïlandais et arabes en Python
Calculez la similitude entre les phrases avec Doc2Vec, une évolution de Word2Vec
Comment obtenir des abonnés et des abonnés de Python à l'aide de l'API Mastodon
Obtenez et définissez la valeur du menu déroulant en utilisant Python et Selenium
Obtenez le titre et la date de livraison de Yahoo! News en Python
Configurer un serveur SMTP factice avec Python et vérifier le fonctionnement de l'envoi depuis Action Mailer
J'ai essayé de livrer du courrier depuis Node.js et Python en utilisant le service de livraison de courrier (SendGrid) d'IBM Cloud!