Pour promouvoir la compréhension de l'apprentissage automatique Une manière classique de construire automatiquement un modèle de classification à partir de données, J'ai implémenté un classificateur Naive Bayes. Récemment, l'analyse d'image telle que API Cloud Vision est devenue populaire. Le seuil semblait élevé pour les débutants, la première étape est donc le traitement du langage naturel.
Cette fois, nous utiliserons l'API Twitter pour collecter les devis du compte du bot. Implémentation du ** Hanyu classifier ** pour classer Hanyu-san et Hanyu-kun.
Le client API est implémenté dans Ruby et le classificateur est implémenté en Python. MeCab est utilisé pour l'analyse morphologique.
En outre, tous deux devraient s'appeler M. Hanyu, Pour plus de commodité, veuillez autoriser M. Hanyu, un patineur artistique, à être appelé M. Hanyu.
APIClient est implémenté comme suit en utilisant Twitter Ruby Gem. L'API Twitter a une limite sur le nombre d'exécutions par heure appelée Limites de taux. Si vous voulez recevoir beaucoup de tweets, vous devez mettre un intervalle d'environ 15 minutes. Veuillez prendre une pause-café de temps en temps.
require 'twitter'
client = Twitter::REST::Client.new do |config|
config.consumer_key = 'XXX'
config.consumer_secret = 'YYY'
config.access_token = 'hoge'
config.access_token_secret = 'fuga'
end
client.user_timeline('TwitterUserID',{ count: 150}).each_with_index do |tl,i|
tw = client.status(tl.id)
tweet = tw.text
#Élimine la duplication
if !tweets.include?(tweet)
puts tweet
end
end
Maintenant, traitons les données acquises précédemment. Comme cela sera décrit plus loin, afin de quantifier et de classer ** si le tweet contient des mots que M. Hanyu et M. Hanyu sont susceptibles de dire **, décomposez d'abord les tweets collectés en deux tweets. Les 50 premiers mots qui apparaissent fréquemment sont repris, pour un total de 100 mots en tant que variables utilisées pour la classification. (En fait, il y avait des doublons, donc il y a 91 cas.)
Tout d'abord, cette fois, seuls ** la nomenclature, les verbes et les adjectifs ** ont été comptés. (L'utilisation des verbes et des adjectifs a été corrigée à la forme de base)
Nomenclature formelle qui ne semble pas pertinente pour le vocabulaire spécifique à la personne, comme indiqué ci-dessous Il semble que cela ait été causé par la division de la nomenclature verbalisée et des adjectifs, J'ai établi des listes de mots qui ne sont pas comptés.
ng_noun = ["chose", "de", "もde", "Il", "Quand", "、", ",", "。", "¡", "(", ")", "."]
ng_verb = ["Faire", "Est", "Devenir", "y a-t-il"]
ng_adjective = ["Yo"]
Le package * collections * est utile pour générer des listes contrées (taples). J'ai également utilisé natto pour lier Python et MeCab.
import collections
from sets import Set
from natto import MeCab
def mostFrequentWords(file, num):
words = collections.Counter()
f = open(file)
line = f.readline()
while line:
#nom:surface="patin", feature="nom,Général,*,*,*,*,patin,patin,patin"
#verbe:surface="Caleçon", feature="verbe,Indépendance,*,*,Un pas,Forme imparfaite,Caleçonる,Esclave,Esclave"
for node in mecab.parse(line, as_nodes=True):
features = node.feature.split(",")
if features[0] == "nom" and node.surface not in ng_noun:
words[node.surface] += 1
elif features[0] == "verbe" and features[6] not in ng_verb:
words[features[6]] += 1
elif features[0] == "adjectif" and features[6] not in ng_adjective:
words[features[6]] += 1
line = f.readline()
return words.most_common(num
words["hanyu"] = mostFrequentWords("hanyu_train.txt", 50)
words["habu"] = mostFrequentWords("habu_train.txt", 50)
tpl = words["hanyu"] + words["habu"]
vocabulary = set([])
for word in tpl:
vocabulary.add(word[0])
Voici une brève explication du contexte mathématique.
Premièrement, le classificateur Naive Bayes est un classificateur basé sur les probabilités. Ce que je veux demander cette fois, c'est quand un certain document (ici, chaque tweet) * d * est donné. S'il a une forte probabilité d'appartenir à quelle classe (M. Hanyu ou M. Hanyu) * c *. Cela peut être exprimé comme * P (c | d) * comme une probabilité conditionnelle étant donné un tweet. Cependant, comme il est difficile d'obtenir directement cette probabilité postérieure, elle est calculée à l'aide du ** théorème de Bayes **.
P(c|d) = \frac{P(c)P(d|c)}{P(d)}
Ici, calculez le côté droit pour chaque classe, c'est-à-dire Hanyu-san / Hanyu-kun, Découvrez à laquelle le tweet est le plus susceptible d'appartenir. Cependant, le dénominateur * P (d) * est constant quelle que soit la classe une fois que le classificateur est construit. ** Il serait bon de ne calculer que la molécule **.
P(c) Cette fois, nous avons reçu 100 tweets pour chacun de M. Hanyu et M. Hanyu, et 70 étaient des données d'entraînement pour la construction d'un classificateur. 30 cas sont utilisés comme données de test pour vérifier l'exactitude du classificateur.
P(d|c) Maintenant, si vous pensez à la signification de cette probabilité conditionnelle * P (d | c) *, M. Hanyu, Hanyu-kun, selon la combinaison des types de mots que chacun peut dire Vous devez trouver la probabilité que chaque tweet se produise, mais c'est impossible. Par conséquent, il est exprimé à l'aide d'un modèle simplifié adapté à la classification des documents. Ici, ** À propos de l'ensemble des mots * V * que M. Hanyu et M. Hanyu sont susceptibles de dire Vérifiez s'ils sont inclus ou non dans les tweets classifiés **.
La distribution des variables stochastiques qui prennent deux valeurs, comme dire / ne pas dire, est la ** distribution de Bernoulli **.
{P_{w,c}}^{\delta_{w,d}}(1-{P_{w,c}})^{1-\delta_{w,d}}
Cette partie exponentielle est appelée fonction delta, et 0 est émis lorsque * w * = * d *, et 1 est émis sinon. Tu le penses bien.
Ici, considérons la distribution de Bernoulli pour chaque mot * w * appartenant à l'ensemble * V *. Le ** modèle de Bernoulli multivarié ** représente * P (d | c) *.
\prod_{w \in V}{P_{w,c}}^{\delta_{w,d}}(1-{P_{w,c}})^{1-\delta_{w,d}}
À propos, les deux points suivants peuvent être lus à partir de ce qui précède comme les caractéristiques du modèle multivarié de Bernoulli.
--Le nombre d'occurrences de mots dans un document n'est pas pris en compte --Le phénomène selon lequel le mot "ne se produit pas" dans le document est souligné
En résumé, cela peut être exprimé comme suit, alors calculez le côté droit pour chacun de M. Hanyu et M. Hanyu. Valeur plus élevée = ** Détermine quelle hypothèse est la plus susceptible de générer des données **. Ce «produit des probabilités que l'observation d se produise sous l'hypothèse c» est appelé ** vraisemblance **, et l'approche pour trouver le c le plus probable qui maximise cette probabilité est la ** méthode la plus probable **. Est appelé.
P(D) = {P(c)P(d|c)} = p_c\prod_{w \in V}({P_{w,c}}^{\delta_{w,d}}(1-{P_{w,c}})^{1-\delta_{w,d}})
Puisque la description de la formule n'est pas le but, la formule est pliée au milieu, mais si elle est transformée,
\log P(D) = \sum N_c \log p_c + \sum_c \sum_{w \in V} N_{w,c} \log p_{w,c} + \sum_c \sum_{w \in V} (N_c - N_{w,c}) \log(1 - p_{w,c})
Ce sera comme ça. Cela ressemble à l'endroit où la fonction delta est allée, mais comme mentionné ci-dessus, elle a la propriété d'être 0 lorsque * w * = * d *, et 1 sinon, donc le mot * w * et la classe * c * coexistent. Il est exprimé en multipliant le nombre de fois. Cela peut sembler difficile à lire, mais le fait est que la distribution est déterminée par deux paramètres, ** Pw, c et Pc **.
Ce serait bien de trouver c qui maximise le logP (D) ci-dessus lorsqu'on leur donne les données à classer. Ici, on suppose que tous les tweets du monde sont écrits par M. Hanyu ou M. Hanyu **. Il est nécessaire de satisfaire la contrainte exprimée par la formule suivante que la somme des probabilités d'être classé dans chaque classe est 1.
\sum_c p_c = 1
(Ce n'est pas non plus le sujet principal, je vais donc le replier.) Pour la fonction de Lagrange définie par la méthode appelée méthode du multiplicateur indéterminé de Lagrange, La valeur maximale peut être obtenue comme suit en prenant un différentiel partiel pour chaque paramètre.
p_{w,c} = \frac {N_{w,c}} {N_c} , p_c = \frac {N_c} {\sum_c N_c}
Maintenant que nous savons comment trouver les paramètres, il est temps de commencer à mettre en œuvre.
À propos, les données d'entraînement suivantes ont été générées à partir des tweets soumis à une analyse morphologique.
cls = ["habu", "hanyu"]
#C'est une image car je ne peux pas la montrer par commodité. Comme mentionné ci-dessus, le tweet est généré en appliquant une analyse morphologique.
vocabulary = ["patin", "Pruschenko", "Jeu", "Le geste de Dieu"]
#De même
documents["habu"] = [["Tenant du titre ","70", "Homme", "Moitié", "Hanyu"],[...]]
documents["hanyu"] = [["Génial","4 rotations", "Réussi", "Gagnant"],[...]]
À partir des données ci-dessus et de la formule calculée, calculez la probabilité simultanée * p (w, c) * qu'un mot se produise dans chaque classe.
def train(cls, vocabulary, documents):
#Nombre d'occurrences de chaque document de formation
n_cls = {}
total = 0.0
for c in cls:
n_cls[c] = len(documents[c])
total += n_cls[c]
#Probabilité d'occurrence de chaque document de formation
p_cls = {}
for c in cls:
p_cls[c] = n_cls[c] / total
#Nombre d'occurrences de mots pour chaque classe
for c in cls:
for d in documents[c]:
for word in vocabulary:
if word in d:
n_word[c][word] += 1
#Probabilité d'occurrence des mots pour chaque classe
for c in cls:
p_word[c] = {}
for word in vocabulary:
p_word[c][word] = \
(n_word[c][word] + 1) / (n_cls[c] + 2)
C'est un peu à part. Dans la partie où la probabilité d'occurrence d'un mot pour chaque classe est calculée, 1 est ajouté à la molécule et 2 est ajouté au dénominateur. C'est le produit de la probabilité et lorsqu'un mot du vocabulaire * V * n'apparaît pas dans le tweet Cela évite que la probabilité que le résultat de l'intégration devienne 0. (Puisqu'il devient une très petite valeur, il se présente sous la forme d'une somme en prenant une valeur logarithmique dans l'implémentation. Puisque 0 n'existe pas dans la zone de définition logarithmique, le programme sera moussé avec une erreur de domaine mathématique)
Par conséquent, nous supposons généralement une distribution de probabilité appelée distribution de Diricre, ce qui rend difficile de prendre 0 pour la facilité d'apparition des mots. C'est ce qu'on appelle le ** lissage ** car il permet d'adoucir les valeurs extrêmes souvent produites par la méthode la plus probable.
De plus, cette approche qui tente de maximiser la probabilité après que les données soient données en tenant compte de la distribution antérieure plutôt que de la facilité d'apparition des données exactes est appelée ** estimation MAP **.
Maintenant que nous avons enfin construit un classificateur, exécutons-le.
En utilisant le classificateur construit, les tweets donnés étaient M. Hanyu et M. Hanyu, Une fonction qui classe par quel document a été écrit.
def classify(data):
#LogP pour chaque classe(D)Cherchant
pp = {}
for c in cls:
pp[c] = math.log(p_cls[c])
for word in vocabulary:
if word in data:
pp[c] += math.log(p_word[c][word])
else:
pp[c] += math.log((1 - p_word[c][word]))
#Obtenu logP(D)Lequel d'entre eux est le plus grand
for c in cls:
maxpp = maxpp if 'maxpp' in locals() else pp[c]
maxcls = maxcls if 'maxcls' in locals() else c
if maxpp < pp[c]:
maxpp = pp[c]
maxcls =c
return (maxcls, maxpp)
Parmi les tweets acquis, appliquons les tweets de 30 x 2 personnes enregistrées pour la vérification de l'exactitude au classificateur.
def test(data, label):
i = 0.0
for tweet in data:
if nb.classify(tweet)[0] == label:
i += 1
return (i / len(data))
# bags_of_words renvoie un tableau bidimensionnel de parties de chaque tweet
test(bags_of_words("hanyu_test.txt"), "hanyu")
test(bags_of_words("habu_test.txt"), "habu")
classe | ① Nombre de données de test | ② Nombre de bonnes réponses | Taux de réponse correct(②/①) |
---|---|---|---|
M. Hanyu | 30 | 28 | 93.33% |
Hanyu-kun | 30 | 28 | 93.33% |
Il peut être déterminé avec une précision assez élevée, Il semble que ce soit parce que M. Hanyu et M. Hanyu contenaient beaucoup de vocabulaire unique. Parce qu'il est significatif de classer les données avec des distributions qui ont le même vocabulaire mais des fréquences différentes. À cet égard, les données du test peuvent ne pas être très bonnes.
Ensuite, analysez Image de M. Hanyu et M. Hanyu Je veux l'essayer.
Introduction à l'apprentissage automatique pour le traitement du langage Différence entre Yuzuru Hanyu et Zenji Hanyu
Recommended Posts