4 Pluspunkte 0 Minuspunkte
Wie kann ich ein Text Classification Model selbst erstellen? Am besten in Tensorflow. Z.B erstelle ich 2 Listen. 1 mit positiven Sätzen und eine mit negativen Sätzen. Ich möchte dann einen Satz eingeben und das Modell sagt mir dann ob der Satz eher positiv oder negativ ist.
von (396 Punkte)  

2 Antworten

3 Pluspunkte 0 Minuspunkte

Zuerst erstellt du 2 Listen. Eines mit den positiven und eines mit den negativen Sätzen.

positive_sentences = ["Dieses Buch ist grossartig", "Ich liebe diesen Film", "Das Essen war koestlich", "Kann ich nur empfehlen", "So schlecht war es nicht"]
negative_sentences = ["Der Film war schrecklich", "Das Buch war langweilig", "Also das war wirklich nicht gut", "Das muss echt besser sein"]

Dann erstellst du 2 Listen zum markieren der Sätze. Die erste Liste voller "0" für negative Sätz und die zweite Liste mit "1" für positive Sätze.

positive_labels = np.ones(len(positive_sentences))
negative_labels = np.zeros(len(negative_sentences))

Das ganze führst du zusammen um 2 Listen zu erhalten. Eine mit den ganzen Sätzen alls Array und eine mit den ganzen Labels als Numpy Array.

sentences = positive_sentences + negative_sentences
labels = np.concatenate([positive_labels, negative_labels])

Die Sätze tokenisierst du mit dem internen Keras Tokenizer.

tokenizer = keras.preprocessing.text.Tokenizer()
tokenizer.fit_on_texts(sentences)

Der Tokenizer erstellt einen "Word Index", dabei wird eine interne Datenbank angelegt wobei jedes Wort einer Ziffer zugeordnet wird. Angenommen du hast den Satz "Heute ist ein schöner Tag". Der Tokenizer speichert jedes gesehene Wort unter einer Nummer.

Heute ist ein schöner Tag

0 Heute
1 ist
2 ein
3 schöner
4 Tag

Der Satz "Heute ist ein schöner Tag" wird intern also so repräsentiert:

[0, 1, 2, 3, 4]

Wenn du dann einen weiteren Satz hast der ein neues Wort beinhaltet speichert der Tokenizer das Wort ebenfalls in der Datenbank unter einer neuen Ziffer ab.

Heute ist kein schöner Tag

...
5 kein
...

Der Satz "Heute ist kein schöner Tag" würde intern damit so repräsentiert:

[0, 1, 5, 3, 4]

Alle Sätze der Trainingsdaten werden mit Hilfe der jeweiligen zugeordneten Ziffern der internen Datenbank ersetzt. Dabei ist darauf zu achten das die Sätze nicht unbedingt alle die selbe Länge haben. Der längste Satz wird als Vorlage genommen, Sätze die kürzer sind werden mit "0" aufgefüllt.

word_index = tokenizer.word_index
sequences = tokenizer.texts_to_sequences(sentences)
padded_sequences = keras.preprocessing.sequence.pad_sequences(sequences)

Schliesslich erstellst du das Modell nach deinen Vorstellungen. Ich habe hier ein einfaches Beispiel mit der sigmoid Funktion im letzten Layer gewählt die eine einzelne Zahl zurückgibt. Die Loss Funktion "binary_crossentropy" sorgt dafür das das Ergebnis ein Wert zwischen 0 und 1 ist.

model = keras.models.Sequential([
    keras.layers.Embedding(len(word_index) + 1, 16, input_length=padded_sequences.shape[1]),
    keras.layers.GlobalAveragePooling1D(),
    keras.layers.Dense(128, activation='relu'),
    keras.layers.Dense(1, activation='sigmoid')
])

model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])

model.fit(padded_sequences, labels, epochs=1000, verbose=1)

Je näher das Ergebnis bei "0" ist desto wahrscheinlicher ist die Eingabe negativ, je näher das Ergebnis bei "1" liegt desto wahrscheinlicher ist es positiv.

von (716 Punkte)  
0 Pluspunkte 0 Minuspunkte

Hier ist ein Beispiel mit Tensorflow und Keras.

import tensorflow as tf
from tensorflow import keras
import numpy as np

positive_sentences = ["Dieses Buch ist grossartig", "Ich liebe diesen Film", "Das Buch war toll", "Das Essen war koestlich", "Kann ich nur empfehlen", "So schlecht war es nicht"]
negative_sentences = ["Der Film war schrecklich", "kein tolles Buch", "Das Buch war langweilig", "Also das war wirklich nicht gut", "Das muss echt besser sein"]

positive_labels = np.ones(len(positive_sentences))
negative_labels = np.zeros(len(negative_sentences))

sentences = positive_sentences + negative_sentences
labels = np.concatenate([positive_labels, negative_labels])

tokenizer = keras.preprocessing.text.Tokenizer()
tokenizer.fit_on_texts(sentences)

word_index = tokenizer.word_index
sequences = tokenizer.texts_to_sequences(sentences)
padded_sequences = keras.preprocessing.sequence.pad_sequences(sequences, padding='post') # added padding parameter

model = keras.models.Sequential([
    keras.layers.Embedding(len(word_index) + 1, 16, input_length=padded_sequences.shape[1]),
    keras.layers.GlobalAveragePooling1D(),
    keras.layers.Dense(128, activation='relu'),
    keras.layers.Dense(1, activation='sigmoid')
])
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])

model.fit(padded_sequences, labels, epochs=1000, verbose=1)

model.save('text_classification.h5')

model = None

model = keras.models.load_model('text_classification.h5')

sentence = "Das ist ein tolles Buch"
sequence = tokenizer.texts_to_sequences([sentence])
padded_sequence = keras.preprocessing.sequence.pad_sequences(sequence, maxlen=padded_sequences.shape[1], padding='post') # added padding parameter
prediction = model.predict(padded_sequence)[0][0]
print(prediction)
von (706 Punkte)