Transcript: PP07 - Machine Learning am Beispiel Textklassifikation

· Back to episode

Full episode transcript. Timestamps refer to the audio playback.

Ja, dann hallo liebe Hörerinnen und Hörer. Schön, dass ihr wieder da seid, dass ihr wieder zugeschaltet habt beim Python-Podcast in der siebten Episode heute. Heute geht es um Machine Learning. Und ja, wir haben heute wieder einen Gast dabei im Wintergarten. Hallo Nico.

Hi, schön weich zu sein.

Ja, und Jochen ist natürlich auch wieder da.

Ja, Jochen. Genau.

Genau, ich bin der Dominik. Wir sollten uns, glaube ich, nochmal kurz vorstellen für den Nico, weil wir wahrscheinlich diese Folge irgendwie auch bei Nico veröffentlichen dürfen. Auf Nicos tollen Podcast InnoCast heißt der noch?

InnoTechCast, genau. Der InnoTechCast ist mein Podcast-Projekt, läuft auch so seit ein bisschen über einem Jahr jetzt. Und da geht es halt nicht nur konkret um Python, sondern um alle möglichen Sachen, die irgendwie Nerds und ITler interessieren könnten.

Irgendwie von Containern über irgendwie so Desktop.

Ja, Forbes-Geschichten, einzelne Programmiersprachen. Was haben wir so gemacht? Wir haben Go gemacht, wir haben Rust behandelt. Wir hatten auch schon mal eine Folge so ein bisschen zu Python.

Also es ist auf jeden Fall sehr spannend. Hört da mal rein. Kann ich empfehlen. Klingt gut.

Genau.

Ja, dann fangen wir doch mal mit dem richtigen Thema an jetzt und gehen das Beispiel durch, was wir für das Machine Learning machen wollen.

Ja, wahrscheinlich sollten wir erstmal so ein bisschen...

Erstmal nochmal so allgemein vielleicht, was ist denn das überhaupt, das Machine Learning? Was macht das denn?

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 da raus?

Ja, das ist das Gefühl, was man heute in den Medien, finde ich, irgendwie immer bekommt.

Also es ist halt so ein Buzzword, was überall rumschwirbt, genauso wie irgendwie künstliche Intelligenz.

Genau. Aber im Wesentlichen geht es ja darum, im Endeffekt gewisse Strukturen in den Daten zu finden, um eben Prognosen über die Zukunft zu lernen.

Das heißt einfach, ich programmiere nicht mehr alles komplett deterministisch runter, was ich irgendwie wie von einem gewissen Eingabewert zu einem gewissen Ausgabewert komme, sondern ich habe halt eine gewisse große Menge an Trainingsdaten und habe dann Algorithmen, die gewisse Parameter anpassen bei solchen sogenannten Trainingsläufen und daraus quasi generelle Strukturen aus den Daten erkennen, um dann damit letztendlich Schlussfolgerungen für die Zukunft oder für unbekannte Daten zu ermöglichen.

So hätte ich das.

Hast du das zusammengefasst?

Ja, würde ich prinzipiell genauso.

Der Computer lernt so, was er mit neuen Sachen dann anfangen muss, aus alten Dingen.

Genau, es gibt keine allgemeingültige Definition, was jetzt Machine Learning ist, aber 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.

Wenn man das jetzt mit traditionellem Programmieren vergleichen würde, dann ist es halt so, dass man eben selbst, wenn man eben programmiert, sozusagen diese Zuordnung von, man bekommt irgendwelche Eingaben und dann soll halt irgendwie irgendwas rauskommen am Schluss, machen muss und wenn man jetzt Machine Learning verwendet, dann macht diesen Schritt halt wie ein mathematisches Optimierungsverfahren und das sich orientiert an Trainingsbeispielen, an Beispielen für das ist reingegangen und das ist rausgekommen und so sollte das halt sein.

Aber genau, das ist ja auch das, was dann der Mensch dann doch wieder macht, ne? 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.

Ja, es gibt auch diverse Probleme, die man sonst gar nicht in den Griff kriegt. Also wo man tatsächlich versucht hat, einen Algorithmus zu schreiben, der das tut, wie zum Beispiel eben sowas wie bei Bildern Katzen von Hunde unterscheiden oder so, aber das geht halt gar nicht, weil man das halt nicht wirklich in einen Algorithmus reinbekommt.

Man kann nicht so ein Gegenstand definieren, wo eine Katze ist irgendwie so ein kleines Tier und grau und weiß und so weiter.

Ja, das ist schwer.

Ja, oder auch das Arbeiten mit Sprache finde ich ein gutes Beispiel. Da hat man halt viele, viele Algorithmen entwickelt, die auch...

Auch zu einem gewissen Grad funktionieren, aber man ist mit Übersetzungen halt einfach quasi dann auf so einem Plateau spägen 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, 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.

Ja, aber natürlich ist es immer schwer für Leute, die das jetzt nicht so in Detail verfolgen können und wer tut das halt, außer die nicht 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 davon ausgeht, dass das irgendwas Magisches ist, dann geht halt alles und das ist ja jetzt auch nicht so.

Ja, aber das ist genau der spannende Punkt. Du hast nämlich genau gerade versucht zu erklären, dass...

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 bei Maschinenlöhne noch einstellt und das halt dann so durchblicken, also was das zu tun hat jetzt mit Statistik oder so, das ist vielleicht nochmal ganz spannend, weil dann würde man vielleicht auch nicht nur glauben, dass Magie, also ne, vielleicht sowas mit zu tun, wenn irgendjemand neue Sachen erfindet, irgendeine Geometrie entdeckt, dann ist das vielleicht auch ganz magisch für jemand, der sowas noch nie gesehen hat und deswegen ist halt diese künstliche Intelligenz gar nicht so künstlich.

Wie wir dachten, aber dann trotzdem so ein Phänomen, was gerade, ja, bei den Leuten, die sich damit nicht auskennen, so ankommt.

Ja, also wenn man das guckt, 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 einer Katze unterscheiden, wie soll das denn gehen, so, ne?

Genau, genau, ja.

Wie, der Computer weiß, was ich da gerade gesagt habe und kann mit mir sprechen oder so, das ist schon phänomenal irgendwo.

Ja, aber ist das nicht eigentlich immer so? Also, wenn man halt quasi irgendein Blackbox-Modell hat und da nicht reinschauen kann, dann...

Ist das, wirkt das wie Magie und wenn man halt nach und nach die Informationen da drin versteht, dann, ja, blickt man halt, okay, das hat gewisse Schlussfolgerungen, ich meine, das hat schon ein Grund.

Verstehen wir die wirklich bei Machine Learning? Das habe ich jetzt nämlich auch noch nicht so ganz verstanden.

Nee, genau, da gibt's, ja, gibt's 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.

Ähm, bei eben Blackbox-Verfahren wie so neuronalen Netzen oder so kann man das prinzipiell eigentlich nicht wirklich, also man kann zwar sehen, welche, äh, was das Ding gemacht hat und, und, ähm, auch irgendwie, was es erkannt hat und, 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.

Ähm, werden sie halt auch sehr groß, also wenn ich dann mehrere, ja, Millionen reicht ja schon, aber wenn ich dann mehrere hundert Millionen Parameter habe, dann, äh, ist das eine Menge, die ich als Mensch ja überhaupt nicht mehr überlegen kann, ne, das ist halt, äh.

Für gewisse Objekte zu verstehen, wie das Modell quasi zu diesem Schluss kam, ähm, also so Blackboxig sind diese, ähm, also diese neuronalen Netze jetzt gar nicht mal mehr, ähm, auch da gibt es Möglichkeiten, die zu verstehen, aber ja, also klar, das ist natürlich deutlich komplexer als jetzt ein Entscheidungsbaum, den ja wahrscheinlich jeder mehr oder weniger kennt, was nicht viel anders ist als ein Flussdiagramm.

Aber vielleicht wollen wir kurz dann 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 da.

Also, ob wir jetzt so ein neuronales Netz oder so ein, so ein Decision Tree verwenden möchten, würde das Sinn 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, ähm, 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, ähm, gewisse Zeitreihe vorhersagen möchte, ähm,

ähm, mit relativ einfachen Mitteln, um vielleicht den Abverkauf von meinem Produkt, ähm, vorherzusehen oder die Temperatur oder sowas, dann gibt es da jetzt erstmal Regressionsverfahren, die so schon sehr gut funktionieren und da muss man jetzt nicht zwangsläufig irgendwie Deep Learning draufwerfen, ist halt eben was anderes wie bei der Bilderkennung, die du jetzt zum Beispiel erwähnt hast.

Gut, Regression ist natürlich immer nur so gut, wie, ähm, die Zukunft, äh, der Vergangenheit entspricht, ne, das ist ja vielleicht immer das Problem.

Ja.

Aber das Problem haben Deep Learning Algorithmen an der Stelle genauso.

Ähm, ja, okay.

Also, natürlich hast du da nicht unbedingt dann immer so einen linearen Zusammenhang, aber, äh, ja, im Grunde natürlich so Dinge, die komplett neu sind.

Ja, wenn, ja, Alph oder sowas, das ist ein Hund oder eine Katze, weiß man nicht so genau, ja, dann kommt was Neues auf die Welt.

Äh, äh, genau, ne, also da, es gibt auch Verfahren, die, die, die total einfach zu verstehen sind, ne, also sowas wie, wie Naive Base zum Beispiel, das ist eine der ersten, äh, äh,

Geschichten, die, äh, also, ich glaube, 2004 hatte Paul Graham halt da irgendwie den, einen Artikel veröffentlicht, The Plan for Spam, äh.

Jetzt musst du nochmal einmal kurz sagen, was Naive Base ü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, äh, den man immer beschreiben kann, halt binäre Klassifikationen, vielleicht, so, äh, womit man anfangen kann, und, ähm, ja, äh, äh, Naive Base ist halt ein,

also binäre, quasi, Klassifikationen, also, drin oder nicht drin, äh, genau, man unterscheidet eigentlich nur zwei Klassen, genau, und, ähm,

im Supervised Machine Learning gibt's dann im Wesentlichen unterschiedliche Tasks, es gibt eine Regression, oder es gibt eine Klassifikation als die beiden typischsten Fälle, und, genau, jetzt, so, 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, ähm, ich such mal grad, ob ich das hier, äh, finde, Moment, äh.

In der näheren Klassifikation, bevor wir dann vielleicht tatsächlich darauf eingehen, was für eine Möglichkeit man hat, jetzt so diese Klassifikation durchzuführen, weil, weiß ich, mehr als zwei Dinge, also wenn du zwei Merkmale hast, dann kannst du ja relativ einfach voneinander trennen, wenn die homogen sind untereinander in ihren eigenen Klassen und das wird ja umso komplexer, umso weniger heterogen die untereinander sind, also umso mehr die sich gleichen, dann hast du natürlich größere Probleme, dann ist es vielleicht auch so, dass du die Merkmale falsch anguckst oder so, also du sollst halt schon unterscheidende Merkmale finden können.

Und das ist halt im Prinzip das, was du mit Base dann relativ gut machen kannst, du kannst halt dann sagen, ey, ist jetzt der Fighter grün oder nicht, oder schwarz oder so, oder ist das halt eine Katze, woran erkennt man das? Ich weiß nicht, ob sich jetzt Base für Katzen und Hunde schon eignen würde, weil, das wird vielleicht schon schwierig.

Ja, also für Bilder wird das sicherlich nicht gut funktionieren, aber wenn ich jetzt, eben, das ist halt auch so ein klassisches Beispiel habe, wenn ich jetzt Spam von Nicht-Spam-Mails unterscheiden möchte, da ist halt genau so, 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 Perl-Script-Spam-Assassin, das hat sich dann halt die Header angeguckt und dann hat es halt manchen Providern mehr und manchen weniger vertraut und irgendwelche, und dann insgesamt halt irgendwie einen Score ausgerechnet und gesagt, ah, okay, das hat jetzt einen Spam-Score von so und so viel oder so und so viel und ab einer bestimmten Grenze wurde dann halt abgeschnitten und gesagt, das ist Spam.

Das hat ganz okay funktioniert, aber...

Das war immer leicht zu unterlaufen von Spammern und das war, und Spam war immer eine relativ ärgerliche Geschichte, bis dann halt eben Paul Graham, halt der, ja, wie heißt der Inkubator, den er gegründet hat, darüber ist er sehr bekannt geworden, habe ich jetzt gerade, ist mir entfallen, also der schreibt auch viele Essays und hat auch ein Buch geschrieben...

Y-Combinator tatsächlich.

Y-Combinator, natürlich.

Ich wollte hart unterzungen, ich habe mich nur nicht getraut.

Ja, der schrieb dann halt irgendwie 2004 ein Essay, so, a plan for Spam, also ich habe da irgendwie so eine Idee, wie wir dieses Problem endgültig in den Griff kriegen und da schlägt er halt vor, irgendwie so Naive Base zu verwenden, um inhaltsmäßig irgendwie Spams, Vernichtspams 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...

Dann kann es auch der Mensch nicht mehr als Spammer kennen und dann verfehlt er seinen Zweck und der...

Liebe Freund, ich brauche in 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?

Ja.

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, ja.

Genau, und zwar, das Verfahren ist halt super einfach.

Das ist halt...

Mach einfach aus den Mails, aus dem Inhalt deiner Mails im Spamordner eine lange Liste von Wörtern.

Zähle, wie oft ein Wort da drin halt vorkommt.

Merke dann die Gesamtzahl der Wörter und die Gesamtzahl der Mails, die da drin waren.

Und mach das Ganze auch nochmal für den Ordner mit den Nicht-Spam-Mails.

Und das ist schon das Training.

Das war's.

Also man hat jetzt quasi an jedem Wort sozusagen nur dranstehen, quasi, ja, wie oft das halt vorkommt.

Und man hat nochmal eine Zahl für, ja, wie viel Mail...

Da sagt der Eigentümer, uh, er hat Penis gesagt.

Und dann sagt der, nee, ist wahrscheinlich Spam.

Also so in etwa.

Genau.

Und die Klassifikation, also wenn man das gemacht hat, ist man mit dem Training schon fertig.

Und das ist auch schon das Modell.

Und die Klassifikation funktioniert jetzt so, wenn man jetzt eine zu prüfende Mail hat, dann zerlegt man die eben auch wieder in eine Liste von Wörtern.

Man macht aus dieser Wortliste eine Liste von Zahlen.

Und man ersetzt jetzt jedes Wort.

Und 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, dann ersetzt man 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.

Und die noch miteinander multipliziert.

Das ist super.

Das heißt, man muss das Ganze noch so normalisieren, dass hinterher halt irgendwie quasi der Wert für Spam und Nicht-Spam, wenn man das addieren würde, 1 ergibt.

Aber, ja, das ist ja auch kein Problem.

Und das war es schon.

Also es ist wirklich nicht, es ist keine große, ja, es ist keine, wie soll man sagen, Raketenchirurgie.

Das ist eigentlich eine ziemlich einfache Geschichte.

Genau, das kann man ja einfach sich eigentlich auch noch so in einem Algorithmus darstellen.

Da braucht man, ja, keine komplexen Selbstlernverfahren eigentlich noch, nicht wahr.

Ja, also gut.

Und deswegen lernt man tatsächlich.

Also wenn ich jetzt sage, wenn jetzt eben, ich habe bisher nur Mails, die mir Produkte zur Vergrößerung meiner primären Geschlechtsmerkmale,

die mir so und so was andrehen wollen, bekommen.

Und ich kriege jetzt zum ersten Mal einen 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-Montage reintun.

Und dann müsste ich halt wieder neu...

Diese Zahlen ermitteln.

Genau, die müssen halt wieder neu gebildet werden, aber...

Dann würden sich die Frequenzen wahrscheinlich zum Beispiel für so ein Wort wie Prinz oder so oder Schweizer Bankkonto entsprechend verändern.

Und dann hoffentlich beim nächsten Mal werden wir dann so eine Mail dieser Art...

Das finde ich ärgerlich für Prinz mit Schweizer Bankkonto.

Ja, die haben ein Problem damit.

Die werden, ja, die haben mit Meldern keinen Spaß mehr seitdem.

Genau, und das, ja, und dann passt sich das durchaus.

Mit quasi neuen Mustern an, wenn die nächste Masche um die Ecke kommt, dann braucht man halt nur die ersten paar sozusagen richtig zu sortieren

und dann sollte das automatisch funktionieren und mitlernen.

Ja.

Ja, ich habe ja kurz eine Base-Kalzifikation erklärt.

Wir sind aber immer noch nicht bei dem Beispiel angekommen, was wir irgendwie den Menschen...

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 Text-Klassifikation.

Und genau, wenn man da drauf geht, sieht man in dem Readme auch erstmal irgendwie alle Informationen,

wie man sich das Ganze zieht.

Also man klont sich halt erstmal das Gits-Repository.

Soweit, so gut.

Und dann kommen auch schon die ersten Python-spezifischen Sachen,

denn dann müssen wir uns erstmal irgendwie mit Conda eine entsprechende Umgebung aufsetzen.

Jochen, sag doch mal, warum sollte man das denn mal machen?

Und warum denn Conda?

Ja, also Conda ist sozusagen der 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 Leute, die die Firma gegründet haben,

sind auch die, die ursprünglich mal NumPy mitentwickelt haben und so.

Und, ja, es ist...

Früher hatte man ja irgendwie mal so die Hoffnung,

dass die Distribution, das ganze 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 ein bisschen besonders schlimm,

weil da gibt es halt nicht nur einen, sondern mehrere.

Je nachdem.

In welcher Community man sich da aufhält,

wenn man irgendwie eher Webentwicklung oder sonst wie Python-Entwicklung macht,

dann ist es eher Pip und als Repository für Pakete halt PyPI.

Ich würde sagen, das Problem hat nicht nur Python.

Nee.

Rust ist da auch ganz schlimm, habe ich schon gelernt, aber ja.

Nee, genau.

Ja, das wäre 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 Webprojekte mache, dann nehme ich...

Äh, 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, wenn man ein Selbstverwahrt,

der irgendwie auch nur irgendwie Pandas noch mitbraucht,

um halt irgendwelche Sachen anzupassen.

Ein Webserver, 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 bei Pip installieren,

aber wenn ich jetzt irgendwie was trainieren wollte,

dann würde ich eher die Conda-Pakete nehmen

oder vielleicht sogar spezielle Docker-Images oder sowas.

Also, ja, aus meiner Sicht hat halt Conda vor allem zwei Vorteile.

Zum einen ist es halt schon mal gekappt,

also zusammen das, was sonst Pip und Virtual Env ist.

Also ich habe die Möglichkeit,

sowohl eine virtuelle Umgebung hier zusammenzubauen

und dann halt eben in die die Pakete mit rein zu installieren,

was man häufig möchte, wenn man gerade zum Beispiel so ein Experiment macht,

dann möchte ich vielleicht meine Basis-Version an Paketen so lassen,

wie ich sie hatte und dann halt mal für jetzt eine Konferenz zum Beispiel

mir nochmal eine zweite daneben stellen.

Das müsste ich ja sonst mit Virtual Env und Pip quasi in zwei Schritten machen.

Ja gut, aber normalerweise machst du ja Virtual Env Rapper,

dann einen Befehl und dann ist das Ding ja oben.

Genau.

Ich habe da tatsächlich ein Python-Skript für sowas geschrieben.

Der auch genau das gleiche macht, wenn ich das will, aber ja.

Genau, und der zweite Punkt ist,

Conda kann halt einfach ja noch ein bisschen mehr als Pip.

Es kann halt vor allem auch quasi Abhängigkeiten,

die außerhalb von Python-Paketen liegen, lösen,

was dann halt auch interessant wird,

wenn es halt um Treiber-Support und so weiter geht.

Genau, aber ich glaube, du hast schon recht,

dass es auch so ein Stück weit ein Community-Ding ist,

dass es sich halt im Data-Science-Umfeld

auch durch den starken Support von Continuum da

und den finanziellen Mitteln, die dahinter stecken,

so durchgesetzt hat.

Ja, aber...

Ja, ja, also...

Weil es so einfach zu installieren ist auch.

Es gibt halt auch, glaube ich, nur Windows-Binarys einfach

und da ist dann alles mit dabei an Modulen, was man so hat

und man muss das gar nicht mehr groß bedienen.

Ich glaube, das ist auch so ein low-leveliger Ansatz.

Das ist auch der 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 Mini-Conda 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 Mini-Conda ist halt erstmal klein und schlank

und dann muss man halt alles quasi mit dazu installieren,

was man dann noch gerne hätte.

Ja, und eben der Vorteil gegenüber Pip

oder sagen wir mal so,

das ist halt auch nicht mehr so ganz...

Das war früher ein Riesenunterschied,

ist heute nicht mehr ganz so relevant,

ist halt, dass man halt binäre Geschichten

bei Anaconda auch installieren kann.

Also man kann halt auch Bibliotheken,

die unten drunter liegen,

also eben nicht nur Python-Pakete,

sondern eben auch sowas.

Man kann auch theoretisch sowas wie

Libc irgendwie mit Conda installieren

und die dann halt in einem Conda-Environment verwenden.

Und muss halt...

Also das ist auch so ein Problem,

wenn man jetzt auf größeren Servern unterwegs ist,

die halt unter Umständen irgendwie

so eine antike Debian-Version irgendwie haben

und eine uralte Libc

und die funktioniert dann mit neueren,

anderen Bibliotheken nicht mehr gut.

Dann hatte ich auch schon den Fall,

dass ich dann per Conda irgendwie eine neue Libc

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 Web-Geschichte ist

oder was ganz anderes,

dann ist es eher Pip.

Ist das denn immer genauso aktuell in Conda

wie auf PyPy?

Nee, Conda ist nicht so aktuell.

Es gibt ja noch Conda Forge,

also sozusagen ein...

Da kann man sich selber Sachen bauen.

Ja, das kann man sowieso,

aber es gibt halt einmal die Pakete,

die sozusagen von der Firma gebaut werden

und ein Repository von Paketen.

Das ist halt eine Distribution,

die halt sozusagen redaktionell

von Continuum Analytics gepflegt wird.

Und es gibt halt auch

ein Community-basiertes Repository,

das nennt sich dann Conda Forge.

Und man kann das halt in dem...

Man hat immer so ein Konfigurations-File

und da kann man halt die Channels sozusagen,

aus denen man Pakete bekommt,

halt eintragen.

Und ja, die meisten verwenden Conda Forge.

Ist es jetzt auch irgendwie so,

dass, glaube ich,

Anaconda selber irgendwie

auf Conda Forge umgestellt hat?

Ja, genau.

Die haben sich das umgestellt.

Das haben wir gehört.

Das gehört auf dem Parkcamp 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 meistens mal gegoogelt,

was ist denn jetzt hier das richtige Repo dafür

und das ist jetzt aber seitdem quasi weg.

Ja, ist tatsächlich anstrengend,

wenn man halt schon unterschiedliche Pakete

hinterhat und dann auch seine eigene Source dafür

irgendwie letztendlich bestimmen muss.

Ich kann mich da an ein oder andere Experimente erinnern

mit so Paketsachen und Sources.

Alles nicht einfach.

Aber hatten wir das schon erwähnt,

warum man das überhaupt machen sollte?

Ja, das...

Das Problem ist eben,

dass die Pakete in der Distribution

halt nicht wirklich aktuell sind meistens.

Also, wie sagte Barry Varsaw, glaube ich,

einer Python-Core-Entwickler,

sagt er mal,

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,

mit halt Python 2 irgendwie noch als Default-Interpreter,

bei Mac auch.

Es gibt einen Counter für Python 2 mittlerweile.

Hatten wir den gesehen?

Desk Clock, ja.

Ich bin mal gespannt,

wenn die Vertriebssysteme es dann auch mal sich trauen.

Das war schon ein bisschen heiter 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.

Ja, doof.

Und daher muss man sowieso eigentlich

immer einen anderen Python-Interpreter verwenden,

als der, der vorinstalliert ist.

Und dann ist es halt so,

wenn man unterschiedliche Projekte hat,

dann haben die halt unterschiedliche

abhängige Projekte,

was bestimmte Bibliotheken angeht.

Und die widersprechen sich halt.

Und das kriegt man halt auch,

wenn man in einem Filesystem ist.

Und das kriegt man halt nicht irgendwie unter einen Hut.

Und daher macht man normalerweise pro Projekt

ein eigenes, sozusagen virtuelles Environment,

in dem man halt irgendwie

alle Abhängigkeiten installiert, die man braucht.

Ist dir schon mal vorgekommen,

dass du für ein Projekt zwei

virtuelle Environments brauchst,

weil da innerhalb des Projektes

sich unterschiedliche Module bespricht?

Nee, das geht auch gar nicht.

Oder, ja, also natürlich doch, stimmt,

man könnte es theoretisch machen.

Aber nee, das ist mir jetzt auch noch nicht

untergebracht.

Was meinst du denn halt von einem Projekt?

Ja, also man könnte ja irgendwie sagen,

dass es zwei Module in einem Projekt gibt,

die unterschiedliche Versionen brauchen,

Python-Versionen,

weil die Module das sonst nicht können

und die man dann irgendwie pipen muss,

damit die man da reden kann.

Und um das dann zu bauen,

müsste man halt dann zwei Versionen benutzen.

Nehmen wir zum Beispiel mal an,

man hätte ein OCR-Projekt

und man möchte jetzt irgendwie

ein aktuelles Ding gegen was Älteres

wie OCR-OPI oder Kraken oder so verwenden.

Nehmen wir mal an,

Kraken kann auch Patentreiber.

Das OCR-OPI kann nur,

OCR-OPI kann nur Python 2

und jetzt möchte man halt das Ding aber

testen gegen was Neues,

was halt vielleicht nur Python 3 kann

und dann müsste man zwei Interpreter halt haben

irgendwie in dem,

ja, das wäre hässlich.

Aber ich glaube,

so kompliziert müssen wir es gar nicht machen.

Nee.

Genau, also wenn ihr euch inzwischen

das Repo ausgeklont habt,

dann ist jetzt vielleicht der richtige Moment,

einmal Corner-Inf-Create auszuführen,

um die Umgebung nicht aufzusetzen.

Was an der Stelle ja passiert ist,

er zieht sich von lokal eben

eine hinterlegte,

äh, 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 seinen

Default-Python-Interpreter gesetzt.

Also Corner-Inf-Create macht dann genau das,

dass er einfach ein Environment setzt,

die heißt dann Great, oder was?

Nee, das steht in dem, äh,

in dem File halt auch mit drin.

Der Name von dem.

Von dem, ähm, äh,

von dem Environment, genau.

Ähm, ähm,

ähm, warte mal, genau, äh,

das ist auch einfach ein YAML-File

und da steht dann eben das erste Name

und da steht dann DS-Tutorial

für das neue Tutorial.

Und dann Dependencies, ach, und dann werden die Pakete danach gepackt.

Und, ach so, das ist auch so,

man kann halt auch, äh, genau,

man kann auch Sachen per PIP installieren.

Ja, das ist auch sowas, also es ist halt

irgendwie, äh, ja,

Conda ist quasi eine echte Obermenge von

PIP, also man kann halt Conda und halt

auch PIP, aber umgekehrt geht's halt nicht.

PIP kann halt nicht Conda Sachen installieren.

Ähm, ja, und manche Sachen installiere ich

via PIP, weil das einfach aktuellere

Versionen dann sind, ähm.

Ja, oder halt, wenn man was sehr Spezielles

will, ist es vielleicht auch nicht unbedingt

immer in jedem Conda-Repository eben drin.

Ähm, 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, genau, das kann ich auch machen, ja.

Genau, und danach müsst ihr, um das Repo

quasi so ausführen zu können, nochmal,

ähm, das lokale Paket

bauen, und zwar mit Minus E.

Ja. Ähm, warum wollen wir

denn erstmal überhaupt ein lokales

Paket, und warum wollen wir Minus E?

Mhm, ähm, ja,

ein lokales Paket, äh, deswegen, weil

man in vielen Notebooks halt,

also, ich hab das Ganze quasi ein bisschen

in unterschiedliche Notebooks aufgeteilt, und da

gibt's dann halt, ähm, einige, die halt

immer wieder den gleichen Code enthalten,

und jetzt könnte man natürlich auch in jedes Notebook

irgendwie reinkopieren, aber wenn man

dann gemerkt hat, oh, ich hab 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, äh, in

mehreren unterschiedlichen Notebooks, äh,

benötigt, den, äh, kann man ja aber auch

einfach in eine Bibliothek, und das ist halt

im Grunde dieses Paket, äh, was man

da installiert, ähm, rausziehen,

und den importiert man dann halt

einfach nur in allen Notebooks, und wenn man da jetzt

ein Fehler fixt, dann ist der halt in allen Notebooks gleichzeitig

gefixt und Minus E installiert man deswegen, um Änderungen,

wenn man da jetzt eine Änderung macht, die sofort

sichtbar werden zu lassen. Also ansonsten müsste man ja eigentlich, wenn man

ein Paket zum Beispiel via PyPI oder so installiert oder normal installiert

sozusagen, jedes Mal, wenn man was ändert, ein neues Paket bauen

und dann dieses Paket wieder installieren. Und

am besten auch nochmal das Notebook neu starten. Und das ist

natürlich ein bisschen umständlich und wenn man sagt pip install minus

E, dann macht das sozusagen keine wirkliche

Paketsinstallation, sondern legt nur einen Link auf das

entsprechende Verzeichnis sozusagen mit nach Side-Packages und

wenn sich da irgendwas ändert

am Code, dann ist das halt sofort irgendwie sichtbar und

dann kann man 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 Notebook neu starten muss, was ja auch praktisch ist.

Man kann das ja fein und granular einstellen. Man will das

vielleicht auch nicht für alle Module machen, aber wenn man das richtig

eingestellt hat, kann man halt, wenn man jetzt

beispielsweise bei einem Code-Teil, der halt

in vielen Notebooks verwendet wird, einen Teil ändert,

dann ist die Änderung sofort da und

bei der nächsten Ausführung

einer Zelle hat man halt auch

schon den geänderten Code mit ausgeführt

und muss da nichts neu installieren,

neu starten oder so.

Da kann ich auch jeden nur zu ermutigen,

zu gehen. Also ich habe mich da am Anfang lange vorgescheut

und habe einfach quasi am Anfang

von meinem Notebook einfach immer mit der

Run-Magic quasi in ein anderes

Notebook gestartet, wo ich alle diese Sachen

initialisiert habe. Das geht auch,

aber das muss man halt dann doch, wenn man in einem anderen Notebook

was ändert, immer noch einmal ausführen

und so viel Zauber

ist es gar nicht, quasi sich selber so ein Paket

zu erstellen. Vor allem ist es auch ein ganz cooles Gefühl.

Man kann es danach auch wirklich direkt mal weitergeben

und weiterleiten und es verleitet

zu ein bisschen besserer

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.

Und wir sind beides umgekehrt für die Studie,

Code? Ah ja, okay.

Ich benutze immer noch alles. Also ich benutze auch immer noch

vor allen Dingen häufig

Wim. Ich benutze auch

PyCharm und auch VSCode.

Ich hatte das mir auch schon gezeigt.

Das ist schon ziemlich gut, muss man sagen.

Genau. Ich meine, am Anfang ist so ein bisschen overhead

mit dem Anlegen von so einer Klasse da, aber

ihr benutzt, glaube ich, so Cookie-Cutter-Templates.

Ja.

Ich benutze PyScaffold,

was ein Projekt ist, was von einem Kollegen von mir

entwickelt wird, was mir da sehr geholfen hat.

Einfach am Anfang quasi so

Scaffolding, mir

mein Gerüst einmal aufzusetzen. Da kenne ich mich

dann direkt dran aus und dann trinke ich da noch meine

zwei, drei Zeilen ein und bin

gleich da. Und das hat mir

so ein bisschen die Angst davor genommen, eigene Pakete

an der Stelle zu schreiben.

Ja.

Genau. Gut. Und

dann können wir letztendlich wirklich

unser Notebook starten.

Du benutzt noch Jupyter

Notebox. Ja, stimmt.

Magst du JupyterLab lieber?

Oder warum magst du kein JupyterLab?

Doch.

Ja, stimmt. Mag ich auch.

Das ist jetzt auch nur so reine Gewohnheit eigentlich.

Aber ja, eigentlich im Grunde

müsste ich auch mal auf JupyterLab umsteigen.

Ja.

Genau. Also gerade die neuen Versionen mit den Plugins,

finde ich, es kommt... Also am Anfang haben wir

noch ein paar Funktionalitäten von JupyterNotebooks

gefehlt, aber jetzt gerade

mit dem sich ausbreitenden

Plugin-System gibt es da echt coole Sachen.

Zum Beispiel, was ich total liebe gerade,

ist halt die Sublime Keybinding

Magic-Funktionalität, die man jetzt einfach sich

so in die JupyterLab-Notebook

reinladen kann.

Und so. Aber genau.

Ja, ja, ja.

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...

Genau.

So. Egal, ob ihr jetzt ein

JupyterNotebook oder ein ehemaliger...

Ja. Egal, ob ihr jetzt ein JupyterNotebook

oder halt schon JupyterLab gestartet habt,

müsstet ihr jetzt quasi

eine Reihe an

Ordnern sehen und

im DS-Tutorial...

Nee, im

Ordner Notebooks gibt es halt eben

das Projekt TestTextClassification

und dem wollen wir uns mal ein bisschen widmen.

Genau. Ja.

Vielleicht kann man einfach direkt mal das

ExploreData-Notebook aufmachen.

Das ist

das Dataset, also

ist man natürlich auch mal ein bisschen darauf angewiesen, dass es

halt ein frei verfügbares

Dataset gibt, das ich

da verwendet habe, ist

das

Reuters

21578

Textklassifikations-Dataset.

Das ist so ein klassisches Ding,

wo

irgendwie eben entsprechend viele

21578

so Ticker-Meldungen

drin sind.

Und die sind halt klassifiziert

in

unterschiedliche Kategorien.

Und bei dem Set geht es auch

im Grunde darum, Modelle zu

bauen oder das benutzt man

eigentlich mal als Trainingsdatum

für

Textklassifikationsmodelle,

weil man halt dann damit

vorhersagen kann,

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

so eine Ticker-Meldung

liegen kann, beziehungsweise auch noch

ein Unterschied ist, es ist nicht

nicht, man würde, das wäre jetzt Multiklass,

wenn es nur eine gäbe,

aber das ist eigentlich ein Multilabel-Dataset,

das heißt, man möchte alle

Kategorien, in denen so eine Ticker-Meldung

drin liegt,

rausfinden. Also vielleicht

halt auch, es gibt welche, die halt,

wo es nicht nur um Politik geht

oder Sport, sondern auch Sport und Politik

oder sowas.

Genau. Das Erste, was man

finde ich bei so einem Datascience-Projekt, der 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 Pandas

DataFrame rein und

dann

nutze 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 ein Describe, was mir dann

für alle numerischen

Spalten

da drin schon mal so ein bisschen eine erste

Übersichtsstatistik gibt. Also irgendwie

wie viele Einträge habe ich, was ist

der Mittelwert, was sind quasi

die Maximalwerte und so weiter.

Machst du das ähnlich oder wie geht es dir?

Ja, ja, doch, durchaus. Also

ich habe das jetzt auch hier gerade nochmal ausgeführt.

Genau.

Ja, also

wenn man jetzt zum Beispiel

ähm,

einige der ersten

Zeilen ausgeführt hat, dann hat man hier auch eben ein DataFrame,

in dem all die

Dokumente halt drin sind und wenn man

DFHat macht, dann sieht man halt

eine Spalte ModUp, 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 nur, eigentlich müsste man dann irgendwie erklären,

was Cross-Validation ist und wie man K-Fault

Cross-Validation, hier ist

das schon fertig, da muss man sich dann keine Gedanken mehr

drum machen sozusagen, das ist vielleicht

ganz gut. Dann

äh,

gibt es eine Spalte mit den Kategorien drin, das ist dann

einfach nur eine Liste der

äh, Kategorien, in denen

halt diese Meldung halt drin ist

und, ähm, genau

das Ganze nochmal, äh, sozusagen

nicht als Textkategorie, sondern

eben, äh, numerisches Label,

weil, äh, wenn man später

das an irgendwelche Modelle verfüttert, dann brauchen

die das halt als, äh,

ja, als Tal

und am besten auch als Talen, die halt

keine Lücken haben, sonst geht das halt

nicht gut, weil man das halt, äh,

one-hot-encoded immer, das

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. Ähm,

ja, dann gibt es da irgendwie noch ein Datum, was da dran

ist, äh, irgendwie ein Titel,

äh, irgendeine komische Dateline, ich weiß jetzt gar nicht mehr genau,

was das ist, und ein Body von dem

Artikel, äh, dann noch

eine ID und ich glaube, das

habe ich irgendwie mal dran gebastelt, einfach nur, um,

äh, weil, weil, äh,

die Idee war halt, dass, ähm,

in dieser, in dieser Machine Learning,

äh, Schulung, äh, man

ja,

äh, als Übung sozusagen vielleicht ein paar neue

Features dazu tun sollte, um zu gucken, ob

das irgendwie die, äh, mit,

äh, ob das den Score irgendwie verbessert, der Modelle

und da war halt so ein erstes Beispiel,

man könnte einfach mal den Wochentag reinschreiben,

der, äh, an dem das irgendwie

erschienen ist und vielleicht schickt er ja irgendwelche

Informationen drin.

Ja, genau, äh, DF-Info.

Wenn ihr irgendwie wissen wollt, wie man mit

diesen Data-Frame-Operationen noch ein bisschen

besser einen Einstieg findet, da gibt es ein ganz spannendes,

äh, Buch von Jake Vanderplast zu,

Data Science mit Python. Das hat er

auch, äh, frei auf seinem GitHub-Account

veröffentlicht und auf einer Webseite.

Ähm, findet ihr irgendwie, da kann man auch mit

Dupedia-Notebooks das tatsächlich auch mal live noch an anderen

Datensätzen üben? Also gerade für Pandas-

Einführung ist da nochmal ein großes Kapitel.

Ja, äh, also die, die Pandas-Dokumentation

ist auch, auch ziemlich gut. Die ist halt nur etwas

länglich und trocken, aber ansonsten ist sie auch super, äh,

zu empfehlen. Äh, und,

äh, ja, äh, ich finde die, die,

die modernen Pandas, äh,

Blog-Artikel-Serie von Tom Augsburger auch super.

Ja, ja, äh.

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.

Mhm. Ähm, die,

da wirfst du einfach so ein DataFrame rein

und die generiert dir daraus so einen kleinen

HTML-Report,

worin man dann quasi so ein paar

Summary-Statistiken nochmal ein bisschen hübscher aufbereitet

bekommt, also irgendwie. Das sieht ja auch super aus, ja.

Welche, äh, wie viele, wie viele Teilen 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,

ähm, du kriegst, ähm,

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, ähm,

den, den Tag und dann nochmal irgendwie

den Tag um ein Jahr verschoben

oder so, dann korrelieren diese beiden Spalten

ja komplett, sowas würdest du dann da drin direkt

sehen und dann würde dich zum Beispiel vorwarnen,

ähm. Ja, das ist ganz praktisch,

ne, wenn ich cleanen muss, dann irgendwie erstmal so

zu gucken, ah ja, das könnte ja ein Problem sein, dann

fangen wir doch mal an da oder so.

Genau. Geht jetzt immer die Zeile oder sowas, so, ne.

Genau, das ist immer irgendwie, finde ich, ganz praktisch, um,

ja, so einen ersten Übersicht zu bekommen.

Ähm, was würdet ihr dann machen?

Würdet ihr denn die Daten, die dann da zum Beispiel fehlen,

irgendwie versuchen zu füllen oder, ähm,

lässt man dann einfach erstmal die Spalten

weg, weil die irgendwie Quatsch sind oder?

Ja, kommt halt

komplett drauf an, ne, also. Ja.

Ähm, also, was du jetzt ansprichst,

ist ja Ausreißerbereinigung im Wesentlichen

und, ähm, Nullwerte füllen,

ähm,

die, 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,

ähm, man versucht

sie zu füllen mit einem

Art von statistischem Maß,

was quasi zum Beispiel den Durchschnitt von

allen Spalten wiedergibt

oder, ähm,

vielleicht habe ich auch 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, ähm,

also es gibt so ein Cyclic Learn zum Beispiel,

das ist so eine Bibliothek für Maschinen,

Diverse, unterschiedliche, also da nennen

es 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, äh, was der Grund

dafür ist, warum das fehlt und wie man das am besten

ausgleicht, äh, ja,

die dann, äh, sozusagen da irgendwas

reinschreiben oder irgendwas mit den Daten machen, ja.

Ja, die Frage ist halt, ob man

die rausrechnen kann, die Daten oder nicht, ne, also

ob das sinnvoll ist und was man halt mit der Spalte sonst macht

oder mit den Datensätzen, die fehlen oder

Korrelation, ob man dann Dummy reinrechnet,

einsetzt, weil man den noch irgendwie braucht und dann immer

merkt, oh, das ist das bei dem Dummy so und dann...

Ja, und auch, wie rum droppst du sie, wenn du sie

droppst? Also, schmeißt du die Zeilen raus

oder schmeißt du die Spalten raus?

Ähm...

Hängt halt immer von dem Tast ab, aber

genau das macht man an der Stelle halt immer auch ein bisschen...

Ja, aber da sieht man genau gerade, ne, man hat ja irgendwie die Warnings gesehen, wie viel irgendwie

das ganz viele aus einer Zeile oder Spalte

dann da fehlen oder so bei irgendwelchen Einträgen,

war bei den Warnings irgendwie mit dabei. Wie hieß das nochmal?

Ich hab das... Pandas Profiling.

Profiling, okay. Genau. Interessant.

Das muss auf jeden Fall auch in die Shownotes.

Ja, mach ich.

Ähm...

Ja, genau. Also,

hängt halt dann immer auch von den Operationen ab,

die man halt danach drauf irgendwie anwenden

möchte.

Ähm, 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 hab 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 meistens

mal 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 es halt sich ein Histogramm von

der Werte halt anzugucken.

Vor allen Dingen auch, wenn man jetzt unterschiedliche Klassen hat,

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 gegen das der anderen und

man halt sieht, okay, da gibt es einen großen Unterschied, dann ist

schon mal, oder auch selbst ein kleiner Unterschied

ist natürlich schon hilfreich irgendwie.

Wenn man sieht, die sind genau gleich verteilt, dann ist das natürlich doof.

Aber, genau.

Genau, in dem

Explore-Data-Block sieht man auch ganz unten

eben, finde ich, ein ganz klassisches, aber

sehr, sehr hilfreiches Diagramm an der Stelle,

wo du einfach mal so die

Länge der Texte

abgetragen hast, den Zeichen,

und da sieht man auch so ein ganz typisches Verhalten.

Man hat halt irgendwie so einen Peak

der Daten, der relativ am Anfang

liegt, also irgendwie, wir haben hier jetzt,

würde ich sagen, wahrscheinlich mal

80 Prozent

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 3.000, 4.000, 5.000,

6.000 plus Einträge haben.

Irgendwann hat ja jemand sein Buch bei Reuters hochgeladen, oder?

Ja, genau.

Aber das ist so ein ganz klassisches Problem, was man halt im echten

Welt-Data-Science halt immer hat,

dass es halt irgendwie so Ausreißer

gibt, die die 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

im Test- oder Training

zugeordnet sind.

Also dieser

Mod-Up-Display teilt

diese Ticker-Meldung halt in

die, auf denen man trainieren kann und die

sozusagen, die man hinterher benutzt,

um zu evaluieren, wie gut denn jetzt

die Modelle funktioniert haben.

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,

aber es ist halt so, dass

wenn man jetzt alle rausnimmt,

auch alle Beispiele rausnimmt,

auch 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

die Kategorien, die rausgefallen sind, sonstiges oder so.

Ja, ich weiß es

gar nicht genau, ich habe es mir auch nicht

angeguckt, was das genau für Kategorien sind, aber

ja, also

das ist halt tatsächlich, sind die Zahlen für alle,

aber

in Wirklichkeit ist es halt nochmal ein bisschen weniger,

also die dann hinterher tatsächlich

zum Trainieren verwendet werden, dann

eben durchschnittliche Anzahl von

Wörtern ist halt irgendwie auch so 90

und genau,

die,

also es gibt so eine Quote

Anzahl der Beispiele, also das

Anzahl der Zeilen im DataFrame

geteilt durch die Anzahl der Wörter pro

Tickermeldung

ist halt auch eine ganz

interessante

Zahl, die man später benutzen kann, um halt

irgendwie rauszukriegen, welche Art

von Modell da irgendwie besser funktionieren

könnte.

Ja,

genau, also überhaupt diese ganze, also das

ist halt 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. Ja, also erstmal visualisieren,

ist glaube ich tatsächlich eine gute Idee, ne, auch verschiedene

Arten, mal gucken, WordCloud bauen vielleicht

oder so und dann schauen, was ist das denn.

Genau, und nebenher finde ich durchaus irgendwie

nochmal so ein Scratchpad offen haben und wenn man

da irgendwie eine Auffälligkeit hat,

die immer gleich reinschreiben, also

man verfällt dann finde ich auch relativ leicht

in so einem, ja, Liebe

zu Charts, weil so Charts

basteln ist was, was ich zum Beispiel total gerne

mache. Also ich finde es total spannend, dann

mir die Daten irgendwie so in Diagrammen

zu visualisieren und die irgendwie hübsch zu machen

und mächtig von ihrer Aussagekraft und so weiter,

aber dabei

verfalle ich da manchmal so ein bisschen in der

Liebe zum Tun und

eigentlich geht es ja darum, Insights zu generieren.

Deswegen finde ich es dann

immer relativ wichtig, sich irgendwo nochmal so eine Liste

runterzuschreiben mit den Auffälligkeiten, wo man so

gedacht hat, ah ja, stimmt, das ist ja interessant,

und das ist interessant, weil

im Endeffekt sind das nachher dann Sachen, aus denen man

dann Ideen bekommt, um zum Beispiel

Features zu generieren, die

dann eben meinem Modell wirklich weiterhelfen könnten.

Ja, also

das ist halt an der Stelle auch definitiv dann

ein iterativer Prozess, wo man

quasi

sich die Daten anschaut, man entwickelt eine Idee

dafür, man probiert sie aus und man geht dann

wieder zurück und guckt sich mal wieder die Daten an

und guckt, ah ja, jetzt habe ich aber ja

ein besseres Verständnis dafür bekommen, weil

ja, da ist so viel

Information in so einem Datensystem, dass es eine ganze Zeit

lang braucht, bis man wirklich

versteht, was man damit alles machen könnte.

Ja, man muss ja natürlich auch immer das Problem erstmal

so ein bisschen reindenken, damit man irgendwie dann mit den Daten

aber auch was anfangen kann.

Genau, und

ja, dabei

hilft halt diese explorative Sache und

ja,

neben diesem ganzen Histogramm, ich glaube, wir haben angefangen

erstmal mit, wie man die Daten noch bekommt, damit waren wir noch gar nicht

so durch. Achso, richtig, ja, stimmt.

Wir sollten irgendwie noch so die Art und Weise

der Methode, wir haben jetzt irgendwie das Describe irgendwie von

DataFrames ein bisschen gemacht, aber wie bekomme ich denn

die Daten überhaupt irgendwie so rein? Das ist ein guter Punkt,

ja.

Ja, also das ist irgendwie

eine URL, die da irgendwo

mit drin steht.

Moment, ich glaube, das ist jetzt mittlerweile gut versteckt

irgendwie in dem

DS-Tutorial-Paket.

Datasets, da gibt es

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 einen

Spielprojekt eine Web-URL, dann ziehe ich es mir

direkt von dort.

Kann man ja direkt auch mit Pandas, glaube ich.

Oder eigene Webdaten-Straight mit einer eigenen Datenbank

oder sowas. Oder von irgendwelchen Sendoren,

die Sachen in irgendeine Datenbank packen.

Eine Datenbank-Anwendung ist natürlich auch guter Punkt,

definitiv. Ist irgendwie in der

echten Welt gefühlt zu selten bei so

Notebooks. Irgendwie landen die Dateien dann doch immer

als Datei da, aber

genau, in dem Fall ist es ja relativ

tief im Code direkt versteckt, wie du es lädst.

Also wenn die Dateien da laden,

also wirklich big ist die Datei dann aber

irgendwie noch nicht.

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 ich weiß nicht.

Meine Präferenz an der Stelle ist

vor allem immer erstmal auch Latenz nicht richtig 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 Embedded auf dem Kompletten ausprobieren.

Machst du das anders?

Nee, nee, also genau. Subsamplen ist

halt auch, wenn die Daten groß sind, auf jeden Fall

eine super Strategie, um halt

schnell 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 den

importiert man sich halt ein DataFrame 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, 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

hinzu und man kann auch mehr an

während Sachen da drauf laufen, also

während man auf einem DataFrame 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 reingenommen und

werden die Sachen halt irgendwie magisch schneller

und man sieht halt auch irgendwie sehr schön,

was da passiert.

Da habe ich jetzt normalerweise kein Beispiel für, aber

das geht

durchaus auch und das

Benutzerinterface ist dann da auch nicht anders,

als wenn man das jetzt auf einer lokalen Maschine macht,

sondern ist auch immer ein Notebook eigentlich.

Ich glaube, zu diesem

Big-Dating müssen wir nochmal eine eigene Folge machen, so mit

Kubernetes, das ist dann nochmal spannend.

Genau, an der Stelle kann ich mal

meine Kubernetes-Folge droppen.

Ach, der ist noch? Ja, genau.

Es gibt eine zu Docker und eine zu Kubernetes.

Ja, und das

Schöne ist halt, dass die Sachen dann auch, wenn man sie nicht mehr braucht,

wieder verschwinden, während halt, das ist ja auch etwas,

was man sonst, also gibt es dann vielleicht auch irgendwie,

in vielen Firmen gibt es dann halt

so ein Cluster, wo man Sachen machen kann, aber die Maschinen sind dann halt

da und

man braucht sie aber irgendwie nur,

man braucht eigentlich so alle halbe Stunde mal so wirklich

volle Power, aber ansonsten braucht man das

eigentlich nicht und

ja,

das ist, glaube ich, auch irgendwie, also das ist

schon ein sehr gutes Argument für diese ganzen

Cloud-Geschichten, weil man zahlt halt tatsächlich nur

in dem Moment, wo man halt die Rechenzeit

braucht und

Also du hast Dasks jetzt auch

schon öfter eingesetzt und das funktioniert für dich gut?

Ja, für mich funktioniert das eigentlich ziemlich gut.

Ich habe 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 den Pandas. Nicht komplett, aber

also sagen wir mal 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 DataFrames aufteilt

und das muss man halt irgendwie, die

unterschiedlichen Teile liegen halt auf unterschiedlichen Rechnern

und ja. Ansonsten,

wenn man Pandas einfach

nur Multicore betreiben möchte, was ja

Pandas per Default jetzt aktuell noch nicht bietet,

gibt es auch ein paar nette Projekte,

da gibt es einmal Modin, das ehemalige

Pandas on Ray,

was quasi einfach über einen Import

einfach nur,

du änderst den Import und dann kannst du

prinzipiell Multicore für

die allermeisten Pandas-Operationen.

Wenn du also eher in die Nische kommst,

geht es da vielleicht dann irgendwann nicht mehr.

Und was ich heute kennengelernt habe und noch nicht ausprobiert

habe, ist Pandarallel,

also

wie Panda und dann

Parallel quasi und

das unterstützt halt eben auch quasi oder verspricht

ein Multicore-Processing für Pandas-Operationen.

Genau. Also bevor man vielleicht

wirklich auch ein Cluster muss,

ist das noch eine gute Option.

Ja.

Ja, ja, ja. Ne, das kann ich auch noch nicht.

Also, ja. Sehr interessant.

Genau.

Aber wir waren hier bei dem...

Wie bekomme ich eigentlich meine Daten?

Ja, ich hatte einfach das entsprechende Notpunkt nicht aufgemacht.

Das heißt hier Preparing Data.

Keine Ahnung, vielleicht ist es unsinnig genannt.

Und das ist einfach das Ding,

also David Lewis ist auch der, der den Modellorten,

den Modellort-Split gemacht hat und auch überhaupt

der, der das ganze Dataset kuratiert hat,

hat das halt irgendwie auf seiner Seite liegen.

Und, ähm,

genau, dann, ähm, ja.

Ähm, was du

auch benutzt an der Stelle im Notebook ist ja

ähm, die, ähm,

die Path Library.

Ja. Ähm, hab 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, äh, früher hab ich das auch

mal mit, äh, OS

und ListDir und OS Paths

Join und so gemacht, aber das ist alles ganz schön

genau, glaub,

ganz schön umständlich und, äh,

ähm, da gibt's halt, äh,

ich weiß gar nicht, wann das in, seit wann

das in der Standard Library ist, aber, äh,

also es gibt da ein, ein, ähm,

ein Modul namens Path Slip

und, äh, da, äh,

kann man, also,

zum Beispiel, es geht

hier los mit, äh, Path.Home, ist halt

sozusagen dann ein Part und, ähm,

die, das Ding funktioniert

im Grunde, wenn man jetzt Pfade erweitern möchte oder so,

über, äh, so Operator

Overloading und, äh,

die haben dann halt einfach das, äh, den

Slash, äh, überladen und jetzt kann man halt

schreiben, äh, irgendwie Path.Home, gibt dann

das Home-Verzeichnis, Slash, Data

Slash TMP

und das ist natürlich viel kürzer, also würde man jetzt schreiben

OS Paths Join,

Klammer auf, und dann gibt man eine Liste oder macht

irgendwie, ja, äh, irgendwie, äh,

muss dann einen absoluten Pfad angeben oder

man gibt irgendwie einen relativen Ankommer, irgendwie

das nächste Ding und, äh,

das ist alles ganz schrecklich. Man kann sehr schön,

ähm, Variablen quasi mit reinbetten

und, ähm, man bekommt

ja am Ende dann auch immer quasi ein Path-Objekt

wieder raus, was dann auch nochmal so

Operationen bietet wie, ähm, okay,

jetzt verraten wir von dem noch bitte die Subdirectories

oder, ähm, ja,

halt Operationen dann immer direkt auf

dem Pfad ausführen. Ja, du kannst einfach ein Dot-Exist

machen oder sowas, das wäre auch ziemlich cool, ja. Genau.

Ja, und ansonsten hätte man immer

OS Paths Exist und so verwenden müssen

und dann, also das ist, es ist

wirklich viel, viel angenehmer damit zu

arbeiten und, ähm, ja, äh,

also sonst hat man immer so, also ich hatte sonst immer das Problem,

dass irgendwie die ganzen, diese ganzen Geschichten

wurden immer relativ festlich und auch die Zeilen wurden sehr

lang und das, das Problem ist irgendwie weg,

seitdem ich Parsel verwende und das ist schon mal echt ein

Vorteil. Vielleicht um das zu kurz zu zeigen,

ich lösche jetzt einfach mal die Daten, die ich hier bei mir

lokal habe, äh,

Data, äh,

TMP, ja,

genau.

Äh, ah.

Da muss man echt mit aufpassen. Ja, ja.

Ja, wenn du willst so ein Git-Repo löschen

oder so, machst dann irgendwie .slash oder so,

und dann immer aus Versehen löscht man den Punkt weg,

dann machst du r-r-slash und dann

Ja,

dann, äh. Immer alles als

Super-User machen. Muss man hoffen, dass

das nicht nur das Backup immer funktioniert hat, sondern

dass das Restore auch mal funktioniert.

Ja.

Äh, genau. Äh, ja.

Ähm, ich verwende hier

einfach so, äh, irgendwie so

Download-from-URL-Funktion,

die benutzt TQDM

um, äh, das ist,

das ist eine sehr schöne Library, mit der man halt so

Progress-Bars ganz gut hinkriegt. Man kann eigentlich alle

Iteratoren irgendwie damit rappen. Ja, man braucht nur

ein Iterat-Bar und, genau.

Und das ist, das ist auch sehr,

sehr hübsch, dann sieht man ungefähr, wo man ist.

Äh, und, äh, ja.

Ja, und jetzt hat das, äh, irgendwie

dieses Dataset halt, äh, irgendwie so ein, so ein

Data-Verzeichnis geschrieben.

Dann, und das ist halt auch irgendwie das Tolle bei Python,

dass man, äh, irgendwie einen Riesenhaufen Funktionalität

schon, äh, in der Standard-Library mit

drin hat, äh, ist eben auch sowas drin

wie tar-File, ne, dass man halt mit, mit, mit

tar, äh, äh,

Archiven halt direkt, äh, irgendwie umgehen kann

und, ja, dem kann man dann halt einfach

sagen, okay, pack doch mal alles aus.

Und, ähm,

ja, dann, äh.

Dann haben wir einen Pickel gebaut, oder? Du hast einen Pickel gebaut. Genau, dann

parse ich das Ganze auf und, äh,

pickel das wieder raus, sozusagen, damit ich

dieses Parsen nicht jedes Mal machen muss. An der Stelle hier ist es

relativ egal, weil das ist so schnell. Also,

Pickel speichert einfach das Python-Objekt in der Binary

einfach, also als Binär-Daten auf

der Platte in einem Objekt und kann es genauso wieder einlesen. Genau.

Pickel ist auch ein Modul aus der Standard-Bibliothek,

genau, und es serialisiert einfach

äh, Python-Objekte, beliebige Python-Objekte

einfach auf, ja, in ein

Format, das man dann halt auf die Platte schreiben kann und

hinterher auch wieder lesen kann. Und es ist

halt relativ schnell. Also,

CSV, äh, genau, ist oft das,

was man bekommt und das, was am meisten

verwendet wird und, äh, ja, Pandas

Reads CSV-Funktion ist sicherlich so eine der

wichtigsten. Aber

das ist halt nicht schnell, äh,

sondern das ist halt irgendwie so, ja,

sagen wir mal, weiß ich nicht,

vielleicht 50 MB pro

Sekunde oder sowas da so durchgeht. Kommt darauf an,

wie komplex das CSV ist.

Und gut, für die meisten Datensätze ist das vielleicht

auch, oder was die meisten Leute so haben, auch

schnell genug, dass das halt irgendwie nicht so

furchtbar merkbare Wartezeiten

erzeugt, aber wenn man

jetzt so ein paar Gigabyte, äh, einlesen will, dann ist

das schon, dann muss man bei CSV schon immer warten.

Und, äh, was ich da oft

auch mache, ist halt die, äh, wenn ich CSVs

habe, die, ähm, zuerst

irgendwie in DataFrame einzulesen mit ReadCSV

und dann halt nochmal, äh,

irgendwie ein Pickel-File davon zu cachen,

weil das Pickel, äh, liest halt

äh, quasi mit Plattengeschwindigkeit, also

da kann man auch so ein Gigabyte pro

Sekunde lesen. Das, das, dann

dauert das halt, wenn man, wenn man halt so ein

DataFrame, der halt irgendwie zwei, drei Gigabyte groß ist,

äh, äh, äh, liest, der, der

und Jochen unterhalten sich über die Programmiersprache Python

und Jochen unterhalten sich über die Programmiersprache Python

und Jochen unterhalten sich über die Programmiersprache Python

und Jochen unterhalten sich über die Programmiersprache Python

und Jochen unterhalten sich über die Programmiersprache Python

und Jochen unterhalten sich über die Programmiersprache Python

und Jochen unterhalten sich über die Programmiersprache Python

und Jochen unterhalten sich über die Programmiersprache Python

und Jochen unterhalten sich über die Programmiersprache Python

und Jochen unterhalten sich über die Programmiersprache Python

und Jochen unterhalten sich über die Programmiersprache Python

und Jochen unterhalten sich über die Programmiersprache Python

und Jochen unterhalten sich über die Programmiersprache Python

und Jochen unterhalten sich über die Programmiersprache Python

und Jochen unterhalten sich über die Programmiersprache Python

und Jochen unterhalten sich über die Programmiersprache Python

und Jochen unterhalten sich über die Programmiersprache Python

und Jochen unterhalten sich über die Programmiersprache Python

und Jochen unterhalten sich über die Programmiersprache Python

und Jochen unterhalten sich über die Programmiersprache Python

und Jochen unterhalten sich über die Programmiersprache Python

und Jochen unterhalten sich über die Programmiersprache Python

und Jochen unterhalten sich über die Programmiersprache Python

und Jochen unterhalten sich über die Programmiersprache Python

und Jochen unterhalten sich über die Programmiersprache Python

und Jochen unterhalten sich über die Programmiersprache Python

und Jochen unterhalten sich über die Programmiersprache Python

und Jochen unterhalten sich über die Programmiersprache Python

und Jochen unterhalten sich über die Programmiersprache Python

und Jochen unterhalten sich über die Programmiersprache Python

und Jochen unterhalten sich über die Programmiersprache Python

und Jochen unterhalten sich über die Programmiersprache Python

und Jochen unterhalten sich über die Programmiersprache Python

und Jochen unterhalten sich über die Programmiersprache Python

und Jochen unterhalten sich über die Programmiersprache Python

und Jochen unterhalten sich über die Programmiersprache Python

und Jochen unterhalten sich über die Programmiersprache Python

und Jochen unterhalten sich über die Programmiersprache Python

und Jochen unterhalten sich über die Programmiersprache Python

und Jochen unterhalten sich über die Programmiersprache Python

und Jochen unterhalten sich über die Programmiersprache Python

und Jochen unterhalten sich über die Programmiersprache Python

und Jochen unterhalten sich über die Programmiersprache Python

und Jochen unterhalten sich über die Programmiersprache Python

und Jochen unterhalten sich über die Programmiersprache Python

und Jochen unterhalten sich über die Programmiersprache Python

und Jochen unterhalten sich über die Programmiersprache Python

und Jochen unterhalten sich über die Programmiersprache Python

und Jochen unterhalten sich über die Programmiersprache Python

und im Grunde, wenn man jetzt, also bei Scikit-Learn ist es jedenfalls so,

und im Grunde, wenn man jetzt, also bei Scikit-Learn ist es jedenfalls so,

und im Grunde, wenn man jetzt, also bei Scikit-Learn ist es jedenfalls so,

und im Grunde, wenn man jetzt, also bei Scikit-Learn ist es jedenfalls so,

und im Grunde, wenn man jetzt, also bei Scikit-Learn ist es jedenfalls so,

und im Grunde, wenn man jetzt, also bei Scikit-Learn ist es jedenfalls so,

eigentlich orientieren sich fast alle anderen Maschinen-Learning-Bibliotheken,

eigentlich orientieren sich fast alle anderen Maschinen-Learning-Bibliotheken,

eigentlich orientieren sich fast alle anderen Maschinen-Learning-Bibliotheken,

die es so gibt, auch an der entsprechenden API von Scikit-Learn,

ist die Estimator-API für Modelle eben,

da übergibt man immer Arrays, also NumPy-Arrays.

Und sowas wie Listen oder so kann man da nicht übergeben.

Das heißt, man muss erstmal das so in Format bringen,

dass man das überhaupt den entsprechenden Modellen übergeben kann.

Und für Multilabel ist es eben so,

dass das richtige Format dann halt ist,

ein NumPy-Array zu haben,

das halt auch wieder genauso viele Zeilen hat,

wie man in der Feature-Matrix hat,

oder eben genauso viele Zeilen, wie es eben Dokumente gibt,

die zum Training-Set gehören,

und dann so viel spalten, wie es Kategorien gibt,

oder Labels gibt, in denen ein Dokument liegen kann,

und sozusagen die, für jede Spalte gibt es dann halt sozusagen,

also jede Spalte ist halt eine Kategorie,

und wenn da ein 0 drinsteht, bedeutet das im Grunde,

dass das Dokument liegt nicht in dieser Kategorie,

oder hat dieses Tag eben nicht.

Wenn da ein 1 drinsteht, dann heißt das,

okay, ja, das ist sozusagen die richtige Kategorie für dieses Dokument.

Und genau, dafür gibt es aus dem Scikit-Learn-Pre-Processing-Modul

halt ein Ding, das nennt sich Multilabel-Binarizer,

und dem gibt man einfach diese Liste von Listen,

und dann spuckt das halt ein richtig formatiertes NumPy-Array aus.

Also das ist auch sowas.

Also diese ganze Transformation, das muss man nicht selber machen.

Da gibt es eigentlich für alle Geschichten, die man da so haben kann,

fertige Lösungen schon.

Ja, man kann sich, glaube ich, auch aussuchen,

was dann mit den Werten, die da nicht reinpassen,

irgendwie geschehen soll und sowas.

Ja, ja, bestimmt.

Ich weiß jetzt gar nicht genau, was der Multilabel-Binarizer

da sonst auch so macht.

Und langfristig ist es vor allem auch nicht sinnvoll,

sich das zu machen.

Also am Anfang, wenn man das noch nie gemacht hat,

denkt man so,

also man muss ja schon auch einmal erstmal durchsteigen,

wie das überhaupt alles funktioniert,

mit diesen Transform-Prozessen und den Modellen und so weiter.

Und dann denkt man,

ich will doch eigentlich nur so ein Modell benutzen,

ich kann den ganzen Rest auch von Hand machen

und fängt damit gerne erstmal an,

weil man auch gerne ein bisschen programmiert

und nicht ewig Doku liest.

Aber faktisch ist man halt letztendlich dann doch viel schneller,

wenn man sich das halt einmal aneignet,

wie denn diese Binarizer und so weiter funktionieren.

Ja.

Genau.

Ja.

Und dann hat man quasi das gleiche Problem,

nur irgendwie ein bisschen anders.

Auf der Feature-Matrix-Seite halt eben auch,

weil 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,

das ist halt ein NumPy-Array von irgendwie Float-Geschichten

und das ist Text halt nicht.

Man muss jetzt erstmal Text irgendwie in Zahlen irgendwie umwandeln

und das ist halt schon so eine Art,

man nennt das halt Feature-Extraktion.

Also man macht sozusagen aus Text irgendwie eine Reihe von Features,

also Spalten in der Feature-Matrix.

Und so eine ganz, ja, alte Standard-Methode,

wie man das halt tun kann,

ist einmal, man repräsentiert Text halt als Back-of-Words,

nennt sich das.

Das bedeutet, man wirft die Reihenfolge-Informationen 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 nicht.

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 ein Null rein in die Spalten.

Also man hat sozusagen so viele Spalten,

wie es überhaupt unterschiedliche Worte im gesamten Dokument-Korpus gibt.

Also über alle Dokumente drüber.

Wobei Back-of-Words macht doch schon auch die Anzahl gleich rein, oder?

Ja, ich weiß nicht.

Man kann auch die Anzahl direkt rein.

Also der einfachste Fall wäre, dass man einfach nur reinschreibt,

ist es da oder nicht, wie näher.

Und genau, dann die nächste etwas,

also das funktioniert auch schon erstaunlich gut.

Aber das hat halt auch diverse Probleme.

Unter anderem ist es halt so,

dass längere Texte natürlich viel,

bei denen steigt die Wahrscheinlichkeit,

dass sie in allen möglichen Kategorien sind.

Einfach deswegen, weil eine Menge Worte darin auftauchen,

die halt in allen möglichen Kategorien auftauchen.

Oder derjenige, die den Nachrichtenbeitrag geschrieben hat,

war SEO-Experte oder so.

Ja, ja, genau.

Das wäre halt etwas, was man versuchen wollen würde zu verhindern,

dass das halt so eine große Auswirkung hat,

wenn da irgendwie eine lange Liste von vielen unterschiedlichen Worten drinsteht.

Und das ist eine klassische Methode, die man da verwendet.

Es kommt auch aus dem Information-Retrieval-Bereich.

Es 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 dem 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 die Anzahl, wie oft kommt es vor,

geteilt durch die Länge des Textes.

Und das funktioniert auch.

Das funktioniert auch schon besser.

Also da könnte man dann irgendwie einen Count-Vectorizer nehmen.

Der würde halt dann zählen, nicht nur binär irgendwie einen großen Vektor bauen,

in dem einzelne Nullen drinstehen, je nachdem, ob ein Wort drin vorkommt oder nicht.

Das wäre dann schon die Term-Frequency, oder?

Ja, damit hätte man erst mal nur die Counts.

Und dann, ich weiß nicht, ob es noch einen...

Aber es gibt keinen Vectorizer, der dann nur Term-Frequenz macht,

sondern dann würde man direkt so etwas nehmen wie TF-EDF-Vectorizer.

Das Problem bei der Term-Frequenz ist halt...

Ich glaube, das habt ihr alle ein bisschen verstanden.

Ich habe mich ein bisschen abgehängt.

Erst mal, was ist ein Term-Vectorizer?

Was ist ein TF-ID?

Ja, also im Grunde kann man eigentlich direkt mit dem TF-EDF einsteigen.

Wenn man sich jetzt einen Vector anguckt, wo nur drinsteht, 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 darinstehen haben für Worte,

weil halt manche Worte sind halt wichtiger oder charakteristischer für eine Kategorie als andere.

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 einen Einsen und Nullen 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.

Ich glaube Anfang der 70er oder so, dass Karen Speck-Jones, glaube ich, irgendwie sich mal überlegt, ich weiß nicht genau.

TF-EDF, 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 dieses Gewichtungsdienst nennt sich halt,

TF-EDF, also Term Frequency mal Inverse Document Frequency.

Term Frequency ist einfach nur die Frequenz von dem Wort in dem Text,

also das ist einfach nur Count, wie oft kommt das Wort vor,

in dem Text geteilt durch wie lang ist der Text,

mal Logarithmus von...

Ja, genau, ich kann den an der Stelle auch nicht genau...

Geteilt durch wie oft kommt das Wort irgendwie

in allen Texten vor, sozusagen, also das Ding wird halt höher, je höher, desto seltener es ist, also sozusagen...

Und man nimmt dann mal den Logarithmus, damit es nicht ganz so schlimm wird, damit es halt so ein bisschen...

Ein bisschen flacher wird.

Genau, genau, weil man möchte halt auch nicht so total krasse Unterschiede haben,

das 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, das ständig vorkommt oder was halt eben relativ selten vorkommt,

gewichtet mit wie häufig kommt dieses Wort in dem Text vor,

das ist ja 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 rausfallen...

Ja, 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 berechnet 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-Dataset schon in das Training mit rein?

Ja, also vor allem...

Darf man das machen?

Ist halt auch die Frage, wie gut sind deine Tester, also sind die halt verteilt, sind die homogen, hast du da eine schiefe Verteilung zum Beispiel oder sowas,

ist ja dann auch irgendwie doof, weil dann die Sachen, die schief drin liegen, dann überprofessionell darin vertreten sind,

und du vielleicht von den Sachen, die da selten drin sind, nicht so viele...

Genau, aber dieses Problem, was du gerade sagst, mit dem Training und den Tester, das ist halt wirklich so ein klassisches...

Also du hast eigentlich nur zwei Optionen, entweder ich sage, ich trainiere mein TF-IDF auf allen meinen Daten, auch vom Test-Set,

dann habe ich halt alle Wörter wirklich drin, die potenziell vorkommen können nachher, aber dann habe ich halt eben die Gefahr von Information Leakage,

also das heißt einfach, die Daten, die mir eigentlich ja potenziell unbekannt sind, ich will ja nachher auf Daten generalisieren,

die ich noch wirklich gar nicht kenne, das Test-Set ist ja nur eine Abstraktion, um irgendwie am Anfang damit trainieren zu können,

dann tue ich so, als würde ich diese 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 Test-Set irgendwelche Wörter habe, die ich so gar nicht habe,

und dann habe ich dazu quasi keinen IDF-Score, keinen validen, genau, und dann gibt es halt im Endeffekt...

Brauchst du halt entweder ein sehr, sehr großes Datenset, dass du das irgendwie selber machen kannst und hast, oder du kannst halt auch quasi ein Datenset benutzen, quasi...

Also für so eine Generalität von Wörtern könntest du jetzt auch ein öffentliches Datenset benutzen.

Wikipedia oder sowas.

Genau, aber dann ist es halt nicht so spezifisch aus deinem Anwendungsfall wahrscheinlich, und vielleicht ist das Wort Enzyklopädie in der Wikipedia selbst irgendwie viel häufiger

und viel unspezifischer, als es bei dir jetzt im Wort vielleicht wäre, also bei dir in deinen Daten vielleicht wäre.

Genau, also es ist auch wieder so ein Abwägungsding, wie geht man damit um?

Ja.

Und ja, hier ist es zum Glück halt irgendwie alles schon, sozusagen, sind diese Geschichten vorgegeben und wir ermitteln die Zahlen halt sozusagen nur auf den Trainingsdaten und fitten das halt nur auf den Testdaten, also, ja.

Äh, wir 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 das richtige Datenset, was das Wichtige ist, als die Menge an Daten? Hört es sich gerade ein bisschen so an, also ich hätte jetzt intuitiv andersrum gedacht,

das heißt, je mehr Testdaten ich zur Verfügung hätte, auf denen ich meinen Algorithmus testen kann, desto besser wird mein Ergebnis und das, was gerade so ein bisschen durchging, war, dass...

Trainingsdaten sind das, was dein Modell besser macht.

Ja, genau.

Testdaten...

Also, das meinte ich mit...

Achso, ich hab's gerade nochmal verwechselt wahrscheinlich.

Ja, okay, ja, genau.

Je mehr Trainingsdaten hast, desto besser, aber...

Ja, weil dann würde man Wikipedia zum Beispiel schon nehmen können, wenn das korrekt gelabelt ist, ja? Dann würde das dazu führen, also selbst wenn da mehr...

Nee, aber Wikipedia ist ja jetzt für deinen Anwendungsfall nicht gelabelt.

Ja, genau, wenn ich das gelabelt hätte, das war ja dann...

Und das ist natürlich wahrscheinlich immer anders, das ist halt das Problem, das ist anders verteilt, als das, was du irgendwie benutzen willst.

Also ist dann aber doch halt nicht die Menge der Daten, sondern die müssen halt schon matchen, also ich brauche halt so den Skop in die richtige Richtung schon.

Ja, klar.

Das heißt, da kann halt ein Riesenproblem daraus entstehen, wenn ich irgendwas rausfinden will, was ich überhaupt nicht beschrieben habe in den Daten, dann ist Murks.

Genau, und ein Stück weit muss man da jetzt auch nochmal unterscheiden. Wir haben ja gerade so ein bisschen davon geredet, wie kriege ich denn die Spezifizität von den Wörtern.

Da geht es ja darum, wie überführe ich unseren Text überhaupt erstmal in so eine Zahlenmatrix, auf denen wir dann basierend unser Training ausführen können.

Und um das, ja, 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...

Dann macht es natürlich überhaupt keinen Sinn, das irgendwie mit Wikipedia-Daten zu machen, wenn ich eigentlich dann meine Art Artikel machen möchte, weil das ist wahrscheinlich dann anders.

Ja, das gibt es auch noch in diversen anderen... also das Problem kriegt man halt auch immer wieder, also wenn man jetzt zum Beispiel... das 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 ein echtes Problem hätte, auf jeden Fall wahrscheinlich auch noch machen wollen würde, ist sogenannte Word-Embeddings, also man würde halt nicht nur, einfach nur, sozusagen pro Wort eine Dimension nehmen, sondern man würde, ja, diese Worte halt aus jedem Wort mehrere Dimensionen erzeugen und da hat sich sozusagen eingebettet in so ein...

Ja, was man mit Word-Embeddings macht...

Ja, was man mit Word-Embeddings macht...

Ja, was man mit Word-Embeddings macht...

Ja, was man mit Word-Embeddings macht...

Ja, was man mit Word-Embeddings macht, ist, man projiziert jedes Wort in einen mehrdimensionalen Vektorraum und dadurch, dass in diesem Vektorraum alle Wörter irgendwie abgebildet sind, kann ich jetzt mathematische Operationen darauf abbilden und kann vor allem gucken, ob sich zwei Wörter ungefähr im selben Bereich dieses Vektorraums befinden und damit kriege ich sowas hin, wie das irgendwie Kirche und Kathedrale plötzlich irgendwie vergleichbar sind, obwohl die jetzt in einem normalen Text natürlich jetzt irgendwie nichts gemeint 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...

Für jedes der Wörter, die ich habe, quasi nachgucken, okay, was ist denn diese Dimensionalität, weil um so ein Word-Embedding wirklich selber zu trainieren, dann brauchst du zum einen sehr, sehr viele Trainingsdaten und zum anderen halt auch wirklich viel Rechenleistung für eine ganze Weile.

Wo würde ich solche Modelle runterladen?

Ja, es gibt zum Beispiel Word-to-Vac, das Modell von Google, das kann man halt benutzen.

Das ist nett, ist gern benutzt.

Ja, und es hängt aber dann... ist halt die Frage, worauf das denn trainiert ist, also wahrscheinlich ist viel Wikipedia dabei, aber bei Google ist bestimmt auch noch...

Es sind auch diverse Webseiten mit drunter.

Die einen oder andere.

Ja, und das sind halt so ein paar Gigabyte, die man dann so runterladen kann.

Und das verbessert halt, wenn man jetzt eben statt TF-EDF, oder normalerweise würde man nicht sagen statt, sondern man nimmt die TF-EDF-Scores natürlich auch mit dazu als Features

und nimmt dann aber auch die Vektoren aus den Word-Embeddings, vieles Wort mit dazu, dann verbessert das halt irgendwie...

Das ist irgendwie so ein Klassifikationsergebnis, schon deutlich.

Aber da hat man halt auch das Problem, man weiß halt dann nicht, wenn man das jetzt einfach so diese vortrainierten Geschichten benutzt...

Ja, aber das ist ja schon wieder... das Nussen der Schwarmintelligenz, das ist ja keine eigene Entwicklung in dem Sinne, sondern man nutzt halt das, was irgendwie einer der Großen dann schon angestellt hat mit seiner Hardware,

auf so einer ganzen Sprache, auf so einer ganzen Grammatik und das Knowledge, das man dann irgendwie...

Sag mal so, wenn du genug Trainingsdaten hättest und auch genug Rechenkraften, um das dann halt alles auszurechnen, wäre es wahrscheinlich besser, wenn du das auf deine eigene...

Auf deine eigenen Daten machst und nicht die auf Wikipedia trainiert nimmst.

Wie viel... also hast du gesagt, es waren bei der Reuters-Daten drin 20.000 irgendwie Datensätze und das heißt, das war nicht historisch, weil da sind sicher mehr?

Das ist ein bestimmter Ausschnitt. Ich weiß nicht genau, nach welchen Kriterien die jetzt ausgewählt worden sind, aber es sind ein paar halt nur...

Es gibt jetzt auch ein neueres Dataset, RCV1, und das heißt irgendwie, da sind dann 800.000 drin oder so.

Ja.

Genau. Aber wie gesagt, an der Stelle würde man...

Dann könnte man halt in der Stelle jetzt eigentlich erstmal diesen Back-of-Words-Ansatz vielleicht 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 Scikit-Learn eigentlich abgeschaut haben.

Da gibt es halt immer im Wesentlichen zwei Operationen. Es gibt eben Fit und Transform.

Git nimmt quasi gewisse Daten und trainiert darauf jetzt mein Modell. Das heißt, dieser Multilabel-Binarizer guckt sich alle Daten an und berechnet für sich daraus, okay, aus jedem dieser Labels, die ich habe, muss ich folgende Zahl nachher rausgenerieren.

Und wenn ich das einmal gemacht habe, gefittet habe, dann kann ich danach halt diesen Label-Binarizer immer transformieren auf irgendeinen beliebigen Text.

Der nimmt dann quasi diesen selben, diese selbe Abbildungsmatrix von Wörtern zu Zahlen und überträgt die auf den neuen Text.

Und ich kann natürlich auch beides gleichzeitig anwenden. Dann mache ich halt eben so wie in dem Notebook hier Fit-Transform. Dann fittet er erst darauf und dann transformiert er auch gleich die Eingangsdaten.

Genau. Ja, das ist jetzt halt inzwischen echt so ein super Standard-Interface geworden und das Schöne ist halt, dass ich im Grunde...

Jedes Modell, wenn ich jetzt eine Klasse habe in Python, die diese Methoden implementiert, ich brauche vielleicht noch ein bisschen mehr, muss man nochmal gucken, aber kann ich die halt auch in allen, dazu kommen wir später auch nochmal, Pipelines und so verwenden und Modelle, die halt diese API implementieren, werden dadurch austauschbar. Das ist halt auch total toll.

Und dann werfe ich die da rein und gucke, ob hinterher was rauskommt und ich muss das halt nicht für jedes Modell irgendwie einzeln nochmal anpassen. Ja.

Genau. Ja, was wollten wir machen?

Ja, jetzt haben wir eigentlich unsere Zahlenmatrix. Eigentlich sind wir jetzt bereit, um darauf Modelle langsam zu trainieren, oder?

Genau. Ich habe hier einen TF-EDF-Facturizer sozusagen instanziiert, dann den gefittet auf den Trainingsdaten. Dem kann man auch noch alle möglichen Optionen mitgeben, was jetzt hier nicht geht.

Das habe ich getan, aber man kann ihm noch sagen, wie er es organisieren soll.

Gewisse Stop-Wörter rauswerfen, was man auf jeden Fall machen würde, aber ja.

Ja, genau. Und ob er halt irgendwie das noch irgendwie smoothen soll, oder ob man kann, welche Normen, man kann.

alles mögliche angeben.

Und

genau, den habe ich in Trainingsdaten gefüttert

und ich benutze jetzt die Transform-Methode,

um damit sozusagen die Texte

aus den

Trainingsdaten und aus den Testdaten

in so Feature-Matrizen zu

verwandeln. Und

genau,

das sind dann hinterher

ja,

das ist auch nochmal so eine kleine Spezialität.

Das ist jetzt natürlich

das, was dabei rauskommt, hat

relativ, also die Matrix, die da rauskommt,

normalerweise muss 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, es ist ja dann wahrscheinlicher, dass du mehr Texte hast, dass du mehr unterschiedliche Wörter hast.

Ja, wobei, also

genau, wenn ich dann

Texte habe, die alle sehr, sehr ähnlich sind, habe ich dann natürlich auch

viele Einser vom Prinzip her.

Das heißt einfach quasi, wie sparse ist

meine Matrix, das Wort dafür.

Genau, sparse.

Die Daten sind halt

sehr sparse und

das ist halt ein Problem

oder ist halt sehr verschwenderisch,

was Hauptsprecher angeht, wenn man tatsächlich die Werte speichern

würde. Und es gibt dann so

ja, also ein SciPy

Modul

irgendwie gibt es dann Klassen, die

sich halt mit Spars,

mit dem Speichern von Sparsen Matrizen

irgendwie beschäftigen.

Und

ja,

da

der Trick ist im Grunde, dass man halt die ganzen Nullen

einfach nicht speichert. Dass man sagt, irgendwie man

speichert

nur, an welchen Stellen irgendwie

Zahlen sind. Alles andere ist halt

defaultmäßig null

und muss man halt auch nicht speichern.

Und man kann sich das auch im Grunde so vorstellen, also

die interessante Operation, die man jetzt auf sowas

ausführt, zum Beispiel wenn man jetzt eine Suchmaschine hat,

würde man irgendwie eine

Cosinus-Distanz

ausrechnen zwischen einem Dokument und einer Query.

Das heißt

sozusagen einfach nur das Skalarprodukt. Man würde den

Query in Vektor verwandeln,

ein Dokument in Vektor

verwandeln und dann bildet man einfach das Skalarprodukt.

Zwischen den beiden. Und

dafür muss man ja sozusagen nur die

Teile miteinander multiplizieren, die nicht null sind.

Weil

die anderen sind alle eh null. Das wird

aufsummiert. Also es ist

einfach weg. Und

daher ist das natürlich toll, wenn man eine Struktur hat,

wo sowieso nur die Teile gespeichert sind,

die nicht null sind. Und dann ist das 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 sparse sind.

Es gibt auch welche, bei denen das nicht geht.

Und da muss man halt unter Bestimmten auch nochmal ein bisschen was

machen.

Was man üblicherweise tun würde, also was

ein Modell, was immer gut funktioniert,

was man normalerweise immer braucht, aber was halt nicht

klarkommt mit sparsen Daten, wäre halt sowas

wie XGBoost zum Beispiel.

So ein

Distribution-Tree-Modell.

XGBoost?

XGBoost.

Extreme Gradient Boosting.

Ah, okay.

Und

da macht man

das eigentlich, oder für alle,

ich meine auch, was auch nicht mit Neuronalen

Netze kommt, auch normalerweise nicht mit sparsen

Eingaben, klar. Was man da vorher

macht, ist, man reduziert die Dimensionen.

Also wenn das,

ich weiß jetzt nicht, was das, was ich glaube,

auch irgendwas 25.000 Wörter gibt es da drin, oder so.

Wenn man jetzt

aus diesen 25.000 Dimensionen

etwas machen möchte, was das dense,

was das dicht ist, dann

projiziert man halt das aus dem

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 ist halt

immer so das Ding, was man dann nutzt und

projiziert, um die Sachen runter zu projizieren.

Es muss einem halt irgendwie mal klar sein,

wenn man halt so einen Korpus hat und dann hat man jetzt

in seinen Daten irgendwie

eine Million Dokumente

und diese Millionen Dokumente haben halt

irgendwie 30.000

unterschiedliche Wörter, dann habe ich halt nachher

prinzipiell erstmal eine Matrix, wenn ich jetzt nichts

davon wegwerfe oder so,

von 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

dieser Spalten, die sich sehr

ähnlich verhalten werden. Also

der Optimalfall

für eine Dimensionalitätsreduktion ist,

dass zwei Spalten oder

zwei Zahlen quasi komplett gleich sind,

weil dann verliere ich quasi

keine Informationen darüber, wenn ich einfach

sage, dass diese beiden Spalten,

wenn ich die beiden quasi zusammenlege.

Und wenn zwei Spalten

sehr, sehr stark korreliert sind,

dann verliere ich auch

nicht viele Informationen in dem Moment, wo ich

die beiden irgendwie zusammen auf 1 abbilde.

Also die, wenn die Spalten ja Wörter sind,

dann ist ja gleiche Wörter relativ unwahrscheinlich,

aber dann muss man tatsächlich diese Kombination

finden aus der Grammatik, die wir eben hatten,

halt das Modul laden dann, was war das,

WordConf, irgendwas,

von Google? Achso, WordSpec,

aber... WordSpec, genau.

Das könnte man ja nehmen als Information, um irgendwie so eine

Kovarianz in den Wörtern festzustellen und die da

halt dann so zu gruppieren, dass die halt dann

zusammenfassen und die... Theoretisch kann es aber auch vorher

der Fall sein. Also mal angenommen, ich habe zum Beispiel

einen Namen dran, 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 1 für ein Dokument.

Dann sind diese

beiden Spalten natürlich perfekt korreliert.

Und dann können die natürlich auch beliebig

von der Dimensionalität

auf einer projiziert werden.

Also würde man da nur einen von

beiden wegschmeißen oder sagt man einfach, ja, das ist eigentlich nur

in einem Dokument, ist eigentlich egal.

Letztendlich machst du das selber gar nicht, sondern der Algorithmus

überlegt sich einfach selbstständig, wo

verliere ich am wenigsten Informationen, indem ich

die runtergebe und was ich von außen nur sage, ist

auf welche Zieldimension will ich gerne?

Also das heißt, dass da einfach 300 reicht.

Genau. Und der projiziert

es für dich runter, aber das ist die Logik, die dahinter steht.

Genau. Und dabei geht praktisch

nur sehr wenig Information

verloren. Das funktioniert halt ziemlich gut.

Genau.

Also das ist halt auch sowas. Aber das ist halt

irgendwie dann doch so eine Geschichte, wo dann

man nicht immer irgendwie alles gleich

verwenden kann, weil es gibt halt Modelle, die kommen

halt mit Spasen-Daten klar und manche halt nicht.

Ja.

Genau, genau, genau.

Gut, aber jetzt wollen wir mal ein Modell trainieren.

Ja, ein Modell trainieren, genau. Dafür gibt es dann halt auch

irgendwie einmal

eine Abstraktionsgeschichte, um halt dieses

Multilabel-Ding sozusagen

es gibt einige Modelle, die

automatisch Multiclass können, aber Multilabel

da muss man halt

braucht man halt noch so einen Wörter außenrum

und eine einfache Art,

wie man halt sozusagen aus einem

Modell, also was alle Modelle können, ist halt

binäre Klassifikation, das ist halt auch das Einfachste

und man kann jetzt natürlich aus

binärer Klassifikation quasi automatisch eine

Multilabel-Klassifikation machen, indem

man einfach für jede Klasse

eins gegen alle anderen

ein Modell trainiert, was dann binäre Klassifikation

macht.

Und dann, das muss man aber auch nicht selber machen,

sondern da gibt es dann halt schon

ein vorgefertigtes Ding,

aus Scikit-Learn Multiclass,

das Ding heißt One-Versus-Rest-Klassifier

und der tut das dann

und man kriegt das gar nicht mit, sondern

steckt einfach nur das eigene Modell, was man verwenden

möchte, da rein und dann passiert das automatisch.

Und dann gibt es halt noch

aus dem

Scikit-Learn-Metrics-Modul

eine Klassification-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

auch ein

Klassifikationsmodell,

das heißt bloß Regression,

das ist nicht so.

Ja, ich bin auch total,

ich habe mich am Anfang auch lange Zeit verwirrt,

dass ein

eine Methode, die

Regression im Namen hat, in Wirklichkeit eine

Klassifikation ist, aber...

Das ist halt irgendwie...

Das ist halt dieser Algorithmus, der im Endeffekt dahinter steht.

Das sollte man nicht zu tief drauf reingehen.

Genau, genau.

Und das ist halt so ein Standard-Ding.

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

kann man 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 komplizierteres Dinge machen, wenn das halt nicht reicht.

Ja.

Genau.

Model ist

jetzt sozusagen einfach nur Run-versus-Rest-Classifier

und da das

Logistic Regression

Modell reingesteckt und

dann

einmal Fit auf, um das Modell zu trainieren

und dann einmal

Predict, um

ja, die Voraussagen

zu bekommen für die

Test-Dokumente.

Ich finde das sehr gut.

Das ist ein sehr gutes Beispiel für,

wie so ein echtes Welt-Data-Science-Projekt aussieht.

Weil, wenn man jetzt irgendwie

sagt, also wenn man von außen dann

naiv draufschaut

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 Predict und hast dein Ergebnis.

Also das eigentliche Modell-Training,

ist kein Problem, aber wir reden

jetzt hier schon eine Stunde, eine halbe

oder so darüber,

wie wir da hinkommen und das

ist die Schwierigkeit bei dem Ganzen, dass es halt

in Wirklichkeit dann doch nicht so trivial ist, dass man halt

eben irgendwie Multiclass oder Multilabel

hat oder sehr große Matrizen oder

Dimensionalitäten reduzieren muss und

Features ingenieren und genau,

dieser Weg dahin ist das Komplizierte.

Ja, und dann haben wir aber jetzt

eine Prognose raus und

müssen uns überlegen, wie gehen wir mit der um,

wo es auch wieder anfängt komplizierter zu werden.

Genau, ist halt wahrscheinlich ein bisschen

unübersichtlich beim Classification-Report, das halt über

alle 90 Kategorien zu machen, deswegen habe ich jetzt einfach mal

die Top-10-Kategorien

genommen. Das ist auch so, wenn man sich

dafür interessiert, gibt es halt

die Doktorarbeit von Thorsten

Joachims, die ist glaube ich

eines der meistzitierten Papers

sozusagen im Textklassifikationsbereich,

irgendwie ist es anderthalb tausend Mal zitiert worden oder so.

Der hat sich

damit zuerst 1998 irgendwie

beschäftigt und

das Ding gibt es als Buch oder man kann halt

irgendwie zu so einer Schattenbibliothek gehen.

Da gibt es das auch.

Und da kann man sich halt auch,

man guckt sich da auch mal die Top-10-Kategorien

an und kann das einfach mal

vergleichen, die Zahlen, die er da rauskriegt,

mit dem, was man da selber irgendwie dann sozusagen

da

als Ergebnis hat und

sieht eigentlich alles ganz gut aus.

Genau, die,

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, das ist was, womit man den Umgang auf jeden Fall wirklich lernen muss.

Da hat mich ganz am Anfang, als ich angefangen habe mit

Data Science, konnte ich mit den ganzen Zahlen auch nicht wirklich

was anfangen.

Was man ja immer im Wesentlichen

hat, ist, man hat

prinzipiell vier Fälle.

Ich kann einfach

bei einer binären

Klassifikation, was so das Einfachste ist,

da kann es sein,

dass ein Ergebnis quasi wahr ist

und ich habe auch gesagt, dass

es wahr ist, das ist das Einfachste, dann habe ich

ein True Positive.

Es kann auch sein, dass es

falsch ist und ich habe aber gesagt,

dass es wahr ist, dann habe ich

ein

False Positive.

Ich kann sein,

dass ich richtig gelegen

habe und es negativ ist,

dann habe ich ein True Negative.

Oder es kann negativ sein und

ich lag auch noch daneben, dann habe ich ein

False Negative.

So, und jetzt

gibt es quasi Kombinationen von diesen

Feldern für Precision und Recall.

Und die inhaltliche Bedeutung davon ist

vom Prinzip, also man kann sich das auch in den Formeln

anschauen, ich finde das hilft aber weniger, als

einfach zu sagen, die Precision

ist, wie viele von

meinen Daten, wo ich gesagt

habe, dass sie wahr sind, sind auch wirklich wahr.

Und Recall ist,

wie viele von denen, die

prinzipiell wahr sind, die ich quasi

prognostizieren wollte,

habe ich dann 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 ein Zahlenwert rauskommt

zwischen 0 und 1. Und wenn ich quasi

die 1 habe, dann habe ich quasi sowohl Precision

als auch Recall perfekt bei 1.

Und wenn ich bei 0 habe, lag ich bei beiden

komplett falsch. Und der gibt

so eine Art Bonus, durch das

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 da 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

Absolut-Skala zu geben. Weil diese Zahlenwerte

sind jetzt natürlich alles relativ. Wenn ich nur

ein Beispiel habe, und das habe ich richtig klassifiziert,

dann habe ich einen F1-Score von 1 und alles

ist super. Aber wenn es halt nur ein Beispiel war,

dann hilft mir das real im echten Leben natürlich wenig.

Deswegen ist dieser F1-Score,

dieser Support dann so eine Matrix für

wie wichtig es ist, denn in absoluten Zahlen.

Ja, ja, ja, ne, 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.

Wenn man jetzt Precision und Recall-Werte hat, dann ist das halt blöd.

Man kann halt nicht so richtig gut nach,

wenn man jetzt 2-Werte hat, irgendwie, wie will man dann sortieren?

Daher

muss man

das halt irgendwie in 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

sowas überhaupt machen muss, man kann jetzt nicht einfach

vorstellen, warum immer nicht einfach Accuracy

oder so. Ja, das

geht halt nicht so gut.

Also Accuracy funktioniert halt dann gut, wenn

das halt,

wenn alle Klassen irgendwie die gleiche Anzahl

von Beispielen haben und so,

dann geht das vielleicht, aber das wird auch schwer,

sich vorzustellen, wenn man jetzt

irgendwie was anderes hat als nur 2.

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

mag das schon so mit dem,

was andere Leute auch beobachten,

übereinstimmen, dass halt 99% der Mails,

die ich bekomme, sind halt Spam.

Und wenn ich jetzt...

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 dann Accuracy von 99%.

Klingt doch super, voll gut. Aber der macht ja eigentlich

gar nichts oder macht auf jeden Fall

nichts Sinnvolles, weil hinterher kriege ich halt gar keine

Mail mehr. Und

äh,

so, das...

Ja, diese Irrtumswahrscheinlichkeit ist tatsächlich, glaube ich,

relativ relevant auch für den Untersuchungsgegenstand, den man hat.

Ich weiß nicht, ob ihr Alpha- oder Beta-Fehler nennt man das, glaube ich,

so in der klassischen Statistik.

Ja, oder viele Erste-Ordnung oder Zweite-Ordnung oder sowas.

Und da ist ja schon

sehr entscheidend, also was für

Untersuchungsgegenstände man hat. Manchmal ist 5%

Abweichung dann ganz okay, weil 95% Wahrscheinlichkeit

ist ausreichend irgendwie. Vielleicht bei Hund-Katze

unterscheiden, vielleicht auch nicht ganz so wichtig.

Aber bei anderen Dingen ist halt dann das

1%, 1% zu viel. Also gerade wenn man

so Häufigkeitsverteilungen hat wie, es kommt nur 1%

der Fälle sowas raus.

Und dann Fallstieg 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.

Vielleicht muss man dann

einen Negativfehler nehmen. Dann muss man vielleicht nicht versuchen,

Spam zu tracken, sondern richtigen Mail.

Aber wenn man jetzt Precision-Recall nehmen würde, würde man sagen,

okay, dann sieht man es halt sofort, weil Precision wäre 0.

Ja, also andersrum ist halt tatsächlich

dieses Ding, wenn du halt den Spam

immer versuchst zu tracken und er sagt immer

Spam, dann müsstest du halt umdrehen, musstest sagen,

hey, ich möchte richtigen Tag tracken. Und dann hättest du halt

vielleicht eine bessere Erkenntnis.

Oder so, weil du das halt nicht

wegschmeißen würdest durch die Fehlerwahrscheinlichkeit.

Ja,

auf jeden Fall, also

für so im allgemeinen

Fall, wenn man viele Klassen oder

Labels hat und

unterschiedlich verteilte

Klassen, dann sind halt

Precision-Recall halt ein viel besseres Maß

als irgendwie

Accuracy. Daher nimmt man das als,

es gibt auch noch andere Metriken, die man irgendwie

benutzen kann, aber das ist schon irgendwie

so, dass

verbreiteten

verbreitetste, denke ich mal.

Das kommt halt auch so aus diesem Information-Retrieval-Bereich.

Genau, und diese Metriken sind halt so ein bisschen,

ja, man muss damit halt lernen, umzugehen.

Jedes Problem ist ein bisschen anders, also

wir haben jetzt hier, wie gesagt, so eine Multi-Label-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

Metriken-Feld wird es dann interessant,

in welchem Bereich von Data Science

man sich begibt und was man gerne machen

möchte.

Da kann man viel Zeit reinstecken.

Das ist auch wichtig.

Genau, und das ist teilweise auch sehr schwer

zu erklären, also wenn man dann irgendwie

ja,

dass dann halt auch Ergebnisse

irgendwie reportet,

ist es 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 sein im Erklären.

Keine Ahnung.

Genau, beim Wesentlichen sind wir jetzt die Basis-Pipeline

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 den mitzunehmen,

zu lernen oder sowas man machen könnte, aber wir haben

zumindest den ganzen Text umgewandelt

in eine Zahlmatrix und die reduziert

und darauf jetzt halt eben ein Modell

berechnet und können sagen,

wie gut dieses Modell ist.

Wenn man jetzt

einfach da eine Spalte dran hängt, geht das

einfach so? Also wenn man das schon so ein bisschen modelliert hat,

dass man dann sagt, hey, ich hänge jetzt sowas dran,

wie die Länge.

Ja, genau.

Also hier erzeuge ich ja sozusagen

die

Feature-Matrizen direkt,

aus dem Text,

aber wenn wir uns jetzt zum Beispiel

mal angucken,

na, ich glaube,

das

Grid-Search-Ding macht das dann halt

auch schon so ein bisschen anders. Was man da

normalerweise dann hat, ist halt

eben

nicht so eine naive Geschichte, wo man das einfach

so erzeugt, sondern man hat halt

eine, die Feature-Matrix wird erzeugt

durch, oder überhaupt das komplette

Ding ist halt

eine Pipeline.

Das ist halt

auch eine Klasse aus Cycle-Learn

und die kombiniert im Grunde

viele Schritte

sozusagen zu einem Ding, das

sich insgesamt wieder so verhält wie ein Modell.

Also zum Beispiel

jetzt bei dieser,

in diesem

Notebook ist es halt so, da

sind die Schritte, aus denen

die Pipeline besteht, halt

eine zweite

Geschichte, die ich irgendwie da noch einführen muss.

Das Ding nennt sich Feature-Union.

Und man kann sich das im Grunde so vorstellen, also Feature-Union

macht genau das,

was du jetzt vorhattest, einfach irgendwie Dinge

an die Feature-Matrix spalten, an die Feature-Matrix

dran bauen,

sozusagen. Also sozusagen, ich hab halt

unterschiedliche

Spalten, ja, und ich möchte die halt

zusammen kombinieren zu einer

Feature-Matrix, dann nehme ich Feature-Union,

das fügt halt die Spalten zusammen

und die Pipeline

integriert die ganzen Schritte, die nötig

sind, um irgendwas zu tun.

Also Feature-Extraction,

unterschiedliche Arten von

Feature-Extraction und halt

am Schluss irgendwie ein Modell trainieren und

ja,

auf den Festdaten halt

Predictions machen,

sodass das

Ganze sich wieder als ein Modell irgendwie

benutzen lässt. Und was

das hier tut, ist

ja, ich übergib der

Feature-Union halt

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, das ist der erste

Schritt, der nimmt

eine Spalte aus dem

Data-Frame, und zwar den Titel

und

macht dann eben so etwas wie

ja,

Text-Statistiken 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 das tut.

Und dann skaliert er halt

diese, weil das,

das wäre bei TF-EDF, das ist halt automatisch

drin, das ist halt irgendwie

sozusagen

ja, skaliert

ist auf wie ein

Intervall zwischen, weiß ich nicht, 0 und 1

und

normalisiert, sodass es halt irgendwie

alle Vektoren, die Länge 1 haben.

Bei den Text-Statistiken 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, ja,

zwischen minus 1 und 1 oder

zwischen 0 und 1 sind und

auch eine Standardabweichung von 1 haben

irgendwie so. Das hängt halt auch mal viel damit

zusammen, was für ein Algorithmus du im Nachhinein dann

benutzt. Manche Algorithmen können

gut umgehen mit

komplett absolut skalierten

Werten, also so im Entscheidungsbaum zum Beispiel,

dem ist das relativ egal, wo er

jetzt zwischen, ob du jetzt den Wert zwischen

0 und 1 reingibst und Werte

zwischen 0 und 10.000, weil

der entscheidet einfach irgendwo, okay, zwischen

diesen zwei bitte splitte und

das rechte Ast, das linke Ast,

aber bei so einer linearen

Regression zum Beispiel, da ist

es halt von Bedeutung, wenn deine

Achsen alle ganz unterschiedlich

sind. Also ich könnte, das Wichtige ist eigentlich nur,

dass sie halbwegs miteinander vergleichbar sind.

Ich könnte sie auch alle von

0 bis 100 skalieren oder so, aber die Konvention ist

halt einfach, man macht das halt einfach alles zwischen 0 und

1 oder minus 1 und 1, je nachdem,

was man da vielleicht bezwecken möchte

und damit macht man in der Regel nichts

falsch. 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

Modells.

Dieses Modell zu trainieren, aber das ist immer das

Gleiche, wenn das ein lineares Modell ist.

Also ob ich jetzt eine Support-Vektor-Maschine

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 ist massiv.

Das heißt, ich muss die alle so

normiert haben, dass hinterher die Länge der

Vektoren 1 ist, damit

nicht ein

Feature halt da so irgendwie...

Alle Features sollten irgendwie so quasi

numerisch gleich wichtig sein.

Ja, deswegen muss ich das halt

skalieren am Schluss. Und dafür

gibt es auch unterschiedliche Skalierer

und der Standard-Scaler

macht glaube ich irgendwie...

Weiß ich gar nicht.

Ja, das ist ganz

validity halt.

Ist validity halt irgendwie oder. Genau.

Der wesentliche Punkt eigentlich bei diesen Pipelines ist,

ich könnte diese ganzen Schritte

auch alle nacheinander ausführen. Also ich kann

prinzipiell in meinem Notebook,

das haben wir vorher quasi auch gesehen,

in dem linearen Regressionsnotebook,

ich kann

erst meinen Text umwandeln,

Dimensionalitätsreaktionen ausführen

in der nächsten Zelle und quasi immer dazwischen

meine Werte irgendwie in ein neues DataFrame

schreiben und das wieder in das nächste reinführen.

Ist zum Debuggen

vielleicht auch mal ganz hilfreich. Aber

wenn ich nachher quasi dann einfach damit

spielen möchte, verschiedene Werte zu verändern,

dann will ich, dass das möglichst einfach hintereinander

durchläuft. Und ich weiß nicht,

cashen so Pipelines auch zwischendrin

Schritte? Genau. Genau, das heißt, das macht

es auch deutlich effizienter, wenn ich dann

quasi in einem relativ späten Step

in der Pipeline eine Kleinigkeit ändere,

dann muss die halt nicht komplett von vorne durchgeführt werden.

Und

genau, das mache ich prinzipiell eher,

wenn ich schon so die erste

Exploration durch habe, dann würde ich anfangen

sowas in eine Pipeline zu stecken oder machst du das wirklich von Anfang

an? Ne, genau, ich mache das auch erst, wenn

ich ungefähr weiß, was ich da

damit tun möchte und

ja, genau,

man braucht es halt auch vor allen Dingen deswegen, wenn man jetzt

unterschiedliche Sachen ausprobieren möchte. Das ist

halt, Stichwort

wäre Hyperparameter-Optimierung,

also sozusagen, welche Features verwende ich.

Man kann ja, man könnte ja dann

doch wieder gewichten, wenn man möchte, oder?

Ja, natürlich,

man kann auch einzelne Teile davon,

man könnte jetzt unterschiedliche Feature-Unions

bauen, so eine zum Beispiel, die sich nur mit dem

also, das ist ja

im Grunde hier auch schon so, also ein

Ding, das sich halt nur mit dem Text beschäftigt, oder

eins wird, dass sich mit dem Body,

mit dem Titel beschäftigt, und eins, dass 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 GridSearch,

und das ist halt auch ein Vorteil, wenn man jetzt so

eine Feature-Pipeline hat, dass man

sozusagen die Bereiche für

die Parameter, die man halt

durchprobieren möchte, die gibt man halt irgendwie an,

und dann

ruft man das halt mit GridSearch auf, und dann

werden diese ganzen Parameter, dieses Parameter-Grid

halt durchprobiert, und am Schluss

ja, also fällt halt das Modell

raus, was halt am besten funktioniert hat, beziehungsweise alle

anderen Ergebnisse werden auch gespeichert, normalerweise

will man jetzt da irgendwie aus diesem

GridSearch-Ding halt

rausholen und irgendwo ein CSV

schreiben, oder irgendwie, und dann kann man sich das halt hinterher

visualisieren, und dann halt gucken,

okay, wann habe ich das mit welchen Parametern

irgendwie ausprobiert, und was ist dabei rausgekommen.

Genau, man muss, also ich würde da

die Hyperparameter-Tuning noch mal

kurz ein bisschen aufgreifen.

Jeder dieser Algorithmen,

die wir jetzt erwähnt haben, die haben jede

Menge Parameter, die man da mitgeben kann.

Also, eine ganz einfache

lineare Regression ist vielleicht noch relativ

beschränkt, aber sobald wir

die jetzt zum Beispiel

regularisieren, das heißt irgendwie

verhindern, dass die irgendwie zu stark sich den Daten

anpasst, bekommt die Hyperparameter

oder noch einfacher finde ich es sich vorzustellen

bei so einem Entscheidungsbaum, der hat halt

eine gewisse Tiefe, der kann irgendwie auf

100 Leveln verschachtelt sein, oder nur auf

2, und der kann auch

zum Beispiel beschränkt werden in der Anzahl der

letztendlichen Blätter, also wie viele mögliche

Output-Ergebnisse kommen dahin, oder

wie viele Samples müssen in

jede dieser Blätter letztendlich fallen. Das sind zum

Beispiel schon drei verschiedene Parameter, die man

da so mitgeben kann, und die können die

Art, wie gut

dieses Modell performt,

extrem beeinflussen. Das ist

wirklich sehr, sehr entscheidend,

und deswegen ist es wichtig, die

einfach nach und nach durchzuprobieren.

Und man sagt jetzt, wir haben noch irgendwie selbstlernende Algorithmen,

irgendwie, warum

muss ich denn da jetzt noch Parameter-Tuning, aber

ich passe ja quasi einfach

die, man muss

es sind halt zwei verschiedene Arten von Parametern.

Die einen sind quasi die internen, die

berechnet werden, innerhalb des Algorithmuses,

die lernt er aus

den Daten, und das andere sind quasi so

die Konfigurationsobjekte,

wie man das, wie

die Berechnung von diesen anderen

Parametern zustande kommt, und

die muss ich ihm halt eben mitgeben,

oder ich versuche sie halt einfach alle,

probiere sie halt einfach alle durch, und das ist,

was ich mehr oder weniger bei so einem Hyper-Parameter-Search

mache. Ich überlege mir

irgendeine Strategie, dass er einfach

möglichst viele von denen durchprobiert, da gibt's

auch Algorithmen, die versuchen quasi selbstständig

so ein bisschen zu wählen, welche

an welcher Schraube drehe ich als nächstes

um halt dann den Algorithmus

in der Stelle optimal zu tunen

und das ist 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 das nochmal

man möchte das ja auch

wenn da mehrere Leute dran arbeiten

denen das ja auch irgendwie kommunizieren

und da ist es natürlich dann schon gut

wenn man das systematisch gemacht hat

weil dann fallen da eben solche CSVs einfach schon bei raus

und man kann halt auch gucken, was andere Leute schon probiert haben

und muss das dann auch nicht nochmal selber machen

Genau und diese Hyperparameter 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 hat gut funktioniert und auch Features reiningenieren möchtest

du schreibst das dann einfach in CSVs weg

oder wie machst du das?

Ja, meistens tatsächlich, ja

Das finde ich immer noch ein bisschen überraschend

dass da Second Learn an der Stelle irgendwie

nichts von sich aus bietet

also ich habe mir jetzt gerade da auch diverse Tools angeschaut

ich finde da jetzt MLflow

von Dataprix

ganz cool

die ja auch quasi Spark gebaut haben

die haben da ein Tool für

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 Predolje

dass er jetzt quasi ein bisschen damit rumspielt

und seine ganzen Ergebnisse an und nach noch tracken möchte

und jeder schreibt sich die irgendwie so ein bisschen

auf seine eigene Art weg

aber der Standardsupport 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

Python

Pythonic, ja

also das basiert halt komplett auf

Kommandozahlenaufrufe und Shell-Skripten

ich habe letztendlich quasi so die Abwägung

würde ich sagen

wenn du schnell Sachen ausprobieren willst

und mehr so in der Exploration bist

dann guck dir lieber MLflow 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 Zeit zu investieren

as 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 oder das andere.

Das hängt ein bisschen mehr von deinem Projekt ab,

aber gerade für die Exploration finde ich

DVC einfach

zu viel Boilerplate Code.

Ich verlinke dazu mal meinen Artikel,

den ich auch gerade noch geschrieben habe, genau darüber.

Ja.

Jetzt könnte man natürlich

alle möglichen verschiedenen Algorithmen draufwerfen

und so, aber ich würde sagen, das überlassen wir mal

den Hörern, da könnte man jetzt auch ewig Zeit

draufwerfen.

Haben wir irgendwas Wesentliches

vergessen?

Den grundsätzlichen Prozess, dieses Datenbeispiel

da von Reuters mal kurz so

zu skizzieren, haben wir schon durch, oder?

Also es funktioniert auf jeden Fall,

wir haben jetzt tatsächlich gelernt,

wie man so eine neue

Nachricht dann mit so einem Label versieht,

dass dann die Klasse so, was ist das für eine Kategorie,

rausfällt unten, oder?

Genau. Also wir sind jetzt in der Lage,

ähm,

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 Text voraussagen,

die wir jetzt

quasi, ähm,

da drin hatten, da können jetzt kein

originär neuer

Artikel natürlich rausfallen oder so,

aber, ähm,

das haben wir und können auch bewerten, wie gut

wir daran sind.

Ja.

Ja, ja. Ja, also haben wir quasi unser erstes

Projekt erfolgreich abgeschlossen. Wenn wir das jetzt

auf dem Server implementiert haben, dann läuft das

so auch. Ja, wir könnten, wir könnten eben jetzt

so ein Modell hinter so einer, äh,

API irgendwie, äh, deployen

und, ähm, dann schicken wir

dann einen Artikel dahin und bekommen dann halt zurück,

äh, in welchen Dingern das liegt und dann,

dann muss man sich dann natürlich noch überlegen, okay,

gibt man halt zurück, in welcher Wahrscheinlichkeit,

mit welcher Wahrscheinlichkeit das in welcher, äh,

oder einfach nur eine Liste der

Kategorien, in denen es liegt,

ähm, und, ähm, wann,

wann sagt man eigentlich, äh, es liegt drin

oder nicht, äh, genau. Und das

ist, äh, da, da müssen wir natürlich noch eine Menge,

äh, Entscheidungen treffen. Das hängt halt

dann auch davon ab, wie das Problem aussieht,

ne? Ist es wichtig, möglichst alle,

äh, in den Kategorien, in denen ein

Artikel liegen könnte, mitzuliefern

Das ist besonders wichtig, möglichst keine Fehler zu machen. Und das hängt dann halt davon ab, welche Art von Problem man gerade hat. Und dann 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 größten.

Das 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 einen Random Forest, was quasi einfach ganz, ganz viele Entscheidungsbäume sind, oder einen Boosting Tree, was quasi verschachtelte Entscheidungsbäume sind, dann hast du natürlich ein Vielfaches dessen.

Dann kommst du auf mehrere Megabyte, ein einzelner 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, also bei den linearen Modellen, die sind halt einfach genauso groß wie deine Feature-Matrix, also sozusagen haben genauso viele Dimensionen wie deine Feature-Matrix.

Und dann kannst du es ja einfach ausrechnen, wenn du pro Gewicht irgendwie vier Byte brauchst für einen Single Precision Float, dann ist das halt viermal, bei denen ist es wahrscheinlich mal 25.000, also viermal 25.000, also 100 Kilobyte, das ist halt nichts.

Aber wenn du jetzt zum Beispiel viele Trainingsdaten hast und du hast halt ein...

Also das ist ja auch noch...

So eine Geschichte, es gab in dem Explorations-Notebook auch so 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.

Also das kann sein, also das Ding halt macht natürlich nur Sinn, wenn man viel, viel mehr Trainingsdaten hat, aber wenn man jetzt irgendwie ein Modell hat,

50 Millionen Parametern, dann muss man die halt irgendwie speichern, das ist halt dann das Modell und dann wird das halt auch sehr, sehr groß unter Umständen.

Ja, aber selbst das ist ja für den Server heute alles nicht mehr so...

Es wird dann interessant noch, wenn man das nicht irgendwie auf den Server deployen möchte, sondern was heute oft gemacht wird, auch auf dem Telefon.

Und da muss man halt vielleicht nochmal 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, ist überhaupt nicht mehr kompliziert.

Aufwendig ist natürlich...

zu trainieren, wobei das mit den Modellen, die wir jetzt hier haben, alles relativ schnell

geht und man es einfach auf dem lokalen Rechner mal durchspielen kann. Bei einem neuronalen

Netzwerk wäre das bei dem Training was anderes, aber die Prognose ist hier nachher dann trotzdem

super einfach, weil dann gehe ich halt einfach nur einmal quasi den Entscheidungsbaum lang

oder laufe einmal mein neuronales Netzwerk von vorne nach hinten durch und fertig.

Wenn ich den Weg kenne, dann kann ich natürlich relativ schnell sagen, wo ich hin soll.

Genau, das kann auf schwacher Hardware laufen.

Ja, cool. Dann habe ich tatsächlich heute wieder ganz viel über Machine Learning gelernt.

Ich hoffe, ihr habt auch noch irgendwas mitgenommen.

Ja, wenn du noch ein bisschen mehr lernen willst. Also ich finde immer, so eigene Projekte

sind super und ansonsten einfach bei Kaggle mal einen Account machen.

Ja, Kaggle, ja.

Selbst wenn man da am Anfang nicht mitmacht. Also selber mitmachen ist sehr viel Aufwand,

aber es reicht eigentlich auch einfach nur mal ein paar Challenges zu beobachten und mal

ein paar Kernels sich aufzumessen.

Oder mal so nachbauen oder so welche, die es schon gab.

Mal gucken, wie gut man an die tollen Lösungen irgendwann rankommt.

Genau. Das Schöne ist ja bei Kaggle, dass diese ganzen Lösungen eigentlich immer einfach

alle online sind. Also diese Kernels, die da sind, die sind ja wirklich immer sehr, sehr

gut. Gerade auch bei der Exploration, wo man, also so ein Kernel ist ja vom Prinzip her

so ein Notebook.

Ja, vielleicht noch ganz kurz. In Kaggle gibt es Bounties dafür, wenn man total tolle Prognosen

herstellt. Also nur das vielleicht mal so für die Leute, die das schon 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 eines der top gerateten Notebooks da durchlese, lerne ich jedes Mal wieder was.

Ja, finde ich auch super hilfreich.

Ja, findet ihr, wie ihr alle eingeschaltet habt?

Jo.

Ihr findet immer die Informationen in den Shownotes.

Jo, sehr.

Genau.

Wie kommt das von dir?

Ich glaube, ich bin nicht lang, ja.

Ja, ja, das kennen wir schon. Und ja, dann hört wieder rein, bleibt gewogen, wann auch

immer ihr uns hört. Wenn ihr irgendwelche Feedback habt, schickt an eine E-Mail an uns,

hallo at peißenpodcast.de oder Nico. Und ja, bis dahin.

Jo.

Genau. Hört wieder rein und bis bald.

Tschüss.

Jo, tschüss.