** Cet article est l'article du troisième jour du Real Escape Advent Calendar 2013. ** **
J'ai rassemblé le code sur Github. https://github.com/katryo/bing_search_naive_bayes_sim
J'ai fait un tel système.
--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.
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.
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.
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.
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.
Le code que j'ai créé peut être divisé en deux parties.
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
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.
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
Blog personnel de Sucrose http://sucrose.hatenablog.com/entry/2012/11/30/132803
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.
Recommended Posts