[PYTHON] Prédisez le nombre de coussins qui peuvent être reçus en tant que répondants rires avec Word2Vec + Random Forest

Motivation

J'aime beaucoup le rire et quand je rentre à la maison, je regarde sans cesse les rires enregistrés. Libéré temporairement des recherches sur le traitement du langage naturel, faites une pause et riez ...

Chachara ~ Charara ** Cha ** ** Cha! !! !! !! !! ** **

inside-head


Obtenez la réponse:(Entrez une réponse qui ressemble à un point de rire)
Yamada-kun! Prenez l'un des Sanyutei Enraku-san!

Bouffée! (Homme inspirant)

Qu'est-ce qu'un point de rire?

・ Programmes de divertissement qui ont eu lieu pendant une longue période ・ Ogiri est célèbre pour les artistes professionnels de rakugo qui donnent des réponses élégantes au sujet. ・ Si vous donnez une réponse intéressante, vous obtiendrez un coussin. Si vous glissez ou donnez une réponse grossière, vous serez enlevé du coussin ・ Collectez 10 coussins et obtenez des produits incroyables

Objectif

Après avoir saisi une réponse riante, ・ Qui est le plus proche de la réponse ・ Combien de coussins puis-je obtenir? Est prédit et affiché.

Procédure ① Collecte de phrases, prétraitement

Contenus antérieurs diffusés par Nippon Television [http://www.ntv.co.jp/sho-ten/02_week/kako_2011.html](http://www.ntv.co.jp/sho-ten / 02_week / kako_2011.html) pour 2011 ·Répondre ·Intimé ・ Augmentation / diminution des coussins Record. Les réponses autres que les six principaux répondants (annonceur Ogiri, jeune Ogiri, etc.) ont été exclues.

Le nombre de réponses recueillies était de 1773. Il était surprenant qu'il n'y ait pas beaucoup de différence, avec environ 330 réponses par personne.

Les symboles et les blancs étranges ont été supprimés de cette phrase, les pictogrammes ont été éliminés avec des emoji et le cas a été unifié avec mojimoji.

Étape ② Word2Vec

J'ai converti une phrase en un vecteur de 200 dimensions avec Word2Vec. Vectorisez les mots dans les phrases en utilisant le vecteur d'entité Wikipedia japonais. (J'ai pensé que ce serait une bonne idée d'utiliser Wikipedia pour la réponse de rire avec de nombreuses expressions verbales, mais je ne pouvais pas battre le modèle appris qui peut être utilisé facilement) La somme des vecteurs de mots tirés des réponses a été utilisée comme vecteur de réponse.

Étape ③ Apprenez à Random Forest

J'ai créé un classificateur dans une forêt aléatoire. La forêt aléatoire est très bonne car elle est légèrement calculée. Nous avons également optimisé les paramètres avec Gridsearch CV. La plage de recherche des paramètres est Profondeur maximale: 1 ~ 10 Nombre d'arbres décidé: 1 ~ 1000 est.

Après avoir recherché les paramètres, extrayez celui avec la plus grande précision et utilisez Pickle pour enregistrer le classificateur.

gridsearch.py


grid_mori_speaker = GridSearchCV(RandomForestClassifier() , grid_param_mori() , cv=10 ,scoring = 'accuracy', verbose = 3,n_jobs=-1)
grid_mori_speaker.fit(kotae_vector,shoten.speaker)
grid_mori_speaker_best = grid_mori_speaker.best_estimator_
with open('shoten_speaker_RF.pickle',mode = 'wb') as fp :
    pickle.dump(grid_mori_speaker_best,fp)

Calculez cela en fonction du nombre de coussins qui peuvent être identifiés par les répondants et enregistrez-le sous forme de fichier pickle.

À propos, le taux de réponse correcte le plus élevé dans la discrimination des répondants était de 0,25 et le nombre de coussins était de 0,50. C'est encore assez bas, donc j'aimerais améliorer les étapes (2) à (3) pour améliorer la précision.

Étape ④ Créez un programme pour saisir des phrases et classer

Créez un programme qui vous permet de saisir manuellement des phrases et d'afficher les résultats de la classification. Ce que je fais, c'est décompresser le classificateur qui a été converti en un fichier pickle, insérer le vecteur de phrase et afficher le résultat de la classification.

shoten.py


#usr/bin/env python
#coding:utf-8

import numpy as np
import re
import emoji
import mojimoji
import MeCab
from gensim.models import KeyedVectors
import pickle

mecab = MeCab.Tagger("")#Si vous utilisez le dictionnaire Neologd, veuillez entrer le chemin
model_entity = KeyedVectors.load_word2vec_format("entity_vector.model.bin",binary = True)

with open('shoten_speaker_RF.pickle', mode='rb') as f:
    speaker_clf = pickle.load(f)
with open('shoten_zabuton_RF.pickle', mode='rb') as f:
    zabuton_clf = pickle.load(f)
    
def text_to_vector(text , w2vmodel,num_features):
    kotae = text
    kotae = kotae.replace(',','、')
    kotae = kotae.replace('/n','')
    kotae = kotae.replace('\t','')
    kotae = re.sub(r'\s','',kotae)
    kotae = re.sub(r'^@.[\w]+','',kotae)
    kotae = re.sub(r'https?://[\w/:%#\$&\?\(\)~\.=\+\-]+','',kotae)
    kotae = re.sub(r'[!-/:-@[-`{-~ ]+','',kotae)
    kotae = re.sub(r'[:-@, [] ★ ☆ "". , ・]+','',kotae)
    kotae = mojimoji.zen_to_han(kotae,kana = False)
    kotae = kotae.lower()
    kotae = ''.join(['' if character in emoji.UNICODE_EMOJI else character for character in kotae])
    kotae_node = mecab.parseToNode(kotae)
    kotae_line = []
    while kotae_node:
        surface = kotae_node.surface
        meta = kotae_node.feature.split(",")
        if not meta[0] == 'symbole' and not meta[0] == 'BOS/EOS':
            kotae_line.append(kotae_node.surface)
        kotae_node = kotae_node.next
    feature_vec = np.zeros((num_features), dtype = "float32")
    word_count = 0
    for word in kotae_line:
        try:
            feature_vec = np.add(feature_vec,w2vmodel[word])
            word_count += 1
        except KeyError :
            pass
        if len(word) > 0:
            if word_count == 0:
                feature_vec = np.divide(feature_vec,1)
            else:
                feature_vec = np.divide(feature_vec,word_count)
        feature_vec = feature_vec.tolist()
    return feature_vec

def zabuton_challenge(insert_text):
    vector = np.array(text_to_vector(insert_text,model_entity,200)).reshape(1,-1)
    if(zabuton_clf.predict(vector)[0] == 0):
        print(str(speaker_clf.predict(vector)[0])+"Je ne te donnerai pas de coussin")
    elif(zabuton_clf.predict(vector)[0] < 0):
        print("Yamada-kun!"+str(speaker_clf.predict(vector)[0])+"à M. ou Mme"+str(zabuton_clf.predict(vector)[0])+"Donnez-moi un morceau!")
    elif(zabuton_clf.predict(vector)[0] > 0):
        print("Yamada-kun!"+str(speaker_clf.predict(vector)[0])+"De"+str(zabuton_clf.predict(vector)[0] * -1)+"Prends-en un!")
    else:
        print("Yamada-kun! Prenez tous les coussins du développeur qui ont fait le classificateur qui donne une erreur!")
        
if __name__ == "__main__":
    while True:
        text = input("Répondre s'il vous plaît:")
        zabuton_challenge(text)

Veuillez me pardonner de ne pas avoir écrit beaucoup de commentaires maintenant. Le contenu de la fonction text_to_vector () est une version modifiée du code écrit dans l'un des articles du blog (je suis désolé d'avoir perdu la source).

bouge toi

Vous pouvez saisir des phrases en démarrant shoten.py. (Il faut un certain temps pour lire le fichier Pickle en premier ...)

Entrez Réponse à la 2395e 1ère question diffusée le 29 décembre 2012 comme données de test. Essayer.

コメント 2019-12-01 161726.png

Seuls Koyuzo, Enraku et Kikuogi sont émis, mais en fonction de la réponse, les trois autres sont également émis. La raison pour laquelle le taux de réponse correct n'est pas bon est que la précision du classificateur créé est médiocre. Je pense aussi que la raison pour laquelle personne n'a reçu de coussin est que plus de la moitié des données collectées était de 0 coussin.

Plan d'amélioration

・ Collectez plus de données (Le site source de la collecte répertorie les réponses de 2011 à avril 2014. Je souhaite collecter plus de données et atteindre le nombre de données ~~ C'est très gênant ~~) ・ Utilisez un corpus qui est fort dans les expressions verbales (je n'ai rien trouvé d'autre que le corpus de Wikipedia, donc si vous connaissez quelque chose de fort dans les expressions verbales, faites-le moi savoir) ・ Changer l'algorithme de classification (je pense essayer BERT car j'ai envie d'utiliser BERT dans mes recherches)

Recommended Posts

Prédisez le nombre de coussins qui peuvent être reçus en tant que répondants rires avec Word2Vec + Random Forest
[Python] Un programme qui trouve le nombre maximum de jouets pouvant être achetés avec votre argent
Prédire le nombre de personnes infectées par COVID-19 avec Prophet
[Python] Un programme pour trouver le nombre de pommes et d'oranges qui peuvent être récoltées
Récapitulatif du format des formats qui peuvent être sérialisés avec gensim
Mesurer l'importance des entités avec un outil de forêt aléatoire
Comparaison de 4 styles pouvant être passés à seaborn avec set_context
[Python] Code qui peut être écrit avec la mort cérébrale au début lors du scraping en tant que débutant
[Python] Un programme qui calcule le nombre de chaussettes jumelées
Nombre maximum de paramètres de fonction pouvant être définis dans chaque langue
Article qui peut être une ressource humaine qui comprend et maîtrise le mécanisme de l'API (avec du code Python)
Compter le nombre de caractères avec écho
Tensorflow, il semble que même la valeur propre de la matrice puisse être automatiquement différenciée
Astuces Python: Une combinaison de enumerate () et zip (), vérifiant si une chaîne peut être convertie en nombre, triant la chaîne sous forme de nombre
[Python] J'ai examiné une pratique qui peut être exécutée en parallèle avec le thread principal par traitement asynchrone (multiprocessing, asyncio)