Étudiant qui ne veut pas lire des articles en anglais (python)

Je veux profiter de la lecture des journaux anglais! !! !!

Je suis trop mauvais en anglais et je ne peux pas faire un cercle, alors j'ai pensé qu'il y avait un moyen d'en profiter. Ce que j'ai proposé, c'est de faire quelque chose comme un résumé et de traduire la phrase en anglais ...

Environnement de vérification de fonctionnement

Qu'est-ce que Colaboratory?

Colaboratory est un environnement de notebook Jupyter qui s'exécute entièrement dans le cloud. Aucun réglage requis et peut être utilisé gratuitement. Avec Colaboratory, vous pouvez écrire et exécuter du code, stocker et partager des analyses, accéder à de puissantes ressources informatiques, etc., le tout gratuitement à partir de votre navigateur. Pouvez. Désolé, la vidéo ne peut pas être lue.

procédure

  1. Extrayez uniquement le texte du document (supprimez les titres, les noms de chapitre, les graphiques et les références)
  2. Appliquez LexRank au texte de chaque chapitre et extrayez le texte clé
  3. Combinez des phrases clés dans chaque chapitre et utilisez un modèle de langage pour créer des phrases proches d'un résumé

À propos de LexRank

Les résumés de phrases peuvent être largement divisés en types extractifs et génératifs. LexRank est un algorithme de synthèse classé comme un type d'extrait. En créant une structure graphique à partir d'un document et en créant un classement des phrases importantes, une phrase qui peut être considérée comme un résumé est produite. Proposé par Gunes Erkan, Dragomir R. Radev en 2004.

Prenons LexRank, une nouvelle approche pour calculer l'importance d'une phrase basée sur le concept de centralité des vecteurs propres dans la représentation graphique de la phrase. Dans ce modèle, la matrice de connectivité basée sur la similitude cosinus intra-phrase est utilisée comme matrice de contiguïté pour la représentation graphique de la phrase.

We consider a new approach, LexRank, for computing sentence importance based on the concept of eigenvector centrality in a graph representation of sentences. In this model, a connectivity matrix based on intra-sentence cosine similarity is used as the adjacency matrix of the graph representation of sentences.

20181117143216.png

Cela a été expliqué en détail dans l'article d'Ohke.

LexRank a deux points clés, qui est un dérivé du TextRank (document de proposition PDF) inspiré du PageRank. Créez un graphe non directionnel avec des instructions comme nœuds et des similitudes entre les phrases comme arêtes. Dans l'article proposé, il est calculé à partir de TF-IDF par similarité cosinus (word2vec etc. devrait être utilisable dans les temps modernes). Calculez jusqu'à ce que la matrice de probabilité de transition (M) et le vecteur de probabilité (P) obtenus à partir du graphique ci-dessus soient stables (MP = P), et sélectionnez la phrase avec la plus grande valeur finale du vecteur de probabilité comme phrase récapitulative. Dans la figure ci-dessus (extraite de l'article proposé Figure 2) qui visualise la théorie ci-dessus, d5s1 et d4s1 avec de nombreux bords (= similaires à de nombreuses phrases) et des bords épais (= haute similitude) sont représentés. Candidat au résumé.

la mise en oeuvre

L'importation de la bibliothèque est la suivante. Il utilise les bibliothèques nécessaires pour implémenter et partager LexRank et construire le modèle de langage LSTM.

from __future__ import absolute_import
from __future__ import division, print_function, unicode_literals
from sumy.parsers.html import HtmlParser
from sumy.parsers.plaintext import PlaintextParser
from sumy.nlp.tokenizers import Tokenizer
from sumy.summarizers.lsa import LsaSummarizer as Summarizer
from sumy.nlp.stemmers import Stemmer
from sumy.utils import get_stop_words
from keras.callbacks import LambdaCallback
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import LSTM
from keras.optimizers import RMSprop
from keras.utils.data_utils import get_file
from googletrans import Translator
import nltk
import numpy as np
import random
import sys
import io
import os
import glob

Supplément: Lors de l'utilisation de nltk, il semble qu'il puisse être utilisé en mettant à jour tout le paquet punkt.

!python -c "import nltk; nltk.download('punkt')"

Partie LexRank (implémentation utilisant sumy)

def sectionLex():
  #Langue définie sur l'anglais
  LANG = "english"
  #.fichier txt(Données corporelles pour chaque section)Tout sélectionner
  file = glob.glob('*.txt')
  ex = []
  for i in range(len(file)):
    parser = PlaintextParser.from_file(file[i], Tokenizer(LANG))
    stemmer = Stemmer(LANG)
    summarizer = Summarizer(stemmer)
    summarizer.stop_words = get_stop_words(LANG)
    for sentence in summarizer(parser.document, [Combien de phrases sortir]):
      ex.append(str(sentence) + '\n')
    # utf-Sortie avec 8 encodages
    with open('output.txt', mode='w', encoding='utf-8') as f:
      f.writelines(ex)

Déclaration des variables utilisées dans le dictionnaire

#Liste de dictionnaires réguliers
chr_index = {}
#Liste de dictionnaire inversé
rvs_index = {}
#Liste des déclarations
sentences = []
#Mot suivant
next_word = []

Partage

# utf-Lire avec 8 encodage et stocker dans le texte
with io.open('output.txt', encoding='utf-8') as f:
    text = f.read().lower()

#Décomposer mot par mot (écriture séparée)
text = nltk.word_tokenize(text)
chars = text

Créer un dictionnaire


#Créez une liste dans l'ordre
count = 0
for c in chars:
    if not c in chr_index:
        chr_index[c] = count
        count += 1
        print(count, c)
#Créer une liste dans l'ordre inverse
rvs_index = dict([(value, key) for (key, value) in chr_index.items()])

Créer des sous-chaînes

for i in range(0, len(text) - maxlen, step):
    #Sous-chaîne de mots maxlen(1 phrase)Stocké comme
    sentences.append(text[i: i + maxlen])
    #Stocke le mot suivant de la sous-chaîne stockée
    next_word.append(text[i + maxlen])

Vectorisation de mots

#np.tableau 3D de type booléen:(Nombre de sous-chaînes, longueur maximale des sous-chaînes, nombre de mots)
x = np.zeros((len(sentences), maxlen, len(chars)), dtype=np.bool)
#np.Tableau bidimensionnel de type booléen:(Nombre de sous-chaînes, nombre de mots)
y = np.zeros((len(sentences), len(chars)), dtype=np.bool)
#Vectoriser chaque sous-chaîne
for i, sentence in enumerate(sentences):
    for t, ch in enumerate(sentence):
        x[i, t, chr_index[ch]] = 1
    y[i, chr_index[next_word[i]]] = 1

Créer un modèle

Cette fois, j'utilise le modèle séquentiel. Concernant softmax, [l'article] de @ rtok (https://qiita.com/rtok/items/b1affc619d826eea61fd) était facile à comprendre.

#Faire un modèle simple
model = Sequential()
#Utilise LSTM. La taille du lot est de 128
model.add(LSTM(128, input_shape=(maxlen, len(chars))))
#Permet de calculer la probabilité avec softmax pour chaque mot
model.add(Dense(len(chars), activation='softmax'))

J'ai utilisé RMSprop pour méthode de gradient. Pour RMSprop, [l'article] de @ tokkuman (https://qiita.com/tokkuman/items/1944c00415d129ca0ee9#rmsprop) était facile à comprendre.

optimizer = RMSprop(learning_rate=0.01)
model.compile(loss='categorical_crossentropy', optimizer=optimizer)

Calculez le taux d'apparition de chaque mot et sélectionnez le mot à sortir

#preds: sortie du modèle. type float32.
#température: Variété. Plus la valeur est basse, plus il est facile de sélectionner celle avec le taux d'apparition le plus élevé.
#La sortie du modèle est sous la forme d'une distribution polynomiale, donc la somme est 1.Devenir 0
def selectWD(preds, temperature=1.0):
    #Convertir en type float64
    preds = np.asarray(preds).astype('float64')
    #Divisez le logarithme naturel par la variété pour faciliter le choix des mots à faible probabilité
    preds = np.log(preds) / temperature
    #Transformer à l'inverse le logarithme naturel de la probabilité (en faire une fonction exponentielle naturelle)
    exp_preds = np.exp(preds)
    #Divisez toutes les valeurs par somme pour que la somme soit 1
    preds = exp_preds / np.sum(exp_preds)
    #Sélectionné au hasard selon la distribution polynomiale
    probas = np.random.multinomial(1, preds, 1)
    return np.argmax(probas)

Traitement pour chaque époque

def on_epoch_end(epoch, _):
    print()
    print('----- Generating text after Epoch: %d' % epoch)
    #Mettez les 4 premiers mots au début de la chaîne d'entrée
    start_index = 0
    #diversité: diversité. Identique à la température SelectWD. Les caractères avec une probabilité plus faible sont également sélectionnés car ils sont plus élevés.
    for diversity in [0.2, 0.5, 0.8, 1.0]:
        print('----- diversity:', diversity)
        #Pour la sortie
        generated = ''
        sentence = text[start_index: start_index + maxlen]
        generated += " ".join(sentence)
        print(" ".join(sentence))

        print('----- Generating with seed: "' + " ".join(sentence)+ '"')
        sys.stdout.write(generated)
        
        #Sortie de phrases OUTSEN ou fin avec une sortie de 1000 mots
        flag = OUTSEN
        for i in range(1000):
            #Quel mot est dans quelle position dans la phrase actuelle
            x_pred = np.zeros((1, maxlen, len(chars)))
            for t, ch in enumerate(sentence):
                x_pred[0, t, chr_index[ch]] = 1.
            #Prédire le mot suivant
            preds = model.predict(x_pred, verbose=0)[0]
            next_index = selectWD(preds, diversity)
            next_char = rvs_index[next_index]
            #Supprimez le premier mot et ajoutez le mot prédit après
            sentence = sentence[1:]
            sentence.append(next_char)
            #Organisation de sortie
            if next_char == '.':
                flag -= 1
                generated += next_char + "\n"
                sys.stdout.write(next_char+"\n")
            elif next_char == ',':
                generated += next_char
                sys.stdout.write(next_char)
            else:
                generated += " " + next_char
                sys.stdout.write(" "+next_char)
            sys.stdout.flush()
            if flag <= 0:
                break
        sys.stdout.flush()
        print()
#Configuré pour appeler le processus ci-dessus à chaque époque
print_callback = LambdaCallback(on_epoch_end=on_epoch_end)

Processus de montage

#Taille de lot 128, numéro d'époque 100, appelez la fonction précédemment décrite
model.fit(x, y, batch_size=128, epochs=100, callbacks=[print_callback])

résultat

C'est le résultat de l'utilisation de Botta et al.

----- Generating text after Epoch: 99 ----- diversity: 0.2 in general , iot ----- Generating with seed: "in general , iot" in general , iot can benefit from the virtually unlimited capabilities and resources of cloud to compensate its technological constraints ( e.g., storage, processing, communication ). being iot characterized by a very high heterogeneity of devices, technologies, and protocols, it lacks different important properties such as scalability, interoperability, flexibility, reliability, efficiency, availability, and security. as a consequence, analyses of unprecedented complexity are possible, and data-driven decision making and prediction algorithms can be employed at low cost, providing means for increasing revenues and reduced risks. the availability of high speed networks enables effective monitoring and control of remote things, their coordination, their communications, and real-time access to the produced data. this represents another important cloudiot driver : iot processing needs can be properly satisfied for performing real-time data analysis ( on-the-fly ), for implementing scalable, real-time, collaborative, sensor-centric applications, for managing complex events, and for supporting task offloading for energy saving.

Je produis 5 phrases, mais quand je le traduis en japonais avec la traduction Google, cela ressemble à ceci.

De manière générale, iot peut bénéficier de fonctionnalités et de ressources quasiment illimitées dans le cloud pour compenser les contraintes techniques (stockage, traitement, communication, etc.). Il présente un très haut degré d'hétérogénéité des dispositifs, des technologies et des protocoles, et manque de diverses propriétés importantes telles que l'évolutivité, l'interopérabilité, la flexibilité, la fiabilité, l'efficacité, la disponibilité et la sécurité. Le résultat est une analyse de complexité sans précédent et une adoption à faible coût d'algorithmes de prise de décision et de prévision basés sur les données pour augmenter les revenus et réduire les risques. La disponibilité du réseau haut débit permet une surveillance et un contrôle efficaces des objets distants, leur coordination, leur communication et l'accès en temps réel aux données générées. Cela représente un autre pilote cloudiot important: effectuer une analyse de données en temps réel (à la volée), mettre en œuvre des applications évolutives et centrées sur les capteurs axées sur la collaboration en temps réel, gérer des événements complexes et décharger des tâches pour économiser de l'argent. Les soutiens.

On a l'impression que c'est organisé!

Le code source complet est disponible sur github. Il y a des choses étranges en japonais, alors je vais l'améliorer ...

Recommended Posts