From 6098f65884908d912ae26fde44f1748fa0900438 Mon Sep 17 00:00:00 2001 From: jvongehr <joel-jerome.vongehr@stud.hs-bochum.de> Date: Sat, 7 Aug 2021 21:33:19 +0200 Subject: [PATCH] =?UTF-8?q?Spelling=20und=20sonstige=20Erg=C3=A4nzungen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dokumentation/1_motivation.tex | 14 +++--- Dokumentation/2_grundlagen.tex | 23 ++++----- Dokumentation/Auswertung.tex | 27 +++++------ Dokumentation/Generatoren.tex | 72 ++++++++++++++++++++--------- Dokumentation/Herausforderungen.tex | 29 ++++++------ Dokumentation/w2v.tex | 2 +- Dokumentation/w2vFromScratch.tex | 14 +++--- 7 files changed, 107 insertions(+), 74 deletions(-) diff --git a/Dokumentation/1_motivation.tex b/Dokumentation/1_motivation.tex index 0f21dc0..7d05fa1 100644 --- a/Dokumentation/1_motivation.tex +++ b/Dokumentation/1_motivation.tex @@ -1,23 +1,23 @@ \section{Abstract} -Diese Hausarbeit befasst sich mit der Word2Vec-Technik und ihrem Einsatz im Online-Marketing. Bei dem Datensatz handelt es sich um das \textit{Yelp restaurant review dataset}, welches Rezensionen von über 160000 Unternehmen aus acht Metropolregionen beinhaltet. Bei jeder Rezension vergibt der Verfasser eine bestimmte Anzahl an Sternen die zwischen eins und fünf liegt. In dieser Arbeit werden zwei Verfahren ausgearbeitet, die es ermöglichen anhand des Bewertungstextes die Anzahl der zugeteilten Sterne vorherzusagen. +Diese Hausarbeit befasst sich mit der Word2Vec-Technik und ihrem Einsatz im Online-Marketing. Bei dem Datensatz handelt es sich um das \textit{Yelp restaurant review dataset}, welches Rezensionen von über 160000 Unternehmen aus acht Metropolregionen beinhaltet. Bei jeder Rezension vergibt der Verfasser eine bestimmte Anzahl an Sternen die zwischen eins und fünf liegt. In dieser Arbeit werden zwei Verfahren ausgearbeitet, die es ermöglichen, anhand des Bewertungstextes die Anzahl der zugeteilten Sterne vorherzusagen. -Bei dem ersten Verfahren handelt es sich um ein \textit{Mean-Vektor-Klassifikationsmodell}. \wip{(Bei Namensänderung entsprechend anpassen)} Hierbei wird der durchschnittliche Wortvektor einer Rezension bestimmt. Mit Hilfe dieses Rezensionsvektors kann die gesamte Bewertung in den zuvor generierten Vektorraum eingeordnet werden. Mittels dieser Einordnung wird nachfolgend die Klassifikation durchgeführt. +Bei dem ersten Verfahren handelt es sich um ein \textit{Mean-Vektor-Klassifikationsmodell}. Hierbei wird der durchschnittliche Wortvektor einer Rezension bestimmt. Mit Hilfe dieses Rezensionsvektors kann die gesamte Bewertung in den zuvor generierten Vektorraum eingeordnet werden. Mittels dieser Einordnung wird nachfolgend die Klassifikation durchgeführt. -Der zweite Ansatz basiert auf einem \textit{Convolutional Neural Network}. Diese Art von neuronalem Netz kommt verstärkt im Feld des maschinellen Sehens zum Einsatz. Durch die Faltungsoperation können CNN's sequenzielle Daten besser verarbeiten, was eben nicht nur bei Bildern sondern auch bei Texten von Vorteil ist. So kann das Netz Wörter in einem Satz als wiederkehrende Sequenz erkennen und entsprechend gewichten. Aufgrund dieser Gewichte werden die Rezensionen anschließend klassifiziert. +Der zweite Ansatz basiert auf einem \textit{Convolutional Neural Network}. Diese Art von neuronalem Netz kommt verstärkt im Feld des maschinellen Sehens zum Einsatz. Durch die Faltungsoperation können CNNs sequenzielle Daten besser verarbeiten, was nicht nur bei Bildern sondern auch bei Texten von Vorteil ist. So kann das Netz Wörter in einem Satz als wiederkehrende Sequenz erkennen und entsprechend gewichten. Aufgrund dieser Gewichtung werden die Rezensionen anschließend klassifiziert. Da diese Hausarbeit auf den Vorlesungsinhalten des Moduls \glqq Maschinelles Lernen\grqq{} von Professor Jörg Frochte basiert, wird nachfolgend lediglich die Verwendung der CNNs motiviert. Die theoretischen Hintergründe zu dieser Kategorie von neuronalen Netzen sind aus der Vorlesung bekannt. -Die beiden Ansätze zur Klassifizierung treffen eine xy genaue Aussage über die Rezensionen, die in positiv, neutral oder negativ eingeordnet werden. \wip{Absatz ergänzen, wenn die Ergebnisse vorliegen} +Die beiden Ansätze zur Klassifizierung treffen jeweils eine ca.\@ $80\,\%$ genaue Aussage über die Rezensionen, die in positiv, neutral oder negativ eingeordnet werden. Dabei werden die Vorgehensweisen mithilfe der Konfusionmatrizen genauer verglichen. \clearpage \section{Motivation \label{sec:Motivation}} -Möchte man heutzutage die Dienstleistungen eines Unternehmens in Anspruch nehmen, so wird man sich zuallererst die Meinungen anderer Kunden durchlesen. Im Hinblick auf diese Kundenbewertungen kann mit Hilfe der Word2Vec-Technik in Kombination mit neuronalen Netzen eine umfassende Aussage über die Art der Rezension getroffen werden. Auf diese Weise kommt Deep Learning im Online-Marketing zum Einsatz. +Möchte man heutzutage die Dienstleistungen eines Unternehmens in Anspruch nehmen, so wird man sich zuerst die Meinungen anderer Kunden durchlesen. Im Hinblick auf diese Kundenbewertungen kann mit Hilfe der Word2Vec-Technik in Kombination mit neuronalen Netzen eine umfassende Aussage über die Art der Rezension getroffen werden. Auf diese Weise kommt Deep Learning im Online-Marketing zum Einsatz. Wie bereits aus der Vorlesung bekannt ist, kann Deep Learning sehr vielseitigen Zwecken dienen. Interessant ist jedoch, wie es in Sprachanwendungen zum Einsatz kommt. Aus der Philosophie geht hervor: \glqq Die Bedeutung eines Wortes ist sein Gebrauch in der Sprache.\grqq{ \cite{wittgenstein_schulte_2019}} Daraus lässt sich schließen, dass ein einzelnes Wort keinerlei Aufschluss über seine Bedeutung liefert. -Ebenfalls bekannt ist, dass Computer zwar überaus effizient mit Zahlen arbeiten können, mit Wörtern hingegen nicht. Daher muss der alphanumerische Eingabedatensatz zunächst umgewandelt werden, sodass er von der Anwendung verarbeitet werden kann. Bei dieser Neudarstellung der Texte darf die Bedeutung der Wörter nicht untergehen. Die Schwierigkeit liegt also darin, dem Computer Texte so aufzubereiten, dass er sie zum einen verarbeiten kann und zum anderen der Kontext der Wörter nicht verloren geht. Genau mit dieser Herausforderung befasst sich die linguistische Datenverarbeitung. +Ebenfalls bekannt ist, dass Computer zwar überaus effizient mit Zahlen arbeiten können, mit Wörtern hingegen nicht. Daher muss der alphanumerische Eingabedatensatz zunächst umgewandelt werden, sodass er von der Anwendung verarbeitet werden kann. Bei dieser Neudarstellung der Texte darf die Bedeutung der Wörter nicht untergehen. Die Schwierigkeit liegt also darin, für den Computer Texte so aufzubereiten, dass er sie zum einen verarbeiten kann und zum anderen der Kontext der Wörter nicht verloren geht. Genau mit dieser Herausforderung befasst sich die linguistische Datenverarbeitung. Um die Ergebnisse abschließend aussagekräftig bewerten zu können, werden, wie einführend bereits erwähnt, zwei Techniken für die Klassifikation vorgestellt. Dabei wird im ersten Ansatz bewusst auf das Verwenden eines neuronalen Netzes verzichtet, um zu zeigen, wie sich Deep-Learning-Techniken im Vergleich zu eher konventionellen Methoden verhalten. Die Wahl fällt hier auf ein \textit{Convolutional Neural Network}. -Der Unterschied zu anderen Feedforward-Netzen steckt im Wort \textit{convolutional}, was auf Deutsch \textit{Faltung} bedeutet. Diese mathematische Faltungsoperation sorgt dafür, dass CNNs nicht nur bei der Bildverarbeitung, sondern generell sequenzielle Daten effizienter verarbeiten. So können \glqq kleine eindimensionale CNNs bei einfachen Aufgaben wie Textklassifizierung [...] eine schnelle Alternative zu RNNs darstellen.\grqq{ \cite[S.288]{chollet_francois_2018}} Aufgrund dieser Tatsache wird der Ansatz mit RNNs bereits in der Aufgabenstellung ausgeschlossen. \ No newline at end of file +Der Unterschied zu anderen Feedforward-Netzen steckt im Wort \textit{convolutional}, was auf Deutsch \textit{Faltung} bedeutet. Diese mathematische Faltungsoperation sorgt dafür, dass CNNs nicht nur bei der Bildverarbeitung, sondern generell sequenzielle Daten effizienter verarbeiten. So können \glqq kleine eindimensionale CNNs bei einfachen Aufgaben wie Textklassifizierung [...] eine schnelle Alternative zu RNNs darstellen.\grqq{ \cite[S.\,288]{chollet_francois_2018}} Aufgrund dieser Tatsache wird der Ansatz mit RNNs bereits in der Aufgabenstellung ausgeschlossen. \ No newline at end of file diff --git a/Dokumentation/2_grundlagen.tex b/Dokumentation/2_grundlagen.tex index 6a137a2..06bb9e6 100644 --- a/Dokumentation/2_grundlagen.tex +++ b/Dokumentation/2_grundlagen.tex @@ -3,26 +3,27 @@ Im Folgenden wird das Basiswissen zur Anwendung der \textbf{Word2Vec-Technik} erläutert. Zu Beginn bedarf es Methoden zur Umwandlung von Sprache in eine für Computer lesbare Form. Darauf folgt eine Implementierung der Technik von Grund auf. \subsection{Linguistische Datenverarbeitung} -Die Technik der \textbf{linguistischen Datenverarbeitung} (engl. \textit{Natural Language Processing}, kurz NLP) beschreibt die maschinelle Verarbeitung von menschlicher Sprache. Das NLP erfordert interdisziplinäre Kompetenzen aus sowohl Linguistik und Informatik, sowie dem Forschungsfeld der künstlichen Intelligenz. Typische Anwendungen für NLP in der Industrie sind die Klassifikation von Dokumenten, maschinelle Übersetzungen, automatische Vervollständigung von Suchanfragen, Spracherkennung und sogar Chatbots \cite[S.28]{krohn_beyleveld_bassens_2020}. +Die Technik der \textbf{linguistischen Datenverarbeitung} (engl. \textit{Natural Language Processing}, kurz NLP) beschreibt die maschinelle Verarbeitung von menschlicher Sprache. Das NLP erfordert interdisziplinäre Kompetenzen aus sowohl Linguistik und Informatik als auch dem Forschungsfeld der künstlichen Intelligenz. Typische Anwendungen für NLP in der Industrie sind die Klassifikation von Dokumenten, maschinelle Übersetzungen, automatische Vervollständigung von Suchanfragen, Spracherkennung und Chatbots \cite[S.\,28]{krohn_beyleveld_bassens_2020}. -Die Klassifikation von Dokumenten ist eine NLP-Aufgabe mit mittlerer Komplexität. Dazu gehört beispielsweise eine Kritik \glqq in eine bestimmte Kategorie einzuordnen\grqq{} \cite[S.28]{krohn_beyleveld_bassens_2020}. Die Verarbeitung von Sprache bedarf einer Darstellung, in der sie von Computern ausgewertet werden kann. Um eine solche quantitative Form zu erreichen, gibt es zwei gängige Methoden. Zum einen die \textbf{1-aus-n-Kodierung} (auch \textit{One-Hot-Kodierung}, engl. \textit{One-Hot-Encoding}) und zum anderen \textbf{Wortvektoren} (auch \textit{Worteinbettungen}, engl. \textit{Word Embeddings}). +Die Klassifikation von Dokumenten ist eine NLP-Aufgabe mit mittlerer Komplexität. Dazu gehört beispielsweise eine Kritik \glqq in eine bestimmte Kategorie einzuordnen\grqq{} \cite[S.\,28]{krohn_beyleveld_bassens_2020}. Die Verarbeitung von Sprache bedarf einer Darstellung, in der sie von Computern ausgewertet werden kann. Um eine solche quantitative Form zu erreichen, gibt es zwei gängige Methoden. Zum einen die \textbf{1-aus-n-Kodierung} (auch \textit{One-Hot-Kodierung}, engl. \textit{One-Hot-Encoding}) und zum anderen \textbf{Wortvektoren} (auch \textit{Worteinbettungen}, engl. \textit{Word Embeddings}). \subsubsection{Vorverarbeitung der Sprachdaten \label{subsec:vorverarbeitung}} Die Vorverarbeitung eines Datensatzes spielt bei der linguistischen Datenverarbeitung eine wichtige Rolle. Thematisch ist diese Vorverarbeitung an dieser Stelle, also vor der Umwandlung in eine für den Computer nutzbare Form, einzuordnen. Bei den Veranschaulichungen der nächsten Abschnitte des Grundlagenteils werden die Techniken jedoch nur teilweise bis gar nicht angewendet. Erst in Abschnitt \ref{sec:Datenaufbereitung} kommen die nachfolgend vorgestellten Methoden am eigentlichen Datensatz zum Einsatz. -Für den Anfang gilt es, die Wörter eines Textes einzeln und unabhängig voneinander abzuspeichern. Dieser Prozess heißt \textbf{Tokenisierung}, da jedes Wort als ein \textbf{Token} gesehen wird. Im \textbf{Textkorpus} befinden sich demnach die tokenisierten Wörter des Rohtextes. \cite[S.241]{krohn_beyleveld_bassens_2020} +Für den Anfang gilt es, die Wörter eines Textes einzeln und unabhängig voneinander abzuspeichern. Dieser Prozess heißt \textbf{Tokenisierung}, da jedes Wort als ein \textbf{Token} gesehen wird. Im \textbf{Textkorpus} befinden sich demnach die tokenisierten Wörter des Rohtextes \cite[S.\,241]{krohn_beyleveld_bassens_2020}. -Im nächsten Schritt geht es darum, alle Großbuchstaben in Kleinbuchstaben umzuwandeln. Gerade im Englischen werden fast ausschließlich Wörter an Satzanfängen großgeschrieben. Ein kontextueller Unterschied besteht nur in seltenen Ausnahmefällen. Im selben Zuge können auch Satzzeichen entfernt werden, da es für den Computer keinen Unterschied macht, ob ein Wort in einem Teilsatz oder am Satzende steht. Durch das Entfernen von Großbuchstaben und Satzzeichen kann die Größe des Datensatzes zumindest etwas verringert werden. +Im nächsten Schritt geht es darum, alle Großbuchstaben in Kleinbuchstaben umzuwandeln. Gerade im Englischen werden fast ausschließlich Wörter an Satzanfängen großgeschrieben. Ein kontextueller Unterschied besteht nur in seltenen Ausnahmefällen. Im selben Zuge können auch Satzzeichen entfernt werden, da es für den Computer keinen Unterschied macht, ob ein Wort in einem Teilsatz oder am Satzende steht. Durch das Entfernen von Großbuchstaben und Satzzeichen kann die Größe des Datensatzes etwas verringert werden. -Um den Korpus weiter zu verkleinern, werden anschließend die sogenannten \textbf{Stoppwörter} (engl. \textit{stop words}) entfernt. Ein Stoppwort zeichnet sich dadurch aus, dass es zum einen häufig vorkommt und zum anderen eine geringe Bedeutung vorweist. Im Deutschen trifft das beispielsweise auf Präpositionen wie \textit{an} oder \textit{in} zu. Im Englischen können es Wörter wie \textit{the} oder \textit{of} sein. Es gibt keine allgemeingültige Sammlung von Stoppwörtern, da diese immer auch auf den Kontext abgestimmt werden müssen. \cite[S.242]{krohn_beyleveld_bassens_2020} +Um den Korpus weiter zu verkleinern, werden anschließend die sogenannten \textbf{Stoppwörter} (engl. \textit{stop words}) entfernt. Ein Stoppwort zeichnet sich dadurch aus, dass es zum einen häufig vorkommt und zum anderen eine geringe Bedeutung aufweist. Im Deutschen trifft das beispielsweise auf Präpositionen wie \textit{an} oder \textit{in} zu. Im Englischen können es Wörter wie \textit{the} oder \textit{of} sein. Es gibt keine allgemeingültige Sammlung von Stoppwörtern, da diese immer auch auf den Kontext abgestimmt werden müssen \cite[S.\,242]{krohn_beyleveld_bassens_2020}. -Meist sind diese Techniken schon ausreichend um den Datensatz bedeutend zu reduzieren und zu bereinigen, ohne jedoch den Kontext zu verfälschen. Es gibt darüber hinaus noch das \textbf{Stemming} und die sogenannten \textbf{N-Gramme}. Beides komplexere Methoden, die in dieser Ausarbeitung allerdings keine Anwendung finden, dennoch erwähnt werden sollten. Ersteres ist \glqq die Zurückführung von Wörtern auf ihren Wortstamm.\grqq{ \cite[S.242]{krohn_beyleveld_bassens_2020}} Letzteres beschreibt Wörter, die überwiegend zusammen vorkommen. Als Beispiele eignen sich das \textit{Bigramm} \textit{New York} beziehungsweise das \textit{Trigramm} \textit{New York City}, welche sich zu einem Token zusammenfassen lassen. +Meist sind diese Techniken schon ausreichend, um den Datensatz bedeutend zu reduzieren und zu bereinigen, ohne jedoch den Kontext zu verfälschen. Es gibt darüber hinaus noch das \textbf{Stemming} und die sogenannten \textbf{N-Gramme}. Beides sind komplexere Methoden, die in dieser Ausarbeitung allerdings keine Anwendung finden, dennoch erwähnt werden sollten. Ersteres ist \glqq die Zurückführung von Wörtern auf ihren Wortstamm.\grqq{ \cite[S.\,242]{krohn_beyleveld_bassens_2020}} Letzteres beschreibt Wörter, die überwiegend zusammen vorkommen. Als Beispiele eignen sich das \textit{Bigramm} \textit{New York} beziehungsweise das \textit{Trigramm} \textit{New York City}, welche sich zu einem Token zusammenfassen lassen. \subsubsection{1-aus-n-Kodierung} -Bei der 1-aus-n-Kodierung werden die im jeweiligen Textbeispiel vorkommenden Wörter in den Spalten der Matrix abgebildet. In die Zeilen dieser Matrix werden die eindeutigen Wörter geschrieben. Eine Zelle der Matrix repräsentiert das Vorhandensein eines einzigartigen Wortes an einer bestimmten Stelle im Text mit einer \textit{1}. Die restlichen Zellen der Zeile markieren mit einer \textit{0} die Abwesenheit des eindeutigen Wortes. Es ergibt sich also eine dünnbesetzte, hochdimensionierte Binärmatrix, wobei jede Spalte maximal eine festprogrammierte \textit{1} enthält. \cite[S.237]{chollet_francois_2018} +Bei der 1-aus-n-Kodierung werden die im jeweiligen Textbeispiel vorkommenden Wörter in den Spalten der Matrix abgebildet. In die Zeilen dieser Matrix werden die eindeutigen Wörter geschrieben. Eine Zelle der Matrix repräsentiert das Vorhandensein eines einzigartigen Wortes an einer bestimmten Stelle im Text mit einer \textit{1}. Die restlichen Zellen der Zeile markieren mit einer \textit{0} die Abwesenheit des eindeutigen Wortes. Es ergibt sich also eine dünnbesetzte, hochdimensionierte Binärmatrix, wobei jede Spalte maximal eine festprogrammierte \textit{1} enthält \cite[S.\,237]{chollet_francois_2018}. -Das entnommene Beispiel in Tabelle \ref{tbl:onehotcoding} zeigt die 1-aus-n-Kodierung des Satzes \glqq The bat sat on the cat.\grqq{} Der Satz besteht aus 6 Wörtern, wovon 5 eindeutig sind. Daraus resultiert die folgende $5\times6$-Matrix. Das Wort \glqq the\grqq{} kommt in diesem Satz zwei Mal vor, was durch die entsprechenden Einträge an erster und fünfter Stelle der ersten Zeile zu sehen ist. Die übrigen eindeutigen Wörter werden mit einer \textit{1} an ihrer Position im Satz markiert. Eine solche Darstellungsform ist sehr intuitiv und für kleine Textbeispiele sehr überschaubar. Bei großen Datensätzen wie dem \textit{Yelp restaurant review dataset} führt die dünne Besetzung dazu, dass zwar die Wortstellung gespeichert wird, der Kontext jedoch verloren geht. Darüber hinaus wird diese Art der Codierung bei entsprechend großen Datensätzen zunehmend ineffizient, da für jedes einzigartige Wort eine neue Dimension hinzukommt. +Das entnommene Beispiel in Tabelle \ref{tbl:onehotcoding} zeigt die 1-aus-n-Kodierung des Satzes \glqq The bat sat on the cat.\grqq{} Der Satz besteht aus 6 Wörtern, wovon 5 eindeutig sind. Daraus resultiert die folgende $5\times6$-Matrix. Das Wort \glqq the\grqq{} kommt in diesem Satz zweimal vor, was durch die entsprechenden Einträge an erster und fünfter Stelle der ersten Zeile zu sehen ist. Die übrigen eindeutigen Wörter werden mit einer \textit{1} an ihrer Position im Satz markiert. Eine solche Darstellungsform ist sehr intuitiv und für kleine Textbeispiele sehr überschaubar. Bei großen Datensätzen wie dem \textit{Yelp restaurant review dataset} führt die dünne Besetzung dazu, dass zwar die Wortstellung gespeichert wird, der Kontext jedoch verloren geht. Darüber hinaus wird diese Art der Codierung bei entsprechend großen Datensätzen zunehmend ineffizient, aufgrund der schnell steigenden Dimensionen. +%da für jedes einzigartige Wort eine neue Dimension hinzukommt. \begin{table}[H] \centering @@ -36,15 +37,15 @@ on & 0 & 0 & 0 & 1 & 0 & 0 \\ \vdots & & & & & & \\ $n$ & & & & & & \end{tabular} -\caption{1-aus-n-Kodierung \cite[S.32]{krohn_beyleveld_bassens_2020}} +\caption{1-aus-n-Kodierung \cite[S.\,32]{krohn_beyleveld_bassens_2020}} \label{tbl:onehotcoding} \end{table} \subsubsection{Wortvektoren} Das Einbetten von Wörtern in Wortvektoren bietet gegenüber dem One-Hot-Encoding den entscheidenden Vorteil, dass die Wortbedeutung über die Daten erlernt wird und abgelesen werden kann. Bei der Erstellung von Wortvektoren werden zunächst die eindeutigen Wörter an eine beliebige Stelle eines \textit{Vektorraums} überführt. Dabei verschiebt sich die Position der Wörter so lange, bis der gesamte Datensatz eingelesen ist. Durch die Betrachtung zusätzlicher \textit{Kontextwörter} kann die Bedeutung des eigentlichen \textit{Zielwortes} im Wortvektor repräsentiert werden. Bei beispielsweise drei Kontextwörtern werden die drei Wörter vor und nach dem Zielwort betrachtet. Am Ende bekommt eine Position im Vektorraum eine bestimmte Bedeutung zugeordnet. -Im so entstehenden $n$-dimensionalen Vektorraum finden sich die einzelnen Wörter des Datensatzes wieder, wobei jedes durch einen Vektor (bspw. $\vec{king}$) beschrieben wird. Der Spaltenvektor der Dimension $n\times1$ bestimmt den Ort des Wortes in allen verfügbaren Dimensionen. Aufgrund fehlendem Vorstellungsvermögens ist es für den Menschen schwierig sich mehr als drei Dimensionen vorzustellen. Ein zweidimensionales Beispiel für einen Vektorraum findet sich in Abbildung \ref{fig:scratch}. Allgemein gilt, dass \glqq je enger zwei Wörter im Vektorraum beieinander stehen, umso ähnlicher ist auch ihre Bedeutung, was durch die Ähnlichkeit der Kontextwörter bestimmt wird, die ihnen in der natürlichen Sprache nahe sind.\grqq{ \cite[S.35]{krohn_beyleveld_bassens_2020}} So liegen Synonyme und Falschschreibungen eng beisammen. Wortgruppen mit ähnlichem Kontext bilden Cluster und Subcluster innerhalb eines großen Vektorraumes. +Im so entstehenden $n$-dimensionalen Vektorraum finden sich die einzelnen Wörter des Datensatzes wieder, wobei jedes durch einen Vektor (bspw. $\vec{king}$) beschrieben wird. Der Spaltenvektor der Dimension $n\times1$ bestimmt den Ort des Wortes in allen verfügbaren Dimensionen. Aufgrund fehlendem Vorstellungsvermögen ist es für den Menschen schwierig sich mehr als drei Dimensionen vorzustellen. Ein zweidimensionales Beispiel für einen Vektorraum findet sich in Abbildung \ref{fig:scratch}. Allgemein gilt, dass \glqq je enger zwei Wörter im Vektorraum beieinander stehen, umso ähnlicher ist auch ihre Bedeutung, was durch die Ähnlichkeit der Kontextwörter bestimmt wird, die ihnen in der natürlichen Sprache nahe sind.\grqq{ \cite[S.\,35]{krohn_beyleveld_bassens_2020}} So liegen Synonyme und Falschschreibungen eng beieinander. Wortgruppen mit ähnlichem Kontext bilden Cluster und Subcluster innerhalb eines großen Vektorraumes. -Für Wortvektoren gilt: \glqq Die geometrischen Beziehungen zwischen Wortvektoren sollten die semantische Beziehungen zwischen den Wörtern widerspiegeln.\grqq{} und \glqq Wortvektoren haben die Aufgabe, die menschliche Sprache auf einen geometrischen Raum abzubilden.\grqq{} Ein Vektor von einem Wort zu einem anderen repräsentiert die \glqq semantische Beziehung zwischen diesen Wörtern.\grqq{ \cite[S.238f]{chollet_francois_2018}} Ein bekanntes Beispiel dafür ist die Hauptstadt-Land-Beziehung, bei der Abstand und Orientierung von einem Land zu seiner Hauptstadt im Vektorraum auf andere Länder übertragen werden können, sodass der Vektor immer auf die zugehörige Hauptstadt zeigt. Eine konkrete Anwendung mit dem ebenso bekannten \glqq \textit{king-queen}\grqq -Beispiel ist im nächsten Abschnitt unter Gleichung \ref{eqn:kingqueen} zu sehen. +Für Wortvektoren gilt: \glqq Die geometrischen Beziehungen zwischen Wortvektoren sollten die semantische Beziehungen zwischen den Wörtern widerspiegeln.\grqq{} und \glqq Wortvektoren haben die Aufgabe, die menschliche Sprache auf einen geometrischen Raum abzubilden.\grqq{} Ein Vektor von einem Wort zu einem anderen repräsentiert die \glqq semantische Beziehung zwischen diesen Wörtern.\grqq{ \cite[S.\,238f]{chollet_francois_2018}} Ein bekanntes Beispiel dafür ist die Hauptstadt-Land-Beziehung, bei der Abstand und Orientierung von einem Land zu seiner Hauptstadt im Vektorraum auf andere Länder übertragen werden können, sodass der Vektor immer auf die zugehörige Hauptstadt zeigt. Eine konkrete Anwendung mit dem ebenso bekannten \glqq \textit{king-queen}\grqq -Beispiel ist im nächsten Abschnitt unter Gleichung \ref{eqn:kingqueen} zu sehen. \input{w2vFromScratch} \ No newline at end of file diff --git a/Dokumentation/Auswertung.tex b/Dokumentation/Auswertung.tex index 66405d3..27035c3 100644 --- a/Dokumentation/Auswertung.tex +++ b/Dokumentation/Auswertung.tex @@ -1,16 +1,16 @@ \subsection{Subjektivität} -Wichtig für machine learning algorithms ist es einen möglichst objektiven Datensatz zu benutzen, auf dem letztlich trainiert wird. Je nach konkretem Szenario und Fragestellung kann sich dies als schwierig gestalten. So ist z.\,B. \noteable{Racial Profiling} durch künstliche Intelligenz ein vieldiskutiertes Thema in diesem Sektor. \wip{Artikel Referenz oder so?.} +Wichtig für machine learning algorithms ist es, einen möglichst objektiven Datensatz zu benutzen, auf dem letztlich trainiert wird. Je nach konkretem Szenario und Fragestellung kann sich dies als schwierig gestalten. So ist z.\,B. \noteable{Racial Profiling} durch künstliche Intelligenz ein vieldiskutiertes Thema in diesem Sektor. % Datensatz mit vorurteilen führt zu entsprechenden Wordclustern % -> Bsp aus w2vfromscratch -Die in dieser Arbeit verwendete Methode "`Word2Vec"' ist besonders anfällig für solche Probleme. Schließlich sollen die Wörter anhand ihrer Bedeutung gruppiert und in Relation zueinander eingeordnet werden. Ist der Datensatz auf dem diese Cluster-Bildung basiert durch Vorurteile oder gar Diskriminierung betroffen spiegelt sich dies auch in den wordembeddings wieder. Dafür muss dies nicht einmal gezielt in den Ausgangsdaten vorliegen, auch ein unvollständiger Datensatz kann zu solchen Ergebnissen führen. Ein direktes Beispiel dafür findet sich in dem Kapitel \ref{subsec:w2vfs} in der Abbildung \ref{fig:scratch}. Hier wurden die Begriffe erfolgreich in männlich und weiblich unterteilt, dazu gehören aber auch die verwendeten Adjektive: \noteable{wise} und \noteable{pretty} sind laut des Programms eher weibliche Begriffe, während \noteable{strong} ein männlicher Begriff sei. Dies stellt der Datensatz letztlich auch so dar. Nun muss man fairerweise sagen, dass diese Begriffe auch von Menschen vermutlich in dieser Weise eingeordnet worden wären. Mit einem umfassenden Datensatz wären diese Tendenzen aber möglicherweise schwächer und allgemein etwas neutraler ausgefallen. +Die in dieser Arbeit verwendete Methode Word2Vec ist besonders anfällig für solche Probleme. Schließlich sollen die Wörter anhand ihrer Bedeutung gruppiert und in Relation zueinander eingeordnet werden. Ist der Datensatz auf dem diese Cluster-Bildung basiert durch Vorurteile oder gar Diskriminierung betroffen, spiegelt sich dies auch in den wordembeddings wieder. Dafür muss dies nicht einmal gezielt in den Ausgangsdaten vorliegen, auch ein unvollständiger Datensatz kann zu solchen Ergebnissen führen. Ein direktes Beispiel dafür findet sich in Kapitel \ref{subsec:w2vfs} in Abbildung \ref{fig:scratch}. Hier wurden die Begriffe erfolgreich in männlich und weiblich unterteilt. Dazu gehören aber auch die verwendeten Adjektive \noteable{wise} und \noteable{pretty}, welche laut des Programms eher weibliche Begriffe seien, während \noteable{strong} ein männlicher Begriff sei. Dies stellt der Datensatz letztlich auch so dar. Es ist anzunehmen, dass diese Begriffe auch von Menschen vermutlich in dieser Weise eingeordnet worden wären. Mit einem umfassenden Datensatz wären diese Tendenzen aber möglicherweise schwächer und allgemein etwas neutraler ausgefallen. % Die Aufgabe an sich ist bereits subjektiv, da Sprache subjektiv ist und diese % auch noch in einem meinungsbehafteten Raum genutzt wird -Gleichzeitig sind diese Subjektivitäten aber auch in vielen Fällen wichtig. Sprache ist in der Regel meinungsbehaftet und viele machine learning Projekte beschäftigen sich damit. So auch dieses Projekt zu einem gewissen Grad. Um Reviews in entsprechende Kategorien einzuteilen müssen die Wörter anhand ihrer gebräuchliche Nutzung eingeordnet werden, im Idealfall speziell in diesem Szenario, um kontextspezifische Unterschiede zu vermeiden. Wenn ein Wort also entgegengesetzt der ursprünglichen Bedeutung in einem völlig anderen Kontext verwendet wird, stellt dies eine wichtige Information dar, welche für die Auswertung beachtet werden muss. \wip{Ich hab das Gefühl das endet abrupt und man könnte hier noch ein paar Worte zu sagen, aber ich tu mich schwer damit} +Gleichzeitig sind diese Subjektivitäten aber auch in vielen Fällen wichtig. Sprache ist in der Regel meinungsbehaftet und viele machine learning Projekte beschäftigen sich damit, wie auch dieses Projekt zu einem gewissen Grad. Um Reviews in entsprechende Kategorien einzuteilen, müssen die Wörter anhand ihrer gebräuchlichen Nutzung eingeordnet werden. Um kontextspezifische Unterschiede zu vermeiden sollte sich idealerweise die Erstellung der Wortvektoren aufgrund dieser Nutzung auf das vorliegende Szenario beziehen. Wenn ein Wort also entgegengesetzt der ursprünglichen Bedeutung in einem völlig anderen Kontext verwendet wird, stellt dies eine wichtige Information dar, welche für die Auswertung beachtet werden muss. Jedoch ist es aufwändig entsprechend zugeschnittene wordembeddings zu erstellen. Weiterhin sind davon viele Wörter nicht betroffen, wodurch ein verhältnismäßig großer Mehraufwand für eine recht geringe Menge an Wörtern entsteht. Man kann ebenfalls davon ausgehen, dass das Modell in vielen Fällen diese Probleme entsprechend optimiert, sodass diese Wörter letztlich korrekt interpretiert werden. % Gleicher Schreibstil wie Leute welche häufig negativ gewertet haben: Automatisch negativ -Schreibstile unterscheiden sich von Person zu Person. Besonders in einem informellen Raum wie es das Internet häufig ist zeigt sich dies. Gewisse Wortwahl und Zeichensetzung ist für die einen ein eindeutiges Zeichen für Sarkasmus, während andere diese Aussagen ernst nehmen. Auch Akzente und Dialekte spiegeln sich teilweise durch Slangwörter oder sonstige Besonderheiten im schriftlichen wieder. Dies kann verschiedene Auswirkungen auf die Kategorisierung von Texten haben. Eine mögliches Szenario wäre, dass ein spezieller Dialekt häufig mit negativen Reviews vorkommt. Die Ursache dafür könnte dabei einen spezifischen Grund haben oder auch rein zufällig sein. Unabhängig davon kann dies jedoch dazu führen, dass das Programm diese \emph{Korrelation} entdeckt und eine \emph{Kausalität} herstellt. Folglich werden alle Reviews, welche diesen Dialekt enthalten als negativ kategorisiert, darunter auch solche, welche ursprünglich positiv waren. +Schreibstile unterscheiden sich von Person zu Person. Besonders in einem informellen Raum wie es das Internet häufig ist zeigt sich dies. Gewisse Wortwahl und Zeichensetzung ist für die einen ein eindeutiges Zeichen für Sarkasmus, während andere diese Aussagen ernst nehmen. Auch Akzente und Dialekte spiegeln sich teilweise durch Slangwörter oder sonstige Besonderheiten im schriftlichen wieder. Dies kann verschiedene Auswirkungen auf die Kategorisierung von Texten haben. Eine mögliches Szenario wäre, dass ein spezieller Dialekt häufig in negativen Reviews vorkommt. Die Ursache dafür könnte dabei einen spezifischen Grund haben oder auch rein zufällig sein. Unabhängig davon kann dies jedoch dazu führen, dass das Programm diese \emph{Korrelation} entdeckt und eine \emph{Kausalität} herstellt. Folglich werden alle Reviews, welche diesen Dialekt enthalten als negativ kategorisiert, darunter auch solche, welche tatsächlich positiv sind. \subsection{Auswertung} %%Gegenüberstellung Konfusionsmatrix & ergebnisse @@ -20,28 +20,29 @@ Schreibstile unterscheiden sich von Person zu Person. Besonders in einem informe Im Folgenden werden die Ergebnisse der Mean- und der CNN-Methode ausgewertet und gegenübergestellt. Zunächst wird jedoch der Einfluss der Trainingsgewichte untersucht. \subsubsection{Gewichte} -Das Mean-Vektor-Klassifikationsmodell wurde sowohl mit, als auch ohne Trainingsgewichte getestet. Dabei hat die Variante ohne extra Gewichte ein allgemein besseres Ergebnis mit $85.70\%$ gegenüber $80.02\%$ ohne Gewichte. Die Konfusionsmatrizen aus den Tabellen \ref{tab:m_w} und \ref{tab:conf_no_w} zeigen jedoch, dass die Verteilung der richtig bestimmten Reviews mit Gewichten gleichmäßiger ist. Ohne Gewichte werden mehr negative und positive Reviews richtig klassifiziert, aber die Anzahl der richtig bestimmten neutralen Reviews beträgt gerade einmal knapp über $27\%$ gegenüber $68\%$ mit Gewichten. Außerdem werden mehr als dreimal so viele neutrale Reviews als positiv identifiziert, wenn die Gewichte weg gelassen werden. -Unter Berücksichtigung der ursprünglichen Distribution des Datensatzes, wie zuvor in Bild \ref{fig::DST} gezeigt, wird auch deutlich, wieso diese 'Entscheidung' für den Algorithmus vom Vorteil ist. Es gibt eine hohe Anzahl an positiven Reviews, während es verhältnismäßig wenig negative, dafür aber nur einen Bruchteil an neutralen Reviews gibt. Wie bereits in Kapitel \ref{subsubsec:Dist} angesprochen entsteht dadurch unweigerlich ein bias zu einer Identifizierung als positive Review, da dies im Gesamtergebnis zu einem größeren Erfolg führt. +Das Mean-Vektor-Klassifikationsmodell wurde sowohl mit als auch ohne Trainingsgewichte getestet. Dabei hat die Variante ohne extra Gewichte ein allgemein besseres Ergebnis mit $85.70\,\%$ gegenüber $80.02\,\%$ ohne Gewichte. Die Konfusionsmatrizen aus den Tabellen \ref{tab:m_w} und \ref{tab:conf_no_w} zeigen jedoch, dass die Verteilung der richtig bestimmten Reviews mit Gewichten gleichmäßiger ist. Ohne Gewichte werden mehr negative und positive Reviews richtig klassifiziert, aber die Anzahl der richtig bestimmten neutralen Reviews beträgt gerade einmal knapp über $27\,\%$ gegenüber $68\,\%$ mit Gewichten. Außerdem werden mehr als dreimal so viele neutrale Reviews als positiv identifiziert, wenn die Gewichte weg gelassen werden. +Unter Berücksichtigung der ursprünglichen Distribution des Datensatzes, wie zuvor in Bild \ref{fig::DST} gezeigt, wird auch deutlich, wieso diese 'Entscheidung' für den Algorithmus von Vorteil ist. Es gibt eine hohe Anzahl an positiven Reviews, während es verhältnismäßig wenig negative, dafür aber nur einen Bruchteil an neutralen Reviews gibt. Wie bereits in Kapitel \ref{subsubsec:Dist} angesprochen entsteht dadurch unweigerlich ein bias zu einer Identifizierung als positive Review, da dies im Gesamtergebnis zu einem größeren Erfolg führt. Es lässt sich also erkennen, dass die Gewichtung der Daten durchaus den gewünschten Effekt erzielt, jedoch darunter das Gesamtergebnis etwas gelitten hat. \subsubsection{Mean vs. CNN \label{subsub:MvsC}} -Für die Gegenüberstellung der verschiedenen Methoden werden nur die Ergebnisse der Mean Methode mit Gewichten berücksichtigt, um so ein ausgeglicheneres Ausgangsszenario zu erhalten. Hier lässt sich zwar erkennen, dass die CNN Methode geringfügig besser abgeschnitten hat, mit $81.44\%$ gegenüber $80.02\%$, jedoch ist dieser Unterschied wirklich minimal. Die Methoden können daher als gleichwertig betrachtet werden. Auch die Konfusionsmatrizen \ref{tab:m_w} und \ref{tab:conf_w_cnn} sind annähernd identisch. Das CNN Modell hat lediglich wieder weniger Wert auf neutrale Reviews gelegt und stattdessen eine positive und negative Kategorisierung bevorzugt. +Für die Gegenüberstellung der verschiedenen Methoden werden nur die Ergebnisse der Mean Methode mit Gewichten berücksichtigt, um so ein ausgeglicheneres Ausgangsszenario zu erhalten. Hier lässt sich zwar erkennen, dass die CNN Methode geringfügig besser abgeschnitten hat, mit $81.44\,\%$ gegenüber $80.02\,\%$, jedoch ist dieser Unterschied minimal. Die Methoden können daher als gleichwertig betrachtet werden. Auch die Konfusionsmatrizen \ref{tab:m_w} und \ref{tab:conf_w_cnn} sind annähernd identisch. Das CNN Modell hat lediglich wieder weniger Wert auf neutrale Reviews gelegt und stattdessen eine positive und negative Kategorisierung bevorzugt. %Mean: 10s epoche, 4ms pro Step; 2048 batchsize %CNN, groß: 7min epoche, ?? pro Step;256 batchsize %CNN, RAM: 17s epoche, 21ms step;128 batchsize -Aufgrund der ähnlichen Ergebnisse ist jedoch die Mean Methode deutlich zu bevorzugen. Zum einen benötigt diese in der Regel weniger Vorbereitung, hier in Form der Generatoren. Das liegt daran, dass die Mean Methode schwächer skalierende Anforderungen an die Hardware hat. Dadurch ist auch die Trainingszeit um ein vielfaches schneller mit ca.\@ 10s pro Epoche gegenüber ungefähr 7min. Der Großteil dieses Unterschieds entsteht dabei durch das Lesen von der Festplatte durch die Generatoren anstelle des Arbeitsspeichers. Aber auch Konfigurationsunterschiede sind dabei zu beachten, z.\,.B\@ nutzt der Mean eine wesentlich größere batchsize von 2048. Im Vergleich arbeitet das CNN nur mit einer Größe von 256. +Aufgrund der ähnlichen Ergebnisse ist jedoch die Mean Methode deutlich zu bevorzugen. Zum einen benötigt diese in der Regel weniger Vorbereitung, hier in Form der Generatoren. Das liegt daran, dass die Mean Methode schwächer skalierende Anforderungen an die Hardware hat. Dadurch ist auch die Trainingszeit um ein vielfaches schneller mit ca.\,10s pro Epoche gegenüber ungefähr 7min. Der Großteil dieses Unterschieds entsteht dabei durch das Lesen von der Festplatte durch die Generatoren anstelle des Arbeitsspeichers. Aber auch Konfigurationsunterschiede sind dabei zu beachten, z.\,.B\@ nutzt der Mean eine wesentlich größere batchsize von 2048. Im Vergleich arbeitet das CNN nur mit einer Größe von 256. %Aber auch in kleineren Beispielen, bei denen das CNN auch ausschließlich den Arbeitsspeicher verwenden kann, schneidet der Mean besser ab. Hier benötigt das CNN immer noch ca.\@ 17s pro Epoche. Jedoch sind hier zusätzlich unterschiedliche batchsizes von 2048 -Allerdings bietet das CNN Modell mehr Möglichkeiten an der Struktur zu arbeiten als die Mean Methode. Während am Mean nur wenige Änderungen vorgenommen werden könnten bietet das CNN ein wesentlich größeres Potenzial. Es besteht also durchaus die Möglichkeit, dass ein ausführlicheres Experimentieren mit dem Aufbau des CNN zu konstant besseren Ergebnissen führt. \wip{Dies konnte in dieser Arbeit aufgrund von Zeitproblemen leider nicht geprüft werden. (Von Zeitproblemen bei ner Arbeit zu reden, welche n halbes Jahr ging is vlt n bissl dreist xD)} +Allerdings bietet das CNN Modell mehr Möglichkeiten an der Struktur zu arbeiten als die Mean Methode. Während am Mean nur wenige Änderungen vorgenommen werden könnten, bietet das CNN ein wesentlich größeres Potenzial. Es besteht also durchaus die Möglichkeit, dass ein ausführlicheres Experimentieren mit dem Aufbau des CNN zu konstant besseren Ergebnissen führt. \subsubsection{Problemstellung} -Die relativ geringe Erfolgsquote der Modelle, aber z.\,B.\@ auch die Schwierigkeiten mit neutralen Reviews zeigen sicherlich, dass es noch Optimierungsmöglichkeiten gibt. Dennoch liegt ein großer Teil der Herausforderung auch an der eigentlichen Problemstellung. Die meisten Menschen hätten vermutlich auch Schwierigkeiten dabei eine 2 Sterne Review, sprich einer negativen, von einer 3 Sterne, also neutralen, zu unterscheiden. Zum einen sind die Übergänge recht fließend. Zum Anderen sind Menschen aber auch einfach unterschiedlich: Der gleiche Text mit den identischen Argumenten könnte für eine Person eine 3 Sterne und für die nächste eine 4 Sterne Review sein. Aus der Sicht des Modells gäbe es also 2 Einträge mit identischen Merkmalen, welche jedoch unterschiedlichen Kategorien zugeordnet werden. +Die relativ geringe Erfolgsquote der Modelle, aber z.\,B.\@ auch die Schwierigkeiten mit neutralen Reviews zeigen sicherlich, dass es noch Optimierungsmöglichkeiten gibt. Dennoch liegt ein großer Teil der Herausforderung auch an der eigentlichen Problemstellung. Die meisten Menschen hätten vermutlich auch Schwierigkeiten dabei eine 2 Sterne Review, sprich eine negative, von einer 3 Sterne, also neutralen, zu unterscheiden. Zum einen sind die Übergänge recht fließend. Zum Anderen sind Menschen aber auch einfach unterschiedlich: Der gleiche Text mit den identischen Argumenten könnte für eine Person eine 3 Sterne und für die nächste eine 4 Sterne Review sein. Aus der Sicht des Modells gäbe es also 2 Einträge mit identischen Merkmalen, welche jedoch unterschiedlichen Kategorien zugeordnet werden. -\subsubsection{Fazit} -Zusammenfassend lässt sich sagen, dass Word2Vec ein valider erster Schritt zur Klassifizierung von Reviews ist. Die Ergebnisse zeigen dabei jedoch, dass noch Optimierungsbedarf herrscht. Dabei ist es aber unklar ob für die genutzten Modelle idealere Strukturen möglich sind oder ob diese Werte eine Obergrenze für diese Problemstellung in Kombination mit ebendiesen Modellen darstellen. -Davon ausgehend, dass die Ergebnisse eine Obergrenze darstellen ist die Mean Methode aufgrund der in Kapitel \ref{subsub:MvsC} besprochenen Punkte deutlich dem CNN Ansatz vorzuziehen. +\newpage +\subsection{Fazit} +Zusammenfassend lässt sich sagen, dass Word2Vec ein valider erster Schritt zur Klassifizierung von Reviews ist. Die Ergebnisse zeigen jedoch, dass noch Optimierungsbedarf herrscht. Dabei ist es aber unklar, ob für die genutzten Modelle idealere Strukturen möglich sind oder ob diese Werte eine Obergrenze für diese Problemstellung in Kombination mit ebendiesen Modellen darstellen. +Davon ausgehend, dass die Ergebnisse eine Obergrenze darstellen, ist die Mean Methode aufgrund der in Kapitel \ref{subsub:MvsC} besprochenen Punkte deutlich dem CNN Ansatz vorzuziehen. Das deutliche Hauptproblem der Klassifizierung stellen die neutralen Reviews dar. Ein möglicher Ansatz wäre die Fragestellung auf eine Kategorisierung in positiv und negativ zu beschränken. Dadurch wird das Problem jedoch nicht gelöst sondern lediglich verschoben. Eine weitere Alternative wäre das Ignorieren von neutralen Reviews, sodass nur mit 1 und 2 sowie 4 und 5 Sterne Reviews gearbeitet wird. Dies wäre aber nur sinnvoll, wenn der geplante Nutzen dieser Klassifizierung das zulässt. Dadurch, dass die Anzahl der neutralen Reviews jedoch ohnehin verhältnismäßig sehr gering ist könnte dies z.\,B.\@ in der Marketinganalyse durchaus eine Option sein. diff --git a/Dokumentation/Generatoren.tex b/Dokumentation/Generatoren.tex index aabcb41..4d8677d 100644 --- a/Dokumentation/Generatoren.tex +++ b/Dokumentation/Generatoren.tex @@ -1,30 +1,30 @@ \subsection{Generatoren \label{subsec:Generator}} %Problemstellung -Spätestens wenn mit etwas größeren Datenmengen trainiert wird stellt sich bei einer unserer Methoden ein neues Problem dar. Während die mean-Methode ohne Probleme durchläuft bricht die CNN-Methode aufgrund mangelnden Arbeitsspeichers ab. %beschwert sich die CNN-Methode, dass nicht genug Arbeitsspeicher vorhanden ist. -Dies lässt sich auch ganz leicht nach folgender Formel nachrechnen: +Spätestens, wenn mit etwas größeren Datenmengen trainiert wird, stellt sich bei einer unserer Methoden ein neues Problem dar. Während die mean-Methode ohne Probleme durchläuft, bricht die CNN-Methode aufgrund mangelnden Arbeitsspeichers ab. %beschwert sich die CNN-Methode, dass nicht genug Arbeitsspeicher vorhanden ist. +Dies lässt sich auch anhand folgender Formel nachrechnen: %Vlt mit Formelzeichen, welche vorher im text definiert werden? % => Kürzere Formel & Mehr Text \begin{equation} \text{Anzahl Einträge }\times \text{ Vektorenanzahl } \times \text{ Vektorendimension } \times \text{ Datentyp-Größe} \end{equation} -Der Datentyp entspricht in unserem Fall float. Ein float wird in Python durch 64 Bit, also 8 Byte dargestellt. Gehen wir davon aus, dass wir alle 8 Millionen Einträge fürs fitten und somit gleichzeitig im Arbeitsspeicher benötigen. Für die mean-Vektor Methode ergibt sich somit folgende Rechnung: +Der Datentyp entspricht in unserem Fall float. Ein float wird in Python durch 64 Bit, also 8 Byte dargestellt. Geht man davon aus, dass alle 8 Millionen Einträge fürs fitten und somit gleichzeitig im Arbeitsspeicher benötigt werden, so ergibt sich für die mean-Vektor Methode folgende Rechnung: \begin{equation} 8,000,000 \times 1 \times 100 \times 8 \approx 6\text{ GB} \end{equation} -Dies könnte mit 8GB RAM etwas knapp werden, jedoch stellt es bei 16GB gar kein Problem dar. Bei der CNN-Methode sieht das jedoch wie folgt aus: +Dies könnte mit 8GB RAM etwas knapp werden, jedoch stellt es bei 16GB kein Problem dar. Bei der CNN-Methode sieht das jedoch wie folgt aus: \begin{equation}\label{eq:430GB} 8,000,000 \times 72 \times 100 \times 8 \approx 430\text{ GB} \end{equation} Das Problem ist recht deutlich. Viele Personen hätten auf ihrem privaten PC vermutlich nicht einmal genug Festplattenspeicher für diese Datenmenge, geschweige denn Arbeitsspeicher. \\ -Die Daten müssen bei der CNN-Methode also nur stückweise in den Arbeitsspeicher geladen werden, dann wird mit diesen trainiert und anschließend werden sie wieder aus dem Arbeitsspeicher gelöscht, um Platz für die nächsten Daten zu machen. Dabei gibt es wieder verschiedene Ansätze. +Die Daten müssen bei der CNN-Methode also nur stückweise in den Arbeitsspeicher geladen werden, dann wird mit diesen trainiert und anschließend werden sie wieder aus dem Arbeitsspeicher gelöscht, um Platz für die nächsten Daten zu machen. Dabei gibt es wieder verschiedene Ansätze, welche im Folgenden beschrieben werden. \subsubsection{Erster Generator}\label{subsubsec:simpleGen} %Erster Ansatz, sehr lange validierungszeit -Ein möglicher Ansatz ist die rohen Daten nur schrittweise einzulesen und diese dann erst dem word2vec model zu übergeben, um daraus einen Vektor zu machen. Dafür wird eine Funktion geschrieben, welche dann der fit Methode des eigentlichen machine learning models als Datensatz-parameter übergeben wird. Dabei wird in der Funktion die batchsize berücksichtigt, sodass stets die gewünschte Menge an Daten gleichzeitig in das Modell geladen werden. +Ein möglicher Ansatz ist, die rohen Daten nur schrittweise einzulesen und diese dann erst dem word2vec model zu übergeben, um daraus einen Vektor zu machen. Dafür wird eine Funktion geschrieben, welche dann der fit Methode des eigentlichen machine learning models als Datensatz-parameter übergeben wird. Dabei wird in der Funktion die batchsize berücksichtigt, sodass stets die gewünschte Menge an Daten gleichzeitig in das Modell geladen werden. %% Aufteilung der Daten -Um dies jedoch zu erfüllen müssen die Daten nach ihrem Nutzen in verschiedene Dateien aufgeteilt werden. Dementsprechend eine Trainings-, Validierungs- und Test-Datei. +Um dies jedoch zu erfüllen, müssen die Daten nach ihrem Nutzen in verschiedene Dateien aufgeteilt werden. Dementsprechend in eine Trainings-, Validierungs- und Test-Datei. \begin{lstlisting}[label={lst:Aufteilung}, caption=Datenaufteilung] val = open('val.json','w',encoding='utf8') test = open('test.json','w',encoding='utf8') @@ -43,12 +43,12 @@ val.close() test.close() train.close() \end{lstlisting} -Das Aufteilen wird durch ein einfaches Zählen und Sortieren gelöst. Dabei zählt eine Variable, hier \lstinline{i}{}, hoch und je nachdem welchen Wert diese Variable hat werden die Daten in die entsprechende Datei sortiert. Das Ziel ist eine 60-20-20 Aufteilung der Daten. Dafür werden bei den Werten \lstinline{0, 1}{} und \lstinline{2}{} die Daten in die Trainingsdatei geschrieben und dementsprechend bei den Werten \lstinline{3}{} und \lstinline{4}{} in die Validierungs-, bzw.\@ Testdatei. -Wenn in die Testdatei geschrieben wird, wird auch gleichzeitig die Zählervariable zurückgesetzt, sodass mit den gleichen Werten von vorne begonnen werden kann. Hier wurde sich bewusst für ein Zurücksetzen der Variable entschieden und gegen ein kontinuierliches Hochzählen und der Sortierung durch Modulo: Auf diese Weise werden bedenkenlos Overflow- und Signifikanzprobleme verhindert, ohne einen deutlichen Verlust der Lesbarkeit des Codes hinnehmen zu müssen. Da der genutzte Datensatz nur etwas über 8 Millionen Einträge besitzt und mit Ganzzahlen gearbeitet wird wären beide Probleme zu vernachlässigen gewesen. +Das Aufteilen wird durch ein einfaches Zählen und Sortieren gelöst. Dabei zählt eine Variable, hier \lstinline{i}{}, hoch und je nachdem welchen Wert diese Variable hat werden die Daten in die entsprechende Datei sortiert. Das Ziel ist eine 60-20-20 Aufteilung der Daten. Dafür werden bei den Werten \lstinline{0}{}, \lstinline{1}{} und \lstinline{2}{} die Daten in die Trainingsdatei geschrieben und dementsprechend bei den Werten \lstinline{3}{} und \lstinline{4}{} in die Validierungs- bzw.\@ Testdatei. +Wenn in die Testdatei geschrieben wird, wird auch gleichzeitig die Zählervariable zurückgesetzt, sodass mit den gleichen Werten von vorne begonnen werden kann. Hier wurde sich bewusst für ein Zurücksetzen der Variable entschieden und gegen ein kontinuierliches Hochzählen und der Sortierung durch Modulo. Auf diese Weise werden bedenkenlos Overflow- und Signifikanzprobleme verhindert, ohne einen deutlichen Verlust der Lesbarkeit des Codes hinnehmen zu müssen. Da der genutzte Datensatz nur etwas über 8 Millionen Einträge besitzt und mit Ganzzahlen gearbeitet wird, wären beide Probleme zu vernachlässigen gewesen. Um einen generell robusteren Code zu nutzen, wurde dieses Vorgehen trotzdem gewählt. Diese Art der Aufteilung ist jedoch nur bedenkenlos einzusetzen in diesem Projekt, da die Daten ohnehin unabhängig sind und ebenfalls unsortiert vorliegen. Aus diesen Gründen sind die drei Datensätze auch ohne extra shuffle zufällig genug. %%Start eigentlicher Generator -Um diese Dateien nun während des Trainings schrittweise auszulesen muss ein sogenannter Generator erstellt werden. Dieser liest die Daten zum Teil aus, überträgt sie in das Word2Vec Modell und stellt sie anschließend dem Modell zur Verfügung. +Um diese Dateien nun während des Trainings schrittweise auszulesen, muss ein sogenannter Generator erstellt werden. Dieser liest die Daten zum Teil aus, überträgt sie in das Word2Vec Modell und stellt sie anschließend dem Modell zur Verfügung. \begin{lstlisting}[caption=Overhead einfacher Generator] import numpy as np @@ -62,7 +62,7 @@ def generate_arrays_from_file(path, batchsize): for line in f: json_line = json.loads(line) \end{lstlisting} -Zunächst ein wenig overhead, bevor wir dann die entsprechende Datei zeilenweise durchgehen. Die Zeile 7 mit \lstinline{while True:}{} wird dabei vom Keras Modell erwartet, denn das Trainieren soll nicht mitten in einer Epoche enden, weil das Ende der Trainingsdatendatei erreicht wurde. +Die Zeile 7 mit \lstinline{while True:}{} wird dabei vom Keras Modell erwartet, denn das Trainieren soll nicht mitten in einer Epoche enden, weil das Ende der Trainingsdatendatei erreicht wurde. \begin{lstlisting}[caption=Sortierung einfacher Generator, firstnumber=10,label={list:Gen_Sort}] try: inputs.append(getSentenceVectorCNN(json_line["text"])) @@ -77,7 +77,7 @@ Zunächst ein wenig overhead, bevor wir dann die entsprechende Datei zeilenweise except: continue \end{lstlisting} -Anschließend wird aus dem eigentlichen Text der Review ein Wortvektor für das CNN gemacht. Das Vorgehen dafür wird in Kapitel \ref{subsubsec:CNN_Impl} im Listing \ref{list:getSentenceVector} beschrieben. Das Ergebnis ob diese Review als positiv, negativ oder neutral gelten soll wird in diesem Beispiel als Index Kategorie gespeichert. Sollte eine Exception geschmissen werden, weil z.\,B.\@ kein einziges Wort, welches in der Review vorkommt im Word2Vec Modell vertreten sein, wird diese Review einfach übersprungen. +Anschließend wird aus dem eigentlichen Text der Review ein Wortvektor für das CNN gemacht. Das Vorgehen dafür wird in Kapitel \ref{subsubsec:CNN_Impl} im Listing \ref{list:getSentenceVector} beschrieben. Das Ergebnis, ob diese Review als positiv, negativ oder neutral gelten soll, wird in diesem Beispiel als Index Kategorie gespeichert. Sollte eine Exception geschmissen werden, weil z.\,B.\@ kein einziges Wort, welches in der Review vorkommt, im Word2Vec Modell vertreten ist, wird diese Review einfach übersprungen. \begin{lstlisting}[caption=Yield der Daten,firstnumber=22] if batchcount > batchsize: X = np.array(inputs) @@ -87,16 +87,16 @@ Anschließend wird aus dem eigentlichen Text der Review ein Wortvektor für das targets = [] batchcount = 0 \end{lstlisting} -Abschließend werden die beiden Listen returned und die entsprechenden Variablen zurückgesetzt. Yield entspricht dabei in Python einem return, welches den dazugehörigen Code erst ausführt wenn die Daten gebraucht werden. Die Ansprüche an den Arbeitsspeicher werden auf diese Weise deutlich gesenkt. Es müssen für das Training also nur so viele Daten gleichzeitig im Arbeitsspeicher gehalten werden wie es die batchsize vorgibt. Wenn diese z.\,B.\@ 512 entspricht fallen dabei, an folgender Formel zu erkennen, lediglich 28 MB an Daten an. +Abschließend werden die beiden Listen returned und die entsprechenden Variablen zurückgesetzt. Yield entspricht dabei in Python einem return, welches den dazugehörigen Code erst ausführt, wenn die Daten gebraucht werden. Die Ansprüche an den Arbeitsspeicher werden auf diese Weise deutlich gesenkt. Es müssen für das Training also nur so viele Daten gleichzeitig im Arbeitsspeicher gehalten werden wie es die batchsize vorgibt. Wenn diese z.\,B.\@ 512 entspricht fallen dabei, an folgender Formel zu erkennen, lediglich 28 MB an Daten an. \begin{equation} 512 \times 72 \times 100 \times 8 \approx 28\text{ MB} \end{equation} -Ein deutlicher Nachteil bei diesem Vorgehen ist jedoch, dass dies sehr zeitaufwändig ist. Nicht nur müssen die Daten während des Trainings von der Festplatte anstelle des Arbeitsspeichers gelesen werden. Sondern diese Daten müssen zunächst auch noch in das Word2Vec Modell überführt werden. Beides sind verhältnismäßig langsame Prozesse, wodurch die Trainingszeit enorm steigt. Aber auch die Validierung benötigt nun in etwa genau so viel Zeit wie das Training an sich. -Dafür ist diese Methode recht simpel und sie benötigt keinen zusätzlichen Festplattenspeicher. Jedoch muss hierfür der Datensatz für Trainings-, Validierungs- und Testmenge in verschiedene Dateien aufgeteilt werden. Sollte also der Festplattenspeicher und nicht so sehr die Zeit ein begrenzender Faktor sein, ist dies ein durchaus valider Ansatz. +Ein deutlicher Nachteil bei diesem Vorgehen ist jedoch, dass dies sehr zeitaufwändig ist. Nicht nur müssen die Daten während des Trainings von der Festplatte anstelle des Arbeitsspeichers gelesen werden. Sondern diese Daten müssen zunächst auch noch in das Word2Vec Modell überführt werden. Beides sind verhältnismäßig langsame Prozesse, wodurch die Trainingszeit enorm steigt. Aber auch die Validierung benötigt nun in etwa genauso viel Zeit wie das Training an sich. +Dafür ist diese Methode recht simpel und benötigt keinen zusätzlichen Festplattenspeicher. Jedoch muss hierfür der Datensatz für Trainings-, Validierungs- und Testmenge in verschiedene Dateien aufgeteilt werden. Sollte also der Festplattenspeicher und nicht so sehr die Zeit ein begrenzender Faktor sein, ist dies ein durchaus valider Ansatz. \subsubsection{hdf5} %Bessere Zeiten, aber hoher Speicherplatz -Ein weiterer Ansatz ist die bereits in das Word2Vec Modell überführten Wörter, also die Vektoren an sich abzuspeichern. Dafür eignen sich z.\,B.\@ hdf5 Dateien, welche einen weiteren Vorteil besitzen auf den später eingegangen wird. Das Prinzip ist bei dieser Methode nahezu identisch zu der zuvor besprochenen, auch hier wird der Fit-Methode ein Generator gegeben, dieser liest jedoch nur die entsprechende Datei. Zunächst muss aber der Datensatz in das Word2Vec Modell überführt und entsprechend abgespeichert werden. Dies beginnt auch hier wieder mit ein wenig overhead: +Ein weiterer Ansatz ist die bereits in das Word2Vec Modell überführten Wörter, also die Vektoren an sich, abzuspeichern. Dafür eignen sich z.\,B.\@ hdf5 Dateien, welche einen weiteren Vorteil besitzen, auf den später eingegangen wird. Das Prinzip ist bei dieser Methode nahezu identisch zu der zuvor besprochenen, auch hier wird der Fit-Methode ein Generator gegeben. Dieser liest jedoch nur die entsprechende Datei und muss die Daten nicht noch vorher umwandeln. Zunächst muss aber der Datensatz in das Word2Vec Modell überführt und entsprechend abgespeichert werden. Dies beginnt auch hier wieder mit overhead: \begin{lstlisting}[caption=Overhead hdf5 Generator] import h5py @@ -115,7 +115,7 @@ with h5py.File(path + "w2vCNN.hdf5", "w") as hf: xTest = [] yTest = [] \end{lstlisting} -Zu Beginn initialisieren wir eine Zähler-Variable auf 0, welche wir später für unsere Aufteilung in Trainings-, Validierungs- und Testmenge nutzen. Für diese Mengen und ihre jeweiligen Input- und Outputdaten bereiten wir auch ein paar Listen vor. In hdf5 Dateien kann man die Daten in sogenannte Chunks aufteilen, welche das schrittweise speichern möglich macht, aber auch das laden verbessern soll. Die Größe dieser Chunks legen wir zunächst auf 10.000 fest. Da wir einen 60-20-20 split unseres Datensatzes haben wollen speichern wir uns ebenfalls die Größe dieser einzelnen Chunks. +Zu Beginn wird eine Zähler-Variable auf 0 initialisiert, welche später für die Aufteilung in Trainings-, Validierungs- und Testmenge genutzt wird. Für diese Mengen und ihre jeweiligen Input- und Outputdaten werden auch ein paar Listen vorbereitet. In hdf5 Dateien kann man die Daten in sogenannte Chunks aufteilen, welche das schrittweise speichern möglich macht, aber auch das Laden verbessern soll. Die Größe dieser Chunks wird zunächst auf 10.000 festgelegt. Da ein 60-20-20 split des Datensatzes gewünscht ist werden ebenfalls die Größe dieser einzelnen Chunks gespeichert. \begin{lstlisting}[caption=Sortierung hdf5 Generator, firstnumber=16] for index, line in enumerate(open(corpus_path,encoding="utf8")): json_line = json.loads(line) @@ -133,7 +133,7 @@ Zu Beginn initialisieren wir eine Zähler-Variable auf 0, welche wir später fü else: yData = 2 \end{lstlisting} -Anschließend wird quasi identisch zu dem Vorgehen im einfachen Generator aus Listing \ref{list:Gen_Sort} der rohe Datensatz ausgelesen und entsprechend in nutzbare x und y Daten umgewandelt. +Anschließend wird fast identisch zu dem Vorgehen im einfachen Generator aus Listing \ref{list:Gen_Sort} der rohe Datensatz ausgelesen und entsprechend in nutzbare x und y Daten umgewandelt. \begin{lstlisting}[caption=Zuordnung hdf5 Generator, firstnumber=31] if i < 3: xTrain.append(xData) @@ -167,8 +167,8 @@ Als nächstes werden die Daten den entsprechenden Listen angehangen. Das Vorgehe xTest = [] yTest = [] \end{lstlisting} -Wenn das erste Mal genug Daten in den buffer-listen liegen können diese noch nirgends appended werden, da in der entsprechenden Datei noch nichts vorliegt wo diese appended werden können. Damit kommen wir auch zu einem weiteren Vorteil der hdf5 Dateien: Wir können verschiedene Datasets, mit entsprechenden Labeln, in der gleichen Datei speichern und diese später auch einfach wieder auslesen. \\ -Diese Datasets müssen aber zunächst erstellt werden. Dafür geben wir zum einen das Label des Datasets an; die Dimensionen der maxshape, welche als Anzahl der Datensätze den Eintrag None bekommt, da wir einfach alle Daten die wir haben speichern wollen; die Dimensionen der chunks, wofür wir die eingangs berechneten Chunkgrößen nun nutzen; und zu guter Letzt natürlich die tatsächlichen Daten, welche stets die gleichen Dimensionen haben müssen wie die Chunks. Abschließend resetten wir die buffer-listen um keine Daten mehrfach zu speichern. +Wenn das erste Mal genug Daten in den buffer-listen liegen können, diese noch nirgends appended werden, da in der entsprechenden Datei noch nichts vorliegt wo diese appended werden können. Hier zeigt sich ein weiterer Vorteil der hdf5 Dateien: Es können verschiedene Datasets, mit entsprechenden Labeln, in der gleichen Datei gespeichert und diese später auch entsprechend wieder ausgelesen werden. \\ +Diese Datasets müssen aber zunächst erstellt werden. Dafür wird zum einen das Label des Datasets angegeben; die Dimensionen der maxshape, welche als Anzahl der Datensätze den Eintrag None bekommt, da alle vorhandenen Daten gespeichert werden sollen; die Dimensionen der chunks, wofür die eingangs berechneten Chunkgrößen nun genutzt werden; und zuletzt die tatsächlichen Daten, welche stets die gleichen Dimensionen haben müssen wie die Chunks. Abschließend werden die buffer-listen resetted, um keine Daten mehrfach zu speichern. \begin{lstlisting}[caption=Nachfüllen der hdf5 Datasets, firstnumber=59] if (index+1) % chunkSize == 0 and index > chunkSize: XTrain.resize(XTrain.shape[0]+trainChunk, axis=0) @@ -197,7 +197,37 @@ Diese Datasets müssen aber zunächst erstellt werden. Dafür geben wir zum eine xTest = [] yTest = [] \end{lstlisting} -Für das appenden der Daten im folgenden Verlauf müssen die Datasets stets um die entsprechende Größe resized werden. Anschließend werden die neuen Felder entsprechend aufgefüllt und zu guter Letzt wieder die buffer-listen resetted.\\ +Für das appenden der Daten im folgenden Verlauf müssen die Datasets stets um die entsprechende Größe resized werden. Anschließend werden die neuen Felder entsprechend aufgefüllt und zuletzt wieder die buffer-listen resetted.\\ +\begin{lstlisting}[caption=Behandeln der Traildaten, firstnumber=85] + trainChunk = len(xTrain) + if trainChunk != 0: + + XTrain.resize(XTrain.shape[0]+trainChunk, axis=0) + XTrain[-trainChunk:] = xTrain + + YTrain.resize(YTrain.shape[0]+trainChunk, axis=0) + YTrain[-trainChunk:] = yTrain + + valTestChunk = len(xVal) + if valTestChunk != 0: + + XVal.resize(XVal.shape[0]+valTestChunk, axis=0) + XVal[-valTestChunk:] = xVal + + YVal.resize(YVal.shape[0]+valTestChunk, axis=0) + YVal[-valTestChunk:] = yVal + + valTestChunk = len(xTest) + if valTestChunk != 0: + + XTest.resize(XTest.shape[0]+valTestChunk, axis=0) + XTest[-valTestChunk:] = xTest + + YTest.resize(YTest.shape[0]+valTestChunk, axis=0) + YTest[-valTestChunk:] = yTest +\end{lstlisting} +Die letzten Daten, welche nicht mehr eine vollständige Chunkgröße füllen müssen nach der Schleife gesondert behandelt werden. Die resize Parameter müssen dabei zu der shape der Restdaten passen und somit entsprechend angepasst werden. + Das Auslesen der Daten erfolgt letztlich ähnlich wie bei dem anderen vorgestellten Generator: \begin{lstlisting}[caption=hdf5 Generator] def hdf5Generator(filePath, batch_size, dataSet, loop=True): diff --git a/Dokumentation/Herausforderungen.tex b/Dokumentation/Herausforderungen.tex index 7014678..99813f3 100644 --- a/Dokumentation/Herausforderungen.tex +++ b/Dokumentation/Herausforderungen.tex @@ -15,33 +15,34 @@ \subsection{Herausforderungen \label{subsec:Herausforderungen}} -Wissend wie Word2Vec funktioniert lassen sich verschiedene Probleme bei diesem Datensatz feststellen. Dabei sind einige davon generisch und quasi in jedem Word2Vec- oder gar machine-learning-Projekt vertreten. Andere jedoch sind verhältnismäßig speziell für einen Datensatz wie diesen. +Durch das Wissen, wie Word2Vec funktioniert, lassen sich verschiedene Probleme bei diesem Datensatz feststellen. Dabei sind einige davon generisch und annähernd in jedem Word2Vec- oder machine-learning-Projekt vertreten. Andere jedoch sind verhältnismäßig speziell für einen Datensatz wie diesen. \subsubsection{Distribution \label{subsubsec:Dist}} -Eine generelle Voraussetzung für Algorithmen des maschinellen Lernens ist, dass mit einem ausgeglichenen Datensatz gearbeitet wird. Unausgeglichene Datensätze, wie der \noteable{Yelp} Datensatz, verleiten dazu, dass +Eine generelle Voraussetzung für Algorithmen des maschinellen Lernens ist, dass mit einem ausgeglichenen Datensatz gearbeitet wird. Unausgeglichene Datensätze wie der \noteable{Yelp} Datensatz verleiten dazu, dass neuronale Netze eben genau diesen Bias lernen. -Wenn der Datensatz jedoch die Realität relativ gut darstellt ist es gerade für Anfänger schwierig zu entscheiden wie damit umgegangen werden soll. Schließlich ist es prinzipiell eine hilfreiche Information wenn es bekannt ist, dass z.\,B. Bewertungen eine Verteilung wie in \ref{fig::DST} besitzen. -Der entwickelte Algorithmus soll die Kategorisierung aber nicht an fundiertem Raten ausmachen, sondern anhand von selbst erarbeiteten Kriterien und damit unabhängig der ursprünglichen Distribution. +Wenn der Datensatz jedoch die Realität relativ gut darstellt, ist es gerade für Anfänger schwierig zu entscheiden wie damit umgegangen werden soll. Schließlich ist es prinzipiell eine hilfreiche Information wenn es bekannt ist, dass z.\,B. Bewertungen eine Verteilung wie in Abbildung \ref{fig::DST} besitzen. +Der entwickelte Algorithmus soll die Kategorisierung aber nicht an fundiertem Raten ausmachen, sondern anhand von selbst erarbeiteten Kriterien und damit unabhängig von der ursprünglichen Distribution. -Generell gibt es zwei Ansätze, um diesen Effekt zu bekämpfen. Zum Einem gibt es die Möglichkeit, den \noteable{Near-Miss-Algorithm} zu benutzen. Mit Hilfe diesem werden im Grunde Einträge von zu oft vertretenen Klassen aus dem Datensatz entfernt, bis dieser ausgeglichen ist. Dadurch wird zwar verhindert, dass eine Klasse bei der Kategorisierung bevorzugt wird, aber man verringert auch den zu Grunde liegenden Datensatz. Je nach ursprünglicher Verteilung und gesamter Menge kann dies zu einem zu kleinen Datensatz und somit weiteren Problemen führen. -Zum Anderen gibt es die Möglichkeit, die Klassen beim Trainieren zu gewichten. \wip{Hier werden selten auftretende Klassen stärker gewertet, um so für das Programm den Anschein zu erwecken, als ob diese häufiger vorkommen. Dies kann dazu führen, dass ausgemachte Kriterien für bestimmte Klassen als aussagekräftiger gelten, als sie eigentlich sind, da sie vermeintlich bei vielen Trainingsdaten so vorkamen.} +Generell gibt es zwei Ansätze, um diesen Effekt zu bekämpfen. Zum Einem gibt es die Möglichkeit, den \noteable{Near-Miss-Algorithm} zu benutzen. Mit Hilfe von diesem werden im Grunde Einträge von zu oft vertretenen Klassen aus dem Datensatz entfernt, bis dieser ausgeglichen ist. Dadurch wird zwar verhindert, dass eine Klasse bei der Kategorisierung bevorzugt wird, aber man verringert auch den zu Grunde liegenden Datensatz. Je nach ursprünglicher Verteilung und gesamter Menge kann dies zu einem zu kleinen Datensatz und somit zu weiteren Problemen führen. +Zum Anderen gibt es die Möglichkeit, die Klassen beim Trainieren zu gewichten. Hier werden selten auftretende Klassen stärker gewertet, sodass das Programm diesen eine höhere Aufmerksamkeit schenkt. +%Dies kann aber auch dazu führen, dass ausgemachte Kriterien für bestimmte Klassen als aussagekräftiger gelten, als sie eigentlich sind, da sie vermeintlich bei vielen Trainingsdaten so vorkamen. Im Rahmen dieser Arbeit wurde der zweite Ansatz gewählt. \subsubsection{Zeichensatz} -Zuerst sollte der Datensatz in lowercase konvertiert werden, da bei den Wordvektoren sonst ein Unterschied zwischen z.B. \noteable{good} und \noteable{Good} besteht. Dabei könnte sogar zufallsbedingt, durch die Anwendung in leicht verschiedenen Kontexten und die generelle unterschiedliche Häufigkeit, die Interpretation dieser Wörter auseinandergehen. +Zuerst sollte der Datensatz in lowercase konvertiert werden, da bei den Wortvektoren sonst ein Unterschied zwischen z.\,B.\@ \noteable{good} und \noteable{Good} bestünde. Dabei könnte zufallsbedingt, durch die Anwendung in leicht verschiedenen Kontexten und die generelle unterschiedliche Häufigkeit, die Interpretation dieser Wörter auseinandergehen. -In eine ähnliche Richtung gehen auch die Satzzeichen. Hier werden zwar Informationen gespeichert, welche durchaus die Bedeutung eines Satzes verändern können, aber dieser Unterschied ist in der Regel zu komplex, um ihn in den meisten Verfahren sinnvoll zu berücksichtigen. Eine Sonderbehandlung wäre dabei ohnehin von Nöten. Weiterhin kann man davon ausgehen, dass sich in der Regel die Bedeutung nicht so gravierend ändert, als dass man diese Review in eine andere Kategorie einordnen würde. Dadurch ist die effizienteste Methode die Satzzeichen einfach zu entfernen. +In eine ähnliche Richtung gehen auch die Satzzeichen. Hier werden zwar Informationen gespeichert, welche durchaus die Bedeutung eines Satzes verändern können, aber dieser Unterschied ist in der Regel zu komplex, um ihn in den meisten Verfahren sinnvoll zu berücksichtigen. Eine Sonderbehandlung wäre dabei ohnehin von Nöten. Weiterhin kann man davon ausgehen, dass sich in der Regel die Bedeutung nicht so gravierend ändert, als dass man diese Review in eine andere Kategorie einordnen würde. Dadurch ist die effizienteste Methode, die Satzzeichen einfach zu entfernen. -Es gibt aber noch weitere Sonderzeichen, die Probleme bereiten. Darunter z.B. das Apostroph. Da die Reviews in der Regel englisch sind finden sich häufiger Wörter wie \noteable{didn't} oder \noteable{we've}. -Wir befinden uns jedoch im Internet und hier werden neben Satzzeichen auch Apostrophe gerne einmal weggelassen, schließlich weiß mit \noteable{didnt} jeder was gemeint ist. Aber auch hier werden diese Versionen als unterschiedliche Wörter interpretiert. -Die simpelste Methode ist auch hier einfach das Apostrophe zu entfernen. In diesem Falle werden aber zum Teil Wörter zusammengefasst, welche durchaus verschieden sind, wie z.\,B.\@ \noteable{its} und \noteable{it's}. Dasselbe gilt dann auch für andere Sprachen bei denen solche Vorkommnisse möglicherweise üblicher sind. Jedoch wird auch bei Wörtern wie \noteable{it's} gerne mal das Apostroph weggelassen, da häufig aus dem Kontext ersichtlich ist, welche Variante gemeint ist. Dadurch wird für den Algorithmus der Unterschied zwischen diesen Wörtern nicht klar und sie werden letztlich im Vektorraum recht nah aneinander liegen. Dies lässt sich auch aus der folgenden Ausgabe anhand des genutzten Modells ablesen. +Es gibt aber noch weitere Sonderzeichen, die Probleme bereiten. Darunter z.\,B.\@ das Apostroph. Da die Reviews in der Regel englisch sind finden sich häufiger Wörter wie \noteable{didn't} oder \noteable{we've}. +Der Datensatz besteht jedoch aus Reviews aus dem Internet. Hier werden neben Satzzeichen auch Apostrophe oft weggelassen, da Sätze und Wörter wie \noteable{didnt} auch ohne diese Zusätze verständlich sind. Aber auch hier werden diese Versionen als unterschiedliche Wörter interpretiert. +Die simpelste Methode ist auch hier einfach das Apostroph zu entfernen. In diesem Fall werden aber zum Teil Wörter zusammengefasst, welche durchaus verschieden sind, wie z.\,B.\@ \noteable{its} und \noteable{it's}. Dasselbe gilt dann auch für andere Sprachen bei denen solche Vorkommnisse möglicherweise üblicher sind. Jedoch wird auch bei Wörtern wie \noteable{it's} oft das Apostroph weggelassen, da häufig aus dem Kontext ersichtlich ist, welche Variante gemeint ist. Dadurch wird für den Algorithmus der Unterschied zwischen diesen Wörtern nicht klar und sie werden letztlich im Vektorraum recht nah aneinander liegen. Dies lässt sich auch aus der folgenden Ausgabe anhand des genutzten Modells ablesen. \begin{verbatim} In: model0.similarity("it's", "its") Out: 0.8579778 \end{verbatim} \subsubsection{Sprachen} -Wie zuvor erwähnt besteht der Datensatz nicht nur aus englischen Reviews, sondern aus verschiedenen Sprachen. Oberflächlich gesehen stellt dies in der Theorie erstmal kein Problem dar, abgesehen von den unterschiedlichen Mengen an data-samples in den jeweiligen Sprachen. Wie durch den vorherigen Abschnitt jedoch zu erahnen ist benötigen verschiedene Sprachen verschiedene Nuancen an Vorverarbeitung. Von Sonderzeichen, die je nach Sprache ggf.\@ anders behandelt werden müssen bis hin zum fehlen ebendieser. In dem Datensatz sind z.B. auch japanische Reviews enthalten, eine Sprache ohne Leerzeichen, was das Isolieren einzelner Wörter erheblich erschwert. Um bei dem Beispiel Japanisch zu bleiben: Hier kommt noch hinzu, dass dies eine sehr kontextuelle Sprache ist. Das bedeutet, dass Wörter die für das Verständnis des Satzes wichtig wären aus dem Kontext als gegeben und gewusst angesehen werden, etwas was ein Code in der Regel nicht leisten kann.\\ -Es stellt sich also die Frage ob der Datensatz von anderen Sprachen bereinigt werden sollte. Ein möglicher Ansatz dafür wäre z.B. nur Reviews zu behalten, welche ausschließlich Zeichen in einer bestimmten (kleinen) utf-8 Reichweite enthalten. Während das Entfernen bei einigen asiatischen Sprachen noch verhältnismäßig einfach erscheint, wird dies bei z.B. europäischen Sprachen wie Französisch oder Spanisch ohne großen Mehraufwand nahezu unmöglich. \\ -Aufgrund dessen verzichten wir darauf solche Sprachen zu entfernen. Aber auch asiatische Sprachen werden wir nicht extra entfernen. Wir können zwar überwiegend keine nützlichen Daten aus diesen Reviews gewinnen, jedoch wird der nützliche Part unseres Datensatzes auch nicht dadurch beeinflusst, da die asiatischen Sprachen mit ziemlicher Sicherheit einen eigenen, eher abgeschiedenen, Wortcluster bilden werden. Weiterhin treten diese Reviews selten genug auf, dass man davon ausgehen kann, dass das Entfernen dieser Datenpunkte keinen merklichen Einfluss auf die Trainingszeiten haben wird. Daher ist es sinnvoller die Zeit, welche in die saubere Entfernung dieser Reviews investiert werden würde, hier einzusparen. \ No newline at end of file +Wie zuvor erwähnt besteht der Datensatz nicht nur aus englischen Reviews, sondern aus verschiedenen Sprachen. Oberflächlich gesehen stellt dies in der Theorie erstmal kein Problem dar, abgesehen von den unterschiedlichen Mengen an data-samples in den jeweiligen Sprachen. Wie durch den vorherigen Abschnitt jedoch zu erahnen ist, benötigen verschiedene Sprachen verschiedene Nuancen an Vorverarbeitung. Von Sonderzeichen, die je nach Sprache ggf.\@ anders behandelt werden müssen, bis hin zum Fehlen ebendieser. In dem Datensatz sind z.\,B.\@ auch japanische Reviews enthalten, eine Sprache ohne Leerzeichen, was das Isolieren einzelner Wörter erheblich erschwert. Um bei dem Beispiel Japanisch zu bleiben: Hier kommt noch hinzu, dass dies eine sehr kontextuelle Sprache ist. Das bedeutet, dass Wörter, die für das Verständnis des Satzes wichtig wären, aus dem Kontext als gegeben und gewusst angesehen werden. Dies ist etwas, was ein Code in der Regel nicht leisten kann.\\ +Es stellt sich also die Frage, ob der Datensatz von anderen Sprachen bereinigt werden sollte. Ein möglicher Ansatz dafür wäre z.\,B.\@ nur Reviews zu behalten, welche ausschließlich Zeichen in einer bestimmten (kleinen) utf-8 Reichweite enthalten. Während das Entfernen bei einigen asiatischen Sprachen noch verhältnismäßig einfach erscheint, wird dies bei z.\,B.\@ europäischen Sprachen wie Französisch oder Spanisch ohne großen Mehraufwand nahezu unmöglich. \\ +Aufgrund dessen wird darauf verzichtet solche Sprachen zu entfernen. Aber auch asiatische Sprachen werden wir nicht extra entfernen. Es können zwar überwiegend keine nützlichen Daten aus diesen Reviews gewonnen werden, jedoch wird der nützliche Part des Datensatzes auch nicht dadurch beeinflusst, da die asiatischen Sprachen mit ziemlicher Sicherheit einen eigenen, eher abgeschiedenen Wortcluster bilden werden. Weiterhin treten diese Reviews selten genug auf, dass man davon ausgehen kann, dass das Entfernen dieser Datenpunkte keinen merklichen Einfluss auf die Trainingszeiten haben wird. Daher ist es sinnvoller die Zeit, welche in die saubere Entfernung dieser Reviews investiert werden würde, hier einzusparen. \ No newline at end of file diff --git a/Dokumentation/w2v.tex b/Dokumentation/w2v.tex index 682838d..f182c15 100644 --- a/Dokumentation/w2v.tex +++ b/Dokumentation/w2v.tex @@ -27,7 +27,7 @@ tabsize=2, %literate={\_}{}{0\discretionary{\_}{}{\_}}, language=Python} -\renewcaptionname{ngerman}\figurename{Bild} +%\renewcaptionname{ngerman}\figurename{Bild} \usepackage{geometry} \geometry{left=3.5cm, right=2cm, top=2.5cm, bottom=2cm} diff --git a/Dokumentation/w2vFromScratch.tex b/Dokumentation/w2vFromScratch.tex index a7b2d79..028449a 100644 --- a/Dokumentation/w2vFromScratch.tex +++ b/Dokumentation/w2vFromScratch.tex @@ -13,7 +13,7 @@ corpus = ['king is a strong man', 'prince is a boy will be king', 'princess is a girl will be queen'] \end{lstlisting} -Unser Datensatz ist dabei recht überschaubar und auch in einer einfachen Struktur gehalten. Auf diese Weise lassen sich die Interaktionen und Einflüsse der Wort-Vektoren übersichtlicher darstellen. +Der hier genutzte Datensatz ist dabei recht überschaubar und auch in einer einfachen Struktur gehalten. Auf diese Weise lassen sich die Interaktionen und Einflüsse der Wort-Vektoren übersichtlicher darstellen. \begin{lstlisting}[caption=Entfernen der Stoppwörter, firstnumber=10] def remove_stop_words(corpus): stop_words = ['is', 'a', 'will', 'be'] @@ -29,7 +29,7 @@ def remove_stop_words(corpus): corpus = remove_stop_words(corpus) \end{lstlisting} -Zunächst entfernen wir die in Kapitel \ref{subsec:vorverarbeitung} bereits erklärten stop words. Dadurch, dass wir hier ein kurzes, akademisches Beispiel haben ist auch die Liste der stop words eher kurz. In der Regel sind Wörter wie die auch hier genutzten in diesen Listen zu finden, aber je nach Anwendungsfall kann es auch Sinn ergeben diese mit ungewöhnlicheren Wörtern zu füllen. +Zunächst werden die, in Kapitel \ref{subsec:vorverarbeitung} bereits erklärten stop words, entfernt. Dadurch, dass hier ein kurzes, akademisches Beispiel vorliegt, ist auch die Liste der stop words eher kurz. In der Regel sind Wörter, wie die auch hier genutzten, ebenfalls in diesen Listen zu finden, aber je nach Anwendungsfall kann es auch Sinn ergeben diese mit ungewöhnlicheren Wörtern zu füllen. \begin{lstlisting}[caption=Nachbarwörter speichern, firstnumber=23] from ordered_set import OrderedSet @@ -60,9 +60,9 @@ import pandas as pd df = pd.DataFrame(data, columns = ['input', 'neighbour']) \end{lstlisting} -Als nächstes erstellen wir ein \lstinline{OrderedSet}{}, welches alle Wörter nur ein einziges Mal enthält und nummerieren dieses durch. Dies wird im späteren Verlauf noch benötigt, wobei die Reihenfolge wichtig für die korrekte Visualisierung ist. Anschließend erstellen wir ein Datenset, welches alle Wörter mit ihren jeweiligen Nachbarn enthält. Dabei entspricht die \lstinline{WINDOW_SIZE}{} in Zeile 17 wie viele Nachbarwörter betrachtet werden sollen. Schließlich haben in langen Sätzen Wörter, welche zum Ende eines Nebensatzes stehen, häufig eine eher schwache oder gar keine Bindung zu den ersten Wörtern des Hauptsatzes. Die ideale Größe der \lstinline{WINDOW_SIZE}{} hängt dabei individuell vom Text ab. Jedoch ist in der Regel eine eher kleine \lstinline{WINDOW_SIZE}{} zu empfehlen, +-2 bis 3 Wörter sind in vielen Fällen genug. +Als nächstes wird ein \lstinline{OrderedSet}{} erstellt, welches alle Wörter nur ein einziges Mal enthält und entsprechend durchnummeriert. Dies wird im späteren Verlauf noch benötigt, wobei die Reihenfolge wichtig für die korrekte Visualisierung ist. Anschließend wird ein Datenset erstellt, welches alle Wörter mit ihren jeweiligen Nachbarn enthält. Dabei entspricht die \lstinline{WINDOW_SIZE}{} in Zeile 17 wie viele Nachbarwörter betrachtet werden sollen. Schließlich haben in langen Sätzen Wörter, welche zum Ende eines Nebensatzes stehen, häufig eine eher schwache oder gar keine Bindung zu den ersten Wörtern des Hauptsatzes. Die ideale Größe der \lstinline{WINDOW_SIZE}{} hängt dabei individuell vom Text ab. Jedoch ist in der Regel eine eher kleine \lstinline{WINDOW_SIZE}{} zu empfehlen, +-2 bis 3 Wörter sind in vielen Fällen genug. % Die +- 2 bis 3 hab ich mir ausgedacht und kann sie dementsprechend nicht belegen% -Abschließend wird das Datenset in ein pandas Dataframe überführt, wodurch das Arbeiten mit diesem erleichtert wird. Weiterhin sind noch 2 Aspekte des Datensets auffällig. Zum einen werden die Wörter mit ihren Nachbarn zwangsweise bidirektional abgespeichert. Die Erklärung dafür ist simpel: Die Beziehung zwischen den Wörtern ist schließlich auch bidirektional und so wird sichergestellt, dass im späteren Verlauf des Codes diese Bidirektionalität auch eingehalten wird, ohne dass darauf explizit geachtet werden muss. Zum anderen werden mehrfach auftretende Kombinationen auch mehrfach abgespeichert und nicht im Nachhinein wieder auf ein unique-dataset bereinigt. Das kommt daher, dass diese Häufigkeit essenzielle Daten enthält. Man geht letztlich davon aus, dass Wörter, die häufig zusammen vorkommen eine stärkere Bindung haben und auch außerhalb des benutzten Datensets verstärkt gemeinsam auftreten. +Abschließend wird das Datenset in ein pandas Dataframe überführt, wodurch das Arbeiten mit diesem erleichtert wird. Weiterhin sind noch 2 Aspekte des Datensets auffällig. Zum einen werden die Wörter mit ihren Nachbarn zwangsweise bidirektional abgespeichert. Die Erklärung dafür ist simpel: Die Beziehung zwischen den Wörtern ist auch bidirektional und so wird sichergestellt, dass im späteren Verlauf des Codes diese Bidirektionalität auch eingehalten wird, ohne dass darauf explizit geachtet werden muss. Zum anderen werden mehrfach auftretende Kombinationen auch mehrfach abgespeichert und nicht im Nachhinein wieder auf ein unique-dataset bereinigt. Das kommt daher, dass diese Häufigkeit essenzielle Daten enthält. Man geht letztlich davon aus, dass Wörter, die häufig zusammen vorkommen, eine stärkere Bindung haben und auch außerhalb des benutzten Datensets verstärkt gemeinsam auftreten. \begin{lstlisting}[caption=Beispielmodell,firstnumber=51] import tensorflow as tf import numpy as np @@ -98,7 +98,7 @@ model.compile(optimizer='adam',loss='categorical_crossentropy',metrics=["accurac model.fit(X_train,Y_train,epochs=1000,verbose=True) \end{lstlisting} -Bevor mit den Daten trainiert werden kann müssen die Wörter in eine dafür nutzbare Form übertragen werden. Dies geschieht in diesem Beispiel durch ein One-Hot-Encoding. Dabei wird das zuvor erstellte Dataset der durchnummerierten, einzigartigen Wörter zu Hilfe genommen. Entsprechend der ursprünglichen Zielsetzung entsprechen die Ausgangswörter den Eingangsdaten und die Nachbarwörter den Zieldaten. Zum Schluss werden diese Daten für das Training in numpy arrays übertragen und einem einfachen Modell fürs Training übergeben. +Bevor mit den Daten trainiert werden kann müssen die Wörter in eine dafür nutzbare Form übertragen werden. Dies geschieht in diesem Beispiel durch ein One-Hot-Encoding. Dabei wird das zuvor erstellte Dataset der durchnummerierten, einzigartigen Wörter zu Hilfe genommen. Gemäß der ursprünglichen Zielsetzung entsprechen die Ausgangswörter den Eingangsdaten und die Nachbarwörter den Zieldaten. Zum Schluss werden diese Daten für das Training in numpy arrays übertragen und einem einfachen Modell fürs Training übergeben. \begin{lstlisting}[caption=Plotten, firstnumber=84] vectors = np.array(model.weights[0]) w2v_df = pd.DataFrame(vectors, columns = ['x1', 'x2']) @@ -123,13 +123,13 @@ plt.rcParams["figure.figsize"] = (10,10) plt.show() \end{lstlisting} -Die eigentliche Arbeit ist damit bereits getan. Da dieses Beispiel jedoch zur Veranschaulichung gedacht ist fehlt noch die Visualisierung. Dafür werden die Gewichte der jeweiligen Vektoren zunächst zusammen mit den entsprechenden Wörtern in ein Dataframe gespeichert. Anschließend wird der Plot vorbereitet und die Wörter werden anhand ihrer zweidimensionalen Vektoren auf einem Koordinatensystem verteilt. Das hier verwendete Beispiel ist insgesamt sehr akademisch gestaltet. Dadurch, dass zwei Dimensionen für Wortvektoren ziemlich gering ist, das Modell nicht ausführlich optimiert und auch die Ausgangsdaten relativ spärlich sind, können die Ergebnisse stark voneinander variieren. Eine sinnvolle Verteilung ist jedoch in Abbildung \ref{fig:scratch} zu sehen. +Die eigentliche Arbeit ist damit bereits getan. Da dieses Beispiel jedoch zur Veranschaulichung gedacht ist fehlt noch die Visualisierung. Dafür werden die Gewichte der jeweiligen Vektoren zunächst zusammen mit den entsprechenden Wörtern in ein Dataframe gespeichert. Anschließend wird der Plot vorbereitet und die Wörter werden anhand ihrer zweidimensionalen Vektoren auf einem Koordinatensystem verteilt. Das hier verwendete Beispiel ist insgesamt sehr akademisch gestaltet. Dadurch, dass zwei Dimensionen für Wortvektoren ziemlich gering sind, das Modell nicht ausführlich optimiert und auch die Ausgangsdaten relativ spärlich sind, können die Ergebnisse stark voneinander variieren. Eine sinnvolle Verteilung ist jedoch in Abbildung \ref{fig:scratch} zu sehen. \begin{figure} \includegraphics[width=\linewidth]{bilder/scratch.png} \caption{Wort-Vektoren Verteilung} \label{fig:scratch} \end{figure} -Hier ist zu erkennen, dass die Begriffe, welche eher weiblich sind im oberen Bereich und dementsprechend die männlichen im unteren Bereich sind. Weiterhin sind die allgemeinen Begriffe \lstinline{man}{} und \lstinline{woman}{} eher rechts zu finden, während spezifische Wörter wie \lstinline{king}{} oder \lstinline{queen}{} sich eher links befinden. In dieser Darstellung funktioniert auch das berühmte Beispiel von: +Hier ist zu erkennen, dass die Begriffe, welche eher weiblich sind, im oberen Bereich und dementsprechend die männlichen im unteren Bereich sind. Weiterhin sind die allgemeinen Begriffe \lstinline{man}{} und \lstinline{woman}{} eher rechts zu finden, während spezifische Wörter wie \lstinline{king}{} oder \lstinline{queen}{} sich eher links befinden. In dieser Darstellung funktioniert auch das berühmte Beispiel von: \begin{equation} \vec{king} - \vec{man} + \vec{woman} \approx \vec{queen} \label{eqn:kingqueen} -- GitLab