[PYTHON] J'ai essayé d'estimer la similitude de l'intention de la question en utilisant Doc2Vec de gensim

introduction

L'autre jour, j'ai remarqué cette remarque de Shinjiro Koizumi.

«Imaginez le futur de la Diète, et quand les mêmes questions sont posées plusieurs fois, je veux que vous utilisiez l'intelligence artificielle. Il y a beaucoup de choses que vous pouvez faire, comme l'utilisation de l'intelligence artificielle et l'avenir de la Diète. Oui »(M. Koizumi, un résident,« Question similaire, à l'avenir, retournez avec AI »)

Alors, je me suis demandé si je pouvais vraiment faire ça, tout en étudiant Doc2Vec, j'ai essayé d'utiliser le "questionnaire", ce qui facilite dans une certaine mesure l'obtention de données. BERT (Représentations d'encodeur bidirectionnel à partir de transformateurs) et ELMo (Embeddings à partir de modèles de langage) sortent ces jours-ci, Doc2Vec? Je pense que certaines personnes disent cela, mais je pense que c'est toujours actif pour faire une petite analyse, comme être emballé dans gensim et facile à utiliser.

Énoncé de question

Lorsque vous posez une question à la Diète, vous pouvez penser à un membre de la Diète qui demande verbalement au ministre. Poser des questions au Cabinet sur les projets de loi et les politiques est une tâche importante pour les législateurs, mais ces questions peuvent également être posées par écrit. C'est l'énoncé de la question.

Le temps pour poser des questions au parlement est limité, en particulier parmi les partis minoritaires. Cet énoncé de question est souvent utilisé dans de tels cas. C’est l’une des méthodes de poursuite les plus importantes pour les parlementaires qui ont été exposés à l’incident du sida dans le passé.

Cependant, en règle générale, le Cabinet qui reçoit le questionnaire doit répondre par écrit dans les 7 jours, mais la réponse à ce moment-là doit être transmise par le Cabinet. Il semble que ce soit une tâche lourde pour le terrain car la réponse au questionnaire restera comme l'avis officiel du gouvernement, en partie parce qu'il a passé le conseil des ministres.

Quel est le "questionnaire" que Kasumi n'aime pas? ABC en termes d'actualité J'ai essayé d'utiliser WordCloud comme auteur du questionnaire pour la période visée cette fois. La présence écrasante de Muneo Suzuki ...

Doc2Vec Docment-to-Vector, qui représente les fonctionnalités document = document sous forme de vecteur. Doc2Vec a été proposé par Tomas Mikilov, qui a développé Word2Vec, et les deux méthodes suivantes sont proposées comme méthodes d'apprentissage.

Dans PV-DM, le vecteur de document est appris de manière à prédire le mot immédiatement suivant à partir du vecteur de mot qui est continu avec le vecteur de document.

Dans PV-DBOW, après avoir ignoré l'ordre des mots, le vecteur de phrase est appris de manière à deviner le mot contenu dans la phrase. On dit que la représentation distribuée des phrases par cette méthode est plus facile que PV-DM, mais moins précise. Comment utiliser la technologie de traitement du langage naturel - j'ai essayé de prédire la qualité des articles en utilisant Doc2Vec et DAN! -

Les données

Cette fois, je vais utiliser le questionnaire de la Chambre des représentants et de la Chambre des représentants obtenu en rampant et en grattant. En fait, j'allais extraire toutes les données de la 1ère Assemblée nationale, mais comme mon cœur se brisait au milieu, je me suis concentré sur Heisei et Reiwa et j'ai extrait les données du questionnaire. Le parlement cible est du 114e au 200e. De plus, comme Doc2Vec est le principal cette fois, je vais omettre le code d'exploration et de grattage et publier uniquement le résultat. De plus, dans cet article, nous allons modéliser de la 114e à la 199e Assemblée nationale et estimer la similitude du questionnaire à la 200e Assemblée nationale.

Avant de regarder le contenu des données, importez d'abord la bibliothèque. Puisque je dessine en japonais cette fois, j'utilise la police pour cela, NotoSansMonoCJKjp-Regular.otf. Adieu le tofu.

import numpy as np
import pandas as pd

import seaborn as sns
import matplotlib.pyplot as plt
from matplotlib.pylab import rcParams
from matplotlib.font_manager import FontProperties
font_path = "/mnt/c/u_home/font/NotoSansMonoCJKjp-Regular.otf"
font_prop = FontProperties(fname=font_path)

Eh bien, les données de cette fois sont comme ça. Du haut, les questionnaires des Chambres des Représentants de la 114e à la 199e, les questionnaires des Chambres des Représentants de la 200e Diète, et la période pendant laquelle la Diète est ouverte ([page ici]](Obtenu sur http://www.shugiin.go.jp/internet/itdb_annai.nsf/html/statics/shiryo/kaiki.htm).

data = pd.read_excel("data.xlsx")
data_200 = pd.read_excel("data_200.xlsx")
data_diet_open = pd.read_excel("data_diet_open.xlsx")

Trier par date et afficher les deux premiers et les deux derniers. ..

data.sort_values(by=['date']).iloc[np.r_[0:2, -2:0]]

s3.png Supplémentairement, «time» Session de la Diète au cours de laquelle le questionnaire a été soumis Chambre des représentants ou Chambre des conseillers «diet» title Le titre de l'énoncé de question nom Auteur du questionnaire date La date à laquelle le questionnaire a été soumis question Le texte de l'énoncé de question q_numb Nombre de questions dans l'énoncé de question (les détails seront décrits plus tard) year L'année où le questionnaire a été soumis month Le mois où le questionnaire a été soumis day Le jour où le questionnaire a été soumis

Les données les plus anciennes utilisées cette fois sont le "Questionnaire sur le contrôle des taux d'intérêt des prêteurs d'argent" soumis par le représentant Shigeji Inokuma le 1989-01-20, et la dernière est le représentant Nozomi Koga 2019-08- Il s'agit du "Questionnaire sur" les enquêtes sur les contrats et les efforts d 'amélioration du Japan Post Group "" soumis en 05. Le nombre de données est de 15 515. Pensez-vous que ce nombre de données n'est pas trop petit?

data.shape
(15515, 10)

Il en va de même pour les données de la 200e Assemblée nationale. Le nombre de données est de 167.

data_200.sort_values(by=['date']).iloc[np.r_[0:2, -2:0]]

s4.png Enfin, une liste des sessions parlementaires


EDA Explorez les données avant d'accéder à Doc2Vec

Nombre de documents principaux par année / mois / jour

Tout d'abord, un graphique pour chaque année. Il augmente rapidement depuis 2006 environ.

rcParams['figure.figsize'] = 8,4
data.groupby('year').size().plot.bar()
Puis mensuellement. Beaucoup en juin. Il y en a peu de juillet à septembre.
rcParams['figure.figsize'] = 8,4
data.groupby('year').size().plot.bar()

Enfin tous les jours. Étant donné que le nombre du 31e est petit en premier lieu, je comprends que le nombre d'intentions est également petit, mais il n'y a pas d'autre tendance que cela.

rcParams['figure.figsize'] = 8,4
data.groupby('day').size().plot.bar()

Convertir en données quotidiennes

Afin de comprendre combien d'intents ont été soumis chaque jour, nous avons trié par date et compté le nombre de cas, et fixé le nombre de jours non soumis à zéro, le premier jour de la 114e Assemblée nationale (30 décembre 1988). ) Jusqu'au dernier jour de la 199e Assemblée nationale (5 août 2019), je voudrais créer des données chronologiques.

def convert_to_daily(data):
    time_index = pd.DataFrame(index=pd.date_range('19881230','20190805'))
    #Définir les premier et dernier jours de la période cible

    doc_num_daily = pd.DataFrame(data.groupby('date').size(), columns=['doc_num'])
    #Comptez le nombre de documents principaux pour chaque date et entrez le nom de la colonne'doc_num'À

    data_daily = pd.concat([time_index, doc_num_daily], axis=1) #fusionner
    data_daily['doc_num'] = data_daily['doc_num'].fillna(0) #Aucune valeur manquante
    data_daily = data_daily.iloc[:,0] #Dans la série pandas
    
    return data_daily

data_daily = convert_to_daily(data) #Courir

De plus, pendant la période de régime, nous avons créé une fonction pour rendre la couleur de fond grise.

def plot_daily_data(data_daily, start_day, end_day):
    subdata = data_diet_open[(data_diet_open['end'] >= start_day) & (data_diet_open['end'] <= end_day)].sort_values(by='diet_time').reset_index(drop=True)
    plt.plot(data_daily.loc[start_day:end_day])
    plt.title("Number of docments between " + start_day + " and " + end_day)
    for i in range(subdata.shape[0]):
        plt.axvspan(subdata.start[i],subdata.end[i], color=sns.xkcd_rgb['grey'], alpha=0.5)

Alors complotez.

rcParams['figure.figsize'] = 20,5
start_day = "1988-12-30"; end_day = "2019-12-31"
plot_daily_data(data_daily, start_day, end_day)

D'une manière ou d'une autre, il augmente, et il semble qu'il augmente depuis 2004, mais c'est difficile à voir ... alors je l'ai divisé en trois parties.

start_day = "1988-12-30"; end_day = "1999-12-31"
plot_daily_data(data_daily, start_day, end_day)
start_day = "2000-01-01"; end_day = "2009-12-31"
plot_daily_data(data_daily, start_day, end_day)
start_day = "2010-01-01"; end_day = "2019-12-31"
plot_daily_data(data_daily, start_day, end_day)

Le questionnaire ne pouvant être soumis que pendant la session de la Diète, il est clair que le nombre de soumissions augmentera à la fin de chaque session de la Diète (= l'extrême droite du gris). Même ainsi, je l'ai divisé en trois parties et ai présenté le graphique, mais l'échelle sur le côté gauche augmente progressivement, ce qui montre clairement que l'énoncé de question est souvent utilisé de nos jours.

Afficher le nombre de questionnaires soumis dans un histogramme. C'est un beau graphique en pente descendante.

plt.hist(data_daily[data_daily > 0], bins=50)

s13.png

La valeur maximale est de 84 le 25 septembre 2015! Ce qui s'est passé ce jour-là sera décrit plus tard ...

data_daily.max()

doc_num    84.0
dtype: float64
data.groupby('date').size().idxmax()
Timestamp('2015-09-25 00:00:00')

De nom

J'aimerais voir quels parlementaires soumettent souvent le questionnaire. Tout d'abord, le nombre de parlementaires répertoriés dans les données est de 789. Veuillez noter que ces données traitent le nom commun comme "Masaken Akamine, Chizuru Takahashi, Hidekatsu Yoshii".

len(data.name.unique())
789

Au fait, voici le top 30 des personnes intéressées!

subdata = data.groupby('name').filter(lambda x: len(x) >= 100)
len(subdata.name.unique())
30 #Extrayez le top 30 des personnes

plot_value = subdata.groupby('name').size().sort_values(ascending=False)
plot_index = subdata.groupby('name').size().sort_values(ascending=False).index

rcParams['figure.figsize'] = 20,5
plt.bar(plot_index, plot_value)
plt.xticks(plot_index, rotation=90, fontproperties=font_prop)
for i, v in enumerate(plot_value):
    plt.text(i - 0.5, v + 5, str(v), color='blue')

C'est Muneo Suzuki qui a pris la tête de loin derrière la 2e place et en dessous. Ce nombre 2155 ... [Wikipédia](https://ja.wikipedia.org/wiki/%E8%B3%AA%E5%95%8F%E4%B8%BB%E6%84%8F%E6%9B%B8#%E6% 8F% 90% E5% 87% BA% E6% 95% B0) a également une description parfaite.

"Un exemple de beaucoup de soumissions est Muneo Suzuki, un nouveau parti qui a soumis 1900 questions à l'époque de l'opposition, également connu sous le nom de" roi des questions ". Muneo a quitté le parlement après avoir perdu son emploi en 2010, mais il a ensuite continué à soumettre le questionnaire à Takahiro Asano, qui est devenu son successeur dans le même nouveau parti. De plus, lorsque Takako Suzuki, la fille aînée de Muneo, a été élue en juin 2013, elle a attaqué par l'intermédiaire de Takako avec une enquête écrite. "

Muneo Suzuki

On dit que la présence de Muneo Suzuki a grandement changé le rôle du questionnaire. Il est également mentionné dans article NHK. Alors, je voudrais regarder le nombre de questions écrites par Muneo Suzuki.

muneo_daily = convert_to_daily(data[data['name']=="Muneo Suzuki"].reset_index(drop=True))

rcParams['figure.figsize'] = 20,5
plt.plot(data_daily)
plt.plot(muneo_daily)
for i in range(data_diet_open.shape[0]):
    plt.axvspan(data_diet_open.start[i],data_diet_open.end[i], color=sns.xkcd_rgb['grey'], alpha=0.4)
La couleur orange correspond au nombre de soumissions du questionnaire de M. Muneo Suzuki. Extension de la période pendant laquelle M. Muneo Suzuki soumettait le questionnaire,
start_day = "2005-10-03"; end_day = "2010-08-04"
subdata = data_diet_open[(data_diet_open['end'] >= start_day) & (data_diet_open['end'] <= end_day)].sort_values(by='diet_time').reset_index(drop=True)

plt.plot(data_daily.loc[start_day:end_day])
plt.plot(muneo_daily.loc[start_day:end_day])
plt.title("Number of docments between " + start_day + " and " + end_day)
for i in range(subdata.shape[0]):
    plt.axvspan(subdata.start[i],subdata.end[i], color=sns.xkcd_rgb['grey'], alpha=0.5)
De 2006 à 2007, vous pouvez voir que la plupart des questionnaires soumis étaient M. Muneo Suzuki.

Par date et auteur

La prochaine fois, j'aimerais trouver un membre qui soumet beaucoup par jour.

subdata = data.groupby(['name','date']).filter(lambda x: len(x) >= 15)
pd.DataFrame(subdata.groupby(['name','date']).size().sort_values(ascending=False))

Le sommet était M. Konishi, qui a soumis 55 livres le 25 septembre 2015. Comme prévu, il y a des moments où il a juste le surnom de "Quiz King of the Diet". Soit dit en passant, voici le titre du questionnaire de M. Konishi soumis ce jour-là.

Des titres similaires continuent, mais surtout 39 et 40 n'ont pas fonctionné ... Même si le coût de l'énoncé de question est crié, il semble que vous cherchiez une erreur.

  1. Questionnaire sur la valeur des bases militaires américaines au Japon basé sur l'alliance nippo-américaine aux États-Unis
  2. Question sur la valeur des bases de l'aviation militaire américaine au Japon sur la base de l'alliance nippo-américaine aux États-Unis

À ce sujet, cet article a également été rédigé.

«En regardant les questions posées par le représentant Konishi, qui a soumis un nombre record de 55 questions cette fois, il y a eu un cas dans lequel seulement une ligne et demie de questions a été posée à plusieurs reprises avec le même thème. Si le livre a le même thème, vous pouvez poser plusieurs questions de manière à puces. De nombreux contenus demandent également l'interprétation du libellé, et le Premier ministre Abe a dit un jour au Comité du budget: «Les questions comme les quiz sont productives. C'est une impression que des questions sans grande image s'alignent, me rappelant la scène où on m'a raconté. "

Nombre de questions dans la déclaration principale

Dans l'explication du nom de la colonne des données, j'ai écrit que q_numb sera décrit plus tard, mais cette fois, non seulement le nombre d'intentions de question mais également le nombre de questions décrites dans l'intention de question est extrait au moment du grattage. Par exemple, cette déclaration pose trois questions.

La partie numérique chinoise est une question individuelle. L'idée est que le coût réel peut être atteint en examinant le nombre de questions dans l'énoncé de question, pas seulement le nombre d'énoncé de question. Commençons par le nombre total de questions par jour.

def convert_to_daily_qnum_sum(data):
    time_index = pd.DataFrame(index=pd.date_range('19881230','20190805'))

    doc_num_daily = data.groupby(['date'], as_index=False)['q_numb'].sum()
    doc_num_daily.set_index('date', inplace=True)
    data_daily = pd.concat([time_index, doc_num_daily], axis=1)
    data_daily['q_numb'] = data_daily['q_numb'].fillna(0)
    data_daily = data_daily["q_numb"]
    
    return data_daily

convert_to_daily_qnum_sum(data).plot()
for i in range(data_diet_open.shape[0]):
    plt.axvspan(data_diet_open.start[i],data_diet_open.end[i], color=sns.xkcd_rgb['grey'], alpha=0.4)
Cela augmente également depuis 2000. En particulier, depuis 2007 environ, il y a eu 269 questions (2007-07-03), ce qui a considérablement augmenté, et plus de 200 jours ont été consultés depuis. Nous examinerons également le nombre moyen de questions par jour.
def convert_to_daily_qnum_mean(data):
    time_index = pd.DataFrame(index=pd.date_range('19881230','20190805'))

    doc_num_daily = data.groupby(['date'], as_index=False)['q_numb'].mean()
    doc_num_daily.set_index('date', inplace=True)
    data_daily = pd.concat([time_index, doc_num_daily], axis=1)
    data_daily['q_numb'] = data_daily['q_numb'].fillna(0)
    data_daily = data_daily["q_numb"]
    
    return data_daily

convert_to_daily_qnum_mean(data).plot()
for i in range(data_diet_open.shape[0]):
    plt.axvspan(data_diet_open.start[i],data_diet_open.end[i], color=sns.xkcd_rgb['grey'], alpha=0.4)

Il n'y a pas beaucoup de changement notable ici ... Le plus grand nombre de questions dans une question était le "Questionnaire sur les zones spéciales stratégiques nationales dans le secteur de l'emploi" de Kazunori Yamai avec 68 questions! D'une manière ou d'une autre, vous avez l'impression de passer un test, tel que "Veuillez donner trois exemples précis de clarification des règles de licenciement" et "L'article 16 de la loi sur le contrat de travail n'est-il pas applicable dans la zone spéciale en premier lieu?" devenu….

Doc2Vec

Partage

La recherche de données est devenue longue, mais voici la production réelle. Commencez par diviser la phrase en mots pour chaque corps de l'énoncé de question (écriture séparée). Par exemple, si «" Je suis un homme "», divisez-le en niveaux de mots, tels que «[Je suis un homme]», et séparez chacun d'eux par un espace d'une demi-largeur. Celui que j'ai utilisé cette fois dans la division est «MeCab». La fonction suivante est celle utilisée pour la division. Seuls les mots de pièce requis par «POS1» peuvent être extraits.

import MeCab
def word_pos(text, POS1=['Coalm','nom','adverbe','verbe','Préfixe','conjonction',
                         'Verbe auxiliaire','Particule','adjectif','symbole','Des mots impressionnants','Remplisseur','Autre']):

    tagger  = MeCab.Tagger('mecab -d /usr/lib/x86_64-linux-gnu/mecab/dic/mecab-ipadic-neologd')
    tagger.parse('')

    node = tagger.parseToNode(text)
    word_class = []
    while node:
        word = node.surface
        wclass = node.feature.split(',')
        if wclass[0] != u'BOS/EOS':
            if wclass[6] == None:
                if wclass[0] in POS1:
                    word_class.append((word,wclass[0],wclass[1],""))
            else:
                if wclass[0] in POS1:
                    word_class.append((word,wclass[0],wclass[1]))
        node = node.next
        
    word_class = pd.DataFrame(word_class, columns=['term', 'pos1', 'pos2'])
    
    return word_class

Après avoir effacé les blancs dans le corps de l'énoncé de question, nous extrairons uniquement la nomenclature et les adjectifs, puis effacerons les «queues», la «non-indépendance» et les «nombres» qui n'ont pas beaucoup de sens. Et stockez-le comme word_list dans data

data.question = data.question.str.replace("\u3000", " ")
data_200.question = data_200.question.str.replace("\u3000", " ")

data['word_list'] = ""

for i in range(data.shape[0]):
    each_data = word_pos(data.question[i], ["nom","adjectif"])
    each_data1 = each_data[each_data['pos2'] != 'suffixe']
    each_data1 = each_data1[each_data1['pos2'] != 'Non indépendant']
    each_data1 = each_data1[each_data1['pos2'] != 'nombre']
    data.loc[i,"word_list"] = " ".join(list(each_data1.term))

data_200['word_list'] = ""

for i in range(data_200.shape[0]):
    each_data = word_pos(data_200.question[i], ["nom","adjectif"])
    each_data1 = each_data[each_data['pos2'] != 'suffixe']
    each_data1 = each_data1[each_data1['pos2'] != 'Non indépendant']
    each_data1 = each_data1[each_data1['pos2'] != 'nombre']
    data_200.loc[i,"word_list"] = " ".join(list(each_data1.term))

Pour obtenir une image, je vais juste vous donner un exemple. Dans la ville de Kamakura, préfecture de Kanagawa, si vous utilisez word_pos pour traiter` la formation à l'évacuation du tsunami menée sur la plage de la ville, ce sera comme suit.

Doc2Vec Ici, nous allons diviser le texte en mots et les mettre dans la liste pour chaque question. L'image est [([mot 1, mot 2, mot 3], identifiant du document), ...]. Dans le code ci-dessous, les mots font référence à la liste des mots contenus dans le document (avec des mots en double) et les balises font référence à l'identifiant de l'énoncé de question (spécifié dans la liste. Plusieurs balises peuvent être ajoutées à une instruction de question). ..

docments = data.word_list
tagged_data = [TaggedDocument(words = data.split(),tags = [i]) for i,data in enumerate(docments)]

Apprentissage de modèle

model = Doc2Vec(documents=tagged_data, size=300, window=10, min_count=5, workers=4, seed=1, dm=1)

Pour les paramètres, size: longueur du vecteur window: taille de la fenêtre min_count: nombre minimum de mots à compter workers: nombre de threads seed: nombre aléatoire fixe dm: Si dm = 1, apprendre avec PV-DM, sinon avec DBoW Ce sera. En plus de cela, il y a ʻalpha et min_alphaqui spécifient le taux d'apprentissage, mais après avoir essayé diverses choses et les avoir évaluées qualitativement, je me suis arrêté sur les paramètres précédents. Pour être honnête,gensim` n'a pas de fonction pour calculer la perte automatiquement, donc j'ai senti qu'il serait beaucoup plus facile de modéliser cette zone par moi-même. De plus, je vois beaucoup de code de ce type dans le sens de l'apprentissage.

for epoch in range(10):
    print('iteration {0}'.format(epoch+1))
    model.train(tagged_data, total_examples=model.corpus_count, epochs=model.iter)
    model.alpha -= 0.0002 # decrease the learning rate
    model.min_alpha = model.alpha # fix the learning rate, no decay

Cependant, selon le créateur de gensim, il s'agit du code d'apprentissage de l'ancienne version de Doc2Vec, et la version actuelle n'a pas besoin d'être faite à moins que vous ne soyez un très expert. était. What does epochs mean in Doc2Vec and train when I have to manually run the iteration? "An advanced user who needed to do some mid-training logging or analysis or adjustment might split the training over multiple train() calls, and very consciously manage the effective alpha parameters for each call. An extremely advanced user experimenting with further training on an already-trained model might also try it, aware of all of the murky quality/balance issues that might involve. But essentially, unless you already know specifically why you'd need to do so, and the benefits and risks, it's a bad idea."

Il y a aussi un commentaire intéressant du créateur de gensim sur la taille du vecteur. Cette fois, la quantité de données est-elle à peine suffisante? what is the minimum dataset size needed for good performance with doc2vec? In general, word2vec/paragraph-vector techniques benefit from a lot of data and variety of word-contexts. I wouldn't expect good results without at least tens-of-thousands of documents. Documents longer than a few words each work much better. Results may be harder to interpret if wildly-different-in-size or -kind documents are mixed in the same training – such as mixing tweets and books.

model.save("doc2vec.model") #Enregistrer le modèle
model = Doc2Vec.load('doc2vec.model') #Appel de modèle

Énoncé de question similaire

Vous pouvez rechercher des intentions de question similaires avec model.docvecs.most_similar ().

model.docvecs.most_similar(10531)

[(12348, 0.8008440732955933),
 (10543, 0.7899609804153442),
 (10534, 0.7879745960235596),
 (12278, 0.7819333076477051),
 (14764, 0.7807815074920654),
 (13340, 0.7798347473144531),
 (11314, 0.7743450403213501),
 (14881, 0.7730422616004944),
 (1828, 0.7719383835792542),
 (14701, 0.7534374594688416)]

Ainsi, l'original et les deux premiers sont affichés

pd.set_option('display.max_colwidth', -1)
data.iloc[10531:10532,:6]

s23.png

idx = model.docvecs.most_similar(10531)[0][0]
pd.set_option('display.max_colwidth', -1)
data.iloc[idx:idx+1,:6]

s24.png

idx = model.docvecs.most_similar(10531)[1][0]
pd.set_option('display.max_colwidth', -1)
data.iloc[idx:idx+1,:6]

s25.png

Tous sont des sujets tels que les heures supplémentaires et la conciliation travail-vie personnelle, donc je pense que c'est un bon résultat.

Similitude avec le nouvel énoncé de question

Eh bien, le sujet principal est enfin d'ici.

«Imaginez le futur de la Diète, et quand les mêmes questions sont posées plusieurs fois, je veux que vous utilisiez l'intelligence artificielle. Il y a beaucoup de choses que vous pouvez faire, comme l'utilisation de l'intelligence artificielle et l'avenir de la Diète. Oui "(M. Shinjiro Koizumi)

Nous évaluerons le degré de similitude à l'aide du questionnaire de la 200e Assemblée nationale, qui n'est pas dans le modèle. Utilisez model.infer_vector () pour transformer un nouveau document en vecteur. Pour (), spécifiez un nouveau document et step combien de fois le modèle doit être tourné. Le nombre d'étapes a été fixé à 20 sur la base de l'avis du créateur de «gensim». De plus, le vecteur pour ce nouveau document est model.docvecs.most_similar (positive = [new_docvec], topn = 1), qui calcule la similitude avec le document dans le modèle existant. «topn» est le nombre de documents principaux à extraire.

list_most_sim_doc   = []
list_most_sim_value = []

for i in range(data_200.shape[0]):
    new_doc = data_200.loc[i,'word_list']
    new_doc = new_doc.split(" ")
    new_docvec = model.infer_vector(new_doc, steps=20)
    most_sim_doc   = model.docvecs.most_similar(positive=[new_docvec], topn=1)[0][0]
    most_sim_value = model.docvecs.most_similar(positive=[new_docvec], topn=1)[0][1]
    
    list_most_sim_doc.append(most_sim_doc)
    list_most_sim_value.append(most_sim_value)

La répartition des similitudes est la suivante. Plus il est proche de 1, plus il est proche.

plt.hist(list_most_sim_value, bins=50)
Combinez maintenant l'ID de document le plus proche et les valeurs de similitude avec l'ensemble de données existant.
new_doc_sim = pd.DataFrame({"sim_doc":list_most_sim_doc,"sim_value":list_most_sim_value})
data_200_sim = pd.concat([data_200, new_doc_sim], axis= 1)

Cliquez ici pour les 3 principales similitudes. Tous sont supérieurs à 0,8.

pd.reset_option('^display.', silent=True)
data_200_sim = data_200_sim.sort_values(by='sim_value', ascending=False).reset_index(drop=True)
data_200_sim.head(3)

s27.png

Contenu de l'énoncé de question

Partie 1

De quel type de contenu s'agit-il? Document 1 de la 200e Assemblée nationale. Le contenu est la raison pour laquelle le médicament Gardacil n'est pas approuvé.

idx=data_200_sim.index[1]
pd.set_option('display.max_colwidth', -1)
data_200_sim.iloc[idx:idx+1,:6]

s30.png Ensuite, le document 1 de la 200e Assemblée nationale est le document le plus proche du modèle. longue…. Le contenu concerne l'approbation d'un médicament appelé Iressa. Résultat raisonnable.

idx=data_200_sim.index[0]
pd.set_option('display.max_colwidth', -1)
data_200_sim.iloc[idx:idx+1,:6]

s31.png

Partie 2

Document 2 de la 200e Assemblée nationale. longue…. Le contenu est des mesures de stimulation économique basées sur la théorie du MMT.

idx=data_200_sim.index[0]
pd.set_option('display.max_colwidth', -1)
data_200_sim.iloc[idx:idx+1,:6]

s28.png Ensuite, le document 2 de la 200e Assemblée nationale est le document le plus proche du modèle. Plus long ... Contenu des mesures de relance économique pour le moment. Pas mal de résultat.

idx=data_200_sim.index[0]
pd.set_option('display.max_colwidth', -1)
data_200_sim.iloc[idx:idx+1,:6]

s29.png

Partie 3

Document 3 de la 200e Assemblée nationale. Le contenu concerne le pardon de l'ère Reiwa.

idx=data_200_sim.index[2]
pd.set_option('display.max_colwidth', -1)
data_200_sim.iloc[idx:idx+1,:6]

s32.png Le document le plus proche du modèle concerne également la grâce de l'ère Reiwa. C'est aussi un bon résultat.

idx=data_200_sim.sim_doc[2]
pd.set_option('display.max_colwidth', -1)
data.iloc[idx:idx+1,:6]

s33.png

en conclusion

La recherche de données est devenue amusante en cours de route, et je l'ai écrite pendant longtemps en vain, mais en essayant à la légère Doc2Vec, j'ai pu assez bien estimer la similitude pour le nouveau document appelé l'énoncé de question de la 200e diète. N'est-ce pas? D'un autre côté, j'ai l'impression que le monde où l'IA pose des questions comme le dit M. Shinjiro Koizumi est un événement futur qui n'est pas proche.

Cette fois, j'ai essayé la recherche de données et le jugement de similitude en utilisant Doc2Vec, mais à l'avenir, je ferai du regroupement tout en mélangeant les données du parti politique, et jugerai la «qualité» de l'énoncé de question que je veux vraiment essayer J'aimerais essayer. En particulier, en ce qui concerne la "qualité" du questionnaire, je pense que nous pouvons changer le ton selon lequel la simple émission d'un grand nombre de questionnaires aboutira à des résultats.

J'ai un ensemble de données d'exploration et de grattage dans ma main, donc si quelqu'un veut analyser et analyser à l'aide de ces données, j'espère que nous pourrons faire quelque chose ensemble!

Recommended Posts

J'ai essayé d'estimer la similitude de l'intention de la question en utilisant Doc2Vec de gensim
J'ai essayé d'estimer la section.
J'ai essayé d'estimer le rapport de circonférence π de manière probabiliste
J'ai essayé d'obtenir l'index de la liste en utilisant la fonction énumérer
J'ai essayé de transformer l'image du visage en utilisant sparse_image_warp de TensorFlow Addons
J'ai essayé d'obtenir les résultats de Hachinai en utilisant le traitement d'image
J'ai essayé de corriger la forme trapézoïdale de l'image
(Python) J'ai essayé d'analyser 1 million de mains ~ J'ai essayé d'estimer le nombre d'AA ~
J'ai essayé d'extraire et d'illustrer l'étape de l'histoire à l'aide de COTOHA
J'ai essayé l'histoire courante de l'utilisation du Deep Learning pour prédire la moyenne Nikkei
En utilisant COTOHA, j'ai essayé de suivre le cours émotionnel de la course aux meros.
J'ai essayé d'utiliser le filtre d'image d'OpenCV
J'ai essayé de vectoriser les paroles de Hinatazaka 46!
J'ai essayé de prédire la détérioration de la batterie lithium-ion en utilisant le SDK Qore
J'ai essayé de notifier la mise à jour de "Hameln" en utilisant "Beautiful Soup" et "IFTTT"
[Python] J'ai essayé de juger l'image du membre du groupe d'idols en utilisant Keras
J'ai essayé de résumer la forme de base de GPLVM
J'ai essayé d'approcher la fonction sin en utilisant le chainer
J'ai essayé d'utiliser l'API de Sakenowa Data Project
J'ai essayé de visualiser les informations spacha de VTuber
J'ai essayé d'effacer la partie négative de Meros
J'ai essayé d'identifier la langue en utilisant CNN + Melspectogram
J'ai essayé de compléter le graphe de connaissances en utilisant OpenKE
J'ai essayé de classer les voix des acteurs de la voix
J'ai essayé de compresser l'image en utilisant l'apprentissage automatique
J'ai essayé de résumer les opérations de chaîne de Python
J'ai essayé de prédire la victoire ou la défaite de la Premier League en utilisant le SDK Qore
J'ai essayé de notifier la mise à jour de "Devenir romancier" en utilisant "IFTTT" et "Devenir un romancier API"
Python pratique 100 coups J'ai essayé de visualiser l'arbre de décision du chapitre 5 en utilisant graphviz
J'ai essayé d'extraire le texte du fichier image en utilisant Tesseract du moteur OCR
[Courses de chevaux] J'ai essayé de quantifier la force du cheval de course
J'ai essayé d'obtenir les informations de localisation du bus Odakyu
J'ai essayé de trouver la moyenne de plusieurs colonnes avec TensorFlow
J'ai essayé de refactoriser le modèle CNN de TensorFlow en utilisant TF-Slim
J'ai essayé de simuler l'optimisation des publicités à l'aide de l'algorithme Bandit
J'ai essayé la reconnaissance faciale du problème du rire en utilisant Keras.
[Python] J'ai essayé de visualiser la relation de suivi de Twitter
[TF] J'ai essayé de visualiser le résultat de l'apprentissage en utilisant Tensorboard
[Apprentissage automatique] J'ai essayé de résumer la théorie d'Adaboost
[Python] J'ai essayé de collecter des données en utilisant l'API de wikipedia
J'ai essayé de combattre le minimum local de la fonction Goldstein-Price
J'ai essayé d'approcher la fonction sin en utilisant chainer (re-challenge)
J'ai essayé de sortir le journal d'accès au serveur en utilisant Node.js
J'ai essayé de comparer la précision des modèles d'apprentissage automatique en utilisant kaggle comme thème.
J'ai essayé d'utiliser GrabCut d'OpenCV
J'ai essayé de prédire l'infection d'une nouvelle pneumonie en utilisant le modèle SIR: ☓ Wuhan edition ○ Hubei province edition
J'ai essayé de déplacer le ballon
J'ai essayé d'automatiser la construction d'un environnement pratique à l'aide de l'API SoftLayer d'IBM Cloud
J'ai essayé d'utiliser l'API checkio
[Linux] J'ai essayé de résumer les commandes de confirmation des ressources
J'ai essayé d'obtenir une base de données sur les courses de chevaux en utilisant Pandas
J'ai essayé d'automatiser l'arrosage du pot avec Raspberry Pi
J'ai essayé de créer une expression régulière de "montant" en utilisant Python
J'ai essayé de créer une expression régulière de "temps" en utilisant Python
J'ai essayé de créer l'image de démarrage SD de LicheePi Nano
Je voulais contester la classification du CIFAR-10 en utilisant l'entraîneur de Chainer
J'ai essayé de créer une expression régulière de "date" en utilisant Python
J'ai regardé les méta-informations de BigQuery et essayé de les utiliser