Phrasen-Stimmungsanalyse unter Verwendung neuronaler Netze

Hallo alle zusammen!

Alle Personen, die eine höhere Ausbildung erhalten, ohne ausgewiesen zu werden, erreichen dennoch das Stadium des Schreibens eines Diploms. Ich war keine Ausnahme. Ich wollte etwas Interessantes implementieren und das bisher Unerforschte beherrschen, deshalb machte ich auf das Thema neuronale Netze und künstliche Intelligenz im Allgemeinen aufmerksam. Und die Aufgabe, die ich mit ihrer Hilfe gelöst habe, ist die Analyse der Tonalität des Textes, die in verschiedenen Überwachungssystemen bereits weit verbreitet ist. Ich werde versuchen, den Prozess seiner Lösung in diesem Artikel zu beschreiben.

Kurz gesagt, das Ziel ist zu verstehen, ob eine Phrase eine positive oder eine negative Konnotation hat. Ich möchte gleich sagen, dass dieses Problem auf verschiedene Weise gelöst werden kann, nicht nur durch neuronale Netze. Wir können Wörterbücher erstellen, in denen die Positionen von Wörtern usw. markiert sind. (Alle Methoden sind auf dem Hub im Überfluss vorhanden), aber jede Methode kann je nach Artikel weiter gehen, sodass wir ihre Überprüfung für später belassen.

Daten


Die erste Aufgabe auf meinem Weg war das Sammeln und Vorverarbeiten von Daten für das Training. Ein guter Datensatz für einen solchen Fall ist das Korpus von Kurztexten von Y. Rubtsova, die zuvor in negative und positive Sätze unterteilt waren, die auf Twitter gesammelt wurden. Was besonders praktisch ist - all dies existiert im CSV-Format.

Trainingsvorbereitung


Achten Sie auf die Form, in der die Daten dargestellt werden - viele Emoticons, Links, unnötige Zeichen, Treffer. All dies ist keine wichtige Information und stört nur das Lernen, außerdem muss alles auf Latein entfernt werden. Daher wäre der Text gut vorzuverarbeiten.

def preprocessText(text):
    text = text.lower().replace("", "")
    text = re.sub('((www\.[^\s]+)|(https?://[^\s]+))', ' ', text)
    text = re.sub('@[^\s]+', ' ', text)
    text = re.sub('[^a-zA-Z--1-9]+', ' ', text)
    text = re.sub(' +', ' ', text)
    return text.strip()

Nachdem wir alle Sätze aus der Datei entfernt haben, bringen wir sie in Kleinbuchstaben, ersetzen "" durch "e", Verweise, Erwähnungen, entfernen wir einfach die englischen Wörter aus Mangel an Bedeutung. Kurz gesagt, wir machen sie zum gleichen Typ und beseitigen den „Müll“, der für das Training überflüssig ist.

Werkzeuge


Wenn Sie zu Hause einen Supercomputer haben, können Sie diesen Abschnitt natürlich weiter nach unten scrollen und nach einem interessanten Teil suchen. Ich empfehle den Rest des Dienstes Google Colab , mit dem Sie Jupyter-Notizbücher (und wer noch nichts davon gehört hat, um der Suchmaschine zu helfen) nur mit einem Browser ausführen können. Die gesamte Arbeit wird auf einer virtuellen Maschine in der Cloud ausgeführt.
Die temporäre Größe der Sitzung, die Sie für die Arbeit erhalten, ist auf 12 Stunden begrenzt. Sie können sie früher beenden. Danach wird alles zurückgesetzt.

Wir schreiben unseren schönen Code


Wie jeder andere Neuling im maschinellen Lernen habe ich mich für Python entschieden - weil es einfach ist und Bibliotheken eine ganze Cloud sind.

Zunächst führt der Paketmanager einen wichtigen Befehl aus, dessen Bedeutung ich etwas später erläutern werde.

Bild

Als nächstes importieren wir die Bibliotheken, die wir beim Trainieren des Rasters und beim Vorbereiten der Daten verwenden werden. Ich denke, viele davon sind Ihnen vertraut.

Bild

Endlich auf den Punkt.

Warum haben wir die Tensorflow-Textbibliothek heruntergeladen und importiert? Tatsache ist, dass Phrasen nicht in der Form, in der sie für uns lesbar sind, dem Raster „zugeführt“ werden können. Hier kommt Word Embedding ins Spiel, ein Begriff, für den ich keine angemessene Übersetzung gefunden habe, und im Allgemeinen bezweifle ich seine Existenz. Aber grob gesagt geht es darum, einen Vektor einem Wort zuzuordnen. Das ist gut gesagt hier .

Wir müssen ganze Sätze in einen Vektor konvertieren, daher verwenden wir eine vorgefertigte Lösung von Google - Universal Satzcodierer.

Bild

Sie können es von der Nabe Download hier . Dort gibt es übrigens viele weitere interessante vorgefertigte Lösungen, die beim Erlernen eines neuronalen Netzwerks verwendet werden können, um sich nicht zu stören.

Bild

Alle Tweets sind nach Klassen klassifiziert - schlecht / gut. Wir erstellen einen Pandas-Datenrahmen, in dem sie nach Klassen sortiert sind (die schlechten sind auf dem Bild nicht sichtbar, da sie passen).

Bild

Wir haben die Daten vorbereitet - kommen wir zum Modell selbst. Verwenden Sie dazu das Keras-Framework.

from tensorflow import keras
from tensorflow.keras import layers
from tensorflow.keras.models import Sequential, load_model
model = tf.keras.Sequential()

model.add(
  tf.keras.layers.Dense(
    units=256,
    input_shape=(X_train.shape[1], ),
    activation='relu'
  )
)
model.add(
  tf.keras.layers.Dropout(rate=0.5)
)

model.add(
  tf.keras.layers.Dense(
    units=128,
    activation='relu'
  )
)
model.add(
  tf.keras.layers.Dropout(rate=0.5)
)

model.add(tf.keras.layers.Dense(2, activation='softmax'))
model.compile(
    loss='categorical_crossentropy',
    optimizer=tf.keras.optimizers.Adam(0.001),
    metrics=['accuracy']
)

history = model.fit(
    X_train, y_train,
    epochs=10,
    batch_size=16,
    validation_split=0.1,
    verbose=1,
    shuffle=True
)

model.evaluate(X_test, y_test)

Ein wenig über das Modell selbst. Es verfügt über Eingabe-, ausgeblendete und Ausgabeebenen.

Jede Schicht hat ihre eigene Aktivierungsfunktion.

Eine kleine Erklärung: In künstlichen neuronalen Netzen bestimmt die Neuronenaktivierungsfunktion das Ausgangssignal, das durch das Eingangssignal oder eine Reihe von Eingangssignalen bestimmt wird. Sie können hier mehr lesen , übrigens gibt es viele davon für verschiedene Aufgaben, aber wir werden nur mit 2 arbeiten. Wir

weisen den ersten beiden Schichten die Aktivierungsfunktion ReLu zu . Der freie Tag ist Softmax .

Zusätzlich zum Hinzufügen von Ebenen können Sie das Wort „Dropout“ bemerken. Was ist es? Seltsamerweise, aber zusätzlich zu dem Problem des Unterlernens eines neuronalen Netzwerks, wenn seine Vorhersagen nicht zutreffen, gibt es das Problem des Übertrainings - das Modell erklärt nur Beispiele aus der Trainingsstichprobe gut und passt sich den Trainingsbeispielen an, anstatt zu lernen, Beispiele zu klassifizieren, die nicht am Training teilgenommen haben. Das ist kitschig bei den neuen Daten, Ihr wunderschönes Model, das ihre Arbeit zuvor hervorragend gemacht hat, „fliegt“ einfach und beginnt Sie unangenehm zu überraschen. Dropout beschäftigt sich also mit der Tatsache, dass es mit einer bestimmten Wahrscheinlichkeit Neuronen aus dem Gitter „ausschaltet“, so dass sie nicht mehr am Lernprozess teilnehmen. Dann werden die Ergebnisse aus mehreren Netzwerken gemittelt (wenn ein Neuron aus dem Netzwerk ausgeschlossen wird, wird ein neues erhalten).

Übrigens ein toller Artikel für Interessierte.

Du kannst anfangen zu lernen!

Train on 53082 samples, validate on 5898 samples
Epoch 1/10
53082/53082 [==============================] - 12s 223us/sample - loss: 0.5451 - accuracy: 0.7207 - val_loss: 0.5105 - val_accuracy: 0.7397
Epoch 2/10
53082/53082 [==============================] - 11s 213us/sample - loss: 0.5129 - accuracy: 0.7452 - val_loss: 0.5000 - val_accuracy: 0.7523
Epoch 3/10
53082/53082 [==============================] - 11s 215us/sample - loss: 0.4885 - accuracy: 0.7624 - val_loss: 0.4914 - val_accuracy: 0.7538
Epoch 4/10
53082/53082 [==============================] - 11s 215us/sample - loss: 0.4686 - accuracy: 0.7739 - val_loss: 0.4865 - val_accuracy: 0.7589
Epoch 5/10
53082/53082 [==============================] - 11s 214us/sample - loss: 0.4474 - accuracy: 0.7889 - val_loss: 0.4873 - val_accuracy: 0.7616
Epoch 6/10
53082/53082 [==============================] - 11s 216us/sample - loss: 0.4272 - accuracy: 0.8004 - val_loss: 0.4878 - val_accuracy: 0.7603
Epoch 7/10
53082/53082 [==============================] - 11s 213us/sample - loss: 0.4081 - accuracy: 0.8111 - val_loss: 0.4986 - val_accuracy: 0.7594
Epoch 8/10
53082/53082 [==============================] - 11s 215us/sample - loss: 0.3899 - accuracy: 0.8241 - val_loss: 0.5101 - val_accuracy: 0.7564
Epoch 9/10
53082/53082 [==============================] - 11s 215us/sample - loss: 0.3733 - accuracy: 0.8315 - val_loss: 0.5035 - val_accuracy: 0.7633
Epoch 10/10
53082/53082 [==============================] - 11s 215us/sample - loss: 0.3596 - accuracy: 0.8400 - val_loss: 0.5239 - val_accuracy: 0.7620
6554/6554 [==============================] - 0s 53us/sample - loss: 0.5249 - accuracy: 0.7524
[0.5249265961105736, 0.752365]

So sind 10 Epochen vergangen. Für diejenigen, die mit solchen Konzepten überhaupt nicht vertraut sind, werde ich die Definition aus dem Internet erläutern: Die Ära ist eine Iteration im Lernprozess, einschließlich der Präsentation aller Beispiele aus dem Trainingssatz und möglicherweise der Überprüfung der Trainingsqualität auf dem Kontrollsatz. Alle unsere Daten haben den gesamten Prozess zehnmal vollständig durchlaufen.

Ergebnis


Bild

Natürlich wird das Netzwerk mehr als einmal benötigt und es wäre schön zu wissen, wie es für die Nachwelt gespeichert werden kann, damit sie es nicht neu trainieren müssen und so weiter.

Die Struktur wird im JSON-Format gespeichert und die Gewichte werden in eine h5- Datei geschrieben .

Die Suchmaschine ist voll von Anleitungen, wie Sie den umgekehrten Prozess der Initialisierung des Netzwerks aus diesen Dateien starten können. Ich werde es daher nicht beschreiben.

Mit der Vorhersagemethode werden wir versuchen, die Meinung des Netzwerks und die Tonkomponente von 2 offensichtlich unterschiedlichen Phrasen in dieser Hinsicht herauszufinden. Zwar müssen sie zuerst noch auf eine Matrixform reduziert werden, aber wir wissen bereits, wie dies mit einer vorgefertigten Lösung zu tun ist.

Am Ausgang sehen wir 2 Zahlen - die Wahrscheinlichkeit, dass die Phrase zu den Klassen „negativ“ / „positiv“ gehört. Ich denke, das Bild zeigt deutlich, dass es einen Unterschied gibt.) Am Ende waren also ähnliche Worte und das Netzwerk hat mit ihrer Beziehung zu ihren Klassen großartige Arbeit geleistet.

Fazit


Daher möchte ich sagen, dass es eine recht einfache Aufgabe zu sein scheint, fortgeschrittene Werkzeuge zur Entwicklung neuronaler Netze und zur Lösung einfacher Probleme zu beherrschen, die notwendigen Schritte zur Lösung korrekt festgelegt und die Theorie ein wenig gelesen zu haben. Ich möchte darauf hinweisen, dass ich mehrere Artikel zum Thema Tonanalyse auf Habré gesehen habe, aber es war immer noch interessant, etwas einfacher und ohne große Textmenge auszuprobieren, obwohl Sie die Theorie bedingungslos studieren müssen :)

Sie können den Code hier finden, wenn Sie ein Sternchen auf das Projekt setzen, es wird großartig sein. Wenn Sie Dateien mit Gewichten und Netzwerkstruktur sowie verarbeitete Daten benötigen, schreiben Sie in die Kommentare und fügen Sie sie dem Repository hinzu.

All Articles