WEBVTT

00:00:00.000 --> 00:00:15.620
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.

00:00:15.620 --> 00:00:17.560
Hi, schön weich zu sein.

00:00:17.560 --> 00:00:20.040
Ja, und Jochen ist natürlich auch wieder da.

00:00:20.040 --> 00:00:21.720
Ja, Jochen. Genau.

00:00:22.540 --> 00:00:32.820
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?

00:00:32.820 --> 00:00:48.920
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.

00:00:48.920 --> 00:00:51.920
Irgendwie von Containern über irgendwie so Desktop.

00:00:52.540 --> 00:01:00.840
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.

00:01:00.840 --> 00:01:05.740
Also es ist auf jeden Fall sehr spannend. Hört da mal rein. Kann ich empfehlen. Klingt gut.

00:01:05.740 --> 00:01:07.700
Genau.

00:01:07.700 --> 00:01:15.280
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.

00:01:15.280 --> 00:01:18.500
Ja, wahrscheinlich sollten wir erstmal so ein bisschen...

00:01:18.500 --> 00:01:22.500
Erstmal nochmal so allgemein vielleicht, was ist denn das überhaupt, das Machine Learning? Was macht das denn?

00:01:22.540 --> 00:01:33.780
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?

00:01:33.780 --> 00:01:37.180
Ja, das ist das Gefühl, was man heute in den Medien, finde ich, irgendwie immer bekommt.

00:01:37.180 --> 00:01:41.880
Also es ist halt so ein Buzzword, was überall rumschwirbt, genauso wie irgendwie künstliche Intelligenz.

00:01:41.880 --> 00:01:52.520
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.

00:01:52.540 --> 00:02:21.540
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.

00:02:21.540 --> 00:02:22.520
So hätte ich das.

00:02:22.540 --> 00:02:23.260
Hast du das zusammengefasst?

00:02:23.260 --> 00:02:26.080
Ja, würde ich prinzipiell genauso.

00:02:26.080 --> 00:02:30.840
Der Computer lernt so, was er mit neuen Sachen dann anfangen muss, aus alten Dingen.

00:02:30.840 --> 00:02:48.420
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.

00:02:52.040 --> 00:03:21.540
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.

00:03:21.540 --> 00:03:29.660
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.

00:03:29.660 --> 00:03:49.860
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.

00:03:51.040 --> 00:04:08.620
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.

00:04:08.620 --> 00:04:13.200
Man kann nicht so ein Gegenstand definieren, wo eine Katze ist irgendwie so ein kleines Tier und grau und weiß und so weiter.

00:04:13.200 --> 00:04:13.900
Ja, das ist schwer.

00:04:13.900 --> 00:04:20.540
Ja, oder auch das Arbeiten mit Sprache finde ich ein gutes Beispiel. Da hat man halt viele, viele Algorithmen entwickelt, die auch...

00:04:20.540 --> 00:04:36.600
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.

00:04:36.600 --> 00:04:50.500
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.

00:04:50.540 --> 00:05:06.900
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.

00:05:06.900 --> 00:05:16.380
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.

00:05:16.380 --> 00:05:20.340
Ja, aber das ist genau der spannende Punkt. Du hast nämlich genau gerade versucht zu erklären, dass...

00:05:20.340 --> 00:05:50.120
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.

00:05:50.140 --> 00:05:55.620
Wie wir dachten, aber dann trotzdem so ein Phänomen, was gerade, ja, bei den Leuten, die sich damit nicht auskennen, so ankommt.

00:05:55.620 --> 00:06:03.000
Ja, also wenn man das guckt, was, wenn man sich einfach nur die Ergebnisse anschaut, dann wirkt das so ein bisschen magisch, aber...

00:06:03.000 --> 00:06:06.360
Genau, also warum kann der Computer jetzt einen Hund von einer Katze unterscheiden, wie soll das denn gehen, so, ne?

00:06:06.360 --> 00:06:07.160
Genau, genau, ja.

00:06:07.160 --> 00:06:13.300
Wie, der Computer weiß, was ich da gerade gesagt habe und kann mit mir sprechen oder so, das ist schon phänomenal irgendwo.

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

00:06:19.940 --> 00:06:29.260
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.

00:06:29.260 --> 00:06:32.100
Verstehen wir die wirklich bei Machine Learning? Das habe ich jetzt nämlich auch noch nicht so ganz verstanden.

00:06:32.100 --> 00:06:48.840
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.

00:06:49.740 --> 00:07:09.840
Ä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.

00:07:09.840 --> 00:07:19.540
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.

00:07:19.540 --> 00:07:32.340
Ä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.

00:07:49.340 --> 00:08:10.500
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.

00:08:10.500 --> 00:08:19.000
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.

00:08:19.140 --> 00:08:25.760
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?

00:08:25.760 --> 00:08:48.940
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,

00:08:48.940 --> 00:09:08.280
ä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.

00:09:08.280 --> 00:09:14.740
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.

00:09:14.740 --> 00:09:15.500
Ja.

00:09:15.500 --> 00:09:18.560
Aber das Problem haben Deep Learning Algorithmen an der Stelle genauso.

00:09:18.740 --> 00:09:22.340
Ähm, ja, okay.

00:09:22.340 --> 00:09:32.100
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.

00:09:32.100 --> 00:09:38.700
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.

00:09:38.700 --> 00:09:48.540
Ä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,

00:09:48.540 --> 00:09:56.220
Geschichten, die, äh, also, ich glaube, 2004 hatte Paul Graham halt da irgendwie den, einen Artikel veröffentlicht, The Plan for Spam, äh.

00:09:56.220 --> 00:09:59.940
Jetzt musst du nochmal einmal kurz sagen, was Naive Base überhaupt ist, für alle, die das noch nie gehört haben.

00:09:59.940 --> 00:10:18.340
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,

00:10:18.340 --> 00:10:48.320
also binäre, quasi, Klassifikationen, also, drin oder nicht drin, äh, genau, man unterscheidet eigentlich nur zwei Klassen, genau, und, ähm,

00:10:48.320 --> 00:11:06.560
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.

00:11:06.560 --> 00:11:18.300
Genau, ähm, ich such mal grad, ob ich das hier, äh, finde, Moment, äh.

00:11:18.300 --> 00:11:46.640
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.

00:11:47.080 --> 00:12:01.440
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.

00:12:01.440 --> 00:12:16.820
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,

00:12:17.080 --> 00:12:43.500
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.

00:12:43.500 --> 00:12:47.060
Das hat ganz okay funktioniert, aber...

00:12:47.080 --> 00:13:12.380
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...

00:13:12.380 --> 00:13:13.360
Y-Combinator tatsächlich.

00:13:13.360 --> 00:13:14.200
Y-Combinator, natürlich.

00:13:14.200 --> 00:13:15.840
Ich wollte hart unterzungen, ich habe mich nur nicht getraut.

00:13:17.080 --> 00:13:47.060
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...

00:13:47.080 --> 00:13:53.080
Dann kann es auch der Mensch nicht mehr als Spammer kennen und dann verfehlt er seinen Zweck und der...

00:13:53.080 --> 00:13:54.120
Liebe Freund, ich brauche in Hilfe.

00:13:54.120 --> 00:13:56.860
Ja gut, okay, das ist jetzt eine bestimmte Art von Spam.

00:13:56.860 --> 00:14:00.180
Das sind die, die bei mir gerade immer durchkommen, immer wieder.

00:14:00.180 --> 00:14:00.680
Die kommen durch?

00:14:00.680 --> 00:14:01.140
Ja.

00:14:01.140 --> 00:14:03.200
Da ist aber irgendwas mit deinem Spamfilter nicht in Ordnung.

00:14:03.200 --> 00:14:04.280
Was für ein Spamfilter?

00:14:04.280 --> 00:14:05.380
Okay.

00:14:05.380 --> 00:14:11.120
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.

00:14:11.120 --> 00:14:12.480
Achso, okay, gut, ja.

00:14:12.480 --> 00:14:15.580
Genau, und zwar, das Verfahren ist halt super einfach.

00:14:15.580 --> 00:14:16.480
Das ist halt...

00:14:17.080 --> 00:14:24.360
Mach einfach aus den Mails, aus dem Inhalt deiner Mails im Spamordner eine lange Liste von Wörtern.

00:14:24.360 --> 00:14:27.460
Zähle, wie oft ein Wort da drin halt vorkommt.

00:14:27.460 --> 00:14:31.080
Merke dann die Gesamtzahl der Wörter und die Gesamtzahl der Mails, die da drin waren.

00:14:31.080 --> 00:14:34.660
Und mach das Ganze auch nochmal für den Ordner mit den Nicht-Spam-Mails.

00:14:34.660 --> 00:14:38.720
Und das ist schon das Training.

00:14:38.720 --> 00:14:39.460
Das war's.

00:14:39.460 --> 00:14:46.960
Also man hat jetzt quasi an jedem Wort sozusagen nur dranstehen, quasi, ja, wie oft das halt vorkommt.

00:14:47.080 --> 00:14:51.500
Und man hat nochmal eine Zahl für, ja, wie viel Mail...

00:14:51.500 --> 00:14:53.360
Da sagt der Eigentümer, uh, er hat Penis gesagt.

00:14:53.360 --> 00:14:55.100
Und dann sagt der, nee, ist wahrscheinlich Spam.

00:14:55.100 --> 00:14:56.300
Also so in etwa.

00:14:56.300 --> 00:14:57.880
Genau.

00:14:57.880 --> 00:15:01.940
Und die Klassifikation, also wenn man das gemacht hat, ist man mit dem Training schon fertig.

00:15:01.940 --> 00:15:03.100
Und das ist auch schon das Modell.

00:15:03.100 --> 00:15:10.040
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.

00:15:10.040 --> 00:15:14.440
Man macht aus dieser Wortliste eine Liste von Zahlen.

00:15:14.440 --> 00:15:17.040
Und man ersetzt jetzt jedes Wort.

00:15:17.080 --> 00:15:18.620
Und eben durch die Kategoriefrequenz.

00:15:18.620 --> 00:15:21.580
Das hatte man ja vorher schon ausgerechnet sozusagen.

00:15:21.580 --> 00:15:25.000
Man wusste halt, wie oft jedes Wort im Spam- und im Nicht-Spam-Ordner vorkommt.

00:15:25.000 --> 00:15:30.740
Und sozusagen, ja, dann ersetzt man jetzt die Wörter eben durch die Kategoriefrequenz.

00:15:30.740 --> 00:15:35.220
Und multipliziert jetzt einfach alle diese Zahlen miteinander.

00:15:35.220 --> 00:15:39.720
Und bekommt dann halt eine Wahrscheinlichkeit, dass eine Mail Spam oder Nicht-Spam ist.

00:15:39.720 --> 00:15:45.140
Und, ja, die Zahlen werden relativ klein sein, weil das sind alles relativ kleine Wahrscheinlichkeiten.

00:15:45.140 --> 00:15:46.640
Und die noch miteinander multipliziert.

00:15:46.640 --> 00:15:47.060
Das ist super.

00:15:47.080 --> 00:15:55.740
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.

00:15:55.740 --> 00:15:57.320
Aber, ja, das ist ja auch kein Problem.

00:15:57.320 --> 00:15:58.120
Und das war es schon.

00:15:58.120 --> 00:16:05.340
Also es ist wirklich nicht, es ist keine große, ja, es ist keine, wie soll man sagen, Raketenchirurgie.

00:16:05.340 --> 00:16:07.560
Das ist eigentlich eine ziemlich einfache Geschichte.

00:16:07.560 --> 00:16:10.340
Genau, das kann man ja einfach sich eigentlich auch noch so in einem Algorithmus darstellen.

00:16:10.340 --> 00:16:15.340
Da braucht man, ja, keine komplexen Selbstlernverfahren eigentlich noch, nicht wahr.

00:16:15.340 --> 00:16:17.040
Ja, also gut.

00:16:17.080 --> 00:16:18.120
Und deswegen lernt man tatsächlich.

00:16:18.120 --> 00:16:27.500
Also wenn ich jetzt sage, wenn jetzt eben, ich habe bisher nur Mails, die mir Produkte zur Vergrößerung meiner primären Geschlechtsmerkmale,

00:16:27.500 --> 00:16:29.960
die mir so und so was andrehen wollen, bekommen.

00:16:29.960 --> 00:16:38.960
Und ich kriege jetzt zum ersten Mal einen Nigeria-Spam, wo mich jemand halt dazu bringen will, einen kleinen Betrag ihm zu geben,

00:16:38.960 --> 00:16:40.980
um einen viel größeren zu bekommen.

00:16:40.980 --> 00:16:45.740
Dann würde ich halt das halt auch mit in die Spams, in den Spam-Montage reintun.

00:16:45.740 --> 00:16:46.740
Und dann müsste ich halt wieder neu...

00:16:47.080 --> 00:16:50.080
Diese Zahlen ermitteln.

00:16:50.080 --> 00:16:53.540
Genau, die müssen halt wieder neu gebildet werden, aber...

00:16:53.540 --> 00:16:59.220
Dann würden sich die Frequenzen wahrscheinlich zum Beispiel für so ein Wort wie Prinz oder so oder Schweizer Bankkonto entsprechend verändern.

00:16:59.220 --> 00:17:02.100
Und dann hoffentlich beim nächsten Mal werden wir dann so eine Mail dieser Art...

00:17:02.100 --> 00:17:03.700
Das finde ich ärgerlich für Prinz mit Schweizer Bankkonto.

00:17:03.700 --> 00:17:06.080
Ja, die haben ein Problem damit.

00:17:06.080 --> 00:17:11.320
Die werden, ja, die haben mit Meldern keinen Spaß mehr seitdem.

00:17:11.320 --> 00:17:16.780
Genau, und das, ja, und dann passt sich das durchaus.

00:17:17.080 --> 00:17:24.400
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

00:17:24.400 --> 00:17:27.060
und dann sollte das automatisch funktionieren und mitlernen.

00:17:27.060 --> 00:17:28.940
Ja.

00:17:28.940 --> 00:17:31.860
Ja, ich habe ja kurz eine Base-Kalzifikation erklärt.

00:17:31.860 --> 00:17:37.060
Wir sind aber immer noch nicht bei dem Beispiel angekommen, was wir irgendwie den Menschen...

00:17:37.060 --> 00:17:37.980
Wie macht man das denn überhaupt?

00:17:37.980 --> 00:17:40.500
Wir haben versprochen, dass wir irgendwie praktisch durchgehen wollen.

00:17:40.500 --> 00:17:41.780
Da hätte ich mal gesagt, lass uns das mal machen.

00:17:41.780 --> 00:17:42.140
Ja.

00:17:42.140 --> 00:17:46.620
Wir packen mit Sicherheit unter die Folgen mal einen Link zu dem Repository,

00:17:46.680 --> 00:17:47.620
was wir dafür benutzen wollen.

00:17:47.620 --> 00:17:48.860
Das ist vom Jochen.

00:17:48.860 --> 00:17:52.180
Da hat er halt eben eine Schulung drin, eine Data Science Schulung,

00:17:52.180 --> 00:17:58.540
woraus wir jetzt vor allem gleich mal das Beispiel nehmen wollen für die Text-Klassifikation.

00:17:58.540 --> 00:18:03.960
Und genau, wenn man da drauf geht, sieht man in dem Readme auch erstmal irgendwie alle Informationen,

00:18:03.960 --> 00:18:05.160
wie man sich das Ganze zieht.

00:18:05.160 --> 00:18:07.560
Also man klont sich halt erstmal das Gits-Repository.

00:18:07.560 --> 00:18:09.260
Soweit, so gut.

00:18:09.260 --> 00:18:11.880
Und dann kommen auch schon die ersten Python-spezifischen Sachen,

00:18:11.880 --> 00:18:16.600
denn dann müssen wir uns erstmal irgendwie mit Conda eine entsprechende Umgebung aufsetzen.

00:18:16.680 --> 00:18:19.480
Jochen, sag doch mal, warum sollte man das denn mal machen?

00:18:19.480 --> 00:18:20.440
Und warum denn Conda?

00:18:20.440 --> 00:18:28.980
Ja, also Conda ist sozusagen der Paketmanager des Teils von Python,

00:18:28.980 --> 00:18:32.600
der sich mit so Data Science, Machine Learning-Geschichten beschäftigt.

00:18:32.600 --> 00:18:35.600
Da steckt halt auch so eine Firma dahinter, Continuum Analytics.

00:18:35.600 --> 00:18:38.780
Das sind auch die Leute, die die Firma gegründet haben,

00:18:38.780 --> 00:18:41.380
sind auch die, die ursprünglich mal NumPy mitentwickelt haben und so.

00:18:41.380 --> 00:18:46.380
Und, ja, es ist...

00:18:46.680 --> 00:18:50.840
Früher hatte man ja irgendwie mal so die Hoffnung,

00:18:50.840 --> 00:18:57.820
dass die Distribution, das ganze Paketinstallationsding halt irgendwie überflüssig machen würden

00:18:57.820 --> 00:19:00.640
und sich halt um Abhängigkeiten und sowas kümmern.

00:19:00.640 --> 00:19:03.160
Und das ist irgendwie nicht passiert.

00:19:03.160 --> 00:19:10.360
Also stattdessen ist es so, dass irgendwie jede Programmiersprache so gefühlt irgendwie ihren eigenen Paketmanager hat.

00:19:10.360 --> 00:19:13.580
Und bei Python ist es ein bisschen besonders schlimm,

00:19:13.580 --> 00:19:15.480
weil da gibt es halt nicht nur einen, sondern mehrere.

00:19:15.480 --> 00:19:16.520
Je nachdem.

00:19:16.640 --> 00:19:20.840
In welcher Community man sich da aufhält,

00:19:20.840 --> 00:19:24.740
wenn man irgendwie eher Webentwicklung oder sonst wie Python-Entwicklung macht,

00:19:24.740 --> 00:19:29.360
dann ist es eher Pip und als Repository für Pakete halt PyPI.

00:19:29.360 --> 00:19:32.560
Ich würde sagen, das Problem hat nicht nur Python.

00:19:32.560 --> 00:19:32.900
Nee.

00:19:32.900 --> 00:19:36.120
Rust ist da auch ganz schlimm, habe ich schon gelernt, aber ja.

00:19:36.120 --> 00:19:37.500
Nee, genau.

00:19:37.500 --> 00:19:39.240
Ja, das wäre auf jeden Fall ziemlich anstrengend.

00:19:39.240 --> 00:19:41.980
Ich weiß gar nicht, ob ich Conda so verwenden würde, so außerhalb von Daten.

00:19:41.980 --> 00:19:43.720
Nee, würde ich glaube ich auch nicht machen.

00:19:43.720 --> 00:19:44.380
Mache ich auch nicht.

00:19:44.380 --> 00:19:46.600
Also wenn ich Webprojekte mache, dann nehme ich...

00:19:46.600 --> 00:19:48.080
Äh, eher Pip.

00:19:48.080 --> 00:19:52.980
Und tatsächlich funktionieren die meisten Sachen auch, wenn man sie mit Pip installiert.

00:19:52.980 --> 00:19:55.920
Also tatsächlich auch die ganzen Datensachen funktionieren über Pip?

00:19:55.920 --> 00:19:58.760
Ja, schon.

00:19:58.760 --> 00:20:03.720
Sie funktionieren zumindest gut genug, als dass man das meistens einfach so verwenden kann.

00:20:03.720 --> 00:20:08.240
Wenn ich jetzt irgendwie tatsächlich ein Modell trainieren wollte,

00:20:08.240 --> 00:20:11.160
ja, aber das will man halt, wenn man ein Selbstverwahrt,

00:20:11.160 --> 00:20:13.320
der irgendwie auch nur irgendwie Pandas noch mitbraucht,

00:20:13.320 --> 00:20:16.020
um halt irgendwelche Sachen anzupassen.

00:20:16.560 --> 00:20:19.460
Ein Webserver, der jetzt halt hinter irgendeiner API ein Modell hat,

00:20:19.460 --> 00:20:21.600
was irgendwas vorhersagt oder was irgendwas klassifiziert

00:20:21.600 --> 00:20:22.540
und dann die Ergebnisse zurückgibt,

00:20:22.540 --> 00:20:25.560
da ist es im Grunde egal, da kann man das bei Pip installieren,

00:20:25.560 --> 00:20:27.980
aber wenn ich jetzt irgendwie was trainieren wollte,

00:20:27.980 --> 00:20:31.740
dann würde ich eher die Conda-Pakete nehmen

00:20:31.740 --> 00:20:36.080
oder vielleicht sogar spezielle Docker-Images oder sowas.

00:20:36.080 --> 00:20:39.880
Also, ja, aus meiner Sicht hat halt Conda vor allem zwei Vorteile.

00:20:39.880 --> 00:20:42.380
Zum einen ist es halt schon mal gekappt,

00:20:42.380 --> 00:20:45.280
also zusammen das, was sonst Pip und Virtual Env ist.

00:20:45.280 --> 00:20:46.460
Also ich habe die Möglichkeit,

00:20:46.520 --> 00:20:49.080
sowohl eine virtuelle Umgebung hier zusammenzubauen

00:20:49.080 --> 00:20:52.240
und dann halt eben in die die Pakete mit rein zu installieren,

00:20:52.240 --> 00:20:56.100
was man häufig möchte, wenn man gerade zum Beispiel so ein Experiment macht,

00:20:56.100 --> 00:21:00.100
dann möchte ich vielleicht meine Basis-Version an Paketen so lassen,

00:21:00.100 --> 00:21:02.980
wie ich sie hatte und dann halt mal für jetzt eine Konferenz zum Beispiel

00:21:02.980 --> 00:21:04.660
mir nochmal eine zweite daneben stellen.

00:21:04.660 --> 00:21:08.640
Das müsste ich ja sonst mit Virtual Env und Pip quasi in zwei Schritten machen.

00:21:08.640 --> 00:21:11.300
Ja gut, aber normalerweise machst du ja Virtual Env Rapper,

00:21:11.300 --> 00:21:13.200
dann einen Befehl und dann ist das Ding ja oben.

00:21:13.200 --> 00:21:13.740
Genau.

00:21:13.740 --> 00:21:16.360
Ich habe da tatsächlich ein Python-Skript für sowas geschrieben.

00:21:16.480 --> 00:21:18.400
Der auch genau das gleiche macht, wenn ich das will, aber ja.

00:21:18.400 --> 00:21:20.460
Genau, und der zweite Punkt ist,

00:21:20.460 --> 00:21:23.660
Conda kann halt einfach ja noch ein bisschen mehr als Pip.

00:21:23.660 --> 00:21:26.460
Es kann halt vor allem auch quasi Abhängigkeiten,

00:21:26.460 --> 00:21:29.340
die außerhalb von Python-Paketen liegen, lösen,

00:21:29.340 --> 00:21:30.580
was dann halt auch interessant wird,

00:21:30.580 --> 00:21:33.240
wenn es halt um Treiber-Support und so weiter geht.

00:21:33.240 --> 00:21:35.800
Genau, aber ich glaube, du hast schon recht,

00:21:35.800 --> 00:21:37.720
dass es auch so ein Stück weit ein Community-Ding ist,

00:21:37.720 --> 00:21:39.480
dass es sich halt im Data-Science-Umfeld

00:21:39.480 --> 00:21:43.200
auch durch den starken Support von Continuum da

00:21:43.200 --> 00:21:45.540
und den finanziellen Mitteln, die dahinter stecken,

00:21:45.540 --> 00:21:46.280
so durchgesetzt hat.

00:21:46.440 --> 00:21:47.560
Ja, aber...

00:21:47.560 --> 00:21:48.640
Ja, ja, also...

00:21:48.640 --> 00:21:50.280
Weil es so einfach zu installieren ist auch.

00:21:50.280 --> 00:21:51.980
Es gibt halt auch, glaube ich, nur Windows-Binarys einfach

00:21:51.980 --> 00:21:54.400
und da ist dann alles mit dabei an Modulen, was man so hat

00:21:54.400 --> 00:21:55.460
und man muss das gar nicht mehr groß bedienen.

00:21:55.460 --> 00:21:58.220
Ich glaube, das ist auch so ein low-leveliger Ansatz.

00:21:58.220 --> 00:21:59.300
Das ist auch der Grund, warum sie das so verbreitet hat.

00:21:59.300 --> 00:22:00.560
Wobei ich jetzt ehrlich gesagt zum Beispiel

00:22:00.560 --> 00:22:02.940
die große Anaconda-Distribution habe ich nie benutzt,

00:22:02.940 --> 00:22:03.660
habe ich nie installiert.

00:22:03.660 --> 00:22:07.300
Also das Anaconda-Distribution ist eigentlich sozusagen

00:22:07.300 --> 00:22:10.700
das eigentliche Ding, was irgendwie da produziert wird.

00:22:10.700 --> 00:22:12.640
Ich habe immer Mini-Conda verwendet

00:22:12.640 --> 00:22:15.100
und dann halt das installiert, was ich gerade gebraucht habe.

00:22:15.100 --> 00:22:15.980
Also der Unterschied ist,

00:22:16.400 --> 00:22:18.500
Anaconda bringt halt schon mal irgendwie alle möglichen Pakete mit,

00:22:18.500 --> 00:22:19.880
die man potenziell so gebrauchen könnte

00:22:19.880 --> 00:22:22.220
und Mini-Conda ist halt erstmal klein und schlank

00:22:22.220 --> 00:22:25.440
und dann muss man halt alles quasi mit dazu installieren,

00:22:25.440 --> 00:22:26.340
was man dann noch gerne hätte.

00:22:26.340 --> 00:22:29.740
Ja, und eben der Vorteil gegenüber Pip

00:22:29.740 --> 00:22:30.960
oder sagen wir mal so,

00:22:30.960 --> 00:22:33.420
das ist halt auch nicht mehr so ganz...

00:22:33.420 --> 00:22:35.340
Das war früher ein Riesenunterschied,

00:22:35.340 --> 00:22:36.500
ist heute nicht mehr ganz so relevant,

00:22:36.500 --> 00:22:38.480
ist halt, dass man halt binäre Geschichten

00:22:38.480 --> 00:22:40.200
bei Anaconda auch installieren kann.

00:22:40.200 --> 00:22:42.320
Also man kann halt auch Bibliotheken,

00:22:42.320 --> 00:22:43.080
die unten drunter liegen,

00:22:43.080 --> 00:22:44.620
also eben nicht nur Python-Pakete,

00:22:44.620 --> 00:22:45.440
sondern eben auch sowas.

00:22:45.440 --> 00:22:46.360
Man kann auch theoretisch sowas wie

00:22:46.360 --> 00:22:48.620
Libc irgendwie mit Conda installieren

00:22:48.620 --> 00:22:52.180
und die dann halt in einem Conda-Environment verwenden.

00:22:52.180 --> 00:22:53.900
Und muss halt...

00:22:53.900 --> 00:22:55.040
Also das ist auch so ein Problem,

00:22:55.040 --> 00:22:57.420
wenn man jetzt auf größeren Servern unterwegs ist,

00:22:57.420 --> 00:22:59.720
die halt unter Umständen irgendwie

00:22:59.720 --> 00:23:02.880
so eine antike Debian-Version irgendwie haben

00:23:02.880 --> 00:23:03.820
und eine uralte Libc

00:23:03.820 --> 00:23:05.720
und die funktioniert dann mit neueren,

00:23:05.720 --> 00:23:09.060
anderen Bibliotheken nicht mehr gut.

00:23:09.060 --> 00:23:11.700
Dann hatte ich auch schon den Fall,

00:23:11.700 --> 00:23:13.920
dass ich dann per Conda irgendwie eine neue Libc

00:23:13.920 --> 00:23:15.300
in meinem Environment installiert habe,

00:23:15.300 --> 00:23:16.320
um überhaupt irgendwie

00:23:16.320 --> 00:23:18.480
bestimmte Sachen benutzen zu können.

00:23:18.480 --> 00:23:19.520
Und das geht halt mit Conda

00:23:19.520 --> 00:23:21.640
und mit Pip wäre man da halt relativ aufgeschmissen.

00:23:21.640 --> 00:23:23.640
Daher, ja,

00:23:23.640 --> 00:23:27.820
für so wirkliche Data-Science-Projekte

00:23:27.820 --> 00:23:29.780
ist das halt schon irgendwie deutlich netter.

00:23:29.780 --> 00:23:31.000
Es ist ein bisschen schade,

00:23:31.000 --> 00:23:33.460
dass jetzt man halt zwei Repositories von Paketen hat

00:23:33.460 --> 00:23:36.280
und ja, manchmal ist es halt auch so ein bisschen kompliziert,

00:23:36.280 --> 00:23:36.940
dann sich zu überlegen,

00:23:36.940 --> 00:23:38.360
was man gerade machen will.

00:23:38.360 --> 00:23:40.800
Aber ich würde die als Faustregel einfach nehmen.

00:23:40.800 --> 00:23:42.380
Wenn es ein reines Data-Science-Projekt ist,

00:23:42.380 --> 00:23:43.960
ja, dann Conda.

00:23:43.960 --> 00:23:45.540
Und wenn es irgendwie eine Web-Geschichte ist

00:23:45.540 --> 00:23:46.300
oder was ganz anderes,

00:23:46.300 --> 00:23:46.760
dann ist es eher Pip.

00:23:46.760 --> 00:23:49.740
Ist das denn immer genauso aktuell in Conda

00:23:49.740 --> 00:23:50.300
wie auf PyPy?

00:23:50.300 --> 00:23:52.880
Nee, Conda ist nicht so aktuell.

00:23:52.880 --> 00:23:54.980
Es gibt ja noch Conda Forge,

00:23:54.980 --> 00:23:56.300
also sozusagen ein...

00:23:56.300 --> 00:23:58.620
Da kann man sich selber Sachen bauen.

00:23:58.620 --> 00:24:00.120
Ja, das kann man sowieso,

00:24:00.120 --> 00:24:03.020
aber es gibt halt einmal die Pakete,

00:24:03.020 --> 00:24:06.040
die sozusagen von der Firma gebaut werden

00:24:06.040 --> 00:24:07.660
und ein Repository von Paketen.

00:24:07.660 --> 00:24:10.100
Das ist halt eine Distribution,

00:24:10.100 --> 00:24:12.520
die halt sozusagen redaktionell

00:24:12.520 --> 00:24:15.440
von Continuum Analytics gepflegt wird.

00:24:15.440 --> 00:24:16.280
Und es gibt halt auch

00:24:16.280 --> 00:24:19.220
ein Community-basiertes Repository,

00:24:19.220 --> 00:24:20.220
das nennt sich dann Conda Forge.

00:24:20.220 --> 00:24:23.660
Und man kann das halt in dem...

00:24:23.660 --> 00:24:25.000
Man hat immer so ein Konfigurations-File

00:24:25.000 --> 00:24:29.040
und da kann man halt die Channels sozusagen,

00:24:29.040 --> 00:24:30.860
aus denen man Pakete bekommt,

00:24:30.860 --> 00:24:31.660
halt eintragen.

00:24:31.660 --> 00:24:33.840
Und ja, die meisten verwenden Conda Forge.

00:24:33.840 --> 00:24:35.420
Ist es jetzt auch irgendwie so,

00:24:35.420 --> 00:24:37.860
dass, glaube ich,

00:24:37.860 --> 00:24:42.460
Anaconda selber irgendwie

00:24:42.460 --> 00:24:43.700
auf Conda Forge umgestellt hat?

00:24:43.700 --> 00:24:44.120
Ja, genau.

00:24:44.120 --> 00:24:45.120
Die haben sich das umgestellt.

00:24:45.120 --> 00:24:46.260
Das haben wir gehört.

00:24:46.260 --> 00:24:47.440
Das gehört auf dem Parkcamp jetzt, ja.

00:24:47.440 --> 00:24:48.140
Ja, richtig.

00:24:48.140 --> 00:24:50.760
Das hatte ich auch gar nicht klar, aber ja.

00:24:50.760 --> 00:24:52.740
Das fand ich manchmal auch echt so ein bisschen nervig.

00:24:52.740 --> 00:24:54.080
Wenn man ein Paket installieren wollte,

00:24:54.080 --> 00:24:55.420
habe ich dann doch meistens mal gegoogelt,

00:24:55.420 --> 00:24:58.120
was ist denn jetzt hier das richtige Repo dafür

00:24:58.120 --> 00:25:00.740
und das ist jetzt aber seitdem quasi weg.

00:25:00.740 --> 00:25:02.900
Ja, ist tatsächlich anstrengend,

00:25:02.900 --> 00:25:03.940
wenn man halt schon unterschiedliche Pakete

00:25:03.940 --> 00:25:05.640
hinterhat und dann auch seine eigene Source dafür

00:25:05.640 --> 00:25:06.620
irgendwie letztendlich bestimmen muss.

00:25:06.620 --> 00:25:10.020
Ich kann mich da an ein oder andere Experimente erinnern

00:25:10.020 --> 00:25:11.360
mit so Paketsachen und Sources.

00:25:11.360 --> 00:25:12.440
Alles nicht einfach.

00:25:12.440 --> 00:25:14.620
Aber hatten wir das schon erwähnt,

00:25:14.620 --> 00:25:15.720
warum man das überhaupt machen sollte?

00:25:15.720 --> 00:25:16.240
Ja, das...

00:25:16.240 --> 00:25:16.860
Das Problem ist eben,

00:25:16.860 --> 00:25:18.900
dass die Pakete in der Distribution

00:25:18.900 --> 00:25:21.080
halt nicht wirklich aktuell sind meistens.

00:25:21.080 --> 00:25:24.020
Also, wie sagte Barry Varsaw, glaube ich,

00:25:24.020 --> 00:25:26.800
einer Python-Core-Entwickler,

00:25:26.800 --> 00:25:27.600
sagt er mal,

00:25:27.600 --> 00:25:28.880
the first rule of Python ist,

00:25:28.880 --> 00:25:30.560
you don't use system Python.

00:25:30.560 --> 00:25:33.760
Das ist halt einfach üblicherweise veraltet

00:25:33.760 --> 00:25:35.440
bei vielen Distributionen,

00:25:35.440 --> 00:25:36.220
weil sie halt auch das,

00:25:36.220 --> 00:25:37.920
weil sie Python halt auch für so

00:25:37.920 --> 00:25:39.600
distributionsinterne Zwecke benutzen,

00:25:39.600 --> 00:25:42.580
mit halt Python 2 irgendwie noch als Default-Interpreter,

00:25:42.580 --> 00:25:43.160
bei Mac auch.

00:25:43.160 --> 00:25:45.480
Es gibt einen Counter für Python 2 mittlerweile.

00:25:45.480 --> 00:25:46.040
Hatten wir den gesehen?

00:25:46.220 --> 00:25:46.940
Desk Clock, ja.

00:25:46.940 --> 00:25:48.780
Ich bin mal gespannt,

00:25:48.780 --> 00:25:50.600
wenn die Vertriebssysteme es dann auch mal sich trauen.

00:25:50.600 --> 00:25:52.800
Das war schon ein bisschen heiter so langsam, aber...

00:25:52.800 --> 00:25:54.080
Ja, die haben halt alle Angst davor,

00:25:54.080 --> 00:25:56.500
dass irgendwie, wenn sie das ändern,

00:25:56.500 --> 00:25:58.000
irgendwie ihre Installationsroutinen

00:25:58.000 --> 00:25:58.680
nicht mehr funktionieren,

00:25:58.680 --> 00:25:59.660
weil die halt Python brauchen

00:25:59.660 --> 00:26:01.540
und vielleicht noch nicht umgestellt sind.

00:26:01.540 --> 00:26:02.500
Und die sind halt alle uralt.

00:26:02.500 --> 00:26:03.720
Ja, doof.

00:26:03.720 --> 00:26:06.920
Und daher muss man sowieso eigentlich

00:26:06.920 --> 00:26:08.800
immer einen anderen Python-Interpreter verwenden,

00:26:08.800 --> 00:26:10.320
als der, der vorinstalliert ist.

00:26:10.320 --> 00:26:12.360
Und dann ist es halt so,

00:26:12.360 --> 00:26:14.120
wenn man unterschiedliche Projekte hat,

00:26:14.120 --> 00:26:15.320
dann haben die halt unterschiedliche

00:26:15.320 --> 00:26:16.200
abhängige Projekte,

00:26:16.200 --> 00:26:18.280
was bestimmte Bibliotheken angeht.

00:26:18.280 --> 00:26:20.640
Und die widersprechen sich halt.

00:26:20.640 --> 00:26:21.860
Und das kriegt man halt auch,

00:26:21.860 --> 00:26:23.180
wenn man in einem Filesystem ist.

00:26:23.180 --> 00:26:26.000
Und das kriegt man halt nicht irgendwie unter einen Hut.

00:26:26.000 --> 00:26:28.500
Und daher macht man normalerweise pro Projekt

00:26:28.500 --> 00:26:30.680
ein eigenes, sozusagen virtuelles Environment,

00:26:30.680 --> 00:26:32.460
in dem man halt irgendwie

00:26:32.460 --> 00:26:34.080
alle Abhängigkeiten installiert, die man braucht.

00:26:34.080 --> 00:26:35.020
Ist dir schon mal vorgekommen,

00:26:35.020 --> 00:26:36.080
dass du für ein Projekt zwei

00:26:36.080 --> 00:26:37.160
virtuelle Environments brauchst,

00:26:37.160 --> 00:26:38.180
weil da innerhalb des Projektes

00:26:38.180 --> 00:26:39.180
sich unterschiedliche Module bespricht?

00:26:39.180 --> 00:26:40.600
Nee, das geht auch gar nicht.

00:26:40.600 --> 00:26:42.360
Oder, ja, also natürlich doch, stimmt,

00:26:42.360 --> 00:26:43.400
man könnte es theoretisch machen.

00:26:43.400 --> 00:26:45.680
Aber nee, das ist mir jetzt auch noch nicht

00:26:45.680 --> 00:26:46.180
untergebracht.

00:26:46.180 --> 00:26:47.860
Was meinst du denn halt von einem Projekt?

00:26:47.860 --> 00:26:48.760
Ja, also man könnte ja irgendwie sagen,

00:26:48.760 --> 00:26:50.000
dass es zwei Module in einem Projekt gibt,

00:26:50.000 --> 00:26:52.880
die unterschiedliche Versionen brauchen,

00:26:52.880 --> 00:26:53.660
Python-Versionen,

00:26:53.660 --> 00:26:55.280
weil die Module das sonst nicht können

00:26:55.280 --> 00:26:56.740
und die man dann irgendwie pipen muss,

00:26:56.740 --> 00:26:57.520
damit die man da reden kann.

00:26:57.520 --> 00:26:58.940
Und um das dann zu bauen,

00:26:58.940 --> 00:27:00.580
müsste man halt dann zwei Versionen benutzen.

00:27:00.580 --> 00:27:02.380
Nehmen wir zum Beispiel mal an,

00:27:02.380 --> 00:27:04.020
man hätte ein OCR-Projekt

00:27:04.020 --> 00:27:05.420
und man möchte jetzt irgendwie

00:27:05.420 --> 00:27:09.220
ein aktuelles Ding gegen was Älteres

00:27:09.220 --> 00:27:12.260
wie OCR-OPI oder Kraken oder so verwenden.

00:27:12.260 --> 00:27:13.180
Nehmen wir mal an,

00:27:13.180 --> 00:27:14.160
Kraken kann auch Patentreiber.

00:27:14.160 --> 00:27:15.620
Das OCR-OPI kann nur,

00:27:16.160 --> 00:27:17.980
OCR-OPI kann nur Python 2

00:27:17.980 --> 00:27:19.800
und jetzt möchte man halt das Ding aber

00:27:19.800 --> 00:27:20.960
testen gegen was Neues,

00:27:20.960 --> 00:27:22.180
was halt vielleicht nur Python 3 kann

00:27:22.180 --> 00:27:24.300
und dann müsste man zwei Interpreter halt haben

00:27:24.300 --> 00:27:24.980
irgendwie in dem,

00:27:24.980 --> 00:27:29.020
ja, das wäre hässlich.

00:27:29.020 --> 00:27:29.700
Aber ich glaube,

00:27:29.700 --> 00:27:31.040
so kompliziert müssen wir es gar nicht machen.

00:27:31.040 --> 00:27:31.240
Nee.

00:27:31.240 --> 00:27:33.760
Genau, also wenn ihr euch inzwischen

00:27:33.760 --> 00:27:35.140
das Repo ausgeklont habt,

00:27:35.140 --> 00:27:37.220
dann ist jetzt vielleicht der richtige Moment,

00:27:37.220 --> 00:27:39.500
einmal Corner-Inf-Create auszuführen,

00:27:39.500 --> 00:27:41.080
um die Umgebung nicht aufzusetzen.

00:27:41.080 --> 00:27:42.720
Was an der Stelle ja passiert ist,

00:27:42.720 --> 00:27:44.300
er zieht sich von lokal eben

00:27:44.300 --> 00:27:46.140
eine hinterlegte,

00:27:46.140 --> 00:27:47.220
äh, Environment-Datei,

00:27:47.220 --> 00:27:49.420
die die ganzen Pakete

00:27:49.420 --> 00:27:51.240
und die jeweiligen Versionen beinhaltet,

00:27:51.240 --> 00:27:52.940
die man bitte zu installieren hat

00:27:52.940 --> 00:27:56.260
und danach kann man das dann eben aktivieren

00:27:56.260 --> 00:27:57.720
und hat das dann quasi als seinen

00:27:57.720 --> 00:27:59.300
Default-Python-Interpreter gesetzt.

00:27:59.300 --> 00:28:02.020
Also Corner-Inf-Create macht dann genau das,

00:28:02.020 --> 00:28:03.560
dass er einfach ein Environment setzt,

00:28:03.560 --> 00:28:04.720
die heißt dann Great, oder was?

00:28:04.720 --> 00:28:06.220
Nee, das steht in dem, äh,

00:28:06.220 --> 00:28:08.640
in dem File halt auch mit drin.

00:28:08.640 --> 00:28:09.700
Der Name von dem.

00:28:09.700 --> 00:28:12.220
Von dem, ähm, äh,

00:28:12.220 --> 00:28:14.040
von dem Environment, genau.

00:28:14.040 --> 00:28:16.120
Ähm, ähm,

00:28:16.120 --> 00:28:18.440
ähm, warte mal, genau, äh,

00:28:18.440 --> 00:28:20.100
das ist auch einfach ein YAML-File

00:28:20.100 --> 00:28:22.040
und da steht dann eben das erste Name

00:28:22.040 --> 00:28:24.120
und da steht dann DS-Tutorial

00:28:24.120 --> 00:28:25.780
für das neue Tutorial.

00:28:25.780 --> 00:28:27.920
Und dann Dependencies, ach, und dann werden die Pakete danach gepackt.

00:28:27.920 --> 00:28:29.920
Und, ach so, das ist auch so,

00:28:29.920 --> 00:28:32.080
man kann halt auch, äh, genau,

00:28:32.080 --> 00:28:33.680
man kann auch Sachen per PIP installieren.

00:28:33.680 --> 00:28:35.920
Ja, das ist auch sowas, also es ist halt

00:28:35.920 --> 00:28:38.020
irgendwie, äh, ja,

00:28:38.020 --> 00:28:39.760
Conda ist quasi eine echte Obermenge von

00:28:39.760 --> 00:28:42.120
PIP, also man kann halt Conda und halt

00:28:42.120 --> 00:28:44.020
auch PIP, aber umgekehrt geht's halt nicht.

00:28:44.020 --> 00:28:45.700
PIP kann halt nicht Conda Sachen installieren.

00:28:46.120 --> 00:28:48.480
Ähm, ja, und manche Sachen installiere ich

00:28:48.480 --> 00:28:50.200
via PIP, weil das einfach aktuellere

00:28:50.200 --> 00:28:51.560
Versionen dann sind, ähm.

00:28:51.560 --> 00:28:54.480
Ja, oder halt, wenn man was sehr Spezielles

00:28:54.480 --> 00:28:56.120
will, ist es vielleicht auch nicht unbedingt

00:28:56.120 --> 00:28:57.940
immer in jedem Conda-Repository eben drin.

00:28:57.940 --> 00:29:00.260
Ähm, da ist PIP, glaube ich, einfach ein bisschen

00:29:00.260 --> 00:29:02.280
größer. Also ich kann auch einfach die Version angeben,

00:29:02.280 --> 00:29:03.940
wie bei PIP auch, ne, mit gleich oder sowas.

00:29:03.940 --> 00:29:05.640
Genau, genau, das kann ich auch machen, ja.

00:29:05.640 --> 00:29:08.360
Genau, und danach müsst ihr, um das Repo

00:29:08.360 --> 00:29:10.160
quasi so ausführen zu können, nochmal,

00:29:10.160 --> 00:29:12.140
ähm, das lokale Paket

00:29:12.140 --> 00:29:13.860
bauen, und zwar mit Minus E.

00:29:13.860 --> 00:29:16.020
Ja. Ähm, warum wollen wir

00:29:16.020 --> 00:29:18.140
denn erstmal überhaupt ein lokales

00:29:18.140 --> 00:29:20.100
Paket, und warum wollen wir Minus E?

00:29:20.100 --> 00:29:22.220
Mhm, ähm, ja,

00:29:22.220 --> 00:29:24.240
ein lokales Paket, äh, deswegen, weil

00:29:24.240 --> 00:29:26.100
man in vielen Notebooks halt,

00:29:26.100 --> 00:29:27.860
also, ich hab das Ganze quasi ein bisschen

00:29:27.860 --> 00:29:29.960
in unterschiedliche Notebooks aufgeteilt, und da

00:29:29.960 --> 00:29:32.040
gibt's dann halt, ähm, einige, die halt

00:29:32.040 --> 00:29:33.600
immer wieder den gleichen Code enthalten,

00:29:33.600 --> 00:29:35.980
und jetzt könnte man natürlich auch in jedes Notebook

00:29:35.980 --> 00:29:38.020
irgendwie reinkopieren, aber wenn man

00:29:38.020 --> 00:29:39.900
dann gemerkt hat, oh, ich hab hier einen blöden Fehler gemacht,

00:29:39.900 --> 00:29:41.980
dann muss man das halt auch in allen Notebooks wieder ändern, was ja

00:29:41.980 --> 00:29:44.000
ein bisschen umständlich wäre, und

00:29:44.000 --> 00:29:45.920
Code, den man halt, äh, in

00:29:45.920 --> 00:29:47.980
mehreren unterschiedlichen Notebooks, äh,

00:29:47.980 --> 00:29:49.900
benötigt, den, äh, kann man ja aber auch

00:29:49.900 --> 00:29:52.080
einfach in eine Bibliothek, und das ist halt

00:29:52.080 --> 00:29:53.960
im Grunde dieses Paket, äh, was man

00:29:53.960 --> 00:29:56.140
da installiert, ähm, rausziehen,

00:29:56.140 --> 00:29:57.860
und den importiert man dann halt

00:29:57.860 --> 00:29:59.980
einfach nur in allen Notebooks, und wenn man da jetzt

00:29:59.980 --> 00:30:04.060
ein Fehler fixt, dann ist der halt in allen Notebooks gleichzeitig

00:30:04.060 --> 00:30:08.320
gefixt und Minus E installiert man deswegen, um Änderungen,

00:30:08.320 --> 00:30:11.300
wenn man da jetzt eine Änderung macht, die sofort

00:30:11.300 --> 00:30:15.640
sichtbar werden zu lassen. Also ansonsten müsste man ja eigentlich, wenn man

00:30:15.640 --> 00:30:19.940
ein Paket zum Beispiel via PyPI oder so installiert oder normal installiert

00:30:19.940 --> 00:30:23.640
sozusagen, jedes Mal, wenn man was ändert, ein neues Paket bauen

00:30:23.640 --> 00:30:27.720
und dann dieses Paket wieder installieren. Und

00:30:27.720 --> 00:30:31.600
am besten auch nochmal das Notebook neu starten. Und das ist

00:30:31.600 --> 00:30:35.620
natürlich ein bisschen umständlich und wenn man sagt pip install minus

00:30:35.620 --> 00:30:39.480
E, dann macht das sozusagen keine wirkliche

00:30:39.480 --> 00:30:42.440
Paketsinstallation, sondern legt nur einen Link auf das

00:30:42.440 --> 00:30:47.640
entsprechende Verzeichnis sozusagen mit nach Side-Packages und

00:30:47.640 --> 00:30:49.620
wenn sich da irgendwas ändert

00:30:49.620 --> 00:30:55.560
am Code, dann ist das halt sofort irgendwie sichtbar und

00:30:55.560 --> 00:30:57.560
dann kann man noch auf...

00:30:57.720 --> 00:31:01.620
Man kann das auch für alle einstellen oder für einige. Auf Notebook-Seite kann man zum Beispiel

00:31:01.620 --> 00:31:03.520
sagen, A-Import statt Import,

00:31:03.520 --> 00:31:09.660
ein bestimmtes Modul, dann wird halt die Aktualisierung

00:31:09.660 --> 00:31:13.200
auch sofort wirksam, ohne dass man das Notebook neu starten muss, was ja auch praktisch ist.

00:31:13.200 --> 00:31:17.520
Man kann das ja fein und granular einstellen. Man will das

00:31:17.520 --> 00:31:21.380
vielleicht auch nicht für alle Module machen, aber wenn man das richtig

00:31:21.380 --> 00:31:25.340
eingestellt hat, kann man halt, wenn man jetzt

00:31:25.340 --> 00:31:27.600
beispielsweise bei einem Code-Teil, der halt

00:31:27.600 --> 00:31:29.280
in vielen Notebooks verwendet wird, einen Teil ändert,

00:31:29.280 --> 00:31:31.780
dann ist die Änderung sofort da und

00:31:31.780 --> 00:31:33.580
bei der nächsten Ausführung

00:31:33.580 --> 00:31:35.640
einer Zelle hat man halt auch

00:31:35.640 --> 00:31:37.340
schon den geänderten Code mit ausgeführt

00:31:37.340 --> 00:31:39.640
und muss da nichts neu installieren,

00:31:39.640 --> 00:31:41.140
neu starten oder so.

00:31:41.140 --> 00:31:43.220
Da kann ich auch jeden nur zu ermutigen,

00:31:43.220 --> 00:31:45.560
zu gehen. Also ich habe mich da am Anfang lange vorgescheut

00:31:45.560 --> 00:31:47.480
und habe einfach quasi am Anfang

00:31:47.480 --> 00:31:49.320
von meinem Notebook einfach immer mit der

00:31:49.320 --> 00:31:51.440
Run-Magic quasi in ein anderes

00:31:51.440 --> 00:31:53.220
Notebook gestartet, wo ich alle diese Sachen

00:31:53.220 --> 00:31:54.940
initialisiert habe. Das geht auch,

00:31:54.940 --> 00:31:57.480
aber das muss man halt dann doch, wenn man in einem anderen Notebook

00:31:57.480 --> 00:31:59.220
was ändert, immer noch einmal ausführen

00:31:59.220 --> 00:32:01.500
und so viel Zauber

00:32:01.500 --> 00:32:03.520
ist es gar nicht, quasi sich selber so ein Paket

00:32:03.520 --> 00:32:05.320
zu erstellen. Vor allem ist es auch ein ganz cooles Gefühl.

00:32:05.320 --> 00:32:07.180
Man kann es danach auch wirklich direkt mal weitergeben

00:32:07.180 --> 00:32:09.320
und weiterleiten und es verleitet

00:32:09.320 --> 00:32:11.180
zu ein bisschen besserer

00:32:11.180 --> 00:32:13.420
Art Software-Code dann auch zu schreiben

00:32:13.420 --> 00:32:15.120
an der Stelle. Man kann dann eine ordentliche

00:32:15.120 --> 00:32:17.080
IDI dafür vielleicht auch benutzen und

00:32:17.080 --> 00:32:19.440
entwickelt dann diese ausgelagerte

00:32:19.440 --> 00:32:21.260
Funktionalität vielleicht nicht direkt im Notebook.

00:32:21.260 --> 00:32:22.460
Welche IDI benutzt du?

00:32:22.460 --> 00:32:25.740
PyCharm, halt ganz klassisch, wie die meisten glaube ich.

00:32:25.740 --> 00:32:27.460
Und wir sind beides umgekehrt für die Studie,

00:32:27.480 --> 00:32:28.460
Code? Ah ja, okay.

00:32:28.460 --> 00:32:31.480
Ich benutze immer noch alles. Also ich benutze auch immer noch

00:32:31.480 --> 00:32:33.060
vor allen Dingen häufig

00:32:33.060 --> 00:32:35.460
Wim. Ich benutze auch

00:32:35.460 --> 00:32:36.520
PyCharm und auch VSCode.

00:32:36.520 --> 00:32:38.860
Ich hatte das mir auch schon gezeigt.

00:32:38.860 --> 00:32:41.340
Das ist schon ziemlich gut, muss man sagen.

00:32:41.340 --> 00:32:43.340
Genau. Ich meine, am Anfang ist so ein bisschen overhead

00:32:43.340 --> 00:32:45.400
mit dem Anlegen von so einer Klasse da, aber

00:32:45.400 --> 00:32:47.480
ihr benutzt, glaube ich, so Cookie-Cutter-Templates.

00:32:47.480 --> 00:32:48.800
Ja.

00:32:48.800 --> 00:32:51.200
Ich benutze PyScaffold,

00:32:51.200 --> 00:32:53.520
was ein Projekt ist, was von einem Kollegen von mir

00:32:53.520 --> 00:32:55.500
entwickelt wird, was mir da sehr geholfen hat.

00:32:55.500 --> 00:32:57.360
Einfach am Anfang quasi so

00:32:57.360 --> 00:32:59.440
Scaffolding, mir

00:32:59.440 --> 00:33:01.420
mein Gerüst einmal aufzusetzen. Da kenne ich mich

00:33:01.420 --> 00:33:03.120
dann direkt dran aus und dann trinke ich da noch meine

00:33:03.120 --> 00:33:05.340
zwei, drei Zeilen ein und bin

00:33:05.340 --> 00:33:07.440
gleich da. Und das hat mir

00:33:07.440 --> 00:33:09.420
so ein bisschen die Angst davor genommen, eigene Pakete

00:33:09.420 --> 00:33:10.280
an der Stelle zu schreiben.

00:33:10.280 --> 00:33:11.400
Ja.

00:33:11.400 --> 00:33:14.880
Genau. Gut. Und

00:33:14.880 --> 00:33:17.100
dann können wir letztendlich wirklich

00:33:17.100 --> 00:33:18.200
unser Notebook starten.

00:33:18.200 --> 00:33:20.780
Du benutzt noch Jupyter

00:33:20.780 --> 00:33:23.020
Notebox. Ja, stimmt.

00:33:23.020 --> 00:33:24.260
Magst du JupyterLab lieber?

00:33:24.260 --> 00:33:26.360
Oder warum magst du kein JupyterLab?

00:33:26.360 --> 00:33:27.140
Doch.

00:33:27.240 --> 00:33:28.340
Ja, stimmt. Mag ich auch.

00:33:28.340 --> 00:33:30.840
Das ist jetzt auch nur so reine Gewohnheit eigentlich.

00:33:30.840 --> 00:33:32.880
Aber ja, eigentlich im Grunde

00:33:32.880 --> 00:33:35.060
müsste ich auch mal auf JupyterLab umsteigen.

00:33:35.060 --> 00:33:36.240
Ja.

00:33:36.240 --> 00:33:38.780
Genau. Also gerade die neuen Versionen mit den Plugins,

00:33:38.780 --> 00:33:41.040
finde ich, es kommt... Also am Anfang haben wir

00:33:41.040 --> 00:33:42.940
noch ein paar Funktionalitäten von JupyterNotebooks

00:33:42.940 --> 00:33:45.160
gefehlt, aber jetzt gerade

00:33:45.160 --> 00:33:46.720
mit dem sich ausbreitenden

00:33:46.720 --> 00:33:49.080
Plugin-System gibt es da echt coole Sachen.

00:33:49.080 --> 00:33:51.020
Zum Beispiel, was ich total liebe gerade,

00:33:51.020 --> 00:33:52.940
ist halt die Sublime Keybinding

00:33:52.940 --> 00:33:54.920
Magic-Funktionalität, die man jetzt einfach sich

00:33:54.920 --> 00:33:57.120
so in die JupyterLab-Notebook

00:33:57.120 --> 00:33:58.060
reinladen kann.

00:33:58.060 --> 00:34:00.880
Und so. Aber genau.

00:34:00.880 --> 00:34:02.760
Ja, ja, ja.

00:34:02.760 --> 00:34:05.000
Das habe ich auch schon lange vor.

00:34:05.000 --> 00:34:06.900
Ich habe es halt bisher nur immer ausprobiert, aber noch nicht

00:34:06.900 --> 00:34:07.680
wirklich verwendet.

00:34:07.680 --> 00:34:10.860
Und genau. Ja, nee. Sieht sehr, sehr gut aus.

00:34:10.860 --> 00:34:13.280
JupyterLab ist...

00:34:13.280 --> 00:34:14.220
Genau.

00:34:14.220 --> 00:34:16.780
So. Egal, ob ihr jetzt ein

00:34:16.780 --> 00:34:19.120
JupyterNotebook oder ein ehemaliger...

00:34:19.120 --> 00:34:21.380
Ja. Egal, ob ihr jetzt ein JupyterNotebook

00:34:21.380 --> 00:34:23.180
oder halt schon JupyterLab gestartet habt,

00:34:23.180 --> 00:34:24.940
müsstet ihr jetzt quasi

00:34:24.940 --> 00:34:27.000
eine Reihe an

00:34:27.000 --> 00:34:28.640
Ordnern sehen und

00:34:28.640 --> 00:34:30.700
im DS-Tutorial...

00:34:30.700 --> 00:34:31.420
Nee, im

00:34:31.420 --> 00:34:34.900
Ordner Notebooks gibt es halt eben

00:34:34.900 --> 00:34:36.700
das Projekt TestTextClassification

00:34:36.700 --> 00:34:38.340
und dem wollen wir uns mal ein bisschen widmen.

00:34:38.340 --> 00:34:40.400
Genau. Ja.

00:34:40.400 --> 00:34:42.640
Vielleicht kann man einfach direkt mal das

00:34:42.640 --> 00:34:44.700
ExploreData-Notebook aufmachen.

00:34:44.700 --> 00:34:46.400
Das ist

00:34:46.400 --> 00:34:48.680
das Dataset, also

00:34:48.680 --> 00:34:50.780
ist man natürlich auch mal ein bisschen darauf angewiesen, dass es

00:34:50.780 --> 00:34:52.780
halt ein frei verfügbares

00:34:52.780 --> 00:34:55.100
Dataset gibt, das ich

00:34:55.100 --> 00:34:55.960
da verwendet habe, ist

00:34:55.960 --> 00:34:56.880
das

00:34:56.880 --> 00:34:57.660
Reuters

00:34:57.660 --> 00:35:00.800
21578

00:35:00.800 --> 00:35:03.620
Textklassifikations-Dataset.

00:35:03.620 --> 00:35:04.860
Das ist so ein klassisches Ding,

00:35:04.860 --> 00:35:07.680
wo

00:35:07.680 --> 00:35:09.120
irgendwie eben entsprechend viele

00:35:09.120 --> 00:35:10.460
21578

00:35:10.460 --> 00:35:14.020
so Ticker-Meldungen

00:35:14.020 --> 00:35:14.480
drin sind.

00:35:14.480 --> 00:35:17.620
Und die sind halt klassifiziert

00:35:17.620 --> 00:35:18.060
in

00:35:18.060 --> 00:35:20.880
unterschiedliche Kategorien.

00:35:20.880 --> 00:35:23.440
Und bei dem Set geht es auch

00:35:23.440 --> 00:35:25.400
im Grunde darum, Modelle zu

00:35:25.400 --> 00:35:26.760
bauen oder das benutzt man

00:35:26.760 --> 00:35:28.100
eigentlich mal als Trainingsdatum

00:35:28.100 --> 00:35:29.540
für

00:35:29.540 --> 00:35:32.820
Textklassifikationsmodelle,

00:35:32.820 --> 00:35:34.520
weil man halt dann damit

00:35:34.520 --> 00:35:35.280
vorhersagen kann,

00:35:35.280 --> 00:35:38.360
wenn man jetzt eine neue Ticker-Meldung reinbekommt,

00:35:38.360 --> 00:35:40.520
welche Kategorie ist denn das? Also es ist im Grunde so ähnlich wie

00:35:40.520 --> 00:35:43.220
das Spam-Klassifikationsbeispiel

00:35:43.220 --> 00:35:44.660
von eben, nur dass

00:35:44.660 --> 00:35:46.720
man halt nicht nur zwischen Spam und Nicht-Spam

00:35:46.720 --> 00:35:48.540
unterscheiden können will, sondern

00:35:48.540 --> 00:35:50.300
halt zwischen allen Kategorien, in denen

00:35:50.300 --> 00:35:52.880
so eine Ticker-Meldung

00:35:52.880 --> 00:35:54.620
liegen kann, beziehungsweise auch noch

00:35:54.620 --> 00:35:56.280
ein Unterschied ist, es ist nicht

00:35:56.280 --> 00:35:58.440
nicht, man würde, das wäre jetzt Multiklass,

00:35:58.440 --> 00:35:59.740
wenn es nur eine gäbe,

00:35:59.740 --> 00:36:02.360
aber das ist eigentlich ein Multilabel-Dataset,

00:36:02.360 --> 00:36:03.980
das heißt, man möchte alle

00:36:03.980 --> 00:36:08.220
Kategorien, in denen so eine Ticker-Meldung

00:36:08.220 --> 00:36:08.580
drin liegt,

00:36:08.580 --> 00:36:10.300
rausfinden. Also vielleicht

00:36:10.300 --> 00:36:11.940
halt auch, es gibt welche, die halt,

00:36:11.940 --> 00:36:14.460
wo es nicht nur um Politik geht

00:36:14.460 --> 00:36:16.300
oder Sport, sondern auch Sport und Politik

00:36:16.300 --> 00:36:16.720
oder sowas.

00:36:16.720 --> 00:36:20.400
Genau. Das Erste, was man

00:36:20.400 --> 00:36:22.300
finde ich bei so einem Datascience-Projekt, der am Anfang immer

00:36:22.300 --> 00:36:24.260
machen muss, vor lauter Tools

00:36:24.260 --> 00:36:25.720
und Frameworks und sonst was,

00:36:26.160 --> 00:36:28.080
das Wichtigste sind immer noch die Daten. Und wenn die Daten

00:36:28.080 --> 00:36:30.120
nicht passen, dann hilft es nicht. Und da muss man

00:36:30.120 --> 00:36:32.160
sich halt echt erstmal reinknien und richtig verstehen,

00:36:32.160 --> 00:36:33.420
was haben wir denn da überhaupt alles.

00:36:33.420 --> 00:36:36.080
Und ich weiß nicht,

00:36:36.080 --> 00:36:38.140
da gibt es so ein paar Befehle, die ich immer als erstes so

00:36:38.140 --> 00:36:40.100
benutze. Also ich lade mir mein

00:36:40.100 --> 00:36:42.080
Dataset irgendwie in Pandas

00:36:42.080 --> 00:36:44.320
DataFrame rein und

00:36:44.320 --> 00:36:45.760
dann

00:36:45.760 --> 00:36:48.140
nutze ich darauf erstmal meist ein Head,

00:36:48.140 --> 00:36:50.000
um einfach mal zu gucken, was habe ich überhaupt drin.

00:36:50.000 --> 00:36:52.280
Dann ein D-Types,

00:36:52.280 --> 00:36:53.860
um mir anzugucken, okay,

00:36:53.860 --> 00:36:56.140
welche Spalten haben denn hier welchen Typ,

00:36:56.160 --> 00:36:58.080
und danach mache ich dann

00:36:58.080 --> 00:37:00.140
eben ein Describe, was mir dann

00:37:00.140 --> 00:37:02.120
für alle numerischen

00:37:02.120 --> 00:37:04.120
Spalten

00:37:04.120 --> 00:37:05.920
da drin schon mal so ein bisschen eine erste

00:37:05.920 --> 00:37:08.080
Übersichtsstatistik gibt. Also irgendwie

00:37:08.080 --> 00:37:10.020
wie viele Einträge habe ich, was ist

00:37:10.020 --> 00:37:12.020
der Mittelwert, was sind quasi

00:37:12.020 --> 00:37:13.620
die Maximalwerte und so weiter.

00:37:13.620 --> 00:37:15.820
Machst du das ähnlich oder wie geht es dir?

00:37:15.820 --> 00:37:17.240
Ja, ja, doch, durchaus. Also

00:37:17.240 --> 00:37:19.820
ich habe das jetzt auch hier gerade nochmal ausgeführt.

00:37:19.820 --> 00:37:21.940
Genau.

00:37:21.940 --> 00:37:23.700
Ja, also

00:37:23.700 --> 00:37:25.240
wenn man jetzt zum Beispiel

00:37:25.240 --> 00:37:25.800
ähm,

00:37:26.040 --> 00:37:28.040
einige der ersten

00:37:28.040 --> 00:37:30.120
Zeilen ausgeführt hat, dann hat man hier auch eben ein DataFrame,

00:37:30.120 --> 00:37:30.760
in dem all die

00:37:30.760 --> 00:37:33.940
Dokumente halt drin sind und wenn man

00:37:33.940 --> 00:37:35.260
DFHat macht, dann sieht man halt

00:37:35.260 --> 00:37:38.040
eine Spalte ModUp, das ist halt sozusagen

00:37:38.040 --> 00:37:39.880
so der klassische Split in Trainings- und

00:37:39.880 --> 00:37:42.100
Testdaten. Das ist halt auch ganz praktisch

00:37:42.100 --> 00:37:44.060
bei dem Dataset, dass man das nicht selber machen muss,

00:37:44.060 --> 00:37:45.920
weil das ist halt auch nur, eigentlich müsste man dann irgendwie erklären,

00:37:45.920 --> 00:37:47.880
was Cross-Validation ist und wie man K-Fault

00:37:47.880 --> 00:37:50.020
Cross-Validation, hier ist

00:37:50.020 --> 00:37:51.720
das schon fertig, da muss man sich dann keine Gedanken mehr

00:37:51.720 --> 00:37:53.800
drum machen sozusagen, das ist vielleicht

00:37:53.800 --> 00:37:55.540
ganz gut. Dann

00:37:55.540 --> 00:37:55.920
äh,

00:37:55.920 --> 00:37:57.760
gibt es eine Spalte mit den Kategorien drin, das ist dann

00:37:57.760 --> 00:37:58.800
einfach nur eine Liste der

00:37:58.800 --> 00:38:01.800
äh, Kategorien, in denen

00:38:01.800 --> 00:38:03.820
halt diese Meldung halt drin ist

00:38:03.820 --> 00:38:05.880
und, ähm, genau

00:38:05.880 --> 00:38:07.700
das Ganze nochmal, äh, sozusagen

00:38:07.700 --> 00:38:09.880
nicht als Textkategorie, sondern

00:38:09.880 --> 00:38:11.740
eben, äh, numerisches Label,

00:38:11.740 --> 00:38:13.760
weil, äh, wenn man später

00:38:13.760 --> 00:38:15.820
das an irgendwelche Modelle verfüttert, dann brauchen

00:38:15.820 --> 00:38:18.200
die das halt als, äh,

00:38:18.200 --> 00:38:19.180
ja, als Tal

00:38:19.180 --> 00:38:21.680
und am besten auch als Talen, die halt

00:38:21.680 --> 00:38:23.820
keine Lücken haben, sonst geht das halt

00:38:23.820 --> 00:38:25.640
nicht gut, weil man das halt, äh,

00:38:25.800 --> 00:38:27.560
one-hot-encoded immer, das

00:38:27.560 --> 00:38:29.800
sozusagen hinterher kriegt halt jede Spalte, äh,

00:38:29.800 --> 00:38:31.340
jedes Label eine eigene Spalte

00:38:31.340 --> 00:38:33.600
und das geht eigentlich natürlich nur dann gut, wenn das halt irgendwie

00:38:33.600 --> 00:38:35.540
keine Lücken hat. Ähm,

00:38:35.540 --> 00:38:37.900
ja, dann gibt es da irgendwie noch ein Datum, was da dran

00:38:37.900 --> 00:38:39.280
ist, äh, irgendwie ein Titel,

00:38:39.280 --> 00:38:41.880
äh, irgendeine komische Dateline, ich weiß jetzt gar nicht mehr genau,

00:38:41.880 --> 00:38:43.320
was das ist, und ein Body von dem

00:38:43.320 --> 00:38:45.820
Artikel, äh, dann noch

00:38:45.820 --> 00:38:47.760
eine ID und ich glaube, das

00:38:47.760 --> 00:38:49.660
habe ich irgendwie mal dran gebastelt, einfach nur, um,

00:38:49.660 --> 00:38:51.840
äh, weil, weil, äh,

00:38:51.840 --> 00:38:53.600
die Idee war halt, dass, ähm,

00:38:53.600 --> 00:38:55.540
in dieser, in dieser Machine Learning,

00:38:55.680 --> 00:38:57.720
äh, Schulung, äh, man

00:38:57.720 --> 00:38:59.660
ja,

00:38:59.660 --> 00:39:01.680
äh, als Übung sozusagen vielleicht ein paar neue

00:39:01.680 --> 00:39:03.700
Features dazu tun sollte, um zu gucken, ob

00:39:03.700 --> 00:39:05.660
das irgendwie die, äh, mit,

00:39:05.660 --> 00:39:07.600
äh, ob das den Score irgendwie verbessert, der Modelle

00:39:07.600 --> 00:39:09.780
und da war halt so ein erstes Beispiel,

00:39:09.780 --> 00:39:11.980
man könnte einfach mal den Wochentag reinschreiben,

00:39:11.980 --> 00:39:13.480
der, äh, an dem das irgendwie

00:39:13.480 --> 00:39:15.720
erschienen ist und vielleicht schickt er ja irgendwelche

00:39:15.720 --> 00:39:16.380
Informationen drin.

00:39:16.380 --> 00:39:19.520
Ja, genau, äh, DF-Info.

00:39:19.520 --> 00:39:21.760
Wenn ihr irgendwie wissen wollt, wie man mit

00:39:21.760 --> 00:39:23.720
diesen Data-Frame-Operationen noch ein bisschen

00:39:23.720 --> 00:39:25.340
besser einen Einstieg findet, da gibt es ein ganz spannendes,

00:39:25.560 --> 00:39:27.240
äh, Buch von Jake Vanderplast zu,

00:39:27.240 --> 00:39:29.440
Data Science mit Python. Das hat er

00:39:29.440 --> 00:39:31.520
auch, äh, frei auf seinem GitHub-Account

00:39:31.520 --> 00:39:32.720
veröffentlicht und auf einer Webseite.

00:39:32.720 --> 00:39:35.220
Ähm, findet ihr irgendwie, da kann man auch mit

00:39:35.220 --> 00:39:37.200
Dupedia-Notebooks das tatsächlich auch mal live noch an anderen

00:39:37.200 --> 00:39:39.540
Datensätzen üben? Also gerade für Pandas-

00:39:39.540 --> 00:39:40.760
Einführung ist da nochmal ein großes Kapitel.

00:39:40.760 --> 00:39:43.680
Ja, äh, also die, die Pandas-Dokumentation

00:39:43.680 --> 00:39:45.300
ist auch, auch ziemlich gut. Die ist halt nur etwas

00:39:45.300 --> 00:39:47.440
länglich und trocken, aber ansonsten ist sie auch super, äh,

00:39:47.440 --> 00:39:49.480
zu empfehlen. Äh, und,

00:39:49.480 --> 00:39:51.460
äh, ja, äh, ich finde die, die,

00:39:51.460 --> 00:39:53.520
die modernen Pandas, äh,

00:39:53.520 --> 00:39:55.520
Blog-Artikel-Serie von Tom Augsburger auch super.

00:39:55.520 --> 00:39:57.800
Ja, ja, äh.

00:39:57.800 --> 00:39:59.400
Was ich ansonsten immer noch ganz gerne mache,

00:39:59.400 --> 00:40:01.260
wenn ich am Anfang so ein Dataset habe, es gibt

00:40:01.260 --> 00:40:03.320
eine Library, die nennt sich Pandas Profiling.

00:40:03.320 --> 00:40:04.820
Mhm. Ähm, die,

00:40:04.820 --> 00:40:07.320
da wirfst du einfach so ein DataFrame rein

00:40:07.320 --> 00:40:09.320
und die generiert dir daraus so einen kleinen

00:40:09.320 --> 00:40:10.740
HTML-Report,

00:40:10.740 --> 00:40:13.140
worin man dann quasi so ein paar

00:40:13.140 --> 00:40:15.240
Summary-Statistiken nochmal ein bisschen hübscher aufbereitet

00:40:15.240 --> 00:40:16.960
bekommt, also irgendwie. Das sieht ja auch super aus, ja.

00:40:16.960 --> 00:40:19.000
Welche, äh, wie viele, wie viele Teilen hast du,

00:40:19.000 --> 00:40:21.260
wie viele Spalten natürlich, aber dann schaut die halt eben

00:40:21.260 --> 00:40:23.200
auch quasi, wie viel Prozent der Daten sind jetzt

00:40:23.200 --> 00:40:25.160
halt irgendwie fehlen, sind Nullwerte,

00:40:25.480 --> 00:40:27.540
ähm, du kriegst, ähm,

00:40:27.540 --> 00:40:29.380
eine Übersicht quasi, welche Typen

00:40:29.380 --> 00:40:31.380
haben, hat das Ganze und der sucht auch quasi nach

00:40:31.380 --> 00:40:33.320
Korrelationen in den Daten, also wenn du jetzt halt

00:40:33.320 --> 00:40:35.380
zwei Spalten hast, wo du eben zum Beispiel schon

00:40:35.380 --> 00:40:37.460
so ein Feature-Engineering gemacht hast und hast

00:40:37.460 --> 00:40:39.300
keine Ahnung, ähm,

00:40:39.300 --> 00:40:41.460
den, den Tag und dann nochmal irgendwie

00:40:41.460 --> 00:40:43.680
den Tag um ein Jahr verschoben

00:40:43.680 --> 00:40:45.540
oder so, dann korrelieren diese beiden Spalten

00:40:45.540 --> 00:40:47.500
ja komplett, sowas würdest du dann da drin direkt

00:40:47.500 --> 00:40:49.800
sehen und dann würde dich zum Beispiel vorwarnen,

00:40:49.800 --> 00:40:51.720
ähm. Ja, das ist ganz praktisch,

00:40:51.720 --> 00:40:53.300
ne, wenn ich cleanen muss, dann irgendwie erstmal so

00:40:53.300 --> 00:40:55.240
zu gucken, ah ja, das könnte ja ein Problem sein, dann

00:40:55.440 --> 00:40:56.580
fangen wir doch mal an da oder so.

00:40:56.580 --> 00:40:59.220
Genau. Geht jetzt immer die Zeile oder sowas, so, ne.

00:40:59.220 --> 00:41:01.240
Genau, das ist immer irgendwie, finde ich, ganz praktisch, um,

00:41:01.240 --> 00:41:03.560
ja, so einen ersten Übersicht zu bekommen.

00:41:03.560 --> 00:41:05.400
Ähm, was würdet ihr dann machen?

00:41:05.400 --> 00:41:07.340
Würdet ihr denn die Daten, die dann da zum Beispiel fehlen,

00:41:07.340 --> 00:41:09.560
irgendwie versuchen zu füllen oder, ähm,

00:41:09.560 --> 00:41:11.300
lässt man dann einfach erstmal die Spalten

00:41:11.300 --> 00:41:12.900
weg, weil die irgendwie Quatsch sind oder?

00:41:12.900 --> 00:41:15.280
Ja, kommt halt

00:41:15.280 --> 00:41:17.100
komplett drauf an, ne, also. Ja.

00:41:17.100 --> 00:41:19.600
Ähm, also, was du jetzt ansprichst,

00:41:19.600 --> 00:41:21.420
ist ja Ausreißerbereinigung im Wesentlichen

00:41:21.420 --> 00:41:23.580
und, ähm, Nullwerte füllen,

00:41:23.580 --> 00:41:25.240
ähm,

00:41:25.400 --> 00:41:27.360
die, die Frage ist, warum fehlen die Werte und

00:41:27.360 --> 00:41:29.240
kannst du sie sinnvoll ersetzen? Also,

00:41:29.240 --> 00:41:31.380
im Endeffekt hat man drei

00:41:31.380 --> 00:41:33.540
Optionen. Man wirft die Daten einfach weg,

00:41:33.540 --> 00:41:35.520
ähm, man versucht

00:41:35.520 --> 00:41:37.080
sie zu füllen mit einem

00:41:37.080 --> 00:41:39.420
Art von statistischem Maß,

00:41:39.420 --> 00:41:41.440
was quasi zum Beispiel den Durchschnitt von

00:41:41.440 --> 00:41:42.920
allen Spalten wiedergibt

00:41:42.920 --> 00:41:44.880
oder, ähm,

00:41:44.880 --> 00:41:47.460
vielleicht habe ich auch nur die beiden Optionen.

00:41:47.460 --> 00:41:48.400
Ich dachte, ich hätte nur eine dritte.

00:41:48.400 --> 00:41:50.020
Ja, man könnte ja irgendwie...

00:41:50.020 --> 00:41:52.280
Es gibt diverse, also man kann auch bei, ähm,

00:41:52.280 --> 00:41:53.840
also es gibt so ein Cyclic Learn zum Beispiel,

00:41:53.840 --> 00:41:55.220
das ist so eine Bibliothek für Maschinen,

00:41:55.360 --> 00:41:57.820
Diverse, unterschiedliche, also da nennen

00:41:57.820 --> 00:41:59.900
es die Oberklasse quasi für all diese Verfahren

00:41:59.900 --> 00:42:02.000
Imputer und man kann halt diverse unterschiedliche

00:42:02.000 --> 00:42:04.040
benutzen, um eine Strategie dafür

00:42:04.040 --> 00:42:06.020
zu haben, weil eben, es kommt halt darauf an,

00:42:06.020 --> 00:42:08.120
wofür man die, äh, was der Grund

00:42:08.120 --> 00:42:10.120
dafür ist, warum das fehlt und wie man das am besten

00:42:10.120 --> 00:42:12.080
ausgleicht, äh, ja,

00:42:12.080 --> 00:42:13.820
die dann, äh, sozusagen da irgendwas

00:42:13.820 --> 00:42:16.280
reinschreiben oder irgendwas mit den Daten machen, ja.

00:42:16.280 --> 00:42:18.040
Ja, die Frage ist halt, ob man

00:42:18.040 --> 00:42:19.820
die rausrechnen kann, die Daten oder nicht, ne, also

00:42:19.820 --> 00:42:21.860
ob das sinnvoll ist und was man halt mit der Spalte sonst macht

00:42:21.860 --> 00:42:23.560
oder mit den Datensätzen, die fehlen oder

00:42:23.560 --> 00:42:25.320
Korrelation, ob man dann Dummy reinrechnet,

00:42:25.320 --> 00:42:27.120
einsetzt, weil man den noch irgendwie braucht und dann immer

00:42:27.120 --> 00:42:29.540
merkt, oh, das ist das bei dem Dummy so und dann...

00:42:29.540 --> 00:42:31.240
Ja, und auch, wie rum droppst du sie, wenn du sie

00:42:31.240 --> 00:42:33.280
droppst? Also, schmeißt du die Zeilen raus

00:42:33.280 --> 00:42:34.920
oder schmeißt du die Spalten raus?

00:42:34.920 --> 00:42:37.100
Ähm...

00:42:37.100 --> 00:42:38.980
Hängt halt immer von dem Tast ab, aber

00:42:38.980 --> 00:42:40.000
genau das macht man an der Stelle halt immer auch ein bisschen...

00:42:40.000 --> 00:42:43.020
Ja, aber da sieht man genau gerade, ne, man hat ja irgendwie die Warnings gesehen, wie viel irgendwie

00:42:43.020 --> 00:42:45.400
das ganz viele aus einer Zeile oder Spalte

00:42:45.400 --> 00:42:47.000
dann da fehlen oder so bei irgendwelchen Einträgen,

00:42:47.000 --> 00:42:49.100
war bei den Warnings irgendwie mit dabei. Wie hieß das nochmal?

00:42:49.100 --> 00:42:50.860
Ich hab das... Pandas Profiling.

00:42:50.860 --> 00:42:52.900
Profiling, okay. Genau. Interessant.

00:42:52.900 --> 00:42:54.920
Das muss auf jeden Fall auch in die Shownotes.

00:42:54.920 --> 00:42:55.480
Ja, mach ich.

00:42:55.480 --> 00:42:58.840
Ähm...

00:42:58.840 --> 00:42:59.680
Ja, genau. Also,

00:42:59.680 --> 00:43:03.020
hängt halt dann immer auch von den Operationen ab,

00:43:03.020 --> 00:43:04.840
die man halt danach drauf irgendwie anwenden

00:43:04.840 --> 00:43:05.160
möchte.

00:43:05.160 --> 00:43:08.820
Ähm, genau. Ansonsten ist

00:43:08.820 --> 00:43:10.820
glaube ich so eine gute Möglichkeit am Anfang

00:43:10.820 --> 00:43:12.760
sich auch nochmal so ein bisschen einfach erstmal zu plotten.

00:43:12.760 --> 00:43:14.820
Also, irgendwie diese statistischen Maße

00:43:14.820 --> 00:43:16.680
sind immer irgendwie ganz nett, um

00:43:16.680 --> 00:43:18.840
ein erstes Gefühl zu bekommen, wie groß ist

00:43:18.840 --> 00:43:20.520
denn meine Spanne an Werten und so weiter.

00:43:20.520 --> 00:43:22.660
Aber...

00:43:22.660 --> 00:43:24.700
Da können halt einzelne Ausreißer das Ganze

00:43:24.700 --> 00:43:25.920
eben ja komplett verziehen.

00:43:25.920 --> 00:43:28.740
Oder ich hab zum Beispiel so einen leichten Shift

00:43:28.740 --> 00:43:30.900
in den Daten, sowas in Kennzahlen zu erfassen

00:43:30.900 --> 00:43:32.720
geht zwar, aber ist irgendwie immer nicht ganz so

00:43:32.720 --> 00:43:34.680
eingängig. Und dann hilft halt meistens

00:43:34.680 --> 00:43:35.940
mal irgendwie so ein Histogramm oder so.

00:43:35.940 --> 00:43:38.560
Ja. Genau, würde ich auch sagen.

00:43:38.560 --> 00:43:39.480
Das ist das

00:43:39.480 --> 00:43:42.640
nützlichste Ding,

00:43:42.640 --> 00:43:44.720
wenn man sich irgendwie, wenn man so ein bisschen

00:43:44.720 --> 00:43:46.540
sehen will, wie das eigentlich verteilt ist.

00:43:46.540 --> 00:43:48.640
Oft ist es halt sich ein Histogramm von

00:43:48.640 --> 00:43:50.360
der Werte halt anzugucken.

00:43:50.360 --> 00:43:52.140
Vor allen Dingen auch, wenn man jetzt unterschiedliche Klassen hat,

00:43:52.420 --> 00:43:54.340
mal die Histogramme gegeneinander zu plotten. Das ist etwas,

00:43:54.340 --> 00:43:55.960
was ich oft

00:43:55.960 --> 00:43:58.360
mir angucke, halt

00:43:58.360 --> 00:44:00.540
sozusagen, um zu sehen, ob das irgendwas ist, wo

00:44:00.540 --> 00:44:02.320
interessante Informationen für

00:44:02.320 --> 00:44:04.100
Klassifikationen oder so drinsteht,

00:44:04.100 --> 00:44:06.360
dass man halt sagt so, okay, man plottet das

00:44:06.360 --> 00:44:08.280
Histogramm der einen Klasse gegen das der anderen und

00:44:08.280 --> 00:44:10.200
man halt sieht, okay, da gibt es einen großen Unterschied, dann ist

00:44:10.200 --> 00:44:12.380
schon mal, oder auch selbst ein kleiner Unterschied

00:44:12.380 --> 00:44:13.660
ist natürlich schon hilfreich irgendwie.

00:44:13.660 --> 00:44:16.180
Wenn man sieht, die sind genau gleich verteilt, dann ist das natürlich doof.

00:44:16.180 --> 00:44:17.700
Aber, genau.

00:44:17.700 --> 00:44:19.720
Genau, in dem

00:44:19.720 --> 00:44:22.180
Explore-Data-Block sieht man auch ganz unten

00:44:22.180 --> 00:44:23.960
eben, finde ich, ein ganz klassisches, aber

00:44:23.960 --> 00:44:25.980
sehr, sehr hilfreiches Diagramm an der Stelle,

00:44:25.980 --> 00:44:27.980
wo du einfach mal so die

00:44:27.980 --> 00:44:29.800
Länge der Texte

00:44:29.800 --> 00:44:31.280
abgetragen hast, den Zeichen,

00:44:31.280 --> 00:44:34.080
und da sieht man auch so ein ganz typisches Verhalten.

00:44:34.080 --> 00:44:35.900
Man hat halt irgendwie so einen Peak

00:44:35.900 --> 00:44:37.860
der Daten, der relativ am Anfang

00:44:37.860 --> 00:44:39.720
liegt, also irgendwie, wir haben hier jetzt,

00:44:39.720 --> 00:44:41.660
würde ich sagen, wahrscheinlich mal

00:44:41.660 --> 00:44:43.560
80 Prozent

00:44:43.560 --> 00:44:45.880
irgendwie im Bereich von 0

00:44:45.880 --> 00:44:47.760
bis 600 Zeichen, oder

00:44:47.760 --> 00:44:49.180
bis 750, glaube ich, sind es.

00:44:49.180 --> 00:44:51.700
Und dann wird es weniger

00:44:51.940 --> 00:44:53.940
und dann gibt es so ein Longtail hinten

00:44:53.940 --> 00:44:55.800
mit so ein paar einzelnen Einträgen, die dann halt

00:44:55.800 --> 00:44:57.640
irgendwie 3.000, 4.000, 5.000,

00:44:57.640 --> 00:44:59.560
6.000 plus Einträge haben.

00:44:59.560 --> 00:45:01.540
Irgendwann hat ja jemand sein Buch bei Reuters hochgeladen, oder?

00:45:01.540 --> 00:45:03.340
Ja, genau.

00:45:03.340 --> 00:45:05.900
Aber das ist so ein ganz klassisches Problem, was man halt im echten

00:45:05.900 --> 00:45:07.640
Welt-Data-Science halt immer hat,

00:45:07.640 --> 00:45:10.180
dass es halt irgendwie so Ausreißer

00:45:10.180 --> 00:45:12.240
gibt, die die Diagramme

00:45:12.240 --> 00:45:13.860
verzerren und die dann auch immer

00:45:13.860 --> 00:45:15.480
den Aufwand beim Programmieren eigentlich bedeuten,

00:45:15.480 --> 00:45:17.880
weil das dann immer die Fälle sind, an die man vielleicht

00:45:17.880 --> 00:45:18.660
so nicht gedacht hat.

00:45:18.660 --> 00:45:20.700
Ja.

00:45:21.700 --> 00:45:23.760
Genau. Ja, wir sehen hier, dass es halt

00:45:23.760 --> 00:45:25.860
so irgendwie ungefähr 10.000

00:45:25.860 --> 00:45:27.840
Dinger gibt, die irgendwie

00:45:27.840 --> 00:45:29.440
im Test- oder Training

00:45:29.440 --> 00:45:31.580
zugeordnet sind.

00:45:31.580 --> 00:45:33.440
Also dieser

00:45:33.440 --> 00:45:34.560
Mod-Up-Display teilt

00:45:34.560 --> 00:45:36.980
diese Ticker-Meldung halt in

00:45:36.980 --> 00:45:39.340
die, auf denen man trainieren kann und die

00:45:39.340 --> 00:45:41.720
sozusagen, die man hinterher benutzt,

00:45:41.720 --> 00:45:43.700
um zu evaluieren, wie gut denn jetzt

00:45:43.700 --> 00:45:44.700
die Modelle funktioniert haben.

00:45:44.700 --> 00:45:47.600
Und es gibt irgendwie

00:45:47.600 --> 00:45:49.040
119 Klassen, aber

00:45:49.040 --> 00:45:51.460
tatsächlich sind es deutlich

00:45:51.460 --> 00:45:53.440
weniger, wenn man jetzt alle

00:45:53.440 --> 00:45:55.340
und

00:45:55.340 --> 00:45:57.680
es gibt so Meta-Superklassen

00:45:57.680 --> 00:45:59.520
quasi, die bestimmte Dinge beinhalten,

00:45:59.520 --> 00:46:01.700
sowas wie Sport, und dann gibt es Unterkategorien,

00:46:01.700 --> 00:46:03.280
Fußball, Hockey. Es gibt einige, die

00:46:03.280 --> 00:46:05.820
deutlich häufiger sind,

00:46:05.820 --> 00:46:06.880
aber es ist halt so, dass

00:46:06.880 --> 00:46:09.680
wenn man jetzt alle rausnimmt,

00:46:09.680 --> 00:46:10.780
auch alle Beispiele rausnimmt,

00:46:10.780 --> 00:46:13.620
auch alle Kategorien rausnimmt, zu denen es nicht mindestens

00:46:13.620 --> 00:46:15.720
ein Trainings- und ein Testbeispiel

00:46:15.720 --> 00:46:17.460
gibt, weil das ist ja auch irgendwie so ein bisschen sinnlos,

00:46:17.460 --> 00:46:19.520
also Sachen, die man nicht gesehen hat, kann man auch schlecht vorhersagen,

00:46:19.520 --> 00:46:21.420
dann sind es

00:46:21.420 --> 00:46:23.540
nochmal deutlich weniger, sind es irgendwie nur 90 Kategorien,

00:46:23.540 --> 00:46:25.380
die übrig bleiben, glaube ich, und halt irgendwie

00:46:25.380 --> 00:46:27.640
die Kategorien, die rausgefallen sind, sonstiges oder so.

00:46:27.640 --> 00:46:30.000
Ja, ich weiß es

00:46:30.000 --> 00:46:31.540
gar nicht genau, ich habe es mir auch nicht

00:46:31.540 --> 00:46:33.400
angeguckt, was das genau für Kategorien sind, aber

00:46:33.400 --> 00:46:34.840
ja, also

00:46:34.840 --> 00:46:37.280
das ist halt tatsächlich, sind die Zahlen für alle,

00:46:37.280 --> 00:46:37.760
aber

00:46:37.760 --> 00:46:41.020
in Wirklichkeit ist es halt nochmal ein bisschen weniger,

00:46:41.020 --> 00:46:43.440
also die dann hinterher tatsächlich

00:46:43.440 --> 00:46:45.020
zum Trainieren verwendet werden, dann

00:46:45.020 --> 00:46:47.360
eben durchschnittliche Anzahl von

00:46:47.360 --> 00:46:49.060
Wörtern ist halt irgendwie auch so 90

00:46:49.060 --> 00:46:51.380
und genau,

00:46:51.380 --> 00:46:51.740
die,

00:46:51.740 --> 00:46:56.940
also es gibt so eine Quote

00:46:56.940 --> 00:46:59.340
Anzahl der Beispiele, also das

00:46:59.340 --> 00:47:00.900
Anzahl der Zeilen im DataFrame

00:47:00.900 --> 00:47:03.700
geteilt durch die Anzahl der Wörter pro

00:47:03.700 --> 00:47:05.600
Tickermeldung

00:47:05.600 --> 00:47:07.380
ist halt auch eine ganz

00:47:07.380 --> 00:47:09.540
interessante

00:47:09.540 --> 00:47:11.300
Zahl, die man später benutzen kann, um halt

00:47:11.300 --> 00:47:13.340
irgendwie rauszukriegen, welche Art

00:47:13.340 --> 00:47:15.380
von Modell da irgendwie besser funktionieren

00:47:15.380 --> 00:47:15.660
könnte.

00:47:15.660 --> 00:47:17.700
Ja,

00:47:17.700 --> 00:47:21.340
genau, also überhaupt diese ganze, also das

00:47:21.340 --> 00:47:23.080
ist halt so irgendwie explorative Phase

00:47:23.080 --> 00:47:24.780
irgendwie bei so einem Projekt,

00:47:24.780 --> 00:47:27.080
man versucht halt rauszukriegen, gibt es irgendwelche

00:47:27.080 --> 00:47:28.460
interessanten Regelmäßigkeiten,

00:47:28.460 --> 00:47:31.060
wie groß sind die Daten,

00:47:31.060 --> 00:47:33.300
was prinzipiell kann ich da eigentlich für Modelle

00:47:33.300 --> 00:47:35.320
verwenden und so. Ja, also erstmal visualisieren,

00:47:35.320 --> 00:47:37.240
ist glaube ich tatsächlich eine gute Idee, ne, auch verschiedene

00:47:37.240 --> 00:47:39.320
Arten, mal gucken, WordCloud bauen vielleicht

00:47:39.320 --> 00:47:41.520
oder so und dann schauen, was ist das denn.

00:47:41.520 --> 00:47:43.320
Genau, und nebenher finde ich durchaus irgendwie

00:47:43.320 --> 00:47:45.320
nochmal so ein Scratchpad offen haben und wenn man

00:47:45.320 --> 00:47:46.900
da irgendwie eine Auffälligkeit hat,

00:47:46.900 --> 00:47:49.080
die immer gleich reinschreiben, also

00:47:49.080 --> 00:47:51.140
man verfällt dann finde ich auch relativ leicht

00:47:51.140 --> 00:47:53.000
in so einem, ja, Liebe

00:47:53.000 --> 00:47:55.120
zu Charts, weil so Charts

00:47:55.120 --> 00:47:57.080
basteln ist was, was ich zum Beispiel total gerne

00:47:57.080 --> 00:47:58.740
mache. Also ich finde es total spannend, dann

00:47:58.740 --> 00:48:00.960
mir die Daten irgendwie so in Diagrammen

00:48:00.960 --> 00:48:03.140
zu visualisieren und die irgendwie hübsch zu machen

00:48:03.140 --> 00:48:05.160
und mächtig von ihrer Aussagekraft und so weiter,

00:48:05.160 --> 00:48:06.360
aber dabei

00:48:06.360 --> 00:48:09.000
verfalle ich da manchmal so ein bisschen in der

00:48:09.000 --> 00:48:10.480
Liebe zum Tun und

00:48:10.480 --> 00:48:12.860
eigentlich geht es ja darum, Insights zu generieren.

00:48:12.860 --> 00:48:15.120
Deswegen finde ich es dann

00:48:15.120 --> 00:48:17.060
immer relativ wichtig, sich irgendwo nochmal so eine Liste

00:48:17.060 --> 00:48:18.980
runterzuschreiben mit den Auffälligkeiten, wo man so

00:48:18.980 --> 00:48:21.100
gedacht hat, ah ja, stimmt, das ist ja interessant,

00:48:21.100 --> 00:48:23.200
und das ist interessant, weil

00:48:23.200 --> 00:48:25.180
im Endeffekt sind das nachher dann Sachen, aus denen man

00:48:25.180 --> 00:48:27.400
dann Ideen bekommt, um zum Beispiel

00:48:27.400 --> 00:48:29.140
Features zu generieren, die

00:48:29.140 --> 00:48:31.300
dann eben meinem Modell wirklich weiterhelfen könnten.

00:48:31.300 --> 00:48:33.300
Ja, also

00:48:33.300 --> 00:48:35.000
das ist halt an der Stelle auch definitiv dann

00:48:35.000 --> 00:48:37.100
ein iterativer Prozess, wo man

00:48:37.100 --> 00:48:38.440
quasi

00:48:38.440 --> 00:48:40.940
sich die Daten anschaut, man entwickelt eine Idee

00:48:40.940 --> 00:48:43.040
dafür, man probiert sie aus und man geht dann

00:48:43.040 --> 00:48:45.040
wieder zurück und guckt sich mal wieder die Daten an

00:48:45.040 --> 00:48:47.080
und guckt, ah ja, jetzt habe ich aber ja

00:48:47.080 --> 00:48:49.060
ein besseres Verständnis dafür bekommen, weil

00:48:49.060 --> 00:48:51.020
ja, da ist so viel

00:48:51.020 --> 00:48:53.120
Information in so einem Datensystem, dass es eine ganze Zeit

00:48:53.120 --> 00:48:55.100
lang braucht, bis man wirklich

00:48:55.100 --> 00:48:56.760
versteht, was man damit alles machen könnte.

00:48:56.760 --> 00:48:59.020
Ja, man muss ja natürlich auch immer das Problem erstmal

00:48:59.020 --> 00:49:00.880
so ein bisschen reindenken, damit man irgendwie dann mit den Daten

00:49:00.880 --> 00:49:01.700
aber auch was anfangen kann.

00:49:01.700 --> 00:49:04.840
Genau, und

00:49:04.840 --> 00:49:06.940
ja, dabei

00:49:06.940 --> 00:49:08.900
hilft halt diese explorative Sache und

00:49:08.900 --> 00:49:10.040
ja,

00:49:10.040 --> 00:49:13.040
neben diesem ganzen Histogramm, ich glaube, wir haben angefangen

00:49:13.040 --> 00:49:14.960
erstmal mit, wie man die Daten noch bekommt, damit waren wir noch gar nicht

00:49:14.960 --> 00:49:17.140
so durch. Achso, richtig, ja, stimmt.

00:49:17.140 --> 00:49:19.160
Wir sollten irgendwie noch so die Art und Weise

00:49:19.160 --> 00:49:20.980
der Methode, wir haben jetzt irgendwie das Describe irgendwie von

00:49:20.980 --> 00:49:22.960
DataFrames ein bisschen gemacht, aber wie bekomme ich denn

00:49:22.960 --> 00:49:25.000
die Daten überhaupt irgendwie so rein? Das ist ein guter Punkt,

00:49:25.000 --> 00:49:25.160
ja.

00:49:25.160 --> 00:49:28.600
Ja, also das ist irgendwie

00:49:28.600 --> 00:49:30.500
eine URL, die da irgendwo

00:49:30.500 --> 00:49:32.680
mit drin steht.

00:49:32.680 --> 00:49:34.920
Moment, ich glaube, das ist jetzt mittlerweile gut versteckt

00:49:34.920 --> 00:49:37.400
irgendwie in dem

00:49:37.400 --> 00:49:39.480
DS-Tutorial-Paket.

00:49:39.480 --> 00:49:41.100
Datasets, da gibt es

00:49:41.100 --> 00:49:43.020
einen Pfeil. Genau, normalerweise in der

00:49:43.020 --> 00:49:45.080
echten Welt würde ich sagen, ist der Fall meist

00:49:45.080 --> 00:49:46.940
entweder habe ich den CSV irgendwo rübergeworfen

00:49:46.940 --> 00:49:48.880
bekommen, dann lese ich die einfach über Pandas ein

00:49:48.880 --> 00:49:50.500
oder ich habe halt irgendwie für einen

00:49:50.500 --> 00:49:52.980
Spielprojekt eine Web-URL, dann ziehe ich es mir

00:49:52.980 --> 00:49:54.100
direkt von dort.

00:49:54.100 --> 00:49:56.780
Kann man ja direkt auch mit Pandas, glaube ich.

00:49:56.780 --> 00:49:59.120
Oder eigene Webdaten-Straight mit einer eigenen Datenbank

00:49:59.120 --> 00:50:01.180
oder sowas. Oder von irgendwelchen Sendoren,

00:50:01.180 --> 00:50:02.880
die Sachen in irgendeine Datenbank packen.

00:50:02.880 --> 00:50:04.940
Eine Datenbank-Anwendung ist natürlich auch guter Punkt,

00:50:04.940 --> 00:50:07.020
definitiv. Ist irgendwie in der

00:50:07.020 --> 00:50:08.960
echten Welt gefühlt zu selten bei so

00:50:08.960 --> 00:50:10.860
Notebooks. Irgendwie landen die Dateien dann doch immer

00:50:10.860 --> 00:50:11.920
als Datei da, aber

00:50:11.920 --> 00:50:15.020
genau, in dem Fall ist es ja relativ

00:50:15.020 --> 00:50:17.220
tief im Code direkt versteckt, wie du es lädst.

00:50:17.220 --> 00:50:18.840
Also wenn die Dateien da laden,

00:50:18.840 --> 00:50:20.340
also wirklich big ist die Datei dann aber

00:50:20.340 --> 00:50:20.940
irgendwie noch nicht.

00:50:20.940 --> 00:50:24.000
Das hier ist alles super small.

00:50:24.000 --> 00:50:26.420
Man will in so einem Notebook auch

00:50:26.420 --> 00:50:27.500
kein Big Data haben.

00:50:27.500 --> 00:50:30.240
Kann man schon, aber...

00:50:30.240 --> 00:50:31.980
Kann man schon, aber ich weiß nicht.

00:50:31.980 --> 00:50:34.280
Meine Präferenz an der Stelle ist

00:50:34.280 --> 00:50:36.280
vor allem immer erstmal auch Latenz nicht richtig zu halten

00:50:36.280 --> 00:50:38.180
und schnell mit Daten zu iterieren

00:50:38.180 --> 00:50:40.440
und lieber erstmal ein kleines Sample ziehen

00:50:40.440 --> 00:50:42.420
und erstmal viel Zeit in diesem kleinen Sample

00:50:42.420 --> 00:50:44.400
zu verbringen und dann

00:50:44.400 --> 00:50:46.400
natürlich sehr bewusst wählen,

00:50:46.400 --> 00:50:48.140
wie wähle ich jetzt mein Sample? Mache ich es wirklich

00:50:48.140 --> 00:50:50.180
komplett random oder habe ich eine Zeitreihe? Muss ich jetzt gewisse

00:50:50.180 --> 00:50:51.900
Aspekte dabei berücksichtigen?

00:50:51.900 --> 00:50:54.180
Aber erstmal darauf eine Weile iterieren

00:50:54.180 --> 00:50:56.280
und dann sich nachher

00:50:56.280 --> 00:50:58.120
die Embedded auf dem Kompletten ausprobieren.

00:50:58.120 --> 00:51:00.040
Machst du das anders?

00:51:00.040 --> 00:51:02.360
Nee, nee, also genau. Subsamplen ist

00:51:02.360 --> 00:51:04.240
halt auch, wenn die Daten groß sind, auf jeden Fall

00:51:04.240 --> 00:51:05.840
eine super Strategie, um halt

00:51:05.840 --> 00:51:07.720
schnell iterieren zu können.

00:51:07.720 --> 00:51:09.380
Man kann aber, wenn man jetzt

00:51:09.380 --> 00:51:12.060
tatsächlich irgendwie

00:51:12.060 --> 00:51:14.120
größere Daten hat

00:51:14.120 --> 00:51:16.260
und das auch nicht irgendwie vielleicht kleiner

00:51:16.260 --> 00:51:18.460
machen will, sich zum Beispiel

00:51:18.460 --> 00:51:19.980
von den

00:51:20.020 --> 00:51:21.960
importiert man sich halt ein DataFrame nicht direkt von Pandas

00:51:21.960 --> 00:51:23.760
sozusagen, sondern man importiert das halt

00:51:23.760 --> 00:51:25.920
von DAS und

00:51:25.920 --> 00:51:28.560
das Ding

00:51:28.560 --> 00:51:30.080
verteilt dann automatisch

00:51:30.080 --> 00:51:31.880
irgendwie die Sachen, die man da drauf tut, halt

00:51:31.880 --> 00:51:34.000
auf zum Beispiel, das hat auch, das ist schon

00:51:34.000 --> 00:51:35.600
ziemlich cool, das hat eine Anbindung an

00:51:35.600 --> 00:51:37.720
Kubernetes und halt auch an die ganzen

00:51:37.720 --> 00:51:39.540
Cloud-Geschichten wie so irgendwo

00:51:39.540 --> 00:51:41.480
Google Compute Engine und so

00:51:41.480 --> 00:51:43.920
und da kann man dann halt einfach sagen,

00:51:43.920 --> 00:51:45.980
okay, ich nehme mir jetzt mal so hier 100 Maschinen

00:51:45.980 --> 00:51:47.720
und füge die dann

00:51:47.720 --> 00:51:50.000
hinzu und man kann auch mehr an

00:51:50.000 --> 00:51:51.800
während Sachen da drauf laufen, also

00:51:51.800 --> 00:51:53.720
während man auf einem DataFrame halt irgendwas

00:51:53.720 --> 00:51:55.560
kopiert oder so, kann man sagen, okay, ach,

00:51:55.560 --> 00:51:57.840
das geht mir zu langsam, nochmal 10 Maschinen dazu oder so

00:51:57.840 --> 00:51:59.840
und dann wird das

00:51:59.840 --> 00:52:01.360
automatisch halt irgendwie,

00:52:01.360 --> 00:52:03.200
werden die mit reingenommen und

00:52:03.200 --> 00:52:05.360
werden die Sachen halt irgendwie magisch schneller

00:52:05.360 --> 00:52:07.760
und man sieht halt auch irgendwie sehr schön,

00:52:07.760 --> 00:52:09.120
was da passiert.

00:52:09.120 --> 00:52:12.020
Da habe ich jetzt normalerweise kein Beispiel für, aber

00:52:12.020 --> 00:52:15.820
das geht

00:52:15.820 --> 00:52:17.300
durchaus auch und das

00:52:17.300 --> 00:52:19.800
Benutzerinterface ist dann da auch nicht anders,

00:52:19.840 --> 00:52:21.420
als wenn man das jetzt auf einer lokalen Maschine macht,

00:52:21.420 --> 00:52:23.560
sondern ist auch immer ein Notebook eigentlich.

00:52:23.560 --> 00:52:25.480
Ich glaube, zu diesem

00:52:25.480 --> 00:52:27.380
Big-Dating müssen wir nochmal eine eigene Folge machen, so mit

00:52:27.380 --> 00:52:29.000
Kubernetes, das ist dann nochmal spannend.

00:52:29.000 --> 00:52:31.520
Genau, an der Stelle kann ich mal

00:52:31.520 --> 00:52:32.740
meine Kubernetes-Folge droppen.

00:52:32.740 --> 00:52:34.960
Ach, der ist noch? Ja, genau.

00:52:34.960 --> 00:52:36.700
Es gibt eine zu Docker und eine zu Kubernetes.

00:52:36.700 --> 00:52:39.520
Ja, und das

00:52:39.520 --> 00:52:41.280
Schöne ist halt, dass die Sachen dann auch, wenn man sie nicht mehr braucht,

00:52:41.280 --> 00:52:43.400
wieder verschwinden, während halt, das ist ja auch etwas,

00:52:43.400 --> 00:52:45.400
was man sonst, also gibt es dann vielleicht auch irgendwie,

00:52:45.400 --> 00:52:47.480
in vielen Firmen gibt es dann halt

00:52:47.480 --> 00:52:49.680
so ein Cluster, wo man Sachen machen kann, aber die Maschinen sind dann halt

00:52:49.680 --> 00:52:50.300
da und

00:52:50.300 --> 00:52:53.040
man braucht sie aber irgendwie nur,

00:52:53.040 --> 00:52:55.420
man braucht eigentlich so alle halbe Stunde mal so wirklich

00:52:55.420 --> 00:52:57.500
volle Power, aber ansonsten braucht man das

00:52:57.500 --> 00:52:59.240
eigentlich nicht und

00:52:59.240 --> 00:53:00.300
ja,

00:53:00.300 --> 00:53:03.560
das ist, glaube ich, auch irgendwie, also das ist

00:53:03.560 --> 00:53:05.240
schon ein sehr gutes Argument für diese ganzen

00:53:05.240 --> 00:53:07.200
Cloud-Geschichten, weil man zahlt halt tatsächlich nur

00:53:07.200 --> 00:53:10.000
in dem Moment, wo man halt die Rechenzeit

00:53:10.000 --> 00:53:11.080
braucht und

00:53:11.080 --> 00:53:13.680
Also du hast Dasks jetzt auch

00:53:13.680 --> 00:53:15.360
schon öfter eingesetzt und das funktioniert für dich gut?

00:53:15.360 --> 00:53:16.920
Ja, für mich funktioniert das eigentlich ziemlich gut.

00:53:16.920 --> 00:53:19.300
Ich habe dann nämlich praktisch so noch keine Erfahrung, ich habe nur

00:53:19.520 --> 00:53:21.240
irgendwie im Hinterkopf, dass man dafür einiges

00:53:21.240 --> 00:53:23.360
umschreiben muss, dass das nicht komplett kompatibel ist

00:53:23.360 --> 00:53:25.420
mit den Pandas. Nicht komplett, aber

00:53:25.420 --> 00:53:27.160
also sagen wir mal so, das meiste geht eigentlich

00:53:27.160 --> 00:53:29.440
schon. Es gibt also ein paar, ja natürlich,

00:53:29.440 --> 00:53:30.980
es gibt natürlich immer so ein paar Ecken.

00:53:30.980 --> 00:53:33.260
Ja, intern ist es halt so, dass der das

00:53:33.260 --> 00:53:35.220
auf eine Menge DataFrames aufteilt

00:53:35.220 --> 00:53:37.140
und das muss man halt irgendwie, die

00:53:37.140 --> 00:53:39.600
unterschiedlichen Teile liegen halt auf unterschiedlichen Rechnern

00:53:39.600 --> 00:53:41.460
und ja. Ansonsten,

00:53:41.460 --> 00:53:43.380
wenn man Pandas einfach

00:53:43.380 --> 00:53:45.260
nur Multicore betreiben möchte, was ja

00:53:45.260 --> 00:53:47.520
Pandas per Default jetzt aktuell noch nicht bietet,

00:53:47.520 --> 00:53:49.360
gibt es auch ein paar nette Projekte,

00:53:49.360 --> 00:53:51.360
da gibt es einmal Modin, das ehemalige

00:53:51.360 --> 00:53:52.980
Pandas on Ray,

00:53:52.980 --> 00:53:55.700
was quasi einfach über einen Import

00:53:55.700 --> 00:53:56.440
einfach nur,

00:53:56.440 --> 00:53:59.360
du änderst den Import und dann kannst du

00:53:59.360 --> 00:54:01.440
prinzipiell Multicore für

00:54:01.440 --> 00:54:03.360
die allermeisten Pandas-Operationen.

00:54:03.360 --> 00:54:05.540
Wenn du also eher in die Nische kommst,

00:54:05.540 --> 00:54:07.040
geht es da vielleicht dann irgendwann nicht mehr.

00:54:07.040 --> 00:54:09.440
Und was ich heute kennengelernt habe und noch nicht ausprobiert

00:54:09.440 --> 00:54:11.160
habe, ist Pandarallel,

00:54:11.160 --> 00:54:12.460
also

00:54:12.460 --> 00:54:14.500
wie Panda und dann

00:54:14.500 --> 00:54:17.220
Parallel quasi und

00:54:17.220 --> 00:54:19.200
das unterstützt halt eben auch quasi oder verspricht

00:54:19.200 --> 00:54:21.300
ein Multicore-Processing für Pandas-Operationen.

00:54:21.300 --> 00:54:23.420
Genau. Also bevor man vielleicht

00:54:23.420 --> 00:54:25.280
wirklich auch ein Cluster muss,

00:54:25.280 --> 00:54:26.680
ist das noch eine gute Option.

00:54:26.680 --> 00:54:28.040
Ja.

00:54:28.040 --> 00:54:31.460
Ja, ja, ja. Ne, das kann ich auch noch nicht.

00:54:31.460 --> 00:54:32.980
Also, ja. Sehr interessant.

00:54:32.980 --> 00:54:35.340
Genau.

00:54:35.340 --> 00:54:37.120
Aber wir waren hier bei dem...

00:54:37.120 --> 00:54:38.220
Wie bekomme ich eigentlich meine Daten?

00:54:38.220 --> 00:54:40.300
Ja, ich hatte einfach das entsprechende Notpunkt nicht aufgemacht.

00:54:40.300 --> 00:54:42.780
Das heißt hier Preparing Data.

00:54:42.780 --> 00:54:44.400
Keine Ahnung, vielleicht ist es unsinnig genannt.

00:54:44.400 --> 00:54:47.220
Und das ist einfach das Ding,

00:54:47.220 --> 00:54:49.180
also David Lewis ist auch der, der den Modellorten,

00:54:49.180 --> 00:54:51.180
den Modellort-Split gemacht hat und auch überhaupt

00:54:51.180 --> 00:54:53.140
der, der das ganze Dataset kuratiert hat,

00:54:53.140 --> 00:54:54.920
hat das halt irgendwie auf seiner Seite liegen.

00:54:54.920 --> 00:54:56.680
Und, ähm,

00:54:56.680 --> 00:54:59.280
genau, dann, ähm, ja.

00:54:59.280 --> 00:55:01.380
Ähm, was du

00:55:01.380 --> 00:55:03.400
auch benutzt an der Stelle im Notebook ist ja

00:55:03.400 --> 00:55:05.180
ähm, die, ähm,

00:55:05.180 --> 00:55:07.000
die Path Library.

00:55:07.000 --> 00:55:09.260
Ja. Ähm, hab ich auch noch nicht so

00:55:09.260 --> 00:55:11.160
lange in Benutzung, aber ist eigentlich mega cool.

00:55:11.160 --> 00:55:12.780
Ja, ja, genau. Sag dazu doch nochmal zwei Sätze.

00:55:12.780 --> 00:55:15.160
Ja, also, äh, früher hab ich das auch

00:55:15.160 --> 00:55:17.180
mal mit, äh, OS

00:55:17.180 --> 00:55:19.020
und ListDir und OS Paths

00:55:19.020 --> 00:55:20.760
Join und so gemacht, aber das ist alles ganz schön

00:55:20.760 --> 00:55:21.800
genau, glaub,

00:55:21.800 --> 00:55:25.160
ganz schön umständlich und, äh,

00:55:25.160 --> 00:55:27.560
ähm, da gibt's halt, äh,

00:55:27.560 --> 00:55:29.200
ich weiß gar nicht, wann das in, seit wann

00:55:29.200 --> 00:55:31.260
das in der Standard Library ist, aber, äh,

00:55:31.260 --> 00:55:33.300
also es gibt da ein, ein, ähm,

00:55:33.300 --> 00:55:34.520
ein Modul namens Path Slip

00:55:34.520 --> 00:55:37.460
und, äh, da, äh,

00:55:37.460 --> 00:55:38.920
kann man, also,

00:55:38.920 --> 00:55:41.160
zum Beispiel, es geht

00:55:41.160 --> 00:55:43.100
hier los mit, äh, Path.Home, ist halt

00:55:43.100 --> 00:55:45.480
sozusagen dann ein Part und, ähm,

00:55:45.480 --> 00:55:47.060
die, das Ding funktioniert

00:55:47.060 --> 00:55:49.000
im Grunde, wenn man jetzt Pfade erweitern möchte oder so,

00:55:49.000 --> 00:55:50.820
über, äh, so Operator

00:55:50.820 --> 00:55:52.620
Overloading und, äh,

00:55:52.620 --> 00:55:54.880
die haben dann halt einfach das, äh, den

00:55:54.880 --> 00:55:56.820
Slash, äh, überladen und jetzt kann man halt

00:55:56.820 --> 00:55:58.840
schreiben, äh, irgendwie Path.Home, gibt dann

00:55:58.840 --> 00:56:00.780
das Home-Verzeichnis, Slash, Data

00:56:00.780 --> 00:56:01.900
Slash TMP

00:56:01.900 --> 00:56:04.960
und das ist natürlich viel kürzer, also würde man jetzt schreiben

00:56:04.960 --> 00:56:06.400
OS Paths Join,

00:56:06.400 --> 00:56:08.660
Klammer auf, und dann gibt man eine Liste oder macht

00:56:08.660 --> 00:56:10.880
irgendwie, ja, äh, irgendwie, äh,

00:56:10.880 --> 00:56:12.840
muss dann einen absoluten Pfad angeben oder

00:56:12.840 --> 00:56:14.920
man gibt irgendwie einen relativen Ankommer, irgendwie

00:56:14.920 --> 00:56:16.800
das nächste Ding und, äh,

00:56:16.800 --> 00:56:18.800
das ist alles ganz schrecklich. Man kann sehr schön,

00:56:18.840 --> 00:56:20.960
ähm, Variablen quasi mit reinbetten

00:56:20.960 --> 00:56:22.860
und, ähm, man bekommt

00:56:22.860 --> 00:56:24.620
ja am Ende dann auch immer quasi ein Path-Objekt

00:56:24.620 --> 00:56:26.500
wieder raus, was dann auch nochmal so

00:56:26.500 --> 00:56:28.600
Operationen bietet wie, ähm, okay,

00:56:28.600 --> 00:56:31.220
jetzt verraten wir von dem noch bitte die Subdirectories

00:56:31.220 --> 00:56:32.900
oder, ähm, ja,

00:56:32.900 --> 00:56:34.680
halt Operationen dann immer direkt auf

00:56:34.680 --> 00:56:36.660
dem Pfad ausführen. Ja, du kannst einfach ein Dot-Exist

00:56:36.660 --> 00:56:38.640
machen oder sowas, das wäre auch ziemlich cool, ja. Genau.

00:56:38.640 --> 00:56:40.620
Ja, und ansonsten hätte man immer

00:56:40.620 --> 00:56:42.560
OS Paths Exist und so verwenden müssen

00:56:42.560 --> 00:56:44.720
und dann, also das ist, es ist

00:56:44.720 --> 00:56:46.580
wirklich viel, viel angenehmer damit zu

00:56:46.580 --> 00:56:48.680
arbeiten und, ähm, ja, äh,

00:56:48.680 --> 00:56:50.700
also sonst hat man immer so, also ich hatte sonst immer das Problem,

00:56:50.700 --> 00:56:52.780
dass irgendwie die ganzen, diese ganzen Geschichten

00:56:52.780 --> 00:56:54.720
wurden immer relativ festlich und auch die Zeilen wurden sehr

00:56:54.720 --> 00:56:56.560
lang und das, das Problem ist irgendwie weg,

00:56:56.560 --> 00:56:58.700
seitdem ich Parsel verwende und das ist schon mal echt ein

00:56:58.700 --> 00:57:00.800
Vorteil. Vielleicht um das zu kurz zu zeigen,

00:57:00.800 --> 00:57:02.680
ich lösche jetzt einfach mal die Daten, die ich hier bei mir

00:57:02.680 --> 00:57:03.900
lokal habe, äh,

00:57:03.900 --> 00:57:06.800
Data, äh,

00:57:06.800 --> 00:57:08.860
TMP, ja,

00:57:08.860 --> 00:57:09.180
genau.

00:57:09.180 --> 00:57:12.320
Äh, ah.

00:57:12.320 --> 00:57:14.420
Da muss man echt mit aufpassen. Ja, ja.

00:57:14.420 --> 00:57:16.640
Ja, wenn du willst so ein Git-Repo löschen

00:57:16.640 --> 00:57:18.600
oder so, machst dann irgendwie .slash oder so,

00:57:18.600 --> 00:57:20.360
und dann immer aus Versehen löscht man den Punkt weg,

00:57:20.360 --> 00:57:22.560
dann machst du r-r-slash und dann

00:57:22.560 --> 00:57:24.440
Ja,

00:57:24.440 --> 00:57:26.560
dann, äh. Immer alles als

00:57:26.560 --> 00:57:28.600
Super-User machen. Muss man hoffen, dass

00:57:28.600 --> 00:57:30.340
das nicht nur das Backup immer funktioniert hat, sondern

00:57:30.340 --> 00:57:31.880
dass das Restore auch mal funktioniert.

00:57:31.880 --> 00:57:34.100
Ja.

00:57:34.100 --> 00:57:36.640
Äh, genau. Äh, ja.

00:57:36.640 --> 00:57:38.520
Ähm, ich verwende hier

00:57:38.520 --> 00:57:40.220
einfach so, äh, irgendwie so

00:57:40.220 --> 00:57:42.940
Download-from-URL-Funktion,

00:57:42.940 --> 00:57:44.600
die benutzt TQDM

00:57:44.600 --> 00:57:46.400
um, äh, das ist,

00:57:46.400 --> 00:57:48.420
das ist eine sehr schöne Library, mit der man halt so

00:57:48.520 --> 00:57:50.500
Progress-Bars ganz gut hinkriegt. Man kann eigentlich alle

00:57:50.500 --> 00:57:52.380
Iteratoren irgendwie damit rappen. Ja, man braucht nur

00:57:52.380 --> 00:57:53.660
ein Iterat-Bar und, genau.

00:57:53.660 --> 00:57:56.480
Und das ist, das ist auch sehr,

00:57:56.480 --> 00:57:58.140
sehr hübsch, dann sieht man ungefähr, wo man ist.

00:57:58.140 --> 00:58:00.060
Äh, und, äh, ja.

00:58:00.060 --> 00:58:02.380
Ja, und jetzt hat das, äh, irgendwie

00:58:02.380 --> 00:58:04.480
dieses Dataset halt, äh, irgendwie so ein, so ein

00:58:04.480 --> 00:58:05.480
Data-Verzeichnis geschrieben.

00:58:05.480 --> 00:58:08.560
Dann, und das ist halt auch irgendwie das Tolle bei Python,

00:58:08.560 --> 00:58:10.720
dass man, äh, irgendwie einen Riesenhaufen Funktionalität

00:58:10.720 --> 00:58:12.440
schon, äh, in der Standard-Library mit

00:58:12.440 --> 00:58:14.420
drin hat, äh, ist eben auch sowas drin

00:58:14.420 --> 00:58:16.520
wie tar-File, ne, dass man halt mit, mit, mit

00:58:16.520 --> 00:58:18.200
tar, äh, äh,

00:58:18.440 --> 00:58:20.520
Archiven halt direkt, äh, irgendwie umgehen kann

00:58:20.520 --> 00:58:22.380
und, ja, dem kann man dann halt einfach

00:58:22.380 --> 00:58:23.720
sagen, okay, pack doch mal alles aus.

00:58:23.720 --> 00:58:26.000
Und, ähm,

00:58:26.000 --> 00:58:28.300
ja, dann, äh.

00:58:28.300 --> 00:58:30.280
Dann haben wir einen Pickel gebaut, oder? Du hast einen Pickel gebaut. Genau, dann

00:58:30.280 --> 00:58:32.840
parse ich das Ganze auf und, äh,

00:58:32.840 --> 00:58:34.400
pickel das wieder raus, sozusagen, damit ich

00:58:34.400 --> 00:58:36.440
dieses Parsen nicht jedes Mal machen muss. An der Stelle hier ist es

00:58:36.440 --> 00:58:38.240
relativ egal, weil das ist so schnell. Also,

00:58:38.240 --> 00:58:40.220
Pickel speichert einfach das Python-Objekt in der Binary

00:58:40.220 --> 00:58:42.340
einfach, also als Binär-Daten auf

00:58:42.340 --> 00:58:44.380
der Platte in einem Objekt und kann es genauso wieder einlesen. Genau.

00:58:44.380 --> 00:58:46.540
Pickel ist auch ein Modul aus der Standard-Bibliothek,

00:58:46.540 --> 00:58:48.360
genau, und es serialisiert einfach

00:58:48.360 --> 00:58:50.520
äh, Python-Objekte, beliebige Python-Objekte

00:58:50.520 --> 00:58:51.920
einfach auf, ja, in ein

00:58:51.920 --> 00:58:54.360
Format, das man dann halt auf die Platte schreiben kann und

00:58:54.360 --> 00:58:56.380
hinterher auch wieder lesen kann. Und es ist

00:58:56.380 --> 00:58:57.540
halt relativ schnell. Also,

00:58:57.540 --> 00:59:00.240
CSV, äh, genau, ist oft das,

00:59:00.240 --> 00:59:02.120
was man bekommt und das, was am meisten

00:59:02.120 --> 00:59:04.200
verwendet wird und, äh, ja, Pandas

00:59:04.200 --> 00:59:06.280
Reads CSV-Funktion ist sicherlich so eine der

00:59:06.280 --> 00:59:08.400
wichtigsten. Aber

00:59:08.400 --> 00:59:10.040
das ist halt nicht schnell, äh,

00:59:10.040 --> 00:59:12.200
sondern das ist halt irgendwie so, ja,

00:59:12.200 --> 00:59:14.320
sagen wir mal, weiß ich nicht,

00:59:14.320 --> 00:59:16.240
vielleicht 50 MB pro

00:59:16.240 --> 00:59:18.220
Sekunde oder sowas da so durchgeht. Kommt darauf an,

00:59:18.280 --> 00:59:19.400
wie komplex das CSV ist.

00:59:19.400 --> 00:59:22.280
Und gut, für die meisten Datensätze ist das vielleicht

00:59:22.280 --> 00:59:24.180
auch, oder was die meisten Leute so haben, auch

00:59:24.180 --> 00:59:26.180
schnell genug, dass das halt irgendwie nicht so

00:59:26.180 --> 00:59:28.520
furchtbar merkbare Wartezeiten

00:59:28.520 --> 00:59:30.240
erzeugt, aber wenn man

00:59:30.240 --> 00:59:32.180
jetzt so ein paar Gigabyte, äh, einlesen will, dann ist

00:59:32.180 --> 00:59:34.140
das schon, dann muss man bei CSV schon immer warten.

00:59:34.140 --> 00:59:36.200
Und, äh, was ich da oft

00:59:36.200 --> 00:59:38.180
auch mache, ist halt die, äh, wenn ich CSVs

00:59:38.180 --> 00:59:40.300
habe, die, ähm, zuerst

00:59:40.300 --> 00:59:42.460
irgendwie in DataFrame einzulesen mit ReadCSV

00:59:42.460 --> 00:59:44.180
und dann halt nochmal, äh,

00:59:44.180 --> 00:59:45.640
irgendwie ein Pickel-File davon zu cachen,

00:59:45.640 --> 00:59:48.200
weil das Pickel, äh, liest halt

00:59:48.200 --> 00:59:50.100
äh, quasi mit Plattengeschwindigkeit, also

00:59:50.100 --> 00:59:52.160
da kann man auch so ein Gigabyte pro

00:59:52.160 --> 00:59:54.260
Sekunde lesen. Das, das, dann

00:59:54.260 --> 00:59:56.100
dauert das halt, wenn man, wenn man halt so ein

00:59:56.100 --> 00:59:58.060
DataFrame, der halt irgendwie zwei, drei Gigabyte groß ist,

00:59:58.060 --> 00:59:59.940
äh, äh, äh, liest, der, der

00:59:59.960 --> 01:00:29.940
und Jochen unterhalten sich über die Programmiersprache Python

01:00:29.960 --> 01:00:56.140
und Jochen unterhalten sich über die Programmiersprache Python

01:00:56.140 --> 01:00:59.940
und Jochen unterhalten sich über die Programmiersprache Python

01:00:59.940 --> 01:00:59.940
und Jochen unterhalten sich über die Programmiersprache Python

01:00:59.940 --> 01:00:59.940
und Jochen unterhalten sich über die Programmiersprache Python

01:00:59.940 --> 01:00:59.940
und Jochen unterhalten sich über die Programmiersprache Python

01:00:59.940 --> 01:01:29.920
und Jochen unterhalten sich über die Programmiersprache Python

01:01:29.920 --> 01:01:59.900
und Jochen unterhalten sich über die Programmiersprache Python

01:01:59.900 --> 01:02:29.880
und Jochen unterhalten sich über die Programmiersprache Python

01:02:29.880 --> 01:02:59.860
und Jochen unterhalten sich über die Programmiersprache Python

01:02:59.860 --> 01:03:29.840
und Jochen unterhalten sich über die Programmiersprache Python

01:03:29.860 --> 01:03:57.860
und Jochen unterhalten sich über die Programmiersprache Python

01:03:57.860 --> 01:03:57.920
und Jochen unterhalten sich über die Programmiersprache Python

01:03:57.920 --> 01:03:58.000
und Jochen unterhalten sich über die Programmiersprache Python

01:03:58.000 --> 01:03:58.020
und Jochen unterhalten sich über die Programmiersprache Python

01:03:58.020 --> 01:03:58.120
und Jochen unterhalten sich über die Programmiersprache Python

01:03:58.120 --> 01:03:58.180
und Jochen unterhalten sich über die Programmiersprache Python

01:03:58.180 --> 01:03:58.340
und Jochen unterhalten sich über die Programmiersprache Python

01:03:58.340 --> 01:03:58.400
und Jochen unterhalten sich über die Programmiersprache Python

01:03:58.400 --> 01:03:58.500
und Jochen unterhalten sich über die Programmiersprache Python

01:03:58.500 --> 01:03:58.540
und Jochen unterhalten sich über die Programmiersprache Python

01:03:58.540 --> 01:03:58.580
und Jochen unterhalten sich über die Programmiersprache Python

01:03:58.580 --> 01:03:58.580
und Jochen unterhalten sich über die Programmiersprache Python

01:03:58.580 --> 01:03:58.640
und Jochen unterhalten sich über die Programmiersprache Python

01:03:58.640 --> 01:04:28.620
und Jochen unterhalten sich über die Programmiersprache Python

01:04:28.620 --> 01:04:28.620
und Jochen unterhalten sich über die Programmiersprache Python

01:04:28.620 --> 01:04:28.620
und Jochen unterhalten sich über die Programmiersprache Python

01:04:28.620 --> 01:04:28.620
und Jochen unterhalten sich über die Programmiersprache Python

01:04:28.620 --> 01:04:28.620
und Jochen unterhalten sich über die Programmiersprache Python

01:04:28.620 --> 01:04:28.620
und Jochen unterhalten sich über die Programmiersprache Python

01:04:28.620 --> 01:04:28.620
und Jochen unterhalten sich über die Programmiersprache Python

01:04:28.620 --> 01:04:28.620
und Jochen unterhalten sich über die Programmiersprache Python

01:04:28.620 --> 01:04:28.620
und Jochen unterhalten sich über die Programmiersprache Python

01:04:28.620 --> 01:04:28.620
und Jochen unterhalten sich über die Programmiersprache Python

01:04:28.620 --> 01:04:58.600
und Jochen unterhalten sich über die Programmiersprache Python

01:04:58.600 --> 01:05:28.580
und Jochen unterhalten sich über die Programmiersprache Python

01:05:28.580 --> 01:05:58.560
und Jochen unterhalten sich über die Programmiersprache Python

01:05:58.560 --> 01:06:28.540
und Jochen unterhalten sich über die Programmiersprache Python

01:06:28.540 --> 01:06:58.520
und Jochen unterhalten sich über die Programmiersprache Python

01:06:58.520 --> 01:07:28.500
und Jochen unterhalten sich über die Programmiersprache Python

01:07:28.500 --> 01:07:28.580
und Jochen unterhalten sich über die Programmiersprache Python

01:07:28.580 --> 01:07:58.480
und Jochen unterhalten sich über die Programmiersprache Python

01:07:58.480 --> 01:08:28.460
und Jochen unterhalten sich über die Programmiersprache Python

01:08:28.460 --> 01:08:58.440
und Jochen unterhalten sich über die Programmiersprache Python

01:08:58.460 --> 01:09:28.440
und Jochen unterhalten sich über die Programmiersprache Python

01:09:28.460 --> 01:09:53.340
und Jochen unterhalten sich über die Programmiersprache Python

01:09:53.340 --> 01:09:53.420
und Jochen unterhalten sich über die Programmiersprache Python

01:09:53.420 --> 01:09:53.500
und Jochen unterhalten sich über die Programmiersprache Python

01:09:53.500 --> 01:09:53.520
und Jochen unterhalten sich über die Programmiersprache Python

01:09:53.520 --> 01:09:57.560
und im Grunde, wenn man jetzt, also bei Scikit-Learn ist es jedenfalls so,

01:09:57.560 --> 01:09:57.620
und im Grunde, wenn man jetzt, also bei Scikit-Learn ist es jedenfalls so,

01:09:57.620 --> 01:09:57.620
und im Grunde, wenn man jetzt, also bei Scikit-Learn ist es jedenfalls so,

01:09:57.620 --> 01:09:57.660
und im Grunde, wenn man jetzt, also bei Scikit-Learn ist es jedenfalls so,

01:09:57.660 --> 01:09:57.760
und im Grunde, wenn man jetzt, also bei Scikit-Learn ist es jedenfalls so,

01:09:57.760 --> 01:09:57.820
und im Grunde, wenn man jetzt, also bei Scikit-Learn ist es jedenfalls so,

01:09:57.820 --> 01:10:02.820
eigentlich orientieren sich fast alle anderen Maschinen-Learning-Bibliotheken,

01:10:02.820 --> 01:10:02.880
eigentlich orientieren sich fast alle anderen Maschinen-Learning-Bibliotheken,

01:10:02.880 --> 01:10:02.900
eigentlich orientieren sich fast alle anderen Maschinen-Learning-Bibliotheken,

01:10:02.900 --> 01:10:07.800
die es so gibt, auch an der entsprechenden API von Scikit-Learn,

01:10:07.800 --> 01:10:11.680
ist die Estimator-API für Modelle eben,

01:10:11.680 --> 01:10:15.880
da übergibt man immer Arrays, also NumPy-Arrays.

01:10:15.880 --> 01:10:18.760
Und sowas wie Listen oder so kann man da nicht übergeben.

01:10:18.760 --> 01:10:23.300
Das heißt, man muss erstmal das so in Format bringen,

01:10:23.300 --> 01:10:25.740
dass man das überhaupt den entsprechenden Modellen übergeben kann.

01:10:25.740 --> 01:10:27.800
Und für Multilabel ist es eben so,

01:10:27.820 --> 01:10:31.900
dass das richtige Format dann halt ist,

01:10:31.900 --> 01:10:35.580
ein NumPy-Array zu haben,

01:10:35.580 --> 01:10:40.980
das halt auch wieder genauso viele Zeilen hat,

01:10:40.980 --> 01:10:42.620
wie man in der Feature-Matrix hat,

01:10:42.620 --> 01:10:45.100
oder eben genauso viele Zeilen, wie es eben Dokumente gibt,

01:10:45.100 --> 01:10:46.820
die zum Training-Set gehören,

01:10:46.820 --> 01:10:53.580
und dann so viel spalten, wie es Kategorien gibt,

01:10:53.580 --> 01:10:57.280
oder Labels gibt, in denen ein Dokument liegen kann,

01:10:57.280 --> 01:11:01.940
und sozusagen die, für jede Spalte gibt es dann halt sozusagen,

01:11:01.940 --> 01:11:03.420
also jede Spalte ist halt eine Kategorie,

01:11:03.420 --> 01:11:05.920
und wenn da ein 0 drinsteht, bedeutet das im Grunde,

01:11:05.920 --> 01:11:08.020
dass das Dokument liegt nicht in dieser Kategorie,

01:11:08.020 --> 01:11:09.060
oder hat dieses Tag eben nicht.

01:11:09.060 --> 01:11:11.020
Wenn da ein 1 drinsteht, dann heißt das,

01:11:11.020 --> 01:11:15.420
okay, ja, das ist sozusagen die richtige Kategorie für dieses Dokument.

01:11:15.420 --> 01:11:22.280
Und genau, dafür gibt es aus dem Scikit-Learn-Pre-Processing-Modul

01:11:22.280 --> 01:11:24.600
halt ein Ding, das nennt sich Multilabel-Binarizer,

01:11:24.600 --> 01:11:26.740
und dem gibt man einfach diese Liste von Listen,

01:11:26.740 --> 01:11:33.180
und dann spuckt das halt ein richtig formatiertes NumPy-Array aus.

01:11:33.180 --> 01:11:34.400
Also das ist auch sowas.

01:11:34.400 --> 01:11:36.880
Also diese ganze Transformation, das muss man nicht selber machen.

01:11:36.880 --> 01:11:39.240
Da gibt es eigentlich für alle Geschichten, die man da so haben kann,

01:11:39.240 --> 01:11:42.320
fertige Lösungen schon.

01:11:42.320 --> 01:11:43.820
Ja, man kann sich, glaube ich, auch aussuchen,

01:11:43.820 --> 01:11:45.520
was dann mit den Werten, die da nicht reinpassen,

01:11:45.520 --> 01:11:46.700
irgendwie geschehen soll und sowas.

01:11:46.700 --> 01:11:49.040
Ja, ja, bestimmt.

01:11:49.040 --> 01:11:51.820
Ich weiß jetzt gar nicht genau, was der Multilabel-Binarizer

01:11:51.820 --> 01:11:52.560
da sonst auch so macht.

01:11:52.560 --> 01:11:54.540
Und langfristig ist es vor allem auch nicht sinnvoll,

01:11:54.540 --> 01:11:55.260
sich das zu machen.

01:11:55.260 --> 01:11:56.720
Also am Anfang, wenn man das noch nie gemacht hat,

01:11:56.740 --> 01:11:57.340
denkt man so,

01:11:57.340 --> 01:12:00.420
also man muss ja schon auch einmal erstmal durchsteigen,

01:12:00.420 --> 01:12:01.900
wie das überhaupt alles funktioniert,

01:12:01.900 --> 01:12:05.380
mit diesen Transform-Prozessen und den Modellen und so weiter.

01:12:05.380 --> 01:12:06.520
Und dann denkt man,

01:12:06.520 --> 01:12:07.980
ich will doch eigentlich nur so ein Modell benutzen,

01:12:07.980 --> 01:12:09.640
ich kann den ganzen Rest auch von Hand machen

01:12:09.640 --> 01:12:11.880
und fängt damit gerne erstmal an,

01:12:11.880 --> 01:12:13.520
weil man auch gerne ein bisschen programmiert

01:12:13.520 --> 01:12:15.560
und nicht ewig Doku liest.

01:12:15.560 --> 01:12:18.580
Aber faktisch ist man halt letztendlich dann doch viel schneller,

01:12:18.580 --> 01:12:20.100
wenn man sich das halt einmal aneignet,

01:12:20.100 --> 01:12:22.100
wie denn diese Binarizer und so weiter funktionieren.

01:12:22.100 --> 01:12:23.360
Ja.

01:12:23.360 --> 01:12:26.080
Genau.

01:12:26.740 --> 01:12:27.260
Ja.

01:12:27.260 --> 01:12:31.440
Und dann hat man quasi das gleiche Problem,

01:12:31.440 --> 01:12:32.940
nur irgendwie ein bisschen anders.

01:12:32.940 --> 01:12:36.120
Auf der Feature-Matrix-Seite halt eben auch,

01:12:36.120 --> 01:12:37.460
weil man hatte erstmal Text.

01:12:37.460 --> 01:12:41.180
Den kann man jetzt so in ein Modell nicht reinwerfen,

01:12:41.180 --> 01:12:44.100
weil, ja, ist halt,

01:12:44.100 --> 01:12:48.120
also letztlich ist eine Feature-Matrix eigentlich immer,

01:12:48.120 --> 01:12:54.900
sollten das eigentlich immer mehr oder weniger Float-Werte sein,

01:12:54.900 --> 01:12:56.080
die da letztlich drin landen.

01:12:56.080 --> 01:12:56.720
Und das ist halt,

01:12:56.740 --> 01:12:58.960
das ist halt ein NumPy-Array von irgendwie Float-Geschichten

01:12:58.960 --> 01:13:00.000
und das ist Text halt nicht.

01:13:00.000 --> 01:13:04.900
Man muss jetzt erstmal Text irgendwie in Zahlen irgendwie umwandeln

01:13:04.900 --> 01:13:07.020
und das ist halt schon so eine Art,

01:13:07.020 --> 01:13:08.300
man nennt das halt Feature-Extraktion.

01:13:08.300 --> 01:13:17.060
Also man macht sozusagen aus Text irgendwie eine Reihe von Features,

01:13:17.060 --> 01:13:19.400
also Spalten in der Feature-Matrix.

01:13:19.400 --> 01:13:25.860
Und so eine ganz, ja, alte Standard-Methode,

01:13:25.860 --> 01:13:26.720
wie man das halt tun kann,

01:13:26.740 --> 01:13:33.420
ist einmal, man repräsentiert Text halt als Back-of-Words,

01:13:33.420 --> 01:13:34.040
nennt sich das.

01:13:34.040 --> 01:13:40.160
Das bedeutet, man wirft die Reihenfolge-Informationen da weiter weg,

01:13:40.160 --> 01:13:42.860
was irgendwie schlimm klingt, aber dann doch nicht so schlimm ist.

01:13:42.860 --> 01:13:47.800
Und merkt sich sozusagen, also jede,

01:13:47.800 --> 01:13:50.040
man kann sich das ungefähr so vorstellen,

01:13:50.040 --> 01:13:53.820
man hat jetzt, ja, weiß nicht, ob das eine gute Idee ist zu sagen,

01:13:53.820 --> 01:13:55.380
man sollte sich das wie eine Excel-Tabelle vorstellen.

01:13:55.380 --> 01:13:56.240
Wahrscheinlich nicht.

01:13:56.740 --> 01:13:59.820
Aber das hat jemand schon niemals, wahrscheinlich schon gesehen.

01:13:59.820 --> 01:14:00.620
Also warum nicht?

01:14:00.620 --> 01:14:04.600
Ja, es ist auch so ein bisschen so ähnlich wie bei den Labels.

01:14:04.600 --> 01:14:06.480
Es ist auch so eine Art One-Hot-Encoding.

01:14:06.480 --> 01:14:10.860
Man hat halt pro Spalte quasi, also man macht eine Spalte pro Wort.

01:14:10.860 --> 01:14:17.320
Und wenn das Wort in dem Text vorkommt, dann macht man da eine Eins rein,

01:14:17.320 --> 01:14:19.820
ansonsten macht man da ein Null rein in die Spalten.

01:14:19.820 --> 01:14:21.560
Also man hat sozusagen so viele Spalten,

01:14:21.560 --> 01:14:24.800
wie es überhaupt unterschiedliche Worte im gesamten Dokument-Korpus gibt.

01:14:24.800 --> 01:14:26.720
Also über alle Dokumente drüber.

01:14:26.740 --> 01:14:31.660
Wobei Back-of-Words macht doch schon auch die Anzahl gleich rein, oder?

01:14:31.660 --> 01:14:33.780
Ja, ich weiß nicht.

01:14:33.780 --> 01:14:35.040
Man kann auch die Anzahl direkt rein.

01:14:35.040 --> 01:14:38.940
Also der einfachste Fall wäre, dass man einfach nur reinschreibt,

01:14:38.940 --> 01:14:40.440
ist es da oder nicht, wie näher.

01:14:40.440 --> 01:14:47.980
Und genau, dann die nächste etwas,

01:14:47.980 --> 01:14:51.220
also das funktioniert auch schon erstaunlich gut.

01:14:51.220 --> 01:14:55.140
Aber das hat halt auch diverse Probleme.

01:14:55.140 --> 01:14:56.640
Unter anderem ist es halt so,

01:14:56.700 --> 01:14:57.940
dass längere Texte natürlich viel,

01:14:57.940 --> 01:15:04.140
bei denen steigt die Wahrscheinlichkeit,

01:15:04.140 --> 01:15:05.460
dass sie in allen möglichen Kategorien sind.

01:15:05.460 --> 01:15:07.660
Einfach deswegen, weil eine Menge Worte darin auftauchen,

01:15:07.660 --> 01:15:10.040
die halt in allen möglichen Kategorien auftauchen.

01:15:10.040 --> 01:15:12.180
Oder derjenige, die den Nachrichtenbeitrag geschrieben hat,

01:15:12.180 --> 01:15:13.380
war SEO-Experte oder so.

01:15:13.380 --> 01:15:14.780
Ja, ja, genau.

01:15:14.780 --> 01:15:20.700
Das wäre halt etwas, was man versuchen wollen würde zu verhindern,

01:15:20.700 --> 01:15:22.220
dass das halt so eine große Auswirkung hat,

01:15:22.220 --> 01:15:25.680
wenn da irgendwie eine lange Liste von vielen unterschiedlichen Worten drinsteht.

01:15:26.700 --> 01:15:31.100
Und das ist eine klassische Methode, die man da verwendet.

01:15:31.100 --> 01:15:34.200
Es kommt auch aus dem Information-Retrieval-Bereich.

01:15:34.200 --> 01:15:38.000
Es ist halt einmal zu zählen, wie oft ein Wort drin vorkommt.

01:15:38.000 --> 01:15:40.200
Das braucht man halt vor allen Dingen deswegen,

01:15:40.200 --> 01:15:44.400
weil man damit mit der Information, wie oft kommt ein Wort in dem Text vor,

01:15:44.400 --> 01:15:47.100
plus wie lang ist der Text, kann man halt die Frequenz ausrechnen.

01:15:47.100 --> 01:15:50.800
Also sozusagen, wie ist die Frequenz von dem Wort in dem Text.

01:15:50.800 --> 01:15:52.800
Das ist einfach nur die Anzahl, wie oft kommt es vor,

01:15:52.800 --> 01:15:54.100
geteilt durch die Länge des Textes.

01:15:54.100 --> 01:15:56.380
Und das funktioniert auch.

01:15:56.660 --> 01:15:57.760
Das funktioniert auch schon besser.

01:15:57.760 --> 01:16:00.360
Also da könnte man dann irgendwie einen Count-Vectorizer nehmen.

01:16:00.360 --> 01:16:05.460
Der würde halt dann zählen, nicht nur binär irgendwie einen großen Vektor bauen,

01:16:05.460 --> 01:16:08.660
in dem einzelne Nullen drinstehen, je nachdem, ob ein Wort drin vorkommt oder nicht.

01:16:08.660 --> 01:16:10.760
Das wäre dann schon die Term-Frequency, oder?

01:16:10.760 --> 01:16:12.860
Ja, damit hätte man erst mal nur die Counts.

01:16:12.860 --> 01:16:15.160
Und dann, ich weiß nicht, ob es noch einen...

01:16:15.160 --> 01:16:18.660
Aber es gibt keinen Vectorizer, der dann nur Term-Frequenz macht,

01:16:18.660 --> 01:16:23.560
sondern dann würde man direkt so etwas nehmen wie TF-EDF-Vectorizer.

01:16:23.560 --> 01:16:25.360
Das Problem bei der Term-Frequenz ist halt...

01:16:25.360 --> 01:16:26.560
Ich glaube, das habt ihr alle ein bisschen verstanden.

01:16:26.660 --> 01:16:27.660
Ich habe mich ein bisschen abgehängt.

01:16:27.660 --> 01:16:28.760
Erst mal, was ist ein Term-Vectorizer?

01:16:28.760 --> 01:16:29.760
Was ist ein TF-ID?

01:16:29.760 --> 01:16:36.760
Ja, also im Grunde kann man eigentlich direkt mit dem TF-EDF einsteigen.

01:16:36.760 --> 01:16:43.760
Wenn man sich jetzt einen Vector anguckt, wo nur drinsteht, ob ein Wort in einem Text vorkommt oder nicht,

01:16:43.760 --> 01:16:47.760
also da stehen nur Einsen und Nullen drin, dann ist das halt schlecht.

01:16:47.760 --> 01:16:50.760
Man möchte eigentlich ein anderes Gewicht darinstehen haben für Worte,

01:16:50.760 --> 01:16:56.560
weil halt manche Worte sind halt wichtiger oder charakteristischer für eine Kategorie als andere.

01:16:56.660 --> 01:17:00.060
Wenn ich die Kategorie Politik habe und da kommt irgendwie Parlament drin vor,

01:17:00.060 --> 01:17:07.260
dann ist das sozusagen dafür irgendwie eine aussagekräftigere Geschichte,

01:17:07.260 --> 01:17:12.760
als wenn jetzt das Wort "das" drin vorkommt oder so, was einfach in jedem Text vorkommt.

01:17:12.760 --> 01:17:17.260
Und wenn man jetzt einfach nur einen Einsen und Nullen reinschreibt,

01:17:17.260 --> 01:17:19.460
dann würde das aber gleich behandelt irgendwie.

01:17:19.460 --> 01:17:22.260
Und das kann ja nicht so richtig sein.

01:17:22.260 --> 01:17:26.560
Und die Methode, mit der man das versucht, besser zu machen,

01:17:26.760 --> 01:17:31.560
ist uralt, ich glaube mittlerweile, ja, über 40 Jahre alt.

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

01:17:38.560 --> 01:17:44.560
TF-EDF, vor allen Dingen für Suchmaschinen entwickelt, da möchte man das halt auch haben,

01:17:44.560 --> 01:17:50.560
man hat halt einen Query und möchte dazu die relevantesten Dokumente irgendwie rausfiltern.

01:17:50.560 --> 01:17:56.560
Und dieses Gewichtungsdienst nennt sich halt,

01:17:56.760 --> 01:18:02.560
TF-EDF, also Term Frequency mal Inverse Document Frequency.

01:18:02.560 --> 01:18:07.560
Term Frequency ist einfach nur die Frequenz von dem Wort in dem Text,

01:18:07.560 --> 01:18:10.560
also das ist einfach nur Count, wie oft kommt das Wort vor,

01:18:10.560 --> 01:18:12.560
in dem Text geteilt durch wie lang ist der Text,

01:18:12.560 --> 01:18:20.560
mal Logarithmus von...

01:18:20.560 --> 01:18:23.560
Ja, genau, ich kann den an der Stelle auch nicht genau...

01:18:23.560 --> 01:18:26.560
Geteilt durch wie oft kommt das Wort irgendwie

01:18:26.660 --> 01:18:31.560
in allen Texten vor, sozusagen, also das Ding wird halt höher, je höher, desto seltener es ist, also sozusagen...

01:18:31.560 --> 01:18:35.560
Und man nimmt dann mal den Logarithmus, damit es nicht ganz so schlimm wird, damit es halt so ein bisschen...

01:18:35.560 --> 01:18:36.560
Ein bisschen flacher wird.

01:18:36.560 --> 01:18:41.560
Genau, genau, weil man möchte halt auch nicht so total krasse Unterschiede haben,

01:18:41.560 --> 01:18:43.560
das soll sich so ein bisschen auswirken, aber...

01:18:43.560 --> 01:18:48.560
Genau, das ist vom Prinzip her die Spezifität des Wortes, also wie charakteristisch...

01:18:48.560 --> 01:18:52.560
Wie ist das ein Wort, das ständig vorkommt oder was halt eben relativ selten vorkommt,

01:18:52.560 --> 01:18:56.560
gewichtet mit wie häufig kommt dieses Wort in dem Text vor,

01:18:56.660 --> 01:18:58.560
das ist ja ein ganz gutes Maß darüber...

01:18:58.560 --> 01:19:01.560
Ja, ist das speziell für diese Kategorie, da oder nicht, ja.

01:19:01.560 --> 01:19:02.560
Genau.

01:19:02.560 --> 01:19:05.560
Ja, und da müsste man tatsächlich aber auch eine Datenbank haben,

01:19:05.560 --> 01:19:09.560
der alle Wörter irgendwo schon in gewisser Häufigkeit vorkommen, also zumindest die, die so allgemein rausfallen...

01:19:09.560 --> 01:19:14.560
Ja, das ist natürlich so eine interessante Geschichte, wie kommt man an diese Gewichte eigentlich ran,

01:19:14.560 --> 01:19:20.560
und wenn man jetzt zum Beispiel irgendwie das mit dem Cross-Validation und Trennen in Trainings- und Testsets selber machen würde,

01:19:20.560 --> 01:19:26.560
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,

01:19:26.760 --> 01:19:34.560
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?

01:19:34.560 --> 01:19:35.560
Ja, also vor allem...

01:19:35.560 --> 01:19:36.560
Darf man das machen?

01:19:36.560 --> 01:19:41.560
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,

01:19:41.560 --> 01:19:47.560
ist ja dann auch irgendwie doof, weil dann die Sachen, die schief drin liegen, dann überprofessionell darin vertreten sind,

01:19:47.560 --> 01:19:50.560
und du vielleicht von den Sachen, die da selten drin sind, nicht so viele...

01:19:50.560 --> 01:19:55.560
Genau, aber dieses Problem, was du gerade sagst, mit dem Training und den Tester, das ist halt wirklich so ein klassisches...

01:19:55.660 --> 01:20:04.560
Also du hast eigentlich nur zwei Optionen, entweder ich sage, ich trainiere mein TF-IDF auf allen meinen Daten, auch vom Test-Set,

01:20:04.560 --> 01:20:11.560
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,

01:20:11.560 --> 01:20:17.560
also das heißt einfach, die Daten, die mir eigentlich ja potenziell unbekannt sind, ich will ja nachher auf Daten generalisieren,

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

01:20:24.660 --> 01:20:31.560
dann tue ich so, als würde ich diese Information eigentlich nicht kennen, aber in Wirklichkeit habe ich sie ja doch irgendwie verarbeitet.

01:20:31.560 --> 01:20:36.560
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,

01:20:36.560 --> 01:20:43.560
und dann habe ich dazu quasi keinen IDF-Score, keinen validen, genau, und dann gibt es halt im Endeffekt...

01:20:43.560 --> 01:20:52.560
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...

01:20:52.660 --> 01:20:57.560
Also für so eine Generalität von Wörtern könntest du jetzt auch ein öffentliches Datenset benutzen.

01:20:57.560 --> 01:20:58.560
Wikipedia oder sowas.

01:20:58.560 --> 01:21:08.560
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

01:21:08.560 --> 01:21:14.560
und viel unspezifischer, als es bei dir jetzt im Wort vielleicht wäre, also bei dir in deinen Daten vielleicht wäre.

01:21:14.560 --> 01:21:18.560
Genau, also es ist auch wieder so ein Abwägungsding, wie geht man damit um?

01:21:18.560 --> 01:21:20.560
Ja.

01:21:20.660 --> 01:21:34.560
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.

01:21:34.560 --> 01:21:41.560
Äh, wir fitten das nur auf den Trainingsdaten und transformieren nur die Testdaten, also sozusagen, ja.

01:21:41.560 --> 01:21:48.560
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,

01:21:48.660 --> 01:21:58.560
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,

01:21:58.560 --> 01:22:06.560
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...

01:22:06.560 --> 01:22:09.560
Trainingsdaten sind das, was dein Modell besser macht.

01:22:09.560 --> 01:22:10.560
Ja, genau.

01:22:10.560 --> 01:22:11.560
Testdaten...

01:22:11.560 --> 01:22:12.560
Also, das meinte ich mit...

01:22:12.560 --> 01:22:14.560
Achso, ich hab's gerade nochmal verwechselt wahrscheinlich.

01:22:14.560 --> 01:22:15.560
Ja, okay, ja, genau.

01:22:15.560 --> 01:22:17.560
Je mehr Trainingsdaten hast, desto besser, aber...

01:22:17.660 --> 01:22:23.560
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...

01:22:23.560 --> 01:22:27.560
Nee, aber Wikipedia ist ja jetzt für deinen Anwendungsfall nicht gelabelt.

01:22:27.560 --> 01:22:29.560
Ja, genau, wenn ich das gelabelt hätte, das war ja dann...

01:22:29.560 --> 01:22:36.560
Und das ist natürlich wahrscheinlich immer anders, das ist halt das Problem, das ist anders verteilt, als das, was du irgendwie benutzen willst.

01:22:36.560 --> 01:22:40.560
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.

01:22:40.560 --> 01:22:41.560
Ja, klar.

01:22:41.560 --> 01:22:46.560
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.

01:22:46.660 --> 01:22:53.560
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.

01:22:53.560 --> 01:23:00.560
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.

01:23:00.560 --> 01:23:13.560
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.

01:23:13.560 --> 01:23:15.560
Wenn ich dann allerdings wirklich mein Modell trainiere, dann...

01:23:15.660 --> 01:23:24.560
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.

01:23:24.560 --> 01:23:44.560
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.

01:23:44.660 --> 01:24:08.560
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...

01:24:08.560 --> 01:24:14.560
Ja, was man mit Word-Embeddings macht...

01:24:14.560 --> 01:24:14.560
Ja, was man mit Word-Embeddings macht...

01:24:14.560 --> 01:24:14.560
Ja, was man mit Word-Embeddings macht...

01:24:14.560 --> 01:24:14.640
Ja, was man mit Word-Embeddings macht...

01:24:14.660 --> 01:24:44.560
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.

01:24:44.560 --> 01:24:53.300
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...

01:24:53.300 --> 01:25:14.460
Ja, wie kommen die da an die gleiche Stelle in diesem Vektorraum? Das habe ich jetzt noch nicht ganz...

01:25:14.460 --> 01:25:26.180
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.

01:25:26.180 --> 01:25:28.340
Wo würde ich solche Modelle runterladen?

01:25:28.340 --> 01:25:32.980
Ja, es gibt zum Beispiel Word-to-Vac, das Modell von Google, das kann man halt benutzen.

01:25:32.980 --> 01:25:36.380
Das ist nett, ist gern benutzt.

01:25:36.380 --> 01:25:44.360
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...

01:25:44.360 --> 01:25:46.620
Es sind auch diverse Webseiten mit drunter.

01:25:46.620 --> 01:25:48.360
Die einen oder andere.

01:25:48.360 --> 01:25:52.960
Ja, und das sind halt so ein paar Gigabyte, die man dann so runterladen kann.

01:25:52.960 --> 01:26:05.260
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

01:26:05.260 --> 01:26:14.260
und nimmt dann aber auch die Vektoren aus den Word-Embeddings, vieles Wort mit dazu, dann verbessert das halt irgendwie...

01:26:14.260 --> 01:26:16.660
Das ist irgendwie so ein Klassifikationsergebnis, schon deutlich.

01:26:16.660 --> 01:26:24.260
Aber da hat man halt auch das Problem, man weiß halt dann nicht, wenn man das jetzt einfach so diese vortrainierten Geschichten benutzt...

01:26:24.260 --> 01:26:32.940
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,

01:26:32.940 --> 01:26:37.280
auf so einer ganzen Sprache, auf so einer ganzen Grammatik und das Knowledge, das man dann irgendwie...

01:26:37.280 --> 01:26:44.160
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...

01:26:44.160 --> 01:26:47.200
Auf deine eigenen Daten machst und nicht die auf Wikipedia trainiert nimmst.

01:26:47.200 --> 01:26:53.640
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?

01:26:53.640 --> 01:27:03.340
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...

01:27:03.340 --> 01:27:07.700
Es gibt jetzt auch ein neueres Dataset, RCV1, und das heißt irgendwie, da sind dann 800.000 drin oder so.

01:27:07.700 --> 01:27:09.660
Ja.

01:27:09.660 --> 01:27:14.060
Genau. Aber wie gesagt, an der Stelle würde man...

01:27:14.060 --> 01:27:36.460
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.

01:27:36.460 --> 01:27:41.740
Da gibt es halt immer im Wesentlichen zwei Operationen. Es gibt eben Fit und Transform.

01:27:43.960 --> 01:28:02.900
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.

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

01:28:13.860 --> 01:28:23.700
Der nimmt dann quasi diesen selben, diese selbe Abbildungsmatrix von Wörtern zu Zahlen und überträgt die auf den neuen Text.

01:28:23.700 --> 01:28:33.300
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.

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

01:28:43.760 --> 01:29:08.740
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.

01:29:13.660 --> 01:29:21.780
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.

01:29:21.780 --> 01:29:25.740
Genau. Ja, was wollten wir machen?

01:29:25.740 --> 01:29:31.860
Ja, jetzt haben wir eigentlich unsere Zahlenmatrix. Eigentlich sind wir jetzt bereit, um darauf Modelle langsam zu trainieren, oder?

01:29:31.860 --> 01:29:43.560
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.

01:29:43.560 --> 01:29:47.620
Das habe ich getan, aber man kann ihm noch sagen, wie er es organisieren soll.

01:29:47.620 --> 01:29:51.200
Gewisse Stop-Wörter rauswerfen, was man auf jeden Fall machen würde, aber ja.

01:29:51.200 --> 01:29:59.940
Ja, genau. Und ob er halt irgendwie das noch irgendwie smoothen soll, oder ob man kann, welche Normen, man kann.

01:29:59.940 --> 01:30:00.840
alles mögliche angeben.

01:30:00.840 --> 01:30:02.840
Und

01:30:02.840 --> 01:30:05.980
genau, den habe ich in Trainingsdaten gefüttert

01:30:05.980 --> 01:30:08.120
und ich benutze jetzt die Transform-Methode,

01:30:08.120 --> 01:30:10.220
um damit sozusagen die Texte

01:30:10.220 --> 01:30:11.840
aus den

01:30:11.840 --> 01:30:13.440
Trainingsdaten und aus den Testdaten

01:30:13.440 --> 01:30:15.920
in so Feature-Matrizen zu

01:30:15.920 --> 01:30:17.760
verwandeln. Und

01:30:17.760 --> 01:30:18.620
genau,

01:30:18.620 --> 01:30:21.560
das sind dann hinterher

01:30:21.560 --> 01:30:23.880
ja,

01:30:23.880 --> 01:30:26.240
das ist auch nochmal so eine kleine Spezialität.

01:30:26.240 --> 01:30:29.800
Das ist jetzt natürlich

01:30:29.800 --> 01:30:31.800
das, was dabei rauskommt, hat

01:30:31.800 --> 01:30:33.980
relativ, also die Matrix, die da rauskommt,

01:30:33.980 --> 01:30:35.720
normalerweise muss man jetzt denken, da kommt einfach nur ein

01:30:35.720 --> 01:30:37.660
NumPy-Array raus, irgendwie

01:30:37.660 --> 01:30:39.920
Zahlen so viel, wie es Dokumente gibt,

01:30:39.920 --> 01:30:41.920
Spalten so viele, wie es Wörter gibt.

01:30:41.920 --> 01:30:43.780
Das Problem dabei ist

01:30:43.780 --> 01:30:44.440
natürlich so ein bisschen,

01:30:44.440 --> 01:30:47.820
die allermeisten Werte in dieser

01:30:47.820 --> 01:30:49.940
Tabelle sind null, weil ja die allermeisten

01:30:49.940 --> 01:30:50.980
Worte halt nicht in

01:30:50.980 --> 01:30:52.980
allen Texten vorkommen, sondern

01:30:52.980 --> 01:30:55.880
ja, also

01:30:55.880 --> 01:30:57.920
pro Text habe ich

01:30:57.920 --> 01:30:59.660
halt eine Teilmenge der Worte, die überhaupt vorkommen, aber

01:30:59.660 --> 01:31:00.680
eben nicht alle

01:31:00.680 --> 01:31:03.720
und die allermeisten kommen halt nicht in den Text vor.

01:31:03.720 --> 01:31:05.400
Also man hat ja natürlich, je mehr Nullen,

01:31:05.400 --> 01:31:06.500
je mehr Texte man hat.

01:31:06.500 --> 01:31:09.240
Je mehr unterschiedliche Wörter man hat.

01:31:09.240 --> 01:31:10.580
Ja, genau, richtig.

01:31:10.580 --> 01:31:14.020
Ja, genau, es ist ja dann wahrscheinlicher, dass du mehr Texte hast, dass du mehr unterschiedliche Wörter hast.

01:31:14.020 --> 01:31:15.440
Ja, wobei, also

01:31:15.440 --> 01:31:16.760
genau, wenn ich dann

01:31:16.760 --> 01:31:19.580
Texte habe, die alle sehr, sehr ähnlich sind, habe ich dann natürlich auch

01:31:19.580 --> 01:31:21.060
viele Einser vom Prinzip her.

01:31:21.060 --> 01:31:23.480
Das heißt einfach quasi, wie sparse ist

01:31:23.480 --> 01:31:24.780
meine Matrix, das Wort dafür.

01:31:24.780 --> 01:31:26.380
Genau, sparse.

01:31:26.380 --> 01:31:28.480
Die Daten sind halt

01:31:28.480 --> 01:31:29.520
sehr sparse und

01:31:29.520 --> 01:31:32.300
das ist halt ein Problem

01:31:32.300 --> 01:31:34.260
oder ist halt sehr verschwenderisch,

01:31:34.260 --> 01:31:36.440
was Hauptsprecher angeht, wenn man tatsächlich die Werte speichern

01:31:36.440 --> 01:31:38.300
würde. Und es gibt dann so

01:31:38.300 --> 01:31:40.680
ja, also ein SciPy

01:31:40.680 --> 01:31:42.500
Modul

01:31:42.500 --> 01:31:44.280
irgendwie gibt es dann Klassen, die

01:31:44.280 --> 01:31:46.240
sich halt mit Spars,

01:31:46.240 --> 01:31:48.240
mit dem Speichern von Sparsen Matrizen

01:31:48.240 --> 01:31:49.300
irgendwie beschäftigen.

01:31:49.300 --> 01:31:51.920
Und

01:31:51.920 --> 01:31:52.980
ja,

01:31:52.980 --> 01:31:54.880
da

01:31:54.880 --> 01:31:56.880
der Trick ist im Grunde, dass man halt die ganzen Nullen

01:31:56.880 --> 01:31:58.880
einfach nicht speichert. Dass man sagt, irgendwie man

01:31:58.880 --> 01:31:59.380
speichert

01:31:59.380 --> 01:32:01.620
nur, an welchen Stellen irgendwie

01:32:01.620 --> 01:32:03.440
Zahlen sind. Alles andere ist halt

01:32:03.440 --> 01:32:05.560
defaultmäßig null

01:32:05.560 --> 01:32:06.660
und muss man halt auch nicht speichern.

01:32:06.660 --> 01:32:09.340
Und man kann sich das auch im Grunde so vorstellen, also

01:32:09.340 --> 01:32:11.620
die interessante Operation, die man jetzt auf sowas

01:32:11.620 --> 01:32:13.380
ausführt, zum Beispiel wenn man jetzt eine Suchmaschine hat,

01:32:13.380 --> 01:32:15.360
würde man irgendwie eine

01:32:15.360 --> 01:32:16.160
Cosinus-Distanz

01:32:16.160 --> 01:32:19.500
ausrechnen zwischen einem Dokument und einer Query.

01:32:19.500 --> 01:32:21.020
Das heißt

01:32:21.020 --> 01:32:23.460
sozusagen einfach nur das Skalarprodukt. Man würde den

01:32:23.460 --> 01:32:24.800
Query in Vektor verwandeln,

01:32:24.800 --> 01:32:27.460
ein Dokument in Vektor

01:32:27.460 --> 01:32:29.240
verwandeln und dann bildet man einfach das Skalarprodukt.

01:32:29.240 --> 01:32:31.100
Zwischen den beiden. Und

01:32:31.100 --> 01:32:33.240
dafür muss man ja sozusagen nur die

01:32:33.240 --> 01:32:35.320
Teile miteinander multiplizieren, die nicht null sind.

01:32:35.320 --> 01:32:36.860
Weil

01:32:36.860 --> 01:32:38.960
die anderen sind alle eh null. Das wird

01:32:38.960 --> 01:32:41.100
aufsummiert. Also es ist

01:32:41.100 --> 01:32:42.840
einfach weg. Und

01:32:42.840 --> 01:32:44.960
daher ist das natürlich toll, wenn man eine Struktur hat,

01:32:44.960 --> 01:32:47.140
wo sowieso nur die Teile gespeichert sind,

01:32:47.140 --> 01:32:49.180
die nicht null sind. Und dann ist das halt

01:32:49.180 --> 01:32:50.820
alles, muss man nicht so viel speichern und

01:32:50.820 --> 01:32:53.380
hat trotzdem alles, was man braucht,

01:32:53.380 --> 01:32:54.760
um halt damit rechnen zu können.

01:32:54.760 --> 01:32:56.980
Ja, das

01:32:56.980 --> 01:32:58.920
funktioniert auch.

01:32:59.240 --> 01:33:01.180
Tatsächlich irgendwie als Eingabe

01:33:01.180 --> 01:33:03.260
für diverse Modelle. Aber halt

01:33:03.260 --> 01:33:05.100
auch nicht für alle. Also da muss man dann halt auch wieder

01:33:05.100 --> 01:33:07.220
aufpassen. Das ist so ein bisschen blöd. Also es gibt

01:33:07.220 --> 01:33:09.080
halt Modelle, die gut damit klarkommen, wenn man

01:33:09.080 --> 01:33:11.120
den Feature-Matrizen

01:33:11.120 --> 01:33:11.960
gibt, die sparse sind.

01:33:11.960 --> 01:33:15.020
Es gibt auch welche, bei denen das nicht geht.

01:33:15.020 --> 01:33:17.140
Und da muss man halt unter Bestimmten auch nochmal ein bisschen was

01:33:17.140 --> 01:33:17.400
machen.

01:33:17.400 --> 01:33:20.360
Was man üblicherweise tun würde, also was

01:33:20.360 --> 01:33:22.900
ein Modell, was immer gut funktioniert,

01:33:22.900 --> 01:33:25.020
was man normalerweise immer braucht, aber was halt nicht

01:33:25.020 --> 01:33:27.060
klarkommt mit sparsen Daten, wäre halt sowas

01:33:27.060 --> 01:33:29.220
wie XGBoost zum Beispiel.

01:33:29.240 --> 01:33:29.760
So ein

01:33:29.760 --> 01:33:33.060
Distribution-Tree-Modell.

01:33:33.060 --> 01:33:34.700
XGBoost?

01:33:34.700 --> 01:33:36.100
XGBoost.

01:33:36.100 --> 01:33:38.700
Extreme Gradient Boosting.

01:33:38.700 --> 01:33:39.260
Ah, okay.

01:33:39.260 --> 01:33:42.780
Und

01:33:42.780 --> 01:33:45.200
da macht man

01:33:45.200 --> 01:33:46.980
das eigentlich, oder für alle,

01:33:46.980 --> 01:33:48.980
ich meine auch, was auch nicht mit Neuronalen

01:33:48.980 --> 01:33:50.560
Netze kommt, auch normalerweise nicht mit sparsen

01:33:50.560 --> 01:33:53.000
Eingaben, klar. Was man da vorher

01:33:53.000 --> 01:33:55.240
macht, ist, man reduziert die Dimensionen.

01:33:55.240 --> 01:33:56.840
Also wenn das,

01:33:56.840 --> 01:33:58.840
ich weiß jetzt nicht, was das, was ich glaube,

01:33:58.880 --> 01:34:00.900
auch irgendwas 25.000 Wörter gibt es da drin, oder so.

01:34:00.900 --> 01:34:02.960
Wenn man jetzt

01:34:02.960 --> 01:34:04.680
aus diesen 25.000 Dimensionen

01:34:04.680 --> 01:34:06.800
etwas machen möchte, was das dense,

01:34:06.800 --> 01:34:08.380
was das dicht ist, dann

01:34:08.380 --> 01:34:10.540
projiziert man halt das aus dem

01:34:10.540 --> 01:34:12.780
hochdimensionalen

01:34:12.780 --> 01:34:14.680
Vektorraum halt runter auf irgendwas

01:34:14.680 --> 01:34:16.300
mit 200 Dimensionen oder 300 oder so.

01:34:16.300 --> 01:34:18.740
Und dafür gibt es dann unterschiedliche Verfahren,

01:34:18.740 --> 01:34:20.320
aber das, was man normalerweise immer verwendet, ist

01:34:20.320 --> 01:34:23.160
Singular Value Decomposition

01:34:23.160 --> 01:34:24.600
und dann auch die Truncated

01:34:24.600 --> 01:34:26.360
Variante davon. Also Truncated

01:34:26.360 --> 01:34:28.680
Singular Value Decomposition ist halt

01:34:28.680 --> 01:34:30.340
immer so das Ding, was man dann nutzt und

01:34:30.340 --> 01:34:32.260
projiziert, um die Sachen runter zu projizieren.

01:34:32.260 --> 01:34:34.360
Es muss einem halt irgendwie mal klar sein,

01:34:34.360 --> 01:34:36.420
wenn man halt so einen Korpus hat und dann hat man jetzt

01:34:36.420 --> 01:34:38.380
in seinen Daten irgendwie

01:34:38.380 --> 01:34:40.640
eine Million Dokumente

01:34:40.640 --> 01:34:42.560
und diese Millionen Dokumente haben halt

01:34:42.560 --> 01:34:43.660
irgendwie 30.000

01:34:43.660 --> 01:34:46.520
unterschiedliche Wörter, dann habe ich halt nachher

01:34:46.520 --> 01:34:48.300
prinzipiell erstmal eine Matrix, wenn ich jetzt nichts

01:34:48.300 --> 01:34:49.700
davon wegwerfe oder so,

01:34:49.700 --> 01:34:52.280
von einer Million mal 30.000.

01:34:52.280 --> 01:34:54.420
Und das kann natürlich

01:34:54.420 --> 01:34:56.540
dann beliebig mit größeren Datensätzen

01:34:56.540 --> 01:34:58.500
noch größer werden und der

01:34:58.500 --> 01:34:59.840
Gedanke an der Stelle ist einfach,

01:34:59.840 --> 01:35:02.400
mit so einer Dimensionalitätsreduktion

01:35:02.400 --> 01:35:04.440
verliere ich theoretisch Informationen,

01:35:04.440 --> 01:35:05.860
aber

01:35:05.860 --> 01:35:08.180
es gibt halt viele

01:35:08.180 --> 01:35:10.320
dieser Spalten, die sich sehr

01:35:10.320 --> 01:35:11.700
ähnlich verhalten werden. Also

01:35:11.700 --> 01:35:14.400
der Optimalfall

01:35:14.400 --> 01:35:15.960
für eine Dimensionalitätsreduktion ist,

01:35:15.960 --> 01:35:18.100
dass zwei Spalten oder

01:35:18.100 --> 01:35:20.480
zwei Zahlen quasi komplett gleich sind,

01:35:20.480 --> 01:35:22.160
weil dann verliere ich quasi

01:35:22.160 --> 01:35:24.120
keine Informationen darüber, wenn ich einfach

01:35:24.120 --> 01:35:25.440
sage, dass diese beiden Spalten,

01:35:25.440 --> 01:35:27.580
wenn ich die beiden quasi zusammenlege.

01:35:28.500 --> 01:35:30.840
Und wenn zwei Spalten

01:35:30.840 --> 01:35:32.800
sehr, sehr stark korreliert sind,

01:35:32.800 --> 01:35:34.960
dann verliere ich auch

01:35:34.960 --> 01:35:36.760
nicht viele Informationen in dem Moment, wo ich

01:35:36.760 --> 01:35:38.580
die beiden irgendwie zusammen auf 1 abbilde.

01:35:38.580 --> 01:35:40.640
Also die, wenn die Spalten ja Wörter sind,

01:35:40.640 --> 01:35:42.780
dann ist ja gleiche Wörter relativ unwahrscheinlich,

01:35:42.780 --> 01:35:44.760
aber dann muss man tatsächlich diese Kombination

01:35:44.760 --> 01:35:46.720
finden aus der Grammatik, die wir eben hatten,

01:35:46.720 --> 01:35:48.080
halt das Modul laden dann, was war das,

01:35:48.080 --> 01:35:50.120
WordConf, irgendwas,

01:35:50.120 --> 01:35:52.500
von Google? Achso, WordSpec,

01:35:52.500 --> 01:35:53.400
aber... WordSpec, genau.

01:35:53.400 --> 01:35:56.300
Das könnte man ja nehmen als Information, um irgendwie so eine

01:35:56.300 --> 01:35:58.420
Kovarianz in den Wörtern festzustellen und die da

01:35:58.420 --> 01:36:00.380
halt dann so zu gruppieren, dass die halt dann

01:36:00.380 --> 01:36:02.320
zusammenfassen und die... Theoretisch kann es aber auch vorher

01:36:02.320 --> 01:36:04.280
der Fall sein. Also mal angenommen, ich habe zum Beispiel

01:36:04.280 --> 01:36:06.680
einen Namen dran, mit einem Vornamen und einem Nachnamen

01:36:06.680 --> 01:36:08.660
und der kommt halt tatsächlich nur in einem der Texte

01:36:08.660 --> 01:36:10.160
vor. Dann habe ich da

01:36:10.160 --> 01:36:12.100
natürlich zwei Spalten für,

01:36:12.100 --> 01:36:14.360
einmal der Vorname, einmal der Nachname

01:36:14.360 --> 01:36:16.220
und die haben genau einmal eine 1 für ein Dokument.

01:36:16.220 --> 01:36:18.320
Dann sind diese

01:36:18.320 --> 01:36:19.940
beiden Spalten natürlich perfekt korreliert.

01:36:19.940 --> 01:36:22.220
Und dann können die natürlich auch beliebig

01:36:22.220 --> 01:36:24.080
von der Dimensionalität

01:36:24.080 --> 01:36:26.260
auf einer projiziert werden.

01:36:26.260 --> 01:36:28.340
Also würde man da nur einen von

01:36:28.340 --> 01:36:30.160
beiden wegschmeißen oder sagt man einfach, ja, das ist eigentlich nur

01:36:30.160 --> 01:36:31.200
in einem Dokument, ist eigentlich egal.

01:36:31.200 --> 01:36:34.280
Letztendlich machst du das selber gar nicht, sondern der Algorithmus

01:36:34.280 --> 01:36:36.080
überlegt sich einfach selbstständig, wo

01:36:36.080 --> 01:36:38.140
verliere ich am wenigsten Informationen, indem ich

01:36:38.140 --> 01:36:40.060
die runtergebe und was ich von außen nur sage, ist

01:36:40.060 --> 01:36:42.560
auf welche Zieldimension will ich gerne?

01:36:42.560 --> 01:36:44.320
Also das heißt, dass da einfach 300 reicht.

01:36:44.320 --> 01:36:46.240
Genau. Und der projiziert

01:36:46.240 --> 01:36:48.020
es für dich runter, aber das ist die Logik, die dahinter steht.

01:36:48.020 --> 01:36:52.080
Genau. Und dabei geht praktisch

01:36:52.080 --> 01:36:54.100
nur sehr wenig Information

01:36:54.100 --> 01:36:55.620
verloren. Das funktioniert halt ziemlich gut.

01:36:55.620 --> 01:36:57.320
Genau.

01:36:58.260 --> 01:37:00.080
Also das ist halt auch sowas. Aber das ist halt

01:37:00.080 --> 01:37:01.620
irgendwie dann doch so eine Geschichte, wo dann

01:37:01.620 --> 01:37:04.160
man nicht immer irgendwie alles gleich

01:37:04.160 --> 01:37:06.120
verwenden kann, weil es gibt halt Modelle, die kommen

01:37:06.120 --> 01:37:07.600
halt mit Spasen-Daten klar und manche halt nicht.

01:37:07.600 --> 01:37:10.100
Ja.

01:37:10.100 --> 01:37:12.080
Genau, genau, genau.

01:37:12.080 --> 01:37:13.900
Gut, aber jetzt wollen wir mal ein Modell trainieren.

01:37:13.900 --> 01:37:16.240
Ja, ein Modell trainieren, genau. Dafür gibt es dann halt auch

01:37:16.240 --> 01:37:17.320
irgendwie einmal

01:37:17.320 --> 01:37:19.840
eine Abstraktionsgeschichte, um halt dieses

01:37:19.840 --> 01:37:22.100
Multilabel-Ding sozusagen

01:37:22.100 --> 01:37:23.780
es gibt einige Modelle, die

01:37:23.780 --> 01:37:26.160
automatisch Multiclass können, aber Multilabel

01:37:26.160 --> 01:37:28.180
da muss man halt

01:37:28.180 --> 01:37:29.540
braucht man halt noch so einen Wörter außenrum

01:37:29.540 --> 01:37:32.040
und eine einfache Art,

01:37:32.040 --> 01:37:33.940
wie man halt sozusagen aus einem

01:37:33.940 --> 01:37:35.860
Modell, also was alle Modelle können, ist halt

01:37:35.860 --> 01:37:37.780
binäre Klassifikation, das ist halt auch das Einfachste

01:37:37.780 --> 01:37:39.940
und man kann jetzt natürlich aus

01:37:39.940 --> 01:37:41.900
binärer Klassifikation quasi automatisch eine

01:37:41.900 --> 01:37:43.940
Multilabel-Klassifikation machen, indem

01:37:43.940 --> 01:37:45.820
man einfach für jede Klasse

01:37:45.820 --> 01:37:47.580
eins gegen alle anderen

01:37:47.580 --> 01:37:50.140
ein Modell trainiert, was dann binäre Klassifikation

01:37:50.140 --> 01:37:50.620
macht.

01:37:50.620 --> 01:37:53.980
Und dann, das muss man aber auch nicht selber machen,

01:37:53.980 --> 01:37:55.080
sondern da gibt es dann halt schon

01:37:55.080 --> 01:37:58.040
ein vorgefertigtes Ding,

01:37:58.100 --> 01:38:00.000
aus Scikit-Learn Multiclass,

01:38:00.000 --> 01:38:02.140
das Ding heißt One-Versus-Rest-Klassifier

01:38:02.140 --> 01:38:03.900
und der tut das dann

01:38:03.900 --> 01:38:05.480
und man kriegt das gar nicht mit, sondern

01:38:05.480 --> 01:38:08.020
steckt einfach nur das eigene Modell, was man verwenden

01:38:08.020 --> 01:38:10.120
möchte, da rein und dann passiert das automatisch.

01:38:10.120 --> 01:38:11.560
Und dann gibt es halt noch

01:38:11.560 --> 01:38:14.080
aus dem

01:38:14.080 --> 01:38:15.860
Scikit-Learn-Metrics-Modul

01:38:15.860 --> 01:38:18.420
eine Klassification-Report-Funktion,

01:38:18.420 --> 01:38:20.240
die halt einem dann so

01:38:20.240 --> 01:38:22.040
eine ganz schöne Übersicht

01:38:22.040 --> 01:38:24.340
gibt, was dann jetzt passiert ist mit den Testdaten,

01:38:24.340 --> 01:38:25.800
wenn man die dann nochmal durch das

01:38:25.800 --> 01:38:28.020
trainierte Modell durchgibt und

01:38:28.020 --> 01:38:29.880
ja, so

01:38:29.880 --> 01:38:31.640
eines der ersten Modelle, die man immer so

01:38:31.640 --> 01:38:33.380
ausprobieren würde,

01:38:33.380 --> 01:38:35.780
denke ich mal, ist so

01:38:35.780 --> 01:38:37.460
Logistic Regression, das ist

01:38:37.460 --> 01:38:39.040
auch ein

01:38:39.040 --> 01:38:41.800
Klassifikationsmodell,

01:38:41.800 --> 01:38:43.820
das heißt bloß Regression,

01:38:43.820 --> 01:38:44.500
das ist nicht so.

01:38:44.500 --> 01:38:47.180
Ja, ich bin auch total,

01:38:47.180 --> 01:38:49.560
ich habe mich am Anfang auch lange Zeit verwirrt,

01:38:49.560 --> 01:38:50.900
dass ein

01:38:50.900 --> 01:38:53.860
eine Methode, die

01:38:53.860 --> 01:38:55.740
Regression im Namen hat, in Wirklichkeit eine

01:38:55.740 --> 01:38:57.940
Klassifikation ist, aber...

01:38:57.940 --> 01:38:58.480
Das ist halt irgendwie...

01:38:58.480 --> 01:39:01.040
Das ist halt dieser Algorithmus, der im Endeffekt dahinter steht.

01:39:01.040 --> 01:39:02.680
Das sollte man nicht zu tief drauf reingehen.

01:39:02.680 --> 01:39:03.400
Genau, genau.

01:39:03.400 --> 01:39:05.980
Und das ist halt so ein Standard-Ding.

01:39:05.980 --> 01:39:07.620
Das ist immer etwas, was man immer am Anfang verwendet,

01:39:07.620 --> 01:39:09.340
weil das ist halt, funktioniert auf

01:39:09.340 --> 01:39:11.820
vielen Sachen ganz gut, es ist sehr schnell.

01:39:11.820 --> 01:39:13.940
Ja.

01:39:13.940 --> 01:39:15.460
Daher

01:39:15.460 --> 01:39:18.000
kann man gut verstehen, was es macht.

01:39:18.000 --> 01:39:20.480
Daher

01:39:20.480 --> 01:39:21.600
man würde gar nicht mit so

01:39:21.600 --> 01:39:23.600
totalen Fancy-Verfahren anfangen,

01:39:23.600 --> 01:39:25.480
sondern eher so mit simplen und dann erstmal gucken,

01:39:25.480 --> 01:39:26.260
was da überhaupt passiert.

01:39:26.260 --> 01:39:27.920
Und dann kann man ja immer,

01:39:27.920 --> 01:39:29.840
noch komplizierteres Dinge machen, wenn das halt nicht reicht.

01:39:29.840 --> 01:39:31.880
Ja.

01:39:31.880 --> 01:39:33.220
Genau.

01:39:33.220 --> 01:39:35.920
Model ist

01:39:35.920 --> 01:39:39.220
jetzt sozusagen einfach nur Run-versus-Rest-Classifier

01:39:39.220 --> 01:39:39.840
und da das

01:39:39.840 --> 01:39:41.080
Logistic Regression

01:39:41.080 --> 01:39:43.600
Modell reingesteckt und

01:39:43.600 --> 01:39:44.540
dann

01:39:44.540 --> 01:39:47.840
einmal Fit auf, um das Modell zu trainieren

01:39:47.840 --> 01:39:50.000
und dann einmal

01:39:50.000 --> 01:39:51.480
Predict, um

01:39:51.480 --> 01:39:54.300
ja, die Voraussagen

01:39:54.300 --> 01:39:55.680
zu bekommen für die

01:39:55.680 --> 01:39:56.840
Test-Dokumente.

01:39:56.840 --> 01:39:57.900
Ich finde das sehr gut.

01:39:57.900 --> 01:39:59.240
Das ist ein sehr gutes Beispiel für,

01:39:59.240 --> 01:40:02.080
wie so ein echtes Welt-Data-Science-Projekt aussieht.

01:40:02.080 --> 01:40:03.380
Weil, wenn man jetzt irgendwie

01:40:03.380 --> 01:40:05.760
sagt, also wenn man von außen dann

01:40:05.760 --> 01:40:07.780
naiv draufschaut

01:40:07.780 --> 01:40:09.160
und denkt sich so,

01:40:09.160 --> 01:40:11.780
so schwer kann es doch nicht sein

01:40:11.780 --> 01:40:13.240
und du machst irgendwie Hello World

01:40:13.240 --> 01:40:15.980
irgendwie Regression oder Klassifikation,

01:40:15.980 --> 01:40:17.160
dann findest du halt einfach

01:40:17.160 --> 01:40:19.800
irgendwo werden Daten vorgefertigt, richtig

01:40:19.800 --> 01:40:21.340
geladen und dann

01:40:21.340 --> 01:40:23.580
nimmst du das Modell, importierst es,

01:40:23.580 --> 01:40:26.040
machst ein Fit, machst ein Predict und hast dein Ergebnis.

01:40:26.040 --> 01:40:27.880
Also das eigentliche Modell-Training,

01:40:27.880 --> 01:40:30.060
ist kein Problem, aber wir reden

01:40:30.060 --> 01:40:31.940
jetzt hier schon eine Stunde, eine halbe

01:40:31.940 --> 01:40:33.580
oder so darüber,

01:40:33.580 --> 01:40:35.820
wie wir da hinkommen und das

01:40:35.820 --> 01:40:37.800
ist die Schwierigkeit bei dem Ganzen, dass es halt

01:40:37.800 --> 01:40:39.960
in Wirklichkeit dann doch nicht so trivial ist, dass man halt

01:40:39.960 --> 01:40:42.020
eben irgendwie Multiclass oder Multilabel

01:40:42.020 --> 01:40:43.900
hat oder sehr große Matrizen oder

01:40:43.900 --> 01:40:45.800
Dimensionalitäten reduzieren muss und

01:40:45.800 --> 01:40:47.580
Features ingenieren und genau,

01:40:47.580 --> 01:40:49.040
dieser Weg dahin ist das Komplizierte.

01:40:49.040 --> 01:40:51.720
Ja, und dann haben wir aber jetzt

01:40:51.720 --> 01:40:53.360
eine Prognose raus und

01:40:53.360 --> 01:40:56.020
müssen uns überlegen, wie gehen wir mit der um,

01:40:56.020 --> 01:40:57.860
wo es auch wieder anfängt komplizierter zu werden.

01:40:57.860 --> 01:40:59.720
Genau, ist halt wahrscheinlich ein bisschen

01:40:59.720 --> 01:41:01.800
unübersichtlich beim Classification-Report, das halt über

01:41:01.800 --> 01:41:03.880
alle 90 Kategorien zu machen, deswegen habe ich jetzt einfach mal

01:41:03.880 --> 01:41:06.080
die Top-10-Kategorien

01:41:06.080 --> 01:41:07.720
genommen. Das ist auch so, wenn man sich

01:41:07.720 --> 01:41:09.660
dafür interessiert, gibt es halt

01:41:09.660 --> 01:41:11.040
die Doktorarbeit von Thorsten

01:41:11.040 --> 01:41:13.200
Joachims, die ist glaube ich

01:41:13.200 --> 01:41:15.680
eines der meistzitierten Papers

01:41:15.680 --> 01:41:17.680
sozusagen im Textklassifikationsbereich,

01:41:17.680 --> 01:41:19.720
irgendwie ist es anderthalb tausend Mal zitiert worden oder so.

01:41:19.720 --> 01:41:21.760
Der hat sich

01:41:21.760 --> 01:41:23.440
damit zuerst 1998 irgendwie

01:41:23.440 --> 01:41:24.760
beschäftigt und

01:41:24.760 --> 01:41:27.840
das Ding gibt es als Buch oder man kann halt

01:41:27.840 --> 01:41:29.340
irgendwie zu so einer Schattenbibliothek gehen.

01:41:29.340 --> 01:41:30.640
Da gibt es das auch.

01:41:30.640 --> 01:41:32.860
Und da kann man sich halt auch,

01:41:32.860 --> 01:41:36.260
man guckt sich da auch mal die Top-10-Kategorien

01:41:36.260 --> 01:41:38.080
an und kann das einfach mal

01:41:38.080 --> 01:41:39.760
vergleichen, die Zahlen, die er da rauskriegt,

01:41:39.760 --> 01:41:41.940
mit dem, was man da selber irgendwie dann sozusagen

01:41:41.940 --> 01:41:42.240
da

01:41:42.240 --> 01:41:45.420
als Ergebnis hat und

01:41:45.420 --> 01:41:47.340
sieht eigentlich alles ganz gut aus.

01:41:47.340 --> 01:41:49.380
Genau, die,

01:41:49.380 --> 01:41:51.760
was man da in Spalten in dem

01:41:51.760 --> 01:41:53.240
Klassifikationsreport drin stehen hat,

01:41:53.240 --> 01:41:55.820
sind halt einmal die Namen

01:41:55.820 --> 01:41:57.040
der Kategorien, dann

01:41:57.040 --> 01:42:00.080
Precision, Recall, F1-Score

01:42:00.080 --> 01:42:01.820
und ja, wie viele

01:42:01.820 --> 01:42:02.700
Beispiele es gab.

01:42:02.700 --> 01:42:05.240
Aber...

01:42:05.240 --> 01:42:07.800
Genau, das ist was, womit man den Umgang auf jeden Fall wirklich lernen muss.

01:42:07.800 --> 01:42:09.680
Da hat mich ganz am Anfang, als ich angefangen habe mit

01:42:09.680 --> 01:42:11.720
Data Science, konnte ich mit den ganzen Zahlen auch nicht wirklich

01:42:11.720 --> 01:42:12.280
was anfangen.

01:42:12.280 --> 01:42:15.980
Was man ja immer im Wesentlichen

01:42:15.980 --> 01:42:17.900
hat, ist, man hat

01:42:17.900 --> 01:42:19.200
prinzipiell vier Fälle.

01:42:19.200 --> 01:42:21.500
Ich kann einfach

01:42:21.500 --> 01:42:23.600
bei einer binären

01:42:23.600 --> 01:42:25.800
Klassifikation, was so das Einfachste ist,

01:42:25.800 --> 01:42:26.900
da kann es sein,

01:42:26.900 --> 01:42:29.200
dass ein Ergebnis quasi wahr ist

01:42:29.200 --> 01:42:30.900
und ich habe auch gesagt, dass

01:42:30.900 --> 01:42:32.980
es wahr ist, das ist das Einfachste, dann habe ich

01:42:32.980 --> 01:42:34.140
ein True Positive.

01:42:34.140 --> 01:42:36.560
Es kann auch sein, dass es

01:42:36.560 --> 01:42:39.040
falsch ist und ich habe aber gesagt,

01:42:39.040 --> 01:42:41.040
dass es wahr ist, dann habe ich

01:42:41.040 --> 01:42:42.280
ein

01:42:42.280 --> 01:42:43.880
False Positive.

01:42:43.880 --> 01:42:46.920
Ich kann sein,

01:42:46.920 --> 01:42:49.080
dass ich richtig gelegen

01:42:49.080 --> 01:42:50.620
habe und es negativ ist,

01:42:50.620 --> 01:42:52.040
dann habe ich ein True Negative.

01:42:52.040 --> 01:42:54.800
Oder es kann negativ sein und

01:42:54.800 --> 01:42:56.760
ich lag auch noch daneben, dann habe ich ein

01:42:56.760 --> 01:42:57.620
False Negative.

01:42:57.620 --> 01:43:00.300
So, und jetzt

01:43:00.300 --> 01:43:02.600
gibt es quasi Kombinationen von diesen

01:43:02.600 --> 01:43:04.480
Feldern für Precision und Recall.

01:43:04.480 --> 01:43:06.620
Und die inhaltliche Bedeutung davon ist

01:43:06.620 --> 01:43:08.400
vom Prinzip, also man kann sich das auch in den Formeln

01:43:08.400 --> 01:43:10.380
anschauen, ich finde das hilft aber weniger, als

01:43:10.380 --> 01:43:12.340
einfach zu sagen, die Precision

01:43:12.340 --> 01:43:14.560
ist, wie viele von

01:43:14.560 --> 01:43:16.640
meinen Daten, wo ich gesagt

01:43:16.640 --> 01:43:18.600
habe, dass sie wahr sind, sind auch wirklich wahr.

01:43:18.600 --> 01:43:20.660
Und Recall ist,

01:43:20.660 --> 01:43:22.380
wie viele von denen, die

01:43:22.380 --> 01:43:24.260
prinzipiell wahr sind, die ich quasi

01:43:24.260 --> 01:43:26.500
prognostizieren wollte,

01:43:26.620 --> 01:43:27.680
habe ich dann auch erwischt.

01:43:27.680 --> 01:43:29.820
Das sind so die beiden.

01:43:29.820 --> 01:43:32.060
Und dazwischen habe ich so ein Trade-Off.

01:43:32.060 --> 01:43:34.240
Und da muss ich halt abwägen.

01:43:34.240 --> 01:43:36.320
Und das ist, was der F1-Score im Endeffekt macht.

01:43:36.320 --> 01:43:38.340
Der tut nämlich einfach

01:43:38.340 --> 01:43:40.200
quasi die beiden so verrechnen,

01:43:40.200 --> 01:43:42.520
dass nachher ein Zahlenwert rauskommt

01:43:42.520 --> 01:43:44.360
zwischen 0 und 1. Und wenn ich quasi

01:43:44.360 --> 01:43:46.380
die 1 habe, dann habe ich quasi sowohl Precision

01:43:46.380 --> 01:43:47.860
als auch Recall perfekt bei 1.

01:43:47.860 --> 01:43:50.320
Und wenn ich bei 0 habe, lag ich bei beiden

01:43:50.320 --> 01:43:52.300
komplett falsch. Und der gibt

01:43:52.300 --> 01:43:54.160
so eine Art Bonus, durch das

01:43:54.160 --> 01:43:56.560
mir berechnet wird, dass ich quasi die beiden

01:43:56.560 --> 01:43:58.420
auch relativ ausgewogen habe. Also wenn ich

01:43:58.420 --> 01:44:00.300
da quasi die Precision auf 1 habe, aber

01:44:00.300 --> 01:44:02.340
den Recall bei 0, dann bin ich da nachher trotzdem

01:44:02.340 --> 01:44:03.800
bei einer 0. Und

01:44:03.800 --> 01:44:06.340
genau, das sind die drei wesentlichen

01:44:06.340 --> 01:44:08.440
Metriken dieses Reports. Und dann

01:44:08.440 --> 01:44:10.480
gibt es halt eben noch den Support, der einfach

01:44:10.480 --> 01:44:12.420
quasi aussagt, okay, wie häufig ist denn

01:44:12.420 --> 01:44:13.700
der Fall überhaupt, um mir so eine

01:44:13.700 --> 01:44:16.380
Absolut-Skala zu geben. Weil diese Zahlenwerte

01:44:16.380 --> 01:44:18.120
sind jetzt natürlich alles relativ. Wenn ich nur

01:44:18.120 --> 01:44:20.440
ein Beispiel habe, und das habe ich richtig klassifiziert,

01:44:20.440 --> 01:44:22.340
dann habe ich einen F1-Score von 1 und alles

01:44:22.340 --> 01:44:24.420
ist super. Aber wenn es halt nur ein Beispiel war,

01:44:24.420 --> 01:44:26.440
dann hilft mir das real im echten Leben natürlich wenig.

01:44:26.440 --> 01:44:28.300
Deswegen ist dieser F1-Score,

01:44:28.300 --> 01:44:30.120
dieser Support dann so eine Matrix für

01:44:30.120 --> 01:44:32.260
wie wichtig es ist, denn in absoluten Zahlen.

01:44:32.260 --> 01:44:34.720
Ja, ja, ja, ne, finde ich

01:44:34.720 --> 01:44:36.280
genau, super erklärt.

01:44:36.280 --> 01:44:38.780
Also so F1-Score

01:44:38.780 --> 01:44:40.540
finde ich jetzt mal, also man braucht

01:44:40.540 --> 01:44:42.480
das sowas in der Art häufig, wenn man

01:44:42.480 --> 01:44:44.460
jetzt zum Beispiel Modelle ranken möchte.

01:44:44.460 --> 01:44:45.800
Man möchte jetzt das beste Modell haben.

01:44:45.800 --> 01:44:48.080
Wenn man jetzt Precision und Recall-Werte hat, dann ist das halt blöd.

01:44:48.080 --> 01:44:49.620
Man kann halt nicht so richtig gut nach,

01:44:49.620 --> 01:44:52.360
wenn man jetzt 2-Werte hat, irgendwie, wie will man dann sortieren?

01:44:52.360 --> 01:44:54.920
Daher

01:44:54.920 --> 01:44:56.320
muss man

01:44:56.320 --> 01:44:57.400
das halt irgendwie in einem Wert

01:44:57.400 --> 01:45:00.100
zusammenfassen und dann nimmt man halt

01:45:00.100 --> 01:45:02.180
einen F1-Wert. Man kann das auch irgendwie anders ausrechnen,

01:45:02.180 --> 01:45:04.320
aber das ist halt das, was meistens

01:45:04.320 --> 01:45:04.780
gemacht wird.

01:45:04.780 --> 01:45:07.900
Ja, und

01:45:07.900 --> 01:45:10.140
einer der Gründe, weshalb man

01:45:10.140 --> 01:45:12.020
sowas überhaupt machen muss, man kann jetzt nicht einfach

01:45:12.020 --> 01:45:14.120
vorstellen, warum immer nicht einfach Accuracy

01:45:14.120 --> 01:45:16.000
oder so. Ja, das

01:45:16.000 --> 01:45:17.340
geht halt nicht so gut.

01:45:17.340 --> 01:45:20.220
Also Accuracy funktioniert halt dann gut, wenn

01:45:20.220 --> 01:45:22.300
das halt,

01:45:22.300 --> 01:45:23.960
wenn alle Klassen irgendwie die gleiche Anzahl

01:45:23.960 --> 01:45:26.100
von Beispielen haben und so,

01:45:26.200 --> 01:45:27.820
dann geht das vielleicht, aber das wird auch schwer,

01:45:27.820 --> 01:45:29.340
sich vorzustellen, wenn man jetzt

01:45:29.340 --> 01:45:31.580
irgendwie was anderes hat als nur 2.

01:45:31.580 --> 01:45:33.080
Und

01:45:33.080 --> 01:45:36.240
es hat auch sonst irgendwie blöde

01:45:36.240 --> 01:45:38.120
Eigenschaften. Also wenn man sich jetzt nochmal

01:45:38.120 --> 01:45:39.820
das Beispiel mit dem Spam und Nicht-Spam

01:45:39.820 --> 01:45:40.320
vorstellt.

01:45:40.320 --> 01:45:44.100
Also bei dir scheint das ja nicht so zu sein.

01:45:44.100 --> 01:45:45.820
Du kriegst ja auch nicht so viel Spam, aber bei mir

01:45:45.820 --> 01:45:48.120
mag das schon so mit dem,

01:45:48.120 --> 01:45:49.440
was andere Leute auch beobachten,

01:45:49.440 --> 01:45:52.180
übereinstimmen, dass halt 99% der Mails,

01:45:52.180 --> 01:45:53.120
die ich bekomme, sind halt Spam.

01:45:53.120 --> 01:45:56.080
Und wenn ich jetzt...

01:45:56.080 --> 01:45:57.740
Was dann noch darunter fällt vielleicht.

01:45:57.740 --> 01:45:58.800
Ja.

01:45:58.800 --> 01:46:01.980
Also ich habe sozusagen eine sehr ungleiche Verteilung

01:46:01.980 --> 01:46:02.280
der

01:46:02.280 --> 01:46:05.940
Klassen. Und wenn ich jetzt

01:46:05.940 --> 01:46:07.960
sozusagen Accuracy nehme

01:46:07.960 --> 01:46:10.060
als Maß oder als Metrik dafür, wie gut

01:46:10.060 --> 01:46:12.200
ist das jetzt, dann könnte

01:46:12.200 --> 01:46:13.740
ich jetzt einen Classifier bauen, der sagt

01:46:13.740 --> 01:46:15.160
irgendwie immer, es ist Spam.

01:46:15.160 --> 01:46:17.800
Und der hätte dann Accuracy von 99%.

01:46:17.800 --> 01:46:19.960
Klingt doch super, voll gut. Aber der macht ja eigentlich

01:46:19.960 --> 01:46:21.560
gar nichts oder macht auf jeden Fall

01:46:21.560 --> 01:46:24.080
nichts Sinnvolles, weil hinterher kriege ich halt gar keine

01:46:24.080 --> 01:46:25.240
Mail mehr. Und

01:46:25.240 --> 01:46:25.760
äh,

01:46:25.960 --> 01:46:27.280
so, das...

01:46:27.280 --> 01:46:29.420
Ja, diese Irrtumswahrscheinlichkeit ist tatsächlich, glaube ich,

01:46:29.420 --> 01:46:31.460
relativ relevant auch für den Untersuchungsgegenstand, den man hat.

01:46:31.460 --> 01:46:33.660
Ich weiß nicht, ob ihr Alpha- oder Beta-Fehler nennt man das, glaube ich,

01:46:33.660 --> 01:46:34.880
so in der klassischen Statistik.

01:46:34.880 --> 01:46:37.660
Ja, oder viele Erste-Ordnung oder Zweite-Ordnung oder sowas.

01:46:37.660 --> 01:46:39.180
Und da ist ja schon

01:46:39.180 --> 01:46:41.440
sehr entscheidend, also was für

01:46:41.440 --> 01:46:43.300
Untersuchungsgegenstände man hat. Manchmal ist 5%

01:46:43.300 --> 01:46:45.660
Abweichung dann ganz okay, weil 95% Wahrscheinlichkeit

01:46:45.660 --> 01:46:47.620
ist ausreichend irgendwie. Vielleicht bei Hund-Katze

01:46:47.620 --> 01:46:48.920
unterscheiden, vielleicht auch nicht ganz so wichtig.

01:46:48.920 --> 01:46:51.480
Aber bei anderen Dingen ist halt dann das

01:46:51.480 --> 01:46:53.500
1%, 1% zu viel. Also gerade wenn man

01:46:53.500 --> 01:46:55.840
so Häufigkeitsverteilungen hat wie, es kommt nur 1%

01:46:55.960 --> 01:46:57.380
der Fälle sowas raus.

01:46:57.380 --> 01:46:59.560
Und dann Fallstieg ist vielleicht nicht so super.

01:46:59.560 --> 01:47:01.520
Ja, aber eben bei Accuracy würde man

01:47:01.520 --> 01:47:03.220
halt gar nicht sehen, dass man da ein Riesenproblem hat,

01:47:03.220 --> 01:47:05.380
wenn man die 99% sieht.

01:47:05.380 --> 01:47:07.720
Vielleicht muss man dann

01:47:07.720 --> 01:47:09.480
einen Negativfehler nehmen. Dann muss man vielleicht nicht versuchen,

01:47:09.480 --> 01:47:10.300
Spam zu tracken, sondern richtigen Mail.

01:47:10.300 --> 01:47:12.960
Aber wenn man jetzt Precision-Recall nehmen würde, würde man sagen,

01:47:12.960 --> 01:47:14.820
okay, dann sieht man es halt sofort, weil Precision wäre 0.

01:47:14.820 --> 01:47:17.480
Ja, also andersrum ist halt tatsächlich

01:47:17.480 --> 01:47:19.080
dieses Ding, wenn du halt den Spam

01:47:19.080 --> 01:47:21.300
immer versuchst zu tracken und er sagt immer

01:47:21.300 --> 01:47:23.060
Spam, dann müsstest du halt umdrehen, musstest sagen,

01:47:23.060 --> 01:47:25.200
hey, ich möchte richtigen Tag tracken. Und dann hättest du halt

01:47:25.200 --> 01:47:25.940
vielleicht eine bessere Erkenntnis.

01:47:25.960 --> 01:47:28.260
Oder so, weil du das halt nicht

01:47:28.260 --> 01:47:30.220
wegschmeißen würdest durch die Fehlerwahrscheinlichkeit.

01:47:30.220 --> 01:47:32.040
Ja,

01:47:32.040 --> 01:47:33.400
auf jeden Fall, also

01:47:33.400 --> 01:47:36.260
für so im allgemeinen

01:47:36.260 --> 01:47:38.000
Fall, wenn man viele Klassen oder

01:47:38.000 --> 01:47:39.280
Labels hat und

01:47:39.280 --> 01:47:40.940
unterschiedlich verteilte

01:47:40.940 --> 01:47:43.920
Klassen, dann sind halt

01:47:43.920 --> 01:47:45.860
Precision-Recall halt ein viel besseres Maß

01:47:45.860 --> 01:47:48.000
als irgendwie

01:47:48.000 --> 01:47:49.840
Accuracy. Daher nimmt man das als,

01:47:49.840 --> 01:47:51.760
es gibt auch noch andere Metriken, die man irgendwie

01:47:51.760 --> 01:47:53.860
benutzen kann, aber das ist schon irgendwie

01:47:53.860 --> 01:47:54.280
so, dass

01:47:54.280 --> 01:47:55.860
verbreiteten

01:47:55.960 --> 01:47:56.900
verbreitetste, denke ich mal.

01:47:56.900 --> 01:47:59.380
Das kommt halt auch so aus diesem Information-Retrieval-Bereich.

01:47:59.380 --> 01:48:02.940
Genau, und diese Metriken sind halt so ein bisschen,

01:48:02.940 --> 01:48:05.800
ja, man muss damit halt lernen, umzugehen.

01:48:05.800 --> 01:48:07.580
Jedes Problem ist ein bisschen anders, also

01:48:07.580 --> 01:48:09.960
wir haben jetzt hier, wie gesagt, so eine Multi-Label-Klassifikation.

01:48:09.960 --> 01:48:11.900
Wenn ich jetzt

01:48:11.900 --> 01:48:13.900
eine Regression habe, habe ich plötzlich wieder komplett

01:48:13.900 --> 01:48:16.300
andere Metriken, die ich da benutze.

01:48:16.300 --> 01:48:18.240
Ich setze mich gerade das erste Mal

01:48:18.240 --> 01:48:20.140
in meinem Leben so ein bisschen mit Recommender-Engines

01:48:20.140 --> 01:48:21.880
auseinander, wo man quasi gleich

01:48:21.880 --> 01:48:24.140
ganze Listen immer zurückgibt

01:48:24.140 --> 01:48:25.600
und quasi sagt, okay,

01:48:25.960 --> 01:48:27.840
ich glaube, das erste ist das Wahrscheinlichste,

01:48:27.840 --> 01:48:29.580
das zweite ist das zweitwahrscheinlichste und so weiter.

01:48:29.580 --> 01:48:31.240
Dann braucht man auch wieder ganz andere Metriken.

01:48:31.240 --> 01:48:33.800
Also, genau, gerade in diesem

01:48:33.800 --> 01:48:35.560
Metriken-Feld wird es dann interessant,

01:48:35.560 --> 01:48:37.480
in welchem Bereich von Data Science

01:48:37.480 --> 01:48:39.620
man sich begibt und was man gerne machen

01:48:39.620 --> 01:48:39.900
möchte.

01:48:39.900 --> 01:48:42.960
Da kann man viel Zeit reinstecken.

01:48:42.960 --> 01:48:43.840
Das ist auch wichtig.

01:48:43.840 --> 01:48:47.560
Genau, und das ist teilweise auch sehr schwer

01:48:47.560 --> 01:48:49.340
zu erklären, also wenn man dann irgendwie

01:48:49.340 --> 01:48:51.120
ja,

01:48:51.120 --> 01:48:53.040
dass dann halt auch Ergebnisse

01:48:53.040 --> 01:48:54.400
irgendwie reportet,

01:48:55.960 --> 01:48:57.940
ist es manchmal nicht so einfach zu erklären,

01:48:57.940 --> 01:48:59.920
warum man das jetzt so macht und nicht irgendwie

01:48:59.920 --> 01:49:01.740
einen einfachen einzelnen Wert nimmt oder so.

01:49:01.740 --> 01:49:04.160
Ja, da muss man

01:49:04.160 --> 01:49:06.220
halt gut sein im Erklären.

01:49:06.220 --> 01:49:06.660
Keine Ahnung.

01:49:06.660 --> 01:49:10.480
Genau, beim Wesentlichen sind wir jetzt die Basis-Pipeline

01:49:10.480 --> 01:49:12.200
ja einmal durch. Also wir haben unsere Daten geladen,

01:49:12.200 --> 01:49:14.460
wir haben sie uns ein bisschen angeschaut,

01:49:14.460 --> 01:49:15.080
wir haben

01:49:15.080 --> 01:49:18.460
darauf jetzt zwar kein großes Feature-Engineering

01:49:18.460 --> 01:49:20.240
gemacht, also wir haben jetzt nicht versucht, irgendwie noch

01:49:20.240 --> 01:49:22.280
zusätzlich sowas dran zu spielen,

01:49:22.280 --> 01:49:24.180
wie zum Beispiel die Textlänge, die noch nicht vorher

01:49:24.180 --> 01:49:25.820
in den Daten so mit drin war und auf den mitzunehmen,

01:49:25.960 --> 01:49:27.800
zu lernen oder sowas man machen könnte, aber wir haben

01:49:27.800 --> 01:49:29.820
zumindest den ganzen Text umgewandelt

01:49:29.820 --> 01:49:31.800
in eine Zahlmatrix und die reduziert

01:49:31.800 --> 01:49:33.880
und darauf jetzt halt eben ein Modell

01:49:33.880 --> 01:49:35.760
berechnet und können sagen,

01:49:35.760 --> 01:49:37.440
wie gut dieses Modell ist.

01:49:37.440 --> 01:49:39.580
Wenn man jetzt

01:49:39.580 --> 01:49:41.800
einfach da eine Spalte dran hängt, geht das

01:49:41.800 --> 01:49:43.620
einfach so? Also wenn man das schon so ein bisschen modelliert hat,

01:49:43.620 --> 01:49:45.680
dass man dann sagt, hey, ich hänge jetzt sowas dran,

01:49:45.680 --> 01:49:46.360
wie die Länge.

01:49:46.360 --> 01:49:49.680
Ja, genau.

01:49:49.680 --> 01:49:51.900
Also hier erzeuge ich ja sozusagen

01:49:51.900 --> 01:49:53.520
die

01:49:53.520 --> 01:49:55.900
Feature-Matrizen direkt,

01:49:55.960 --> 01:49:57.940
aus dem Text,

01:49:57.940 --> 01:50:00.120
aber wenn wir uns jetzt zum Beispiel

01:50:00.120 --> 01:50:01.960
mal angucken,

01:50:01.960 --> 01:50:03.600
na, ich glaube,

01:50:03.600 --> 01:50:06.000
das

01:50:06.000 --> 01:50:08.040
Grid-Search-Ding macht das dann halt

01:50:08.040 --> 01:50:09.860
auch schon so ein bisschen anders. Was man da

01:50:09.860 --> 01:50:12.080
normalerweise dann hat, ist halt

01:50:12.080 --> 01:50:14.180
eben

01:50:14.180 --> 01:50:15.980
nicht so eine naive Geschichte, wo man das einfach

01:50:15.980 --> 01:50:17.980
so erzeugt, sondern man hat halt

01:50:17.980 --> 01:50:20.300
eine, die Feature-Matrix wird erzeugt

01:50:20.300 --> 01:50:21.880
durch, oder überhaupt das komplette

01:50:21.880 --> 01:50:23.860
Ding ist halt

01:50:23.860 --> 01:50:24.680
eine Pipeline.

01:50:25.960 --> 01:50:28.340
Das ist halt

01:50:28.340 --> 01:50:30.060
auch eine Klasse aus Cycle-Learn

01:50:30.060 --> 01:50:32.400
und die kombiniert im Grunde

01:50:32.400 --> 01:50:33.460
viele Schritte

01:50:33.460 --> 01:50:36.160
sozusagen zu einem Ding, das

01:50:36.160 --> 01:50:37.720
sich insgesamt wieder so verhält wie ein Modell.

01:50:37.720 --> 01:50:40.300
Also zum Beispiel

01:50:40.300 --> 01:50:41.520
jetzt bei dieser,

01:50:41.520 --> 01:50:44.260
in diesem

01:50:44.260 --> 01:50:45.740
Notebook ist es halt so, da

01:50:45.740 --> 01:50:48.120
sind die Schritte, aus denen

01:50:48.120 --> 01:50:50.160
die Pipeline besteht, halt

01:50:50.160 --> 01:50:52.020
eine zweite

01:50:52.020 --> 01:50:53.860
Geschichte, die ich irgendwie da noch einführen muss.

01:50:53.860 --> 01:50:55.520
Das Ding nennt sich Feature-Union.

01:50:55.960 --> 01:50:58.080
Und man kann sich das im Grunde so vorstellen, also Feature-Union

01:50:58.080 --> 01:51:00.280
macht genau das,

01:51:00.280 --> 01:51:02.000
was du jetzt vorhattest, einfach irgendwie Dinge

01:51:02.000 --> 01:51:04.280
an die Feature-Matrix spalten, an die Feature-Matrix

01:51:04.280 --> 01:51:05.920
dran bauen,

01:51:05.920 --> 01:51:08.080
sozusagen. Also sozusagen, ich hab halt

01:51:08.080 --> 01:51:10.300
unterschiedliche

01:51:10.300 --> 01:51:12.040
Spalten, ja, und ich möchte die halt

01:51:12.040 --> 01:51:14.060
zusammen kombinieren zu einer

01:51:14.060 --> 01:51:16.100
Feature-Matrix, dann nehme ich Feature-Union,

01:51:16.100 --> 01:51:17.520
das fügt halt die Spalten zusammen

01:51:17.520 --> 01:51:19.220
und die Pipeline

01:51:19.220 --> 01:51:22.120
integriert die ganzen Schritte, die nötig

01:51:22.120 --> 01:51:23.080
sind, um irgendwas zu tun.

01:51:23.080 --> 01:51:25.940
Also Feature-Extraction,

01:51:25.960 --> 01:51:28.020
unterschiedliche Arten von

01:51:28.020 --> 01:51:29.840
Feature-Extraction und halt

01:51:29.840 --> 01:51:32.020
am Schluss irgendwie ein Modell trainieren und

01:51:32.020 --> 01:51:33.360
ja,

01:51:33.360 --> 01:51:35.660
auf den Festdaten halt

01:51:35.660 --> 01:51:37.000
Predictions machen,

01:51:37.000 --> 01:51:40.000
sodass das

01:51:40.000 --> 01:51:41.960
Ganze sich wieder als ein Modell irgendwie

01:51:41.960 --> 01:51:44.020
benutzen lässt. Und was

01:51:44.020 --> 01:51:44.940
das hier tut, ist

01:51:44.940 --> 01:51:47.500
ja, ich übergib der

01:51:47.500 --> 01:51:49.660
Feature-Union halt

01:51:49.660 --> 01:51:51.780
eine Liste von Transformern, die irgendwie Dinge tun

01:51:51.780 --> 01:51:53.900
und man kann die

01:51:53.900 --> 01:51:55.900
jetzt ineinander wieder verschachteln.

01:51:55.960 --> 01:51:57.220
Das ist jetzt wieder eine Pipeline.

01:51:57.220 --> 01:51:59.820
Und die Pipeline, die da drin

01:51:59.820 --> 01:52:01.900
ist, die macht halt, das ist der erste

01:52:01.900 --> 01:52:03.340
Schritt, der nimmt

01:52:03.340 --> 01:52:04.860
eine Spalte aus dem

01:52:04.860 --> 01:52:07.400
Data-Frame, und zwar den Titel

01:52:07.400 --> 01:52:09.260
und

01:52:09.260 --> 01:52:11.360
macht dann eben so etwas wie

01:52:11.360 --> 01:52:13.020
ja,

01:52:13.020 --> 01:52:15.980
Text-Statistiken drauf.

01:52:15.980 --> 01:52:17.420
Also sowas wie, wie lang ist der Titel,

01:52:17.420 --> 01:52:19.760
wie viele Buchstaben sind da drin,

01:52:19.760 --> 01:52:21.820
weiß nicht, wie viele Wörter sind da drin oder sowas,

01:52:21.820 --> 01:52:23.140
ich weiß jetzt gar nicht mehr genau, was das tut.

01:52:23.140 --> 01:52:25.120
Und dann skaliert er halt

01:52:25.120 --> 01:52:25.940
diese, weil das,

01:52:25.960 --> 01:52:27.960
das wäre bei TF-EDF, das ist halt automatisch

01:52:27.960 --> 01:52:30.220
drin, das ist halt irgendwie

01:52:30.220 --> 01:52:33.600
sozusagen

01:52:33.600 --> 01:52:36.080
ja, skaliert

01:52:36.080 --> 01:52:37.840
ist auf wie ein

01:52:37.840 --> 01:52:39.900
Intervall zwischen, weiß ich nicht, 0 und 1

01:52:39.900 --> 01:52:40.280
und

01:52:40.280 --> 01:52:43.780
normalisiert, sodass es halt irgendwie

01:52:43.780 --> 01:52:45.100
alle Vektoren, die Länge 1 haben.

01:52:45.100 --> 01:52:47.840
Bei den Text-Statistiken ist das

01:52:47.840 --> 01:52:49.840
natürlich nicht, da kommt dann halt so eine Zahl raus, wie

01:52:49.840 --> 01:52:51.740
der Titel hat jetzt 25

01:52:51.740 --> 01:52:53.700
Buchstaben. Und da,

01:52:53.700 --> 01:52:55.780
was man eigentlich immer macht, wenn man

01:52:55.780 --> 01:52:57.320
jetzt solche Zahlen hat, ist

01:52:57.320 --> 01:52:59.840
das so zu skalieren, dass

01:52:59.840 --> 01:53:01.840
alle Features irgendwie immer

01:53:01.840 --> 01:53:03.040
zwischen, ja,

01:53:03.040 --> 01:53:05.640
zwischen minus 1 und 1 oder

01:53:05.640 --> 01:53:07.700
zwischen 0 und 1 sind und

01:53:07.700 --> 01:53:09.860
auch eine Standardabweichung von 1 haben

01:53:09.860 --> 01:53:11.740
irgendwie so. Das hängt halt auch mal viel damit

01:53:11.740 --> 01:53:13.600
zusammen, was für ein Algorithmus du im Nachhinein dann

01:53:13.600 --> 01:53:15.740
benutzt. Manche Algorithmen können

01:53:15.740 --> 01:53:17.380
gut umgehen mit

01:53:17.380 --> 01:53:19.660
komplett absolut skalierten

01:53:19.660 --> 01:53:21.900
Werten, also so im Entscheidungsbaum zum Beispiel,

01:53:21.900 --> 01:53:23.820
dem ist das relativ egal, wo er

01:53:23.820 --> 01:53:25.600
jetzt zwischen, ob du jetzt den Wert zwischen

01:53:25.600 --> 01:53:27.600
0 und 1 reingibst und Werte

01:53:27.600 --> 01:53:29.580
zwischen 0 und 10.000, weil

01:53:29.580 --> 01:53:31.480
der entscheidet einfach irgendwo, okay, zwischen

01:53:31.480 --> 01:53:33.780
diesen zwei bitte splitte und

01:53:33.780 --> 01:53:35.520
das rechte Ast, das linke Ast,

01:53:35.520 --> 01:53:37.800
aber bei so einer linearen

01:53:37.800 --> 01:53:39.620
Regression zum Beispiel, da ist

01:53:39.620 --> 01:53:41.780
es halt von Bedeutung, wenn deine

01:53:41.780 --> 01:53:43.700
Achsen alle ganz unterschiedlich

01:53:43.700 --> 01:53:45.500
sind. Also ich könnte, das Wichtige ist eigentlich nur,

01:53:45.500 --> 01:53:47.520
dass sie halbwegs miteinander vergleichbar sind.

01:53:47.520 --> 01:53:49.360
Ich könnte sie auch alle von

01:53:49.360 --> 01:53:51.600
0 bis 100 skalieren oder so, aber die Konvention ist

01:53:51.600 --> 01:53:53.600
halt einfach, man macht das halt einfach alles zwischen 0 und

01:53:53.600 --> 01:53:55.400
1 oder minus 1 und 1, je nachdem,

01:53:55.420 --> 01:53:56.840
was man da vielleicht bezwecken möchte

01:53:56.840 --> 01:53:59.440
und damit macht man in der Regel nichts

01:53:59.440 --> 01:54:01.340
falsch. Ja, also kann man sich

01:54:01.340 --> 01:54:03.320
ganz einfach vorstellen, bei einem linearen Modell, ein lineares

01:54:03.320 --> 01:54:05.540
Modell bedeutet, dass du im Grunde

01:54:05.540 --> 01:54:06.560
einen

01:54:06.560 --> 01:54:09.320
Vektor hast, der genau die

01:54:09.320 --> 01:54:11.400
gleiche Dimension hat, wie

01:54:11.400 --> 01:54:12.440
du Spalten hast, sozusagen.

01:54:12.440 --> 01:54:15.680
Und die Klassifikation

01:54:15.680 --> 01:54:17.340
ist einfach nur das Skalarprodukt aus

01:54:17.340 --> 01:54:19.040
einem neuen Feature-Vektor und diesem Modell.

01:54:19.040 --> 01:54:20.700
Und

01:54:20.700 --> 01:54:23.040
jetzt gibt es ganz

01:54:23.040 --> 01:54:24.480
viele unterschiedliche Arten dieses

01:54:24.480 --> 01:54:25.240
Modells.

01:54:25.240 --> 01:54:27.020
Dieses Modell zu trainieren, aber das ist immer das

01:54:27.020 --> 01:54:28.620
Gleiche, wenn das ein lineares Modell ist.

01:54:28.620 --> 01:54:30.300
Also ob ich jetzt eine Support-Vektor-Maschine

01:54:30.300 --> 01:54:32.980
nehme, die das halt trainiert, oder

01:54:32.980 --> 01:54:35.060
halt Logistic Regression, oder halt

01:54:35.060 --> 01:54:36.840
irgendwie sonst irgendwie eins von den

01:54:36.840 --> 01:54:39.720
Generalized Linear Models

01:54:39.720 --> 01:54:40.540
oder so, die es da so gibt,

01:54:40.540 --> 01:54:42.900
da fällt immer so ein Vektor dabei raus und die

01:54:42.900 --> 01:54:44.160
Klassifikation ist eigentlich immer gleich.

01:54:44.160 --> 01:54:47.020
Und ich kann mir natürlich jetzt leicht vorstellen,

01:54:47.020 --> 01:54:49.080
was passiert, wenn ich irgendwie überall

01:54:49.080 --> 01:54:50.940
Werte zwischen 0 und 1 habe in den Spalten.

01:54:50.940 --> 01:54:53.020
Nur in einer Spalte habe ich jetzt Werte um die 10.000

01:54:53.020 --> 01:54:54.920
oder so. Dann dominiert diese Spalte

01:54:54.920 --> 01:54:55.220
natürlich.

01:54:55.220 --> 01:54:57.160
Das Klassifikationsergebnis ist massiv.

01:54:57.160 --> 01:54:58.740
Das heißt, ich muss die alle so

01:54:58.740 --> 01:55:01.260
normiert haben, dass hinterher die Länge der

01:55:01.260 --> 01:55:03.260
Vektoren 1 ist, damit

01:55:03.260 --> 01:55:04.060
nicht ein

01:55:04.060 --> 01:55:07.160
Feature halt da so irgendwie...

01:55:07.160 --> 01:55:08.660
Alle Features sollten irgendwie so quasi

01:55:08.660 --> 01:55:10.360
numerisch gleich wichtig sein.

01:55:10.360 --> 01:55:13.180
Ja, deswegen muss ich das halt

01:55:13.180 --> 01:55:14.980
skalieren am Schluss. Und dafür

01:55:14.980 --> 01:55:17.520
gibt es auch unterschiedliche Skalierer

01:55:17.520 --> 01:55:19.280
und der Standard-Scaler

01:55:19.280 --> 01:55:21.220
macht glaube ich irgendwie...

01:55:21.220 --> 01:55:22.920
Weiß ich gar nicht.

01:55:22.920 --> 01:55:25.040
Ja, das ist ganz

01:55:25.040 --> 01:55:25.540
validity halt.

01:55:25.540 --> 01:55:26.920
Ist validity halt irgendwie oder. Genau.

01:55:26.920 --> 01:55:29.060
Der wesentliche Punkt eigentlich bei diesen Pipelines ist,

01:55:29.060 --> 01:55:31.080
ich könnte diese ganzen Schritte

01:55:31.080 --> 01:55:33.260
auch alle nacheinander ausführen. Also ich kann

01:55:33.260 --> 01:55:35.320
prinzipiell in meinem Notebook,

01:55:35.320 --> 01:55:36.880
das haben wir vorher quasi auch gesehen,

01:55:36.880 --> 01:55:39.320
in dem linearen Regressionsnotebook,

01:55:39.320 --> 01:55:41.900
ich kann

01:55:41.900 --> 01:55:43.660
erst meinen Text umwandeln,

01:55:43.660 --> 01:55:45.220
Dimensionalitätsreaktionen ausführen

01:55:45.220 --> 01:55:47.180
in der nächsten Zelle und quasi immer dazwischen

01:55:47.180 --> 01:55:49.360
meine Werte irgendwie in ein neues DataFrame

01:55:49.360 --> 01:55:51.300
schreiben und das wieder in das nächste reinführen.

01:55:51.300 --> 01:55:53.280
Ist zum Debuggen

01:55:53.280 --> 01:55:54.960
vielleicht auch mal ganz hilfreich. Aber

01:55:54.960 --> 01:55:56.980
wenn ich nachher quasi dann einfach damit

01:55:56.980 --> 01:55:58.820
spielen möchte, verschiedene Werte zu verändern,

01:55:58.820 --> 01:56:01.120
dann will ich, dass das möglichst einfach hintereinander

01:56:01.120 --> 01:56:02.940
durchläuft. Und ich weiß nicht,

01:56:02.940 --> 01:56:04.960
cashen so Pipelines auch zwischendrin

01:56:04.960 --> 01:56:06.940
Schritte? Genau. Genau, das heißt, das macht

01:56:06.940 --> 01:56:08.900
es auch deutlich effizienter, wenn ich dann

01:56:08.900 --> 01:56:11.020
quasi in einem relativ späten Step

01:56:11.020 --> 01:56:12.400
in der Pipeline eine Kleinigkeit ändere,

01:56:12.400 --> 01:56:14.960
dann muss die halt nicht komplett von vorne durchgeführt werden.

01:56:14.960 --> 01:56:15.940
Und

01:56:15.940 --> 01:56:18.580
genau, das mache ich prinzipiell eher,

01:56:18.580 --> 01:56:20.900
wenn ich schon so die erste

01:56:20.900 --> 01:56:22.980
Exploration durch habe, dann würde ich anfangen

01:56:22.980 --> 01:56:24.920
sowas in eine Pipeline zu stecken oder machst du das wirklich von Anfang

01:56:24.920 --> 01:56:26.860
an? Ne, genau, ich mache das auch erst, wenn

01:56:26.860 --> 01:56:27.940
ich ungefähr weiß, was ich da

01:56:27.940 --> 01:56:30.100
damit tun möchte und

01:56:30.100 --> 01:56:32.840
ja, genau,

01:56:32.840 --> 01:56:34.620
man braucht es halt auch vor allen Dingen deswegen, wenn man jetzt

01:56:34.620 --> 01:56:36.760
unterschiedliche Sachen ausprobieren möchte. Das ist

01:56:36.760 --> 01:56:38.860
halt, Stichwort

01:56:38.860 --> 01:56:40.440
wäre Hyperparameter-Optimierung,

01:56:40.440 --> 01:56:42.360
also sozusagen, welche Features verwende ich.

01:56:42.360 --> 01:56:44.820
Man kann ja, man könnte ja dann

01:56:44.820 --> 01:56:46.140
doch wieder gewichten, wenn man möchte, oder?

01:56:46.140 --> 01:56:48.660
Ja, natürlich,

01:56:48.660 --> 01:56:50.500
man kann auch einzelne Teile davon,

01:56:50.500 --> 01:56:52.960
man könnte jetzt unterschiedliche Feature-Unions

01:56:52.960 --> 01:56:54.760
bauen, so eine zum Beispiel, die sich nur mit dem

01:56:54.760 --> 01:56:56.880
also, das ist ja

01:56:56.880 --> 01:56:58.220
im Grunde hier auch schon so, also ein

01:56:58.220 --> 01:57:00.460
Ding, das sich halt nur mit dem Text beschäftigt, oder

01:57:00.460 --> 01:57:02.280
eins wird, dass sich mit dem Body,

01:57:02.280 --> 01:57:04.580
mit dem Titel beschäftigt, und eins, dass sich mit dem

01:57:04.580 --> 01:57:06.720
Body dieser Tickermeldung

01:57:06.720 --> 01:57:08.680
beschäftigt, und jetzt könnte man

01:57:08.680 --> 01:57:10.380
diesen Dingern unterschiedliche Gewichte geben auch.

01:57:10.380 --> 01:57:11.660
Das auf jeden Fall.

01:57:11.660 --> 01:57:14.380
Ja, und

01:57:14.380 --> 01:57:16.840
aber all diese Änderungen, die man macht,

01:57:16.840 --> 01:57:18.700
wenn man jetzt da an irgendwelchen

01:57:18.700 --> 01:57:20.700
Parametern dreht, die möchte man ja

01:57:20.700 --> 01:57:22.640
hinterher auch, also das muss man sich ja

01:57:22.640 --> 01:57:24.600
irgendwie merken, und eigentlich möchte man das ja auch

01:57:24.600 --> 01:57:26.460
systematisch durchprobieren, und das

01:57:26.460 --> 01:57:27.580
nicht von Hand immer wieder verändern,

01:57:27.580 --> 01:57:30.280
und ein Verfahren, um das halt systematisch

01:57:30.280 --> 01:57:32.400
durchzuprobieren, ist halt GridSearch,

01:57:32.400 --> 01:57:34.400
und das ist halt auch ein Vorteil, wenn man jetzt so

01:57:34.400 --> 01:57:36.100
eine Feature-Pipeline hat, dass man

01:57:36.100 --> 01:57:38.540
sozusagen die Bereiche für

01:57:38.540 --> 01:57:39.940
die Parameter, die man halt

01:57:39.940 --> 01:57:42.420
durchprobieren möchte, die gibt man halt irgendwie an,

01:57:42.420 --> 01:57:44.380
und dann

01:57:44.380 --> 01:57:46.420
ruft man das halt mit GridSearch auf, und dann

01:57:46.420 --> 01:57:48.420
werden diese ganzen Parameter, dieses Parameter-Grid

01:57:48.420 --> 01:57:50.600
halt durchprobiert, und am Schluss

01:57:50.600 --> 01:57:54.440
ja, also fällt halt das Modell

01:57:54.440 --> 01:57:56.320
raus, was halt am besten funktioniert hat, beziehungsweise alle

01:57:56.320 --> 01:57:58.480
anderen Ergebnisse werden auch gespeichert, normalerweise

01:57:58.480 --> 01:57:59.740
will man jetzt da irgendwie aus diesem

01:57:59.740 --> 01:58:02.300
GridSearch-Ding halt

01:58:02.300 --> 01:58:04.140
rausholen und irgendwo ein CSV

01:58:04.140 --> 01:58:06.340
schreiben, oder irgendwie, und dann kann man sich das halt hinterher

01:58:06.340 --> 01:58:07.940
visualisieren, und dann halt gucken,

01:58:07.940 --> 01:58:10.440
okay, wann habe ich das mit welchen Parametern

01:58:10.440 --> 01:58:12.040
irgendwie ausprobiert, und was ist dabei rausgekommen.

01:58:12.040 --> 01:58:14.420
Genau, man muss, also ich würde da

01:58:14.420 --> 01:58:16.320
die Hyperparameter-Tuning noch mal

01:58:16.320 --> 01:58:17.360
kurz ein bisschen aufgreifen.

01:58:17.360 --> 01:58:20.640
Jeder dieser Algorithmen,

01:58:20.640 --> 01:58:22.380
die wir jetzt erwähnt haben, die haben jede

01:58:22.380 --> 01:58:24.120
Menge Parameter, die man da mitgeben kann.

01:58:24.280 --> 01:58:26.220
Also, eine ganz einfache

01:58:26.220 --> 01:58:27.980
lineare Regression ist vielleicht noch relativ

01:58:27.980 --> 01:58:30.100
beschränkt, aber sobald wir

01:58:30.100 --> 01:58:30.900
die jetzt zum Beispiel

01:58:30.900 --> 01:58:33.840
regularisieren, das heißt irgendwie

01:58:33.840 --> 01:58:36.160
verhindern, dass die irgendwie zu stark sich den Daten

01:58:36.160 --> 01:58:37.980
anpasst, bekommt die Hyperparameter

01:58:37.980 --> 01:58:39.980
oder noch einfacher finde ich es sich vorzustellen

01:58:39.980 --> 01:58:41.940
bei so einem Entscheidungsbaum, der hat halt

01:58:41.940 --> 01:58:43.960
eine gewisse Tiefe, der kann irgendwie auf

01:58:43.960 --> 01:58:46.060
100 Leveln verschachtelt sein, oder nur auf

01:58:46.060 --> 01:58:48.060
2, und der kann auch

01:58:48.060 --> 01:58:49.700
zum Beispiel beschränkt werden in der Anzahl der

01:58:49.700 --> 01:58:51.960
letztendlichen Blätter, also wie viele mögliche

01:58:51.960 --> 01:58:54.120
Output-Ergebnisse kommen dahin, oder

01:58:54.120 --> 01:58:56.080
wie viele Samples müssen in

01:58:56.080 --> 01:58:57.980
jede dieser Blätter letztendlich fallen. Das sind zum

01:58:57.980 --> 01:59:00.020
Beispiel schon drei verschiedene Parameter, die man

01:59:00.020 --> 01:59:01.980
da so mitgeben kann, und die können die

01:59:01.980 --> 01:59:03.780
Art, wie gut

01:59:03.780 --> 01:59:06.480
dieses Modell performt,

01:59:06.480 --> 01:59:07.920
extrem beeinflussen. Das ist

01:59:07.920 --> 01:59:09.500
wirklich sehr, sehr entscheidend,

01:59:09.500 --> 01:59:12.020
und deswegen ist es wichtig, die

01:59:12.020 --> 01:59:13.920
einfach nach und nach durchzuprobieren.

01:59:13.920 --> 01:59:16.020
Und man sagt jetzt, wir haben noch irgendwie selbstlernende Algorithmen,

01:59:16.020 --> 01:59:18.080
irgendwie, warum

01:59:18.080 --> 01:59:19.840
muss ich denn da jetzt noch Parameter-Tuning, aber

01:59:19.840 --> 01:59:22.080
ich passe ja quasi einfach

01:59:22.080 --> 01:59:23.960
die, man muss

01:59:23.960 --> 01:59:25.820
es sind halt zwei verschiedene Arten von Parametern.

01:59:25.820 --> 01:59:27.800
Die einen sind quasi die internen, die

01:59:27.800 --> 01:59:30.220
berechnet werden, innerhalb des Algorithmuses,

01:59:30.220 --> 01:59:32.020
die lernt er aus

01:59:32.020 --> 01:59:33.960
den Daten, und das andere sind quasi so

01:59:33.960 --> 01:59:35.340
die Konfigurationsobjekte,

01:59:35.340 --> 01:59:37.860
wie man das, wie

01:59:37.860 --> 01:59:39.820
die Berechnung von diesen anderen

01:59:39.820 --> 01:59:41.860
Parametern zustande kommt, und

01:59:41.860 --> 01:59:43.940
die muss ich ihm halt eben mitgeben,

01:59:43.940 --> 01:59:46.000
oder ich versuche sie halt einfach alle,

01:59:46.000 --> 01:59:47.840
probiere sie halt einfach alle durch, und das ist,

01:59:47.840 --> 01:59:50.300
was ich mehr oder weniger bei so einem Hyper-Parameter-Search

01:59:50.300 --> 01:59:51.880
mache. Ich überlege mir

01:59:51.880 --> 01:59:53.800
irgendeine Strategie, dass er einfach

01:59:53.800 --> 01:59:55.760
möglichst viele von denen durchprobiert, da gibt's

01:59:55.760 --> 01:59:57.840
auch Algorithmen, die versuchen quasi selbstständig

01:59:57.840 --> 01:59:59.620
so ein bisschen zu wählen, welche

01:59:59.620 --> 02:00:02.280
an welcher Schraube drehe ich als nächstes

02:00:02.280 --> 02:00:04.260
um halt dann den Algorithmus

02:00:04.260 --> 02:00:05.760
in der Stelle optimal zu tunen

02:00:05.760 --> 02:00:07.240
und das ist ein ganz entscheidender Prozess

02:00:07.240 --> 02:00:09.480
innerhalb von so einem Data Science Projekt

02:00:09.480 --> 02:00:10.980
Ja

02:00:10.980 --> 02:00:13.580
Ja auch um halt die

02:00:13.580 --> 02:00:15.780
man möchte es auch deshalb schon formalisieren

02:00:15.780 --> 02:00:17.860
damit man die Ergebnisse kommuniziert bekommt

02:00:17.860 --> 02:00:19.880
weil wenn ich jetzt im Notebook irgendwie Parameter erinnere

02:00:19.880 --> 02:00:22.020
und das durchprobiere, dann weiß ich das vielleicht noch

02:00:22.020 --> 02:00:23.980
obwohl meistens vergisst man das ja auch relativ schnell

02:00:23.980 --> 02:00:25.000
wieder, was man alles probiert hat

02:00:25.000 --> 02:00:28.160
dann weiß man vielleicht noch so, ach vor zwei Wochen hatte ich da irgendwas gemacht

02:00:28.160 --> 02:00:29.600
das war ziemlich gut, oh was war das nochmal

02:00:29.600 --> 02:00:31.900
man möchte das ja auch

02:00:31.900 --> 02:00:33.560
wenn da mehrere Leute dran arbeiten

02:00:33.560 --> 02:00:35.260
denen das ja auch irgendwie kommunizieren

02:00:35.260 --> 02:00:38.020
und da ist es natürlich dann schon gut

02:00:38.020 --> 02:00:39.200
wenn man das systematisch gemacht hat

02:00:39.200 --> 02:00:41.760
weil dann fallen da eben solche CSVs einfach schon bei raus

02:00:41.760 --> 02:00:43.680
und man kann halt auch gucken, was andere Leute schon probiert haben

02:00:43.680 --> 02:00:45.360
und muss das dann auch nicht nochmal selber machen

02:00:45.360 --> 02:00:47.400
Genau und diese Hyperparameter Search

02:00:47.400 --> 02:00:49.580
gibt einem halt am Ende auch so eine Operation

02:00:49.580 --> 02:00:51.640
irgendwie Best Parameter oder Best Fit

02:00:51.640 --> 02:00:52.120
oder sowas

02:00:52.120 --> 02:00:55.380
und dann gibt er einem halt einfach das Beste von allen

02:00:55.380 --> 02:00:56.300
die er ausprobiert hat wieder

02:00:56.300 --> 02:00:59.100
aber ansonsten

02:00:59.100 --> 02:01:00.920
wenn du quasi auch so tracken möchtest

02:01:00.920 --> 02:01:03.340
was hat gut funktioniert und auch Features reiningenieren möchtest

02:01:03.340 --> 02:01:04.980
du schreibst das dann einfach in CSVs weg

02:01:04.980 --> 02:01:05.920
oder wie machst du das?

02:01:05.920 --> 02:01:08.060
Ja, meistens tatsächlich, ja

02:01:08.060 --> 02:01:11.320
Das finde ich immer noch ein bisschen überraschend

02:01:11.320 --> 02:01:12.920
dass da Second Learn an der Stelle irgendwie

02:01:12.920 --> 02:01:14.140
nichts von sich aus bietet

02:01:14.140 --> 02:01:17.400
also ich habe mir jetzt gerade da auch diverse Tools angeschaut

02:01:17.400 --> 02:01:19.180
ich finde da jetzt MLflow

02:01:19.180 --> 02:01:21.320
von Dataprix

02:01:21.320 --> 02:01:21.920
ganz cool

02:01:21.920 --> 02:01:24.760
die ja auch quasi Spark gebaut haben

02:01:24.760 --> 02:01:26.280
die haben da ein Tool für

02:01:26.300 --> 02:01:28.520
es gibt da auch irgendwie Sacred und DVC

02:01:28.520 --> 02:01:30.020
die ich mir alle mal angeschaut habe

02:01:30.020 --> 02:01:31.540
aber irgendwie finde ich es merkwürdig

02:01:31.540 --> 02:01:34.180
jeder kommt in diese Predolje

02:01:34.180 --> 02:01:35.900
dass er jetzt quasi ein bisschen damit rumspielt

02:01:35.900 --> 02:01:38.080
und seine ganzen Ergebnisse an und nach noch tracken möchte

02:01:38.080 --> 02:01:39.840
und jeder schreibt sich die irgendwie so ein bisschen

02:01:39.840 --> 02:01:40.860
auf seine eigene Art weg

02:01:40.860 --> 02:01:44.300
aber der Standardsupport von irgendwelchen Bibliotheken

02:01:44.300 --> 02:01:45.740
ist da finde ich noch ein bisschen

02:01:45.740 --> 02:01:47.160
jung und schwach

02:01:47.160 --> 02:01:49.000
Ja, ja

02:01:49.000 --> 02:01:51.700
Wie fandest du DVC?

02:01:51.700 --> 02:01:53.500
Das wollte ich mir demnächst mal irgendwie angucken

02:01:53.500 --> 02:01:55.400
DVC ist halt nicht

02:01:55.400 --> 02:01:55.500
Python

02:01:56.300 --> 02:01:57.360
Pythonic, ja

02:01:57.360 --> 02:02:00.000
also das basiert halt komplett auf

02:02:00.000 --> 02:02:02.680
Kommandozahlenaufrufe und Shell-Skripten

02:02:02.680 --> 02:02:05.300
ich habe letztendlich quasi so die Abwägung

02:02:05.300 --> 02:02:05.800
würde ich sagen

02:02:05.800 --> 02:02:09.700
wenn du schnell Sachen ausprobieren willst

02:02:09.700 --> 02:02:12.700
und mehr so in der Exploration bist

02:02:12.700 --> 02:02:14.240
dann guck dir lieber MLflow an

02:02:14.240 --> 02:02:15.780
das finde ich dafür deutlich angenehmer

02:02:15.780 --> 02:02:19.520
wenn du sehr viel Wert auf Reproduzierbarkeit

02:02:19.520 --> 02:02:20.840
deiner Experimente legst

02:02:20.840 --> 02:02:22.840
und vielleicht auch große Experimente machst

02:02:22.840 --> 02:02:23.840
und dafür bereit bist

02:02:23.840 --> 02:02:25.120
mehr Zeit zu investieren

02:02:25.120 --> 02:02:26.280
und mehr Zeit zu investieren

02:02:26.900 --> 02:02:28.800
as Maturity Level vom Prinzip her hast

02:02:28.800 --> 02:02:30.680
und auch im Team arbeitest, dann ist DVC

02:02:30.680 --> 02:02:32.520
meiner Meinung nach die bessere Wahl.

02:02:32.520 --> 02:02:34.180
Also ich habe Kollegen, die benutzen das eine oder das andere.

02:02:34.180 --> 02:02:36.520
Das hängt ein bisschen mehr von deinem Projekt ab,

02:02:36.520 --> 02:02:38.560
aber gerade für die Exploration finde ich

02:02:38.560 --> 02:02:39.740
DVC einfach

02:02:39.740 --> 02:02:41.840
zu viel Boilerplate Code.

02:02:41.840 --> 02:02:50.560
Ich verlinke dazu mal meinen Artikel,

02:02:50.560 --> 02:02:52.580
den ich auch gerade noch geschrieben habe, genau darüber.

02:02:56.520 --> 02:02:57.000
Ja.

02:02:57.000 --> 02:03:00.020
Jetzt könnte man natürlich

02:03:00.020 --> 02:03:02.100
alle möglichen verschiedenen Algorithmen draufwerfen

02:03:02.100 --> 02:03:04.020
und so, aber ich würde sagen, das überlassen wir mal

02:03:04.020 --> 02:03:05.900
den Hörern, da könnte man jetzt auch ewig Zeit

02:03:05.900 --> 02:03:06.540
draufwerfen.

02:03:06.540 --> 02:03:12.100
Haben wir irgendwas Wesentliches

02:03:12.100 --> 02:03:12.440
vergessen?

02:03:12.440 --> 02:03:16.100
Den grundsätzlichen Prozess, dieses Datenbeispiel

02:03:16.100 --> 02:03:17.340
da von Reuters mal kurz so

02:03:17.340 --> 02:03:19.580
zu skizzieren, haben wir schon durch, oder?

02:03:19.580 --> 02:03:21.920
Also es funktioniert auf jeden Fall,

02:03:21.920 --> 02:03:23.640
wir haben jetzt tatsächlich gelernt,

02:03:23.640 --> 02:03:26.140
wie man so eine neue

02:03:26.140 --> 02:03:27.440
Nachricht dann mit so einem Label versieht,

02:03:27.440 --> 02:03:30.200
dass dann die Klasse so, was ist das für eine Kategorie,

02:03:30.200 --> 02:03:31.480
rausfällt unten, oder?

02:03:31.480 --> 02:03:34.140
Genau. Also wir sind jetzt in der Lage,

02:03:34.140 --> 02:03:35.500
ähm,

02:03:35.500 --> 02:03:37.600
haben jetzt ein Modell da liegen,

02:03:37.600 --> 02:03:40.000
was auf den Testdaten

02:03:40.000 --> 02:03:41.960
Prognosen rechnen könnte und wenn jetzt ein neuer

02:03:41.960 --> 02:03:43.700
vergleichbarer Textartikel reinkommt,

02:03:43.700 --> 02:03:45.940
der dieselben Spalten hat, egal wo der herkommt,

02:03:45.940 --> 02:03:48.000
dann können wir den auch reinwerfen und dann wird

02:03:48.000 --> 02:03:50.140
der einen der Text voraussagen,

02:03:50.140 --> 02:03:52.060
die wir jetzt

02:03:52.060 --> 02:03:53.620
quasi, ähm,

02:03:53.620 --> 02:03:55.640
da drin hatten, da können jetzt kein

02:03:55.640 --> 02:03:56.520
originär neuer

02:03:56.520 --> 02:03:58.800
Artikel natürlich rausfallen oder so,

02:03:58.800 --> 02:04:00.820
aber, ähm,

02:04:00.820 --> 02:04:03.520
das haben wir und können auch bewerten, wie gut

02:04:03.520 --> 02:04:04.220
wir daran sind.

02:04:04.220 --> 02:04:05.240
Ja.

02:04:05.240 --> 02:04:09.480
Ja, ja. Ja, also haben wir quasi unser erstes

02:04:09.480 --> 02:04:11.320
Projekt erfolgreich abgeschlossen. Wenn wir das jetzt

02:04:11.320 --> 02:04:13.480
auf dem Server implementiert haben, dann läuft das

02:04:13.480 --> 02:04:15.440
so auch. Ja, wir könnten, wir könnten eben jetzt

02:04:15.440 --> 02:04:17.340
so ein Modell hinter so einer, äh,

02:04:17.340 --> 02:04:19.520
API irgendwie, äh, deployen

02:04:19.520 --> 02:04:21.680
und, ähm, dann schicken wir

02:04:21.680 --> 02:04:23.320
dann einen Artikel dahin und bekommen dann halt zurück,

02:04:23.320 --> 02:04:25.440
äh, in welchen Dingern das liegt und dann,

02:04:25.440 --> 02:04:27.140
dann muss man sich dann natürlich noch überlegen, okay,

02:04:27.140 --> 02:04:29.280
gibt man halt zurück, in welcher Wahrscheinlichkeit,

02:04:29.280 --> 02:04:31.160
mit welcher Wahrscheinlichkeit das in welcher, äh,

02:04:31.160 --> 02:04:32.700
oder einfach nur eine Liste der

02:04:32.700 --> 02:04:34.440
Kategorien, in denen es liegt,

02:04:34.440 --> 02:04:37.160
ähm, und, ähm, wann,

02:04:37.160 --> 02:04:39.200
wann sagt man eigentlich, äh, es liegt drin

02:04:39.200 --> 02:04:41.300
oder nicht, äh, genau. Und das

02:04:41.300 --> 02:04:43.100
ist, äh, da, da müssen wir natürlich noch eine Menge,

02:04:43.100 --> 02:04:45.180
äh, Entscheidungen treffen. Das hängt halt

02:04:45.180 --> 02:04:47.260
dann auch davon ab, wie das Problem aussieht,

02:04:47.260 --> 02:04:48.640
ne? Ist es wichtig, möglichst alle,

02:04:48.640 --> 02:04:51.200
äh, in den Kategorien, in denen ein

02:04:51.200 --> 02:04:53.540
Artikel liegen könnte, mitzuliefern

02:04:54.180 --> 02:05:05.320
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.

02:05:05.320 --> 02:05:07.340
Wie groß ist das Modell auf dem Server?

02:05:07.340 --> 02:05:12.440
Die hier sind relativ klein, wenige Megabyte, denke ich, sind die größten.

02:05:12.440 --> 02:05:19.920
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.

02:05:20.400 --> 02:05:32.440
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.

02:05:32.440 --> 02:05:41.080
Dann kommst du auf mehrere Megabyte, ein einzelner Entscheidungsbaum ist wahrscheinlich sogar im Kilobyte-Bereich. Je nachdem, wie tief du den halt eben machst.

02:05:41.080 --> 02:05:50.380
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.

02:05:50.400 --> 02:06:12.860
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.

02:06:12.860 --> 02:06:18.860
Aber wenn du jetzt zum Beispiel viele Trainingsdaten hast und du hast halt ein...

02:06:18.860 --> 02:06:20.360
Also das ist ja auch noch...

02:06:20.360 --> 02:06:35.220
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.

02:06:35.220 --> 02:06:44.440
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.

02:06:44.440 --> 02:06:50.160
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,

02:06:50.320 --> 02:06:57.500
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.

02:06:57.500 --> 02:07:00.320
Ja, aber selbst das ist ja für den Server heute alles nicht mehr so...

02:07:00.320 --> 02:07:08.600
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.

02:07:08.600 --> 02:07:13.320
Und da muss man halt vielleicht nochmal ein bisschen gucken, was die Größe angeht, aber...

02:07:13.320 --> 02:07:19.500
Das Schöne ist ja vor allem, eben eine Prognose jetzt mit so einem Modell zu berechnen, ist überhaupt nicht mehr kompliziert.

02:07:20.280 --> 02:07:21.440
Aufwendig ist natürlich...

02:07:21.460 --> 02:07:25.400
zu trainieren, wobei das mit den Modellen, die wir jetzt hier haben, alles relativ schnell

02:07:25.400 --> 02:07:32.180
geht und man es einfach auf dem lokalen Rechner mal durchspielen kann. Bei einem neuronalen

02:07:32.180 --> 02:07:35.760
Netzwerk wäre das bei dem Training was anderes, aber die Prognose ist hier nachher dann trotzdem

02:07:35.760 --> 02:07:39.680
super einfach, weil dann gehe ich halt einfach nur einmal quasi den Entscheidungsbaum lang

02:07:39.680 --> 02:07:43.620
oder laufe einmal mein neuronales Netzwerk von vorne nach hinten durch und fertig.

02:07:43.620 --> 02:07:48.160
Wenn ich den Weg kenne, dann kann ich natürlich relativ schnell sagen, wo ich hin soll.

02:07:48.160 --> 02:07:50.140
Genau, das kann auf schwacher Hardware laufen.

02:07:51.460 --> 02:07:56.460
Ja, cool. Dann habe ich tatsächlich heute wieder ganz viel über Machine Learning gelernt.

02:07:56.460 --> 02:07:58.020
Ich hoffe, ihr habt auch noch irgendwas mitgenommen.

02:07:58.020 --> 02:08:03.920
Ja, wenn du noch ein bisschen mehr lernen willst. Also ich finde immer, so eigene Projekte

02:08:03.920 --> 02:08:08.700
sind super und ansonsten einfach bei Kaggle mal einen Account machen.

02:08:08.700 --> 02:08:09.400
Ja, Kaggle, ja.

02:08:09.400 --> 02:08:13.960
Selbst wenn man da am Anfang nicht mitmacht. Also selber mitmachen ist sehr viel Aufwand,

02:08:13.960 --> 02:08:18.360
aber es reicht eigentlich auch einfach nur mal ein paar Challenges zu beobachten und mal

02:08:18.360 --> 02:08:19.340
ein paar Kernels sich aufzumessen.

02:08:19.340 --> 02:08:21.300
Oder mal so nachbauen oder so welche, die es schon gab.

02:08:21.400 --> 02:08:23.360
Mal gucken, wie gut man an die tollen Lösungen irgendwann rankommt.

02:08:23.360 --> 02:08:27.420
Genau. Das Schöne ist ja bei Kaggle, dass diese ganzen Lösungen eigentlich immer einfach

02:08:27.420 --> 02:08:32.360
alle online sind. Also diese Kernels, die da sind, die sind ja wirklich immer sehr, sehr

02:08:32.360 --> 02:08:37.840
gut. Gerade auch bei der Exploration, wo man, also so ein Kernel ist ja vom Prinzip her

02:08:37.840 --> 02:08:38.360
so ein Notebook.

02:08:38.360 --> 02:08:41.960
Ja, vielleicht noch ganz kurz. In Kaggle gibt es Bounties dafür, wenn man total tolle Prognosen

02:08:41.960 --> 02:08:44.360
herstellt. Also nur das vielleicht mal so für die Leute, die das schon nicht gesehen

02:08:44.360 --> 02:08:44.520
hatten.

02:08:44.520 --> 02:08:50.440
Genau, genau. Es ist also ein Wettbewerb für Data Science Projekte und Leute sind da so

02:08:50.440 --> 02:08:51.380
nett und stellen halt quasi.

02:08:51.380 --> 02:08:55.200
Ihre Kernels online, ihre Notebooks online und man kann da einfach mal gucken, wie die

02:08:55.200 --> 02:08:59.680
das lösen. Da kriegt man sowohl mit, welche Tools sind gerade irgendwie angesagt, wie

02:08:59.680 --> 02:09:05.380
geht man damit um. Man lernt so die Syntax und genau. Also ich lerne da auch jedes Mal,

02:09:05.380 --> 02:09:10.040
wenn ich so eines der top gerateten Notebooks da durchlese, lerne ich jedes Mal wieder was.

02:09:10.040 --> 02:09:13.320
Ja, finde ich auch super hilfreich.

02:09:13.320 --> 02:09:16.420
Ja, findet ihr, wie ihr alle eingeschaltet habt?

02:09:16.420 --> 02:09:17.080
Jo.

02:09:17.080 --> 02:09:19.080
Ihr findet immer die Informationen in den Shownotes.

02:09:19.080 --> 02:09:20.020
Jo, sehr.

02:09:20.020 --> 02:09:20.620
Genau.

02:09:20.620 --> 02:09:21.320
Wie kommt das von dir?

02:09:21.320 --> 02:09:22.200
Ich glaube, ich bin nicht lang, ja.

02:09:22.200 --> 02:09:28.460
Ja, ja, das kennen wir schon. Und ja, dann hört wieder rein, bleibt gewogen, wann auch

02:09:28.460 --> 02:09:33.160
immer ihr uns hört. Wenn ihr irgendwelche Feedback habt, schickt an eine E-Mail an uns,

02:09:33.160 --> 02:09:37.660
hallo at peißenpodcast.de oder Nico. Und ja, bis dahin.

02:09:37.660 --> 02:09:38.600
Jo.

02:09:38.600 --> 02:09:41.660
Genau. Hört wieder rein und bis bald.

02:09:41.660 --> 02:09:42.280
Tschüss.

02:09:42.280 --> 02:09:42.940
Jo, tschüss.
