Transkript: PP07 - Machine Learning am Beispiel Textklassifikation
Vollständiges Transkript der Episode. Zeitstempel beziehen sich auf die Audiowiedergabe.
Ja, dann hallo liebe Hörerinnen und Hörer.
Bitteschö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 der Schiff.
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 Nikos tollen Podcast InnoCast heißt er noch.
Innotechcast, genau.
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 IT-La interessieren könnten, irgendwie von Containern, über irgendwie so DevOps-Geschichten, einzelne Programmiersprachen.
Was haben wir so gemacht?
Wir haben GoGame gehabt, wir haben Rust behandelt.
Wir hatten auch schon mal eine Folge so ein bisschen zu Python.
Also es ist auf jeden Fall sehr spannend, hört da mal rein.
Kann ich empfehlen?
Klangt gut.
Genau.
Ja, dann fangen wir doch mal mit dem richtigen Thema an jetzt.
Und gehen das Beispiel durch, was wir fürs Machine Learning machen wollen.
Ja, da habe ich noch ein bisschen zu erklären, wie es geht.
Wahrscheinlich sollten wir erstmal so ein bisschen.
Erstmal nochmal so allgemein vielleicht, was ist denn das überhaupt, das Machine Learning?
Was macht das denn?
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 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.
Computer lernt so, was er ja mit neuen Sachen dann anfangen muss, aus alten Dingen.
Genau, es gibt einmal, also es gibt keine allgemeingültige Definition, was jetzt Machine Learning ist, aber also ich, 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 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 irgendwie 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 halt, 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, weil man das nicht wirklich in einen Algorithmus reinbekommt.
Man kann nicht so einen Gegenstand definieren, wo eine Katze ist irgendwie so ein kleines Tier und grau und weiß und so weiter.
Und dann ist es gerade schwer zu unterscheiden.
Ja, oder auch die Arbeit mit Sprache finde ich ein gutes Beispiel.
Da hat man halt viele, viele Algorithmen entwickelt, die auch zu einer 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.
Ja, das ist, 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ßerdem 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 da irgendwie man ja davon ausgeht, dass das irgendwas Magisches ist, dann geht halt alles und dann und das ist ja jetzt auch nicht so.
Das ist genau der spannende Punkt.
Du hast nämlich genau gerade versucht zu erklären, dass das, was da passiert, irgendwelche mathematischen Algorithmen sind, ja.
Und die halt zu verstehen als Mensch oder daran zu schrauben zu können, die Parameter, die man halt irgendwie beim Machine Learning 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 so was damit zu tun, wenn irgendjemand neue Sachen erfindet, irgendeine Geometrie entdeckt, dann ist das vielleicht auch ganz magisch für jemanden, 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 bei den Leuten, die sich damit nicht auskennen, so ankommt.
Ja, also wenn man das guckt, was, wenn man sich einfach nur die Ergebnisse anschaut, dann wirkt das so ein bisschen magisch, aber.
Genau, also warum kann der Computer jetzt einen Hund von der Katze unterscheiden?
Wie soll das denn gehen?
Genau, genau, ja.
Wie der Computer weiß, was ich da gerade gesagt habe und kann mit mir sprechen.
Oder ist das 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 es wie Magie und wenn man halt nach und nach die Informationen da drin versteht, dann blickt man halt, okay, das hat gewisse Schlussfolgerungen.
Ich meine, es hat schon.
Verstehen wir die wirklich bei Maschinenlein?
Das habe ich jetzt nämlich auch noch nicht so ganz verstanden.
Nee.
Genau, oder da gibt es, ja, gibt es natürlich einen Unterschied zwischen so eben Blackbox-Whitebox-Verfahren, bei denen man, also bei den 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 Millionen reicht ja schon, aber wenn ich auch mehrere hundert Millionen Parameter habe, dann ist das eine Menge, die ich als Mensch ja überhaupt nicht mehr überblicken.
Das ist halt so viel.
Ja, wobei es inzwischen da ja schon viel Forschung gibt, gerade auch um gerade auch um neuronalen 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 gewiss, 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 Schlussdiagramm.
Aber vielleicht wollen wir kurz nochmal 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 neurodales Netz oder so ein Decision-Tree verwenden möchten.
Wird das denn machen?
Was sagt ihr?
Ja, also ich finde, man muss ja 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 gewisse Zeitreihe vorhersagen möchte, mit relativen einfachen Mitteln, um vielleicht den Abverkauf von meinem 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 drauf werfen.
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, ne?
Das ist ja vielleicht immer ein anderes Problem.
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 ich mal Alphe oder sowas, das ist ein Hund oder eine Katze, weiß man nicht so genau.
Ja, dann kommt was Neues auf die Welt.
Genau, nee, also da, es gibt auch Verfahren, die total einfach zu verstehen sind.
Also sowas wie Naiv Bass 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 Naiv-Bass ü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 immer beschreiben kann, halt binäre Klassifikation, vielleicht.
So, womit man anfangen.
Und ja, Naiv Base ist halt ein.
Also binäre Klassifikation ist jetzt drin oder nicht drin.
Genau, man unterscheidet eigentlich nur zwei Klassen.
Und du merkst
ganz kurz, genau, wenn man das nochmal 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 Informationen 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 typsten Fälle.
Und genau, jetzt 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 jetzt hier finde, Moment.
Genau, wir wollten nochmal kurz erklären, was Space macht in 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, bei, weiß ich, mehr als zwei Dingen.
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 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 Bassern relativ gut machen kannst.
Du kannst halt dann sagen, ey, ist jetzt der Falter grün oder nicht?
Oder schwarz oder so?
Oder ist es 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, das war so ein Perlscript-Spam-Assassin.
Das hat sich dann halt die Header angeguckt und dann hat es halt manchen Providern mehr und manchen weniger vertraut und irgendwelche, dann insgesamt halt irgendwie einen Score ausgerechnet und gesagt, ah, okay, das hat jetzt ein Spam-Score von so und so viel oder so und so viel und ab der bestimmten Grenze wurden halt abgeschnitten und gesagt, das ist Spam.
Das hat ganz okay funktioniert, aber das war immer leicht zu unterlaufen von Spammern und das war, und Spam war immer relativ ärgerliche Geschichte.
Bis dann halt eben Programme halt der wie heißt der Inkubator, den er gegründet hat, darüber ist er sehr bekannt geworden.
Hab ich jetzt gerade fallen.
Also der schreibt auch viele Essays und hat auch ein Buch geschrieben bei Krassan.
Y Combinator tatsächlich.
Vorher hat es auf der Tun, ich habe mich noch nicht getroffen.
Da doch.
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 endkönlich in den Griff kriegen.
Und da schlägt er halt vor, irgendwie so Nai-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.
Er 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 sein Zweck.
Liebe Freund, ich brauche hin 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 Spamfilter nicht in Ordnung.
Was für ein Spamfilter?
Okay.
Nein, also die landen bei mir im Spamfilter und ich kann dann immer sehen, okay, es war eine Message im Spamfilter, was auch nicht so häufig passiert.
Achso, okay, gut.
Genau, und zwar ist das Verfahren halt super einfach.
Das ist halt, mach einfach aus den Mails, äh, 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 dir 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 dran stehen quasi, wie oft es halt vorkommt und man hat nochmal eine Zahl für wie viel Mail.
Da sagt der Algorithmus,
uh, er hat Penis gesagt und dann sagt er, nee, jetzt wahrscheinlich Spam.
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 nah 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, das ist ja auch kein Problem.
Und das war es schon.
Also es ist wirklich nicht, es ist keine große Exatten.
Es ist keine, wie sagen wir, Raketenchirurgie irgendwie, ist eigentlich eine ziemlich einfache Geschichte.
Genau, das kann man ja einfach eigentlich auch noch so in einem Algorithmus darstellen.
Da braucht man keine komplexen Selbstlernenverfahren eigentlich noch, nicht mal.
Ja, also gut, das Ding lernt ja tatsächlich.
Also wenn ich jetzt sage, wenn jetzt eben, ich habe bisher nur Mails, die mich, die mir Produkte zur Vergrößerung meiner primären Geschlechtsmerkmale, wie mir sonst was andrehen wollen, bekommen.
Und ich kriege jetzt zum ersten Mal 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, in den Spam-Ordner 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, wenn wieder eine so eine Meldisarbeit.
Das ist nicht ärgerlich für Prinzen mit Schweizer Bankkonto.
Ja, die haben ein Problem.
Die werden 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 Mal schon 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, jetzt habe ich kurz an Base-Klassifikation erklärt.
Wir sind aber immer noch nicht bei dem Beispiel angekommen, was wir irgendwie denn müssen.
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.
Ja.
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 Textklassifikation.
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, so weit, 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?
Warum denn Conda?
Ja, also Conda ist ein Paketmanager des Teils von Python, der sich mit so Data Science Machine 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, es ist, früher hatte man ja irgendwie mal so die Hoffnung, dass die Distribution das ganze Paketinstallationsding 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 so ein bisschen besonders schlimm, weil da gibt es halt nicht nur einen, sondern je nachdem, in welcher Community man sich da aufhält, wenn man irgendwie eher Webentwicklung oder sonst wie Python-Entwicklung macht, dann ist es eher PIP und als Repository für Pakete halt PyPI.
Das Problem hat nicht nur Python.
Rust ist da auch ganz schlimm, habe ich schon gelernt.
Aber ja.
Nee, genau.
Ist ja auf jeden Fall ziemlich anstrengend.
Ich weiß gar nicht, ob ich Conda so verwenden würde, so außerhalb von Daten.
Nee, würde ich glaube ich auch nicht machen.
Mache ich auch nicht.
Also wenn ich, wenn ich Webprojekte 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, ja, aber das will man halt auf einer, wenn man 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 irgendeiner API ein 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 Pip installieren, aber wenn ich jetzt irgendwie was trainieren wollte, dann würde ich eher die Konda-Pakete nehmen oder vielleicht sogar spezielle Docker-Images oder sowas.
Ja, aus meiner Sicht hat 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 Basisversion 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 VirtualEnd und 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-School 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 halt im Data Science-Umfeld auch durch den starken Support von Continuum da und den finanziellen Mitteln, die dahinter stecken, so durchgesetzt hat.
Aber ich.
So einfach zu installieren ist auch.
Es gibt halt auch, glaube ich, nur Windows-Binaries 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
bisschen 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 Minikonda 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 Minikonda ist halt erstmal klein und schlank und dann muss man halt alles quasi mit dazu installieren, was man dann noch gerne hätte.
Ja.
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 Riesenunterschied, ist heute nicht mehr ganz so relevant, ist halt, dass man halt Binärgeschichten per Gondor 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 eine Lib C irgendwie mit Conda installieren und die dann halt in einem Gondor-Environment verwenden.
Und muss halt, also das ist auch so ein Problem, wenn man hier jetzt auf größeren Servern unterwegs ist, die halt unter Umständen irgendwie so eine antike Debian-Version irgendwie haben und eine Uralt-Lib C und die funktioniert dann mit neueren anderen Bibliotheken nicht mehr gut.
Dann hat er 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 als Faustregel einfach nehmen.
Wenn es ein reines Data Science-Projekt ist, ja, dann Conda und wenn es irgendwie eine Webgeschichte 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 Conda Forge, also sozusagen ein.
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 einen Konfigurationsfile und da kann man halt die Channels sozusagen, aus denen man Pakete bekommt, halt eintragen.
Und ja, die meisten verwenden Condaforge.
Es ist jetzt auch irgendwie so, dass, glaube ich, Anaconda selber irgendwie auf Condaforge umgestellt hat oder was ich nicht.
Genau, die haben
sich das eben.
Das haben wir gehört auf dem Barcamp jetzt.
Ja, 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 meist nochmal gegoogelt, was ist denn jetzt hier das richtige Repo dafür und das ist jetzt aber seitdem quasi weg.
Ja, es ist tatsächlich anstrengend, wenn man halt schon unterschiedlich bei Gipmenter hatten dann auch seine eigene Source dafür irgendwie das stemmen muss.
Kann mich dann anderes.
Das macht das alles Experimente erinnern mit so Paketsachen und Sources noch.
Alles nicht einfach, 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 Vassau, glaube ich, einer Python-Core-Entwickler, sagt man, The first rule of Python ist 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, wird halt Python 2 irgendwie noch als Default-Interpreter bei Mac auch.
Es gibt einen Countdown für Python 2 mittlerweile, habt ihr den gesehen?
Desklock, ja, gibt's.
Bin mal gespannt, wann die Betriebssysteme es dann auch mal sich trauen.
Also 20 bis Leitern so langsam, aber.
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.
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 Fallsystem ist und das kriegt man halt nicht irgendwie unter einen Hut.
Und daher macht man normalerweise pro Projekt ein eigenes 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 braucht, weil da innerhalb des Projektes sich unterschiedliche Module übersprechen?
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.
Das 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, eine Python-Versionen, weil die Module das sonst nicht können und die man dann irgendwie pipen, wo sie mit dem Männer reden können.
Und um das dann zu bauen, müsste man halt dann zwei Versionen benutzen.
Nehmen wir zum Beispiel mal an, man würde ein OCR-Projekt und man möchte jetzt irgendwie ein aktuelles Ding gegen was älteres wie Ozeropi oder Kraken oder so verwenden.
Das nehmen wir mal an, genau Kraken kann auch Python 3, aber das Ozeropi kann nur, oder Ozeropus, das 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 das gar nicht machen.
Genau, also wenn ihr euch inzwischen das Repo ausgeklont habt, dann ist jetzt vielleicht der richtige Moment, einmal ConnerEnvCreate auszuführen, um die Umgebung ruhig aufzusetzen.
Was an der Stelle ja passiert ist, er zieht sich von lokal eben ein 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 seinem Default-Python-Interpreter gesetzt.
Also Connect Grade macht dann genau das, dass du einfach ein Environment setzt, die heißt dann Grade, oder was?
Nee, das steht in dem File halt auch mit drin.
Der Name von dem
Environment, genau.
Warte mal, genau.
Das ist auch einfach ein YAML-File.
Und da steht dann eben das erste Name und da steht ein IS-Totorial für das Peter.
Ach, dann werden einfach die Pakete danach geben.
Und achso, das ist auch so, man kann halt auch.
Pip-Pakete einstellen.
Genau, dann kann ich auch Sachen per Pip installieren.
Ja, das ist auch sowas.
Also, es ist halt irgendwie, ja, Konter ist quasi eine echte Obermenge von Pip.
Also man kann halt Konda 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 Konda 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, ne?
Mit gleich oder sowas.
Genau, das kann man nicht auch machen.
Genau.
Und danach müsst ihr, um das Repo quasi so ausführen zu können, nochmal das lokale Paket bauen und zwar mit <unk>E.
Warum wollen wir denn erstmal überhaupt ein lokales Paket und warum wollen wir <unk>-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 den 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 in 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 Pipe PI 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 halt sozusagen mit nach Side-Packages.
Und wenn sich da irgendwas ändert am Code, dann ist das halt sofort irgendwie sichtbar.
Und dann kann man noch auf, man kann 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 ja fein granular 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 beim Code-Teil, der halt in vielen Notebooks verwendet wird, einen Teil ändert, dann ist das halt, 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, diesen Schritt zu gehen.
Also ich habe mich da am Anfang lange vorgescheut und habe einfach quasi am Anfang von meinem Notebook einfach immer mit der Run-Magic quasi 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 so ein bisschen bessere 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 Code?
Ah ja, okay.
Ah, 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.
Nein, aber ich hatte das nämlich auch gezeigt, deswegen dann so.
Genau.
Ich meine, am Anfang ist so ein bisschen Overhead mit dem Anliegen von so einer Klasse da, aber ihr benutzt, glaube ich, so Cookie-Cutter-Templates.
Ja.
Ich benutze PyScaffold, was ein Projekt ist, was vom Kollegen von mir entwickelt wird, was mir da sehr geholfen hat, einfach am Anfang quasi so Scaffolding mir mein Gerüsteimer aufzusetzen.
Da kenne ich mich dann direkt drin aus und dann träge ich da nochmal 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.
Gut, und dann können wir letztendlich wirklich unser Notebook starten.
Du würdest nur Jupyter Notebox.
Ja, stimmt.
Magst du Jupyter Lab lieber?
Oder warum magst du kein Jupyter Lab?
Doch, stimmt, mag ich auch.
Ich habe es jetzt auch nur so reine Gewohnheit eigentlich.
Aber ja, eigentlich im Grunde müsste ich auch mal auf Jupyter Lab umsteigen.
Genau, also gerade die neuen Versionen mit den Plugins, finde ich, es kommt, also am Anfang haben mir noch ein paar Funktionalitäten von Jupyter Notebooks 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 Jupyter Lab Notebooks reinladen kann.
Aber genau.
Ja, ja, ja, nee, das genau, das 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
jetzt ein Jupyter Notebook oder ein ehemaliger, ähm, egal ob ihr jetzt ein Jupyter Notebook oder halt schon ein Jupyter Lab 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 Explore Data Notebook aufmachen.
Das ist das Dataset, also da 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 das Reuters 21578 Textklassifikationsdataset, das ist so ein klassisches Ding, wo irgendwie eben entsprechend viele 21.578 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, als Trainingsdatum für Textklassifikationsmodelle, weil man halt dann damit vorhersagen kann, versucht zu vorhersagen, wenn man jetzt eine neue Ticker-Meldung reinbekommt, welche Kategorie ist denn 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 Ticker-Meldung liegen kann, beziehungsweise auch noch ein Unterschied ist, es ist nicht, das wäre jetzt Multi-Class, wenn man nur, wenn es nur eine gäbe.
Aber das ist eigentlich ein Multilabel-Data-Set, das heißt, man möchte alle Kategorien, in denen so eine Ticker, 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.
Und das Erste, was man, finde ich, bei so einem Data Science-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 lade mir mein Dataset irgendwie in ein Pandas-Data Frame rein und dann benutze ich darauf erstmal meist ein Head, um einfach mal zu gucken, was habe ich überhaupt drin.
Dann ein 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 Übersichtsstatistiken 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 hin?
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 DFET macht, dann sieht man halt eine Spalte Modupte.
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-Fold-Cross-Validation hat und 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 Zahl und am besten auch als Zahlen, die halt keine Lücken haben.
Sonst geht das halt nicht gut.
Weil man das halt, äh, One Hot Hot Encoded, nimmt man das, dass sozusagen hinterher kriegt halt jede Spalte, äh, 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, irgendwie ein Titel, irgendeine komische Dateline, ich weiß jetzt gar nicht immer genau, was es 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, in dieser Machine Learning-Schulung man als Übung sozusagen vielleicht ein paar neue Features dazu tun sollte, um zu gucken, ob das irgendwie die Sc
ore irgendwie verbessert der Modelle.
Und da war halt so ein erstes Beispiel, man könnte einfach mal den Wochentag reinschreiben, an dem das irgendwie erschienen ist und vielleicht checkt er ja irgendwelche Informationen drin.
Ja, genau.
Die F-Info.
Wenn ihr irgendwie wissen wollt, wie man mit diesen Data Frame-Operationen noch ein bisschen besseren Einstieg findet, da gibt es ein ganz spannendes Buch von Jake Wanderplaast 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 Jupyter Notebooks das tatsächlich auch mal live noch an anderen Datensätzen üben.
Also gerade für Pandas-Einführung ist dann 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-Blog-Artikel-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.
Die wirbst einfach so einen Data Frame rein und die generiert dir daraus so einen kleinen HTML-Report, worin man dann quasi so ein paar Summary-Statistiken nochmal ein bisschen hübsch aufbereitet 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 haben hat das Ganze und der sucht auch quasi nach Korrelationen in den Daten.
Also wenn du jetzt halt 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.
So was würdest du dann da drin direkt sehen und dann würde dich zum Beispiel vor Waren.
Ja, das ist einfach ganz praktisch, wenn die clean 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, und es ist immer irgendwie, finde ich, ganz praktisch, um so einen ersten Übersicht zu bekommen.
Was würdet ihr denn 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, es kommt halt komplett drauf an.
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 statistisch 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 ein Cycle-Learn zum Beispiel, ist so eine Bibliothek für Maschinenlehnen-Geschichten, diverse unterschiedliche, also da ist die Oberklasse quasi für all diese Verfahren Imputer 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 es am besten ausgleicht.
Ja, die dann sozusagen da irgendwas reinschreiben oder irgendwas mitmachen.
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, wenn man den noch irgendwie braucht und immer merkt, oh, das ist erst bei dem Dummy so.
Ja, und auch wieum 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, aber genau das macht es an der Spalte.
Da sieht man genau gerade, ne?
Dann hast du irgendwie die Warnings gesehen, wie viel irgendwie, dass ganz viele aus einer Teile oder Spalte dann fehlen oder so bei irgendwelchen Einträgen.
War bei den Warnings irgendwie mit dabei.
Wie hieß das nochmal?
Ich habe das eine.
Pandas Profiling.
Profiling, okay.
Interessant.
Du musst auf jeden Fall auch in die Shownotes.
Mache ich.
Ja, genau.
Also hängt halt dann eben 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, das ist das nützlichste Ding, wenn man sich irgendwie, wenn man so ein bisschen sehen will, wie das eigentlich verteilt ist, oft ist, halt sich ein Histogramm der Werte halt anzugucken, vor allen Dingen auch, wenn man jetzt unterschiedliche Klassen hat, einfach mal die Histogramme gegeneinander zu plotten, das ist etwas, was ich oft mir angucke, halt, sozusagen, 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 g
egen 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, diesen genau gleichverteilt, dann ist es natürlich doof.
Aber genau.
Genau, in dem Explore Data Homebox 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 so einen Peak der Daten, der relativ am Anfang liegt.
Also irgendwie, wir haben hier jetzt, würde ich sagen, wahrscheinlich mal 80% irgendwie im Bereich von 0 bis 600 Zeichen.
Oder bis 750, glaube ich, sind es.
Und dann wird es weniger und dann gibt es so ein Longtail hinten mit so ein paar einzelnen Einträgen, die dann halt irgendwie 3000, 4000, 5000, 6000 bloß Einträge haben.
Irgendwann hat ja jemand sein Buch bei Reuters hochgeladen oder so.
Ja, 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 Diagramme 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 Dinger gibt, die irgendwie einen Test- oder Training zugeordnet sind.
Also den entsprechenden, also dieser Mod-Up-Displit teilt die diese Ticker-Meldung halt in die, die man, auf denen man trainieren kann und die sozusagen, die man hinterher benutzt, um zu evaluieren, wie gut denn jetzt die Modelle funktioniert haben.
Und es gibt irgendwie 119 Klassen, aber tatsächlich sind es deutlich weniger, wenn man jetzt alle und
es gibt 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, also 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 viele
Kategorien rausgefallen sind sonstiges oder so.
Ja, ich weiß es gar nicht genau.
Ich habe es mir das auch nicht angeguckt, was das genau für Kategorien sind, aber ja, also das ist halt 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 ja, 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 Zahlen im Data Frame, geteilt durch die Anzahl der Wörter pro Ticker-Meldung, 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 so 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, das glaube ich tatsächlich Idee, ne?
Auch verschiedene Arten, mal gucken, Wordcloud bauen vielleicht oder so und dann schauen, was ist das denn?
Von dem her 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 dann 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 mein 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 Datensatz, dass es eine ganze Zeit lang braucht, bis man wirklich versteht, was man damit alles so machen könnte.
Ja, man muss sich natürlich auch immer das Problem erstmal so ein bisschen reindenken, damit man irgendwie da mit den Daten aber auch was anfangen kann.
Ja.
Genau, und ja,
dabei hilft dann halt diese explorative Sache.
Und ja, neben diesen ganzen Hestogramm, ich glaube, wir haben angefangen erstmal mit, wie man die Daten noch bekommt, damit waren wir noch gar nicht so durch.
Achso, richtig.
Wir sollten irgendwie noch so die Art und Weise der Methode.
Wir haben jetzt irgendwie das Describe irgendwie von Data Frames 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 einen Pfeil.
Genau, normalerweise in der echten Welt würde ich sagen, ist der Fall 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 WebURL, dann ziehe ich es mir direkt von dort.
Kann man ja direkt auch mit Pandas, glaube ich.
Oder eigene Webdatenscrapen, eine eigene Datenbank oder sowas.
Oder von irgendwelchen Sensoren, die Sachen in irgendeine Datenbank packen.
Eine Datenbankanbindung 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 släst.
Also wenn die irgendwie Dateiner laden, also wirklich big ist die Data dann aber irgendwie noch nicht.
Nee, das hier ist alles super small.
Man will in so einem Notebook auch kein Big Data haben.
Kann man schon, aber.
Kann man schon, aber also ich weiß nicht, also meine Präferenz an der Stelle ist vor allem immer erstmal auch Latenzen niedrig zu halten und schnell mit Daten zu iterieren und lieber erstmal ein kleines Sample ziehen und erstmal viel Zeit in 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 M-Modelle auf den Kombletten ausprobieren.
Siehst du, machst du das anders?
Nee, nee, also genau, Subsample ist halt auch, wenn die Daten groß sind, auf jeden Fall eine super Strategie, um halt schnell iterieren 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 Data Frame nicht direkt von Pandas sozusagen, sondern man importiert das halt von DAS.
Und das Ding verteilt dann automatisch irgendwie die Sachen, die man da drauf tut, halt auf zum Beispiel, das hat auch einen, das ist schon ziemlich cool, das hat eine Anbindung an Kubernetes und halt auch an die ganzen Cloud-Geschichten, wie so irgendwo Google Compute 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 da hinzu.
Und man kann auch während Sachen da drauf laufen, also während man auf einem Data Frame halt irgendwas kopiert 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 da 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 auch 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, so diesem Big Data-Ding müssen wir nochmal eine eigene Folge machen, so mit Kubernetes-Inko, das ist auch nochmal spannend.
Genau, an der Stelle kann ich mal meine Kubernetes-Folge droppen.
Ach ja,
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, wenn man in vielen Firmen gibt es dann halt so ein Cluster, wo man Sachen machen kann, aber die Maschinen sind halt halt da und man braucht sie aber irgendwie nur, irgendwie, man braucht eigentlich so alle halbe Stunde mal so wirklich volle Power und 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 das jetzt auch schon öfter eingesetzt und es funktioniert für dich gut.
Ja, für mich funktioniert das eigentlich ziemlich.
Ich habe dann 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 dem Pandas.
Nicht komplett, aber also sagen wir so, 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 und 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 Pandason 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 es da vielleicht dann immer nicht mehr.
Und was ich heute kennengelernt habe, aber noch nicht ausprobiert habe, ist Pandall.
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.
Also bevor man vielleicht wirklich auf dem Cluster muss, ist das noch eine gute Option.
Ja.
Ja, ja, ja.
Nee, das kann ich auch noch nicht.
Also ja, ist interessant.
Genau, aber wir waren hierbei mit, wie bekomme ich eigentlich meine Daten, ne?
Ich hatte da einfach das entsprechende Notebook nicht aufgemacht.
Das heißt hier Preparing Data, keine Ahnung, vielleicht ein bisschen unbedingt genannt.
Und das ist einfach das Ding, also David Lewis, das ist auch der, der den Modup-Dis-Split gemacht hat und auch überhaupt 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 Path Library.
Habe ich auch noch nicht so lange in Benutzung, aber ist eigentlich mega cool.
Ja, ja, genau.
Sag dazu doch nochmal zwei Sätze.
Ja, also früher habe ich das auch mal mit OS und Listia und OS Path Join und so gemacht, aber das ist alles ganz schön, genau, glaub, ganz schön umständlich.
Und da gibt es halt, äh, ich weiß gar nicht, wann das in, seit wann das in der Standard Library ist, aber also es gibt da ein Modul namens Parslib.
Und da kann man, also zum Beispiel, es geht hier los mit Pars.homme, 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 den Slash überladen und jetzt kann man halt schreiben, irgendwie Pass.homme, gibt einem das Home-Verzeichnis, Slash Data Slash TMP.
Und das ist natürlich viel kürzer, als würde man jetzt schreiben, OS-Path join, Klammer auf und dann gibt man eine Liste oder macht irgendwie, ja, irgendwie muss dann einen absoluten Pfad angeben oder man gibt irgendwie ein relativen Ankomma, irgendwie das nächste Ding und das ist alles ganz schrecklich.
Man kann sehr schön Variablen quasi mit reinbetten und man kommt 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 halt Operationen dann immer direkt auf dem Pfad ausführen.
Ja, du kannst einfach DotExist machen oder sowas, was
mich cool.
Genau.
Ja, und ansonsten hätte man immer OS-Path Exist und so verwenden müssen.
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 hässlich und auch die Zeilen wurden sehr lang.
Und das Problem ist irgendwie weg, seitdem ich Passlip verwende und das ist schon mal echt ein Worthörner.
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.
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-RF Slash und dann.
Immer alles als Superuser machen.
Muss man hoffen, dass nicht nur das Backup immer funktioniert hat, sondern dass das Restort auch mal funktioniert.
Ich verwende hier einfach so irgendwie so einen 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 wrappen.
Man braucht nur einen Iterator 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 Data-Set halt irgendwie in so ein Data-Verzeichnis geschrieben.
Und das ist halt auch irgendwie das Tolle bei Python, dass man irgendwie einen riesen Haufen Funktionalität schon in der Standardlibrary mit drin hat.
Ist eben auch sowas drin wie Tar-File, dass man halt mit Tar-Archiven halt direkt irgendwie umgehen kann.
Und ja, 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 es so schnell ist
Pickel speichert einfach das Python-Objekt in der Binary einfach, also als Binär-Daten auf der Platte in einem Objekt und kann es genauso wieder einlesen.
Pickel ist auch ein Modul aus der Standardbibliothek, genau, und es serialisiert einfach Python-Objekte, Python-Objekte einfach in einem 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 Real 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 es halt irgendwie nicht so furchtbar merkbare Wartezeiten erzeugt, aber wenn man jetzt so ein paar Gigabyte einlesen will, dann ist das schon, da 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 ein Data Frame einzulesen mit Re-CSV und dann halt nochmal irgendwie einen Pickel-File davon zu cachen.
Weil das Pickel liest halt quasi mit Plattengeschwindigkeit.
Also da kann man auch so ein Gigabyte pro Sekunde lesen.
Dann dauert es halt, wenn man halt so einen Data Frame, der halt irgendwie zwei, drei Gigabyte groß ist, liest, der man auf die 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 gut.
Aber es hat natürlich trotzdem Sinn, dass man irgendwie eine CSV nimmt zum Teilen, weil in so einem Pickel kann halt eben alles dran sein.
Es ist halt ein Binary-File.
Ja, ja.
Und dementsprechend wahrscheinlich nicht das Beste, um es irgendwie im Internet.
Als Austauschformat als
Austauschformat zu benutzen.
Also es hat auf jeden Fall ein Sicherheitsrisiko, ne?
Weil wenn du da irgendwelche Sachen reinlädst und da habe ich dann meinen Code reingeschrieben an.
Also wenn man das für einen eigenen Cache benutzt, ist es okay, weil das zieht ja sonst keiner, aber stimmt, so verteilen sollte.
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 nur mal 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.
Ja, und dann hat man halt sozusagen die Daten in einem Format, das man damit irgendwie arbeiten kann.
Ja, und
jetzt können wir das schreiben und reingucken.
Genau, genau, genau.
Und dann halt dieses Explorer-Notebook sozusagen ausführen.
Genau, und dann halt eben die Daten visualisieren.
Wir haben da vorher jetzt nicht so darüber geredet, was für eine Bibliothek man dafür am besten benutzt.
Was ist denn euer Favorite?
Cbone.
Meine.
Ja, würde ich auch.
Cbonne ist mal das, was ich normalerweise am Anfang verwende.
Also C-Bone ist auf Mattplotlib 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 Achsenbeschriftung stimmt, für irgendwie ein Meeting mit 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 mit vielen verschiedene Sachen zu machen.
Ich benutze AltR sehr gerne zum Beispiel.
Kann ich sehr empfehlen.
Das ist halt die Möglichkeit dann quasi.
Alt R-R?
Genau.
Baut unten drunter auf Vega auf von der Visualisierungsengine 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?
Ja, ja, genau.
Da habe ich mal eine Weile mitgearbeitet.
Irgendwie bin ich da nie so richtig reingekommen, aber das kann auch bei mir liegen.
Ja, Bokie ist halt eine so 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 BOKI 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 Buket.
Und das ist auch relativ beeindruckend, was sie damit machen.
Aber ja, nee, Plotly ist auch das, was ich ein bisschen lieber
mache.js dann irgendwie noch gemoddet irgendwie oder so.
Kann 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 hat, hätte oder so, halt einfach auf eine Webseite packen.
Und das ist natürlich auch sehr praktisch.
Genau.
Ja, in 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, irgendwie hier, du bist jetzt eine JavaScript-Zelle und hier kommen die Daten von Python her.
Also es gibt unterschiedliche Wege, wie man das, 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 irgendwie so einen Force-Graphen, wenn es so ein 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 es 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 Bouquet oder so geht, keine Ahnung.
Aber mit D3 geht das natürlich schön.
Da gibt es 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 nochmal so ein bisschen komplexer wirklich so Dashboards zu bauen, die für euch gut funktioniert?
Nee, ich hab davon gehört, dass, äh, wie hieß das noch?
Dash, es ist halt Fortflug quasi die Variante, die da so dabei 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 ist ja.
Ja, Dash versucht genau das zu sein, aber aktuell ist es, das finde ich noch nicht.
Ja, bastelt auch gerade an so einem eigenen Visualisierungsding herum, aber das noch nicht.
So weit.
Ja, gut.
Haben wir unsere Daten ausreichend visualisiert, würde ich sagen.
Genau.
Wollen wir uns mal dem Modelltraining widmen?
Ja.
So.
Ja.
Wie trainieren wir denn das Modell?
Also wir haben jetzt die ganzen Daten, wir haben denen schon mal angeguckt, wir wissen so ein bisschen was, was hier rausgeschrieben hat, was man damit so alles anstellen könnte.
Warum, wie sogar man irgendwelche Features braucht und wir wissen natürlich, was wir vielleicht rausbekommen wollen oder wissen wir es nicht?
Also idealerweise wissen wir, dass wir irgendwelche Zusammenhänge finden möchten.
Genau, und wir haben ja jetzt in dem Fall ein Supervised Machine Learning-Problem, weil wir wissen halt eben für diese ganzen Artikel, welche Tags da hinten nachher dran stehen 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.
Da müssten könnten wir nur versuchen, irgendwie ähnliche Artikel zusammenzugruppieren.
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 das zu vergleichen.
Das ist halt eben wesentlich, was man tut mit einem Training und eben so einem sogenannten Testset.
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 7770 Trainingsdokumente, 3000 Testdokumente in dem vorgegebenen Split.
Und ja, man hat ja jetzt sozusagen die Labels eher als Liste von Klassen in den, 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 besorgt einfach nur, dass wir eben diese verschiedenen Klassen haben.
Also wenn wir nicht nur Ja oder Nein sagen, sondern hier halt eben diese 90 Tags, so die es gibt, quasi haben, dann haben wir erstmal nur ein Multi-Class-Problem.
Aber jetzt kann es halt auch sein, dass einer dieser Artikel eben mehreren von diesen Tags zugewiesen ist.
In dem Moment haben wir dann halt eben auch ein sogenanntes Multilabel-Problem.
Ja.
Und in diesem Format kann ich halt die Labels in einem Modell nicht geben.
Also ich geb dem Modell, was ich jetzt trainieren möchte, immer eben zwei Sachen.
Ich gebe dem einmal eine Feature, eine Matrix der, eine Feature-Matrix nennt sich das, also quasi eine Matrix, in der die Zeilen die einzelnen Beobachtungen gesammelt sind und die Spalten sind halt die unterschiedlichen Features.
Und die Labels oder Targets oder wie auch immer man das nennt, bei denen 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 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 viele 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 ScikitLearn, 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 erstmal das so in ein 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 Trainingset gehören.
Und dann so viele Spalten, wie es Kategorien gibt oder ja, 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 da eine 0 drin steht, bedeutet, dass im Grunde das Dokument liegt nicht in dieser Kategorie oder hat dieses Tag eben nicht.
Wenn eine 1 drin steht, dann heißt es, okay, ja, das ist sozusagen die richtige Kategorie für dieses Dokument.
Und genau, dafür gibt es aus dem Cyclit 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, äh, richtig formatiertes NumPy-Array aus.
Also das ist auch sowas.
Das muss man, also diese ganzen Transformationen, 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 ja, glaube ich, auch aussuchen, was da mit den Werten, die da nicht reinpassen, irgendwie geschehen soll und sowas.
Ja, ja, bestimmt.
Ich weiß jetzt gar nicht genau, was der Multilabel-Bonarizer da sonst noch 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 Transformprozessen und den Modellen und so weiter.
Und dann denkt man, ich will doch eigentlich nur so ein Modell benutzen.
Ich kann den ganzen Rest doch von Hand machen und fängt damit gerne erstmal an, weil man auch gerne ein bisschen programmiert und nicht ewig Doku liest, aber praktisch ist man halt letztendlich dann doch viel schneller, wenn man sich das halt einmal aneignet, wie dann diese Binarizer und so weiter funktionieren.
Ja.
Genau.
Und dann hat man quasi das gleiche Problem, nur irgendwie ein bisschen anders.
Auf der Feature-Matrix-Seite halt eben auch.
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 Numper-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 Standardmethode, 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 da weiter 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 ehrlich.
Aber das hat jemand schon niemals wahrscheinlich schon 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 null rein in die Spalten.
Also man hat sozusagen so viele Spalten, wie es überhaupt unterschiedliche Worte im gesamten Dokumentkorpus gibt, also über alle Dokumente drüber.
Wobei Back of Words macht schon auch die Anzahl gleich rein, oder?
Ja, ich weiß nicht, auch die Anzahl direkt rein.
Also, ob es, 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, das funktioniert schon erstaunlich gut.
Aber das hat halt 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 Auswirkungen hat, wenn da irgendwie einfach eine lange Liste von vielen unterschiedlichen Wörtern drin steht.
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 Anzahl, wie oft kurz vorgeteilt durch Länge des Textes.
Und das funktioniert halt schon besser.
Also da könnte man irgendwie einen Count Vectorizer nehmen, der würde halt dann zählen, nicht nur binär irgendwie einen großen Vektor bauen, in dem einzelnen Null drinstehen, je nachdem, ob ein Wort drin vorkommt oder nicht.
Das wäre dann schon die Termfrequency, 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 Termfrequenz macht, sondern dann würde man direkt sowas nehmen wie TF-IDF-Vectorizer.
Das Problem bei der Termfrequenz ist halt.
Ich glaube, das habt ihr alle ein bisschen abgehängt.
Erstmal, was ist ein Term Vectorizer, was ist eine TF-ID?
Ja, also im Grunde kann man eigentlich direkt mit dem TF-IDF einstellen.
Wenn man sich jetzt ein Vektor anguckt, wo nur drin steht, ob ein Wort in einem Text vorkommt oder nicht, also 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 halt 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-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, ja, über 40 Jahre alt.
Das ist, glaube ich, Anfang der 70er oder so hat das Kern Spec Jones, glaube ich, irgendwie sich mal überlegt.
Ich weiß es nicht genau.
TF-IDF, vor allen Dingen für Suchmaschinen entwickelt, da möchte man das halt auch haben, man hat halt einen Query und möchte dazu die relevantesten Dokumente irgendwie rausfiltern.
Und diese Gewichtungs-Gewichtungsdienst nennt sich halt TF-IDF, 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
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 wir und man nimmt dann nochmal einen Logarithmus, damit es nicht ganz so schlimm wird, damit es halt so ein bisschen flacher wird.
Genau, genau.
Weil man möchte halt auch nicht so total krasse Unterschiede haben.
Es soll 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, ja?
Genau.
Ja, und
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 rausmacht?
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 Testsets selber machen würde, dann läuft man direkt da in solche Probleme rein.
Wo rechnet man eigentlich die Gewichte?
Nimmt man alle Daten, die man hat, um die auszurechnen?
Hat man da nicht, liegt man da nicht die Tester, dann liegt man nicht die Informationen über das Test-Data-Set schon in das Training mit rein?
Ja, also kann
man das machen.
Ist halt auch die Frage, wie gut sind deine Testan, also 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 überproportional drin vertreten sind und du vielleicht von den Sachen, die da selten drin sind, nicht so viele hast.
Genau, aber dieses Problem, was du gerade sagst, mit dem Training und den Testsaten, das ist halt wirklich so ein klassisches, du, also du hast eigentlich nur zwei Optionen.
Entweder ich sage, ich trainiere mein TFIDF auf allen meinen Daten, auch vom Testset, 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 Testset ist ja nur eine Abstraktion, um irgendwie am Anfang damit trainieren zu können.
Dann tue ich so, als würde ich diese Information 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 und 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 auf deinen 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, äh, 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.
Äh, 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 Datenset eine bessere Methode verursacht, sondern tatsächlich der das richtige Datenset, was wichtiger ist als die Menge an Daten?
Hörte sich gerade ein bisschen so an.
Also ich hätte jetzt intuitiv andersrum gedacht.
Das heißt, je mehr Tests, Daten 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 Tilingdaten.
Achso, gerade gerade nochmal verwechselt wahrscheinlich.
Ja, okay, ja, genau.
Ja, ja, je mehr Trainingsdaten hast, desto besser.
Weil dann würde man Wikipedia zum Beispiel schon nehmen können, wenn das korrekt gelabelt ist.
Dann würde das dazu führen, selbst wenn da mehr als über die
drin stimmen würde.
Wikipedia ist ja jetzt für deinen Anwendungsfall nicht gelabelt.
Ja, genau.
Wenn ich das nicht 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.
Das sind aber doch halt nicht.
Die Menge der Daten und die müssen halt von 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 MORCHS.
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 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 Wikipedia-Daten zu machen, wenn ich eigentlich dann meine Artikel machen möchte, weil das ist wahrscheinlich dann anders.
Das gibt es auch noch in diversen anderen, also das Problem kriegt man halt auch immer wieder.
Also wenn man jetzt zum Beispiel, das ist 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 das, wenn man ein echtes Problem hätte, auf jeden Fall wahrscheinlich auch noch machen wollen würde, ist so sogenannte Word-Embeddings.
Also man würde halt nicht nur einfach nur sozusagen pro Wort eine Dimension nehmen, sondern man würde diese Worte halt aus jedem Wort mehrere Dimensionen erzeugen und halt sie sozusagen eingebettet in so ein Ja.
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 dass 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 Word-Embeddings vor irgendwie drei, vier, fünf Jahren irgendwie sehr, sehr populär wurde und ja,
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 musste halt vorher quasi trainieren und was ich vom Prinzip her mache, ist so eine Art Collaborative Filtering, glaube ich.
Aber ich glaube, das würde an der Stelle jetzt zu weit führen, die, also die würde man jetzt an der Stelle auch vor allem nicht selber trainieren.
Wenn würdest du die, 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 Wörter-Mbedding 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 WörterVec, das Modell von Google, das kann man halt benutzen.
Ja, genau.
Ja, und das hängt aber dann, ist halt die Frage, worauf das dann trainiert ist.
Also wahrscheinlich ist viel Wikipedia dabei, aber bei Google sind bestimmt auch noch diverse Webseiten mit drunter.
Die einen oder anderen.
Ja, und das sind halt so ein paar Gigabyte, die man dann runterladen kann.
Und das verbessert halt, wenn man jetzt eben statt TF-IDF, oder normalerweise, man würde nicht sagen Stadt, 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 das 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 nutzt in der Schwarmintelligenz, ne?
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.
Irgendwie auf so einer ganzen Sprache, auf so einer ganzen Grammatik und das Knowledge miteinander irgendwie rein.
Sag mal so, wenn du genug Trainingsdaten hättest und auch genug Rechenkraft, um das dann halt alles auszurechnen, dann wäre es wahrscheinlich besser, wenn du das auf deine eigenen Daten machst und nicht die auf Wikipedia-Trainierten nimmst.
Wie viel, also hast du gesagt, waren da Reuters-Daten drin, 20.000 irgendwie Datensätze?
Und das heißt, das war nicht historisch, weil da sich halt 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 Data-Set RC V1 oder heißt es 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 Backoff-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 Zircuit Learn eigentlich abgeschaut haben.
Da gibt es halt immer im Wesentlichen zwei Operationen.
Es gibt eben Fit und Transform.
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 herausgenerieren.
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 diesen selben, dieselbe 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 FitTransform, 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, oder wenn ich jetzt eine Klasse habe in Python, die diese Methoden implementiert, ich brauche vielleicht noch mal ein bisschen mehr, muss man nochmal gucken, aber kann ich die halt auch in allen, ja und dazu kommen wir dann später auch nochmal Pipelines und so verwenden.
Und Modelle, die halt diese API implementieren, sind halt, 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 halt hinterher, was rauskommt.
Und ich muss das halt nicht für jedes Modell irgendwie einzeln nochmal anpassen.
Ja.
Genau, wir waren, ja, was sollten wir machen?
Wir wollten ja nichts.
Eigentlich sind wir jetzt bereit, um darauf Modelle langsam zu trainieren, oder?
Genau, wenn ich jetzt, äh, 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 ihm noch sagen, wie er kommunisieren soll oder.
Gewisse Stopp-Wörter rauswerfen, was man auf jeden Fall machen würde, aber ja.
Ja, genau, ob er halt irgendwie das noch irgendwie smooten soll oder ob man welche Normen.
Man kann alles Mögliche da angeben.
Und genau, den habe ich in Trainingsdaten gefüttert und ich benutze ihn jetzt die Transformmethode, um damit sozusagen die Texte aus den Trainingsdaten und aus den Testdaten in so Feature-Matrizen zu verwandeln.
Und genau.
Das sind dann hinterher, ja, das ist auch nochmal so eine kleine Spezialität.
Das ist jetzt natürlich ein, das, was dabei rauskommt, hat relativ.
Also 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.
Also man hat ja natürlich, je mehr Nullen, je mehr Texte man hat.
Je mehr unterschiedliche Wörter man hat.
Ja, genau, richtig.
Ja, genau, das ist ja dann wir wahrscheinlicher, desto mehr Texte hast, desto 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 Einsatz vom Prinzip her.
Das heißt einfach quasi, wie Spaß ist meine Masterwort dafür.
Das ist, genau, Spaß.
Die Daten sind halt sehr spaß und das ist halt ein Problem oder ist halt sehr verschwenderisch, was Hauptspeicher angeht, wenn man tatsächlich die Werte speichern würde.
Und es gibt dann so, ja, aus dem Sci-Pi-Modul irgendwie gibt es dann Klassen, die sich halt mit Spaß, mit dem Speichern von Spaßen-Matrizen irgendwie beschäftigen.
Und ja, da der Trick ist im Grunde, dass man halt die ganzen Nullen einfach nicht speichert.
Dass man sagt, irgendwie, man speichert nur, an welchen Stellen irgendwie Zahlen sind.
Alles andere ist halt default-mäßig null, 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 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 Skalarprodukt.
Man würde den Query in einen Vektor verwandeln, ein Dokument in einen 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 EO null und das wird aufsummiert.
Also es ist einfach weg.
Und daher ist das natürlich toll, wenn man eine Struktur hat, die sowieso, wo sowieso nur die Teile gespeichert sind, die nicht null sind.
Und dann ist es halt alles, 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 Spaß sind.
Es gibt auch welche, bei denen das nicht geht und da muss man halt unter Beständen auch nochmal ein bisschen was machen.
Was man üblicherweise tun würde, also was ein Modell, was man, was immer gut funktioniert, was man normalerweise immer braucht, aber was halt nicht klarkommt mit Spaßen-Daten ist, wäre halt sowas wie XG-Boost zum Beispiel, so ein Decision-Tree-Modell.
X-Tree-Boost?
XG-Boost für Extreme Gradient-Boosting.
Ah, okay.
Und da macht man das eigentlich, oder für alle, ich meine auch, was auch nicht mit, neuronale Netze kommen auch normalerweise nicht mit Swasen-Eingaben klar.
Was man da vorher macht, ist, man reduziert die Dimensionen.
Also wenn das, ich weiß nicht 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 denn ist, was halt dicht ist, dann projiziert man halt das 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 benutzt und projiziert, um die Sachen runterzuprojizieren.
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 Million 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 einer Million 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 Information darüber, wenn ich einfach sagt, 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, ähm, wenn die Spalten ja Wörter sind, dann ist ja gleiche Wörter relativ unwahrscheinlich, aber dann müsste man tatsächlich diese Kombination finden aus der Grammatik, die wir eben hatten, halt das Modul laden dann, was war das?
Wortkonf von Google?
Achso, WordPec, aber.
WordSpeck, genau.
Das könnte man ja nehmen als Information, um irgendwie so eine Kovarianz in den Wörtern festzustellen und die da halt dann so zu gruppieren, dass die halt dann zusammenfassen und die dann.
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 Nachname und die haben genau einmal eine Eins 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, aber 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 er einfach 300 reicht.
Genau, 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 Informationen verloren.
Das funktioniert halt ziemlich gut.
Genau.
Also das ist halt auch sowas, aber das ist halt irgendwie dann doch so eine Geschichte, wo dann, wo man nicht immer irgendwie alles gleich verwenden kann, weil es gibt halt Modelle, die kommen halt mit Zwarsen-Daten klar und manche halt nicht.
Ja, genau, genau, genau.
Gut, aber jetzt wollen wir mal ein Modell trainieren.
Modell trainieren, genau.
Dafür gibt es dann halt auch irgendwie einmal eine Abstraktionsgeschichte, um halt dieses Multilabel-Ding.
Es gibt einige Modelle, die automatisch Multi-Class können, aber Multilabel, da muss man halt, braucht man halt noch so einen Wapper 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 Cyclone Multiclass.
Das Ding heißt One vs.
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 ein Cyclitlearns Metrics-Modul eine Classification Report-Funktion, die halt 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 Plus Regression, das ist nicht so.
Ja, es 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 vs.
REST-Classifier und da das Logistic Regression Modell reingesteckt und dann einmal Fit auf, um das Modell zu trainieren und dann einmal Predigt, um die Voraussagen zu bekommen für die Testdokumente.
Ich finde das 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 und du machst irgendwie Hello World irgendwie Regression oder Klassifikation, dann findest du halt einfach, irgendwo werden Daten vorgefertigt, richtig geladen und dann nimmst du das Modell, importierst es, machst ein Fit, machst ein Predigt und hast dein Ergebnis.
Also das eigentliche Modell trainieren ist kein Problem, aber wir reden jetzt hier schon eine Stunde, eine halbe, 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 Features engineeren.
Und genau, dieser Weg dahin ist das Komplizierte.
Genau, 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 Reporter, das halt über alle 90 Kategorien zu machen, deswegen habe ich jetzt einfach mal die Top-Ten-Kategorien genommen.
Das auch so, wenn man sich dafür interessiert, gibt es halt die Doktorarbeit von Thorsten Joachim, die ist, glaube ich, eines der meistzitierten Papers sozusagen im Textklassifikationsbereich, irgendwie das anderthalb tausendmal 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 werden sich auch, er guckt sich da auch mit 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 die, äh, was man da in Spalten in dem Klassifikationsreport drin stehen hat, sind halt einmal die Namen der Kategorien, dann Precision, Recall, F1-Score und ja, wie viele Beispiele es gab.
Aber 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, also 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, es ist wahr, 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, 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 Kombination 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 ein 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 einen 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 mir 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 dann nachher trotzdem bei einer 0.
Und genau, 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 Absolutskala 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, nee, finde ich genau.
Super erklärt.
Also so F1-Score finde ich jetzt 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.
Und man jetzt Precision und Recall-Wert hat, dann ist es halt blöd.
Man kann halt nicht so richtig gut nach, wenn man zwei Werte hat, irgendwie, wie will man dann sortieren?
Daher muss man das halt irgendwie in einem Wert, in einem 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 könnte jetzt sicher einfach vorstellen, ach, warum nimmt man nicht einfach Accuracy oder so?
Ja, das geht halt nicht so gut.
Also Accuracy funktioniert halt dann gut, wenn das halt, wenn alle Klassen irgendwie 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.
Und 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 ist es, mag das schon so mit den, 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 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 eine Accuracy von 99%.
Klingt doch super, ne?
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 so das.
Diese Irrtumswahrscheinlichkeit ist tatsächlich, glaube ich, relativ relevant auch für den Untersuchungsgegenstand, den man hat.
Ich weiß nicht, ob der Alpha oder Beta-Fehler nennt man es, glaube ich, so in der klassischen Statistik.
Ja, oder viele erster Ordnung oder zweiter Ordnung oder sowas.
Und da ist ja schon sehr entscheidend, also was für einen Untersuchungsgegenstand man hat.
Manchmal ist 5% Abweichung dann ganz okay, bei 95 Trefferwahrscheinlichkeit ist es ausreichend irgendwie.
Vielleicht bei Hund Katze unterscheiden, vielleicht auch nicht ganz so wichtig.
Aber bei anderen Dingen ist halt dann das eine Prozent, 1% so viel.
Also gerade wenn man so Häufigkeitsverteilungen hat wie es kommt nur ein Prozent der Fälle sowas raus und dann falsch stieg ist vielleicht nicht so super.
Ja, aber eben bei Accuracy würde man halt gar nicht sehen, dass man da ein Riesenproblem hat, wenn man die 99% sieht.
Da muss man dann einen negativen Fehler nehmen, dann muss man vielleicht nicht versuchen, Spam tracken, sondern richtige Mails.
Wenn man jetzt Precision Recall nehmen würde, würde man sagen, okay, dann sieht man es halt sofort, weil Precision wäre null.
Also andersrum ist halt tatsächlich dieses Ding.
Wenn du halt den Spam immer versuchst zu tracken und er sagt immer, er spam, dann müsstest du halt das umdrehen, müsstest 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 eher Wahrscheinlichkeit.
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.
Da halt immer das.
Also es gibt auch noch andere Metriken, die man irgendwie benutzen kann, aber das ist schon irgendwie so das Verbreitetste, denke ich mal.
Es 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 dann irgendwie das dann halt auch Ergebnisse irgendwie reportet, ist auch nicht so manchmal nicht so einfach zu erklären, warum man das jetzt so macht und nicht irgendwie einen einfachen einzelnen Wert nimmt oder so.
Ja, da muss man halt gut seinem 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 so, was 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 dranhä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.
Ja.
Genau, also hier erzeuge ich ja sozusagen die Feature-Matrizen direkt aus dem Text.
Aber wenn wir uns jetzt zum Beispiel mal angucken, ja, ich glaube das Script Search-Ding macht das dann halt auch schon so ein bisschen anders.
Was man da normalerweise dann hat, ist halt ja 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, ja, 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 wieder 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.
Also sozusagen, ich habe halt unterschiedliche Spalten, ja, und ich möchte die halt zusammenkombinieren zu einer Feature-Matrix, dann nehme ich Feature Union, das fügt halt die Spalten zusammen.
Und die Pipeline macht halt, 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 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 übergibe der Feature Union, äh, 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, ist der erste Schritt, der nimmt irgendeine Spalte aus dem Data Frame, 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, weiß nicht, wie viele Wörter sind da drin oder sowas.
Ich weiß jetzt gar nicht mehr genau, was es tut.
Und dann skaliert er halt diese, weil das wäre bei der TF-EDF ist es halt automatisch drin, das ist halt irgendwie sozusagen skaliert ist auf ein Intervall zwischen, weiß ich nicht, 0 und 1 und normalisiert, sodass es halt irgendwie alle Vektoren die Länge 1 haben.
Bei den Textstratistiken 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.
Es hängt halt auch mal viel damit zusammen, was für einen Algorithmus du im Nachhinein benutzt.
Manche Algorithmen können gut umgehen mit komplett absolut skalierten Werten.
Also so einem Entscheidungsbaum zum Beispiel, dem ist es 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 ist 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 skannieren 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.
Ja, 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 Supporter-Vektormaschine nehme, die das halt trainiert oder halt Logistic Regression oder halt irgendwie sonst irgendwie 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 speziell, ein Feature halt da so irgendwie, also 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 Unterschiedskalierer und der Standard Scaler macht, glaube ich, irgendwie, ja, weiß ich gar nicht.
Ja, skaliert die halt.
Es skaliert halt irgendwie runter.
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 Regressions-Notebook, ich kann erst meinen Text umwandeln, Dimensionalitätsreduktionen ausführen in der nächsten Zelle und quasi immer dazwischen meine Werte irgendwie in ein neues Data Frame 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, cachen 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?
Nee, 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, das Stichwort wäre Hyperparameteroptimierung, also sozusagen welche Features verwende ich.
Man kann ja dann doch wieder gewichten, wenn man möchte, oder?
Oder mit so Gewichten.
Natürlich, man kann auch einzelne Teile davon, man könnte jetzt unterschiedliche Feature Unions bauen, ne, so eine zum Beispiel, die sich nur mit dem, also es ist ja im Grunde ja auch schon so, also eine Ding, das sich halt nur mit dem Text beschäftigt oder nur eins mit, das sich mit dem Body, äh, mit dem Titel beschäftigt und eins, das sich mit dem Body dieser Tickermeldung beschäftigt.
Und jetzt könnte man diesen Dingern unterschiedliche Gewichte geben auch.
Das auf jeden Fall.
Ja, und 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 Grid Search 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 Grid Search 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 würde man jetzt da irgendwie aus diesem Grid Search-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 ist.
Genau, man muss, also 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 es vielleicht noch relativ beschränkt, aber sobald wir die jetzt zum Beispiel regularisieren, das heißt irgendwie verhindern, dass die irgendwie zu stark sich den Daten anpasst, bekommt die Hyperparameter oder noch einfacher, finde ich, sich vorzustellen bei so einem Entscheidungsbaum, der hat halt eine gewisse Tiefe, der kann irgendwie auf 100 Leveln verschachtelt sein oder nur auf zwei.
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 diese Modell, 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 noch irgendwie selbstlernende Algorithmen.
Warum muss ich denn da jetzt noch Parameter tun?
Aber ich passe ja quasi einfach die, die, man musste, 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.
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 erinnere 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 denn das nochmal?
Man möchte das ja auch an, wenn da mehrere Leute dran arbeiten, denen das ja auch irgendwie kommunizieren und da ist 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 er einem halt einfach das Beste von allen, die er ausprobiert hat, wieder.
Aber ansonsten, wenn du quasi auch so tracken möchtest, was halt gut funktioniert und auch Features reiningen möchtest, du schreibst es dann einfach in CSVs weg oder wie machst du das?
Ja, meistens tatsächlich ja.
Okay, weil das finde ich immer noch ein bisschen überraschend, dass da Cyclic Learn an der Stelle irgendwie nichts von sich ausbietet.
Also ich habe mir jetzt gerade auch diverse Tools angeschaut.
Ich finde da jetzt ML-Flow von Datapricks 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 Predouille, dass er jetzt quasi ein bisschen damit rumspielt und seine ganzen Ergebnisse alle und nach und nach tracken möchte.
Und jeder schreibt sich die irgendwie so ein bisschen auf seine eigene Art weg, aber der Standard-Support 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 Kommandozahlen aufrufen und Shellskripten.
Ich hab 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 im L-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 andere.
Es hängt ein bisschen mehr von deinem Projekt ab, aber gerade für die Exploration finde ich DVC einfach zu viel Boilerplate-Code.
Interessant.
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?
Also den grundsätzlichen Prozess, dieses Datenbeispiel davon 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 natürlich rausfallen oder so.
Aber das haben wir und können auch bewerten, wie gut wir darin sind.
Ja, ja.
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 AP hier 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 dann 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 das liegt?
Und wann sagt man eigentlich, es liegt drin oder nicht?
Genau.
Und das ist, da muss man 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 man dann halt davon ab, welche Art von Problem man gerade hat.
Und ja, genau, dann würde man das halt entsprechend machen.
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 in einem Random Forest, was quasi hier 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, einen einzelnen Entscheidungsbaum 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 und 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, wenn du pro Gewicht irgendwie 4 Byte brauchst für einen Signal Precision Float, dann ist es halt viermal, bei denen bei dem ist es 25.000 wahrscheinlich mal, also 4x25.000, also 100 Kilobyte, ja, ist ja nichts.
Aber wenn du jetzt zum Beispiel viele Trainingsdaten hast und du hast halt einen, also das ist ja auch noch so eine Geschichte, es gab in dem Explorationsnotebook auch so einen 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.
Macht natürlich nur Sinn, wenn man viel, viel mehr Trainingsdaten hat, aber wenn man jetzt irgendwie ein Modell hat mit 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 halt 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 offen gemacht wird, auch auf ein Telefon.
Und da muss man dann halt vielleicht noch ein bisschen gucken, was die Größe angeht, aber
das Schöne ist ja vor allem eben eine Prognose jetzt mit so einem Modell zu berechnen.
Das 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 es einfach auf einem 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 lauf einmal mein neuronales Netzwerk von vorne nach hinten durch und fertig.
Und genau, das kann dann halt auch.
Dann kann ich natürlich relativ schnell sagen, wo ich hin soll, ja.
Genau, es kann auf schwacher Hardware laufen.
Ja, cool.
Jo, 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 Kegel mal einen Account.
Ja, Kegel, 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.
Oder mal so nachbauen oder so, welche die schon gaben, mal gucken, wie gut man an die tollen Lösungen irgendwann rankommt.
Genau, also beziehungsweise das Schöne ist ja bei Kegel, dass diese ganzen Lösungen eigentlich immer einfach alle online sind.
Also diese Kaggle, 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, also vielleicht noch ganz kurz, in Kegel gibt es Bounties dafür, wenn man total tolle Prognosen herstellt, zumindest 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 topgerateten Notebooks da durchlese, lerne ich jedes Mal wieder was.
Finde ich auch super hilfreich.
Ja, schön, dass ihr wieder alle eingeschaltet habt.
Ihr findet immer die Informationen in den Shownotes.
Genau, die Welt.
Ja, ja, das kennen wir ja 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.python podcast.de oder Nico.
Und ja, bis dahin.
Genau.
Hört wieder rein und bis bald.