Skip to content
Snippets Groups Projects
Commit 8c2e21ca authored by Silas Dohm's avatar Silas Dohm
Browse files

spelling

parent 5ac3d09e
Branches
No related tags found
No related merge requests found
\subsection{Analyse des Datensatzes} \subsection{Analyse des Datensatzes}
Ein wichtiger Schritt in jeder Aufgabe im Bereich des Maschinellen Lernens ist es die Datenbasis zu analysieren und zu verstehen. Ein wichtiger Schritt in jeder Aufgabe im Bereich des maschinellen Lernens ist es die Datenbasis zu analysieren und zu verstehen.
Der Yelp-Datensatz besteht aus einer Ansammlung von json Dateien. Darunter jeweils eine Datei für businesses, reviews, user, checkins, sowie tips - quasi short-reviews - und photos, welche als Cross-Referenz für andere Datensätze fungiert. Für dieses Projekt interessiert jedoch nur die review Datei. Der Yelp-Datensatz besteht aus einer Ansammlung von json Dateien. Darunter jeweils eine Datei für businesses, reviews, user, checkins, sowie tips - quasi short-reviews - und photos, welche als Cross-Referenz für andere Datensätze fungiert. Für dieses Projekt interessiert jedoch nur die review Datei.
Die Yelp-Reviews befinden sich in einer 6GB großen json Datei. Diese Datei könnte mit einem Leistungsstarken Computer vollständig in den Arbeitsspeicher geladen werden. Jedoch wird im Rahmen dieser Arbeit die Datei Zeilenweise verarbeitet. Die Yelp-Reviews befinden sich in einer 6GB großen json Datei. Diese Datei könnte mit einem leistungsstarken Computer vollständig in den Arbeitsspeicher geladen werden. Jedoch wird im Rahmen
dieser Arbeit die Datei zeilenweise verarbeitet.
Das Zeilenweise verarbeiten der Datei ermöglicht es, die Systemanforderungen Das zeilenweise verarbeiten der Datei ermöglicht es, die Systemanforderungen
gering zu halten und bringt den zusätzlichen Vorteil, gering zu halten und bringt den zusätzlichen Vorteil,
dass der in dieser Arbeit erarbeitet Ansatz dass der in dieser Arbeit erarbeitete Ansatz
problemlos auf größere Datensätze angewendet werden kann. problemlos auf größere Datensätze angewendet werden kann.
\subsubsection{Datenstruktur} \subsubsection{Datenstruktur}
Das Programm in Listing \ref{list:four} gibt die zwei ersten Zeilen der json Datei aus. Das Programm in Listing \ref{list:four} gibt die zwei ersten Zeilen der json Datei aus.
...@@ -23,7 +24,7 @@ for index,line in enumerate(open(data_path,encoding="utf8")): ...@@ -23,7 +24,7 @@ for index,line in enumerate(open(data_path,encoding="utf8")):
In Zeile 0 wird der Pfad des Datensatzes definiert. In Zeile 0 wird der Pfad des Datensatzes definiert.
Danach wird in Zeile 2 mit einer for-Schleife über jede Zeile des Datensatzes iteriert, Danach wird in Zeile 2 mit einer for-Schleife über jede Zeile des Datensatzes iteriert,
wobei die Funktion \lstinline{open} die Datei öffnet und ein iterierbares Objekt zurückliefet. wobei die Funktion \lstinline{open} die Datei öffnet und ein iterierbares Objekt zurück liefert.
Durch das Benutzen der Funktion \lstinline{enumerate} erhalten wir den Durch das Benutzen der Funktion \lstinline{enumerate} erhalten wir den
aktuellen Index, sodass in der Variable \lstinline{index} die aktuelle aktuellen Index, sodass in der Variable \lstinline{index} die aktuelle
...@@ -63,7 +64,7 @@ In diesem Datensatz sind Sonderzeichen mit einem Backslash escaped. ...@@ -63,7 +64,7 @@ In diesem Datensatz sind Sonderzeichen mit einem Backslash escaped.
Um die Anzahl der Reviews zu ermitteln, wird die Datei einmal in Listing \ref{list:rev_count} komplett durchlaufen und die Anzahl der Zeilen aufaddiert. Um die Anzahl der Reviews zu ermitteln, wird die Datei einmal in Listing \ref{list:rev_count} komplett durchlaufen und die Anzahl der Zeilen aufaddiert.
Aufgrund des Aufbaus der Datei entspricht die Summe aller Zeilen der Anzahl der Reviews im Datensatz. Aufgrund des Aufbaus der Datei entspricht die Summe aller Zeilen der Anzahl der Reviews im Datensatz.
\begin{lstlisting}[caption={Programm zur ermittlung der Anzahl der Reviews},label={list:rev_count}] \begin{lstlisting}[caption={Programm zur Ermittlung der Anzahl der Reviews},label={list:rev_count}]
nr_of_reviews= 0 nr_of_reviews= 0
for line in open(data_path,encoding="utf8"): for line in open(data_path,encoding="utf8"):
nr_of_reviews +=1 nr_of_reviews +=1
...@@ -73,7 +74,7 @@ print (nr_of_reviews)) ...@@ -73,7 +74,7 @@ print (nr_of_reviews))
Das Programm liefert \lstinline{8021122} zurück. Das Programm liefert \lstinline{8021122} zurück.
\subsubsection{Reviewlänge}\label{subsubsec:reviewlength} \subsubsection{Reviewlänge}\label{subsubsec:reviewlength}
\begin{lstlisting}[inputencoding=latin1,caption={Programm zur ermittlung der Reviewlänge},label={list:rev_len}] \begin{lstlisting}[inputencoding=latin1,caption={Programm zur Ermittlung der Reviewlänge},label={list:rev_len}]
import json import json
import numpy as np import numpy as np
X = [] X = []
...@@ -89,7 +90,7 @@ In Zeile 2 wird \lstinline{X} als leere Liste definiert. ...@@ -89,7 +90,7 @@ In Zeile 2 wird \lstinline{X} als leere Liste definiert.
Anschließend wird in der 3. Zeile wie gehabt über jede Zeile des Datensatzes iteriert. Anschließend wird in der 3. Zeile wie gehabt über jede Zeile des Datensatzes iteriert.
In der Schleife in Zeile 4 parsen wir die aktuelle Zeile des Datensatzes und Konvertieren diese in ein Python Dictionary. Danach wird in Zeile 5 der Reviewtext der aktuellen Zeile in Wörter zerteilt und anschließen wird die Anzahl der Wörter der Liste X hinzugefügt. In der Schleife in Zeile 4 parsen wir die aktuelle Zeile des Datensatzes und konvertieren diese in ein Python Dictionary. Danach wird in Zeile 5 der Reviewtext der aktuellen Zeile in Wörter zerteilt und anschließen wird die Anzahl der Wörter der Liste X hinzugefügt.
Nach dem Durchlauf der Schleife erhalten wir eine Liste, die alle Reviewlängen beinhaltet. Nach dem Durchlauf der Schleife erhalten wir eine Liste, die alle Reviewlängen beinhaltet.
...@@ -101,10 +102,10 @@ Durchschnittslänge mithilfe der Numpy-Funktion \lstinline{mean} ausgegeben. ...@@ -101,10 +102,10 @@ Durchschnittslänge mithilfe der Numpy-Funktion \lstinline{mean} ausgegeben.
Die Medianlänge beträgt für diesen Datensatz 78 Wörter, die Durchschnittslänge beträgt 110 Wörter. Die Medianlänge beträgt für diesen Datensatz 78 Wörter, die Durchschnittslänge beträgt 110 Wörter.
\subsubsection{Distribution der Bewertungen} \subsubsection{Distribution der Bewertungen}
Ein Interessantes Merkmal eines Datensatzes ist es wie ausgeglichen die Zieldaten sind. Ein interessantes Merkmal eines Datensatzes ist es, wie ausgeglichen die Zieldaten sind.
Für diese Arbeit sind die Zieldaten die Bewertungen. Für diese Arbeit sind die Zieldaten die Bewertungen.
\begin{lstlisting}[inputencoding=latin1,caption={Programm zur ermittlung der Distribution},label={list:rev_len}] \begin{lstlisting}[inputencoding=latin1,caption={Programm zur Ermittlung der Distribution},label={list:rev_len}]
import json import json
import numpy as np import numpy as np
...@@ -119,7 +120,7 @@ Im Grunde wird hier die gleiche Schleife durchlaufen wie bei der Textlänge. ...@@ -119,7 +120,7 @@ Im Grunde wird hier die gleiche Schleife durchlaufen wie bei der Textlänge.
Anstelle der Textlänge parsen wir diesmal die Bewertung und speichern diese in der Liste \lstinline{ratings}. Anstelle der Textlänge parsen wir diesmal die Bewertung und speichern diese in der Liste \lstinline{ratings}.
In Zeile 7 wird die Liste zu einem Numpy-Array konvertiert In Zeile 7 wird die Liste zu einem Numpy-Array konvertiert.
\begin{lstlisting}[firstnumber=8,inputencoding=latin1] \begin{lstlisting}[firstnumber=8,inputencoding=latin1]
from matplotlib import pyplot as plt from matplotlib import pyplot as plt
...@@ -136,11 +137,15 @@ ax.bar(value,count/ratings.size *100) ...@@ -136,11 +137,15 @@ ax.bar(value,count/ratings.size *100)
In Zeile 8 wird \lstinline{pyplot} von der Library \lstinline{matplotlib} In Zeile 8 wird \lstinline{pyplot} von der Library \lstinline{matplotlib}
unter dem Alias \lstinline{plt} importiert. unter dem Alias \lstinline{plt} importiert.
Danach wird in Zeile 9 mit der Funktion \lstinline{unique} von Numpy die verschiedenen Bewertungen in der Variable \lstinline{value} gespeichert. Der Parameter \lstinline{return_counts=True} sorgt dafür das zusätzlich die Häufigkeit der Bewertung zurückgegeben wird. Die Häufigkeit wird in der Variable \lstinline{count} gespeichert. Danach werden in Zeile 9 mit der Funktion \lstinline{unique} von Numpy die
verschiedenen Bewertungen in der Variable \lstinline{value} gespeichert.
Der Parameter \lstinline{return_counts=True} sorgt dafür, dass zusätzlich die Häufigkeit der
Bewertung zurückgegeben wird. Die Häufigkeit wird in der Variable \lstinline{count} gespeichert.
In Zeile 11 bis 16 wird der Plot erstellt. In Zeile 11 bis 16 wird der Plot erstellt.
Das Ausführen des Quelltextes führt zu folgendem Plot, welcher in Bild \ref{fig::DST} zu sehen ist. Hier ist zu erkennen, dass die Verteilung nicht gleichmäßig ist. Dies führt zu verschiedenen Ansätzen, welche im Folgenden Kapitel \ref{subsubsec:Dist} erläutert werden. Das Ausführen des Quelltextes führt zu folgendem Plot, welcher in Bild \ref{fig::DST} zu sehen ist. Hier ist zu erkennen, dass die Verteilung nicht gleichmäßig ist. Dies führt zu verschiedenen Ansätzen, welche im
folgenden Kapitel \ref{subsubsec:Dist} erläutert werden.
\begin{figure}[h!] \begin{figure}[h!]
\begin{center} \begin{center}
......
...@@ -17,9 +17,9 @@ class MyCorpus: ...@@ -17,9 +17,9 @@ class MyCorpus:
json_line = json.loads(line) json_line = json.loads(line)
yield utils.simple_preprocess(json_line["text"]) yield utils.simple_preprocess(json_line["text"])
\end{lstlisting} \end{lstlisting}
Im Konstruktor der Klasse MyCorpus (Zeile 3) wird der Pfad zu dem Yelp-Datensatz Übergeben. Im Konstruktor der Klasse MyCorpus (Zeile 3) wird der Pfad zu dem Yelp-Datensatz übergeben.
In Zeile 5 wird die von Funktion \lstinline{__iter__} implementiert, In Zeile 5 wird die Funktion \lstinline{__iter__} implementiert,
diese wird von Gensim erwartet und führt dazu, dass über Objekte der diese wird von Gensim erwartet und führt dazu, dass über Objekte der
Klasse \lstinline{MyCorpus} Klasse \lstinline{MyCorpus}
iteriert werden kann. iteriert werden kann.
...@@ -27,7 +27,7 @@ iteriert werden kann. ...@@ -27,7 +27,7 @@ iteriert werden kann.
Die Funktion ist ein einfacher Generator mit der Besonderheit, dass Die Funktion ist ein einfacher Generator mit der Besonderheit, dass
in Zeile 9 die Funktion \lstinline{utils.simple_preproces} aufgerufen wird. in Zeile 9 die Funktion \lstinline{utils.simple_preproces} aufgerufen wird.
Die Funktion \lstinline{utils.simple_preproces} wird benutzt um aus der aktuellen Review in \lstinline{json_line["text"]} eine Liste von Tokens zu generieren. Die Funktion \lstinline{utils.simple_preproces} wird benutzt, um aus der aktuellen Review in \lstinline{json_line["text"]} eine Liste von Tokens zu generieren.
Hierbei werden Wörter mit weniger als 2 Buchstaben und Wörter mit mehr als 15 Buchstaben ignoriert. Diese Grenzen können über die Parameter \lstinline{min_len} und \lstinline{max_len} gesetzt werden. Hierbei werden Wörter mit weniger als 2 Buchstaben und Wörter mit mehr als 15 Buchstaben ignoriert. Diese Grenzen können über die Parameter \lstinline{min_len} und \lstinline{max_len} gesetzt werden.
......
\newpage \newpage
\subsection{Word2Vec-CNN-Modell} \subsection{Word2Vec-CNN-Modell}
Ein \noteable{convolutional neural network}, kurz CNN, ist in der Lage, Ein \noteable{convolutional neural network}, kurz CNN, ist in der Lage
lokale Muster in einer Sequenz zu erlernen und diese später lokale Muster in einer Sequenz zu erlernen und diese später
wiederzuerkennen, auch wenn diese an einer anderen Stelle auftreten. wiederzuerkennen, auch wenn diese an einer anderen Stelle auftreten.
...@@ -36,15 +36,16 @@ def getSentenceVectorCNN(sentence): ...@@ -36,15 +36,16 @@ def getSentenceVectorCNN(sentence):
\end{lstlisting} \end{lstlisting}
Zuerst wird in Zeile 5 die im Listing \ref{list:gw2v} geschriebene Funktion Zuerst wird in Zeile 5 die im Listing \ref{list:gw2v} geschriebene Funktion
\lstinline{getWordVecMode} aufgerufen, um das Word2Vec-Modell erhalten. \lstinline{getWordVecMode} aufgerufen, um das Word2Vec-Modell zu erhalten.
Die Funktion \lstinline{getSentenceVectorCNN} in Zeile 7 nimmt eine Rezension entgegen und Die Funktion \lstinline{getSentenceVectorCNN} in Zeile 7 nimmt eine Rezension entgegen und
transformiert diese in eine für das CNN verarbeitbare Form. transformiert diese in eine für das CNN verarbeitbare Form.
\wip{genauer erklären?} \wip{genauer erklären?}
Dafür wird die Rezension in Zeile 8 tokenisiert, sodass in der variable \wip{komischer Satz...}
\lstinline{split} eine Liste der durch die Funktion \lstinline{utils.simple_preprocess} Dafür wird die Rezension in Zeile 8 tokenisiert, sodass in der Variable
vorverarbeiteten Wörter gespeichert ist. \lstinline{split} eine Liste der, durch die Funktion \lstinline{utils.simple_preprocess}
vorverarbeiteten, Wörter gespeichert ist.
Danach wird in Zeile 9 das Numpy-Array wordVecs mit Nullen initialisiert. Danach wird in Zeile 9 das Numpy-Array wordVecs mit Nullen initialisiert.
Dieses Numpy-Array speichert die ersten 72 Wortvektoren der Rezension, Dieses Numpy-Array speichert die ersten 72 Wortvektoren der Rezension,
...@@ -90,13 +91,13 @@ modelNN.add(Dense(3,activation='softmax')) ...@@ -90,13 +91,13 @@ modelNN.add(Dense(3,activation='softmax'))
modelNN.compile(optimizer='adam',loss='sparse_categorical_crossentropy',metrics=["sparse_categorical_accuracy"]) modelNN.compile(optimizer='adam',loss='sparse_categorical_crossentropy',metrics=["sparse_categorical_accuracy"])
modelNN.summary() modelNN.summary()
\end{lstlisting} \end{lstlisting}
Hier wurden dem Netzwerk zwei \noteable{Conv1D-Schichten} hinzugefügt mit der Hier wurden dem Netzwerk zwei \noteable{Conv1D-Schichten} hinzugefügt, mit der
Aktivierungsfunktion Aktivierungsfunktion
\lstinline{relu}. Die erste Schicht hat hier 150 Filter und eine \lstinline{relu}. Die erste Schicht hat hier 150 Filter und eine
Kernelgröße von fünf. Die zweite Schicht hat hingegen 100 Filter und eine Kernelgröße von fünf. Die zweite Schicht hat hingegen 100 Filter und eine
Kernelgröße von drei. Kernelgröße von drei.
Die \noteable{MaxPooling1D-Schichten} dienen dazu, die Informationen nach den Die \noteable{MaxPooling1D-Schichten} dienen dazu die Informationen nach den
Faltungen zu verdichten. Faltungen zu verdichten.
Die Matrix, die als Ergebnis der zweiten \noteable{MaxPooling1D-Schicht} entsteht, Die Matrix, die als Ergebnis der zweiten \noteable{MaxPooling1D-Schicht} entsteht,
...@@ -141,7 +142,7 @@ dense_3 (Dense) (None, 10) 510 ...@@ -141,7 +142,7 @@ dense_3 (Dense) (None, 10) 510
Um das Modell mit Generatoren zu trainieren, muss Um das Modell mit Generatoren zu trainieren, muss
aufgrund der für das Netzwerk unbekannten Größe der Trainingsmenge aufgrund der für das Netzwerk unbekannten Größe der Trainingsmenge
angeben werde, wie viele Schritte pro Epoche erfolgen sollen. angeben werden, wie viele Schritte pro Epoche erfolgen sollen.
\begin{lstlisting}[caption={CNN - Fitting},label={list:modelCNNFit},firstnumber=20] \begin{lstlisting}[caption={CNN - Fitting},label={list:modelCNNFit},firstnumber=20]
...@@ -166,7 +167,7 @@ modelNN.evaluate(testData) ...@@ -166,7 +167,7 @@ modelNN.evaluate(testData)
Hierfür wird die Größe der Trainingsmenge durch die BatchSize geteilt (Zeile 24). Hierfür wird die Größe der Trainingsmenge durch die BatchSize geteilt (Zeile 24).
Um ein Overfitting zu verhindern, wird, wie beim Mean-Modell auch schon in Um ein Overfitting zu verhindern, wird, wie beim Mean-Modell auch schon in
Zeile 25 ein Earlystop definiert. Zeile 25 ein Earlystop definiert.
Dieser unterbricht das Training vorzeitig, fall acht Epochen lang keine Dieser unterbricht das Training vorzeitig, falls acht Epochen lang keine
Verbesserung auf der Validierungsmenge erzielt wird. Verbesserung auf der Validierungsmenge erzielt wird.
Die Generatoren für die Trainings- und Testmenge werden in Die Generatoren für die Trainings- und Testmenge werden in
...@@ -174,18 +175,18 @@ Zeile 27 und 28 variablen gespeichert. ...@@ -174,18 +175,18 @@ Zeile 27 und 28 variablen gespeichert.
Die Klassengewichte in Zeile 31 wurden im Listing \ref{list:modelCNNWeights} berechnet. Die Klassengewichte in Zeile 31 wurden im Listing \ref{list:modelCNNWeights} berechnet.
Mit allen Anforderungen erfüllt kann jetzt in Zeile 32 das Modell trainiert werden. Mit allen Anforderungen erfüllt kann jetzt in Zeile 32 das Modell trainiert werden.
Dabei ist zu beachten, dass die Anzahl der Schritte pro \wip{schwer zu versteheneder Satz}Dabei ist zu beachten, dass die Anzahl der Schritte pro
Epoche für die Validierungsmenge gedrittelt wird, da Epoche für die Validierungsmenge gedrittelt wird, da
die Trainingsmenge $\frac{3}{5}$ des Datensatzes ausmacht die Validierungsmenge die Trainingsmenge $\frac{3}{5}$ des Datensatzes ausmacht die Validierungsmenge
hingegen nur $\frac{1}{5}$ wird hingegen nur $\frac{1}{5}$ wird
trotzdem nach jeder Epoche die gesamte Validierungsmenge evaluiert. trotzdem nach jeder Epoche die gesamte Validierungsmenge evaluiert.
Nachdem Training des Netzes gilt es ist an der Zeit, das Modell zu evaluieren, Nach dem Training des Netzes ist es an der Zeit das Modell zu evaluieren.
dafür wird in Zeile 34 zunächst wieder ein Generator angelegt. Mit dem Dafür wird in Zeile 34 zunächst wieder ein Generator angelegt. Mit dem
Parameter \lstinline{loop=False} wird gewährleistet, das der Generator den Datensatz nur Parameter \lstinline{loop=False} wird gewährleistet, dass der Generator den Datensatz nur
einmal durchläuft. Dieser Generator kann nun in einmal durchläuft. Dieser Generator kann nun in
Zeile 35 an die Methode \lstinline{evaluate} übergeben werden. Zeile 35 an die Methode \lstinline{evaluate} übergeben werden.
Das Evaluieren zeigt das dieses Modell zu $81.44\%$ die Klassen richtig klassifiziert. Das Evaluieren zeigt, dass dieses Modell zu $81.44\%$ die Klassen der Testmenge richtig klassifiziert.
\begin{lstlisting}[caption={CNN - Klassengewichte},label={list:modelCNNWeights},numbers=none] \begin{lstlisting}[caption={CNN - Klassengewichte},label={list:modelCNNWeights},numbers=none]
Y_train=[] Y_train=[]
...@@ -214,7 +215,7 @@ confusion_matrix(y_test,y_pred,normalize='true') ...@@ -214,7 +215,7 @@ confusion_matrix(y_test,y_pred,normalize='true')
Dafür werden die vom Netz vorhergesagten Klassen der Testmenge in dem Dafür werden die vom Netz vorhergesagten Klassen der Testmenge in dem
Vektor \lstinline{y_pred} gespeichert und die tatsächlichen Klassen der Testmenge in dem Vektor \lstinline{y_pred} gespeichert und die tatsächlichen Klassen der Testmenge in dem
Vektor \lstinline{y_test}. Beide Vektoren werden der Funktion Vektor \lstinline{y_test}. Beide Vektoren werden der Funktion
\lstinline{confusion_matrix} Übergeben, \lstinline{confusion_matrix} übergeben,
welche die in der Tabelle \ref{tab:conf_w_cnn} dargestellte Konfusionsmatrix welche die in der Tabelle \ref{tab:conf_w_cnn} dargestellte Konfusionsmatrix
zurückliefert. zurückliefert.
......
...@@ -14,12 +14,12 @@ werden als Eingangswerte genutzt und mithilfe eines neuronalen Netzes eine ...@@ -14,12 +14,12 @@ werden als Eingangswerte genutzt und mithilfe eines neuronalen Netzes eine
Klassifikation der Rezensionen durchzuführen. Klassifikation der Rezensionen durchzuführen.
\subsubsection{Implementierung} \subsubsection{Implementierung}
Durch die Bildung der Satzvektoren verringert sich der benötigte Speicherbedarf, Durch die Bildung der Satzvektoren verringert sich der benötigte Speicherbedarf.
somit ist es möglich, auf die Generatoren zu verzichten und die Trainingsdaten im Somit ist es möglich, auf die Generatoren zu verzichten und die Trainingsdaten im
Arbeitsspeicher zu halten. Arbeitsspeicher zu halten.
Dies hilft, die benötigte Trainingszeit zu reduzieren. Dies hilft, die benötigte Trainingszeit zu reduzieren.
Sollte die Arbeitsspeicherkapazität nicht ausreichen, befindet sich eine Implementierung, die Generatoren benutzt im Anhang. Sollte die Arbeitsspeicherkapazität nicht ausreichen, befindet sich eine Implementierung die Generatoren benutzt im Anhang.
\wip{referenzieren und Tatsächlich einfügen} \wip{referenzieren und Tatsächlich einfügen}
Um das Word2Vec-Modell zu erhalten, importieren wir die im Listing \ref{list:gw2v} geschriebene Funktion Um das Word2Vec-Modell zu erhalten, importieren wir die im Listing \ref{list:gw2v} geschriebene Funktion
...@@ -48,11 +48,11 @@ def getSentenceVector(sentence): ...@@ -48,11 +48,11 @@ def getSentenceVector(sentence):
\end{lstlisting} \end{lstlisting}
Die Funktion \lstinline{getSentenceVector} in Zeile 8 nimmt eine Rezension entgegen und Die Funktion \lstinline{getSentenceVector} in Zeile 8 nimmt eine Rezension entgegen und
teilt diese in Zeile 9 in ihre Wörter auf. Danach wird jedes Wort geprüft, teilt diese in Zeile 9 in ihre Wörter auf. Danach wird jedes Wort geprüft,
ob es im Word2Vec-Modell hinterlegt ist, ist dies der Fall, wird der Wortvektor der ob es im Word2Vec-Modell hinterlegt ist. Ist dies der Fall, wird der Wortvektor der
Liste \lstinline{wordVecs} hinzugefügt. Liste \lstinline{wordVecs} hinzugefügt.
Ist kein einziges Wort der Rezension im Word2Vec-Modell enthalten, wird eine Exception geworfen. Ist kein einziges Wort der Rezension im Word2Vec-Modell enthalten, wird eine Exception geworfen.
In Zeile 18 wird der Durschnitt aller Wortvektoren zurückgeben. In Zeile 18 wird der Durchschnitt aller Wortvektoren zurückgeben.
Um die Daten für das Klassifikationsmodell zu generieren, muss der Datensatz in die Satzvektoren transformiert werden. Um die Daten für das Klassifikationsmodell zu generieren, muss der Datensatz in die Satzvektoren transformiert werden.
\begin{lstlisting}[caption={Daten},label={list:mean2},firstnumber=19] \begin{lstlisting}[caption={Daten},label={list:mean2},firstnumber=19]
...@@ -89,12 +89,12 @@ Sind keine Daten vorhanden, ...@@ -89,12 +89,12 @@ Sind keine Daten vorhanden,
wird der gesamte Datensatz durchlaufen und für jede einzelne Rezension der Satzvektor ermittelt. wird der gesamte Datensatz durchlaufen und für jede einzelne Rezension der Satzvektor ermittelt.
Befindet sich kein Wort der Rezension im Word2Vec-Modell so wird diese Rezension in Zeile 33 übersprungen. Befindet sich kein Wort der Rezension im Word2Vec-Modell so wird diese Rezension in Zeile 33 übersprungen.
Die Bewertungen werden wie folg codiert: Negativ (0), Neutral (1) und Positiv (2). Die Bewertungen werden wie folgt codiert: Negativ (0), Neutral (1) und Positiv (2).
Anschließend werden die generierten Daten gespeichert, um bei mehrfacher Ausführung zeit Anschließend werden die generierten Daten gespeichert, um bei mehrfacher Ausführung Zeit
zu sparen. zu sparen.
Danach werden die Daten in Zeile 45 in Trainings- und Testdaten aufgeteilt, hierfür wird die Funktion \lstinline{train_test_split} von \lstinline{sklearn} verwendet. Danach werden die Daten in Zeile 45 in Trainings- und Testdaten aufgeteilt, hierfür wird die Funktion \lstinline{train_test_split} von \lstinline{sklearn} verwendet.
Die Rezensionen liegen jetzt in Form von Satzvektoren bzw. genau genommen Rezensionsvektoren vor, anhand dieser Daten kann nun ein neuronales Netz trainiert werden. Die Rezensionen liegen jetzt in Form von Satzvektoren bzw. genau genommen Rezensionsvektoren vor. Anhand dieser Daten kann nun ein neuronales Netz trainiert werden.
\begin{lstlisting}[caption={Neuronales Netz},label={list:mean3},firstnumber=46] \begin{lstlisting}[caption={Neuronales Netz},label={list:mean3},firstnumber=46]
from tensorflow.keras.models import Sequential from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense from tensorflow.keras.layers import Dense
...@@ -121,8 +121,8 @@ Zeile 54 einige Parameter gesetzt. Für den Optimierungsalgorithmus wird \lstinl ...@@ -121,8 +121,8 @@ Zeile 54 einige Parameter gesetzt. Für den Optimierungsalgorithmus wird \lstinl
Für die Fehlerfunktion, hier loss genannt, wird \lstinline{sparse_categorical_crossentropy} benutzt. Für die Fehlerfunktion, hier loss genannt, wird \lstinline{sparse_categorical_crossentropy} benutzt.
Die Fehlerfunktion \lstinline{sparse_categorical_crossentropy} ermöglicht im Gegensatz zur Die Fehlerfunktion \lstinline{sparse_categorical_crossentropy} ermöglicht im Gegensatz zur
\lstinline{binary_crossentropy} mehr als zwei Klassen zu Klassifizieren. Eine weite \lstinline{binary_crossentropy} mehr als zwei Klassen zu Klassifizieren. Eine weitere
Mögliche Fehlerfunktion ist die \lstinline{categorical_crossentropy}, hierzu müssten mögliche Fehlerfunktion ist die \lstinline{categorical_crossentropy}, hierzu müssten
bloß die Zielwerte \noteable{One-Hot-Encoded} werden. bloß die Zielwerte \noteable{One-Hot-Encoded} werden.
Zuletzt wird für den Parameter \lstinline{Metrics} der Wert \lstinline{sparse_categorical_accuracy} Zuletzt wird für den Parameter \lstinline{Metrics} der Wert \lstinline{sparse_categorical_accuracy}
übergeben. übergeben.
...@@ -145,19 +145,19 @@ Zusätzlich werden die Gewichte, die zu dem besten Ergebnis geführt haben, nach ...@@ -145,19 +145,19 @@ Zusätzlich werden die Gewichte, die zu dem besten Ergebnis geführt haben, nach
dem vorzeitigen Stopp wieder hergestellt. dem vorzeitigen Stopp wieder hergestellt.
In Zeile 59 findet das tatsächliche Training des neuronalen Netzes statt. In Zeile 59 findet das tatsächliche Training des neuronalen Netzes statt.
Hierfür wird der Methode \lstinline{fit} die Trainingsdaten Übergeben. Der Parameter Hierfür werden der Methode \lstinline{fit} die Trainingsdaten übergeben. Der Parameter
\lstinline{validation_split = 0.2} sorgt dafür das $20 \%$ der Trainingsdaten als \lstinline{validation_split = 0.2} sorgt dafür, dass $20 \%$ der Trainingsdaten als
Validierungsmenge genommen werden, hierbei ist aber anzumerken das es sich bei den Validierungsmenge genommen werden. Hierbei ist aber anzumerken, dass es sich bei den
Trainingsdaten ohnehin schon nur um $80 \%$ des Datensatzes handelt, Trainingsdaten ohnehin schon nur um $80 \%$ des Datensatzes handelt,
weswegen die tatsächliche Validierungsmenge $16 \%$ des Datensatzes beinhaltet. weswegen die tatsächliche Validierungsmenge $16 \%$ des Datensatzes beinhaltet.
Die \lstinline{batch_size} wird aufgrund des großen Datensatzes auf 2048 gesetzt, um das Optimieren der Gewichte zu Die \lstinline{batch_size} wird aufgrund des großen Datensatzes auf 2048 gesetzt, um das Optimieren der Gewichte zu
beschleunigen. Eine kleinere \lstinline{batch_size} hat beim Experimentieren in disem Fall nicht zu einer schnelleren Konvergenz beschleunigen. Eine kleinere \lstinline{batch_size} hat beim Experimentieren in diesem Fall nicht zu einer schnelleren Konvergenz
geführt. geführt.
Wie in Kapitel \ref{subsubsec:Dist} diskutiert gibt es verschiedene Umgänge mit unausgeglichenen Datensätzen. Die für diese Arbeit gewählte Methode der Gewichtung ist hier zu erkennen an den, an Wie in Kapitel \ref{subsubsec:Dist} diskutiert gibt es verschiedene Umgänge mit unausgeglichenen Datensätzen. Die für diese Arbeit gewählte Methode der Gewichtung ist hier zu erkennen an den, an
die Methode \lstinline{fit} Übergebenen, Klassengewichte. die Methode \lstinline{fit} übergebenen, Klassengewichte.
\wip{vll noch erklären wie die Gewichte entstehen} \wip{vll noch erklären wie die Gewichte entstehen}
\begin{lstlisting}[caption={Neuronales Netz - Evaluieren},label={list:mean5},firstnumber=60] \begin{lstlisting}[caption={Neuronales Netz - Evaluieren},label={list:mean5},firstnumber=60]
modelNN.evaluate(X_test,Y_test) modelNN.evaluate(X_test,Y_test)
...@@ -166,7 +166,7 @@ Um das Modell zu evaluieren, wird in Zeile 60 die Methode evaluate mit den Testd ...@@ -166,7 +166,7 @@ Um das Modell zu evaluieren, wird in Zeile 60 die Methode evaluate mit den Testd
Das hier trainierte neuronale Netzwerk klassifiziert $80.02 \%$ der Testdaten richtig. Das hier trainierte neuronale Netzwerk klassifiziert $80.02 \%$ der Testdaten richtig.
\subsubsection{Konfusionsmatrix} \subsubsection{Konfusionsmatrix}
Die bereits berechnete Genauigkeit ist ein gutes erstes Leistungsmerkmal des Die bereits berechnete Genauigkeit ist ein gutes erstes Leistungsmerkmal des
Klassifikators, um den Klassifikator noch besser Einschätzen zu können, Klassifikators. Um den Klassifikator noch besser einschätzen zu können,
lohnt es sich, eine Konfusionsmatrix aufzustellen. lohnt es sich, eine Konfusionsmatrix aufzustellen.
Hierfür wird die Funktion \lstinline{confusion_matrix} von \lstinline{sklearn} benutzt. Hierfür wird die Funktion \lstinline{confusion_matrix} von \lstinline{sklearn} benutzt.
\begin{lstlisting}[caption={Konfusionsmatrix},label={list:mean6},firstnumber=61] \begin{lstlisting}[caption={Konfusionsmatrix},label={list:mean6},firstnumber=61]
...@@ -194,15 +194,15 @@ neutral klassifiziert und $2.28\%$ werden als positiv klassifiziert. ...@@ -194,15 +194,15 @@ neutral klassifiziert und $2.28\%$ werden als positiv klassifiziert.
Neutrale Bewertungen werden zu $68.44\%$ richtig klassifiziert, Neutrale Bewertungen werden zu $68.44\%$ richtig klassifiziert,
jedoch werden $16.82\%$ der neutralen Bewertungen falsch als jedoch werden $16.82\%$ der neutralen Bewertungen falsch als
negative klassifiziert und zu $14.74\%$ falsch als positiv klassifiziert. negativ klassifiziert und zu $14.74\%$ falsch als positiv klassifiziert.
Die positiven Bewertungen werden zu $81.72\%$ richtig als positive Die positiven Bewertungen werden zu $81.72\%$ richtig als positive
Bewertungen klassifiziert, zu $15.86\%$ als neutral und zu Bewertungen klassifiziert, zu $15.86\%$ als neutral und zu
$2.42\%$ als negativ klassifiziert. $2.42\%$ als negativ klassifiziert.
Das gleiche Modell ohne die Gewichtung der Klassen erreicht eine Genauigkeit Das gleiche Modell ohne die Gewichtung der Klassen erreicht eine Genauigkeit
von $85.7\%$, betrachtet man jedoch die Konfusionsmatrix in Tabelle \ref{tab:conf_no_w}, so von $85.7\%$. Betrachtet man jedoch die Konfusionsmatrix in Tabelle \ref{tab:conf_no_w}, so
sieht man das dort bloß $27\%$ der neutralen Rezensionen richtig klassifiziert wurden. sieht man, dass dort bloß $27\%$ der neutralen Rezensionen richtig klassifiziert wurden.
\begin{table}[ht] \begin{table}[ht]
\def\arraystretch{1.3} \def\arraystretch{1.3}
\begin{center} \begin{center}
......
No preview for this file type
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment