diff --git a/Dokumentation/silas/daten_analyse.tex b/Dokumentation/silas/daten_analyse.tex index 418d415104d4ba4300c379c587282a712ea0d12d..638275d8f6e17d49ff4b85fb3527499e58dc2e50 100644 --- a/Dokumentation/silas/daten_analyse.tex +++ b/Dokumentation/silas/daten_analyse.tex @@ -1,14 +1,15 @@ \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. -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, -dass der in dieser Arbeit erarbeitet Ansatz +dass der in dieser Arbeit erarbeitete Ansatz problemlos auf größere Datensätze angewendet werden kann. \subsubsection{Datenstruktur} 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")): In Zeile 0 wird der Pfad des Datensatzes definiert. 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 aktuellen Index, sodass in der Variable \lstinline{index} die aktuelle @@ -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. 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 for line in open(data_path,encoding="utf8"): nr_of_reviews +=1 @@ -73,7 +74,7 @@ print (nr_of_reviews)) Das Programm liefert \lstinline{8021122} zurück. \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 numpy as np X = [] @@ -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. -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. @@ -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. \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. -\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 numpy as np @@ -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}. -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] from matplotlib import pyplot as plt @@ -136,11 +137,15 @@ ax.bar(value,count/ratings.size *100) In Zeile 8 wird \lstinline{pyplot} von der Library \lstinline{matplotlib} 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. -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{center} diff --git a/Dokumentation/silas/gensim.tex b/Dokumentation/silas/gensim.tex index 5d3418c2fa65d243eb2c8b70c9f79a5f205cff54..fee723dec49b14adabdf419893c605052becbb52 100644 --- a/Dokumentation/silas/gensim.tex +++ b/Dokumentation/silas/gensim.tex @@ -17,9 +17,9 @@ class MyCorpus: json_line = json.loads(line) yield utils.simple_preprocess(json_line["text"]) \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 Klasse \lstinline{MyCorpus} iteriert werden kann. @@ -27,7 +27,7 @@ iteriert werden kann. Die Funktion ist ein einfacher Generator mit der Besonderheit, dass 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. diff --git a/Dokumentation/silas/w2vCNN.tex b/Dokumentation/silas/w2vCNN.tex index 07f83fee157dc8e7acacec517ccc328ca04f8b51..5ff1aee0be19ba007316b5b3680e02ce1734f0a8 100644 --- a/Dokumentation/silas/w2vCNN.tex +++ b/Dokumentation/silas/w2vCNN.tex @@ -1,6 +1,6 @@ \newpage \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 wiederzuerkennen, auch wenn diese an einer anderen Stelle auftreten. @@ -36,15 +36,16 @@ def getSentenceVectorCNN(sentence): \end{lstlisting} 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 transformiert diese in eine für das CNN verarbeitbare Form. \wip{genauer erklären?} -Dafür wird die Rezension in Zeile 8 tokenisiert, sodass in der variable -\lstinline{split} eine Liste der durch die Funktion \lstinline{utils.simple_preprocess} -vorverarbeiteten Wörter gespeichert ist. +\wip{komischer Satz...} +Dafür wird die Rezension in Zeile 8 tokenisiert, sodass in der Variable +\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. Dieses Numpy-Array speichert die ersten 72 Wortvektoren der Rezension, @@ -67,7 +68,7 @@ da das CNN eine feste Dimension der Eingangsdaten benötigt. Anschließend wird in Zeile 18 geprüft, ob weniger als 5 Wortvektoren in dem Array stehen, ist dies der Fall, wird eine Exception geworfen. -Nachdem implementieren der Funktion \lstinline{getSentenceVectorCNN} muss das CNN erstellt werden. +Nach dem implementieren der Funktion \lstinline{getSentenceVectorCNN} muss das CNN erstellt werden. \begin{lstlisting}[caption={CNN},label={list:modelCNN}] import numpy as np from tensorflow.keras.models import Sequential @@ -90,13 +91,13 @@ modelNN.add(Dense(3,activation='softmax')) modelNN.compile(optimizer='adam',loss='sparse_categorical_crossentropy',metrics=["sparse_categorical_accuracy"]) modelNN.summary() \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 \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 drei. -Die \noteable{MaxPooling1D-Schichten} dienen dazu, die Informationen nach den +Die \noteable{MaxPooling1D-Schichten} dienen dazu die Informationen nach den Faltungen zu verdichten. Die Matrix, die als Ergebnis der zweiten \noteable{MaxPooling1D-Schicht} entsteht, @@ -141,7 +142,7 @@ dense_3 (Dense) (None, 10) 510 Um das Modell mit Generatoren zu trainieren, muss 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] @@ -166,7 +167,7 @@ modelNN.evaluate(testData) 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 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. Die Generatoren für die Trainings- und Testmenge werden in @@ -174,18 +175,18 @@ Zeile 27 und 28 variablen gespeichert. 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. -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 die Trainingsmenge $\frac{3}{5}$ des Datensatzes ausmacht die Validierungsmenge hingegen nur $\frac{1}{5}$ wird trotzdem nach jeder Epoche die gesamte Validierungsmenge evaluiert. -Nachdem Training des Netzes gilt es ist an der Zeit, das Modell zu evaluieren, -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 +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 +Parameter \lstinline{loop=False} wird gewährleistet, dass der Generator den Datensatz nur einmal durchläuft. Dieser Generator kann nun in 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] Y_train=[] @@ -214,7 +215,7 @@ confusion_matrix(y_test,y_pred,normalize='true') 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_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 zurückliefert. diff --git a/Dokumentation/silas/w2vMean.tex b/Dokumentation/silas/w2vMean.tex index f70963c84a6bd868cd0ab7de498de093923b0b8a..b6f4b7de024755fa989f6faa2d5d04f49f92780e 100644 --- a/Dokumentation/silas/w2vMean.tex +++ b/Dokumentation/silas/w2vMean.tex @@ -14,12 +14,12 @@ werden als Eingangswerte genutzt und mithilfe eines neuronalen Netzes eine Klassifikation der Rezensionen durchzuführen. \subsubsection{Implementierung} -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 +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 Arbeitsspeicher zu halten. 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} Um das Word2Vec-Modell zu erhalten, importieren wir die im Listing \ref{list:gw2v} geschriebene Funktion @@ -48,11 +48,11 @@ def getSentenceVector(sentence): \end{lstlisting} 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, -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. 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. \begin{lstlisting}[caption={Daten},label={list:mean2},firstnumber=19] @@ -89,12 +89,12 @@ Sind keine Daten vorhanden, 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. -Die Bewertungen werden wie folg codiert: Negativ (0), Neutral (1) und Positiv (2). - Anschließend werden die generierten Daten gespeichert, um bei mehrfacher Ausführung zeit +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 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. -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] from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Dense @@ -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. Die Fehlerfunktion \lstinline{sparse_categorical_crossentropy} ermöglicht im Gegensatz zur -\lstinline{binary_crossentropy} mehr als zwei Klassen zu Klassifizieren. Eine weite -Mögliche Fehlerfunktion ist die \lstinline{categorical_crossentropy}, hierzu müssten +\lstinline{binary_crossentropy} mehr als zwei Klassen zu Klassifizieren. Eine weitere +mögliche Fehlerfunktion ist die \lstinline{categorical_crossentropy}, hierzu müssten bloß die Zielwerte \noteable{One-Hot-Encoded} werden. Zuletzt wird für den Parameter \lstinline{Metrics} der Wert \lstinline{sparse_categorical_accuracy} übergeben. @@ -145,19 +145,19 @@ Zusätzlich werden die Gewichte, die zu dem besten Ergebnis geführt haben, nach dem vorzeitigen Stopp wieder hergestellt. In Zeile 59 findet das tatsächliche Training des neuronalen Netzes statt. -Hierfür wird der Methode \lstinline{fit} die Trainingsdaten Übergeben. Der Parameter -\lstinline{validation_split = 0.2} sorgt dafür das $20 \%$ der Trainingsdaten als -Validierungsmenge genommen werden, hierbei ist aber anzumerken das es sich bei den +Hierfür werden der Methode \lstinline{fit} die Trainingsdaten übergeben. Der Parameter +\lstinline{validation_split = 0.2} sorgt dafür, dass $20 \%$ der Trainingsdaten als +Validierungsmenge genommen werden. Hierbei ist aber anzumerken, dass es sich bei den Trainingsdaten ohnehin schon nur um $80 \%$ des Datensatzes handelt, 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 -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. 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} \begin{lstlisting}[caption={Neuronales Netz - Evaluieren},label={list:mean5},firstnumber=60] 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 Das hier trainierte neuronale Netzwerk klassifiziert $80.02 \%$ der Testdaten richtig. \subsubsection{Konfusionsmatrix} 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. Hierfür wird die Funktion \lstinline{confusion_matrix} von \lstinline{sklearn} benutzt. \begin{lstlisting}[caption={Konfusionsmatrix},label={list:mean6},firstnumber=61] @@ -194,15 +194,15 @@ neutral klassifiziert und $2.28\%$ werden als positiv klassifiziert. Neutrale Bewertungen werden zu $68.44\%$ richtig klassifiziert, 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 Bewertungen klassifiziert, zu $15.86\%$ als neutral und zu $2.42\%$ als negativ klassifiziert. 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 -sieht man das dort bloß $27\%$ der neutralen Rezensionen richtig klassifiziert wurden. +von $85.7\%$. Betrachtet man jedoch die Konfusionsmatrix in Tabelle \ref{tab:conf_no_w}, so +sieht man, dass dort bloß $27\%$ der neutralen Rezensionen richtig klassifiziert wurden. \begin{table}[ht] \def\arraystretch{1.3} \begin{center} diff --git a/Dokumentation/w2v.pdf b/Dokumentation/w2v.pdf index 3c5b788ff4e55dd7ad949a0b6cd4e8eb4f5a70d3..9cee8f1446ad2c06ae031624675854bd2281f1ca 100644 Binary files a/Dokumentation/w2v.pdf and b/Dokumentation/w2v.pdf differ