Transcript: PP07 - Machine Learning am Beispiel Textklassifikation
Full episode transcript. Timestamps refer to the audio playback.
Ja, dann hallo, liebe Hörerinnen und Hörer, schön, dass ihr wieder da seid, dass ihr wieder zugeschaltet habt beim Python-Podcast in der siebten Episode heute.
Heute geht es um Machine Learning und ja, wir haben heute wieder einen Gast dabei im Wintergarten.
Hallo Nico.
Hi, schön, bei euch zu sein.
Ja, und Jochen ist natürlich auch wieder da.
Ja, Jochen ist auch da, genau.
Genau, ich bin der Dominik.
Wir sollten uns, glaube ich, nochmal kurz vorstellen für den Nico, weil wir wahrscheinlich diese Folge irgendwie auch bei Nico veröffentlichen dürfen.
auf Nicos tollen Podcast
InnoCast heißt der noch?
InnoTechCast, genau.
Der InnoTechCast
ist mein Podcast-Projekt, läuft auch so seit
ein bisschen über einem Jahr jetzt
und da geht es halt nicht nur konkret um Python,
sondern um alle möglichen
Sachen, die irgendwie
Nerds und ITler interessieren könnten,
irgendwie von Containern über
irgendwie so DevOps-Geschichten,
einzelne Programmiersprachen.
Was haben wir so gemacht? Wir haben Go gemacht,
wir haben Rust behandelt,
Wir hatten auch schon mal eine Folge so ein bisschen zu peisen.
Also es ist auf jeden Fall sehr spannend, hört da mal rein.
Kann ich empfehlen, klingt gut.
Genau.
Ja, dann fangen wir doch mal mit dem richtigen Thema an jetzt
und gehen das Beispiel durch, was wir für das Machine Learning machen wollen.
Ja, wahrscheinlich sollten wir erstmal so ein bisschen...
Erstmal nochmal so allgemein vielleicht, was ist denn das überhaupt, das Machine Learning?
Was macht das denn?
Ja, das denke ich auch.
Wie viel Statistik ist das eigentlich oder ist das Statistik oder was ist das
oder macht da irgendwelche magischen
Dinge, der Computer einfach magische
Sachen und dann kommt irgendwie wusch
künstliche Intelligenz daraus.
Ja, das ist ja das Gefühl, was man heute in den Medien, finde ich,
irgendwie immer bekommt. Also es ist halt so ein
Buzzword, was überall rumschwirbt, genauso wie
irgendwie künstliche Intelligenz.
Genau, aber im Wesentlichen geht
es ja darum, im Endeffekt gewisse
Strukturen in den Daten zu finden,
um eben Prognosen
über die Zukunft zu lernen.
Das heißt einfach, ich programmiere nicht mehr alles
komplett deterministisch runter, was
ich irgendwie wie von einem gewissen
Eingabewert zu einem gewissen Ausgabewert komme,
sondern ich habe halt eine gewisse
große Menge an Trainingsdaten
und habe dann Algorithmen,
die gewisse Parameter
anpassen bei solchen sogenannten
Trainingsläufen und daraus
quasi generelle Strukturen aus den Daten erkennen,
um dann damit letztendlich
Schlussfolgerungen für die Zukunft
oder für unbekannte Daten
zu ermöglichen. So hätte ich das
zusammengefasst. Ja, würde ich
prinzipiell genauso. Der Computer lernt so,
was er mit neuen Sachen dann anfangen
muss, aus alten Dingen.
Genau, es gibt einmal, es gibt keine
allgemeingültige Definition, was jetzt Machine Learning
ist, aber also
eine von Tom Mitchell wäre halt
so ganz allgemein gehalten, ja,
Machine Learning führt
halt dazu, dass Computer oder dass Programme
aus Erfahrung lernen irgendwie,
mit Erfahrung besser werden.
Genau,
wenn man das jetzt mit traditionellem
Programmieren vergleichen würde, dann ist es halt so,
Dass man eben selbst, wenn man damit programmiert, sozusagen diese Zuordnung von, man bekommt irgendwelche Eingaben und dann soll halt irgendwie irgendwas rauskommen am Schluss, machen muss. Und wenn man jetzt Machine Learning verwendet, dann macht diesen Schritt halt wie ein mathematisches Optimierungsverfahren. Und das sich orientiert an Trainingsbeispielen, an Beispielen für, das ist reingegangen und das ist rausgekommen und so sollte das halt sein.
Aber genau das ist ja auch das, was dann der Mensch dann doch wieder macht. Das heißt, der Mensch macht ja diese Vorarbeit, indem er die Trainingsdaten mit den richtigen Zuordnungen, mit den richtigen Labels bereitstellt.
Genau, richtig. Aber es ist halt schon ein Unterschied, ob man jetzt quasi einem Computer nur zeigen muss, was er tun soll oder ob man ihm tatsächlich explizit Schritt für Schritt sagen muss, was passieren soll. Das eine ist halt deutlich einfacher als das andere. Und damit kommen halt natürlich viel mehr Probleme in den Bereich der Lösbarkeit, als man halt vorher hatte.
Und es gibt auch diverse Probleme, die man sonst gar nicht in den Griff kriegt. Also wo man tatsächlich versucht hat, einen Algorithmus zu schreiben, der das tut, wie zum Beispiel eben sowas wie bei Bildern Katzen von Hunde unterscheiden oder so. Aber das geht halt gar nicht, weil man das halt nicht wirklich in einen Algorithmus reinbekommt.
Man kann nicht so ein Gegenstand definieren. Eine Katze ist irgendwie so ein kleines Tier und grau und weiß und so weiter. Das ist schwer zu unterscheiden.
Ja, oder auch das Arbeiten mit Sprache finde ich ein gutes Beispiel, da hat man halt viele, viele Algorithmen entwickelt, die auch zu einem gewissen Grad funktionieren, aber man ist mit Übersetzungen halt einfach quasi dann auf so einem Plateau spähen geblieben und kam da nicht mehr weiter und dank Deep Learning Verfahren, also tiefen neuronalen Netzen ist es halt eben dann möglich geworden, dann nochmal ganz neue Lernraten zu erreichen.
Ja, das ist genau, das ist halt auch Stichwort Deep Learning eigentlich das Ding, was in den letzten paar Jahren halt diesen Hype irgendwie befeuert hat und da ist durchaus irgendwie ordentlich was dran, also es gehen inzwischen viele Sachen, die früher überhaupt gar nicht gingen und ja, aber natürlich ist es immer schwer für Leute, die das jetzt nicht so ordentlich verfolgen können und wer tut das halt, außer die irgendwie tatsächlich damit arbeiten, zu unterscheiden, was denn jetzt irgendwie geht und was nicht geht und was eigentlich das Coole daran ist,
Und in den Medien hat man dann doch oft das Gefühl, dass man davon ausgeht, dass das irgendwas Magisches ist, dann geht halt alles und das ist ja jetzt auch nicht so.
Das ist genau der spannende Punkt. Du hast nämlich gerade versucht zu erklären, dass das, was da passiert, irgendwelche mathematischen Algorithmen sind und die halt zu verstehen als Mensch oder daran zu schrauben zu können, die Parameter, die man halt irgendwie bei Maschinenlöhnen noch einstellt und das halt dann so durchblicken.
Also was das zu tun hat jetzt mit Statistik oder so, das ist vielleicht nochmal ganz spannend, weil dann würde man vielleicht auch nicht nur glauben, dass Magie, also ne, vielleicht sowas mit zu tun, wenn irgendjemand neue Sachen erfindet, irgendeine Geometrie entdeckt, dann ist das vielleicht auch ganz magisch für jemand, der sowas noch nie gesehen hat und deswegen ist halt diese künstliche Intelligenz gar nicht so künstlich, wie wir dachten, aber dann trotzdem so ein Phänomen, was gerade ja bei den Leuten, die sich damit nicht auskennen, so ankommt.
Ja, also wenn man das guckt, wenn man sich einfach nur die Ergebnisse anschaut, dann wirkt das so ein bisschen magisch.
Genau, also warum kann der Computer jetzt einen Hund von einer Katze unterscheiden? Wie soll das denn gehen?
Wie, der Computer weiß, was ich da gerade gesagt habe und kann mit mir sprechen. Das ist schon phänomenal irgendwo.
Aber ist das nicht eigentlich immer so? Also wenn man halt quasi irgendein Blackbox-Modell hat und da nicht reinschauen kann, dann wirkt das wie Magie.
und wenn man halt nach und nach die
Informationen da drin versteht,
dann, ja, blickt man halt, okay, das
hat gewisse Schlussfolgerungen. Ich meine, es hat schon
Verstehen wir die wirklich bei Machine Learning? Das habe ich jetzt nämlich auch noch nicht
so ganz verstanden. Nee, genau,
da gibt es natürlich einen Unterschied zwischen
so eben Blackbox, Whitebox-Verfahren,
bei denen man, also bei denen
sozusagen, ja,
Whitebox-Verfahren, sowas wie Decision Trees
kann man prinzipiell verstehen, wie die funktionieren, weil man
einfach sicher den Entscheidungsbaum
aufmalen kann, dann kann man den halt von Hand durchgehen.
Bei eben
Blackbox-Verfahren wie so neuronalen Netzen
oder so, kann man das prinzipiell eigentlich
nicht wirklich. Also man kann zwar sehen,
welche, was das Ding gemacht hat
und
auch irgendwie, was es erkannt hat und
woran es sich orientiert, aber so letztlich
genau verstehen, warum es jetzt zu einem bestimmten
Ergebnis gekommen ist, kann man eigentlich
nicht mehr. Und ich fürchte auch, einer der
größten, wichtigsten Punkte,
weshalb das so prinzipiell eine schwierige Geschichte
ist, ist, dass die Modelle, je komplexer
sie werden und desto mehr Parameter sie
haben, werden sie halt auch sehr groß.
Also wenn ich dann mehrere,
ja, Millionen reicht ja schon, aber wenn ich
mehrere hundert Millionen Parameter habe,
dann ist das eine Menge, die ich
als Mensch ja überhaupt nicht mehr überlegen kann.
Das ist halt...
Ja, wobei es inzwischen da ja schon viel
Forschung gibt, gerade auch um
neuronale Netze
eben verständlich zu machen.
Zum Beispiel ja irgendwie
Lime ist ja da so ein Paket, was da in der Zeit
total gehypt wurde, in dem es halt
eben möglich ist, quasi an gewissen
Zumindest für gewisse Objekte zu verstehen, wie das Modell quasi zu diesem Schluss kam.
Also so blackboxig sind diese neuronalen Netze jetzt gar nicht mal mehr.
Auch da gibt es Möglichkeiten, die zu verstehen.
Aber ja, also klar, das ist natürlich deutlich komplexer als jetzt ein Entscheidungsbaum,
den ja wahrscheinlich jeder mehr oder weniger kennt, was nicht viel anders ist als ein Flussdiagramm.
Aber vielleicht wollen wir kurz noch mal ein, zwei Schritte zurückgehen und so ein bisschen die Hörer da abholen.
Wir wollten ja so ein bisschen das Beispiel erzählen und vielleicht kommen wir dann,
welche Methoden man denn verwenden kann für bestimmte
Datensätze. Darum, ob wir jetzt so ein
neuronales Netz oder so ein Decision Tree
verwenden möchten.
Würde das Sinn machen? Was sagt ihr?
Ja, also ich finde, man muss
erstmal festhalten, dass es halt irgendwie
nicht so ist, dass jetzt plötzlich
für alles man Deep Learning benutzen sollte,
nur weil es jetzt gerade gehypt ist, sondern
es gibt ganz, ganz viele Verfahren,
die schon lange existieren, die bewährt
sind und die für einige Tasks
halt auch sehr gut funktionieren. Also wenn ich
jetzt zum Beispiel einfach eine
Zeitreihe vorhersagen möchte
mit
relativ einfachen Mitteln, um vielleicht den Abverkauf
von einem Produkt vorherzusehen oder
die Temperatur oder sowas, dann
gibt es da jetzt erstmal Regressionsverfahren,
die so schon sehr gut funktionieren
und da muss man jetzt nicht zwangsläufig
irgendwie Deep Learning draufwerfen.
Ist halt eben was anderes wie bei der
Bilderkennung, die du jetzt zum Beispiel erwähnt hast.
Regression ist natürlich immer nur so gut, wie
die Zukunft
der Vergangenheit entspricht. Das ist ja vielleicht
Ja, klar, genau.
Aber das Problem haben Deep Learning Algorithmen
an der Stelle genauso.
Ja?
Okay. Also natürlich hast du
da nicht unbedingt dann immer so einen linearen
Zusammenhang, aber
ja, im Grunde natürlich
so Dinge, die komplett neu sind.
Ja, wenn es einmal
Alph oder sowas ist, ein Hund oder eine Katze, weiß man nicht so genau.
Ja, dann kommt was
Neues auf die Welt.
Genau, also es gibt auch
Verfahren, die total einfach zu verstehen
sind. Also sowas wie NaiveBase
zum Beispiel. Das ist eine der ersten
Geschichten, die
also ich glaube 2004 hatte Paul Graham
halt da irgendwie den Artikel
veröffentlicht, The Plan for Spam.
Jetzt musst du nochmal einmal kurz sagen, was
NaiveBase überhaupt ist, für alle, die das noch nie gehört haben.
Das ist auch ein Klassifikationsverfahren und zwar
also ich, genau, ich wollte, also wenn man
jetzt ein bisschen erklären möchte, wie funktioniert das oder wie
funktioniert Machine Learning, dann ist der
allereinfachste Fall, den man beschreiben kann,
halt binäre Klassifikationen, vielleicht.
So, womit man anfangen kann.
Und
ja, NaiveBase
ist halt ein... Also binäre
Klassifikation. Also drin oder nicht drin.
Genau, man unterscheidet eigentlich nur zwei Klassen.
Genau. Und
Merkst du ganz kurz, genau, wenn man
das mal zusammenfassen darf, man hat halt
vom Prinzip her Supervised Machine Learning
und Unsupervised Machine Learning, solche, wo
ich irgendwie Daten habe, wo ich quasi
Labels habe, wo ich sagen kann,
okay, das soll quasi nachher rauskommen,
das ist Supervised Machine Learning. Und es
gibt solche, wo ich diese Information nicht habe,
Das ist das Feld der Unsupervised-Machine-Learning-Sachen.
Und im Feld von Supervised-Machine-Learning
gibt es dann im Wesentlichen unterschiedliche Tasks.
Es gibt eine Regression oder es gibt eine Klassifikation
als die beiden typischsten Fälle.
Und genau, der einfachste Fall wäre dann halt eben
eine binäre Klassifikation, wo ich einfach nur sage,
in folgendem Fall, Daumen hoch, Daumen runter, ja oder nein.
Genau.
Ich suche mal gerade, ob ich das hier...
Ja, schau mal.
finde, Moment.
Wir wollten noch mal kurz erklären, was Space
macht mit einer binären Klassifikation.
Bevor
wir dann vielleicht tatsächlich darauf eingehen, was für eine Möglichkeit
man hat, jetzt so diese Klassifikation durchzuführen,
weil, weiß ich, mehr als zwei
Dinge, also wenn du zwei Merkmale hast, dann
kannst du ja relativ einfach voneinander trennen, wenn die
homogen sind untereinander
in ihren eigenen Klassen. Und das wird ja umso
komplexer, umso
weniger heterogen die untereinander sind, also
umso mehr die sich gleichen, dann hast du natürlich größere
Probleme, dann ist es vielleicht auch so, dass du die Merkmale falsch
anguckst oder so. Also du sollst halt schon
unterscheidende Merkmale finden können.
Und das ist halt im Prinzip das, was du mit Base dann relativ
gut machen kannst. Du kannst halt dann sagen, ey, ist jetzt
der Falter grün oder nicht? Oder schwarz
oder so? Oder ist das halt eine Katze?
Woran erkennt man das? Ich weiß nicht, ob sich
jetzt Base für Katzen und Hunde schon
eignen würde, weil das wird vielleicht schon
schwierig. Ja, also für Bilder
wird das sicherlich nicht gut funktionieren,
aber wenn ich jetzt, eben
das ist halt auch so ein klassisches Beispiel habe,
wenn ich jetzt Spam von Nicht-Spam-Mails unterscheiden
möchte, da ist es halt
genauso, das war früher, waren die ganzen
Spam-Filter irgendwie
regelbasiert, also man erinnert sich da vielleicht noch so an
Zeiten, ich habe das auch selber noch benutzt,
ja, das war so ein
Spam-Assassin,
das hat sich dann halt die Header angeguckt
und dann hat es halt manchen
Providern mehr und manchen weniger vertraut
und
irgendwelche, insgesamt halt irgendwie
einen Score ausgerechnet und gesagt, ah, okay,
das hat jetzt einen Spam-Score von so und so viel
oder so und so viel und ab einer bestimmten Grenze
wurde dann halt abgeschnitten und gesagt, das ist Spam.
Das hat
ganz okay funktioniert, aber das war immer
leicht zu unterlaufen von Spammern
und Spam war immer eine relativ
ärgerliche Geschichte.
Bis dann halt eben
Paul Graham, halt der
ähm
ähm
ja, wie heißt der Inkubator, den er gegründet hat?
Darüber ist er sehr bekannt geworden.
habe ich jetzt gerade, ist mir entfallen,
also der schreibt auch viele Essays und
hat auch ein Buch geschrieben.
Y Combinator tatsächlich.
Vorher hat er es auf der Zunge, ich habe mich nur nicht getroffen.
Ja, der
schrieb dann halt irgendwie 2004
ein Essay, so
A Plan for Spam, also ich habe da irgendwie so eine Idee,
wie wir dieses Problem endgültig in den Griff kriegen.
Und da schlägt er halt vor, irgendwie so
Naive Base zu verwenden, um
inhaltsmäßig irgendwie
Spams von Nicht-Spams zu
unterscheiden, weil, naja, irgendwie
ein Spammer muss ja reinschreiben, dass er was
verkaufen will oder muss ja irgendwie, er kann ja
den Content kann er im Grunde nicht wirklich
so ändern,
dass man das nicht mehr als Spam erkennen
kann, weil dann kann es auch der Mensch
nicht mehr als Spam erkennen und dann
verfehlt das ja seinen Zweck.
Liebe Freund, ich brauche Hilfe.
Ja gut, okay, das ist jetzt eine bestimmte
Art von Spam.
Das sind die, die bei mir gerade immer durchkommen, immer wieder.
Die kommen durch? Da ist aber irgendwas mit
deinem Spam-Filter nicht in Ordnung. Was für ein Spam-Filter?
Okay.
Nein, also sie landen bei mir im Spam-Filter
und ich kann dann immer sehen,
okay, es war eine Message im Spam-Filter,
was auch nicht so häufig passiert.
Ach so, okay, gut, ja.
Genau, und zwar das Verfahren ist halt super einfach.
Das ist halt, mach einfach aus den Mails,
aus dem Inhalt deiner Mails im Spam-Ordner
eine lange Liste von Wörtern,
zähle, wie oft ein Wort da drin halt vorkommt,
merke die Gesamtzahl der Wörter
und die Gesamtzahl der Mails, die da drin waren
und mach das Ganze auch nochmal für den Ordner
mit den Nicht-Spam-Mails
und
das ist schon das Training.
Das war's. Also man hat jetzt
quasi an jedem Wort sozusagen nur dranstehen
quasi
wie oft das halt
vorkommt und man hat nochmal eine Zahl für
wie viel
Mails man gesammelt hat.
Er hat Penis gesagt und dann sagt er, nee, ist wahrscheinlich Spam.
Also so in etwa.
Genau. Und die Klassifikation,
also wenn man das gemacht hat,
ist man mit dem Training schon fertig und das ist auch schon das
Modell. Und die
Klassifikation funktioniert jetzt so,
wenn man jetzt eine zu prüfende Mail hat, dann zerlegt man die
eben auch wieder in eine Liste von Wörtern.
Man macht aus
dieser Wortliste eine Liste von Zahlen
und man ersetzt jetzt
jedes Wort eben durch die Kategoriefrequenz.
Das hatte man ja vorher schon
ausgerechnet, sozusagen. Man wusste halt, wie oft
jedes Wort im Spam- und im Nicht-Spam-Ordner
vorkommt. Und
sozusagen, ja,
man ersetzt jetzt die Wörter eben durch die Kategoriefrequenz
und
multipliziert jetzt einfach alle diese Zahlen
miteinander und
bekommt dann halt eine Wahrscheinlichkeit, dass eine Mail Spam
oder nicht Spam ist. Und
ja, die Zahlen werden relativ klein
sein, weil das sind alles relativ kleine Wahrscheinlichkeiten.
Wenn die noch miteinander multipliziert, ist es
super nahe Null. Das heißt,
man muss das Ganze noch so normalisieren, dass hinterher ja halt
irgendwie quasi
der Wert für Spam und nicht Spam, wenn man das addieren würde,
eins ergibt. Aber ja, ist ja auch
kein Problem. Und das war es schon. Also es ist wirklich
nicht, ist keine große
Hexerei.
Wie sagen wir, Raketenchirurgie.
Das ist eigentlich eine ziemlich einfache Geschichte.
Genau, das kann man ja einfach sich eigentlich auch noch so
in einem Algorithmus darstellen. Da braucht man
ja, keine komplexen
Selbstlernverfahren eigentlich noch, nicht wahr?
Ja, also gut, das Ding
lernt ja tatsächlich. Also wenn ich jetzt sage,
eben, ich habe bisher nur
Mails,
die mir Produkte zur
Vergrößerung meiner primären Geschlechtsmerkmale
irgendwie mir so ein Zeugs andrehen
wollen, bekommen und ich kriege jetzt zum ersten Mal
ein Nigeria-Spam, wo mich jemand halt
dazu bringen will, einen kleinen Betrag
ihm zu geben,
um einen viel größeren zu bekommen,
dann würde ich halt
das halt auch mit in die Spams
reintun und dann müsste ich halt wieder neu
diese Zahlen
ermitteln. Genau, die müssen halt
wieder neu gebildet werden, aber
dann würden sich die Frequenzen wahrscheinlich zum Beispiel
für so ein Wort wie Prinz oder so oder Schweizer
Bankkonto entsprechend verändern
und dann hoffentlich beim nächsten Mal werden wieder so
eine Mail dieser Art... Ziemlich ärgerlich für Prinzen mit Schweizer
Bankkonto. Ja, die haben
ein Problem mit, die werden
ja,
die haben mit Meldern keinen Spaß mehr seitdem.
Genau
und das, ja, und dann
passt sich das durchaus halt
quasi neuen Mustern an, wenn
die nächste Masche um die Ecke kommt, dann braucht man halt nur die
ersten paar
sozusagen richtig zu sortieren und dann sollte das
automatisch funktionieren und mitlernen.
Ja.
Ja, jetzt haben wir kurz an Base-Klassifikationen erklärt. Wir sind aber immer noch nicht bei dem Beispiel angekommen, was wir irgendwie den Menschen, also wie macht man das denn überhaupt?
Wir haben versprochen, dass wir irgendwie praktisch durchgehen wollen. Da hätte ich mal gesagt, lass uns das mal machen. Wir packen mit Sicherheit unter die Folgen mal einen Link zu dem Repository, was wir dafür benutzen wollen. Das ist vom Jochen. Da hat er halt eben eine Schulung drin, eine Data Science Schulung, woraus wir jetzt vor allem gleich mal das Beispiel nehmen wollen für die Text-Klassifikation.
und genau, wenn man da drauf geht,
sieht man in dem Readme auch erstmal irgendwie alle
Informationen, wie man sich das Ganze zieht, also
man klont sich halt erstmal das Git-Repository
soweit, so gut
und dann kommen auch schon die ersten Python-spezifischen
Sachen, denn dann müssen
wir uns erstmal irgendwie mit Conda
eine entsprechende Umgebung aufsetzen. Jochen,
sag doch mal, warum sollte man das immer machen?
Und warum denn Conda?
Ja, also Conda ist
sozusagen der Paketmanager
des Teils
von Python,
der sich mit so Data-Science-Maschinen-Learning-Geschichten beschäftigt.
Da steckt halt auch so eine Firma dahinter, Continuum Analytics.
Das sind auch die, oder die Leute, die die Firma gegründet haben,
sind auch die, die ursprünglich mal NumPy mitentwickelt haben und so.
Und ja, es ist, früher hatte man ja irgendwie mal so die Hoffnung,
dass die Distribution, das ganze Paket-Installations-Ding
halt irgendwie überflüssig machen würden
Und sich halt um Abhängigkeiten und sowas kümmern und das ist irgendwie nicht passiert. Also stattdessen ist es so, dass irgendwie jede Programmiersprache so gefühlt irgendwie ihren eigenen Paketmanager hat.
Und bei Python ist es ein bisschen
besonders schlimm, weil da gibt es halt nicht nur einen,
sondern mehrere. Je nachdem, in welcher
Community man sich da aufhält.
Wenn man irgendwie eher Web-Entwicklung oder sonst
wie Python-Entwicklung macht,
dann ist es eher Pip und
als Repository für Pakete
halt PyPI.
Lass dir sagen, das Problem hat nicht nur Python.
Rust ist da auch ganz schlimm, habe ich schon
gelernt, aber ja.
Ja, es ist auf jeden Fall ziemlich
anstrengend. Ich weiß gar nicht, ob ich Conda so verwenden
würde, so außerhalb von Daten.
Ne, würde ich glaube ich auch nicht, mache ich auch nicht.
Also wenn ich Web-Projekte mache, dann nehme ich
eher PIP und
tatsächlich funktionieren
die meisten Sachen auch, wenn man sie mit PIP installiert.
Also tatsächlich auch die ganzen
Datensachen funktionieren über PIP?
Ja, schon.
Sie
funktionieren zumindest gut genug, als dass man das
meistens einfach so verwenden kann. Wenn ich jetzt
irgendwie tatsächlich
ein Modell trainieren wollte,
aber das will man halt, wenn man
wenn es einen Web-Server hat, der irgendwie auch nur
Pandas noch mitbraucht, um halt irgendwelche
Sachen anzunehmen, oder
selbst ein Web-Server, der jetzt halt hinter
irgendeinem ARP-Modell hat, was irgendwas vorhersagt
oder was irgendwas klassifiziert und dann die Ergebnisse zurückgibt,
da ist es im Grunde egal, da kann man
das bei PIP installieren, aber wenn ich jetzt
irgendwie was trainieren wollte,
dann würde ich eher
die Conda-Pakete nehmen
oder vielleicht sogar
spezielle Docker-Images oder sowas.
Ja, aus meiner Sicht
hatte halt Conda vor allem zwei Vorteile. Zum einen
ist es halt schon mal
zusammen das, was sonst
PIP und Virtual Env ist. Also ich habe die
Möglichkeit, sowohl eine virtuelle Umgebung
mit zusammenzubauen und dann
halt eben in die die Pakete mit rein zu installieren.
Was man häufig möchte,
wenn man gerade zum Beispiel so ein Experiment macht,
dann möchte ich vielleicht meine
Basis-Version an Paketen so lassen,
wie ich sie hatte und dann halt mal für jetzt
eine Konferenz zum Beispiel mir nochmal eine zweite
daneben stellen. Das müsste ich ja sonst mit
Virtual-End-Pip quasi in zwei
Schritten machen. Ja gut, aber normalerweise
machst du ja Virtual-End-Wrapper, dann einen Befehl
und dann ist das Ding ja oben. Genau.
Ich habe tatsächlich einen Python-Skript für sowas
geschrieben, der auch genau das gleiche macht, wenn ich das will.
Aber ja. Genau, und der zweite Punkt ist,
Conda kann halt
einfach ja noch ein bisschen mehr als Pip.
Es kann halt vor allem auch quasi Abhängigkeiten,
die außerhalb von Python-Paketen
liegen, lösen, was dann halt auch
interessant wird, wenn es halt um Treiber-Support und so weiter
geht.
Genau, aber ich glaube, du hast schon recht,
dass es auch so ein Stück weit ein Community-Ding ist,
dass es sich halt im Data-Science-Umfeld
auch durch den starken Support von Continuum da
und den finanziellen Mitteln, die dahinter stecken,
so durchgesetzt hat.
Ja, ja, also ich...
Weil es so einfach zu installieren ist auch.
Es gibt halt auch, glaube ich, nur Windows-Binarys einfach
und da ist dann alles mit dabei an Modulen, was man so hat
und man muss das gar nicht mehr groß bedienen.
Ich glaube, das ist auch so ein low-leveliger Ansatz.
Das ist ein Grund, warum sie das so verbreitet hat.
Wobei ich jetzt ehrlich gesagt zum Beispiel
die große Anaconda-Distribution habe ich nie benutzt,
habe ich nie installiert.
Also das Anaconda-Distribution ist
eigentlich sozusagen das eigentliche
Ding, was irgendwie da produziert
wird. Ich habe immer Miniconda verwendet
und dann halt das installiert, was ich
gerade gebraucht habe. Also der Unterschied ist, Anaconda
bringt halt schon mal irgendwie alle möglichen Pakete mit,
die man potenziell so gebrauchen könnte und Miniconda
ist halt erstmal klein und schlank und
dann muss man halt alles quasi mit
dazu installieren, was man dann noch gerne hätte.
Ja, und eben
der Vorteil gegenüber PIP oder
sagen wir mal so, das ist halt auch nicht mehr so
ganz, das war früher ein Riesen
Unterschied, ist heute nicht mehr ganz so relevant,
ist halt, dass man halt binäre Geschichten
bei Conda auch installieren kann. Also man kann
halt auch Bibliotheken, die unten
drunter liegen, also eben nicht nur Python-Pakete,
sondern eben auch sowas, man kann auch theoretisch sowas wie
Libc irgendwie mit Conda
installieren und die dann halt
in einem Conda-Environment verwenden
und muss halt, also das ist
auch so ein Problem, wenn man jetzt auf größeren
Servern unterwegs ist, die halt
unter Umständen irgendwie
so eine antike Debian-Version
irgendwie haben und eine uralte Lib C
und die funktioniert dann mit neueren
anderen
Bibliotheken nicht mehr gut, dann
habe ich, hatte auch schon den Fall, dass ich dann
per Conda irgendwie eine neue Lib C
in meinem Environment installiert habe, um überhaupt
irgendwie bestimmte Sachen benutzen
zu können. Und das geht halt mit Conda und mit
PIP wäre man da halt relativ aufgeschmissen.
Daher, ja,
für so
wirkliche Data Science Projekte ist das
halt schon irgendwie deutlich netter.
Es ist ein bisschen schade, dass jetzt man halt
zwei Repositories von Paketen hat und
ja, manchmal ist es halt auch so ein bisschen
kompliziert, dann sich zu überlegen, was man gerade
machen will, aber ich würde die
Faustregel einfach nehmen, wenn es ein reines
Data-Science-Projekt ist, ja dann
Conda und wenn es irgendwie eine Web-Geschichte ist oder
was ganz anderes, eher Pip.
Ist das denn immer genauso aktuell in Conda
wie auf PyPy?
Nee, Conda ist nicht so aktuell.
Es gibt dann noch CondaForge, also sozusagen
ein...
Da kann man sich selber Sachen bauen.
Ja, das kann man sowieso, aber
es gibt halt einmal die Pakete,
die sozusagen von der Firma
gebaut werden und ein Repository
von Paketen, das halt
also eine Distribution, die halt
sozusagen redaktionell von
Continuum Analytics gepflegt
wird und es gibt halt
ein Community-basiertes Repository,
das nennt sich dann CondaForge
und man kann das halt
in dem, man hat immer so ein Konfigurations-File
und da kann man
halt die Channels sozusagen
aus denen man Pakete bekommt, halt eintragen
und ja, die meisten verwenden
ContaForge. Es ist jetzt auch irgendwie so,
dass, glaube ich,
Anaconda selber irgendwie auf ContaForge umgestellt
hat oder so. Ja, genau, die haben sich tatsächlich umgestellt.
Das haben wir gehört auf dem Parkcamp jetzt.
Ja, richtig, das hatte ich
auch gar nicht klar, aber ja.
Das fand ich manchmal auch echt so ein bisschen nervig, wenn man ein Paket
installieren wollte, habe ich dann doch meistens mal gegoogelt,
was ist denn jetzt hier das richtige
Repo dafür und das ist jetzt aber
seitdem quasi weg.
Ja, ist tatsächlich anstrengend, wenn man halt schon
unterschiedliche Paketmente hat und dann auch seine eigene Source
dafür irgendwie bestimmen muss.
Ich kann mich da an andere Experimente
erinnern mit so Paketsachen und Sources.
Alles nicht einfacher, aber
hatten wir das schon erwähnt, warum man das überhaupt machen
sollte? Ja, das Problem ist eben, dass die
Pakete in der Distribution halt
nicht wirklich aktuell sind meistens.
Also, wie sagte Barry Varsaw,
glaube ich, einer
Python-Core-Entwickler
sagt man mal, the first rule of Python
is, you don't use system Python.
Das ist halt einfach
üblicherweise veraltet bei vielen
Distributionen, weil sie halt auch das,
weil sie Python halt auch für so
distributionsinterne Zwecke benutzen, mit halt
Python 2 irgendwie noch als Default-Interpreter
bei Mac auch. Es gibt einen
Counter für Python 2 mittlerweile, habt ihr den gesehen?
Desk Clock, ja, gibt's.
Bin mal gespannt, wann die Vertriebssysteme es dann auch mal
sich trauen, also schon ein bisschen halbern so langsam.
Ja, die haben halt alle Angst davor,
dass irgendwie, wenn sie das
ändern, irgendwie ihre Installationsroutinen
nicht mehr funktionieren, weil die halt Python brauchen und
vielleicht noch nicht umgestellt sind. Und die sind halt
alle uralt. Ja, doof.
Und daher muss man
sowieso eigentlich immer einen anderen
Python-Interpreter verwenden, als der, der vorinstalliert
ist. Und dann ist es
halt so, wenn man unterschiedliche Projekte hat,
dann haben die halt unterschiedliche
Abhängigkeiten, was bestimmte Bibliotheken
angeht. Und die
widersprechen sich halt. Und das kriegt man halt auch,
wenn man in einem Filesystem ist.
und das kriegt man halt nicht irgendwie unter einen Hut.
Und daher macht man normalerweise pro Projekt
ein eigenes sozusagen virtuelles Environment,
in dem man halt irgendwie alle Abhängigkeiten installiert,
die man braucht.
Ist dir schon mal vorgekommen,
dass du für ein Projekt zwei Virtual Environments brauchtest,
weil da innerhalb des Projektes
sich unterschiedliche Module besprachen?
Nee, das geht auch gar nicht.
Oder ja, also natürlich doch, stimmt,
man könnte es theoretisch machen,
aber nee, das ist mir jetzt auch noch nicht untergekommen.
Was meinst du innerhalb von einem Projekt?
Ja, es könnte ja irgendwie sein,
dass es zwei Module in einem Projekt gibt,
die unterschiedliche Versionen brauchen,
Python-Version, weil die Module das sonst nicht können
und die man dann irgendwie pipen muss, damit die
man da reden kann. Und um das dann zu bauen,
müsste man halt dann zwei Versionen benutzen.
Nehmen wir zum Beispiel mal an, man hätte
ein OCR-Projekt und man möchte jetzt
irgendwie ein aktuelles
Ding gegen was Älteres
wie Oceropi oder
Kraken oder so verwenden.
Angenommen, Kraken kann auch Python 3, aber
Oceropi kann nur, oder Oceropus
kann nur Python 2. Und jetzt möchte man
halt das Ding aber testen gegen was Neues,
was halt vielleicht nur Python 3 kann. Und dann müsste man
zwei Interpreter halt haben, irgendwie
in dem, ja, das wäre
hässlich.
Aber ich glaube, so kompliziert müssen wir es gar nicht
machen.
Also wenn ihr euch inzwischen das Repo ausgeklont
habt, dann ist jetzt vielleicht der
richtige Moment, einmal corner.env.create
auszuführen, um die Umgebung euch aufzusetzen.
Was an der Stelle ja passiert ist,
er zieht sich von lokal eben
eine hinterlegte
Environment-Datei, die
die ganzen Pakete und die jeweiligen
Versionen beinhaltet, die man bitte
zu installieren hat.
Und danach kann man das dann eben aktivieren
und hat das dann quasi als sein
Default-Python-Interpreter gesetzt.
Also Connor M. Great macht dann genau das,
dass er einfach ein Environment setzt, die heißt dann
Great, oder was? Ne, das steht in dem
in dem File halt
auch mit drin. Der Name von dem?
Von dem
Environment, genau.
Warte mal.
Das ist auch einfach ein YAML-File
und da steht dann eben das erste Name
ds-tutorial
ds-tutorial und dann dependencies,
ach, und dann werden die Pakete danach geploppt.
Und, achso, ist auch so, man kann halt
auch Sachen
per PIP installieren.
Ja, das ist auch sowas, also es ist halt irgendwie,
ja, Conda ist quasi
eine echte Obermenge von PIP,
man kann halt Conda und halt auch PIP,
aber umgekehrt geht es halt nicht, PIP kann halt nicht
Conda Sachen installieren.
Ja, und manche Sachen installiere ich
via PIP, weil das einfach aktuellere Versionen
dann sind.
Ja, oder halt, wenn man was sehr Spezielles
will, ist es vielleicht auch nicht unbedingt immer
in jedem Conda-Repository eben drin.
Da ist PIP, glaube ich, einfach ein bisschen
größer. Also ich kann auch einfach die Version angeben,
wie bei PIP auch, mit gleich oder sowas.
Genau.
Genau. Und danach müsst ihr, um das Repo
quasi so ausführen zu können, noch mal
das lokale Paket bauen
und zwar mit "-e".
Warum wollen wir denn
erstmal überhaupt ein lokales Paket
und warum wollen wir "-e"?
Ja, ein lokales Paket
deswegen, weil man in
vielen Notebooks halt, also ich habe das
Ganze quasi ein bisschen in unterschiedliche
Notebooks aufgeteilt und da gibt es dann
einige, die halt immer wieder den gleichen
Code enthalten. Und jetzt könnte man
natürlich auch in jedes Notebook irgendwie reinkopieren,
aber wenn man dann gemerkt hat, oh, ich habe hier
einen blöden Fehler gemacht, dann muss man das halt auch
in allen Notebooks wieder ändern, was ja ein bisschen
umständlich wäre. Und Code, den man halt
in mehreren unterschiedlichen Notebooks
benötigt, den
kann man ja aber auch einfach eine
Bibliothek und das ist halt im Grunde
dieses Paket, was man da installiert,
rausziehen und
den importiert man dann halt einfach nur in
allen Notebooks und wenn man da jetzt einen Fehler
fixt, dann ist der halt
in allen Notebooks gleichzeitig gefixt
und Minus E installiert man
deswegen, um Änderungen,
wenn man da jetzt eine Änderung macht,
die sofort sichtbar
werden zu lassen. Also ansonsten müsste man
ja eigentlich, wenn man ein Paket
zum Beispiel via PyPI oder so
installiert oder normal installiert sozusagen,
jedes Mal, wenn man was ändert, ein neues Paket bauen
und dann dieses Paket wieder installieren.
Und am besten auch nochmal das Notebook neu starten.
Und das ist natürlich ein bisschen umständlich.
Und wenn man sagt pip install –i,
dann macht das sozusagen keine wirkliche Paketsinstallation,
sondern legt nur einen Link auf das entsprechende Verzeichnis
sozusagen mit nach Side-Packages.
Und wenn sich da irgendwas ändert am Code,
dann ist das halt sofort irgendwie sichtbar.
Und dann kann man das auch für alle einstellen
oder für einige auf Notebook-Seite kann man zum Beispiel sagen,
A-Import statt Import, ein bestimmtes Modul,
dann wird halt die Aktualisierung auch sofort wirksam,
ohne dass man das neu starten muss, was ja auch praktisch ist.
Also man kann das sehr feigengranulär einstellen.
Man will das vielleicht auch nicht für alle Module machen, aber wenn man das richtig eingestellt hat, sozusagen, kann man halt, wenn man jetzt beispielsweise bei einem Code-Teil, der halt in vielen Notebooks verwendet wird, einen Teil ändert, dann ist die Änderung sofort da und bei der nächsten Ausführung einer Zelle hat man halt auch schon den geänderten Code mit ausgeführt und muss da nichts neu installieren, neu starten oder so.
Da kann ich auch jeden nur zu ermutigen,
zu gehen. Also ich habe mich da am Anfang lange
vorgescheut und habe einfach quasi
am Anfang von meinem Notebook einfach immer
mit der Runmagic quasi
in ein anderes Notebook gestartet, wo ich alle diese
Sachen initialisiert habe. Das geht auch.
Aber das muss man halt dann doch, wenn man
in einem anderen Notebook was ändert, immer noch einmal ausführen.
Und so viel
Zauber ist es gar nicht, quasi sich selber
so ein Paket zu erstellen. Vor allem ist es auch ein ganz cooles
Gefühl. Man kann es danach auch wirklich direkt mal weitergeben
und weiterleiten und es
verleitet zu ein bisschen besserer
Ja, Art Software-Code dann auch zu schreiben
an der Stelle. Man kann dann eine ordentliche
IDI dafür vielleicht auch benutzen und
entwickelt dann diese ausgelagerte
Funktionalität vielleicht nicht direkt im Notebook.
Welche IDI benutzt du?
PyCharm, halt ganz klassisch, wie die meisten, glaube ich.
Wir sind beides umgestiegen auf Visual Studio.
Studio Code? Ah ja, okay.
Ich benutze immer noch alles. Also ich benutze
auch immer noch, also vor allen Dingen häufig
eigentlich Wim.
Ich benutze auch PyCharm und auch VS Code.
Ich hatte das mir auch gezeigt.
Ja, ist schon ziemlich gut, muss man sagen.
Genau. Ich meine, am Anfang ist so ein bisschen
overhead mit dem Anlegen von so einer Klasse da,
aber ihr benutzt, glaube ich, so
Cookie-Cutter-Templates. Ja.
Ich benutze PyScaffold,
was ein Projekt ist, was von Kollegen
von mir entwickelt wird, was mir da sehr geholfen
hat, einfach am Anfang quasi so
Scaffolding, mir
mein Gerüst einmal aufzusetzen, da kenne ich mich
dann direkt drin aus und dann dränge ich dann noch meine zwei, drei
Zeilen ein und ja, bin gleich
da und das hat mir so ein bisschen
die Angst davor genommen, eigene Pakete
an der Stelle zu schreiben.
Ja, genau.
Gut, und dann
können wir letztendlich wirklich unser
Notebook starten.
Du benutzt noch Jupyter
Notebooks. Ja, stimmt.
Magst du JupyterLab lieber, also
warum magst du kein JupyterLab?
Doch, stimmt, mag ich auch.
Das ist jetzt auch nur so reine Gewohnheit eigentlich.
Aber ja, eigentlich im Grunde
müsste ich auch mal auf JupyterLab umsteigen.
Ja.
Genau, also gerade die neuen Versionen mit den Plugins
finde ich, es kommt, also am Anfang
haben wir noch ein paar Funktionalitäten von JupyterNotebooks
gefehlt, aber jetzt
gerade mit dem sich ausbreitenden
Plugin-System gibt es da echt coole
Sachen, zum Beispiel, was ich total liebe
gerade, ist halt die Sublime Keybinding
Magic-Funktionalität, die man jetzt einfach
sich so in die JupyterLab
Notebooks reinladen kann.
Und so. Aber genau.
Ja, ja, ja, nee,
das, genau, das hatte ich auch, habe ich auch schon lange vor.
Ich habe es halt bisher nur immer ausprobiert, aber noch nicht
wirklich verwendet.
Und genau, ja, nee, sieht sehr, sehr gut aus.
JupyterLab ist, ja.
Genau.
So, egal, ob ihr jetzt ein
Jupyter Notebook oder ein ehemaliger,
ja, egal, ob ihr jetzt ein Jupyter
Notebook oder halt schon JupyterLab gestartet
habt, müsstet ihr jetzt quasi
eine Reihe an
Ordnern sehen und
im DS-Tutorial,
nee, im
Ordner Notebooks gibt es halt eben
das Projekt Text Classification
und dem wollen wir uns mal ein bisschen widmen.
Genau. Ja,
vielleicht kann man einfach direkt mal das
Explorer Data Notebook aufmachen.
Das ist
das Dataset, also
ist man natürlich auch mal ein bisschen darauf angewiesen, dass es
halt irgendein frei verfügbares
Dataset gibt, das ich
da verwendet habe, ist
Reuters
21578
Textklassifikations
Dataset, das ist so ein klassisches Ding,
wo
irgendwie eben entsprechend viele
21578
so Ticker
Meldungen drin sind
und die sind halt klassifiziert
in
unterschiedliche Kategorien und
bei dem Set geht es auch
im Grunde darum, Modelle zu
bauen oder das benutzt man eigentlich mal
als Trainingsdatum
für
Textklassifikationsmodelle,
weil man halt dann damit vorhersagen kann,
versucht zu vorhersagen, wenn man jetzt
eine neue Tickermeldung reinbekommt, welche Kategorie ist
das? Also es ist im Grunde so ähnlich wie das
Spam-Klassifikationsbeispiel
von eben, nur dass man halt nicht
nur zwischen Spam und Nicht-Spam unterscheiden
können will, sondern halt zwischen
allen Kategorien, in denen halt
so eine Tickermeldung liegen kann
beziehungsweise auch noch ein Unterschied ist,
es ist nicht, man würde,
das wäre jetzt Multiclass, wenn es nur eine gäbe,
aber das ist eigentlich ein Multilabel
Dataset, das heißt, man möchte
alle Kategorien, in denen so
eine Ticker-Meldung
drin liegt, rausfinden.
Also vielleicht halt auch, es gibt welche,
die halt, wo es
nicht nur um Politik geht oder Sport, sondern auch
Sport und Politik oder sowas.
Genau.
Das Erste, was man, finde ich, bei so einem Datascience-Projekt
ja am Anfang immer machen muss, vor
lauter Tools und Frameworks und sonst was.
Das Wichtigste sind immer noch die Daten.
Und wenn die Daten nicht passen, dann hilft es nicht.
Und da muss man sich halt echt erstmal reinknien
und richtig verstehen, was haben wir denn da überhaupt alles.
Und
ich weiß nicht, da gibt es so ein paar Befehle, die ich immer
als erstes so benutze. Also ich lad
mir mein Dataset irgendwie
in Pandas DataFrame rein.
Und
dann nutze ich darauf erstmal
meist ein Head, um einfach mal zu gucken, was
habe ich überhaupt drin. Dann
D-Types, um mir anzugucken,
okay, welche Spalten haben denn hier
welchen Typ? Und danach
mache ich dann eben einen Describe,
was mir dann für alle numerischen
Spalten da drin schon mal so ein bisschen
eine erste Übersichtsstatistik gibt.
Also irgendwie, wie viele Einträge habe ich?
Was ist der Mittelwert?
Was sind quasi die Maximalwerte?
Und so weiter. Machst du das ähnlich?
Oder wie gehst du? Ja, ja, doch, durchaus.
Also ich habe das jetzt auch hier
gerade nochmal ausgeführt.
Genau, ja, also wenn man jetzt zum Beispiel einige der ersten Zeilen ausgeführt hat, dann hat man hier auch eben ein Data-Frame, in dem all die Dokumente halt drin sind und wenn man DF-Head macht, dann sieht man halt eine Spalte Mod-Update, das ist halt sozusagen so der klassische Split in Trainings- und Testdaten.
Das ist halt auch ganz praktisch bei dem Dataset, dass man das nicht selber machen muss, weil das ist halt auch noch, eigentlich müsste man dann irgendwie erklären, was Cross-Validation ist und wie man K-Fault-Cross-Validation, hier ist das schon fertig.
Da muss man sich dann keine Gedanken mehr drum machen,
sozusagen. Das ist vielleicht ganz gut.
Dann gibt es eine Spalte mit den
Kategorien drin. Das ist dann einfach nur eine Liste der
Kategorien,
in denen halt diese
Meldung halt drin ist.
Und genau, das Ganze nochmal
sozusagen nicht als
Textkategorie, sondern eben
numerisches Label, weil
wenn man später das an irgendwelche Modelle
verfüttert, dann brauchen die das halt als
ja, als
Zahl und am besten auch
als Zahlen, die halt keine Lücken haben.
Sonst geht das halt nicht gut, weil man
das halt, One-Hot-Encoded
nimmt man das sozusagen, hinterher kriegt
halt jedes Label eine eigene
Spalte und das geht eigentlich natürlich nur dann
gut, wenn das halt irgendwie keine Lücken hat.
Ja, dann gibt es da irgendwie
noch ein Datum, was da dran ist,
einen Titel, irgendeine komische
Dateline, ich weiß jetzt gar nicht genau, was das ist und ein Body
von dem Artikel,
dann noch eine ID und
ich glaube, das habe ich irgendwie mal dran gebastelt,
einfach nur um,
weil die Idee war halt,
dass in dieser
Machine Learning-Schulung
man
ja, als Übung sozusagen
vielleicht ein paar neue Features dazu tun sollte,
um zu gucken, ob das irgendwie die
mit, ob das den Score irgendwie
verbessert, der Modelle. Und da war
halt so ein erstes Beispiel, man könnte einfach mal
den Wochentag reinschreiben, der
an dem das irgendwie erschienen ist
und vielleicht steckt da ja irgendwelche Informationen drin.
ja genau, DF-Info
Wenn ihr irgendwie wissen wollt, wie man
mit diesen Data-Frame-Operationen noch
ein bisschen besser einen Einstieg findet, da gibt es ein ganz spannendes
Buch von Jake Wanderplast zu
Data Science mit Python, das hat er
auch frei auf seinem GitHub-Account
veröffentlicht und auf einer Webseite
findet ihr irgendwie, da kann man auch mit
Dupade der Notebooks das tatsächlich auch mal live noch an anderen
Datensätzen üben, also gerade für Pandas
Einführung ist da nochmal ein großes Kapitel
Ja, also die Pandas-Dokumentation
ist auch ziemlich gut, die ist halt nur etwas
länglich und trocken, aber ansonsten ist sie auch super
zu empfehlen.
Und ja, ich finde
die Modern Pandas
Blogartikel-Serie von Tom Augsburger
auch super.
Was ich ansonsten immer noch ganz gerne
mache, wenn ich am Anfang so ein Dataset habe, es gibt
eine Library, die nennt sich Pandas Profiling.
Der wirft so einfach so ein DataFrame rein
und die generiert dir daraus so einen
kleinen HTML-Report,
worin man dann quasi so ein paar
Summary-Statistiken nochmal ein bisschen hübscher aufbereiten
bekommt. Das sieht ja auch super aus.
Wie viele Zeilen hast du, wie viele
Spalten natürlich. Aber dann schaut die halt eben
auch quasi, wie viel Prozent der Daten sind jetzt
halt irgendwie fehlen, sind Nullwerte.
Du kriegst
eine Übersicht quasi, welche Typen
hat das Ganze und der sucht auch quasi
nach Korrelationen in den Daten. Also wenn du jetzt
zwei Spalten hast, wo du eben zum Beispiel
schon so ein Feature Engineering gemacht hast und
hast, keine Ahnung,
den Tag und dann nochmal
irgendwie den Tag um ein Jahr
verschoben oder so, dann korrelieren diese
beiden Spalten ja komplett, sowas würdest du dann
da drin direkt sehen und der würde dich zum Beispiel
vorwarnen.
Ja, das wäre ganz praktisch, wenn man die cleanen muss, dann irgendwie
erstmal so zu gucken, ah ja, das könnte ja ein Problem
sein, dann fangen wir doch mal an da oder so.
Genau.
Genau, das ist immer irgendwie, finde ich, ganz praktisch,
um so einen ersten
Übersicht zu bekommen.
Was würdet ihr dann machen? Würdet ihr dann die Daten, die dann da
zum Beispiel fehlen, irgendwie versuchen zu füllen?
Oder lässt man dann einfach
erstmal die Spalten weg, weil die irgendwie Quatsch sind?
Ja.
Kommt halt komplett drauf an.
Ja.
Also, was du jetzt ansprichst,
ist ja Ausreißerbereinigung im Wesentlichen
und Nullwerte füllen.
Die Frage ist, warum fehlen die Werte
und kannst du sie sinnvoll ersetzen?
Also, im Endeffekt hat man drei Optionen.
Man wirft die Daten einfach weg.
Man versucht sie zu füllen
mit einem Art von statistischem Maß,
was quasi zum Beispiel den Durchschnitt
von allen Spalten wiedergibt.
Oder, vielleicht habe ich ja nur die beiden Optionen.
Ich dachte, ich hätte nur eine dritte.
Ja, man könnte ja irgendwie.
Es gibt diverse, also man kann auch bei,
also es gibt dann Cyclic Learn zum Beispiel,
das ist so eine Bibliothek für Maschinen und Geschichten,
diverse, unterschiedliche, also da ist die Oberklasse quasi
für all diese Verfahren im Pewter
und man kann halt diverse unterschiedliche benutzen,
um eine Strategie dafür zu haben,
weil eben, es kommt halt darauf an,
wofür man die, was der Grund dafür ist,
warum das fehlt und wie man das am besten ausgleicht.
die dann sozusagen da irgendwas reinschreiben
oder irgendwas mit den Daten machen, ja.
Ja, die Frage ist halt, ob man die rausrechnen kann,
die Daten oder nicht, also ob das sinnvoll ist
und was man halt mit der Spalte sonst macht
oder mit den Datensätzen, die fehlen oder Korrelationen,
ob man da einen Dummy reinsetzt, weil man den noch irgendwie braucht
und dann immer merkt, oh, das ist das bei dem Dummy so.
Ja, und auch, wie rum droppst du sie, wenn du sie droppst?
Also schmeißt du die Zeilen raus oder schmeißt du die Spalten raus?
Hängt halt immer von dem Tast ab.
Ja, aber das sieht man genau gerade.
man hat ja irgendwie die Warnings gesehen, wie viel irgendwie
das ganz viele aus einer Teile oder
Spalte dann da fehlen oder so bei irgendwelchen Einträgen.
War bei den Warnings irgendwie mit dabei. Wie hieß das nochmal?
Ich hab das... Pandas Profiling.
Profiling, okay. Genau. Interessant.
Muss auf jeden Fall auch in die Shownotes.
Mach ich.
Ja, genau.
Also, hängt halt
dann immer auch von den Operationen ab,
die man halt danach drauf irgendwie anwenden möchte.
Genau. Ansonsten ist, glaube ich,
so eine gute Möglichkeit, am Anfang
sich auch nochmal so ein bisschen einfach erstmal zu plotten.
Also irgendwie diese statistischen Maße
sind immer irgendwie ganz nett, um
ein erstes Gefühl zu bekommen, wie groß ist
denn meine Spanne an Werten und so weiter.
Aber
da können halt einzelne Ausreißer das Ganze
eben ja komplett verziehen.
Oder ich habe zum Beispiel so einen leichten Shift
in den Daten, sowas in Kennzahlen zu erfassen
geht zwar, aber ist irgendwie immer nicht ganz so
eingängig. Und dann hilft halt meist
erstmal irgendwie so ein Histogramm oder so.
Ja, genau. Würde ich auch sagen,
dass
Das ist das nützlichste Ding, wenn man so ein bisschen sehen will, wie das eigentlich verteilt ist.
Oft ist es halt, sich ein Histogramm von der Werte anzugucken.
Vor allen Dingen auch, wenn man jetzt unterschiedliche Klassen hat, einfach mal die Histogramme gegeneinander zu plotten.
Das ist etwas, was ich mir oft angucke, um zu sehen, ob das irgendwas ist, wo interessante Informationen für Klassifikationen oder so drinsteht.
dass man halt sagt so, okay, man plottet
das Histogramm der einen Klasse gegen das der anderen
und man halt sieht, okay, da gibt es einen großen Unterschied, dann ist
schon mal, oder auch selbst ein kleiner
Unterschied ist natürlich schon hilfreich irgendwie.
Wenn man sieht, die sind genau gleich verteilt, dann ist das natürlich doof.
Aber genau.
Genau, in dem
Explore-Data-Monbook sieht man auch ganz unten
eben, finde ich, ein ganz klassisches, aber
sehr, sehr hilfreiches Diagramm an der Stelle,
wo du einfach mal so die
Länge der Texte
abgetragen hast, den Zeichen,
und da sieht man auch so ein ganz typisches Verhalten.
Man hat halt irgendwie so einen Peak der Daten, der relativ am Anfang liegt. Also irgendwie, wir haben ja jetzt, würde ich sagen, wahrscheinlich mal 80 Prozent irgendwie im Bereich von 0 bis 600 Zeichen oder bis 750, glaube ich, sind das. Und dann wird es weniger und dann gibt es so einen Longtail hinten mit so ein paar einzelnen Einträgen, die dann halt irgendwie 3.000, 4.000, 5.000, 6.000 plus Einträge haben.
Irgendwann hat ja jemand sein Buch bei Reuters hochgeladen, oder?
Ja, genau. Aber das ist so ein ganz klassisches Problem, was man halt im echten Welt-Data-Science halt immer hat, dass es halt irgendwie so Ausreißer gibt, die die Degagramme verzerren und die dann auch immer den Aufwand beim Programmieren eigentlich bedeuten, weil das dann immer die Fälle sind, an die man vielleicht so nicht gedacht hat.
Ja, genau. Ja, wir sehen hier, dass es halt so irgendwie ungefähr 10.000 Dinge gibt, die irgendwie Test oder Training zugeordnet sind. Also dieser Mod-Up-Split teilt diese Ticker-Meldung halt in die, auf denen man trainieren kann und die sozusagen, die man hinterher benutzt, um zu evaluieren, wie gut denn jetzt die Modelle funktioniert haben.
es gibt 119 Klassen, aber
tatsächlich sind es
deutlich weniger, wenn man jetzt
alle
Also gibt es so
Meta-Superklassen quasi, die bestimmte Dinge
beinhalten, sowas wie Sport und dann gibt es
Unterkategorien, Fußball, Hockey.
Es gibt einige, die deutlich häufiger sind,
aber es ist halt so, dass
wenn man jetzt alle rausnimmt,
auch alle Beispiele rausnimmt,
alle Kategorien rausnimmt, zu denen es nicht mindestens
ein Trainings- und ein Testbeispiel
gibt, weil das ist ja auch irgendwie so ein bisschen sinnlos.
Also Sachen, die man nicht gesehen hat, kann man auch schlecht vorhersagen.
Dann sind es
nochmal deutlich weniger, sind es irgendwie nur 90 Kategorien,
die übrig bleiben, glaube ich, und halt irgendwie
Vielleicht sind die Kategorien herausgefallen, so Donziges oder so.
Ja, ich weiß
es gar nicht genau. Ich habe es mir auch nicht
angeguckt, was das genau für Kategorien sind, aber
ja, also
das sind tatsächlich die Zahlen für alle, aber
in Wirklichkeit
ist es halt nochmal ein bisschen weniger.
Also die dann hinterher tatsächlich
zum Trainieren verwendet werden, dann
eben durchschnittliche Anzahl
von Wörtern ist halt irgendwie auch so 90
und
genau, die
also es gibt so eine Quote
Anzahl der Beispiele,
also das ist sozusagen Anzahl der Zeilen im DataFrame
geteilt durch die Anzahl der Wörter
pro
Tickermeldung, ist halt auch
eine ganz
interessante Zahl, die man später benutzen kann,
um halt irgendwie rauszukriegen,
welche Art von Modell da irgendwie besser
funktionieren könnte.
Ja,
genau, also überhaupt diese ganze,
also das ist halt irgendwie explorative Phase
irgendwie bei so einem Projekt.
Man versucht halt rauszukriegen, gibt es
irgendwelche interessanten Regelmäßigkeiten,
wie groß sind die Daten,
was prinzipiell kann ich da eigentlich
für Modelle verwenden und so.
Also erstmal visualisieren ist glaube ich tatsächlich
die beste Idee. Auch verschiedene Arten, mal gucken,
Wordcloud bauen vielleicht oder so und dann
schauen, was ist das denn.
Und nebenher finde ich durchaus irgendwie nochmal so ein Scratchpad
offen haben und wenn man da irgendwie eine
Auffälligkeit hat, die immer gleich
reinschreiben. Also man verfällt dann
finde ich auch relativ leicht in so einem
Liebe zu Charts, weil
so Charts basteln ist was, was ich
zum Beispiel total gerne mache. Also ich finde es
total spannend, dann mir die Daten
irgendwie so in Diagrammen zu visualisieren
und die irgendwie hübsch zu machen und mächtig
von ihrer Aussagekraft und so weiter, aber
dabei verfalle ich da manchmal
so ein bisschen in der Liebe zum Tun
und eigentlich geht es ja darum
Insights zu generieren. Deswegen
finde ich es dann immer relativ wichtig, sich irgendwo
nochmal so eine Liste runterzuschreiben mit den Auffälligkeiten,
wo man so gedacht hat, ah ja, stimmt,
das ist ja interessant und das ist interessant,
weil im Endeffekt sind das nachher dann Sachen,
aus denen man dann Ideen bekommt,
um zum Beispiel Features zu generieren,
die dann eben meinem Modell wirklich
weiterhelfen könnten.
Ja, also das ist halt an der Stelle auch definitiv
dann ein iterativer Prozess,
wo man quasi
sich die Daten anschaut, man entwickelt
eine Idee dafür, man probiert sie aus und
Man geht dann wieder zurück und guckt sich mal wieder die Daten an und guckt, ah ja, jetzt habe ich aber ja ein besseres Verständnis dafür bekommen, weil ja, da ist so viel Information in so einem Datensystem, dass es eine ganze Zeit lang braucht, bis man wirklich versteht, was man damit alles machen könnte.
Da muss man sich natürlich auch immer das Problem erstmal so ein bisschen reindenken, damit man irgendwie dann mit den Daten überhaupt was anfangen kann.
Ja, genau und ja.
Dabei hilft halt diese explorative Sache.
Und ja,
neben diesem ganzen Histogramm, ich glaube,
wir haben angefangen erstmal mit, wie man die Daten noch bekommt.
Damit waren wir noch gar nicht so durch.
Achso, richtig. Ja, stimmt.
Wir sollten irgendwie noch so die Art und Weise der Methode,
wir haben jetzt irgendwie das Describe von DataFrames
ein bisschen gemacht, aber wie bekomme ich denn die Daten
überhaupt irgendwie so rein? Das ist ein guter Punkt, ja.
Ja, also
das ist irgendwie eine
URL, die da irgendwo
mit drin steht. Moment, ich glaube,
das ist jetzt mittlerweile gut versteckt irgendwie
in dem
DS-Tutorial-Paket
Datasets, da gibt es so ein
Pfeil. Genau, normalerweise in der echten Welt
würde ich sagen, ist der Pfeil meist, entweder
habe ich den CSV irgendwo rübergeworfen bekommen,
dann lese ich die einfach über Pandas ein, oder
ich habe halt irgendwie für ein Spielprojekt
eine Web-URL, dann ziehe ich es mir direkt
von dort. Kann man ja
direkt auch mit Pandas, glaube ich.
Oder eigene Webdaten-Scrapes mit einer eigenen Datenbank oder
sowas. Oder von irgendwelchen Sendoren,
die Sachen in irgendeine Datenbank packen.
Eine Datenbank-Anbindung ist natürlich auch ein guter Punkt,
definitiv. Ist irgendwie in der
echten Welt gefühlt zu selten bei so
Notebooks. Irgendwie landen die Dateien dann doch immer
als Datei da, aber
genau, in dem Fall ist es ja relativ
tief im Code direkt versteckt, wie du es lädst.
Also wenn die Dateien da laden,
also wirklich big ist die Datei dann aber irgendwie noch nicht.
Nee, das hier ist alles
super, super small.
Man will in so einem Notebook auch kein Big Data
haben. Kann man
schon, aber... Kann man schon,
aber ich weiß nicht,
Also meine Präferenz an der Stelle ist
vor allem immer erstmal auch Latenz niedrig zu halten
und schnell mit Daten zu iterieren
und lieber erstmal ein kleines Sample ziehen
und erstmal viel Zeit mit diesem kleinen Sample
zu verbringen und dann
natürlich sehr bewusst wählen,
wie wähle ich jetzt mein Sample? Mache ich es wirklich
komplett random oder habe ich eine Zeitreihe? Muss ich jetzt gewisse
Aspekte dabei berücksichtigen?
Aber erstmal darauf eine Weile iterieren
und dann sich nachher
die Modelle auf dem Kompletten ausprobieren.
Machst du das anders?
Nee, nee, also genau. Subsamplen
ist halt auch, wenn die Daten groß sind, auf jeden Fall
eine super Strategie, um halt
schnell integrieren zu können.
Man kann aber, wenn man jetzt
tatsächlich irgendwie
größere Daten hat
und das auch nicht irgendwie vielleicht
kleiner machen will,
sich zum Beispiel von, dann importiert
man sich halt ein DataFrame nicht direkt von Pandas
sozusagen, sondern man importiert das halt von
Dask und
das Ding
verteilt dann automatisch
irgendwie die Sachen, die man da drauf tut, halt auf
zum Beispiel, das ist schon
ziemlich cool, das hat eine Anbindung an
Kubernetes und halt auch an die ganzen
Cloud-Geschichten wie so
Google Computer Engine und so
und da kann man dann halt einfach sagen,
okay, ich nehme mir jetzt mal so hier 100 Maschinen
und füge die dann
hinzu und man kann auch
während Sachen da drauf laufen, also
während man auf einem DataFrame halt irgendwas
gruppiert oder so, kann man sagen, okay, ach,
das geht mir zu langsam, nochmal 10 Maschinen dazu oder so
und dann wird das
automatisch halt irgendwie,
werden die mit reingenommen und
werden die Sachen halt irgendwie magisch schneller
und man sieht halt auch irgendwie sehr schön,
was da passiert.
Habe ich jetzt normalerweise kein Beispiel für, aber
das geht
durchaus auch und das
Benutzerinterface ist sozusagen da auch nicht anders,
als wenn man das jetzt auf einer lokalen Maschine macht,
sondern ist auch immer ein Notebook eigentlich.
Ich glaube, zu diesem Big-Data-Ding
müssen wir nochmal eine eigene Folge machen, so mit
Kubernetes, das ist ja nochmal spannend.
Genau, an der Stelle kann ich mal meine
Kubernetes-Folge droppen.
Ja, genau. Es gibt eine zu Docker
und eine zu Kubernetes.
Ja, und das Schöne ist halt,
dass die Sachen dann auch, wenn man sie nicht mehr braucht, wieder verschwinden.
Während halt, das ist ja auch etwas, was man sonst,
also gibt es dann vielleicht auch irgendwie,
in vielen Firmen gibt es dann halt so ein Cluster,
wo man Sachen machen kann, aber die Maschinen sind dann halt da
und man braucht
sie aber irgendwie nur, irgendwie, man braucht
eigentlich so alle halbe Stunde mal so wirklich volle Power
und, aber ansonsten braucht man das eigentlich nicht.
Und,
ja, das ist
glaube ich auch irgendwie, also das ist schon ein sehr
gutes Argument für diese ganzen Cloud-Geschichten,
weil man zahlt halt tatsächlich nur in dem
Moment, wo man halt die Rechenzeit
braucht.
Also du hast Dasks jetzt auch schon öfter
eingesetzt und das funktioniert für dich gut? Ja,
für mich funktioniert das eigentlich ziemlich gut. Ich habe damit nämlich praktisch
so noch keine Erfahrung. Ich habe nur irgendwie
im Hinterkopf, dass man dafür einiges umschreiben
muss, dass das nicht komplett kompatibel ist mit den Pandas.
Nicht komplett, aber also
das meiste geht eigentlich schon.
Es gibt also ein paar, ja natürlich,
es gibt natürlich immer so ein paar Ecken,
Ja, intern ist es halt so, dass der das auf eine Menge
Data Frames aufteilt und das
muss man halt irgendwie, die unterschiedlichen
Teile liegen halt auf unterschiedlichen Rechnern und
ja. Ansonsten, wenn man
Pandas einfach nur Multicore
betreiben möchte, was ja Pandas
per Default jetzt aktuell noch nicht bietet,
gibt es auch ein paar nette Projekte. Da gibt es
einmal Modin, das ehemalige
Pandas on Ray,
was quasi einfach über einen Import
einfach nur,
du änderst den Import und dann kannst du prinzipiell
Multicore für die allermeisten
Pandas-Operationen.
Wenn du sehr in die Nische kommst, geht's
da vielleicht dann irgendwann nicht mehr. Und was ich
heute kennengelernt habe und noch nicht ausprobiert habe, ist
Pandarallel.
Also so wie Panda
und dann Parallel
quasi. Und das unterstützt
halt eben auch quasi oder verspricht ein Multicore-Processing
für Pandas-Operationen.
Genau. Also bevor man vielleicht
wirklich auf den Cluster muss, ist das
noch eine gute Option.
Ja.
Ja, ja, ja.
Nee, das kann ich auch noch nicht. Also, ja.
Das ist interessant.
Genau, aber wir waren hier bei dem...
Wie bekomme ich eigentlich meine Daten?
Ich hatte einfach das entsprechende Notpunkt nicht aufgemacht.
Das heißt hier
Preparing Data.
Und das ist einfach
das Ding, also David Lewis,
das ist auch der, der den Mod-Up-Display gemacht hat
und auch überhaupt der, der das ganze Dataset
kuratiert hat, hat das halt irgendwie auf seiner
Seite liegen. Und
genau, dann
ja.
Was du auch benutzt an der Stelle im Notebook
ist ja die
die Path Library.
Ja.
Habe ich auch noch nicht so lange in Benutzung, aber ist eigentlich
mega cool. Ja, genau. Sag dazu doch nochmal zwei Sätze.
Ja, also
früher habe ich das auch mal mit
OS und ListDir und
OS Path Join und so gemacht, aber das ist alles
ganz schön, genau, glaube
ganz schön umständlich und
da
gibt es halt, ich weiß gar nicht,
seit wann das in der Standard-Library ist, aber
also es gibt da
ein Modul namens Parslip
und
da kann man
also
es geht hier los mit Pars.home
ist halt sozusagen dann ein Pfad
und das Ding
funktioniert im Grunde, wenn man jetzt Pfade erweitern möchte
oder so über so Operator
Overloading und
die haben dann halt einfach das
den Slash überladen und jetzt kann man
halt schreiben, irgendwie pass.home
gibt einem das Home-Verzeichnis, Slash
Data Slash TMP
und das ist natürlich viel kürzer, als würde man jetzt
schreiben, OS Pass Join
Klammer auf und dann gibt man eine Liste
oder macht irgendwie, ja irgendwie
muss dann einen absoluten Pfad angeben
oder man gibt irgendwie einen relativen Ankommer
irgendwie das nächste Ding und
das ist alles ganz schrecklich. Man kann sehr
schön Variablen quasi mit rein
betten und
man bekommt ja am Ende dann auch immer quasi ein Path-Objekt
wieder raus, was dann auch nochmal so
Operationen bietet, wie
okay, jetzt verrat mir von dem noch bitte die
Subdirectories oder
ja, halt Operationen dann immer direkt
auf dem Pfad ausführen. Ja, du kannst einfach
.exist machen oder sowas, das wäre auch ziemlich cool.
Genau. Ja, und ansonsten
hätte man immer os-path-exist und so verwenden
müssen und dann, also das ist
wirklich viel, viel angenehmer
damit zu arbeiten und
ja, also sonst hat man immer so, also ich hatte sonst
immer das Problem, dass irgendwie diese ganzen
Geschichten wurden immer relativ festlich und auch die
Zeilen wurden sehr lang und das Problem ist
irgendwie weg, seitdem ich Parslip verwende und das
ist schon mal echt ein Vorteil. Vielleicht um das
zu kurz zu zeigen, ich lösche jetzt einfach mal die Daten,
die ich hier bei mir lokal habe.
Data,
TMP.
Ja, genau.
Muss man echt mit aufpassen.
Ja, ja. Ja, wenn du willst so ein Git-Repo
löschen oder so, machst dann irgendwie Punkt-Slash
oder so und dann immer aus Versehen löscht man den Punkt
weg, dann machst du r-r-slash
und dann
ja, dann
immer alles als Super-User machen. Muss man hoffen,
dass nicht nur das Backup immer funktioniert hat,
sondern dass das Restore auch mal funktioniert
ist.
Ja, genau.
Ja, ich verwende
hier einfach so irgendwie
so Download-from-URL
Funktion, die benutzt
tqdm, um
das ist eine sehr schöne Library, mit der man
halt so Progress-Bars ganz gut hinkriegt.
Man kann eigentlich alle Iteratoren irgendwie damit rappen.
Ja, man braucht nur ein Iterat-Bar und genau.
Und das ist
auch sehr, sehr hübsch. Dann sieht man ungefähr, wo man ist.
Und ja,
jetzt hat das
irgendwie dieses Dataset halt irgendwie
in so ein Data-Verzeichnis geschrieben.
Dann, das ist halt auch irgendwie das
Tolle bei Python, dass man irgendwie einen Riesenhaufen
Funktionalität schon in der Standard-Library
mit drin hat. Ist eben auch
sowas drin wie tar-File, dass man halt
mit tar
Archiven halt direkt irgendwie umgehen
kann und dem kann man dann halt
einfach sagen, okay, pack doch mal alles aus
und
ja, dann
Dann haben wir einen Pickel gebaut oder du hast einen Pickel gebaut?
Genau, dann parse ich das Ganze auf und
pickel das wieder raus sozusagen,
damit ich dieses Parsen nicht jedes Mal machen muss. An der Stelle
hier ist es relativ egal, weil das ist so schnell.
Also Pickel speichert einfach das Python-Objekt in der
Binary einfach, also als Binärdaten
auf der Platte in einem Objekt und kann es genauso wieder einlesen.
Pickel ist auch ein Modul aus der Standard-
Bibliothek, genau, und es serialisiert
einfach Python-Objekte, beliebige
Python-Objekte einfach auf, ja, in ein
Format, das man dann halt auf die Platte schreiben
kann und hinterher auch wieder lesen kann.
Und es ist halt relativ schnell. Also
CSV, genau, ist oft
das, was man bekommt und das, was am
meisten verwendet wird und, ja,
Pandas Reals CSV-Funktion ist sicherlich so
eine der wichtigsten.
Aber das ist halt nicht schnell,
sondern das ist halt irgendwie so,
ja, sagen wir mal,
weiß ich nicht, vielleicht 50 MB
pro Sekunde oder so, was da so durchgeht,
kommt darauf an, wie komplex das CSV ist.
Und gut, für die meisten Datensätze
ist das vielleicht auch, oder was die meisten Leute so haben,
auch schnell genug, dass das halt irgendwie
nicht so furchtbar merkbare
Wartezeiten erzeugt, aber
wenn man jetzt so ein paar Gigabyte einlesen
will, dann ist das schon, dann muss man bei CSV schon
immer warten. Und was
ich da oft auch mache, ist halt die, wenn ich
CSVs habe, die
zuerst irgendwie in DataFrame einzulesen
mit ReadCSV und dann halt nochmal
irgendwie einen Pickle-File davon zu cachen.
weil das Pickel liest halt quasi mit Plattengeschwindigkeit, also da kann man auch so einen Gigabyte pro Sekunde lesen, dann dauert das halt, wenn man halt so einen Data-Frame, der halt irgendwie zwei, drei Gigabyte groß ist, liest, den man auf der Platte gepickelt hat, das dauert dann halt irgendwie auch nur so ein, zwei Sekunden und nicht mehr irgendwie anderthalb Minuten, wenn man das per CSV machen würde und ja, das ist halt auch ganz praktisch.
natürlich trotzdem Sinn, dass man irgendwie
eine CSV nimmt zum Teilen, weil
in so einem Pickel kann halt eben alles dran sein.
Das ist halt ein Binary-File und
dementsprechend wahrscheinlich nicht das Beste, um es irgendwie
im Internet als Austauschformat zu benutzen.
Das ist auf jeden Fall ein Sicherheitsrisiko,
weil wenn du da irgendwelche Sachen reinlädst
und da habe ich dann mein Code reingeschrieben.
Also wenn man das für einen eigenen Cache benutzt, ist es
okay, weil das zieht ja sonst keiner, aber stimmt.
So verteilen soll. Es gibt natürlich auch
Formate, die dafür gedacht sind, dass man irgendwie
da größere Datenmengen drin hat
und das halt auch
irgendwie teilt.
Ja, HDF5
oder NET,
wie heißt denn das noch, Nachfolger davon?
Keine Ahnung.
Oder halt eben sowas wie Parquet-Files
oder so. Aber
genau, CSV ist wahrscheinlich immer noch das
üblichste.
Ja, genau, ich habe das jetzt einfach
nochmal so gemacht, um das zu demonstrieren, wie das geht.
In dem Fall ist es halt völlig überflüssig, weil
eigentlich sind das so wenig Daten.
Das merkt man gar nicht.
Und dann hat man halt sozusagen die
Daten in einem Format, dass man
damit irgendwie arbeiten kann.
Ja, das können wir describen und reingucken.
Genau, genau, genau. Und dann halt dieses
Explorer-Notebook sozusagen ausführen.
Genau, und dann halt eben Daten visualisieren.
Wir haben vorher jetzt nicht so drüber geredet,
was für eine Bibliothek man dafür am besten benutzt.
Was ist denn euer Favorite?
C-Bone, meiner. Ja, würde ich auch.
C-Bone ist mal das, was ich normalerweise am Anfang
verwende.
Also Seaborn ist auf Matplotlib
drauf und macht es noch ein bisschen hübscher.
Ja. Genau, also finde ich
auch so zum Explorieren ziemlich gut
am Anfang, sobald meine, ich finde
man hat für so Grafik-Tools
ja ganz unterschiedliche Anforderungen. Am Anfang
willst du irgendwie einfach schnell erstmal
irgendwie ein bisschen was bekommen, dass es
irgendwie dir ein Gefühl dafür gibt.
Dann gibt es den Anwendungsfall, dass man
irgendwelche High-Resolution-Charts
machen möchte am Ende, um
sie zu präsentieren, die dann irgendwie,
wo dann wichtig ist, dass die Achsbeschriftung stimmt,
für irgendwie ein Meeting mit
einem Vorstand oder für eine Publikation
oder so. Und ich persönlich
habe dann immer nochmal so einen dritten Anwendungsfall,
wo ich so ein Diagramm benutze,
um damit irgendwie kontinuierlich zu arbeiten,
um irgendwelche Modellmöglichkeiten
zu visualisieren und die
dürfen dann gerne auch sehr mächtig und
ja, teils überladen sein und so weiter.
Und da finde ich Sibon zum Beispiel
jetzt irgendwie auch
zu kompliziert, um jetzt viele verschiedene
Sachen zu machen. Ich benutze Alt-R sehr gerne
zum Beispiel.
kann ich sehr empfehlen, das ist halt die Möglichkeit
dann quasi
Alter, Alter, Alter,
genau, baut
unten drunter auch Vega auf,
von der Visualisierungs-Engine
und folgt halt
diesem Paradigma von
Grammar of Graphics, wo man
halt quasi verschiedene Charts quasi
übereinander kombinieren kann,
relativ einfach und
genau, die benutze ich
jetzt seit ein paar Monaten sehr, sehr gerne.
Ja,
Kennt jemand von euch Buki?
Ja, ja, genau.
Habe ich zu meiner Welle mitgearbeitet, irgendwie bin ich da nie so richtig reingekommen, aber das kann auch an mir liegen.
Ja, Buki ist halt eine so, ist für interaktive Geschichten halt sehr schön, das ist halt eine der beiden Möglichkeiten, um Plots so ein bisschen interaktiver hinzubekommen, andere wäre Plotly.
Genau, die benutze ich dann lieber.
Ja, genau, ich auch. Aber Buki ist, glaube ich, auch nicht so schlecht. Also zum Beispiel die Visualisierung, was gerade auf dem Cluster passiert, bei Dask ist halt auch basiert auf Buki.
Und das ist auch relativ beeindruckend, was die damit
machen. Aber
ja,
nee, Plotly ist auch das, was ich ein bisschen
lieber finde. Hat jemand das mit DJI JS dann irgendwie noch
gemoddet irgendwie oder so? Könnte das sein?
Genau, ich glaube, das basiert unten drunter
auf die drei. Ja, ich meine auch.
Eben gerade, weil man das halt eben auch
dann auch auf Webseiten gut verwenden kann.
Und zum Beispiel, wenn man jetzt
irgendwie ein Dashboard hat,
dann
kann man halt relativ simpel
irgendwie mit Plotly halt auch die
Visualisierung, die man sonst normalerweise im Notebook
hätte oder so, halt einfach auf eine Webseite packen.
Und das ist natürlich auch sehr praktisch.
Genau.
Ja,
im D3 kann man aber auch
verwenden, man kann auch in Notebooks irgendwie
halt die Daten,
das kann man natürlich nicht mit unendlich vielen Daten tun, aber
man kann die halt auch in
JavaScript reinbringen.
Also man kann ja auch sozusagen
im Browser
via JavaScript Dinge im Notebook
ausführen, dann sagt man halt der Zelle
sozusagen, du bist jetzt eine JavaScript-Zelle
und
hier kommen die Daten von Python her, also
es gibt unterschiedliche Wege, wie man die Daten von Python
dann zu JavaScript irgendwie rüberschaufelt
und dann kann man da auch
mit D3 irgendwelche Dinge machen, wenn man zum Beispiel
so einen Forced
Graphen, wenn man so einen Graphen-Layout
hat, was man irgendwie darstellen möchte,
und man möchte jetzt an irgendeinem Knoten
ziehen und dann soll das so rumwobbeln oder so, gibt's
häufig, dann geht das natürlich mit
also ich wüsste jetzt nicht,
dass es da irgendwas in Python gibt, was man da nehmen
kann. Kann sein, dass es mittlerweile auch
mit Buket oder so geht, keine Ahnung.
Aber mit D3 geht das natürlich schön. Da gibt's
einige sehr, sehr witzige, interaktive
Visualisierungsgeschichten
und das kann man halt auch im Notebook verwenden.
Aber es ist so ein bisschen
fummelig, aber geht auch.
Habt ihr eine Lieblingslösung, um dann noch mal
so ein bisschen komplexer, wirklich so Dashboards zu
bauen, die für euch gut funktioniert?
Nee,
ich habe davon gehört, dass,
wie hieß das noch?
Das ist quasi die Variante, die da so
kommt, aber irgendwie
habe ich bisher nicht so wirklich
verwendet, weil ich ja also in der
Django-Welt
zu Hause bin und da habe ich das halt immer selber gebaut
bisher, also meistens mache ich halt irgendwelche
APIs, so Rest-APIs oder so,
hinter denen dann halt irgendein Modell ist und dann
meistens auch irgendwie ein View, der dann halt
ein Dashboard ist, was die Modelle
so getan haben über die Zeit.
Ja, und nee, aber
genau, eigentlich,
was man gerne hätte, wäre sowas wie Shiny
für R, aber ich glaube da...
Ja, Dash versucht genau das zu sein,
aber aktuell ist es das, finde ich, noch nicht.
Ja, ich bastel auch gerade an so einem
eigenen Visualisierungsding da rum, aber
das ist noch nicht soweit.
Ja.
Ja gut, haben wir unsere Daten
ausreichend visualisiert, würde ich sagen.
Genau. Wollen wir uns mal dem Modelltraining
widmen? Ja.
Okidoki.
So. Ja.
Wie trainieren
wir denn das Modell? Also wir haben
jetzt die ganzen Daten, wir haben den schon mal angeguckt,
wir wissen so ein bisschen was, du hast ja rausgeschrieben, was man
damit so alles anstehen könnte.
Warum, wieso, weshalb man irgendwelche Features braucht
und wir wissen natürlich, was wir vielleicht
rausbekommen wollen oder wissen wir es nicht.
Also hier dabei wissen wir, dass wir irgendwelche Zusammenhänge
finden möchten, aber. Genau und wir
haben ja jetzt in dem Fall ein
Super-West-Machine-Loading-Problem, weil
wir wissen halt eben für diese ganzen
Artikel, welche Tags
da hinten nachher dranstehen sollen. Also
wir versuchen ja quasi für einen Artikel
einen gewissen Tag zu identifizieren
und den
kennen wir. Wenn wir den nicht kennen würden,
dann wäre es quasi unbekannt, dann könnten wir
nur versuchen, irgendwie ähnliche Artikel
zusammen zu gruppieren,
aber dadurch, dass wir die kennen,
können wir jetzt halt eben versuchen,
einige von denen zu
nehmen, da so zu tun, als würden
wir sie nicht kennen, auf den anderen, wo wir sie
kennen, unser Modell zu trainieren und
dann eben quasi auf den, wo wir sie
quasi weggestrichen haben, eine Prognose zu machen und
es zu vergleichen. Das ist halt eben
wesentlich, was man tut mit einem Training
und eben so einem sogenannten Test-Set.
Genau.
Ja, also da gibt es zum Beispiel
das Notebook einfach nur
Linear-Model
und genau,
wenn man da sozusagen die ersten paar
Zeilen ausführt, sieht man auch schon nochmal
quasi, da hat man die Trainings- und
Testdaten
und das sind irgendwie 7.770
Trainingsdokumente,
3.000 Testdokumente
in dem vorgegebenen Split
und
ja, man hat ja jetzt
sozusagen die
Labels eher als Liste
von Klassen, in denen
also wenn ich mir jetzt
zum Beispiel Train Labels
mal anschaue,
Dann ist es halt eine Liste von Listen und jedes Element dieser Liste, der großen Liste außenrum, ist halt sozusagen eine Liste der Tags, die halt zu dem entsprechenden Dokument gehören.
Das ist halt in dem Fall jetzt so, weil wir jetzt eben so ein Multiclass-Multilabel-Problem haben. Also Multiclass besagt ja einfach nur, dass wir eben diese verschiedenen Klassen haben.
Also wenn wir nicht nur Ja oder Nein sagen, sondern hier halt eben diese 90 Texte, die es gibt, quasi haben, dann haben wir erstmal nur ein Multiclass-Problem.
Aber jetzt kann es halt auch sein, dass einer dieser Artikel eben mehreren von diesen Texten zugewiesen ist.
In dem Moment haben wir dann halt eben auch ein sogenanntes Multilabel-Problem.
Ja, und diesem Format kann ich halt die Labels in einem Modell nicht geben.
Also ich gebe dem Modell, was ich jetzt trainieren möchte, immer eben zwei Sachen.
Ich gebe dem einmal eine Feature, eine Matrix der, Feature-Matrix nennt sich das, also quasi eine Matrix, in der die Zeilen, die einzelnen Beobachtungen, Samples sind.
Und die Spalten sind halt die unterschiedlichen Features und die Labels oder Targets oder wie auch immer man das nennt, die irgendwie eine Information darüber enthalten, was denn jetzt sozusagen da richtig rauskommen sollte, wenn man sich diese Zeile anguckt.
und wenn man jetzt
ein Multilabel-Dataset hat, dann
man kann jetzt das nicht
sozusagen als diese Liste von Listen übergeben.
Listen wären sowieso schlecht,
weil Listen sind halt, brauchen in Python
relativ viel Hauptspeicher und
im Grunde, wenn man jetzt, also
bei Scikit-Learn ist es jedenfalls so, aber
eigentlich orientieren sich fast alle
anderen Maschinen-Learning-
Bibliotheken, die es so gibt, auch
an der entsprechenden API
von Scikit-Learn,
das ist die Estimator-API für Modelle eben,
da übergibt man immer Arrays, also NumPy-Arrays.
Und sowas wie Listen oder so kann man da nicht übergeben.
Das heißt, man muss erst mal das so in Format bringen,
dass man das überhaupt den entsprechenden Modellen übergeben kann.
Und für Multilabel ist es eben so,
dass das richtige Format dann halt ist,
ein NumPy-Array zu haben,
das halt auch wieder genauso viele Zeilen hat,
wie man in der Feature-Matrix hat
oder eben genauso viele Zeilen,
wie es eben Dokumente gibt,
die zum Training-Set gehören
und dann so viel spalten,
wie es Kategorien gibt oder Labels gibt,
in denen ein Dokument liegen kann
und sozusagen die,
für jede Spalte gibt es dann halt sozusagen,
also jede Spalte ist halt eine Kategorie
und wenn dann ein Null drin steht,
bedeutet das im Grunde, das Dokument liegt
nicht in dieser Kategorie oder hat dieses Tag eben nicht.
Wenn da 1 drin steht, dann heißt das,
okay, ja, das ist sozusagen die richtige
Kategorie für dieses Dokument.
Und
genau, dafür gibt es
aus dem Scikit-Learn
Pre-Processing-Modul halt ein Ding,
das nennt sich Multilabel-Binarizer
und dem gibt man einfach diese Liste von Listen
und dann spuckt das halt eine richtig formatierte
richtig formatiertes NumPy-Array aus.
Also das ist auch sowas, das muss man,
also diese ganze Transformation, das muss man nicht selber machen.
Da gibt es eigentlich für alle Geschichten, die man da so
haben kann, fertige
Lösungen schon.
Man kann sich, glaube ich, auch aussuchen, was da mit den Werten,
die da nicht reinpassen, irgendwie geschehen soll und sowas.
Ja,
bestimmt. Ich weiß jetzt gar nicht genau, was der
Multilabel-Bannerizer da sonst auch so macht.
Und langfristig ist es vor allem auch nicht sinnvoll,
sich das zu machen. Also am Anfang, wenn man das noch nie gemacht hat,
denkt man so, also man muss ja
schon auch einmal erstmal durchsteigen, wie das
überhaupt alles funktioniert mit diesen
Prozessen und den Modellen und so weiter
und dann denkt man, ich will doch eigentlich nur so ein Modell
benutzen, ich kann den ganzen Rest auch von Hand machen
und fängt damit gerne erstmal
an, weil man auch gerne ein bisschen programmiert
und nicht ewig Doku liest,
aber faktisch ist man halt letztendlich
dann doch viel schneller, wenn man sich das halt einmal
aneignet, wie denn diese Binarizer und so weiter
funktionieren.
Genau, ja.
Und dann
hat man quasi das gleiche Problem,
nur irgendwie ein bisschen anders.
auf der Feature-Matrix-Seite halt eben
auch, da man hatte erstmal Text.
Den kann man jetzt so in ein Modell
nicht reinwerfen, weil
ja, ist halt
also
letztlich ist eine Feature-Matrix eigentlich immer
sollten das eigentlich immer mehr oder weniger
Float-Werte sein, die da letztlich drin landen
und das ist halt ein NumPy-Array von
irgendwie Float-Geschichten und das ist Text
halt nicht. Man muss jetzt erstmal Text irgendwie
in Zahlen
irgendwie umwandeln und das ist halt
schon so eine Art, man nennt das halt
Feature-Extraktion.
Also man macht
sozusagen aus Text
irgendwie eine
Reihe von Features,
also Spalten in einer Feature-Matrix.
Und
so eine ganz
alte Standard-Methode,
wie man das halt tun kann, ist
einmal man repräsentiert
Text halt als Back of Words
nennt sich das. Das bedeutet,
man
wirft die Reihenfolgeinformation
der Wörter weg, was irgendwie schlimm klingt, aber
dann doch nicht so schlimm ist
und merkt sich
sozusagen, also
jede, man kann sich das ungefähr so
vorstellen, man hat jetzt, ja,
weiß nicht, ob das eine gute Idee ist,
zu sagen, man sollte sich das wie eine Excel-Tabelle vorstellen.
Wahrscheinlich eher nicht.
Das hat jemand schon niemals
gesehen. Also warum nicht?
Ja, es ist auch so ein bisschen so ähnlich wie bei den Labels.
Es ist auch so eine Art One-Hot-Encoding.
Man hat halt pro Spalte quasi, also man macht eine Spalte pro Wort.
Und wenn das Wort in dem Text vorkommt, dann macht man da eine Eins rein,
ansonsten macht man da eine Null rein in die Spalten.
Also man hat sozusagen so viele Spalten, wie es überhaupt unterschiedliche Worte
im gesamten Dokument-Korpus gibt, also über alle Dokumente drüber.
Wobei Back of Words macht doch schon auch die Anzahl gleich rein, oder?
Ja, ich weiß nicht, man kann auch die Anzahl direkt rein, also der einfachste Fall wäre, dass man einfach nur reinschreibt, ist es da oder nicht, binär.
Und genau, dann die nächste etwas, also das funktioniert auch schon erstaunlich gut, aber das hat halt auch diverse Probleme.
Unter anderem ist es halt so, dass längere Texte natürlich viel, bei denen steigt die Wahrscheinlichkeit, dass sie in allen möglichen Kategorien sind. Einfach deswegen, weil eine Menge Worte darin auftauchen, die halt in allen möglichen Kategorien auftauchen.
Oder derjenige, die den Nachrichtenbeitrag geschrieben hat, war SEO-Experte oder so.
Ja, ja, genau. Das wäre halt etwas, was man versuchen wollen würde zu verhindern, dass das halt so eine große Auswirkung hat, wenn da irgendwie eine lange Liste von vielen unterschiedlichen Wörtern drinsteht. Und das ist eine klassische Methode, die man da verwendet. Es kommt auch aus dem Information Retrieval Bereich, ist halt einmal zu zählen, wie oft ein Wort drin vorkommt.
Das braucht man halt vor allen Dingen deswegen, weil man damit mit der Information, wie oft kommt ein Wort in einem Text vor plus wie lang ist der Text, kann man halt die Frequenz ausrechnen, also sozusagen wie ist die Frequenz von dem Wort in dem Text. Das ist einfach nur wie oft kommt es vor, geteilt durch die Länge des Textes und das funktioniert dann schon besser, also da könnte man dann irgendwie einen Count Vectorizer nehmen, der würde halt dann zählen, nicht nur binär irgendwie einen großen Vektor bauen, in dem 1 und 0 drinstehen, je nachdem ob ein Wort drin ist.
kommt oder nicht. Das wäre dann schon die
Term-Frequency, oder? Ja, damit
hätte man erstmal nur die Counts und dann
ich weiß nicht, ob es noch einen, aber es gibt
keinen Vectorizer, der dann nur
Term-Frequenz macht, sondern dann
würde man direkt sowas nehmen wie TF-EDF
Vectorizer. Das Problem
bei der Term-Frequenz ist halt... Ich glaube,
das habt ihr alle ein bisschen abgehängt. Erstmal, was ist ein
Term-Vectorizer, was ist ein TF-ID?
Ja, also
im Grunde kann man eigentlich direkt mit dem TF-EDF
einsteigen.
Das ist halt sozusagen eine
Wenn man sich jetzt einen Vektor anguckt, wo nur drinsteht, ob ein Wort in einem Text vorkommt oder nicht, da stehen nur Einsen und Nullen drin, dann ist das halt schlecht.
Man möchte eigentlich ein anderes Gewicht darin stehen haben für Worte, weil manche Worte sind halt wichtiger oder charakteristischer für eine Kategorie als andere.
Also wenn ich die Kategorie Politik habe und da kommt irgendwie Parlament drin vor, dann ist das sozusagen dafür irgendwie eine aussagekräftigere Geschichte, als wenn jetzt das Wort das drin vorkommt oder so, was einfach in jedem Text vorkommt.
Und wenn man jetzt einfach nur ein 1 und ein 0 reinschreibt, dann würde das aber gleich behandelt irgendwie und das kann ja nicht so richtig sein. Und die Methode, mit der man das versucht, besser zu machen, ist uralt, ich glaube mittlerweile über 40 Jahre alt.
Ich glaube, Anfang der 70er oder so, dass
Karen Speck-Jones, glaube ich, irgendwie sich mal
überlegt. Ich weiß es nicht genau.
Eben, TF-EDF
vor allen Dingen für Suchmaschinen entwickelt.
Da möchte man das halt auch haben.
Man hat halt ein Query und möchte dazu
die relevantesten Dokumente irgendwie
rausfiltern.
Und
dieses Gewichtungs...
Dieses Gewichtungsding nennt sich halt
TF-EDF, also Term Frequency
mal
Inverse Document Frequency.
Term Frequency ist einfach nur die
Frequenz von dem Wort
in dem Text. Also das ist einfach nur Count,
wie oft kommt das Wort vor
in dem Text, geteilt durch, wie lang ist der Text,
mal
Logarithmus von
Ja, genau. Ich kann den an der Stelle auch nicht genau
geteilt durch, wie oft kommt
das Wort irgendwie
in allen Texten vor, sozusagen. Also
das Ding wird halt höher. Je höher, desto
seltener es ist. Also sozusagen
und man nimmt dann mal den Logarithmus,
damit es nicht ganz so schlimm wird, damit es halt so ein bisschen
ein bisschen flacher wird. Genau.
Weil man möchte halt auch nicht so total krasse
Unterschiede haben.
Es sollte sich so ein bisschen auswirken, aber
Genau. Das ist vom Prinzip her die Spezifität
des Wortes. Also
wie charakteristisch, wie
ist das ein Wort, was ständig vorkommt oder was halt eben
relativ selten vorkommt. Gewichtet
mit wie häufig kommt dieses Wort in dem Text vor.
Gibt halt ein ganz gutes Maß darüber.
Ja, ist das speziell
für diese Kategorie? Da oder nicht?
Da müsste man tatsächlich aber auch
eine Datenbank haben, der alle Wörter irgendwo
schon in gewisser Häufigkeit vorkommen, also zumindest
die, die so allgemein rausfallen.
Das ist natürlich so eine interessante Geschichte.
Wie kommt man an diese Gewichte
eigentlich ran? Und wenn man jetzt zum Beispiel
irgendwie das mit dem Cross-Validation und
Trennen in Trainings- und Test-Sets selber machen
würde, dann läuft man direkt in solche
Probleme rein. Wo berechnet man eigentlich
die Gewichte? Nimmt man alle Daten, die man hat, um die
auszurechnen?
Liegt man da nicht
die Tester, dann legt man nicht die
Informationen über das Test-Dataset schon
in das Training mit rein? Darf man das machen?
Ja, vor allem ist halt auch die Frage, wie gut sind deine
Tester? Sind die halt verteilt? Sind die homogen? Hast du da
eine schiefe Verteilung zum Beispiel oder sowas?
Das wäre dann auch irgendwie doof, weil
dann die Sachen, die schief drin liegen,
dann überprofessionell drin vertreten sind und du
vielleicht von den Sachen, die da
selten drin sind, nicht so viele. Genau, aber
dieses Problem, was du gerade sagst mit dem Training
und den Testarten, ist halt wirklich so ein klassisches.
Also du hast eigentlich nur zwei Optionen.
Entweder ich sage,
ich trainiere mein TF-IDF
auf allen meinen Daten, auch
vom Test-Set, dann habe ich halt alle Wörter
wirklich drin, die potenziell vorkommen können
nachher, aber dann habe ich halt eben
die Gefahr von Information Leakage,
also das heißt einfach, die Daten, die mir
eigentlich ja potenziell unbekannt sind, ich will ja nachher
auf Daten generalisieren, die
ich noch wirklich gar nicht kenne. Das Test-Set
ist ja nur eine Abstraktion, um irgendwie am Anfang
damit trainieren zu können.
Dann
tue ich so, als würde ich diese Informationen
eigentlich nicht kennen, aber in Wirklichkeit habe ich sie ja
doch irgendwie verarbeitet. Auf der anderen
Seite, wenn ich das nicht mache, passiert es mir halt, dass
ich im Testset irgendwelche Wörter habe, die ich
so gar nicht habe und dann habe ich dazu quasi
keinen IDF-Score, keinen validen.
Genau.
Und dann gibt es halt im Endeffekt, brauchst du halt
entweder ein sehr, sehr großes Datenset, dass du das
irgendwie selber machen kannst und
hast oder du kannst halt auch quasi
ein Datenset benutzen,
quasi, also für so eine Generalität
von Wörtern könntest du jetzt auch ein
öffentliches Datenset benutzen. Wikipedia
oder sowas. Genau, aber dann ist es halt nicht so spezifisch
aus deinem Anwendungsfall wahrscheinlich und
vielleicht ist das Wort
Enzyklopädie in der
Wikipedia selbst irgendwie viel häufiger
und viel unspezifischer,
als es bei dir jetzt im Wort vielleicht wäre.
Bei dir in deinen Daten vielleicht wäre.
Genau, also es ist auch
wieder so ein Abwägungsding, wie geht man damit um?
Ja.
Und ja, hier ist es zum Glück halt
irgendwie alles schon sozusagen
sind diese Geschichten vorgegeben und wir
ermitteln die Zahlen halt sozusagen nur auf den
Trainingsdaten und
fitten das halt nur auf den Testdaten, also
ja.
Fitten das nur auf den Trainingsdaten
und transformieren nur die Testdaten, also
sozusagen, ja.
Und es ist gerade spannend,
mir kommt gerade der Gedanke, ist es denn
tatsächlich dann so, dass nicht ein größeres
Daten-Set eine bessere Methode
verursacht, sondern tatsächlich das richtige
Daten-Set, was das Wichtige ist, als
die Menge an Daten?
Hört es sich gerade ein bisschen so an, also ich fette jetzt
intuitiv andersrum gedacht.
Das heißt, je mehr Testdaten
ich zur Verfügung hätte, auf denen ich meinen Algorithmus
testen kann, desto besser wird mein Ergebnis
und das, was gerade so ein bisschen durchgehen war,
dass Trainingsdaten sind
das, was dein Modell besser macht.
Ja, genau. Testdaten. Also das meinte ich
mit. Achso, gerade nochmal verwechselt wahrscheinlich.
Ja, okay, ja, genau. Ja, ja, je mehr
Trainingsdaten hast, desto besser, aber. Also weil dann würde man
Wikipedia zum Beispiel schon nehmen können, wenn das korrekt
gelabelt ist. Ja, dann würde das dazu
führen, selbst wenn da mehr
Aber Wikipedia ist ja jetzt für deinen Anwendungsfall
nicht gelabelt.
Wenn ich das gelabelt hätte, das war ja dann das.
Und das ist natürlich wahrscheinlich eben anders. Das ist halt das Problem.
Das ist anders verteilt als
das, was du irgendwie benutzen
willst. Also es ist dann aber doch halt nicht die Menge der Daten,
sondern die müssen halt schon matchen. Also ich brauche halt so den Scope
in die richtige Richtung schon. Das heißt, da kann halt
ein Riesenproblem daraus entstehen, wenn ich irgendwas
rausfinden will, was ich überhaupt nicht beschrieben habe in den Daten.
Dann ist Murks. Genau. Und ein Stück weit
muss man da jetzt auch nochmal unterscheiden. Wir haben ja gerade so ein bisschen
davon geredet, wie kriege ich denn die
Spezifizität von den Wörtern, da geht es ja darum,
wie überführe ich unseren Text
überhaupt erstmal in so eine Zahlenmatrix,
auf den wir dann basierend unser Training
ausführen können. Und um das
transformieren von den
Textdaten zu so einer Zahlenmatrix
zu machen, da kann ich vielleicht durchaus einen
größeren, globalen
Korpus nehmen, den ich da quasi für die Wörter
benutze zum Umwandeln.
Wenn ich dann allerdings wirklich mein Modell trainiere, dann
macht es natürlich überhaupt keinen Sinn, das irgendwie mit Wikipedia
Daten zu machen, wenn ich eigentlich dann
meine Art Artikel machen möchte,
weil das ist wahrscheinlich dann anders.
Ja.
Das gibt es auch noch in diversen
anderen,
also
das Problem kriegt man halt auch immer wieder, also wenn man jetzt
zum Beispiel
das jetzt TF-IDF ist
halt auch so ein klassisches Verfahren und
man kann es auch noch relativ leicht verstehen, insofern
ist das eigentlich, glaube ich, ein ganz guter Kandidat, um das
da zu benutzen, was man jetzt, wenn man
ein echtes Problem hätte, auf jeden Fall
wahrscheinlich auch noch machen wollen würde,
ist sogenannte
Word Embeddings. Also man würde halt
nicht nur, einfach nur
sozusagen pro Wort eine Dimension nehmen, sondern
man würde
ja, diese
Worte halt aus
jedem Wort mehrere Dimensionen erzeugen
und die sozusagen eingebettet in so ein
Ja, also was man
mit Word Embeddings macht, ist man
projiziert jedes Wort
in einen mehrdimensionalen Vektorraum
und dadurch, dass in diesem
Vektorraum alle Wörter irgendwie abgebildet sind,
kann ich jetzt mathematische Operationen darauf abbilden
und kann vor allem gucken, ob sich zwei
Wörter ungefähr im selben Bereich dieses Vektorraums
befinden
und damit kriege ich sowas hin,
wie das irgendwie Kirche und
Kathedrale plötzlich irgendwie vergleichbar
sind, obwohl die jetzt in einem normalen Text natürlich
jetzt irgendwie nichts gemein haben, das sind komplett unterschiedliche
Wörter, auch wenn sie halt eine ähnliche
inhaltliche Bedeutung haben
und das ist halt was, was halt eben mit
Wörter-Empendings vor irgendwie
drei, vier, fünf Jahren irgendwie
sehr, sehr populär wurde und
ja, inzwischen überall... Wie kommen die da an die gleiche
Stelle in diesem Vektorraum? Das habe ich jetzt noch nicht ganz...
Ja, das ist ein relativ kompliziertes Verfahren.
Ich muss da halt vorher quasi
trainieren und was ich vom Prinzip her mache, ist so eine Art
Color-Vertical-Filtering, glaube ich.
Aber ich glaube, das würde an der Stelle jetzt
zu weit führen. Also die würde man jetzt an der Stelle auch
vor allem nicht selber trainieren. Wenn, würdest du
die einfach laden aus dem Internet
und die quasi dann für jedes
der Wörter, die ich habe, quasi nachgucken, okay,
was ist denn diese Dimensionalität?
Weil um so ein Word-Embedding wirklich selber zu
trainieren, dann brauchst du zum einen sehr, sehr viele
Trainingsdaten und zum anderen halt auch wirklich viel
Rechenleistung für eine ganze Weile. Wo
würde ich solche Modelle runterladen?
Ja, es gibt zum Beispiel Word2Vec, das Modell von
Google, das kann man halt benutzen.
Das ist nett.
Ja, genau.
Ja, und es hängt aber dann,
ist halt die Frage, worauf das dann trainiert ist.
Also wahrscheinlich ist viel Wikipedia dabei, aber
bei Google ist bestimmt auch noch
diverse Webseiten mit drunter.
Ja, und das sind halt so ein paar Gigabyte,
die man dann so runterladen kann.
Und das verbessert halt,
wenn man jetzt eben statt TF-IDF,
oder normalerweise würde man nicht sagen statt,
sondern man nimmt die TF-IDF-Scores
natürlich auch mit dazu als Features
und nimmt dann aber auch die Vektoren
aus den Word-Embeddings für jedes Wort mit dazu,
dann verbessert das halt irgendwie
so ein Klassifikationsergebnis schon deutlich.
Also, aber
da hat man halt auch das Problem, man weiß halt
dann nicht, wenn man das jetzt einfach so, diese vortrainierten
Geschichten benutzt.
Ja, aber das ist ja schon wieder, das Nussen der Schwarmintelligenz,
das ist ja keine eigene Entwicklung in dem Sinne, sondern
man nutzt halt das, was irgendwie einer der Großen
dann schon angestellt hat mit seiner Hardware,
auf so einer ganzen Sprache, auf so einer ganzen
Grammatik und das Knowledge, das man dann irgendwie
Sagen wir mal so, wenn du genug Trainingsdaten hättest
und auch genug
Rechenkraft, um das dann halt alles auszurechnen, wäre es
wahrscheinlich besser, wenn du das auf deine eigenen Daten machst
und nicht die auf Wikipedia trainiert
nimmst. Wie viel, also hast du gesagt,
es waren bei der Reuters-Daten drin 20.000 irgendwie
Datensätze und das heißt, das war nicht historisch, weil
da sind sicher mehr.
Das ist ein bestimmter
Ausschnitt. Ich weiß nicht genau, nach welchen Kriterien
die jetzt ausgewählt worden sind, aber es sind ein paar
halt nur. Es gibt jetzt auch ein neueres Dataset
RCV1 und das heißt irgendwie, da sind dann
800.000 drin oder so.
Ja.
Genau, aber wie gesagt, an der Stelle
würde man halt in der Stelle jetzt eigentlich
erstmal diesen Back-of-Words-Ansatz
wählen oder halt vielleicht auch mit
Wörter-Embeddings, aber
genau, wir waren ja so ein bisschen
stehen geblieben bei den Label-Binarizern
und ich finde, man sollte
da nochmal so dieses Interface ein bisschen beschreiben,
was wir benutzen, weil das ist
sowas ganz generisch, was sich auch inzwischen alle
möglichen Bibliotheken auch außerhalb von
Circuit Learn eigentlich abgeschaut haben.
Da gibt es halt immer im Wesentlichen zwei Operationen.
Es gibt eben Fit
und Transform.
Und Fit nimmt quasi gewisse Daten und trainiert darauf jetzt mein Modell. Das heißt, dieser Multilabel-Binarizer guckt sich alle Daten an und berechnet für sich daraus, okay, aus jedem dieser Labels, die ich habe, muss ich folgende Zahl nachher rausgenerieren.
Und wenn ich das einmal gemacht habe, gefittet habe, dann kann ich danach halt diesen Label-Binarizer immer transformieren auf irgendeinen beliebigen Text.
Und der nimmt dann quasi diese selbe Abbildungsmatrix von Wörtern zu Zahlen und überträgt die auf den neuen Text.
Und ich kann natürlich auch beides gleichzeitig anwenden, dann mache ich halt eben so wie in dem Notebook hier Fit-Transform.
Dann fittet er erst darauf und dann transformiert er auch gleich die Eingangsdaten.
Genau. Ja, das ist jetzt halt inzwischen echt so ein super Standard-Interface geworden und das Schöne ist halt, dass ich im Grunde jedes Modell, wenn ich jetzt eine Klasse habe in Python, die diese Methoden implementiert, ich brauche vielleicht noch ein bisschen mehr, muss man nochmal gucken,
aber kann ich die halt auch in allen, dazu kommen wir dann später auch nochmal, Pipelines und so verwenden.
Und Modelle, die halt diese API implementieren, werden dadurch austauschbar.
Das ist halt auch total toll, weil ich dann halt sozusagen einfach nur über eine Liste von Modellen gehen kann
und dann werfe ich die da rein und gucke, ob hinterher was rauskommt.
Und ich muss das halt nicht für jedes Modell irgendwie einzeln nochmal anpassen.
Ja, genau. Was wollten wir machen? Wir wollten Texte vektorisieren.
Ja, jetzt haben wir eigentlich unsere Zahlmatrix. Eigentlich sind wir jetzt bereit, um darauf Modelle langsam zu trainieren, oder?
Genau, ich habe hier einen TF-EDF-Vectorizer sozusagen instanziiert, dann den gefittet auf den Trainingsdaten.
Dem kann man auch noch alle möglichen Optionen mitgeben, was ich jetzt hier nicht getan habe, aber man kann eben noch sagen, wie er trainieren soll.
Ein gewisses Top-Wörter-Rauswerfen, was man auf jeden Fall machen würde, aber ja.
Ja, genau. Aber halt irgendwie, dass man irgendwie smoothen soll oder man kann, welche Norm, man kann alles Mögliche da angeben.
Und genau, den habe ich im Trainingsdaten gefüttert und ich benutze jetzt die Transform-Methode, um damit sozusagen die Texte aus den Trainingsdaten und aus den Testdaten in so Feature-Matrizen zu verwandeln.
Das sind dann hinterher
das ist auch nochmal so eine kleine Spezialität.
Das ist jetzt natürlich
das, was dabei rauskommt, hat relativ
die Matrix, die da rauskommt. Normalerweise würde man jetzt denken, da kommt einfach nur ein NumPy
Array raus, irgendwie Zahlen so viel wie es Dokumente gibt,
Spalten so viele wie es Wörter gibt. Das Problem dabei ist natürlich so ein bisschen
die allermeisten
Werte in dieser Tabelle sind null, weil
ja die allermeisten Worte halt nicht
in allen Texten vorkommen, sondern
ja,
also
pro Text habe ich halt eine Teilmenge der Worte, die
überhaupt vorkommen, aber eben nicht alle
und die allermeisten kommen halt
nicht in den Text vor.
Je mehr Nullen, je mehr Texte man hat?
Ja. Je mehr unterschiedliche Wörter
man hat. Ja, genau, richtig.
Ja, genau, es ist ja dann mehr wahrscheinlicher, dass du mehr Texte hast,
dass du mehr unterschiedliche Wörter hast.
Ja, wobei, also genau, wenn ich dann Texte habe, die alle sehr, sehr ähnlich sind, habe ich dann natürlich auch viele Einser vom Prinzip her. Das heißt einfach quasi wie sparse ist meine Matrix das Wort dafür.
Genau, sparse.
Die Daten sind halt sehr sparse
und das ist halt
ein Problem oder
ist halt sehr verschwenderisch, was Hauptsprecher angeht,
wenn man tatsächlich die Werte speichern würde.
Und es gibt dann so
aus dem SciPy
Modul
irgendwie gibt es dann Klassen, die sich halt
mit sparse, mit dem
Speichern von sparsen Matrizen irgendwie
beschäftigen.
Und
ja, da
der Trick ist im Grunde, dass man halt die ganzen Nullen
einfach nicht speichert. Was man sagt,
man speichert nur, an welchen
Stellen irgendwie Zahlen sind. Alles andere
ist halt
defaultmäßig null und muss man halt auch nicht speichern.
Und man kann sich das auch im Grunde so
vorstellen, also die interessante Operation,
die man jetzt auf sowas ausführt, zum Beispiel wenn man jetzt
eine Suchmaschine hat, würde man irgendwie
eine Cosinus-Distanz
ausrechnen zwischen einem Dokument
und einer Query.
Das heißt sozusagen einfach nur das Scalar-Produkt.
man würde den Query in Vektor verwandeln,
ein Dokument
in Vektor verwandeln und dann bildet man
einfach das Skalarprodukt zwischen den beiden
und dafür muss man ja sozusagen nur
die Teile miteinander multiplizieren,
die nicht Null sind, weil
die anderen sind alle EU-Null,
das wird aufsummiert, also
es ist einfach weg und
daher ist das natürlich toll, wenn man eine Struktur
hat, wo sowieso nur die Teile gespeichert
sind, die nicht Null sind und dann
muss man nicht so viel speichern und
hat trotzdem alles, was man braucht,
um halt damit rechnen zu können.
Ja, das
funktioniert auch
tatsächlich irgendwie als Eingabe
für diverse Modelle, aber halt
auch nicht für alle. Also da muss man dann halt auch wieder
aufpassen, das ist so ein bisschen blöd. Also es gibt
halt Modelle, die gut damit klarkommen, wenn man
den Feature-Matrizen
gibt, die sparse sind.
Es gibt auch welche, bei denen das nicht geht.
Und da muss man halt unter Bestimmten auch nochmal ein bisschen was
machen, was man
üblicherweise tun würde, also was ein Modell,
was immer gut funktioniert, was man
normalerweise immer braucht, aber was halt nicht
klarkommt mit sparsen Daten, wäre halt sowas wie
XGBoost zum Beispiel,
so ein
Decision Tree Modell.
XGBoost?
XGBoost, für Extreme
Gradient Boosting.
Ah, okay.
Und
da
macht man das eigentlich, oder
für alle, ich meine auch, was auch nicht mit
Neuronalen Netze kommen auch normalerweise nicht mit Spasen
Eingaben klar.
Was man da vorher macht, ist, man reduziert
die Dimensionen. Also wenn
das, ich weiß jetzt nicht, was das,
was ich glaube auch irgendwas, 25.000 Wörter gibt es da drin
oder so.
Wenn man jetzt aus diesen 25.000 Dimensionen
etwas machen möchte, was
dense, was dicht ist, dann
projiziert man halt das aus dem
aus diesem hochdimensionalen
Vektorraum halt runter auf irgendwas
mit 200 Dimensionen oder 300 oder so.
Und dafür gibt es dann unterschiedliche Verfahren, aber das, was man
normalerweise immer verwendet, ist Singular Value
Decomposition
und dann auch die Truncated-Variante
davon, also Truncated Singular Value
Decomposition. Das ist halt immer so das Ding,
was man dann nutzt und projiziert, um
die Sachen runter zu projizieren.
Es muss einem halt irgendwie mal klar sein, wenn man halt so einen
Korpus hat und dann hat man jetzt in
seinen Daten irgendwie
eine Million Dokumente und
diese Millionen Dokumente haben halt irgendwie
30.000 unterschiedliche
Wörter, dann habe ich halt nachher prinzipiell
erstmal eine Matrix, wenn ich jetzt nichts davon wegwerfe
oder so, von
1.000.000 mal 30.000
und das kann natürlich dann beliebig
mit größeren Datensätzen noch größer
werden und der Gedanke
an der Stelle ist einfach, mit
so einer Dimensionalitätsreduktion
verliere ich theoretisch Informationen,
aber
es gibt halt viele Dimensionen
oder viele dieser Spalten, die sich sehr, sehr ähnlich
verhalten werden. Also
der Optimalfall für eine
Dimensionalitätsreduktion ist, dass zwei
Spalten oder zwei Zahlen
quasi komplett gleich sind,
weil dann verliere ich quasi keine
Informationen darüber, wenn ich einfach sage, dass
diese beiden Spalten, wenn ich
die beiden quasi zusammenlege.
Und wenn zwei
Spalten sehr, sehr stark korreliert
sind, dann
verliere ich auch nicht viele Informationen in dem Moment,
wo ich die beiden irgendwie zusammen auf 1 abbilde.
Also die, wenn die Spalten ja Wörter
sind, dann ist ja gleiche Wörter relativ
unwahrscheinlich, aber dann muss man tatsächlich diese
Kombination finden aus der Grammatik, die
wir eben hatten, halt das Modul laden dann, was war das?
Word Conf, irgendwas
von Google. Achso,
WordSpec, aber. WordSpec, genau.
Das könnte man ja nehmen als Information, um irgendwie
so eine Kovarianz in den Wörtern festzustellen
und die halt dann so zu gruppieren, dass
die halt dann zusammenfassen. Theoretisch kann es aber
auch vorher der Fall sein. Also mal angenommen, ich habe
zum Beispiel einen Namen drin, mit einem Vornamen
und einem Nachnamen und der kommt halt tatsächlich nur in einem
der Texte vor. Dann habe ich da
natürlich zwei Spalten für.
Einmal der Vorname, einmal der
Nachnamen und die haben genau einmal eine 1 für ein Dokument,
dann sind
diese beiden Spalten natürlich perfekt korreliert.
Und dann können die natürlich auch beliebig
von der Dimensionalität
auf einer projiziert werden.
Also würde man da nur einen von beiden
wegschmeißen oder sagt man einfach, ja, das ist eigentlich nur
in einem Dokument, ist eigentlich egal?
Letztendlich machst du das selber gar nicht, sondern der Algorithmus
überlegt sich einfach selbstständig, wo
verliere ich am wenigsten Informationen, indem ich die
runtergebe und was ich von außen nur sage, ist
auf welche Zieldimension will ich gerne?
Also dass da einfach 300 reicht.
Genau. Und der projiziert es für dich runter,
aber das ist die Logik, die dahinter steht.
Genau.
Und dabei geht praktisch
nur sehr wenig Information verloren.
Das funktioniert halt ziemlich gut.
Genau.
Also das ist halt auch so. Aber das ist halt irgendwie
dann doch so eine Geschichte, wo man
nicht immer irgendwie alles gleich
verwenden kann. Weil es gibt halt Modelle, die kommen halt
mit Spasen-Daten klar und manche halt nicht.
Ja.
Genau, genau, genau.
Gut, aber jetzt wollen wir mal ein Modell trainieren.
Ja, ein Modell trainieren, genau. Dafür gibt es dann halt auch
irgendwie einmal
eine Abstraktionsgeschichte, um halt dieses
Multilevel-Ding
Es gibt einige Modelle, die automatisch Multiclass können,
aber Multilabel, da braucht man halt noch so einen Wrapper außenrum.
Und eine einfache Art, wie man halt sozusagen aus einem Modell,
also was alle Modelle können, ist halt binäre Klassifikation.
Das ist halt auch das Einfachste.
Und man kann jetzt natürlich aus binärer Klassifikation
quasi automatisch eine Multilabel-Klassifikation machen,
indem man einfach für jede Klasse eins gegen alle anderen ein Modell trainiert,
was dann binäre Klassifikation macht.
Und dann, das muss man aber auch nicht selber machen, sondern da gibt es dann halt schon ein vorgefertigtes Ding aus Scikit-Learn Multiclass, das Ding heißt One Versus REST Classifier und der tut das dann und man kriegt das gar nicht mit, sondern steckt einfach nur das eigene Modell, was man verwenden möchte, da rein und dann passiert das automatisch.
Und dann gibt es halt noch aus dem Scikit-Learns-Metrics-Modul eine Classification-Report-Funktion, die einem dann so eine ganz schöne Übersicht gibt, was dann jetzt passiert ist mit den Testdaten, wenn man die dann nochmal durch das trainierte Modell durchgibt.
Und ja, so eines der ersten Modelle, die man immer so ausprobieren würde, denke ich mal, ist so Logistic Regression. Das ist ein Klassifikationsmodell. Das heißt bloß Regression, das ist nicht so.
Ja, das ist auch total, habe ich am Anfang auch lange Zeit verwirrt, dass eine Methode, die Regression im Namen hat, in Wirklichkeit eine Klassifikation ist, aber das ist halt der Algorithmus, der im Endeffekt dahinter steht, da sollte man nicht zu tief drauf reingehen.
Genau, genau.
Und das ist halt so ein Standardding.
Das ist immer etwas, was man immer am Anfang verwendet,
weil das ist halt, funktioniert auf
vielen Sachen ganz gut. Es ist sehr schnell.
Ja.
Daher
man kann gut verstehen, was es macht.
Daher
man würde gar nicht mit so totalen
Fancy-Verfahren anfangen, sondern
eher so mit simplen und dann erstmal gucken, was da überhaupt
passiert. Und dann kann man ja immer
noch kompliziertere Dinge machen, wenn das halt nicht reicht.
Ja.
Genau, Model ist jetzt sozusagen einfach nur Run-versus-Rest-Classifier und da das Logistic Regression-Modell reingesteckt und dann einmal Fit auf, um das Modell zu trainieren und dann einmal Predict, um die Voraussagen zu bekommen für die Testdokumente.
Ich finde, das ist ein sehr gutes Beispiel für, wie so ein echtes Welt-Data-Science-Projekt aussieht, weil wenn man jetzt irgendwie sagt, also wenn man von außen dann naiv drauf schaut und denkt sich so, so schwer kann es doch nicht sein, du machst irgendwie Hello World, irgendwie Regression oder Klassifikation, dann findest du halt einfach, irgendwo werden Daten vorgefertigt, richtig geladen und dann nimmst du dieses Modell, importierst es, machst ein Fit, machst ein Predict und hast dein Ergebnis.
Also das eigentliche Modell trainieren ist kein Problem, aber wir reden jetzt hier schon eine Stunde, eine halbe oder so darüber, wie wir da hinkommen und das ist die Schwierigkeit bei dem Ganzen, dass es halt in Wirklichkeit dann doch nicht so trivial ist, dass man halt eben irgendwie Multiclass oder Multilabel hat oder sehr große Matrizen oder Dimensionalitäten reduzieren muss und Features ingenieren und genau, dieser Weg dahin ist das Komplizierte.
Ja, und dann haben wir aber jetzt eine Prognose raus und müssen uns überlegen, wie gehen wir mit der um, wo es auch wieder anfängt komplizierter zu werden.
Genau, es wäre wahrscheinlich ein bisschen unübersichtlich beim Classification Report das halt über alle 90 Kategorien zu machen, deswegen habe ich jetzt einfach mal die Top 10 Kategorien genommen. Das ist auch so, wenn man sich dafür interessiert, gibt es halt die Doktorarbeit von Thorsten Joachim, die ist glaube ich eines der meist zitierten Papers sozusagen im Textklassifikationsbereich, irgendwie ist es anderthalb tausend Mal zitiert worden oder so.
Der hat sich damit zuerst 1998 irgendwie beschäftigt und das Ding gibt es als Buch oder man kann halt irgendwie zu so einer Schattenbibliothek gehen, da gibt es das auch.
Und da kann man sich halt auch, da guckt man sich auch mal die Top 10 Kategorien an und kann das einfach mal vergleichen, die Zahlen, die er da rauskriegt mit dem, was man da selber irgendwie dann sozusagen da als Ergebnis hat und ja, sieht eigentlich alles ganz gut aus.
Genau, was man da in Spalten in dem Klassifikationsreport drinstehen hat, sind halt einmal die Namen der Kategorien, dann Precision, Recall, F1-Score und ja, wie viele Beispiele es gab.
Genau, und das ist was, womit man den Umgang auf jeden Fall wirklich lernen muss.
Da hat mich ganz am Anfang, als ich angefangen habe mit Data Science, konnte ich mit den ganzen Zahlen auch nicht wirklich was anfangen.
Was man ja immer im Wesentlichen hat, ist, man hat prinzipiell vier Fälle.
Ich kann einfach, bei einer binären Klassifikation, was so das Einfachste ist,
da kann es sein, dass ein Ergebnis quasi wahr ist.
Und ich habe auch gesagt, dass es wahr ist, das ist das Einfachste.
Dann habe ich ein True Positive.
Es kann auch sein, dass es falsch ist.
Und ich habe aber gesagt, dass es wahr ist.
Dann habe ich ein false positive.
Ich kann sein, dass ich richtig gelegen habe
und es negativ ist.
Dann habe ich ein true negative.
Oder es kann negativ sein
und ich lag auch noch daneben.
Dann habe ich ein false negative.
So, und jetzt gibt es quasi Kombinationen
von diesen Feldern für Precision und Recall.
Und die inhaltliche Bedeutung davon ist vom Prinzip,
also man kann sich das auch in den Formeln anschauen,
ich finde das hilft aber weniger,
als einfach zu sagen, die Precision ist, wie viele von meinen Daten,
wo ich gesagt habe, dass sie wahr sind, sind auch wirklich wahr.
Und Recall ist, wie viele von denen, die prinzipiell wahr sind,
die ich quasi prognostizieren wollte, habe ich denn auch erwischt.
Das sind so die beiden.
Und dazwischen habe ich so einen Trade-off.
Und da muss ich halt abwägen.
Und das ist, was der F1-Score im Endeffekt macht.
der tut nämlich einfach quasi
die beiden so verrechnen,
dass nachher ein Zahlenwert rauskommt
zwischen 0 und 1 und wenn ich quasi die
1 habe, dann habe ich quasi sowohl Precision
als auch Recall perfekt bei 1
und wenn ich bei 0 habe, lag ich bei beiden
komplett falsch und der gibt so
eine Art Bonus, durch das wie er
berechnet wird, dass ich quasi die beiden
auch relativ ausgewogen habe. Also wenn ich
da quasi die Precision auf 1 habe, aber den
Recall bei 0, dann bin ich da nachher trotzdem
bei einer 0.
Das sind die drei wesentlichen
Metriken dieses Reports und dann gibt es halt
eben noch den Support, der einfach quasi
aussagt, okay, wie häufig ist denn der Fall
überhaupt, um mir so eine Absolut-Skala
zu geben, weil diese Zahlenwerte sind jetzt
natürlich alles relativ, wenn ich nur ein Beispiel
habe und das habe ich richtig klassifiziert, dann
habe ich einen F1-Score von 1 und alles ist super,
aber wenn es halt nur ein Beispiel war, dann hilft
mir das real im echten Leben natürlich wenig.
Deswegen ist dieser F1-Score, äh, dieser
Support dann so eine Matrix für, wie
wichtig ist es denn in absoluten Zahlen.
Ja, ja, ja, ne, finde ich
genau, super erklärt.
also so F1-Core finde ich
es mal, also man braucht das
sowas in der Art häufig, wenn man jetzt
zum Beispiel Modelle ranken möchte, man möchte
jetzt das beste Modell haben, wo man jetzt Precision
und Recall-Werte hat, dann ist es halt blöd, man kann halt nicht so
richtig gut nach, wenn man jetzt 2-Werte
hat, irgendwie, wie will man dann sortieren?
Daher
muss man das halt irgendwie
in einen Wert
zusammenfassen und dann nimmt man halt einen F1-Wert,
man kann das auch irgendwie anders ausrechnen, aber
das ist halt das, was meistens gemacht wird.
Ja, und einer der Gründe, weshalb man da sowas überhaupt machen muss, man kann sich jetzt nicht einfach vorstellen, warum immer nicht einfach Accuracy oder so, ja, das geht halt nicht so gut, also Accuracy funktioniert halt dann gut, wenn alle Klassen irgendwie die gleiche Anzahl von Beispielen haben und so, dann geht das vielleicht, aber das wird auch schwer sich vorzustellen, wenn man jetzt irgendwie was anderes hat als nur zwei.
Aber es hat auch sonst irgendwie blöde Eigenschaften. Also wenn man sich jetzt nochmal das Beispiel mit dem Spam und Nicht-Spam vorstellt. Also bei dir scheint das ja nicht so zu sein. Du kriegst ja auch nicht so viel Spam, aber bei mir mag das schon so mit dem, was andere Leute auch beobachten, übereinstimmen, dass halt 99% der Mails, die ich bekomme, sind halt Spam.
was dann noch darunter fällt vielleicht.
Ja.
Also ich habe sozusagen eine sehr ungleiche
Verteilung der
der Klassen und wenn ich
jetzt sozusagen Accuracy
nehme als Maß oder als Metrik dafür,
wie gut ist das jetzt,
dann könnte ich jetzt einen Classifier bauen, der sagt
irgendwie immer, es ist Spam.
Und der hätte dann Accuracy von 99%.
Klingt doch super, voll gut. Aber der macht
ja eigentlich gar nichts oder macht auf jeden Fall
nichts Sinnvolles, weil hinterher kriege ich
halt gar keine Mail mehr und
diese Irrtumswahrscheinlichkeit
ist tatsächlich, glaube ich, relativ relevant, auch für den
Untersuchungsgegenstand, den man hat. Ich weiß nicht, ob wir
Alpha- oder Beta-Fehler nennt man das, glaube ich, so in der klassischen
Statistik. Ja, oder viele Erste Ordnung
oder Zweite Ordnung oder sowas.
Und das ist ja schon
sehr entscheidend, also was für Untersuchungsgegenstand
man hat. Manchmal ist 5% Abweichung
dann ganz okay, weil 95 Treffer Wahrscheinlichkeit ist
ausreichend irgendwie. Vielleicht bei Hund, Katze
unterscheiden, vielleicht auch nicht ganz so wichtig. Aber
bei anderen Dingen ist halt dann das 1%,
1% zu viel. Also gerade, wenn man so
Häufigkeitsverteilung hat, wie es kommt nur
ein Prozent der Fälle sowas raus
und dann falsch liegt es vielleicht nicht so super.
Ja, aber eben bei Accuracy würde man
halt gar nicht sehen, dass man da ein riesen Problem hat, wenn man
die 99 Prozent sieht.
Aber vielleicht muss man dann
einen negativen Fehler nehmen, dann muss man vielleicht nicht versuchen
einen Spam zu tracken, sondern eine richtige Mail.
Aber wenn man jetzt Precision Recall nehmen würde,
würde man sagen, okay, dann sieht man es halt sofort, weil
Precision wäre null.
Andersrum ist halt tatsächlich dieses Ding,
wenn du halt den Spam immer versuchst zu tracken
und er sagt immer Spam, dann müsstest du halt
das umdrehen, musst du sagen, hey, ich möchte richtigen Text tracken
und dann hättest du halt vielleicht eine bessere Erkennungsrate
oder so, ja, weil du das halt
nicht wegschmeißen würdest durch die Fehlerwahrscheinlichkeit.
Ja,
auf jeden Fall, also
für so im allgemeinen
Fall, wenn man viele Klassen oder
Labels hat und unterschiedlich
verteilte
Klassen, dann sind halt
Precision Recall halt ein viel besseres Maß
als irgendwie
Accuracy. Daher nimmt man das als, es gibt
auch noch andere Metriken, die man irgendwie benutzen
kann, aber das ist schon irgendwie so
das verbreitetste,
denke ich mal. Das kommt halt auch so aus
diesem Information Retrieval-Bereich.
Genau, und diese Metriken
sind halt so ein bisschen,
ja, man muss damit halt lernen umzugehen.
Jedes Problem ist ein bisschen anders. Also,
wir haben jetzt hier, wie gesagt, so eine Multilabel-Klassifikation.
Wenn ich jetzt
eine Regression habe, habe ich plötzlich wieder komplett
andere Metriken, die ich da benutze.
Ich setze mich gerade das erste
Mal in meinem Leben so ein bisschen mit Recommender-Engines
auseinander, wo man quasi gleich ganze
Listen immer zurückgibt
und quasi sagt, okay, ich glaube
das Erste ist das Wahrscheinlichste, das
Zweite ist das Zweitwahrscheinlichste und so weiter, dann braucht man
auch wieder ganz andere Metriken. Also
genau, gerade in diesem Metrikenfeld
wird es dann interessant, in welchem
Bereich von Data Science man sich begibt
und was man gerne machen möchte.
Ja, da kann man
viel Zeit reinstecken. Das ist auch wichtig.
Genau, und
das ist halt, das ist teilweise auch sehr schwer zu erklären,
also wenn man dann irgendwie
ja, dass dann halt
auch Ergebnisse irgendwie
reportet,
ist manchmal nicht so einfach zu erklären,
warum man das jetzt so macht und nicht irgendwie
einen einfachen einzelnen Wert nimmt oder so.
Ja,
muss man halt gut sein im
Erklären, keine Ahnung.
Genau, beim Wesentlichen sind wir jetzt die
Basispipeline ja einmal durch. Also wir haben unsere Daten
geladen, wir haben sie uns ein bisschen
angeschaut, wir haben
darauf jetzt zwar kein großes
Feature-Engineering gemacht, also wir haben jetzt nicht versucht,
irgendwie noch zusätzlich sowas
dran zu spielen, wie zum Beispiel die Textlänge, die
noch nicht vorher in den Daten so mit drin war und auf
denen mitzulernen oder sowas man machen könnte, aber wir
haben zumindest den ganzen Text umgewandelt
in eine Zahlenmatrix und die reduziert
und darauf jetzt halt eben ein Modell
berechnet und können sagen,
wie gut dieses Modell ist.
Wenn man jetzt
einfach da eine Spalte dran hängt, geht
das einfach so? Also wenn man das schon so ein bisschen modelliert hat,
dass man dann sagt, hey, ich hänge jetzt sowas dran
wie die Länge.
Ähm, genau, also hier erzeuge ich ja sozusagen die Feature-Matrizen direkt aus dem Text, aber wenn wir uns jetzt zum Beispiel mal angucken, na, ich glaube, das Grid-Search-Ding macht das dann halt auch schon so ein bisschen anders.
Was man da normalerweise dann hat, ist halt eben nicht so eine naive Geschichte, wo man das einfach so erzeugt, sondern man hat halt eine, die Feature Matrix wird erzeugt durch, oder überhaupt das komplette Ding ist halt eine Pipeline, ist halt auch eine Klasse aus Cycle Learn und die kombiniert im Grunde viele Schritte sozusagen zu einem Ding, das sich insgesamt wieder so verhält wie ein Modell.
Also zum Beispiel jetzt bei dieser, in diesem Notebook ist es halt so, da sind die Schritte, aus denen die Pipeline besteht, halt, ja, das ist eine zweite Geschichte, die ich irgendwie da noch einführen muss.
Das Ding nennt sich Feature Union und man kann sich das im Grunde so vorstellen, also Feature Union macht genau das, was du jetzt vorhattest, einfach irgendwie Dinge an die Feature Matrix spalten, an die Feature Matrix dran bauen, sozusagen.
Ich habe unterschiedliche Spalten und ich möchte die zusammen kombinieren zu einer Feature-Matrix. Dann nehme ich Feature-Union, das fügt die Spalten zusammen und die Pipeline integriert die ganzen Schritte, die nötig sind, um irgendwas zu tun.
halt, also
Feature-Extraktionen,
unterschiedliche Arten von Feature-Extraktionen
und halt am Schluss irgendwie ein Modell
trainieren und
ja, auf den Testdaten
halt Predictions machen.
Sodass das Ganze sich wieder als ein
Modell irgendwie benutzen lässt.
Und was das hier tut, ist
ja, ich übergib
der Feature-Union
halt irgendwie eine Liste von Transformern,
die irgendwie Dinge tun und
man kann die jetzt ineinander
wieder verschachteln. Das ist jetzt wieder eine Pipeline.
Und die Pipeline,
die da drin ist, die macht halt
der erste Schritt, der nimmt
eine Spalte aus dem
DataFrame, und zwar den Titel
und
macht dann eben so etwas wie
Textstatistiken
drauf. Also sowas wie, wie lang ist der Titel?
Wie viele Buchstaben sind
da drin? Wie viele Wörter sind da drin?
oder sowas, ich weiß jetzt gar nicht mehr genau, was das tut.
Und dann skaliert er halt diese,
weil bei TF-EDF ist das halt
automatisch drin, das ist halt
irgendwie
sozusagen
skaliert ist auf
einen Intervall zwischen, weiß ich nicht,
0 und 1 und
normalisiert, sodass es halt
irgendwie alle Vektoren, die Länge 1 haben.
Bei den Textstatistiken
ist das natürlich nicht, da kommt dann halt so eine Zahl raus,
wie, der Titel hat jetzt
25 Buchstaben und
da, was man eigentlich immer
macht, wenn man jetzt solche Zahlen hat, ist
das so zu skalieren,
dass alle Features irgendwie
immer zwischen
minus 1 und 1
oder zwischen 0 und 1 sind
und auch eine Standardabweichung
von 1 haben.
Das hängt halt auch mal viel damit zusammen, was für ein Algorithmus du im Nachhinein
dann benutzt. Manche Algorithmen
können gut umgehen mit
komplett absolut skalierten
Werten, also so im Entscheidungsbaum zum Beispiel,
dem ist das relativ egal, wo er
jetzt zwischen, ob du jetzt die Werte zwischen
0 und 1 reingibst und Werte
zwischen 0 und 10.000, weil der
entscheidet einfach irgendwo, okay, zwischen diesen
zwei bitte splitte und
das rechte Ast, das linke Ast,
aber bei so einer linearen
Regression zum Beispiel, da ist es
halt von Bedeutung, wenn deine
Achsen alle ganz unterschiedlich
sind. Also ich könnte, das Wichtige ist eigentlich nur, dass
sie halbwegs miteinander vergleichbar sind.
Ich könnte sie auch alle von 0 bis 100 skalieren
oder so, aber die Konvention ist halt einfach,
man macht das halt einfach alles zwischen 0 und 1 oder
minus 1 und 1, je nachdem, was man da vielleicht
bezwecken möchte.
Und damit macht man in der Regel nichts falsch.
Also kann man sich ganz einfach vorstellen,
bei einem linearen Modell, ein lineares Modell bedeutet,
dass du im Grunde
einen Vektor
hast, der genau die gleiche
Dimension hat, wie du Spalten hast,
sozusagen.
Und die Klassifikation ist einfach
nur das Skalarprodukt aus einem neuen Feature-Vektor
und diesem Modell.
Und jetzt gibt es
ganz viele unterschiedliche Arten,
dieses Modell zu trainieren,
aber das ist immer das Gleiche, wenn das ein lineares
Modell ist. Also ob ich jetzt eine Support-Vector-Maschine
nehme, die das halt
trainiert oder halt Logistic Regression
oder halt irgendwie sonst
eins von den
Generalized Linear Models oder so,
die es da so gibt, da fällt immer so ein Vektor
dabei raus und die Klassifikation ist eigentlich immer gleich.
Und ich kann mir natürlich
jetzt leicht vorstellen, was passiert, wenn ich
irgendwie überall Werte zwischen 0 und 1
habe in den Spalten. Nur in einer Spalte habe ich jetzt
Werte um die 10.000 oder so.
Dann dominiert diese Spalte natürlich das
Klassifikationsergebnis massiv. Das heißt,
ich muss die alle so normiert haben,
dass hinterher die Länge der Vektoren
1 ist, damit nicht
ein Feature halt da so
irgendwie, so alle Features sollten
irgendwie so quasi numerisch gleich
wichtig sein.
Ja, deswegen muss ich das halt skalieren am Schluss.
Und dafür nimmt man halt, ja, gibt es auch
unterschiedliche Skalierer und
Standard Scaler macht, glaube ich, irgendwie
ja,
weiß ich gar nicht.
Ja, es skaliert halt.
Es skaliert halt irgendwie runter, genau.
Der wesentliche Punkt eigentlich bei diesen Pipelines ist,
ich könnte diese ganzen Schritte auch alle nacheinander
ausführen. Also ich kann prinzipiell
in meinem Notebook, das haben wir
vorher quasi auch gesehen, in dem
linearen Regressionsnotebook,
ich kann
erst meinen Text umwandeln,
Dimensionalitätsreaktionen ausführen in der nächsten
Zelle und quasi immer dazwischen meine Werte
irgendwie in ein neues DataFrame schreiben
und das wieder in das nächste reinführen.
Ist zum Debuggen vielleicht auch mal
ganz hilfreich, aber wenn ich nachher quasi
dann einfach damit spielen möchte,
verschiedene Werte zu verändern, dann will ich, dass das
möglichst einfach hintereinander durchläuft
und ich weiß nicht, cashen so
Pipelines auch zwischendrin Schritte? Genau.
Genau, das heißt, das macht es auch deutlich effizienter,
wenn ich dann quasi in einem
relativ späten Step in der Pipeline
eine Kleinigkeit ändere, dann muss die halt nicht
komplett von vorne durchgeführt werden
und genau, das mache ich
prinzipiell eher, wenn ich
schon so die erste Exploration
durch habe, dann würde ich anfangen, sowas in eine Pipeline
zu stecken oder machst du das wirklich von Anfang an?
Ne, genau, ich mache das auch erst, wenn ich ungefähr weiß,
was ich damit tun möchte
und ja,
genau, man braucht es halt auch
vor allen Dingen deswegen, wenn man jetzt unterschiedliche Sachen
ausprobieren möchte, das ist halt
Stichwort wäre
Hyperparameter-Optimierung, also sozusagen, welche
Features verwende ich.
Man kann ja im Moment ja dann doch
wieder gewichten, wenn man möchte, oder?
Oder mit so Gewichten so ein bisschen umspielen?
Natürlich, man kann auch einzelne Teile davon,
man könnte jetzt unterschiedliche Feature-Unions
bauen, so eine zum Beispiel, die sich nur mit dem
also das ist ja
im Grunde hier auch schon so, also ein Ding,
das sich halt nur mit dem Text beschäftigt oder
eins, was sich mit dem Body,
mit dem Titel beschäftigt und eins, was sich mit dem
Body dieser Ticker-Meldung
beschäftigt und jetzt könnte man
diesen Dingern unterschiedliche Gewichte geben auch.
Das auf jeden Fall.
Ja, aber all diese Änderungen, die man macht,
wenn man jetzt da an irgendwelchen Parametern dreht,
die möchte man ja hinterher auch,
also das muss man sich ja irgendwie merken
und eigentlich möchte man das ja auch systematisch durchprobieren
und das nicht von Hand immer wieder verändern.
Und ein Verfahren, um das halt systematisch durchzuprobieren,
ist halt GridSearch und das ist halt auch ein Vorteil,
wenn man jetzt so eine Feature-Pipeline hat,
dass man sozusagen die Bereiche für die Parameter,
die man halt durchprobieren möchte,
die gibt man halt irgendwie an
und dann ruft man das halt
mit GridSearch auf und dann werden diese ganzen
Parameter, dieses Parameter-Grid halt durchprobiert
und am Schluss
fällt halt das Modell raus, was
am besten funktioniert hat, beziehungsweise alle anderen
Ergebnisse werden auch gespeichert. Normalerweise will man jetzt
da irgendwie aus diesem GridSearch
Ding halt rausholen
und irgendwo ein CSV schreiben oder irgendwie
und dann kann man sich das halt hinterher visualisieren
und dann halt gucken, okay, wann
habe ich das mit welchen Parametern irgendwie ausprobiert
und was dabei rausgekommen.
Genau, ich würde da die
Hyperparameter-Tuning nochmal kurz ein bisschen aufgreifen.
Jeder dieser Algorithmen, die wir jetzt
erwähnt haben, die haben jede Menge Parameter,
die man da mitgeben kann.
Eine ganz einfache lineare Regression
ist vielleicht noch relativ beschränkt,
aber sobald wir die jetzt zum Beispiel
regularisieren,
das heißt irgendwie verhindern, dass die
zu stark sich den Daten anpasst,
bekommt die Hyperparameter oder noch einfacher
finde ich es sich vorzustellen, bei so einem Entscheidungsbaum
Der hat halt eine gewisse Tiefe, der kann irgendwie auf 100 Leveln verschachtelt sein oder nur auf 2 und der kann auch zum Beispiel beschränkt werden in der Anzahl der letztendlichen Blätter, also wie viele mögliche Output-Ergebnisse kommen dahin oder wie viele Samples müssen in jede dieser Blätter letztendlich fallen.
Das sind zum Beispiel schon drei verschiedene Parameter, die man da so mitgeben kann und die können die Art, wie gut dieses Modell performt, extrem beeinflussen. Das ist wirklich sehr, sehr entscheidend und deswegen ist es wichtig, die einfach nach und nach durchzuprobieren.
Und man sagt jetzt, wir haben doch irgendwie selbstlernende Algorithmen, irgendwie, warum muss ich denn da jetzt noch Parameter tunen? Aber ich passe ja quasi einfach die, man muss, es sind halt zwei verschiedene Arten von Parametern. Die einen sind quasi die internen, die berechnet werden innerhalb des Algorithmuses, die lernt er aus den Daten und das andere sind quasi so die Konfigurationsobjekte, wie man das, wie die Berechnung von diesen anderen Parametern zustande kommt.
Und die muss ich ihm halt eben mitgeben oder ich versuche sie halt einfach alle, probiere sie halt einfach alle durch. Und das ist, was ich mehr oder weniger bei so einem Hyperparameter-Search mache. Ich überlege mir irgendeine Strategie, dass er einfach möglichst viele von denen durchprobiert. Da gibt es auch Algorithmen, die versuchen quasi selbstständig so ein bisschen zu wählen, an welcher Schraube drehe ich als nächstes, um halt dann den Algorithmus an der Stelle optimal zu tunen.
Und das ist halt ein ganz entscheidender Prozess innerhalb von so einem Data-Science-Projekt.
Ja, auch um halt die, man möchte es auch deshalb schon formalisieren,
damit man die Ergebnisse kommuniziert bekommt,
weil wenn ich jetzt im Notebook irgendwie Parameter ändere
und das durchprobiere, dann weiß ich das vielleicht noch,
obwohl meistens vergisst man das ja auch relativ schnell wieder,
was man alles probiert hat.
Dann weiß man vielleicht noch so,
ach, vor zwei Wochen hatte ich da irgendwas gemacht,
das war ziemlich gut.
Oh, was war das nochmal?
Man möchte das ja auch, wenn da mehrere Leute dran arbeiten,
denen das ja auch irgendwie kommunizieren
und da ist es natürlich dann schon gut,
wenn man das systematisch gemacht hat,
weil dann fallen da eben solche CSVs
einfach schon bei raus und man kann halt auch gucken, was andere Leute
schon probiert haben und muss das dann auch nicht nochmal
selber machen. Genau, und diese Hyper-Parameter-Search
gibt einem halt am Ende auch so eine
Operation irgendwie Best Parameter
oder Best Fit oder sowas und dann
gibt der einem halt einfach das Beste
von allen, die er ausprobiert hat, wieder.
Aber ansonsten,
wenn du quasi auch so tracken möchtest,
was hat gut funktioniert und auch Features reiningenieren
möchtest, du schreibst es dann einfach in CSVs weg
oder wie machst du das? Ja, meistens
tatsächlich, ja.
Weil das finde ich immer noch ein bisschen
überraschend, dass da Second Learn an der Stelle irgendwie
nichts von sich aus bietet.
Also ich habe mir jetzt gerade da auch diverse Tools
angeschaut. Ich finde da jetzt
MLflow von
Dataprix ganz cool,
die ja auch quasi Spark gebaut haben.
Die haben da ein Tool für gebaut.
Es gibt da auch irgendwie Sacred und DVC,
die ich mir alle mal angeschaut habe, aber
irgendwie finde ich es merkwürdig,
jeder kommt in diese Predulie, dass er jetzt
quasi ein bisschen damit rumspielt und seine ganzen
Ergebnisse an und nach noch tracken möchte
und jeder schreibt sich die irgendwie so ein bisschen
auf seine eigene Art weg, aber
ja, der Standardsupport irgendwie
von irgendwelchen Bibliotheken ist da, finde ich, noch ein bisschen
jung und schwach.
Ja, ja.
Wie fandest du DVC?
Das wollte ich mir demnächst mal irgendwie angucken.
DVC ist halt nicht
Pythonic, ja.
Also das basiert halt komplett auf
Kommandozahlenaufrufen
und Shell-Skripten. Ich habe
letztendlich quasi so die Abwägung, würde ich sagen,
wenn du schnell
Sachen ausprobieren willst
und mehr so in der
Exploration bist, dann guck dir lieber ML-Flow
an. Das finde ich dafür deutlich angenehmer.
Wenn du sehr viel Wert
auf Reproduzierbarkeit deiner Experimente
legst und vielleicht auch große
Experimente machst und dafür bereit bist,
mehr Zeit zu investieren
und mehr so ein höheres Maturity-Level
vom Prinzip her hast und auch im Team arbeitest,
dann ist DVC meiner Meinung nach
die bessere Wahl. Also ich habe Kollegen, die benutzen das eine
als das andere. Das hängt ein bisschen mehr
von deinem Projekt ab, aber gerade für die Exploration
finde ich DVC einfach
zu viel Boilerplate-Code.
Ich verlinke dazu mal
meinen Artikel, den ich auch gerade noch
geschrieben habe, genau darüber.
Ja.
Jetzt könnte man
natürlich alle möglichen verschiedenen Algorithmen
draufwerfen und so, aber ich würde sagen, das überlassen
wir mal den Hörern. Da könnte man jetzt auch ewig
Zeit drauf werfen.
Haben wir irgendwas
Wesentliches vergessen?
Den grundsätzlichen Prozess, dieses Datenbeispiel
da von Reuters mal kurz so
zu skizzieren, haben wir schon durch, oder?
Also es funktioniert auf jeden Fall.
Wir haben jetzt tatsächlich gelernt,
wie man so eine neue
Nachricht dann mit so einem Label versieht, dass dann
die Klasse so, was ist das für eine Kategorie,
rausfällt unten, oder?
Genau. Also wir sind jetzt in der Lage,
Wir haben jetzt ein Modell da liegen, was auf den Testdaten Prognosen rechnen könnte und wenn jetzt ein neuer vergleichbarer Textartikel reinkommt, der dieselben Spalten hat, egal wo der herkommt, dann können wir den auch reinwerfen und dann wird der einen der Tags voraussagen, die wir jetzt quasi da drin hatten.
da können jetzt kein originär neuer
Artikel natürlich rausfallen
oder so, aber
das haben wir
und können auch bewerten, wie gut wir daran sind.
Ja, also
haben wir quasi unser erstes Projekt erfolgreich
abgeschlossen und wenn wir das jetzt auf dem Server implementiert haben,
dann läuft das so auch.
Ja, wir könnten eben jetzt so ein Modell hinter
so einer API
irgendwie deployen und
dann schicken wir da einen Artikel dahin
und bekommen dann halt zurück, in welchen
Dingern das liegt und dann muss man sich
natürlich noch überlegen, okay, gibt man halt
zurück, mit welcher Wahrscheinlichkeit
das in welcher oder einfach nur
eine Liste der Kategorien, in denen
es liegt
und wann sagt man
eigentlich, es liegt drin oder nicht.
Genau, und das ist,
da müssen wir natürlich noch eine Menge
Entscheidungen treffen. Das hängt halt auch
davon ab, wie das Problem aussieht. Ist es wichtig,
möglichst alle Kategorien,
in denen ein Artikel liegen könnte,
mitzuliefern oder
ist es besonders wichtig, möglichst keine Fehler
zu machen und das hängt dann halt davon ab,
welche Art von Problem man gerade
hat und dann, ja,
genau, dann würde
man das halt entsprechend machen, aber
Wie groß ist das Modell auf dem Server?
Die hier sind
relativ klein, wenige Megabyte, denke ich,
sind die groß, also das ist also
Hängt vor allem auch viel von der
Art des Modells ab, was du jetzt benutzt,
also so ein Entscheidungsbaum zum Beispiel ist relativ klein,
wenn du jetzt halt komplexere Algorithmen
nimmst, wie zum Beispiel dein Random Forest,
was quasi einfach ganz, ganz viele
Entscheidungsbäume sind oder ein
Boosting-Tree, was quasi verschachtelte
Entscheidungsbäume sind, dann hast du natürlich ein
Vielfaches dessen. Genau. Dann kommst du
auf mehrere Megabyte
einzelne Entscheidungsbäume, ist wahrscheinlich sogar im Kilobyte-Bereich.
Je nachdem,
wie tief du den halt eben machst.
Und hängt halt auch davon ab, wie deine
Trainingsdaten, also bei den linearen Modellen,
die sind halt einfach genauso groß wie deine
Feature-Matrix, also sozusagen haben genauso viele Dimensionen
wie deine Feature-Matrix. Und dann kannst du
es ja einfach ausrechnen, irgendwie, wenn du
pro Gewicht irgendwie
4 Byte
brauchst für ein Float,
Single Precision Float,
dann ist das halt
4 mal, bei dem
ist es 25.000 wahrscheinlich mal,
also 4 mal 25.000,
also 100
Kilobyte, das ist ja nichts.
Aber
wenn du jetzt zum Beispiel viele Trainingsdaten hast und
du hast halt ein,
also das ist ja auch noch so eine Geschichte, es gab
in dem
Explorations-Notebook auch so ein
quasi manuellen
Entscheidungsbaum dafür,
welches
Modell man denn jetzt für welches
Klassifikationsproblem nehmen könnte.
Und da gibt es halt auch so irgendwie zum Beispiel
so rekurrente
neuronale Netze,
die man nehmen kann. Und die können halt unter Umständen
sehr, sehr viel mehr Parameter haben.
Das Ding macht natürlich
nur Sinn, wenn man viel, viel mehr Trainingsdaten hat.
Aber wenn man jetzt irgendwie ein Modell hat,
50 Millionen Parametern, dann muss man die halt irgendwie
speichern. Das ist halt dann das Modell und dann
wird das halt auch sehr, sehr groß unter Umständen.
Ja, aber selbst
das ist ja für Server heute alles nicht mehr so.
Es wird dann interessant noch, wenn man
das nicht irgendwie auf einen Server deployen möchte,
sondern, was heute oft
gemacht wird, auch auf ein
Telefon. Und da
muss man halt vielleicht nochmal ein bisschen gucken, was die Größe angeht, aber
ja.
Das Schöne ist ja vor allem, eben eine Prognose
jetzt mit so einem Modell zu berechnen, ist
überhaupt nicht mehr kompliziert. Also
aufwendig ist es natürlich, Modelle zu trainieren,
wobei das mit den Modellen, die wir jetzt hier haben,
alles relativ schnell geht und man das einfach
auf dem lokalen Rechner mal durchspielen
kann.
Bei einem neuronalen
Netzwerk wäre das bei dem Training was anderes,
aber die Prognose ist hier nachher dann trotzdem super
einfach, weil dann gehe ich halt
einfach nur einmal quasi den Entscheidungsbaum lang oder
laufe einmal mein neuronales Netzwerk von vorne
nach hinten durch und fertig.
Und das kann dann halt auch...
Wenn man den Weg kennenlernt, dann kann ich natürlich relativ schnell sagen, wo ich hin soll.
Genau, es kann auf schwache Hardware laufen.
Ja, cool.
Dann habe ich tatsächlich heute wieder ganz viel über Machine Learning gelernt.
Ich hoffe, ihr habt auch noch irgendwas mitgenommen.
Ja, wenn du noch ein bisschen mehr lernen willst.
Also ich finde immer, so eigene Projekte sind super.
Und ansonsten einfach bei Kaggle mal einen Account machen.
Ja, Kaggle, ja.
Selbst wenn man da am Anfang nicht mitmacht.
Also selber mitmachen ist sehr viel Aufwand.
Aber es reicht eigentlich auch einfach nur mal ein paar Challenges zu beobachten
und mal ein paar Kernels sich aufmessen.
Oder mal so nachbauen oder so welche, die es schon gab.
Mal gucken, wie gut man an die tollen Lösungen irgendwann rankommt.
Genau, also beziehungsweise das Schöne ist ja bei Kaggle,
dass diese ganzen Lösungen eigentlich immer einfach alle online sind.
Also diese Kernels, die da sind,
die sind ja wirklich immer sehr, sehr gut.
Gerade auch bei der Exploration, wo man,
also so ein Kernel ist ja vom Prinzip her so ein Notebook.
Ja, vielleicht noch ganz kurz, in Kaggle gibt es Bounties dafür,
wenn man total tolle Prognosen herstellt.
Also nur das vielleicht mal so für die Leute,
die das noch nicht gesehen hatten.
Genau, genau. Es ist also ein Wettbewerb
für Data Science Projekte und
Leute sind da so nett und stellen halt quasi
ihre Kernels online, ihre Notebooks online
und man kann da einfach mal gucken, wie die das
lösen. Da kriegt man sowohl mit, welche
Tools sind gerade irgendwie angesagt,
wie geht man damit um, man lernt so die
Syntax und
genau, also ich lerne da auch jedes Mal,
wenn ich so eins der top gerateten
Notebooks da durchlese, lerne ich
jedes Mal wieder was.
Ja, finde ich auch super hilfreich.
Ja, schön, dass ihr wieder alle eingeschaltet habt.
Ihr findet immer die
Informationen in den Shownotes.
Genau, die werden nicht mehr, glaube ich, ziemlich lang.
Ja, das kennen wir schon.
Und ja, dann
hört wieder rein, bleibt gewogen.
Wann auch immer ihr uns hört.
Wenn ihr irgendwelche Feedback habt, schickt eine E-Mail
an uns, hallo at peißenpodcast.de
oder Nico.
Und ja, bis dahin.
Genau, hört
wieder rein und bis bald.
Tschüss.