WEBVTT

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

00:00:08.620 --> 00:00:14.400
Heute geht es um Machine Learning und ja, wir haben heute wieder einen Gast dabei im Wintergarten.

00:00:15.300 --> 00:00:15.620
Hallo Nico.

00:00:16.200 --> 00:00:17.540
Hi, schön, bei euch zu sein.

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

00:00:20.040 --> 00:00:21.740
Ja, Jochen ist auch da, genau.

00:00:22.700 --> 00:00:23.620
Genau, ich bin der Dominik.

00:00:24.400 --> 00:00:28.980
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.

00:00:29.280 --> 00:00:30.860
auf Nicos tollen Podcast

00:00:30.860 --> 00:00:32.820
InnoCast heißt der noch?

00:00:33.240 --> 00:00:34.020
InnoTechCast, genau.

00:00:34.920 --> 00:00:36.020
Der InnoTechCast

00:00:36.020 --> 00:00:39.160
ist mein Podcast-Projekt, läuft auch so seit

00:00:39.160 --> 00:00:40.420
ein bisschen über einem Jahr jetzt

00:00:40.420 --> 00:00:43.300
und da geht es halt nicht nur konkret um Python,

00:00:43.300 --> 00:00:45.700
sondern um alle möglichen

00:00:45.700 --> 00:00:46.880
Sachen, die irgendwie

00:00:46.880 --> 00:00:48.940
Nerds und ITler interessieren könnten,

00:00:49.160 --> 00:00:51.260
irgendwie von Containern über

00:00:51.260 --> 00:00:53.340
irgendwie so DevOps-Geschichten,

00:00:53.720 --> 00:00:55.080
einzelne Programmiersprachen.

00:00:55.700 --> 00:00:57.100
Was haben wir so gemacht? Wir haben Go gemacht,

00:00:57.400 --> 00:00:58.540
wir haben Rust behandelt,

00:00:59.120 --> 00:01:00.860
Wir hatten auch schon mal eine Folge so ein bisschen zu peisen.

00:01:02.660 --> 00:01:04.120
Also es ist auf jeden Fall sehr spannend, hört da mal rein.

00:01:04.720 --> 00:01:05.740
Kann ich empfehlen, klingt gut.

00:01:07.400 --> 00:01:07.720
Genau.

00:01:08.440 --> 00:01:10.880
Ja, dann fangen wir doch mal mit dem richtigen Thema an jetzt

00:01:10.880 --> 00:01:15.300
und gehen das Beispiel durch, was wir für das Machine Learning machen wollen.

00:01:15.300 --> 00:01:18.520
Ja, wahrscheinlich sollten wir erstmal so ein bisschen...

00:01:18.520 --> 00:01:21.780
Erstmal nochmal so allgemein vielleicht, was ist denn das überhaupt, das Machine Learning?

00:01:21.940 --> 00:01:22.360
Was macht das denn?

00:01:22.360 --> 00:01:22.780
Ja, das denke ich auch.

00:01:23.020 --> 00:01:26.560
Wie viel Statistik ist das eigentlich oder ist das Statistik oder was ist das

00:01:26.560 --> 00:01:28.500
oder macht da irgendwelche magischen

00:01:28.500 --> 00:01:30.440
Dinge, der Computer einfach magische

00:01:30.440 --> 00:01:31.980
Sachen und dann kommt irgendwie wusch

00:01:31.980 --> 00:01:33.740
künstliche Intelligenz daraus.

00:01:34.260 --> 00:01:36.420
Ja, das ist ja das Gefühl, was man heute in den Medien, finde ich,

00:01:36.460 --> 00:01:38.300
irgendwie immer bekommt. Also es ist halt so ein

00:01:38.300 --> 00:01:40.300
Buzzword, was überall rumschwirbt, genauso wie

00:01:40.300 --> 00:01:42.600
irgendwie künstliche Intelligenz.

00:01:43.160 --> 00:01:44.540
Genau, aber im Wesentlichen geht

00:01:44.540 --> 00:01:46.400
es ja darum, im Endeffekt gewisse

00:01:46.400 --> 00:01:48.140
Strukturen in den Daten zu finden,

00:01:48.820 --> 00:01:50.240
um eben Prognosen

00:01:50.240 --> 00:01:52.660
über die Zukunft zu lernen.

00:01:52.840 --> 00:01:54.580
Das heißt einfach, ich programmiere nicht mehr alles

00:01:54.580 --> 00:01:56.500
komplett deterministisch runter, was

00:01:56.500 --> 00:01:58.540
ich irgendwie wie von einem gewissen

00:01:58.540 --> 00:02:00.600
Eingabewert zu einem gewissen Ausgabewert komme,

00:02:01.060 --> 00:02:02.640
sondern ich habe halt eine gewisse

00:02:02.640 --> 00:02:04.300
große Menge an Trainingsdaten

00:02:04.300 --> 00:02:06.440
und habe dann Algorithmen,

00:02:06.680 --> 00:02:07.800
die gewisse Parameter

00:02:07.800 --> 00:02:10.640
anpassen bei solchen sogenannten

00:02:10.640 --> 00:02:12.420
Trainingsläufen und daraus

00:02:12.420 --> 00:02:14.580
quasi generelle Strukturen aus den Daten erkennen,

00:02:14.880 --> 00:02:16.640
um dann damit letztendlich

00:02:16.640 --> 00:02:18.720
Schlussfolgerungen für die Zukunft

00:02:18.720 --> 00:02:20.560
oder für unbekannte Daten

00:02:20.560 --> 00:02:22.660
zu ermöglichen. So hätte ich das

00:02:22.660 --> 00:02:25.240
zusammengefasst. Ja, würde ich

00:02:25.240 --> 00:02:27.360
prinzipiell genauso. Der Computer lernt so,

00:02:27.640 --> 00:02:29.360
was er mit neuen Sachen dann anfangen

00:02:29.360 --> 00:02:30.840
muss, aus alten Dingen.

00:02:31.340 --> 00:02:33.220
Genau, es gibt einmal, es gibt keine

00:02:33.220 --> 00:02:35.340
allgemeingültige Definition, was jetzt Machine Learning

00:02:35.340 --> 00:02:36.080
ist, aber also

00:02:36.080 --> 00:02:38.660
eine von Tom Mitchell wäre halt

00:02:38.660 --> 00:02:41.000
so ganz allgemein gehalten, ja,

00:02:41.140 --> 00:02:43.320
Machine Learning führt

00:02:43.320 --> 00:02:44.980
halt dazu, dass Computer oder dass Programme

00:02:44.980 --> 00:02:46.820
aus Erfahrung lernen irgendwie,

00:02:47.460 --> 00:02:48.420
mit Erfahrung besser werden.

00:02:50.540 --> 00:02:50.900
Genau,

00:02:51.320 --> 00:02:53.240
wenn man das jetzt mit traditionellem

00:02:53.240 --> 00:02:55.020
Programmieren vergleichen würde, dann ist es halt so,

00:02:55.240 --> 00:03:21.560
Dass man eben selbst, wenn man damit programmiert, sozusagen diese Zuordnung von, man bekommt irgendwelche Eingaben und dann soll halt irgendwie irgendwas rauskommen am Schluss, machen muss. Und wenn man jetzt Machine Learning verwendet, dann macht diesen Schritt halt wie ein mathematisches Optimierungsverfahren. Und das sich orientiert an Trainingsbeispielen, an Beispielen für, das ist reingegangen und das ist rausgekommen und so sollte das halt sein.

00:03:21.560 --> 00:03:29.560
Aber genau das ist ja auch das, was dann der Mensch dann doch wieder macht. Das heißt, der Mensch macht ja diese Vorarbeit, indem er die Trainingsdaten mit den richtigen Zuordnungen, mit den richtigen Labels bereitstellt.

00:03:30.500 --> 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:50.060 --> 00:04:08.620
Und es gibt auch diverse Probleme, die man sonst gar nicht in den Griff kriegt. Also wo man tatsächlich versucht hat, einen Algorithmus zu schreiben, der das tut, wie zum Beispiel eben sowas wie bei Bildern Katzen von Hunde unterscheiden oder so. Aber das geht halt gar nicht, weil man das halt nicht wirklich in einen Algorithmus reinbekommt.

00:04:08.620 --> 00:04:14.680
Man kann nicht so ein Gegenstand definieren. Eine Katze ist irgendwie so ein kleines Tier und grau und weiß und so weiter. Das ist schwer zu unterscheiden.

00:04:15.320 --> 00:04:36.600
Ja, oder auch das Arbeiten mit Sprache finde ich ein gutes Beispiel, da hat man halt viele, viele Algorithmen entwickelt, die auch zu einem gewissen Grad funktionieren, aber man ist mit Übersetzungen halt einfach quasi dann auf so einem Plateau spähen geblieben und kam da nicht mehr weiter und dank Deep Learning Verfahren, also tiefen neuronalen Netzen ist es halt eben dann möglich geworden, dann nochmal ganz neue Lernraten zu erreichen.

00:04:36.920 --> 00:05:06.900
Ja, das ist genau, das ist halt auch Stichwort Deep Learning eigentlich das Ding, was in den letzten paar Jahren halt diesen Hype irgendwie befeuert hat und da ist durchaus irgendwie ordentlich was dran, also es gehen inzwischen viele Sachen, die früher überhaupt gar nicht gingen und ja, aber natürlich ist es immer schwer für Leute, die das jetzt nicht so ordentlich verfolgen können und wer tut das halt, außer die irgendwie tatsächlich damit arbeiten, zu unterscheiden, was denn jetzt irgendwie geht und was nicht geht und was eigentlich das Coole daran ist,

00:05:06.920 --> 00:05:16.380
Und in den Medien hat man dann doch oft das Gefühl, dass man davon ausgeht, dass das irgendwas Magisches ist, dann geht halt alles und das ist ja jetzt auch nicht so.

00:05:17.120 --> 00:05:33.240
Das ist genau der spannende Punkt. Du hast nämlich gerade versucht zu erklären, dass das, was da passiert, irgendwelche mathematischen Algorithmen sind und die halt zu verstehen als Mensch oder daran zu schrauben zu können, die Parameter, die man halt irgendwie bei Maschinenlöhnen noch einstellt und das halt dann so durchblicken.

00:05:33.240 --> 00:05:55.620
Also was das zu tun hat jetzt mit Statistik oder so, das ist vielleicht nochmal ganz spannend, weil dann würde man vielleicht auch nicht nur glauben, dass Magie, also ne, vielleicht sowas mit zu tun, wenn irgendjemand neue Sachen erfindet, irgendeine Geometrie entdeckt, dann ist das vielleicht auch ganz magisch für jemand, der sowas noch nie gesehen hat und deswegen ist halt diese künstliche Intelligenz gar nicht so künstlich, wie wir dachten, aber dann trotzdem so ein Phänomen, was gerade ja bei den Leuten, die sich damit nicht auskennen, so ankommt.

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

00:06:02.960 --> 00:06:05.960
Genau, also warum kann der Computer jetzt einen Hund von einer Katze unterscheiden? Wie soll das denn gehen?

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

00:06:13.900 --> 00:06:21.300
Aber ist das nicht eigentlich immer so? Also wenn man halt quasi irgendein Blackbox-Modell hat und da nicht reinschauen kann, dann wirkt das wie Magie.

00:06:21.300 --> 00:06:23.340
und wenn man halt nach und nach die

00:06:23.340 --> 00:06:24.940
Informationen da drin versteht,

00:06:25.440 --> 00:06:27.220
dann, ja, blickt man halt, okay, das

00:06:27.220 --> 00:06:29.120
hat gewisse Schlussfolgerungen. Ich meine, es hat schon

00:06:29.120 --> 00:06:31.400
Verstehen wir die wirklich bei Machine Learning? Das habe ich jetzt nämlich auch noch nicht

00:06:31.400 --> 00:06:33.340
so ganz verstanden. Nee, genau,

00:06:33.480 --> 00:06:35.380
da gibt es natürlich einen Unterschied zwischen

00:06:35.380 --> 00:06:37.080
so eben Blackbox, Whitebox-Verfahren,

00:06:37.800 --> 00:06:39.080
bei denen man, also bei denen

00:06:39.080 --> 00:06:40.880
sozusagen, ja,

00:06:41.360 --> 00:06:43.340
Whitebox-Verfahren, sowas wie Decision Trees

00:06:43.340 --> 00:06:45.340
kann man prinzipiell verstehen, wie die funktionieren, weil man

00:06:45.340 --> 00:06:47.140
einfach sicher den Entscheidungsbaum

00:06:47.140 --> 00:06:48.860
aufmalen kann, dann kann man den halt von Hand durchgehen.

00:06:50.320 --> 00:06:51.160
Bei eben

00:06:51.160 --> 00:06:53.340
Blackbox-Verfahren wie so neuronalen Netzen

00:06:53.340 --> 00:06:55.340
oder so, kann man das prinzipiell eigentlich

00:06:55.340 --> 00:06:56.840
nicht wirklich. Also man kann zwar sehen,

00:06:57.300 --> 00:06:59.460
welche, was das Ding gemacht hat

00:06:59.460 --> 00:06:59.740
und

00:06:59.740 --> 00:07:03.180
auch irgendwie, was es erkannt hat und

00:07:03.180 --> 00:07:05.500
woran es sich orientiert, aber so letztlich

00:07:05.500 --> 00:07:07.340
genau verstehen, warum es jetzt zu einem bestimmten

00:07:07.340 --> 00:07:09.460
Ergebnis gekommen ist, kann man eigentlich

00:07:09.460 --> 00:07:11.320
nicht mehr. Und ich fürchte auch, einer der

00:07:11.320 --> 00:07:13.200
größten, wichtigsten Punkte,

00:07:13.440 --> 00:07:15.320
weshalb das so prinzipiell eine schwierige Geschichte

00:07:15.320 --> 00:07:17.300
ist, ist, dass die Modelle, je komplexer

00:07:17.300 --> 00:07:19.260
sie werden und desto mehr Parameter sie

00:07:19.260 --> 00:07:21.240
haben, werden sie halt auch sehr groß.

00:07:21.480 --> 00:07:22.580
Also wenn ich dann mehrere,

00:07:22.980 --> 00:07:24.880
ja, Millionen reicht ja schon, aber wenn ich

00:07:24.880 --> 00:07:26.940
mehrere hundert Millionen Parameter habe,

00:07:27.460 --> 00:07:29.160
dann ist das eine Menge, die ich

00:07:29.160 --> 00:07:30.560
als Mensch ja überhaupt nicht mehr überlegen kann.

00:07:30.820 --> 00:07:32.360
Das ist halt...

00:07:32.360 --> 00:07:34.860
Ja, wobei es inzwischen da ja schon viel

00:07:34.860 --> 00:07:36.580
Forschung gibt, gerade auch um

00:07:36.580 --> 00:07:39.700
neuronale Netze

00:07:39.700 --> 00:07:40.900
eben verständlich zu machen.

00:07:41.620 --> 00:07:42.720
Zum Beispiel ja irgendwie

00:07:42.720 --> 00:07:44.740
Lime ist ja da so ein Paket, was da in der Zeit

00:07:44.740 --> 00:07:46.700
total gehypt wurde, in dem es halt

00:07:46.700 --> 00:07:48.920
eben möglich ist, quasi an gewissen

00:07:48.920 --> 00:07:52.900
Zumindest für gewisse Objekte zu verstehen, wie das Modell quasi zu diesem Schluss kam.

00:07:53.880 --> 00:07:59.600
Also so blackboxig sind diese neuronalen Netze jetzt gar nicht mal mehr.

00:08:00.680 --> 00:08:01.960
Auch da gibt es Möglichkeiten, die zu verstehen.

00:08:01.960 --> 00:08:06.300
Aber ja, also klar, das ist natürlich deutlich komplexer als jetzt ein Entscheidungsbaum,

00:08:06.480 --> 00:08:09.960
den ja wahrscheinlich jeder mehr oder weniger kennt, was nicht viel anders ist als ein Flussdiagramm.

00:08:10.520 --> 00:08:14.260
Aber vielleicht wollen wir kurz noch mal ein, zwei Schritte zurückgehen und so ein bisschen die Hörer da abholen.

00:08:14.320 --> 00:08:16.380
Wir wollten ja so ein bisschen das Beispiel erzählen und vielleicht kommen wir dann,

00:08:16.460 --> 00:08:18.360
welche Methoden man denn verwenden kann für bestimmte

00:08:18.360 --> 00:08:20.260
Datensätze. Darum, ob wir jetzt so ein

00:08:20.260 --> 00:08:22.260
neuronales Netz oder so ein Decision Tree

00:08:22.260 --> 00:08:23.080
verwenden möchten.

00:08:24.200 --> 00:08:25.760
Würde das Sinn machen? Was sagt ihr?

00:08:26.960 --> 00:08:28.160
Ja, also ich finde, man muss

00:08:28.160 --> 00:08:30.300
erstmal festhalten, dass es halt irgendwie

00:08:30.300 --> 00:08:32.400
nicht so ist, dass jetzt plötzlich

00:08:32.400 --> 00:08:34.360
für alles man Deep Learning benutzen sollte,

00:08:34.460 --> 00:08:36.240
nur weil es jetzt gerade gehypt ist, sondern

00:08:36.240 --> 00:08:37.620
es gibt ganz, ganz viele Verfahren,

00:08:37.860 --> 00:08:40.280
die schon lange existieren, die bewährt

00:08:40.280 --> 00:08:42.380
sind und die für einige Tasks

00:08:42.380 --> 00:08:44.180
halt auch sehr gut funktionieren. Also wenn ich

00:08:44.180 --> 00:08:45.480
jetzt zum Beispiel einfach eine

00:08:45.480 --> 00:08:48.200
Zeitreihe vorhersagen möchte

00:08:48.200 --> 00:08:50.500
mit

00:08:50.500 --> 00:08:52.540
relativ einfachen Mitteln, um vielleicht den Abverkauf

00:08:52.540 --> 00:08:54.540
von einem Produkt vorherzusehen oder

00:08:54.540 --> 00:08:56.620
die Temperatur oder sowas, dann

00:08:56.620 --> 00:08:59.020
gibt es da jetzt erstmal Regressionsverfahren,

00:08:59.160 --> 00:09:00.900
die so schon sehr gut funktionieren

00:09:00.900 --> 00:09:02.740
und da muss man jetzt nicht zwangsläufig

00:09:02.740 --> 00:09:04.060
irgendwie Deep Learning draufwerfen.

00:09:04.500 --> 00:09:06.460
Ist halt eben was anderes wie bei der

00:09:06.460 --> 00:09:08.260
Bilderkennung, die du jetzt zum Beispiel erwähnt hast.

00:09:08.740 --> 00:09:10.360
Regression ist natürlich immer nur so gut, wie

00:09:10.360 --> 00:09:11.640
die Zukunft

00:09:11.640 --> 00:09:14.100
der Vergangenheit entspricht. Das ist ja vielleicht

00:09:14.100 --> 00:09:14.900
Ja, klar, genau.

00:09:16.280 --> 00:09:17.880
Aber das Problem haben Deep Learning Algorithmen

00:09:17.880 --> 00:09:18.560
an der Stelle genauso.

00:09:20.580 --> 00:09:21.020
Ja?

00:09:21.860 --> 00:09:24.100
Okay. Also natürlich hast du

00:09:24.100 --> 00:09:25.740
da nicht unbedingt dann immer so einen linearen

00:09:25.740 --> 00:09:26.620
Zusammenhang, aber

00:09:26.620 --> 00:09:30.060
ja, im Grunde natürlich

00:09:30.060 --> 00:09:32.100
so Dinge, die komplett neu sind.

00:09:32.800 --> 00:09:33.580
Ja, wenn es einmal

00:09:33.580 --> 00:09:36.240
Alph oder sowas ist, ein Hund oder eine Katze, weiß man nicht so genau.

00:09:37.060 --> 00:09:38.040
Ja, dann kommt was

00:09:38.040 --> 00:09:38.700
Neues auf die Welt.

00:09:39.700 --> 00:09:41.760
Genau, also es gibt auch

00:09:41.760 --> 00:09:44.000
Verfahren, die total einfach zu verstehen

00:09:44.000 --> 00:09:45.900
sind. Also sowas wie NaiveBase

00:09:45.900 --> 00:09:47.600
zum Beispiel. Das ist eine der ersten

00:09:47.600 --> 00:09:49.200
Geschichten, die

00:09:49.200 --> 00:09:52.020
also ich glaube 2004 hatte Paul Graham

00:09:52.020 --> 00:09:53.900
halt da irgendwie den Artikel

00:09:53.900 --> 00:09:55.360
veröffentlicht, The Plan for Spam.

00:09:56.400 --> 00:09:57.920
Jetzt musst du nochmal einmal kurz sagen, was

00:09:57.920 --> 00:09:59.940
NaiveBase überhaupt ist, für alle, die das noch nie gehört haben.

00:09:59.960 --> 00:10:01.940
Das ist auch ein Klassifikationsverfahren und zwar

00:10:01.940 --> 00:10:03.980
also ich, genau, ich wollte, also wenn man

00:10:03.980 --> 00:10:05.780
jetzt ein bisschen erklären möchte, wie funktioniert das oder wie

00:10:05.780 --> 00:10:07.520
funktioniert Machine Learning, dann ist der

00:10:07.520 --> 00:10:09.680
allereinfachste Fall, den man beschreiben kann,

00:10:09.780 --> 00:10:11.400
halt binäre Klassifikationen, vielleicht.

00:10:11.800 --> 00:10:13.160
So, womit man anfangen kann.

00:10:13.940 --> 00:10:14.300
Und

00:10:14.300 --> 00:10:17.640
ja, NaiveBase

00:10:17.640 --> 00:10:19.080
ist halt ein... Also binäre

00:10:19.080 --> 00:10:21.640
Klassifikation. Also drin oder nicht drin.

00:10:21.840 --> 00:10:23.620
Genau, man unterscheidet eigentlich nur zwei Klassen.

00:10:24.060 --> 00:10:25.360
Genau. Und

00:10:25.360 --> 00:10:27.640
Merkst du ganz kurz, genau, wenn man

00:10:27.640 --> 00:10:29.660
das mal zusammenfassen darf, man hat halt

00:10:29.660 --> 00:10:31.480
vom Prinzip her Supervised Machine Learning

00:10:31.480 --> 00:10:33.680
und Unsupervised Machine Learning, solche, wo

00:10:33.680 --> 00:10:35.840
ich irgendwie Daten habe, wo ich quasi

00:10:35.840 --> 00:10:37.540
Labels habe, wo ich sagen kann,

00:10:37.660 --> 00:10:39.460
okay, das soll quasi nachher rauskommen,

00:10:39.560 --> 00:10:41.660
das ist Supervised Machine Learning. Und es

00:10:41.660 --> 00:10:43.620
gibt solche, wo ich diese Information nicht habe,

00:10:43.700 --> 00:10:46.020
Das ist das Feld der Unsupervised-Machine-Learning-Sachen.

00:10:46.840 --> 00:10:49.260
Und im Feld von Supervised-Machine-Learning

00:10:49.260 --> 00:10:51.500
gibt es dann im Wesentlichen unterschiedliche Tasks.

00:10:51.580 --> 00:10:54.480
Es gibt eine Regression oder es gibt eine Klassifikation

00:10:54.480 --> 00:10:56.280
als die beiden typischsten Fälle.

00:10:57.060 --> 00:11:00.140
Und genau, der einfachste Fall wäre dann halt eben

00:11:00.140 --> 00:11:02.360
eine binäre Klassifikation, wo ich einfach nur sage,

00:11:03.160 --> 00:11:06.560
in folgendem Fall, Daumen hoch, Daumen runter, ja oder nein.

00:11:08.220 --> 00:11:08.700
Genau.

00:11:10.060 --> 00:11:12.340
Ich suche mal gerade, ob ich das hier...

00:11:12.340 --> 00:11:12.900
Ja, schau mal.

00:11:13.360 --> 00:11:14.660
finde, Moment.

00:11:15.880 --> 00:11:17.620
Wir wollten noch mal kurz erklären, was Space

00:11:17.620 --> 00:11:19.960
macht mit einer binären Klassifikation.

00:11:21.340 --> 00:11:21.700
Bevor

00:11:21.700 --> 00:11:23.380
wir dann vielleicht tatsächlich darauf eingehen, was für eine Möglichkeit

00:11:23.380 --> 00:11:25.860
man hat, jetzt so diese Klassifikation durchzuführen,

00:11:26.080 --> 00:11:27.500
weil, weiß ich, mehr als zwei

00:11:27.500 --> 00:11:29.520
Dinge, also wenn du zwei Merkmale hast, dann

00:11:29.520 --> 00:11:31.160
kannst du ja relativ einfach voneinander trennen, wenn die

00:11:31.160 --> 00:11:33.420
homogen sind untereinander

00:11:33.420 --> 00:11:35.400
in ihren eigenen Klassen. Und das wird ja umso

00:11:35.400 --> 00:11:36.940
komplexer, umso

00:11:36.940 --> 00:11:39.420
weniger heterogen die untereinander sind, also

00:11:39.420 --> 00:11:41.360
umso mehr die sich gleichen, dann hast du natürlich größere

00:11:41.360 --> 00:11:43.340
Probleme, dann ist es vielleicht auch so, dass du die Merkmale falsch

00:11:43.340 --> 00:11:45.320
anguckst oder so. Also du sollst halt schon

00:11:45.320 --> 00:11:46.640
unterscheidende Merkmale finden können.

00:11:47.300 --> 00:11:49.320
Und das ist halt im Prinzip das, was du mit Base dann relativ

00:11:49.320 --> 00:11:51.060
gut machen kannst. Du kannst halt dann sagen, ey, ist jetzt

00:11:51.060 --> 00:11:53.260
der Falter grün oder nicht? Oder schwarz

00:11:53.260 --> 00:11:55.060
oder so? Oder ist das halt eine Katze?

00:11:55.320 --> 00:11:57.280
Woran erkennt man das? Ich weiß nicht, ob sich

00:11:57.280 --> 00:11:58.660
jetzt Base für Katzen und Hunde schon

00:11:58.660 --> 00:12:01.120
eignen würde, weil das wird vielleicht schon

00:12:01.120 --> 00:12:03.100
schwierig. Ja, also für Bilder

00:12:03.100 --> 00:12:05.160
wird das sicherlich nicht gut funktionieren,

00:12:05.280 --> 00:12:07.180
aber wenn ich jetzt, eben

00:12:07.180 --> 00:12:08.740
das ist halt auch so ein klassisches Beispiel habe,

00:12:09.480 --> 00:12:11.820
wenn ich jetzt Spam von Nicht-Spam-Mails unterscheiden

00:12:11.820 --> 00:12:13.680
möchte, da ist es halt

00:12:13.680 --> 00:12:15.320
genauso, das war früher, waren die ganzen

00:12:15.320 --> 00:12:17.460
Spam-Filter irgendwie

00:12:17.460 --> 00:12:19.740
regelbasiert, also man erinnert sich da vielleicht noch so an

00:12:19.740 --> 00:12:21.820
Zeiten, ich habe das auch selber noch benutzt,

00:12:22.600 --> 00:12:23.280
ja, das war so ein

00:12:23.280 --> 00:12:25.000
Spam-Assassin,

00:12:26.160 --> 00:12:27.760
das hat sich dann halt die Header angeguckt

00:12:27.760 --> 00:12:29.540
und dann hat es halt manchen

00:12:29.540 --> 00:12:31.800
Providern mehr und manchen weniger vertraut

00:12:31.800 --> 00:12:32.200
und

00:12:32.200 --> 00:12:35.660
irgendwelche, insgesamt halt irgendwie

00:12:35.660 --> 00:12:37.540
einen Score ausgerechnet und gesagt, ah, okay,

00:12:37.800 --> 00:12:39.580
das hat jetzt einen Spam-Score von so und so viel

00:12:39.580 --> 00:12:41.160
oder so und so viel und ab einer bestimmten Grenze

00:12:41.160 --> 00:12:43.500
wurde dann halt abgeschnitten und gesagt, das ist Spam.

00:12:45.080 --> 00:12:45.560
Das hat

00:12:45.560 --> 00:12:47.460
ganz okay funktioniert, aber das war immer

00:12:47.460 --> 00:12:49.460
leicht zu unterlaufen von Spammern

00:12:49.460 --> 00:12:51.460
und Spam war immer eine relativ

00:12:51.460 --> 00:12:52.180
ärgerliche Geschichte.

00:12:53.600 --> 00:12:55.060
Bis dann halt eben

00:12:55.060 --> 00:12:56.320
Paul Graham, halt der

00:12:56.320 --> 00:12:57.500
ähm

00:12:57.500 --> 00:12:59.560
ähm

00:12:59.560 --> 00:13:02.960
ja, wie heißt der Inkubator, den er gegründet hat?

00:13:03.040 --> 00:13:03.960
Darüber ist er sehr bekannt geworden.

00:13:06.660 --> 00:13:08.800
habe ich jetzt gerade, ist mir entfallen,

00:13:08.960 --> 00:13:10.400
also der schreibt auch viele Essays und

00:13:10.400 --> 00:13:12.160
hat auch ein Buch geschrieben.

00:13:12.440 --> 00:13:13.340
Y Combinator tatsächlich.

00:13:14.280 --> 00:13:15.840
Vorher hat er es auf der Zunge, ich habe mich nur nicht getroffen.

00:13:16.740 --> 00:13:18.760
Ja, der

00:13:18.760 --> 00:13:20.560
schrieb dann halt irgendwie 2004

00:13:20.560 --> 00:13:21.760
ein Essay, so

00:13:21.760 --> 00:13:24.180
A Plan for Spam, also ich habe da irgendwie so eine Idee,

00:13:24.280 --> 00:13:25.660
wie wir dieses Problem endgültig in den Griff kriegen.

00:13:26.220 --> 00:13:28.160
Und da schlägt er halt vor, irgendwie so

00:13:28.160 --> 00:13:29.760
Naive Base zu verwenden, um

00:13:29.760 --> 00:13:32.040
inhaltsmäßig irgendwie

00:13:32.040 --> 00:13:34.340
Spams von Nicht-Spams zu

00:13:34.340 --> 00:13:36.220
unterscheiden, weil, naja, irgendwie

00:13:36.220 --> 00:13:38.160
ein Spammer muss ja reinschreiben, dass er was

00:13:38.160 --> 00:13:40.240
verkaufen will oder muss ja irgendwie, er kann ja

00:13:40.240 --> 00:13:42.040
den Content kann er im Grunde nicht wirklich

00:13:42.040 --> 00:13:44.800
so ändern,

00:13:44.940 --> 00:13:46.380
dass man das nicht mehr als Spam erkennen

00:13:46.380 --> 00:13:48.260
kann, weil dann kann es auch der Mensch

00:13:48.260 --> 00:13:49.400
nicht mehr als Spam erkennen und dann

00:13:49.400 --> 00:13:51.600
verfehlt das ja seinen Zweck.

00:13:52.820 --> 00:13:54.080
Liebe Freund, ich brauche Hilfe.

00:13:54.920 --> 00:13:56.260
Ja gut, okay, das ist jetzt eine bestimmte

00:13:56.260 --> 00:13:56.880
Art von Spam.

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

00:14:00.260 --> 00:14:02.200
Die kommen durch? Da ist aber irgendwas mit

00:14:02.200 --> 00:14:04.280
deinem Spam-Filter nicht in Ordnung. Was für ein Spam-Filter?

00:14:05.080 --> 00:14:05.400
Okay.

00:14:06.180 --> 00:14:07.360
Nein, also sie landen bei mir im Spam-Filter

00:14:07.360 --> 00:14:08.120
und ich kann dann immer sehen,

00:14:08.240 --> 00:14:09.960
okay, es war eine Message im Spam-Filter,

00:14:10.040 --> 00:14:11.120
was auch nicht so häufig passiert.

00:14:11.500 --> 00:14:12.480
Ach so, okay, gut, ja.

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

00:14:15.940 --> 00:14:19.600
Das ist halt, mach einfach aus den Mails,

00:14:19.840 --> 00:14:23.180
aus dem Inhalt deiner Mails im Spam-Ordner

00:14:23.180 --> 00:14:24.340
eine lange Liste von Wörtern,

00:14:25.080 --> 00:14:27.460
zähle, wie oft ein Wort da drin halt vorkommt,

00:14:28.420 --> 00:14:29.560
merke die Gesamtzahl der Wörter

00:14:29.560 --> 00:14:31.080
und die Gesamtzahl der Mails, die da drin waren

00:14:31.080 --> 00:14:33.680
und mach das Ganze auch nochmal für den Ordner

00:14:33.680 --> 00:14:34.640
mit den Nicht-Spam-Mails

00:14:34.640 --> 00:14:36.060
und

00:14:36.060 --> 00:14:38.740
das ist schon das Training.

00:14:39.000 --> 00:14:40.980
Das war's. Also man hat jetzt

00:14:40.980 --> 00:14:43.160
quasi an jedem Wort sozusagen nur dranstehen

00:14:43.160 --> 00:14:44.920
quasi

00:14:44.920 --> 00:14:46.920
wie oft das halt

00:14:46.920 --> 00:14:49.080
vorkommt und man hat nochmal eine Zahl für

00:14:49.080 --> 00:14:50.720
wie viel

00:14:50.720 --> 00:14:52.260
Mails man gesammelt hat.

00:14:52.300 --> 00:14:54.980
Er hat Penis gesagt und dann sagt er, nee, ist wahrscheinlich Spam.

00:14:55.740 --> 00:14:56.400
Also so in etwa.

00:14:57.680 --> 00:14:59.060
Genau. Und die Klassifikation,

00:14:59.700 --> 00:15:00.820
also wenn man das gemacht hat,

00:15:00.820 --> 00:15:02.800
ist man mit dem Training schon fertig und das ist auch schon das

00:15:02.800 --> 00:15:04.220
Modell. Und die

00:15:04.220 --> 00:15:06.260
Klassifikation funktioniert jetzt so,

00:15:06.680 --> 00:15:08.640
wenn man jetzt eine zu prüfende Mail hat, dann zerlegt man die

00:15:08.640 --> 00:15:10.040
eben auch wieder in eine Liste von Wörtern.

00:15:10.940 --> 00:15:11.680
Man macht aus

00:15:11.680 --> 00:15:14.420
dieser Wortliste eine Liste von Zahlen

00:15:14.420 --> 00:15:16.560
und man ersetzt jetzt

00:15:16.560 --> 00:15:18.600
jedes Wort eben durch die Kategoriefrequenz.

00:15:19.060 --> 00:15:20.160
Das hatte man ja vorher schon

00:15:20.160 --> 00:15:22.500
ausgerechnet, sozusagen. Man wusste halt, wie oft

00:15:22.500 --> 00:15:24.600
jedes Wort im Spam- und im Nicht-Spam-Ordner

00:15:24.600 --> 00:15:26.080
vorkommt. Und

00:15:26.080 --> 00:15:28.120
sozusagen, ja,

00:15:28.260 --> 00:15:30.720
man ersetzt jetzt die Wörter eben durch die Kategoriefrequenz

00:15:30.720 --> 00:15:31.700
und

00:15:31.700 --> 00:15:34.860
multipliziert jetzt einfach alle diese Zahlen

00:15:34.860 --> 00:15:36.720
miteinander und

00:15:36.720 --> 00:15:39.000
bekommt dann halt eine Wahrscheinlichkeit, dass eine Mail Spam

00:15:39.000 --> 00:15:40.700
oder nicht Spam ist. Und

00:15:40.700 --> 00:15:43.060
ja, die Zahlen werden relativ klein

00:15:43.060 --> 00:15:45.140
sein, weil das sind alles relativ kleine Wahrscheinlichkeiten.

00:15:45.520 --> 00:15:46.880
Wenn die noch miteinander multipliziert, ist es

00:15:46.880 --> 00:15:49.020
super nahe Null. Das heißt,

00:15:49.060 --> 00:15:51.120
man muss das Ganze noch so normalisieren, dass hinterher ja halt

00:15:51.120 --> 00:15:52.140
irgendwie quasi

00:15:52.140 --> 00:15:55.040
der Wert für Spam und nicht Spam, wenn man das addieren würde,

00:15:55.300 --> 00:15:57.040
eins ergibt. Aber ja, ist ja auch

00:15:57.040 --> 00:15:58.860
kein Problem. Und das war es schon. Also es ist wirklich

00:15:58.860 --> 00:16:00.320
nicht, ist keine große

00:16:00.320 --> 00:16:03.120
Hexerei.

00:16:03.240 --> 00:16:05.340
Wie sagen wir, Raketenchirurgie.

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

00:16:07.860 --> 00:16:09.440
Genau, das kann man ja einfach sich eigentlich auch noch so

00:16:09.440 --> 00:16:10.880
in einem Algorithmus darstellen. Da braucht man

00:16:10.880 --> 00:16:13.540
ja, keine komplexen

00:16:13.540 --> 00:16:15.320
Selbstlernverfahren eigentlich noch, nicht wahr?

00:16:16.120 --> 00:16:17.480
Ja, also gut, das Ding

00:16:17.480 --> 00:16:18.900
lernt ja tatsächlich. Also wenn ich jetzt sage,

00:16:19.240 --> 00:16:20.800
eben, ich habe bisher nur

00:16:20.800 --> 00:16:23.680
Mails,

00:16:23.840 --> 00:16:25.360
die mir Produkte zur

00:16:25.360 --> 00:16:27.500
Vergrößerung meiner primären Geschlechtsmerkmale

00:16:27.500 --> 00:16:29.420
irgendwie mir so ein Zeugs andrehen

00:16:29.420 --> 00:16:31.240
wollen, bekommen und ich kriege jetzt zum ersten Mal

00:16:31.240 --> 00:16:33.180
ein Nigeria-Spam, wo mich jemand halt

00:16:33.180 --> 00:16:34.560
dazu bringen will, einen kleinen Betrag

00:16:34.560 --> 00:16:38.960
ihm zu geben,

00:16:39.100 --> 00:16:40.980
um einen viel größeren zu bekommen,

00:16:41.680 --> 00:16:42.800
dann würde ich halt

00:16:42.800 --> 00:16:44.380
das halt auch mit in die Spams

00:16:44.380 --> 00:16:46.820
reintun und dann müsste ich halt wieder neu

00:16:46.820 --> 00:16:48.040
diese Zahlen

00:16:48.040 --> 00:16:51.220
ermitteln. Genau, die müssen halt

00:16:51.220 --> 00:16:53.320
wieder neu gebildet werden, aber

00:16:53.320 --> 00:16:55.040
dann würden sich die Frequenzen wahrscheinlich zum Beispiel

00:16:55.040 --> 00:16:56.960
für so ein Wort wie Prinz oder so oder Schweizer

00:16:56.960 --> 00:16:59.240
Bankkonto entsprechend verändern

00:16:59.240 --> 00:17:01.240
und dann hoffentlich beim nächsten Mal werden wieder so

00:17:01.240 --> 00:17:03.220
eine Mail dieser Art... Ziemlich ärgerlich für Prinzen mit Schweizer

00:17:03.220 --> 00:17:04.860
Bankkonto. Ja, die haben

00:17:04.860 --> 00:17:06.940
ein Problem mit, die werden

00:17:06.940 --> 00:17:08.180
ja,

00:17:09.000 --> 00:17:11.320
die haben mit Meldern keinen Spaß mehr seitdem.

00:17:13.120 --> 00:17:13.560
Genau

00:17:13.560 --> 00:17:15.280
und das, ja, und dann

00:17:15.280 --> 00:17:17.140
passt sich das durchaus halt

00:17:17.140 --> 00:17:18.680
quasi neuen Mustern an, wenn

00:17:18.680 --> 00:17:21.260
die nächste Masche um die Ecke kommt, dann braucht man halt nur die

00:17:21.260 --> 00:17:22.460
ersten paar

00:17:22.460 --> 00:17:25.220
sozusagen richtig zu sortieren und dann sollte das

00:17:25.220 --> 00:17:27.060
automatisch funktionieren und mitlernen.

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

00:17:29.240 --> 00:17:38.000
Ja, jetzt haben wir kurz an Base-Klassifikationen erklärt. Wir sind aber immer noch nicht bei dem Beispiel angekommen, was wir irgendwie den Menschen, also wie macht man das denn überhaupt?

00:17:38.120 --> 00:17:58.520
Wir haben versprochen, dass wir irgendwie praktisch durchgehen wollen. Da hätte ich mal gesagt, lass uns das mal machen. Wir packen mit Sicherheit unter die Folgen mal einen Link zu dem Repository, was wir dafür benutzen wollen. Das ist vom Jochen. Da hat er halt eben eine Schulung drin, eine Data Science Schulung, woraus wir jetzt vor allem gleich mal das Beispiel nehmen wollen für die Text-Klassifikation.

00:17:59.120 --> 00:18:01.620
und genau, wenn man da drauf geht,

00:18:01.700 --> 00:18:03.420
sieht man in dem Readme auch erstmal irgendwie alle

00:18:03.420 --> 00:18:05.380
Informationen, wie man sich das Ganze zieht, also

00:18:05.380 --> 00:18:07.560
man klont sich halt erstmal das Git-Repository

00:18:07.560 --> 00:18:09.260
soweit, so gut

00:18:09.260 --> 00:18:11.660
und dann kommen auch schon die ersten Python-spezifischen

00:18:11.660 --> 00:18:13.460
Sachen, denn dann müssen

00:18:13.460 --> 00:18:14.900
wir uns erstmal irgendwie mit Conda

00:18:14.900 --> 00:18:17.300
eine entsprechende Umgebung aufsetzen. Jochen,

00:18:17.380 --> 00:18:19.500
sag doch mal, warum sollte man das immer machen?

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

00:18:21.140 --> 00:18:23.340
Ja, also Conda ist

00:18:23.340 --> 00:18:25.660
sozusagen der Paketmanager

00:18:25.660 --> 00:18:27.560
des Teils

00:18:27.560 --> 00:18:29.000
von Python,

00:18:29.120 --> 00:18:32.600
der sich mit so Data-Science-Maschinen-Learning-Geschichten beschäftigt.

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

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

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

00:18:42.480 --> 00:18:50.120
Und ja, es ist, früher hatte man ja irgendwie mal so die Hoffnung,

00:18:51.080 --> 00:18:55.580
dass die Distribution, das ganze Paket-Installations-Ding

00:18:55.580 --> 00:18:57.820
halt irgendwie überflüssig machen würden

00:18:58.460 --> 00:19:10.360
Und sich halt um Abhängigkeiten und sowas kümmern und das ist irgendwie nicht passiert. Also stattdessen ist es so, dass irgendwie jede Programmiersprache so gefühlt irgendwie ihren eigenen Paketmanager hat.

00:19:11.180 --> 00:19:12.940
Und bei Python ist es ein bisschen

00:19:12.940 --> 00:19:14.780
besonders schlimm, weil da gibt es halt nicht nur einen,

00:19:14.880 --> 00:19:17.040
sondern mehrere. Je nachdem, in welcher

00:19:17.040 --> 00:19:20.840
Community man sich da aufhält.

00:19:21.140 --> 00:19:22.880
Wenn man irgendwie eher Web-Entwicklung oder sonst

00:19:22.880 --> 00:19:24.740
wie Python-Entwicklung macht,

00:19:24.820 --> 00:19:26.020
dann ist es eher Pip und

00:19:26.020 --> 00:19:28.740
als Repository für Pakete

00:19:28.740 --> 00:19:29.360
halt PyPI.

00:19:30.800 --> 00:19:32.560
Lass dir sagen, das Problem hat nicht nur Python.

00:19:33.100 --> 00:19:34.780
Rust ist da auch ganz schlimm, habe ich schon

00:19:34.780 --> 00:19:36.140
gelernt, aber ja.

00:19:37.260 --> 00:19:38.920
Ja, es ist auf jeden Fall ziemlich

00:19:38.920 --> 00:19:40.840
anstrengend. Ich weiß gar nicht, ob ich Conda so verwenden

00:19:40.840 --> 00:19:41.980
würde, so außerhalb von Daten.

00:19:42.060 --> 00:19:44.380
Ne, würde ich glaube ich auch nicht, mache ich auch nicht.

00:19:44.540 --> 00:19:46.440
Also wenn ich Web-Projekte mache, dann nehme ich

00:19:46.440 --> 00:19:48.760
eher PIP und

00:19:48.760 --> 00:19:50.840
tatsächlich funktionieren

00:19:50.840 --> 00:19:52.980
die meisten Sachen auch, wenn man sie mit PIP installiert.

00:19:53.660 --> 00:19:54.620
Also tatsächlich auch die ganzen

00:19:54.620 --> 00:19:55.920
Datensachen funktionieren über PIP?

00:19:56.860 --> 00:19:58.780
Ja, schon.

00:20:00.200 --> 00:20:00.320
Sie

00:20:00.320 --> 00:20:02.600
funktionieren zumindest gut genug, als dass man das

00:20:02.600 --> 00:20:04.680
meistens einfach so verwenden kann. Wenn ich jetzt

00:20:04.680 --> 00:20:06.560
irgendwie tatsächlich

00:20:06.560 --> 00:20:08.240
ein Modell trainieren wollte,

00:20:08.340 --> 00:20:10.260
aber das will man halt, wenn man

00:20:10.260 --> 00:20:11.880
wenn es einen Web-Server hat, der irgendwie auch nur

00:20:11.880 --> 00:20:15.100
Pandas noch mitbraucht, um halt irgendwelche

00:20:15.100 --> 00:20:16.340
Sachen anzunehmen, oder

00:20:16.340 --> 00:20:18.300
selbst ein Web-Server, der jetzt halt hinter

00:20:18.300 --> 00:20:20.380
irgendeinem ARP-Modell hat, was irgendwas vorhersagt

00:20:20.380 --> 00:20:22.540
oder was irgendwas klassifiziert und dann die Ergebnisse zurückgibt,

00:20:23.160 --> 00:20:24.380
da ist es im Grunde egal, da kann man

00:20:24.380 --> 00:20:26.200
das bei PIP installieren, aber wenn ich jetzt

00:20:26.200 --> 00:20:27.980
irgendwie was trainieren wollte,

00:20:28.980 --> 00:20:30.360
dann würde ich eher

00:20:30.360 --> 00:20:31.760
die Conda-Pakete nehmen

00:20:31.760 --> 00:20:34.280
oder vielleicht sogar

00:20:34.280 --> 00:20:36.060
spezielle Docker-Images oder sowas.

00:20:37.640 --> 00:20:38.320
Ja, aus meiner Sicht

00:20:38.320 --> 00:20:40.340
hatte halt Conda vor allem zwei Vorteile. Zum einen

00:20:40.340 --> 00:20:41.180
ist es halt schon mal

00:20:41.180 --> 00:20:44.040
zusammen das, was sonst

00:20:44.040 --> 00:20:46.140
PIP und Virtual Env ist. Also ich habe die

00:20:46.140 --> 00:20:48.300
Möglichkeit, sowohl eine virtuelle Umgebung

00:20:48.300 --> 00:20:50.200
mit zusammenzubauen und dann

00:20:50.200 --> 00:20:52.240
halt eben in die die Pakete mit rein zu installieren.

00:20:52.480 --> 00:20:54.160
Was man häufig möchte,

00:20:54.260 --> 00:20:56.100
wenn man gerade zum Beispiel so ein Experiment macht,

00:20:56.340 --> 00:20:57.840
dann möchte ich vielleicht meine

00:20:57.840 --> 00:21:00.100
Basis-Version an Paketen so lassen,

00:21:00.180 --> 00:21:01.960
wie ich sie hatte und dann halt mal für jetzt

00:21:01.960 --> 00:21:04.000
eine Konferenz zum Beispiel mir nochmal eine zweite

00:21:04.000 --> 00:21:05.840
daneben stellen. Das müsste ich ja sonst mit

00:21:05.840 --> 00:21:07.680
Virtual-End-Pip quasi in zwei

00:21:07.680 --> 00:21:10.060
Schritten machen. Ja gut, aber normalerweise

00:21:10.060 --> 00:21:12.080
machst du ja Virtual-End-Wrapper, dann einen Befehl

00:21:12.080 --> 00:21:13.740
und dann ist das Ding ja oben. Genau.

00:21:14.620 --> 00:21:16.140
Ich habe tatsächlich einen Python-Skript für sowas

00:21:16.140 --> 00:21:18.080
geschrieben, der auch genau das gleiche macht, wenn ich das will.

00:21:18.180 --> 00:21:20.460
Aber ja. Genau, und der zweite Punkt ist,

00:21:21.380 --> 00:21:22.160
Conda kann halt

00:21:22.160 --> 00:21:23.660
einfach ja noch ein bisschen mehr als Pip.

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

00:21:26.760 --> 00:21:28.220
die außerhalb von Python-Paketen

00:21:28.220 --> 00:21:30.100
liegen, lösen, was dann halt auch

00:21:30.100 --> 00:21:32.300
interessant wird, wenn es halt um Treiber-Support und so weiter

00:21:32.300 --> 00:21:33.240
geht.

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

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

00:21:38.140 --> 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.600 --> 00:21:46.300
so durchgesetzt hat.

00:21:47.440 --> 00:21:48.680
Ja, ja, also ich...

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

00:21:50.360 --> 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.580 --> 00:21:58.220
Ich glaube, das ist auch so ein low-leveliger Ansatz.

00:21:58.240 --> 00:21:59.300
Das ist ein Grund, warum sie das so verbreitet hat.

00:21:59.400 --> 00:22:00.540
Wobei ich jetzt ehrlich gesagt zum Beispiel

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

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

00:22:04.520 --> 00:22:06.600
Also das Anaconda-Distribution ist

00:22:06.600 --> 00:22:08.600
eigentlich sozusagen das eigentliche

00:22:08.600 --> 00:22:10.540
Ding, was irgendwie da produziert

00:22:10.540 --> 00:22:12.640
wird. Ich habe immer Miniconda verwendet

00:22:12.640 --> 00:22:14.440
und dann halt das installiert, was ich

00:22:14.440 --> 00:22:16.460
gerade gebraucht habe. Also der Unterschied ist, Anaconda

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

00:22:18.540 --> 00:22:20.580
die man potenziell so gebrauchen könnte und Miniconda

00:22:20.580 --> 00:22:22.440
ist halt erstmal klein und schlank und

00:22:22.440 --> 00:22:24.580
dann muss man halt alles quasi mit

00:22:24.580 --> 00:22:26.320
dazu installieren, was man dann noch gerne hätte.

00:22:26.800 --> 00:22:28.400
Ja, und eben

00:22:28.400 --> 00:22:30.220
der Vorteil gegenüber PIP oder

00:22:30.220 --> 00:22:32.420
sagen wir mal so, das ist halt auch nicht mehr so

00:22:32.420 --> 00:22:34.520
ganz, das war früher ein Riesen

00:22:34.520 --> 00:22:36.440
Unterschied, ist heute nicht mehr ganz so relevant,

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

00:22:38.480 --> 00:22:40.580
bei Conda auch installieren kann. Also man kann

00:22:40.580 --> 00:22:42.640
halt auch Bibliotheken, die unten

00:22:42.640 --> 00:22:44.620
drunter liegen, also eben nicht nur Python-Pakete,

00:22:44.700 --> 00:22:46.320
sondern eben auch sowas, man kann auch theoretisch sowas wie

00:22:46.320 --> 00:22:48.020
Libc irgendwie mit Conda

00:22:48.020 --> 00:22:50.480
installieren und die dann halt

00:22:50.480 --> 00:22:52.180
in einem Conda-Environment verwenden

00:22:52.180 --> 00:22:54.500
und muss halt, also das ist

00:22:54.500 --> 00:22:56.240
auch so ein Problem, wenn man jetzt auf größeren

00:22:56.240 --> 00:22:58.560
Servern unterwegs ist, die halt

00:22:58.560 --> 00:22:59.740
unter Umständen irgendwie

00:22:59.740 --> 00:23:02.080
so eine antike Debian-Version

00:23:02.080 --> 00:23:03.860
irgendwie haben und eine uralte Lib C

00:23:03.860 --> 00:23:05.700
und die funktioniert dann mit neueren

00:23:05.700 --> 00:23:08.160
anderen

00:23:08.160 --> 00:23:10.000
Bibliotheken nicht mehr gut, dann

00:23:10.000 --> 00:23:12.100
habe ich, hatte auch schon den Fall, dass ich dann

00:23:12.100 --> 00:23:13.900
per Conda irgendwie eine neue Lib C

00:23:13.900 --> 00:23:15.920
in meinem Environment installiert habe, um überhaupt

00:23:15.920 --> 00:23:18.100
irgendwie bestimmte Sachen benutzen

00:23:18.100 --> 00:23:20.060
zu können. Und das geht halt mit Conda und mit

00:23:20.060 --> 00:23:21.660
PIP wäre man da halt relativ aufgeschmissen.

00:23:22.560 --> 00:23:23.660
Daher, ja,

00:23:23.980 --> 00:23:26.080
für so

00:23:26.080 --> 00:23:28.060
wirkliche Data Science Projekte ist das

00:23:28.060 --> 00:23:29.780
halt schon irgendwie deutlich netter.

00:23:30.120 --> 00:23:31.880
Es ist ein bisschen schade, dass jetzt man halt

00:23:31.880 --> 00:23:33.740
zwei Repositories von Paketen hat und

00:23:33.740 --> 00:23:35.840
ja, manchmal ist es halt auch so ein bisschen

00:23:35.840 --> 00:23:37.440
kompliziert, dann sich zu überlegen, was man gerade

00:23:37.440 --> 00:23:39.560
machen will, aber ich würde die

00:23:39.560 --> 00:23:41.540
Faustregel einfach nehmen, wenn es ein reines

00:23:41.540 --> 00:23:42.740
Data-Science-Projekt ist, ja dann

00:23:42.740 --> 00:23:45.640
Conda und wenn es irgendwie eine Web-Geschichte ist oder

00:23:45.640 --> 00:23:46.760
was ganz anderes, eher Pip.

00:23:48.040 --> 00:23:49.760
Ist das denn immer genauso aktuell in Conda

00:23:49.760 --> 00:23:50.900
wie auf PyPy?

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

00:23:53.900 --> 00:23:55.560
Es gibt dann noch CondaForge, also sozusagen

00:23:55.560 --> 00:23:57.640
ein...

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

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

00:24:00.460 --> 00:24:03.040
es gibt halt einmal die Pakete,

00:24:03.160 --> 00:24:05.100
die sozusagen von der Firma

00:24:05.100 --> 00:24:07.160
gebaut werden und ein Repository

00:24:07.160 --> 00:24:08.100
von Paketen, das halt

00:24:08.100 --> 00:24:10.720
also eine Distribution, die halt

00:24:10.720 --> 00:24:12.720
sozusagen redaktionell von

00:24:12.720 --> 00:24:15.180
Continuum Analytics gepflegt

00:24:15.180 --> 00:24:16.680
wird und es gibt halt

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

00:24:19.300 --> 00:24:20.200
das nennt sich dann CondaForge

00:24:20.200 --> 00:24:23.100
und man kann das halt

00:24:23.100 --> 00:24:25.000
in dem, man hat immer so ein Konfigurations-File

00:24:25.000 --> 00:24:27.240
und da kann man

00:24:27.240 --> 00:24:29.020
halt die Channels sozusagen

00:24:29.020 --> 00:24:31.640
aus denen man Pakete bekommt, halt eintragen

00:24:31.640 --> 00:24:33.280
und ja, die meisten verwenden

00:24:33.280 --> 00:24:35.440
ContaForge. Es ist jetzt auch irgendwie so,

00:24:35.540 --> 00:24:37.880
dass, glaube ich,

00:24:40.460 --> 00:24:43.480
Anaconda selber irgendwie auf ContaForge umgestellt

00:24:43.480 --> 00:24:45.140
hat oder so. Ja, genau, die haben sich tatsächlich umgestellt.

00:24:45.580 --> 00:24:47.280
Das haben wir gehört auf dem Parkcamp jetzt.

00:24:47.440 --> 00:24:48.880
Ja, richtig, das hatte ich

00:24:48.880 --> 00:24:50.780
auch gar nicht klar, aber ja.

00:24:51.100 --> 00:24:53.440
Das fand ich manchmal auch echt so ein bisschen nervig, wenn man ein Paket

00:24:53.440 --> 00:24:55.420
installieren wollte, habe ich dann doch meistens mal gegoogelt,

00:24:55.420 --> 00:24:56.640
was ist denn jetzt hier das richtige

00:24:56.640 --> 00:24:59.580
Repo dafür und das ist jetzt aber

00:24:59.580 --> 00:25:00.740
seitdem quasi weg.

00:25:02.060 --> 00:25:03.340
Ja, ist tatsächlich anstrengend, wenn man halt schon

00:25:03.340 --> 00:25:05.340
unterschiedliche Paketmente hat und dann auch seine eigene Source

00:25:05.340 --> 00:25:06.640
dafür irgendwie bestimmen muss.

00:25:07.120 --> 00:25:09.720
Ich kann mich da an andere Experimente

00:25:09.720 --> 00:25:11.380
erinnern mit so Paketsachen und Sources.

00:25:11.780 --> 00:25:12.700
Alles nicht einfacher, aber

00:25:12.700 --> 00:25:15.460
hatten wir das schon erwähnt, warum man das überhaupt machen

00:25:15.460 --> 00:25:17.240
sollte? Ja, das Problem ist eben, dass die

00:25:17.240 --> 00:25:19.320
Pakete in der Distribution halt

00:25:19.320 --> 00:25:21.100
nicht wirklich aktuell sind meistens.

00:25:21.360 --> 00:25:23.460
Also, wie sagte Barry Varsaw,

00:25:23.600 --> 00:25:24.500
glaube ich, einer

00:25:24.500 --> 00:25:26.800
Python-Core-Entwickler

00:25:26.800 --> 00:25:28.640
sagt man mal, the first rule of Python

00:25:28.640 --> 00:25:30.560
is, you don't use system Python.

00:25:31.680 --> 00:25:32.380
Das ist halt einfach

00:25:32.380 --> 00:25:34.280
üblicherweise veraltet bei vielen

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

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

00:25:37.920 --> 00:25:40.280
distributionsinterne Zwecke benutzen, mit halt

00:25:40.280 --> 00:25:42.580
Python 2 irgendwie noch als Default-Interpreter

00:25:42.580 --> 00:25:44.160
bei Mac auch. Es gibt einen

00:25:44.160 --> 00:25:46.040
Counter für Python 2 mittlerweile, habt ihr den gesehen?

00:25:46.100 --> 00:25:47.340
Desk Clock, ja, gibt's.

00:25:48.280 --> 00:25:50.180
Bin mal gespannt, wann die Vertriebssysteme es dann auch mal

00:25:50.180 --> 00:25:52.180
sich trauen, also schon ein bisschen halbern so langsam.

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

00:25:54.260 --> 00:25:56.160
dass irgendwie, wenn sie das

00:25:56.160 --> 00:25:58.000
ändern, irgendwie ihre Installationsroutinen

00:25:58.000 --> 00:26:00.100
nicht mehr funktionieren, weil die halt Python brauchen und

00:26:00.100 --> 00:26:02.040
vielleicht noch nicht umgestellt sind. Und die sind halt

00:26:02.040 --> 00:26:03.720
alle uralt. Ja, doof.

00:26:04.900 --> 00:26:06.140
Und daher muss man

00:26:06.140 --> 00:26:07.640
sowieso eigentlich immer einen anderen

00:26:07.640 --> 00:26:10.120
Python-Interpreter verwenden, als der, der vorinstalliert

00:26:10.120 --> 00:26:12.120
ist. Und dann ist es

00:26:12.120 --> 00:26:14.120
halt so, wenn man unterschiedliche Projekte hat,

00:26:14.180 --> 00:26:15.340
dann haben die halt unterschiedliche

00:26:15.340 --> 00:26:17.900
Abhängigkeiten, was bestimmte Bibliotheken

00:26:17.900 --> 00:26:19.880
angeht. Und die

00:26:19.880 --> 00:26:21.860
widersprechen sich halt. Und das kriegt man halt auch,

00:26:21.920 --> 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.840 --> 00:26:28.500
Und daher macht man normalerweise pro Projekt

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

00:26:31.240 --> 00:26:33.580
in dem man halt irgendwie alle Abhängigkeiten installiert,

00:26:33.640 --> 00:26:34.080
die man braucht.

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

00:26:35.100 --> 00:26:37.220
dass du für ein Projekt zwei Virtual Environments brauchtest,

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

00:26:38.180 --> 00:26:39.200
sich unterschiedliche Module besprachen?

00:26:39.200 --> 00:26:40.620
Nee, das geht auch gar nicht.

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

00:26:42.420 --> 00:26:43.420
man könnte es theoretisch machen,

00:26:44.500 --> 00:26:46.220
aber nee, das ist mir jetzt auch noch nicht untergekommen.

00:26:46.520 --> 00:26:47.860
Was meinst du innerhalb von einem Projekt?

00:26:48.020 --> 00:26:48.760
Ja, es könnte ja irgendwie sein,

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

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

00:26:53.020 --> 00:26:55.280
Python-Version, weil die Module das sonst nicht können

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

00:26:56.960 --> 00:26:58.940
man da reden kann. Und um das dann zu bauen,

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

00:27:01.220 --> 00:27:03.280
Nehmen wir zum Beispiel mal an, man hätte

00:27:03.280 --> 00:27:04.880
ein OCR-Projekt und man möchte jetzt

00:27:04.880 --> 00:27:07.280
irgendwie ein aktuelles

00:27:07.940 --> 00:27:09.220
Ding gegen was Älteres

00:27:09.220 --> 00:27:10.420
wie Oceropi oder

00:27:10.420 --> 00:27:12.260
Kraken oder so verwenden.

00:27:12.920 --> 00:27:14.680
Angenommen, Kraken kann auch Python 3, aber

00:27:14.680 --> 00:27:16.840
Oceropi kann nur, oder Oceropus

00:27:16.840 --> 00:27:19.080
kann nur Python 2. Und jetzt möchte man

00:27:19.080 --> 00:27:20.960
halt das Ding aber testen gegen was Neues,

00:27:21.060 --> 00:27:22.960
was halt vielleicht nur Python 3 kann. Und dann müsste man

00:27:22.960 --> 00:27:24.660
zwei Interpreter halt haben, irgendwie

00:27:24.660 --> 00:27:26.460
in dem, ja, das wäre

00:27:26.460 --> 00:27:29.020
hässlich.

00:27:29.240 --> 00:27:30.860
Aber ich glaube, so kompliziert müssen wir es gar nicht

00:27:30.860 --> 00:27:31.060
machen.

00:27:32.340 --> 00:27:34.940
Also wenn ihr euch inzwischen das Repo ausgeklont

00:27:34.940 --> 00:27:36.700
habt, dann ist jetzt vielleicht der

00:27:36.700 --> 00:27:38.820
richtige Moment, einmal corner.env.create

00:27:38.820 --> 00:27:41.080
auszuführen, um die Umgebung euch aufzusetzen.

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

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

00:27:44.300 --> 00:27:46.260
eine hinterlegte

00:27:46.260 --> 00:27:48.080
Environment-Datei, die

00:27:48.080 --> 00:27:50.320
die ganzen Pakete und die jeweiligen

00:27:50.320 --> 00:27:52.100
Versionen beinhaltet, die man bitte

00:27:52.100 --> 00:27:52.940
zu installieren hat.

00:27:54.200 --> 00:27:56.260
Und danach kann man das dann eben aktivieren

00:27:56.260 --> 00:27:57.700
und hat das dann quasi als sein

00:27:57.700 --> 00:27:59.280
Default-Python-Interpreter gesetzt.

00:28:00.300 --> 00:28:02.020
Also Connor M. Great macht dann genau das,

00:28:02.120 --> 00:28:03.980
dass er einfach ein Environment setzt, die heißt dann

00:28:03.980 --> 00:28:05.840
Great, oder was? Ne, das steht in dem

00:28:05.840 --> 00:28:08.140
in dem File halt

00:28:08.140 --> 00:28:09.720
auch mit drin. Der Name von dem?

00:28:09.720 --> 00:28:10.520
Von dem

00:28:10.520 --> 00:28:14.080
Environment, genau.

00:28:16.400 --> 00:28:16.920
Warte mal.

00:28:17.680 --> 00:28:20.080
Das ist auch einfach ein YAML-File

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

00:28:22.040 --> 00:28:24.800
ds-tutorial

00:28:24.800 --> 00:28:26.380
ds-tutorial und dann dependencies,

00:28:26.580 --> 00:28:27.940
ach, und dann werden die Pakete danach geploppt.

00:28:28.720 --> 00:28:30.680
Und, achso, ist auch so, man kann halt

00:28:30.680 --> 00:28:32.780
auch Sachen

00:28:32.780 --> 00:28:33.700
per PIP installieren.

00:28:34.720 --> 00:28:36.560
Ja, das ist auch sowas, also es ist halt irgendwie,

00:28:37.900 --> 00:28:38.560
ja, Conda ist quasi

00:28:38.560 --> 00:28:40.240
eine echte Obermenge von PIP,

00:28:40.420 --> 00:28:42.500
man kann halt Conda und halt auch PIP,

00:28:42.740 --> 00:28:44.680
aber umgekehrt geht es halt nicht, PIP kann halt nicht

00:28:44.680 --> 00:28:45.700
Conda Sachen installieren.

00:28:47.240 --> 00:28:48.480
Ja, und manche Sachen installiere ich

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

00:28:50.500 --> 00:28:50.920
dann sind.

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

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

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

00:28:59.100 --> 00:29:00.260
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.380 --> 00:29:03.940
wie bei PIP auch, mit gleich oder sowas.

00:29:03.960 --> 00:29:04.160
Genau.

00:29:06.160 --> 00:29:08.360
Genau. Und danach müsst ihr, um das Repo

00:29:08.360 --> 00:29:10.340
quasi so ausführen zu können, noch mal

00:29:10.340 --> 00:29:12.420
das lokale Paket bauen

00:29:12.420 --> 00:29:14.620
und zwar mit "-e".

00:29:14.620 --> 00:29:16.320
Warum wollen wir denn

00:29:16.320 --> 00:29:18.540
erstmal überhaupt ein lokales Paket

00:29:18.540 --> 00:29:20.420
und warum wollen wir "-e"?

00:29:21.020 --> 00:29:23.020
Ja, ein lokales Paket

00:29:23.020 --> 00:29:24.980
deswegen, weil man in

00:29:24.980 --> 00:29:26.840
vielen Notebooks halt, also ich habe das

00:29:26.840 --> 00:29:28.860
Ganze quasi ein bisschen in unterschiedliche

00:29:28.860 --> 00:29:30.360
Notebooks aufgeteilt und da gibt es dann

00:29:30.360 --> 00:29:32.860
einige, die halt immer wieder den gleichen

00:29:32.860 --> 00:29:34.600
Code enthalten. Und jetzt könnte man

00:29:34.600 --> 00:29:36.700
natürlich auch in jedes Notebook irgendwie reinkopieren,

00:29:37.220 --> 00:29:38.920
aber wenn man dann gemerkt hat, oh, ich habe hier

00:29:38.920 --> 00:29:40.800
einen blöden Fehler gemacht, dann muss man das halt auch

00:29:40.800 --> 00:29:42.240
in allen Notebooks wieder ändern, was ja ein bisschen

00:29:42.240 --> 00:29:44.860
umständlich wäre. Und Code, den man halt

00:29:44.860 --> 00:29:47.060
in mehreren unterschiedlichen Notebooks

00:29:47.060 --> 00:29:48.820
benötigt, den

00:29:48.820 --> 00:29:50.500
kann man ja aber auch einfach eine

00:29:50.500 --> 00:29:52.740
Bibliothek und das ist halt im Grunde

00:29:52.740 --> 00:29:54.440
dieses Paket, was man da installiert,

00:29:55.180 --> 00:29:56.600
rausziehen und

00:29:56.600 --> 00:29:58.440
den importiert man dann halt einfach nur in

00:29:58.440 --> 00:30:00.320
allen Notebooks und wenn man da jetzt einen Fehler

00:30:00.320 --> 00:30:02.480
fixt, dann ist der halt

00:30:02.480 --> 00:30:04.360
in allen Notebooks gleichzeitig gefixt

00:30:04.360 --> 00:30:06.280
und Minus E installiert man

00:30:06.280 --> 00:30:08.340
deswegen, um Änderungen,

00:30:08.420 --> 00:30:10.120
wenn man da jetzt eine Änderung macht,

00:30:10.540 --> 00:30:12.360
die sofort sichtbar

00:30:12.360 --> 00:30:14.440
werden zu lassen. Also ansonsten müsste man

00:30:14.440 --> 00:30:16.440
ja eigentlich, wenn man ein Paket

00:30:16.440 --> 00:30:18.320
zum Beispiel via PyPI oder so

00:30:18.320 --> 00:30:20.280
installiert oder normal installiert sozusagen,

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

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

00:30:27.320 --> 00:30:29.720
Und am besten auch nochmal das Notebook neu starten.

00:30:30.660 --> 00:30:32.660
Und das ist natürlich ein bisschen umständlich.

00:30:32.920 --> 00:30:35.940
Und wenn man sagt pip install –i,

00:30:36.740 --> 00:30:40.240
dann macht das sozusagen keine wirkliche Paketsinstallation,

00:30:40.240 --> 00:30:45.000
sondern legt nur einen Link auf das entsprechende Verzeichnis

00:30:45.000 --> 00:30:46.560
sozusagen mit nach Side-Packages.

00:30:47.300 --> 00:30:53.300
Und wenn sich da irgendwas ändert am Code,

00:30:53.400 --> 00:30:55.380
dann ist das halt sofort irgendwie sichtbar.

00:30:55.560 --> 00:30:59.080
Und dann kann man das auch für alle einstellen

00:30:59.080 --> 00:31:01.960
oder für einige auf Notebook-Seite kann man zum Beispiel sagen,

00:31:01.960 --> 00:31:07.120
A-Import statt Import, ein bestimmtes Modul,

00:31:07.460 --> 00:31:10.720
dann wird halt die Aktualisierung auch sofort wirksam,

00:31:10.900 --> 00:31:13.220
ohne dass man das neu starten muss, was ja auch praktisch ist.

00:31:13.360 --> 00:31:15.520
Also man kann das sehr feigengranulär einstellen.

00:31:16.840 --> 00:31:41.160
Man will das vielleicht auch nicht für alle Module machen, aber wenn man das richtig eingestellt hat, sozusagen, kann man halt, wenn man jetzt beispielsweise bei einem Code-Teil, der halt in vielen Notebooks verwendet wird, einen Teil ändert, dann ist die Änderung sofort da und bei der nächsten Ausführung einer Zelle hat man halt auch schon den geänderten Code mit ausgeführt und muss da nichts neu installieren, neu starten oder so.

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

00:31:43.320 --> 00:31:45.000
zu gehen. Also ich habe mich da am Anfang lange

00:31:45.000 --> 00:31:46.920
vorgescheut und habe einfach quasi

00:31:46.920 --> 00:31:48.800
am Anfang von meinem Notebook einfach immer

00:31:48.800 --> 00:31:50.860
mit der Runmagic quasi

00:31:50.860 --> 00:31:52.960
in ein anderes Notebook gestartet, wo ich alle diese

00:31:52.960 --> 00:31:54.940
Sachen initialisiert habe. Das geht auch.

00:31:55.500 --> 00:31:56.980
Aber das muss man halt dann doch, wenn man

00:31:56.980 --> 00:31:59.220
in einem anderen Notebook was ändert, immer noch einmal ausführen.

00:31:59.860 --> 00:32:01.000
Und so viel

00:32:01.000 --> 00:32:02.960
Zauber ist es gar nicht, quasi sich selber

00:32:02.960 --> 00:32:05.040
so ein Paket zu erstellen. Vor allem ist es auch ein ganz cooles

00:32:05.040 --> 00:32:07.180
Gefühl. Man kann es danach auch wirklich direkt mal weitergeben

00:32:07.180 --> 00:32:08.880
und weiterleiten und es

00:32:08.880 --> 00:32:11.140
verleitet zu ein bisschen besserer

00:32:11.140 --> 00:32:13.420
Ja, 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.480 --> 00:32:22.440
Welche IDI benutzt du?

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

00:32:25.920 --> 00:32:27.320
Wir sind beides umgestiegen auf Visual Studio.

00:32:27.320 --> 00:32:28.440
Studio Code? Ah ja, okay.

00:32:28.840 --> 00:32:31.080
Ich benutze immer noch alles. Also ich benutze

00:32:31.080 --> 00:32:33.040
auch immer noch, also vor allen Dingen häufig

00:32:33.040 --> 00:32:33.620
eigentlich Wim.

00:32:34.820 --> 00:32:36.460
Ich benutze auch PyCharm und auch VS Code.

00:32:37.300 --> 00:32:38.840
Ich hatte das mir auch gezeigt.

00:32:39.200 --> 00:32:41.320
Ja, ist schon ziemlich gut, muss man sagen.

00:32:41.540 --> 00:32:42.960
Genau. Ich meine, am Anfang ist so ein bisschen

00:32:42.960 --> 00:32:45.000
overhead mit dem Anlegen von so einer Klasse da,

00:32:45.180 --> 00:32:46.920
aber ihr benutzt, glaube ich, so

00:32:46.920 --> 00:32:48.800
Cookie-Cutter-Templates. Ja.

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

00:32:51.200 --> 00:32:53.260
was ein Projekt ist, was von Kollegen

00:32:53.260 --> 00:32:55.320
von mir entwickelt wird, was mir da sehr geholfen

00:32:55.320 --> 00:32:57.300
hat, einfach am Anfang quasi so

00:32:57.300 --> 00:32:59.420
Scaffolding, mir

00:32:59.420 --> 00:33:01.420
mein Gerüst einmal aufzusetzen, da kenne ich mich

00:33:01.420 --> 00:33:03.460
dann direkt drin aus und dann dränge ich dann noch meine zwei, drei

00:33:03.460 --> 00:33:05.560
Zeilen ein und ja, bin gleich

00:33:05.560 --> 00:33:07.700
da und das hat mir so ein bisschen

00:33:07.700 --> 00:33:09.420
die Angst davor genommen, eigene Pakete

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

00:33:11.320 --> 00:33:13.680
Ja, genau.

00:33:13.960 --> 00:33:15.600
Gut, und dann

00:33:15.600 --> 00:33:17.460
können wir letztendlich wirklich unser

00:33:17.460 --> 00:33:18.220
Notebook starten.

00:33:19.760 --> 00:33:20.760
Du benutzt noch Jupyter

00:33:20.760 --> 00:33:23.020
Notebooks. Ja, stimmt.

00:33:23.240 --> 00:33:24.620
Magst du JupyterLab lieber, also

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

00:33:26.840 --> 00:33:28.340
Doch, stimmt, mag ich auch.

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

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

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

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

00:33:36.780 --> 00:33:38.760
Genau, also gerade die neuen Versionen mit den Plugins

00:33:38.760 --> 00:33:40.800
finde ich, es kommt, also am Anfang

00:33:40.800 --> 00:33:42.920
haben wir noch ein paar Funktionalitäten von JupyterNotebooks

00:33:42.920 --> 00:33:44.840
gefehlt, aber jetzt

00:33:44.840 --> 00:33:46.720
gerade mit dem sich ausbreitenden

00:33:46.720 --> 00:33:48.800
Plugin-System gibt es da echt coole

00:33:48.800 --> 00:33:50.700
Sachen, zum Beispiel, was ich total liebe

00:33:50.700 --> 00:33:52.960
gerade, ist halt die Sublime Keybinding

00:33:52.960 --> 00:33:54.720
Magic-Funktionalität, die man jetzt einfach

00:33:54.720 --> 00:33:56.720
sich so in die JupyterLab

00:33:56.840 --> 00:33:58.480
Notebooks reinladen kann.

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

00:34:02.000 --> 00:34:03.000
Ja, ja, ja, nee,

00:34:03.140 --> 00:34:04.980
das, genau, das hatte ich auch, habe ich auch schon lange vor.

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

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

00:34:08.720 --> 00:34:10.860
Und genau, ja, nee, sieht sehr, sehr gut aus.

00:34:10.940 --> 00:34:11.900
JupyterLab ist, ja.

00:34:13.880 --> 00:34:14.240
Genau.

00:34:14.840 --> 00:34:16.800
So, egal, ob ihr jetzt ein

00:34:16.800 --> 00:34:19.140
Jupyter Notebook oder ein ehemaliger,

00:34:19.920 --> 00:34:20.980
ja, egal, ob ihr jetzt ein Jupyter

00:34:20.980 --> 00:34:22.880
Notebook oder halt schon JupyterLab gestartet

00:34:22.880 --> 00:34:24.920
habt, müsstet ihr jetzt quasi

00:34:24.920 --> 00:34:26.740
eine Reihe an

00:34:26.740 --> 00:34:28.660
Ordnern sehen und

00:34:28.660 --> 00:34:30.300
im DS-Tutorial,

00:34:30.680 --> 00:34:33.240
nee, im

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

00:34:34.900 --> 00:34:36.700
das Projekt Text Classification

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

00:34:38.740 --> 00:34:40.400
Genau. Ja,

00:34:41.200 --> 00:34:42.640
vielleicht kann man einfach direkt mal das

00:34:42.640 --> 00:34:44.680
Explorer Data Notebook aufmachen.

00:34:46.040 --> 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 irgendein frei verfügbares

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

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

00:34:55.960 --> 00:34:57.640
Reuters

00:34:57.640 --> 00:35:00.760
21578

00:35:00.760 --> 00:35:03.140
Textklassifikations

00:35:03.140 --> 00:35:04.840
Dataset, das ist so ein klassisches Ding,

00:35:05.940 --> 00:35:07.680
wo

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

00:35:09.100 --> 00:35:10.460
21578

00:35:10.460 --> 00:35:12.840
so Ticker

00:35:12.840 --> 00:35:14.480
Meldungen 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:21.460
unterschiedliche Kategorien und

00:35:21.460 --> 00:35:23.440
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:27.200
bauen oder das benutzt man eigentlich mal

00:35:27.200 --> 00:35:28.100
als Trainingsdatum

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

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

00:35:33.240 --> 00:35:35.280
weil man halt dann damit vorhersagen kann,

00:35:35.900 --> 00:35:37.200
versucht zu vorhersagen, wenn man jetzt

00:35:37.200 --> 00:35:39.200
eine neue Tickermeldung reinbekommt, welche Kategorie ist

00:35:39.200 --> 00:35:41.040
das? Also es ist im Grunde so ähnlich wie das

00:35:41.040 --> 00:35:43.220
Spam-Klassifikationsbeispiel

00:35:43.220 --> 00:35:45.220
von eben, nur dass man halt nicht

00:35:45.220 --> 00:35:47.240
nur zwischen Spam und Nicht-Spam unterscheiden

00:35:47.240 --> 00:35:49.060
können will, sondern halt zwischen

00:35:49.060 --> 00:35:50.560
allen Kategorien, in denen halt

00:35:50.560 --> 00:35:53.300
so eine Tickermeldung liegen kann

00:35:53.300 --> 00:35:55.280
beziehungsweise auch noch ein Unterschied ist,

00:35:55.400 --> 00:35:57.200
es ist nicht, man würde,

00:35:57.480 --> 00:35:59.740
das wäre jetzt Multiclass, wenn es nur eine gäbe,

00:36:00.480 --> 00:36:01.620
aber das ist eigentlich ein Multilabel

00:36:01.620 --> 00:36:03.660
Dataset, das heißt, man möchte

00:36:03.660 --> 00:36:05.420
alle Kategorien, in denen so

00:36:05.420 --> 00:36:08.220
eine Ticker-Meldung

00:36:08.220 --> 00:36:09.380
drin liegt, rausfinden.

00:36:09.880 --> 00:36:11.560
Also vielleicht halt auch, es gibt welche,

00:36:11.700 --> 00:36:13.560
die halt, wo es

00:36:13.560 --> 00:36:15.440
nicht nur um Politik geht oder Sport, sondern auch

00:36:15.440 --> 00:36:16.720
Sport und Politik oder sowas.

00:36:18.400 --> 00:36:18.800
Genau.

00:36:19.360 --> 00:36:21.640
Das Erste, was man, finde ich, bei so einem Datascience-Projekt

00:36:21.640 --> 00:36:23.420
ja am Anfang immer machen muss, vor

00:36:23.420 --> 00:36:25.700
lauter Tools und Frameworks und sonst was.

00:36:26.040 --> 00:36:27.400
Das Wichtigste sind immer noch die Daten.

00:36:27.580 --> 00:36:29.600
Und wenn die Daten nicht passen, dann hilft es nicht.

00:36:29.680 --> 00:36:31.420
Und da muss man sich halt echt erstmal reinknien

00:36:31.420 --> 00:36:33.420
und richtig verstehen, was haben wir denn da überhaupt alles.

00:36:34.460 --> 00:36:34.780
Und

00:36:34.780 --> 00:36:37.440
ich weiß nicht, da gibt es so ein paar Befehle, die ich immer

00:36:37.440 --> 00:36:39.480
als erstes so benutze. Also ich lad

00:36:39.480 --> 00:36:41.280
mir mein Dataset irgendwie

00:36:41.280 --> 00:36:42.900
in Pandas DataFrame rein.

00:36:43.960 --> 00:36:44.320
Und

00:36:44.320 --> 00:36:47.140
dann nutze ich darauf erstmal

00:36:47.140 --> 00:36:49.200
meist ein Head, um einfach mal zu gucken, was

00:36:49.200 --> 00:36:51.120
habe ich überhaupt drin. Dann

00:36:51.120 --> 00:36:53.500
D-Types, um mir anzugucken,

00:36:53.660 --> 00:36:55.480
okay, welche Spalten haben denn hier

00:36:55.480 --> 00:36:57.320
welchen Typ? Und danach

00:36:57.320 --> 00:36:59.160
mache ich dann eben einen Describe,

00:36:59.540 --> 00:37:01.340
was mir dann für alle numerischen

00:37:01.340 --> 00:37:05.400
Spalten da drin schon mal so ein bisschen

00:37:05.400 --> 00:37:07.280
eine erste Übersichtsstatistik gibt.

00:37:07.460 --> 00:37:09.320
Also irgendwie, wie viele Einträge habe ich?

00:37:09.720 --> 00:37:11.200
Was ist der Mittelwert?

00:37:11.200 --> 00:37:13.080
Was sind quasi die Maximalwerte?

00:37:13.280 --> 00:37:15.240
Und so weiter. Machst du das ähnlich?

00:37:15.460 --> 00:37:16.800
Oder wie gehst du? Ja, ja, doch, durchaus.

00:37:17.220 --> 00:37:18.960
Also ich habe das jetzt auch hier

00:37:18.960 --> 00:37:19.800
gerade nochmal ausgeführt.

00:37:21.120 --> 00:37:40.360
Genau, ja, also wenn man jetzt zum Beispiel einige der ersten Zeilen ausgeführt hat, dann hat man hier auch eben ein Data-Frame, in dem all die Dokumente halt drin sind und wenn man DF-Head macht, dann sieht man halt eine Spalte Mod-Update, das ist halt sozusagen so der klassische Split in Trainings- und Testdaten.

00:37:41.080 --> 00:37:50.460
Das ist halt auch ganz praktisch bei dem Dataset, dass man das nicht selber machen muss, weil das ist halt auch noch, eigentlich müsste man dann irgendwie erklären, was Cross-Validation ist und wie man K-Fault-Cross-Validation, hier ist das schon fertig.

00:37:50.620 --> 00:37:52.540
Da muss man sich dann keine Gedanken mehr drum machen,

00:37:52.660 --> 00:37:54.100
sozusagen. Das ist vielleicht ganz gut.

00:37:55.240 --> 00:37:56.720
Dann gibt es eine Spalte mit den

00:37:56.720 --> 00:37:58.860
Kategorien drin. Das ist dann einfach nur eine Liste der

00:37:58.860 --> 00:38:01.040
Kategorien,

00:38:01.540 --> 00:38:02.260
in denen halt diese

00:38:02.260 --> 00:38:03.820
Meldung halt drin ist.

00:38:04.760 --> 00:38:06.640
Und genau, das Ganze nochmal

00:38:06.640 --> 00:38:08.380
sozusagen nicht als

00:38:08.380 --> 00:38:10.320
Textkategorie, sondern eben

00:38:10.320 --> 00:38:12.000
numerisches Label, weil

00:38:12.000 --> 00:38:14.780
wenn man später das an irgendwelche Modelle

00:38:14.780 --> 00:38:16.680
verfüttert, dann brauchen die das halt als

00:38:16.680 --> 00:38:18.840
ja, als

00:38:18.840 --> 00:38:20.880
Zahl und am besten auch

00:38:20.880 --> 00:38:22.680
als Zahlen, die halt keine Lücken haben.

00:38:23.100 --> 00:38:24.860
Sonst geht das halt nicht gut, weil man

00:38:24.860 --> 00:38:27.140
das halt, One-Hot-Encoded

00:38:27.140 --> 00:38:28.880
nimmt man das sozusagen, hinterher kriegt

00:38:28.880 --> 00:38:30.980
halt jedes Label eine eigene

00:38:30.980 --> 00:38:32.820
Spalte und das geht eigentlich natürlich nur dann

00:38:32.820 --> 00:38:34.160
gut, wenn das halt irgendwie keine Lücken hat.

00:38:35.860 --> 00:38:36.840
Ja, dann gibt es da irgendwie

00:38:36.840 --> 00:38:38.260
noch ein Datum, was da dran ist,

00:38:38.580 --> 00:38:40.680
einen Titel, irgendeine komische

00:38:40.680 --> 00:38:42.760
Dateline, ich weiß jetzt gar nicht genau, was das ist und ein Body

00:38:42.760 --> 00:38:44.600
von dem Artikel,

00:38:45.120 --> 00:38:46.800
dann noch eine ID und

00:38:46.800 --> 00:38:48.920
ich glaube, das habe ich irgendwie mal dran gebastelt,

00:38:49.040 --> 00:38:49.660
einfach nur um,

00:38:50.440 --> 00:38:52.760
weil die Idee war halt,

00:38:53.080 --> 00:38:54.160
dass in dieser

00:38:54.160 --> 00:38:56.680
Machine Learning-Schulung

00:38:56.680 --> 00:38:57.720
man

00:38:57.720 --> 00:39:00.960
ja, als Übung sozusagen

00:39:00.960 --> 00:39:02.840
vielleicht ein paar neue Features dazu tun sollte,

00:39:03.000 --> 00:39:04.380
um zu gucken, ob das irgendwie die

00:39:04.380 --> 00:39:06.860
mit, ob das den Score irgendwie

00:39:06.860 --> 00:39:08.840
verbessert, der Modelle. Und da war

00:39:08.840 --> 00:39:10.540
halt so ein erstes Beispiel, man könnte einfach mal

00:39:10.540 --> 00:39:12.240
den Wochentag reinschreiben, der

00:39:12.240 --> 00:39:14.760
an dem das irgendwie erschienen ist

00:39:14.760 --> 00:39:16.380
und vielleicht steckt da ja irgendwelche Informationen drin.

00:39:16.800 --> 00:39:19.520
ja genau, DF-Info

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

00:39:21.580 --> 00:39:23.380
mit diesen Data-Frame-Operationen noch

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

00:39:25.340 --> 00:39:27.240
Buch von Jake Wanderplast zu

00:39:27.240 --> 00:39:29.440
Data Science mit Python, das hat er

00:39:29.440 --> 00:39:31.500
auch frei auf seinem GitHub-Account

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

00:39:32.720 --> 00:39:35.200
findet ihr irgendwie, da kann man auch mit

00:39:35.200 --> 00:39:37.200
Dupade der Notebooks das tatsächlich auch mal live noch an anderen

00:39:37.200 --> 00:39:39.400
Datensätzen üben, also gerade für Pandas

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

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

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

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

00:39:47.080 --> 00:39:48.020
zu empfehlen.

00:39:49.300 --> 00:39:50.980
Und ja, ich finde

00:39:50.980 --> 00:39:52.580
die Modern Pandas

00:39:52.580 --> 00:39:55.080
Blogartikel-Serie von Tom Augsburger

00:39:55.080 --> 00:39:55.520
auch super.

00:39:57.780 --> 00:39:59.240
Was ich ansonsten immer noch ganz gerne

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

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

00:40:04.680 --> 00:40:07.300
Der wirft so einfach so ein DataFrame rein

00:40:07.300 --> 00:40:09.080
und die generiert dir daraus so einen

00:40:09.080 --> 00:40:10.720
kleinen HTML-Report,

00:40:11.180 --> 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 aufbereiten

00:40:15.240 --> 00:40:16.860
bekommt. Das sieht ja auch super aus.

00:40:17.400 --> 00:40:19.240
Wie viele Zeilen hast du, wie viele

00:40:19.240 --> 00:40:21.260
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.140
halt irgendwie fehlen, sind Nullwerte.

00:40:26.380 --> 00:40:27.140
Du kriegst

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

00:40:29.380 --> 00:40:31.180
hat das Ganze und der sucht auch quasi

00:40:31.180 --> 00:40:33.100
nach Korrelationen in den Daten. Also wenn du jetzt

00:40:33.100 --> 00:40:35.160
zwei Spalten hast, wo du eben zum Beispiel

00:40:35.160 --> 00:40:37.240
schon so ein Feature Engineering gemacht hast und

00:40:37.240 --> 00:40:38.860
hast, keine Ahnung,

00:40:39.640 --> 00:40:41.020
den Tag und dann nochmal

00:40:41.020 --> 00:40:42.320
irgendwie den Tag um ein Jahr

00:40:42.320 --> 00:40:45.020
verschoben oder so, dann korrelieren diese

00:40:45.020 --> 00:40:46.940
beiden Spalten ja komplett, sowas würdest du dann

00:40:46.940 --> 00:40:48.600
da drin direkt sehen und der würde dich zum Beispiel

00:40:48.600 --> 00:40:49.860
vorwarnen.

00:40:50.840 --> 00:40:52.880
Ja, das wäre ganz praktisch, wenn man die cleanen muss, dann irgendwie

00:40:52.880 --> 00:40:54.860
erstmal so zu gucken, ah ja, das könnte ja ein Problem

00:40:54.860 --> 00:40:56.580
sein, dann fangen wir doch mal an da oder so.

00:40:57.400 --> 00:40:57.620
Genau.

00:40:58.860 --> 00:41:00.920
Genau, das ist immer irgendwie, finde ich, ganz praktisch,

00:41:01.100 --> 00:41:02.480
um so einen ersten

00:41:02.480 --> 00:41:03.560
Übersicht zu bekommen.

00:41:04.540 --> 00:41:06.740
Was würdet ihr dann machen? Würdet ihr dann die Daten, die dann da

00:41:06.740 --> 00:41:08.680
zum Beispiel fehlen, irgendwie versuchen zu füllen?

00:41:08.920 --> 00:41:10.740
Oder lässt man dann einfach

00:41:10.740 --> 00:41:12.640
erstmal die Spalten weg, weil die irgendwie Quatsch sind?

00:41:14.140 --> 00:41:14.500
Ja.

00:41:15.020 --> 00:41:15.980
Kommt halt komplett drauf an.

00:41:16.520 --> 00:41:17.040
Ja.

00:41:18.120 --> 00:41:19.600
Also, was du jetzt ansprichst,

00:41:19.620 --> 00:41:21.420
ist ja Ausreißerbereinigung im Wesentlichen

00:41:21.420 --> 00:41:23.580
und Nullwerte füllen.

00:41:25.240 --> 00:41:27.040
Die Frage ist, warum fehlen die Werte

00:41:27.040 --> 00:41:28.800
und kannst du sie sinnvoll ersetzen?

00:41:28.800 --> 00:41:31.860
Also, im Endeffekt hat man drei Optionen.

00:41:31.900 --> 00:41:33.520
Man wirft die Daten einfach weg.

00:41:34.560 --> 00:41:36.200
Man versucht sie zu füllen

00:41:36.200 --> 00:41:39.400
mit einem Art von statistischem Maß,

00:41:39.520 --> 00:41:41.220
was quasi zum Beispiel den Durchschnitt

00:41:41.220 --> 00:41:42.920
von allen Spalten wiedergibt.

00:41:43.800 --> 00:41:47.460
Oder, vielleicht habe ich ja nur die beiden Optionen.

00:41:47.560 --> 00:41:48.400
Ich dachte, ich hätte nur eine dritte.

00:41:49.000 --> 00:41:49.860
Ja, man könnte ja irgendwie.

00:41:50.020 --> 00:41:51.800
Es gibt diverse, also man kann auch bei,

00:41:52.340 --> 00:41:53.820
also es gibt dann Cyclic Learn zum Beispiel,

00:41:53.940 --> 00:41:55.620
das ist so eine Bibliothek für Maschinen und Geschichten,

00:41:55.760 --> 00:41:59.140
diverse, unterschiedliche, also da ist die Oberklasse quasi

00:41:59.140 --> 00:42:00.380
für all diese Verfahren im Pewter

00:42:00.380 --> 00:42:02.380
und man kann halt diverse unterschiedliche benutzen,

00:42:02.560 --> 00:42:04.380
um eine Strategie dafür zu haben,

00:42:04.380 --> 00:42:06.020
weil eben, es kommt halt darauf an,

00:42:06.080 --> 00:42:08.400
wofür man die, was der Grund dafür ist,

00:42:08.440 --> 00:42:10.720
warum das fehlt und wie man das am besten ausgleicht.

00:42:11.660 --> 00:42:14.400
die dann sozusagen da irgendwas reinschreiben

00:42:14.400 --> 00:42:16.260
oder irgendwas mit den Daten machen, ja.

00:42:17.200 --> 00:42:18.720
Ja, die Frage ist halt, ob man die rausrechnen kann,

00:42:18.800 --> 00:42:20.500
die Daten oder nicht, also ob das sinnvoll ist

00:42:20.500 --> 00:42:21.860
und was man halt mit der Spalte sonst macht

00:42:21.860 --> 00:42:24.580
oder mit den Datensätzen, die fehlen oder Korrelationen,

00:42:24.600 --> 00:42:26.800
ob man da einen Dummy reinsetzt, weil man den noch irgendwie braucht

00:42:26.800 --> 00:42:28.540
und dann immer merkt, oh, das ist das bei dem Dummy so.

00:42:29.380 --> 00:42:31.620
Ja, und auch, wie rum droppst du sie, wenn du sie droppst?

00:42:31.780 --> 00:42:34.920
Also schmeißt du die Zeilen raus oder schmeißt du die Spalten raus?

00:42:37.200 --> 00:42:38.860
Hängt halt immer von dem Tast ab.

00:42:39.280 --> 00:42:40.920
Ja, aber das sieht man genau gerade.

00:42:41.100 --> 00:42:43.040
man hat ja irgendwie die Warnings gesehen, wie viel irgendwie

00:42:43.040 --> 00:42:45.060
das ganz viele aus einer Teile oder

00:42:45.060 --> 00:42:47.000
Spalte dann da fehlen oder so bei irgendwelchen Einträgen.

00:42:47.320 --> 00:42:49.080
War bei den Warnings irgendwie mit dabei. Wie hieß das nochmal?

00:42:49.220 --> 00:42:50.880
Ich hab das... Pandas Profiling.

00:42:51.260 --> 00:42:52.920
Profiling, okay. Genau. Interessant.

00:42:53.460 --> 00:42:54.920
Muss auf jeden Fall auch in die Shownotes.

00:42:55.080 --> 00:42:55.460
Mach ich.

00:42:58.660 --> 00:42:59.220
Ja, genau.

00:42:59.540 --> 00:43:01.040
Also, hängt halt

00:43:01.040 --> 00:43:03.020
dann immer auch von den Operationen ab,

00:43:03.060 --> 00:43:05.140
die man halt danach drauf irgendwie anwenden möchte.

00:43:07.860 --> 00:43:09.040
Genau. Ansonsten ist, glaube ich,

00:43:09.040 --> 00:43:10.820
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:13.160 --> 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:21.200 --> 00:43:21.560
Aber

00:43:21.560 --> 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:27.020 --> 00:43:28.720
Oder ich habe zum Beispiel so einen leichten Shift

00:43:28.720 --> 00:43:30.880
in den Daten, sowas in Kennzahlen zu erfassen

00:43:30.880 --> 00:43:32.720
geht zwar, aber ist irgendwie immer nicht ganz so

00:43:32.720 --> 00:43:34.560
eingängig. Und dann hilft halt meist

00:43:34.560 --> 00:43:35.920
erstmal irgendwie so ein Histogramm oder so.

00:43:36.540 --> 00:43:38.560
Ja, genau. Würde ich auch sagen,

00:43:38.560 --> 00:43:38.680
dass

00:43:38.680 --> 00:43:46.540
Das ist das nützlichste Ding, wenn man so ein bisschen sehen will, wie das eigentlich verteilt ist.

00:43:46.900 --> 00:43:50.340
Oft ist es halt, sich ein Histogramm von der Werte anzugucken.

00:43:50.440 --> 00:43:53.880
Vor allen Dingen auch, wenn man jetzt unterschiedliche Klassen hat, einfach mal die Histogramme gegeneinander zu plotten.

00:43:53.880 --> 00:44:04.100
Das ist etwas, was ich mir oft angucke, um zu sehen, ob das irgendwas ist, wo interessante Informationen für Klassifikationen oder so drinsteht.

00:44:04.420 --> 00:44:06.220
dass man halt sagt so, okay, man plottet

00:44:06.220 --> 00:44:08.080
das Histogramm der einen Klasse gegen das der anderen

00:44:08.080 --> 00:44:10.180
und man halt sieht, okay, da gibt es einen großen Unterschied, dann ist

00:44:10.180 --> 00:44:12.100
schon mal, oder auch selbst ein kleiner

00:44:12.100 --> 00:44:13.660
Unterschied ist natürlich schon hilfreich irgendwie.

00:44:14.300 --> 00:44:16.180
Wenn man sieht, die sind genau gleich verteilt, dann ist das natürlich doof.

00:44:16.720 --> 00:44:17.700
Aber genau.

00:44:19.160 --> 00:44:19.720
Genau, in dem

00:44:19.720 --> 00:44:22.180
Explore-Data-Monbook sieht man auch ganz unten

00:44:22.180 --> 00:44:23.940
eben, finde ich, ein ganz klassisches, aber

00:44:23.940 --> 00:44:25.980
sehr, sehr hilfreiches Diagramm an der Stelle,

00:44:26.500 --> 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.620 --> 00:44:34.080
und da sieht man auch so ein ganz typisches Verhalten.

00:44:34.080 --> 00:44:59.560
Man hat halt irgendwie so einen Peak der Daten, der relativ am Anfang liegt. Also irgendwie, wir haben ja jetzt, würde ich sagen, wahrscheinlich mal 80 Prozent irgendwie im Bereich von 0 bis 600 Zeichen oder bis 750, glaube ich, sind das. Und dann wird es weniger und dann gibt es so einen Longtail hinten mit so ein paar einzelnen Einträgen, die dann halt irgendwie 3.000, 4.000, 5.000, 6.000 plus Einträge haben.

00:44:59.560 --> 00:45:01.540
Irgendwann hat ja jemand sein Buch bei Reuters hochgeladen, oder?

00:45:02.220 --> 00:45:18.680
Ja, genau. Aber das ist so ein ganz klassisches Problem, was man halt im echten Welt-Data-Science halt immer hat, dass es halt irgendwie so Ausreißer gibt, die die Degagramme verzerren und die dann auch immer den Aufwand beim Programmieren eigentlich bedeuten, weil das dann immer die Fälle sind, an die man vielleicht so nicht gedacht hat.

00:45:20.260 --> 00:45:44.700
Ja, genau. Ja, wir sehen hier, dass es halt so irgendwie ungefähr 10.000 Dinge gibt, die irgendwie Test oder Training zugeordnet sind. Also dieser Mod-Up-Split teilt diese Ticker-Meldung halt in die, auf denen man trainieren kann und die sozusagen, die man hinterher benutzt, um zu evaluieren, wie gut denn jetzt die Modelle funktioniert haben.

00:45:46.360 --> 00:45:49.000
es gibt 119 Klassen, aber

00:45:49.000 --> 00:45:51.180
tatsächlich sind es

00:45:51.180 --> 00:45:53.020
deutlich weniger, wenn man jetzt

00:45:53.020 --> 00:45:53.440
alle

00:45:53.440 --> 00:45:56.840
Also gibt es so

00:45:56.840 --> 00:45:58.980
Meta-Superklassen quasi, die bestimmte Dinge

00:45:58.980 --> 00:46:00.980
beinhalten, sowas wie Sport und dann gibt es

00:46:00.980 --> 00:46:02.540
Unterkategorien, Fußball, Hockey.

00:46:02.760 --> 00:46:05.820
Es gibt einige, die deutlich häufiger sind,

00:46:05.820 --> 00:46:06.860
aber es ist halt so, dass

00:46:06.860 --> 00:46:09.680
wenn man jetzt alle rausnimmt,

00:46:09.740 --> 00:46:10.780
auch alle Beispiele rausnimmt,

00:46:10.900 --> 00:46:13.620
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.440
gibt, weil das ist ja auch irgendwie so ein bisschen sinnlos.

00:46:17.600 --> 00:46:19.500
Also Sachen, die man nicht gesehen hat, kann man auch schlecht vorhersagen.

00:46:20.620 --> 00:46:21.600
Dann sind es

00:46:21.600 --> 00:46:23.540
nochmal deutlich weniger, sind es irgendwie nur 90 Kategorien,

00:46:23.600 --> 00:46:25.400
die übrig bleiben, glaube ich, und halt irgendwie

00:46:25.400 --> 00:46:27.640
Vielleicht sind die Kategorien herausgefallen, so Donziges oder so.

00:46:28.680 --> 00:46:29.560
Ja, ich weiß

00:46:29.560 --> 00:46:31.540
es gar nicht genau. Ich habe es mir auch nicht

00:46:31.540 --> 00:46:33.380
angeguckt, was das genau für Kategorien sind, aber

00:46:33.380 --> 00:46:34.840
ja, also

00:46:34.840 --> 00:46:37.740
das sind tatsächlich die Zahlen für alle, aber

00:46:37.740 --> 00:46:39.860
in Wirklichkeit

00:46:39.860 --> 00:46:41.000
ist es halt nochmal ein bisschen weniger.

00:46:42.240 --> 00:46:43.420
Also die dann hinterher tatsächlich

00:46:43.420 --> 00:46:45.020
zum Trainieren verwendet werden, dann

00:46:45.020 --> 00:46:47.180
eben durchschnittliche Anzahl

00:46:47.180 --> 00:46:49.080
von Wörtern ist halt irgendwie auch so 90

00:46:49.080 --> 00:46:50.520
und

00:46:50.520 --> 00:46:52.480
genau, die

00:46:52.480 --> 00:46:56.900
also es gibt so eine Quote

00:46:56.900 --> 00:46:58.940
Anzahl der Beispiele,

00:46:59.120 --> 00:47:00.880
also das ist sozusagen Anzahl der Zeilen im DataFrame

00:47:00.880 --> 00:47:02.860
geteilt durch die Anzahl der Wörter

00:47:02.860 --> 00:47:03.360
pro

00:47:03.360 --> 00:47:06.960
Tickermeldung, ist halt auch

00:47:06.960 --> 00:47:07.380
eine ganz

00:47:07.380 --> 00:47:10.820
interessante Zahl, die man später benutzen kann,

00:47:10.940 --> 00:47:12.920
um halt irgendwie rauszukriegen,

00:47:12.920 --> 00:47:14.480
welche Art von Modell da irgendwie besser

00:47:14.480 --> 00:47:15.660
funktionieren könnte.

00:47:17.460 --> 00:47:17.700
Ja,

00:47:18.080 --> 00:47:20.860
genau, also überhaupt diese ganze,

00:47:21.060 --> 00:47:23.060
also das ist halt irgendwie explorative Phase

00:47:23.060 --> 00:47:24.780
irgendwie bei so einem Projekt.

00:47:25.060 --> 00:47:26.680
Man versucht halt rauszukriegen, gibt es

00:47:26.680 --> 00:47:28.440
irgendwelche interessanten Regelmäßigkeiten,

00:47:29.680 --> 00:47:31.060
wie groß sind die Daten,

00:47:31.320 --> 00:47:32.880
was prinzipiell kann ich da eigentlich

00:47:32.880 --> 00:47:34.340
für Modelle verwenden und so.

00:47:34.340 --> 00:47:35.880
Also erstmal visualisieren ist glaube ich tatsächlich

00:47:35.880 --> 00:47:37.940
die beste Idee. Auch verschiedene Arten, mal gucken,

00:47:38.180 --> 00:47:39.860
Wordcloud bauen vielleicht oder so und dann

00:47:39.860 --> 00:47:41.520
schauen, was ist das denn.

00:47:41.760 --> 00:47:44.240
Und nebenher finde ich durchaus irgendwie nochmal so ein Scratchpad

00:47:44.240 --> 00:47:46.060
offen haben und wenn man da irgendwie eine

00:47:46.060 --> 00:47:47.760
Auffälligkeit hat, die immer gleich

00:47:47.760 --> 00:47:50.020
reinschreiben. Also man verfällt dann

00:47:50.020 --> 00:47:51.700
finde ich auch relativ leicht in so einem

00:47:51.700 --> 00:47:53.920
Liebe zu Charts, weil

00:47:53.920 --> 00:47:56.020
so Charts basteln ist was, was ich

00:47:56.020 --> 00:47:57.880
zum Beispiel total gerne mache. Also ich finde es

00:47:57.880 --> 00:47:59.780
total spannend, dann mir die Daten

00:47:59.780 --> 00:48:01.820
irgendwie so in Diagrammen zu visualisieren

00:48:01.820 --> 00:48:03.840
und die irgendwie hübsch zu machen und mächtig

00:48:03.840 --> 00:48:05.920
von ihrer Aussagekraft und so weiter, aber

00:48:05.920 --> 00:48:07.940
dabei verfalle ich da manchmal

00:48:07.940 --> 00:48:10.020
so ein bisschen in der Liebe zum Tun

00:48:10.020 --> 00:48:11.920
und eigentlich geht es ja darum

00:48:11.920 --> 00:48:13.700
Insights zu generieren. Deswegen

00:48:13.700 --> 00:48:16.480
finde ich es dann immer relativ wichtig, sich irgendwo

00:48:16.480 --> 00:48:18.520
nochmal so eine Liste runterzuschreiben mit den Auffälligkeiten,

00:48:18.600 --> 00:48:20.340
wo man so gedacht hat, ah ja, stimmt,

00:48:20.440 --> 00:48:22.720
das ist ja interessant und das ist interessant,

00:48:23.020 --> 00:48:24.560
weil im Endeffekt sind das nachher dann Sachen,

00:48:24.560 --> 00:48:26.620
aus denen man dann Ideen bekommt,

00:48:26.820 --> 00:48:28.620
um zum Beispiel Features zu generieren,

00:48:29.040 --> 00:48:30.460
die dann eben meinem Modell wirklich

00:48:30.460 --> 00:48:31.300
weiterhelfen könnten.

00:48:32.900 --> 00:48:34.800
Ja, also das ist halt an der Stelle auch definitiv

00:48:34.800 --> 00:48:36.000
dann ein iterativer Prozess,

00:48:36.580 --> 00:48:38.440
wo man quasi

00:48:38.440 --> 00:48:40.520
sich die Daten anschaut, man entwickelt

00:48:40.520 --> 00:48:42.480
eine Idee dafür, man probiert sie aus und

00:48:42.480 --> 00:48:56.760
Man geht dann wieder zurück und guckt sich mal wieder die Daten an und guckt, ah ja, jetzt habe ich aber ja ein besseres Verständnis dafür bekommen, weil ja, da ist so viel Information in so einem Datensystem, dass es eine ganze Zeit lang braucht, bis man wirklich versteht, was man damit alles machen könnte.

00:48:57.660 --> 00:49:01.680
Da muss man sich natürlich auch immer das Problem erstmal so ein bisschen reindenken, damit man irgendwie dann mit den Daten überhaupt was anfangen kann.

00:49:01.680 --> 00:49:06.160
Ja, genau und ja.

00:49:06.660 --> 00:49:08.300
Dabei hilft halt diese explorative Sache.

00:49:08.920 --> 00:49:10.020
Und ja,

00:49:10.860 --> 00:49:12.280
neben diesem ganzen Histogramm, ich glaube,

00:49:12.340 --> 00:49:14.260
wir haben angefangen erstmal mit, wie man die Daten noch bekommt.

00:49:14.360 --> 00:49:15.440
Damit waren wir noch gar nicht so durch.

00:49:15.800 --> 00:49:17.140
Achso, richtig. Ja, stimmt.

00:49:17.360 --> 00:49:19.520
Wir sollten irgendwie noch so die Art und Weise der Methode,

00:49:19.520 --> 00:49:21.460
wir haben jetzt irgendwie das Describe von DataFrames

00:49:21.460 --> 00:49:23.260
ein bisschen gemacht, aber wie bekomme ich denn die Daten

00:49:23.260 --> 00:49:25.160
überhaupt irgendwie so rein? Das ist ein guter Punkt, ja.

00:49:26.840 --> 00:49:27.540
Ja, also

00:49:27.540 --> 00:49:29.440
das ist irgendwie eine

00:49:29.440 --> 00:49:30.540
URL, die da irgendwo

00:49:30.540 --> 00:49:33.360
mit drin steht. Moment, ich glaube,

00:49:33.540 --> 00:49:35.240
das ist jetzt mittlerweile gut versteckt irgendwie

00:49:35.240 --> 00:49:37.380
in dem

00:49:37.380 --> 00:49:39.480
DS-Tutorial-Paket

00:49:39.480 --> 00:49:41.260
Datasets, da gibt es so ein

00:49:41.260 --> 00:49:43.380
Pfeil. Genau, normalerweise in der echten Welt

00:49:43.380 --> 00:49:45.340
würde ich sagen, ist der Pfeil meist, entweder

00:49:45.340 --> 00:49:47.280
habe ich den CSV irgendwo rübergeworfen bekommen,

00:49:47.420 --> 00:49:49.220
dann lese ich die einfach über Pandas ein, oder

00:49:49.220 --> 00:49:51.480
ich habe halt irgendwie für ein Spielprojekt

00:49:51.480 --> 00:49:53.240
eine Web-URL, dann ziehe ich es mir direkt

00:49:53.240 --> 00:49:55.320
von dort. Kann man ja

00:49:55.320 --> 00:49:56.840
direkt auch mit Pandas, glaube ich.

00:49:57.020 --> 00:49:59.260
Oder eigene Webdaten-Scrapes mit einer eigenen Datenbank oder

00:49:59.260 --> 00:50:01.180
sowas. Oder von irgendwelchen Sendoren,

00:50:01.340 --> 00:50:02.860
die Sachen in irgendeine Datenbank packen.

00:50:03.120 --> 00:50:04.940
Eine Datenbank-Anbindung ist natürlich auch ein guter Punkt,

00:50:05.020 --> 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.900
als Datei da, aber

00:50:11.900 --> 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.480 --> 00:50:18.820
Also wenn die Dateien da laden,

00:50:18.920 --> 00:50:20.920
also wirklich big ist die Datei dann aber irgendwie noch nicht.

00:50:21.640 --> 00:50:22.960
Nee, das hier ist alles

00:50:22.960 --> 00:50:24.000
super, super small.

00:50:24.660 --> 00:50:27.020
Man will in so einem Notebook auch kein Big Data

00:50:27.020 --> 00:50:29.100
haben. Kann man

00:50:29.100 --> 00:50:31.060
schon, aber... Kann man schon,

00:50:31.240 --> 00:50:31.980
aber ich weiß nicht,

00:50:32.600 --> 00:50:34.260
Also meine Präferenz an der Stelle ist

00:50:34.260 --> 00:50:36.280
vor allem immer erstmal auch Latenz niedrig zu halten

00:50:36.280 --> 00:50:38.160
und schnell mit Daten zu iterieren

00:50:38.160 --> 00:50:40.420
und lieber erstmal ein kleines Sample ziehen

00:50:40.420 --> 00:50:42.420
und erstmal viel Zeit mit diesem kleinen Sample

00:50:42.420 --> 00:50:44.380
zu verbringen und dann

00:50:44.380 --> 00:50:46.400
natürlich sehr bewusst wählen,

00:50:46.640 --> 00:50:48.120
wie wähle ich jetzt mein Sample? Mache ich es wirklich

00:50:48.120 --> 00:50:50.220
komplett random oder habe ich eine Zeitreihe? Muss ich jetzt gewisse

00:50:50.220 --> 00:50:51.900
Aspekte dabei berücksichtigen?

00:50:52.380 --> 00:50:54.160
Aber erstmal darauf eine Weile iterieren

00:50:54.160 --> 00:50:56.260
und dann sich nachher

00:50:56.260 --> 00:50:58.120
die Modelle auf dem Kompletten ausprobieren.

00:50:59.200 --> 00:51:00.020
Machst du das anders?

00:51:00.280 --> 00:51:02.200
Nee, nee, also genau. Subsamplen

00:51:02.200 --> 00:51:04.240
ist halt auch, wenn die Daten groß sind, auf jeden Fall

00:51:04.240 --> 00:51:05.820
eine super Strategie, um halt

00:51:05.820 --> 00:51:07.720
schnell integrieren zu können.

00:51:08.480 --> 00:51:09.400
Man kann aber, wenn man jetzt

00:51:09.400 --> 00:51:12.080
tatsächlich irgendwie

00:51:12.080 --> 00:51:14.100
größere Daten hat

00:51:14.100 --> 00:51:15.740
und das auch nicht irgendwie vielleicht

00:51:15.740 --> 00:51:16.720
kleiner machen will,

00:51:17.840 --> 00:51:20.260
sich zum Beispiel von, dann importiert

00:51:20.260 --> 00:51:21.940
man sich halt ein DataFrame nicht direkt von Pandas

00:51:21.940 --> 00:51:24.200
sozusagen, sondern man importiert das halt von

00:51:24.200 --> 00:51:25.920
Dask und

00:51:25.920 --> 00:51:28.540
das Ding

00:51:28.540 --> 00:51:30.080
verteilt dann automatisch

00:51:30.080 --> 00:51:32.060
irgendwie die Sachen, die man da drauf tut, halt auf

00:51:32.060 --> 00:51:34.000
zum Beispiel, das ist schon

00:51:34.000 --> 00:51:35.740
ziemlich cool, das hat eine Anbindung an

00:51:35.740 --> 00:51:37.720
Kubernetes und halt auch an die ganzen

00:51:37.720 --> 00:51:39.080
Cloud-Geschichten wie so

00:51:39.080 --> 00:51:41.460
Google Computer Engine und so

00:51:41.460 --> 00:51:43.900
und da kann man dann halt einfach sagen,

00:51:44.020 --> 00:51:45.960
okay, ich nehme mir jetzt mal so hier 100 Maschinen

00:51:45.960 --> 00:51:47.720
und füge die dann

00:51:47.720 --> 00:51:49.760
hinzu und man kann auch

00:51:49.760 --> 00:51:51.800
während Sachen da drauf laufen, also

00:51:51.800 --> 00:51:53.740
während man auf einem DataFrame halt irgendwas

00:51:53.740 --> 00:51:55.560
gruppiert oder so, kann man sagen, okay, ach,

00:51:55.680 --> 00:51:57.820
das geht mir zu langsam, nochmal 10 Maschinen dazu oder so

00:51:57.820 --> 00:51:59.840
und dann wird das

00:51:59.840 --> 00:52:01.340
automatisch halt irgendwie,

00:52:01.880 --> 00:52:03.200
werden die mit reingenommen und

00:52:03.200 --> 00:52:05.340
werden die Sachen halt irgendwie magisch schneller

00:52:05.340 --> 00:52:07.740
und man sieht halt auch irgendwie sehr schön,

00:52:07.880 --> 00:52:09.120
was da passiert.

00:52:10.060 --> 00:52:12.060
Habe ich jetzt normalerweise kein Beispiel für, aber

00:52:12.060 --> 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.780
Benutzerinterface ist sozusagen da auch nicht anders,

00:52:19.780 --> 00:52:21.400
als wenn man das jetzt auf einer lokalen Maschine macht,

00:52:21.980 --> 00:52:23.580
sondern ist auch immer ein Notebook eigentlich.

00:52:24.960 --> 00:52:26.080
Ich glaube, zu diesem Big-Data-Ding

00:52:26.080 --> 00:52:27.360
müssen wir nochmal eine eigene Folge machen, so mit

00:52:27.360 --> 00:52:28.980
Kubernetes, das ist ja nochmal spannend.

00:52:30.420 --> 00:52:31.760
Genau, an der Stelle kann ich mal meine

00:52:31.760 --> 00:52:32.740
Kubernetes-Folge droppen.

00:52:33.240 --> 00:52:35.960
Ja, genau. Es gibt eine zu Docker

00:52:35.960 --> 00:52:36.720
und eine zu Kubernetes.

00:52:37.940 --> 00:52:39.940
Ja, und das Schöne ist halt,

00:52:40.020 --> 00:52:41.880
dass die Sachen dann auch, wenn man sie nicht mehr braucht, wieder verschwinden.

00:52:42.100 --> 00:52:44.020
Während halt, das ist ja auch etwas, was man sonst,

00:52:44.240 --> 00:52:45.380
also gibt es dann vielleicht auch irgendwie,

00:52:45.720 --> 00:52:47.920
in vielen Firmen gibt es dann halt so ein Cluster,

00:52:48.060 --> 00:52:49.920
wo man Sachen machen kann, aber die Maschinen sind dann halt da

00:52:49.920 --> 00:52:51.980
und man braucht

00:52:51.980 --> 00:52:53.880
sie aber irgendwie nur, irgendwie, man braucht

00:52:53.880 --> 00:52:55.960
eigentlich so alle halbe Stunde mal so wirklich volle Power

00:52:55.960 --> 00:52:57.880
und, aber ansonsten braucht man das eigentlich nicht.

00:52:58.940 --> 00:52:59.240
Und,

00:52:59.320 --> 00:53:01.600
ja, das ist

00:53:01.600 --> 00:53:03.880
glaube ich auch irgendwie, also das ist schon ein sehr

00:53:03.880 --> 00:53:05.980
gutes Argument für diese ganzen Cloud-Geschichten,

00:53:06.120 --> 00:53:07.620
weil man zahlt halt tatsächlich nur in dem

00:53:07.620 --> 00:53:09.980
Moment, wo man halt die Rechenzeit

00:53:09.980 --> 00:53:10.320
braucht.

00:53:12.100 --> 00:53:13.960
Also du hast Dasks jetzt auch schon öfter

00:53:13.960 --> 00:53:15.700
eingesetzt und das funktioniert für dich gut? Ja,

00:53:15.820 --> 00:53:17.960
für mich funktioniert das eigentlich ziemlich gut. Ich habe damit nämlich praktisch

00:53:17.960 --> 00:53:19.760
so noch keine Erfahrung. Ich habe nur irgendwie

00:53:19.760 --> 00:53:21.760
im Hinterkopf, dass man dafür einiges umschreiben

00:53:21.760 --> 00:53:24.040
muss, dass das nicht komplett kompatibel ist mit den Pandas.

00:53:24.600 --> 00:53:25.620
Nicht komplett, aber also

00:53:25.620 --> 00:53:27.560
das meiste geht eigentlich schon.

00:53:27.780 --> 00:53:29.440
Es gibt also ein paar, ja natürlich,

00:53:29.660 --> 00:53:30.980
es gibt natürlich immer so ein paar Ecken,

00:53:31.600 --> 00:53:33.940
Ja, intern ist es halt so, dass der das auf eine Menge

00:53:33.940 --> 00:53:35.980
Data Frames aufteilt und das

00:53:35.980 --> 00:53:38.060
muss man halt irgendwie, die unterschiedlichen

00:53:38.060 --> 00:53:39.860
Teile liegen halt auf unterschiedlichen Rechnern und

00:53:39.860 --> 00:53:42.000
ja. Ansonsten, wenn man

00:53:42.000 --> 00:53:44.200
Pandas einfach nur Multicore

00:53:44.200 --> 00:53:45.900
betreiben möchte, was ja Pandas

00:53:45.900 --> 00:53:47.520
per Default jetzt aktuell noch nicht bietet,

00:53:48.080 --> 00:53:49.880
gibt es auch ein paar nette Projekte. Da gibt es

00:53:49.880 --> 00:53:51.900
einmal Modin, das ehemalige

00:53:51.900 --> 00:53:52.960
Pandas on Ray,

00:53:54.040 --> 00:53:55.680
was quasi einfach über einen Import

00:53:55.680 --> 00:53:56.440
einfach nur,

00:53:57.760 --> 00:53:59.900
du änderst den Import und dann kannst du prinzipiell

00:53:59.900 --> 00:54:02.340
Multicore für die allermeisten

00:54:02.340 --> 00:54:04.040
Pandas-Operationen.

00:54:04.040 --> 00:54:05.960
Wenn du sehr in die Nische kommst, geht's

00:54:05.960 --> 00:54:07.960
da vielleicht dann irgendwann nicht mehr. Und was ich

00:54:07.960 --> 00:54:10.000
heute kennengelernt habe und noch nicht ausprobiert habe, ist

00:54:10.000 --> 00:54:11.160
Pandarallel.

00:54:11.980 --> 00:54:13.900
Also so wie Panda

00:54:13.900 --> 00:54:16.000
und dann Parallel

00:54:16.000 --> 00:54:17.920
quasi. Und das unterstützt

00:54:17.920 --> 00:54:20.320
halt eben auch quasi oder verspricht ein Multicore-Processing

00:54:20.320 --> 00:54:21.920
für Pandas-Operationen.

00:54:22.300 --> 00:54:23.400
Genau. Also bevor man vielleicht

00:54:23.400 --> 00:54:26.020
wirklich auf den Cluster muss, ist das

00:54:26.020 --> 00:54:26.660
noch eine gute Option.

00:54:27.860 --> 00:54:28.040
Ja.

00:54:29.400 --> 00:54:30.380
Ja, ja, ja.

00:54:30.600 --> 00:54:32.040
Nee, das kann ich auch noch nicht. Also, ja.

00:54:32.540 --> 00:54:33.020
Das ist interessant.

00:54:34.960 --> 00:54:37.100
Genau, aber wir waren hier bei dem...

00:54:37.100 --> 00:54:38.220
Wie bekomme ich eigentlich meine Daten?

00:54:38.420 --> 00:54:40.280
Ich hatte einfach das entsprechende Notpunkt nicht aufgemacht.

00:54:40.680 --> 00:54:41.760
Das heißt hier

00:54:41.760 --> 00:54:42.800
Preparing Data.

00:54:45.320 --> 00:54:46.440
Und das ist einfach

00:54:46.440 --> 00:54:48.500
das Ding, also David Lewis,

00:54:48.600 --> 00:54:50.620
das ist auch der, der den Mod-Up-Display gemacht hat

00:54:50.620 --> 00:54:52.520
und auch überhaupt der, der das ganze Dataset

00:54:52.520 --> 00:54:54.440
kuratiert hat, hat das halt irgendwie auf seiner

00:54:54.440 --> 00:54:56.140
Seite liegen. Und

00:54:56.140 --> 00:54:58.040
genau, dann

00:54:58.040 --> 00:54:59.280
ja.

00:55:00.760 --> 00:55:02.880
Was du auch benutzt an der Stelle im Notebook

00:55:02.880 --> 00:55:04.720
ist ja die

00:55:04.720 --> 00:55:06.980
die Path Library.

00:55:07.140 --> 00:55:07.260
Ja.

00:55:08.260 --> 00:55:10.580
Habe ich auch noch nicht so lange in Benutzung, aber ist eigentlich

00:55:10.580 --> 00:55:12.780
mega cool. Ja, genau. Sag dazu doch nochmal zwei Sätze.

00:55:13.440 --> 00:55:14.020
Ja, also

00:55:14.020 --> 00:55:15.600
früher habe ich das auch mal mit

00:55:15.600 --> 00:55:18.180
OS und ListDir und

00:55:18.180 --> 00:55:20.420
OS Path Join und so gemacht, aber das ist alles

00:55:20.420 --> 00:55:21.800
ganz schön, genau, glaube

00:55:21.800 --> 00:55:24.260
ganz schön umständlich und

00:55:24.260 --> 00:55:26.640
da

00:55:26.640 --> 00:55:28.280
gibt es halt, ich weiß gar nicht,

00:55:28.420 --> 00:55:30.560
seit wann das in der Standard-Library ist, aber

00:55:30.560 --> 00:55:32.120
also es gibt da

00:55:32.120 --> 00:55:34.520
ein Modul namens Parslip

00:55:34.520 --> 00:55:35.700
und

00:55:35.700 --> 00:55:37.980
da kann man

00:55:37.980 --> 00:55:38.940
also

00:55:38.940 --> 00:55:42.760
es geht hier los mit Pars.home

00:55:42.760 --> 00:55:43.920
ist halt sozusagen dann ein Pfad

00:55:43.920 --> 00:55:46.720
und das Ding

00:55:46.720 --> 00:55:48.740
funktioniert im Grunde, wenn man jetzt Pfade erweitern möchte

00:55:48.740 --> 00:55:50.800
oder so über so Operator

00:55:50.800 --> 00:55:52.360
Overloading und

00:55:52.360 --> 00:55:53.880
die haben dann halt einfach das

00:55:53.880 --> 00:55:56.680
den Slash überladen und jetzt kann man

00:55:56.680 --> 00:55:58.580
halt schreiben, irgendwie pass.home

00:55:58.580 --> 00:55:59.920
gibt einem das Home-Verzeichnis, Slash

00:55:59.920 --> 00:56:01.900
Data Slash TMP

00:56:01.900 --> 00:56:04.560
und das ist natürlich viel kürzer, als würde man jetzt

00:56:04.560 --> 00:56:06.380
schreiben, OS Pass Join

00:56:06.380 --> 00:56:08.360
Klammer auf und dann gibt man eine Liste

00:56:08.360 --> 00:56:10.340
oder macht irgendwie, ja irgendwie

00:56:10.340 --> 00:56:12.640
muss dann einen absoluten Pfad angeben

00:56:12.640 --> 00:56:14.520
oder man gibt irgendwie einen relativen Ankommer

00:56:14.520 --> 00:56:16.020
irgendwie das nächste Ding und

00:56:16.020 --> 00:56:18.460
das ist alles ganz schrecklich. Man kann sehr

00:56:18.460 --> 00:56:20.520
schön Variablen quasi mit rein

00:56:20.520 --> 00:56:21.640
betten und

00:56:21.640 --> 00:56:24.600
man bekommt ja am Ende dann auch immer quasi ein Path-Objekt

00:56:24.600 --> 00:56:26.500
wieder raus, was dann auch nochmal so

00:56:26.500 --> 00:56:27.800
Operationen bietet, wie

00:56:27.800 --> 00:56:30.260
okay, jetzt verrat mir von dem noch bitte die

00:56:30.260 --> 00:56:31.540
Subdirectories oder

00:56:31.540 --> 00:56:34.360
ja, halt Operationen dann immer direkt

00:56:34.360 --> 00:56:36.140
auf dem Pfad ausführen. Ja, du kannst einfach

00:56:36.140 --> 00:56:38.220
.exist machen oder sowas, das wäre auch ziemlich cool.

00:56:38.420 --> 00:56:40.240
Genau. Ja, und ansonsten

00:56:40.240 --> 00:56:42.260
hätte man immer os-path-exist und so verwenden

00:56:42.260 --> 00:56:44.460
müssen und dann, also das ist

00:56:44.460 --> 00:56:46.240
wirklich viel, viel angenehmer

00:56:46.240 --> 00:56:47.260
damit zu arbeiten und

00:56:47.260 --> 00:56:50.180
ja, also sonst hat man immer so, also ich hatte sonst

00:56:50.180 --> 00:56:52.040
immer das Problem, dass irgendwie diese ganzen

00:56:52.040 --> 00:56:54.140
Geschichten wurden immer relativ festlich und auch die

00:56:54.140 --> 00:56:56.200
Zeilen wurden sehr lang und das Problem ist

00:56:56.200 --> 00:56:58.100
irgendwie weg, seitdem ich Parslip verwende und das

00:56:58.100 --> 00:57:00.220
ist schon mal echt ein Vorteil. Vielleicht um das

00:57:00.220 --> 00:57:02.160
zu kurz zu zeigen, ich lösche jetzt einfach mal die Daten,

00:57:02.260 --> 00:57:03.380
die ich hier bei mir lokal habe.

00:57:04.880 --> 00:57:05.240
Data,

00:57:06.340 --> 00:57:07.600
TMP.

00:57:08.740 --> 00:57:09.140
Ja, genau.

00:57:12.400 --> 00:57:13.520
Muss man echt mit aufpassen.

00:57:14.080 --> 00:57:16.340
Ja, ja. Ja, wenn du willst so ein Git-Repo

00:57:16.340 --> 00:57:18.200
löschen oder so, machst dann irgendwie Punkt-Slash

00:57:18.200 --> 00:57:20.200
oder so und dann immer aus Versehen löscht man den Punkt

00:57:20.200 --> 00:57:22.160
weg, dann machst du r-r-slash

00:57:22.160 --> 00:57:22.560
und dann

00:57:22.560 --> 00:57:25.220
ja, dann

00:57:25.220 --> 00:57:28.080
immer alles als Super-User machen. Muss man hoffen,

00:57:28.540 --> 00:57:30.120
dass nicht nur das Backup immer funktioniert hat,

00:57:30.240 --> 00:57:31.940
sondern dass das Restore auch mal funktioniert

00:57:31.940 --> 00:57:32.580
ist.

00:57:33.960 --> 00:57:35.560
Ja, genau.

00:57:36.200 --> 00:57:38.220
Ja, ich verwende

00:57:38.220 --> 00:57:39.920
hier einfach so irgendwie

00:57:39.920 --> 00:57:42.420
so Download-from-URL

00:57:42.420 --> 00:57:43.660
Funktion, die benutzt

00:57:43.660 --> 00:57:44.960
tqdm, um

00:57:44.960 --> 00:57:48.140
das ist eine sehr schöne Library, mit der man

00:57:48.140 --> 00:57:49.720
halt so Progress-Bars ganz gut hinkriegt.

00:57:49.820 --> 00:57:51.840
Man kann eigentlich alle Iteratoren irgendwie damit rappen.

00:57:51.880 --> 00:57:53.660
Ja, man braucht nur ein Iterat-Bar und genau.

00:57:55.000 --> 00:57:55.660
Und das ist

00:57:55.660 --> 00:57:58.160
auch sehr, sehr hübsch. Dann sieht man ungefähr, wo man ist.

00:57:59.160 --> 00:58:00.080
Und ja,

00:58:01.060 --> 00:58:01.820
jetzt hat das

00:58:01.820 --> 00:58:03.960
irgendwie dieses Dataset halt irgendwie

00:58:03.960 --> 00:58:05.480
in so ein Data-Verzeichnis geschrieben.

00:58:06.500 --> 00:58:08.020
Dann, das ist halt auch irgendwie das

00:58:08.020 --> 00:58:10.080
Tolle bei Python, dass man irgendwie einen Riesenhaufen

00:58:10.080 --> 00:58:12.260
Funktionalität schon in der Standard-Library

00:58:12.260 --> 00:58:14.020
mit drin hat. Ist eben auch

00:58:14.020 --> 00:58:15.860
sowas drin wie tar-File, dass man halt

00:58:15.860 --> 00:58:16.920
mit tar

00:58:16.920 --> 00:58:20.220
Archiven halt direkt irgendwie umgehen

00:58:20.220 --> 00:58:22.200
kann und dem kann man dann halt

00:58:22.200 --> 00:58:23.720
einfach sagen, okay, pack doch mal alles aus

00:58:23.720 --> 00:58:25.420
und

00:58:25.420 --> 00:58:27.740
ja, dann

00:58:27.740 --> 00:58:29.860
Dann haben wir einen Pickel gebaut oder du hast einen Pickel gebaut?

00:58:29.880 --> 00:58:32.520
Genau, dann parse ich das Ganze auf und

00:58:32.520 --> 00:58:34.060
pickel das wieder raus sozusagen,

00:58:34.180 --> 00:58:36.100
damit ich dieses Parsen nicht jedes Mal machen muss. An der Stelle

00:58:36.100 --> 00:58:37.600
hier ist es relativ egal, weil das ist so schnell.

00:58:38.140 --> 00:58:39.940
Also Pickel speichert einfach das Python-Objekt in der

00:58:39.940 --> 00:58:42.140
Binary einfach, also als Binärdaten

00:58:42.140 --> 00:58:44.220
auf der Platte in einem Objekt und kann es genauso wieder einlesen.

00:58:44.420 --> 00:58:46.140
Pickel ist auch ein Modul aus der Standard-

00:58:46.140 --> 00:58:48.020
Bibliothek, genau, und es serialisiert

00:58:48.020 --> 00:58:50.000
einfach Python-Objekte, beliebige

00:58:50.000 --> 00:58:51.920
Python-Objekte einfach auf, ja, in ein

00:58:51.920 --> 00:58:54.000
Format, das man dann halt auf die Platte schreiben

00:58:54.000 --> 00:58:55.320
kann und hinterher auch wieder lesen kann.

00:58:55.860 --> 00:58:57.540
Und es ist halt relativ schnell. Also

00:58:57.540 --> 00:58:59.940
CSV, genau, ist oft

00:58:59.940 --> 00:59:01.880
das, was man bekommt und das, was am

00:59:01.880 --> 00:59:03.820
meisten verwendet wird und, ja,

00:59:03.900 --> 00:59:05.920
Pandas Reals CSV-Funktion ist sicherlich so

00:59:05.920 --> 00:59:06.820
eine der wichtigsten.

00:59:08.020 --> 00:59:09.320
Aber das ist halt nicht schnell,

00:59:10.280 --> 00:59:11.740
sondern das ist halt irgendwie so,

00:59:12.020 --> 00:59:12.900
ja, sagen wir mal,

00:59:13.900 --> 00:59:15.940
weiß ich nicht, vielleicht 50 MB

00:59:15.940 --> 00:59:17.680
pro Sekunde oder so, was da so durchgeht,

00:59:17.760 --> 00:59:19.400
kommt darauf an, wie komplex das CSV ist.

00:59:20.400 --> 00:59:21.860
Und gut, für die meisten Datensätze

00:59:21.860 --> 00:59:23.860
ist das vielleicht auch, oder was die meisten Leute so haben,

00:59:24.000 --> 00:59:25.760
auch schnell genug, dass das halt irgendwie

00:59:25.760 --> 00:59:27.500
nicht so furchtbar merkbare

00:59:27.500 --> 00:59:29.180
Wartezeiten erzeugt, aber

00:59:29.180 --> 00:59:31.780
wenn man jetzt so ein paar Gigabyte einlesen

00:59:31.780 --> 00:59:33.660
will, dann ist das schon, dann muss man bei CSV schon

00:59:33.660 --> 00:59:35.780
immer warten. Und was

00:59:35.780 --> 00:59:37.680
ich da oft auch mache, ist halt die, wenn ich

00:59:37.680 --> 00:59:38.720
CSVs habe, die

00:59:38.720 --> 00:59:41.720
zuerst irgendwie in DataFrame einzulesen

00:59:41.720 --> 00:59:43.420
mit ReadCSV und dann halt nochmal

00:59:43.420 --> 00:59:45.640
irgendwie einen Pickle-File davon zu cachen.

00:59:45.940 --> 01:00:08.320
weil das Pickel liest halt quasi mit Plattengeschwindigkeit, also da kann man auch so einen Gigabyte pro Sekunde lesen, dann dauert das halt, wenn man halt so einen Data-Frame, der halt irgendwie zwei, drei Gigabyte groß ist, liest, den man auf der Platte gepickelt hat, das dauert dann halt irgendwie auch nur so ein, zwei Sekunden und nicht mehr irgendwie anderthalb Minuten, wenn man das per CSV machen würde und ja, das ist halt auch ganz praktisch.

01:00:08.320 --> 01:00:10.060
natürlich trotzdem Sinn, dass man irgendwie

01:00:10.060 --> 01:00:12.260
eine CSV nimmt zum Teilen, weil

01:00:12.260 --> 01:00:13.980
in so einem Pickel kann halt eben alles dran sein.

01:00:14.080 --> 01:00:16.020
Das ist halt ein Binary-File und

01:00:16.020 --> 01:00:18.300
dementsprechend wahrscheinlich nicht das Beste, um es irgendwie

01:00:18.300 --> 01:00:20.700
im Internet als Austauschformat zu benutzen.

01:00:21.200 --> 01:00:22.760
Das ist auf jeden Fall ein Sicherheitsrisiko,

01:00:22.880 --> 01:00:24.400
weil wenn du da irgendwelche Sachen reinlädst

01:00:24.400 --> 01:00:25.720
und da habe ich dann mein Code reingeschrieben.

01:00:26.320 --> 01:00:28.320
Also wenn man das für einen eigenen Cache benutzt, ist es

01:00:28.320 --> 01:00:30.240
okay, weil das zieht ja sonst keiner, aber stimmt.

01:00:30.720 --> 01:00:32.200
So verteilen soll. Es gibt natürlich auch

01:00:32.200 --> 01:00:34.340
Formate, die dafür gedacht sind, dass man irgendwie

01:00:34.340 --> 01:00:36.440
da größere Datenmengen drin hat

01:00:36.440 --> 01:00:37.160
und das halt auch

01:00:37.160 --> 01:00:38.840
irgendwie teilt.

01:00:39.680 --> 01:00:41.600
Ja, HDF5

01:00:41.600 --> 01:00:42.760
oder NET,

01:00:43.240 --> 01:00:45.260
wie heißt denn das noch, Nachfolger davon?

01:00:45.720 --> 01:00:46.180
Keine Ahnung.

01:00:47.240 --> 01:00:49.220
Oder halt eben sowas wie Parquet-Files

01:00:49.220 --> 01:00:50.760
oder so. Aber

01:00:50.760 --> 01:00:53.160
genau, CSV ist wahrscheinlich immer noch das

01:00:53.160 --> 01:00:53.800
üblichste.

01:00:55.160 --> 01:00:57.280
Ja, genau, ich habe das jetzt einfach

01:00:57.280 --> 01:00:59.260
nochmal so gemacht, um das zu demonstrieren, wie das geht.

01:00:59.480 --> 01:01:01.280
In dem Fall ist es halt völlig überflüssig, weil

01:01:01.280 --> 01:01:03.340
eigentlich sind das so wenig Daten.

01:01:03.340 --> 01:01:05.180
Das merkt man gar nicht.

01:01:06.640 --> 01:01:08.760
Und dann hat man halt sozusagen die

01:01:08.760 --> 01:01:10.840
Daten in einem Format, dass man

01:01:10.840 --> 01:01:12.760
damit irgendwie arbeiten kann.

01:01:14.600 --> 01:01:16.740
Ja, das können wir describen und reingucken.

01:01:16.780 --> 01:01:18.580
Genau, genau, genau. Und dann halt dieses

01:01:18.580 --> 01:01:20.880
Explorer-Notebook sozusagen ausführen.

01:01:21.160 --> 01:01:23.080
Genau, und dann halt eben Daten visualisieren.

01:01:23.360 --> 01:01:24.800
Wir haben vorher jetzt nicht so drüber geredet,

01:01:24.860 --> 01:01:26.580
was für eine Bibliothek man dafür am besten benutzt.

01:01:26.740 --> 01:01:28.180
Was ist denn euer Favorite?

01:01:28.440 --> 01:01:30.460
C-Bone, meiner. Ja, würde ich auch.

01:01:30.680 --> 01:01:32.600
C-Bone ist mal das, was ich normalerweise am Anfang

01:01:32.600 --> 01:01:32.920
verwende.

01:01:34.920 --> 01:01:36.860
Also Seaborn ist auf Matplotlib

01:01:36.860 --> 01:01:38.480
drauf und macht es noch ein bisschen hübscher.

01:01:39.520 --> 01:01:40.700
Ja. Genau, also finde ich

01:01:40.700 --> 01:01:42.600
auch so zum Explorieren ziemlich gut

01:01:42.600 --> 01:01:44.700
am Anfang, sobald meine, ich finde

01:01:44.700 --> 01:01:47.000
man hat für so Grafik-Tools

01:01:47.000 --> 01:01:48.780
ja ganz unterschiedliche Anforderungen. Am Anfang

01:01:48.780 --> 01:01:50.720
willst du irgendwie einfach schnell erstmal

01:01:50.720 --> 01:01:52.600
irgendwie ein bisschen was bekommen, dass es

01:01:52.600 --> 01:01:54.220
irgendwie dir ein Gefühl dafür gibt.

01:01:54.940 --> 01:01:56.740
Dann gibt es den Anwendungsfall, dass man

01:01:56.740 --> 01:01:59.020
irgendwelche High-Resolution-Charts

01:01:59.020 --> 01:02:00.580
machen möchte am Ende, um

01:02:00.580 --> 01:02:02.940
sie zu präsentieren, die dann irgendwie,

01:02:03.140 --> 01:02:04.800
wo dann wichtig ist, dass die Achsbeschriftung stimmt,

01:02:04.920 --> 01:02:06.540
für irgendwie ein Meeting mit

01:02:06.540 --> 01:02:08.860
einem Vorstand oder für eine Publikation

01:02:08.860 --> 01:02:10.840
oder so. Und ich persönlich

01:02:10.840 --> 01:02:12.380
habe dann immer nochmal so einen dritten Anwendungsfall,

01:02:12.860 --> 01:02:14.960
wo ich so ein Diagramm benutze,

01:02:15.040 --> 01:02:16.700
um damit irgendwie kontinuierlich zu arbeiten,

01:02:16.880 --> 01:02:18.920
um irgendwelche Modellmöglichkeiten

01:02:19.600 --> 01:02:20.900
zu visualisieren und die

01:02:20.900 --> 01:02:22.980
dürfen dann gerne auch sehr mächtig und

01:02:22.980 --> 01:02:24.560
ja, teils überladen sein und so weiter.

01:02:25.260 --> 01:02:26.780
Und da finde ich Sibon zum Beispiel

01:02:26.780 --> 01:02:28.360
jetzt irgendwie auch

01:02:28.360 --> 01:02:30.960
zu kompliziert, um jetzt viele verschiedene

01:02:30.960 --> 01:02:32.840
Sachen zu machen. Ich benutze Alt-R sehr gerne

01:02:32.840 --> 01:02:33.340
zum Beispiel.

01:02:34.920 --> 01:02:36.780
kann ich sehr empfehlen, das ist halt die Möglichkeit

01:02:36.780 --> 01:02:38.200
dann quasi

01:02:38.200 --> 01:02:40.560
Alter, Alter, Alter,

01:02:40.660 --> 01:02:42.200
genau, baut

01:02:42.200 --> 01:02:43.940
unten drunter auch Vega auf,

01:02:44.200 --> 01:02:46.720
von der Visualisierungs-Engine

01:02:46.720 --> 01:02:48.420
und folgt halt

01:02:48.420 --> 01:02:49.720
diesem Paradigma von

01:02:49.720 --> 01:02:52.520
Grammar of Graphics, wo man

01:02:52.520 --> 01:02:54.180
halt quasi verschiedene Charts quasi

01:02:54.180 --> 01:02:56.140
übereinander kombinieren kann,

01:02:56.880 --> 01:02:58.580
relativ einfach und

01:02:58.580 --> 01:03:00.620
genau, die benutze ich

01:03:00.620 --> 01:03:02.100
jetzt seit ein paar Monaten sehr, sehr gerne.

01:03:04.020 --> 01:03:04.220
Ja,

01:03:04.580 --> 01:03:05.740
Kennt jemand von euch Buki?

01:03:06.280 --> 01:03:07.080
Ja, ja, genau.

01:03:07.080 --> 01:03:11.180
Habe ich zu meiner Welle mitgearbeitet, irgendwie bin ich da nie so richtig reingekommen, aber das kann auch an mir liegen.

01:03:12.700 --> 01:03:21.460
Ja, Buki ist halt eine so, ist für interaktive Geschichten halt sehr schön, das ist halt eine der beiden Möglichkeiten, um Plots so ein bisschen interaktiver hinzubekommen, andere wäre Plotly.

01:03:21.560 --> 01:03:22.860
Genau, die benutze ich dann lieber.

01:03:22.860 --> 01:03:34.000
Ja, genau, ich auch. Aber Buki ist, glaube ich, auch nicht so schlecht. Also zum Beispiel die Visualisierung, was gerade auf dem Cluster passiert, bei Dask ist halt auch basiert auf Buki.

01:03:34.580 --> 01:03:36.280
Und das ist auch relativ beeindruckend, was die damit

01:03:36.280 --> 01:03:37.540
machen. Aber

01:03:37.540 --> 01:03:40.300
ja,

01:03:40.440 --> 01:03:42.240
nee, Plotly ist auch das, was ich ein bisschen

01:03:42.240 --> 01:03:44.120
lieber finde. Hat jemand das mit DJI JS dann irgendwie noch

01:03:44.120 --> 01:03:45.660
gemoddet irgendwie oder so? Könnte das sein?

01:03:46.860 --> 01:03:48.240
Genau, ich glaube, das basiert unten drunter

01:03:48.240 --> 01:03:49.780
auf die drei. Ja, ich meine auch.

01:03:50.780 --> 01:03:52.260
Eben gerade, weil man das halt eben auch

01:03:52.260 --> 01:03:54.080
dann auch auf Webseiten gut verwenden kann.

01:03:54.540 --> 01:03:56.280
Und zum Beispiel, wenn man jetzt

01:03:56.280 --> 01:03:57.180
irgendwie ein Dashboard hat,

01:03:58.400 --> 01:03:59.060
dann

01:03:59.060 --> 01:04:01.780
kann man halt relativ simpel

01:04:01.780 --> 01:04:03.680
irgendwie mit Plotly halt auch die

01:04:03.680 --> 01:04:05.880
Visualisierung, die man sonst normalerweise im Notebook

01:04:05.880 --> 01:04:07.960
hätte oder so, halt einfach auf eine Webseite packen.

01:04:08.860 --> 01:04:10.080
Und das ist natürlich auch sehr praktisch.

01:04:11.340 --> 01:04:11.460
Genau.

01:04:13.120 --> 01:04:13.440
Ja,

01:04:14.640 --> 01:04:15.840
im D3 kann man aber auch

01:04:15.840 --> 01:04:17.980
verwenden, man kann auch in Notebooks irgendwie

01:04:17.980 --> 01:04:18.900
halt die Daten,

01:04:19.480 --> 01:04:21.800
das kann man natürlich nicht mit unendlich vielen Daten tun, aber

01:04:21.800 --> 01:04:23.540
man kann die halt auch in

01:04:23.540 --> 01:04:26.400
JavaScript reinbringen.

01:04:26.580 --> 01:04:27.520
Also man kann ja auch sozusagen

01:04:27.520 --> 01:04:29.120
im Browser

01:04:29.120 --> 01:04:32.020
via JavaScript Dinge im Notebook

01:04:32.020 --> 01:04:34.320
ausführen, dann sagt man halt der Zelle

01:04:34.320 --> 01:04:36.320
sozusagen, du bist jetzt eine JavaScript-Zelle

01:04:36.320 --> 01:04:36.720
und

01:04:36.720 --> 01:04:40.000
hier kommen die Daten von Python her, also

01:04:40.000 --> 01:04:42.180
es gibt unterschiedliche Wege, wie man die Daten von Python

01:04:42.180 --> 01:04:44.220
dann zu JavaScript irgendwie rüberschaufelt

01:04:44.220 --> 01:04:46.240
und dann kann man da auch

01:04:46.240 --> 01:04:47.940
mit D3 irgendwelche Dinge machen, wenn man zum Beispiel

01:04:47.940 --> 01:04:49.560
so einen Forced

01:04:49.560 --> 01:04:52.580
Graphen, wenn man so einen Graphen-Layout

01:04:52.580 --> 01:04:54.280
hat, was man irgendwie darstellen möchte,

01:04:54.650 --> 01:04:56.890
und man möchte jetzt an irgendeinem Knoten

01:04:56.890 --> 01:04:58.710
ziehen und dann soll das so rumwobbeln oder so, gibt's

01:04:58.710 --> 01:05:00.910
häufig, dann geht das natürlich mit

01:05:00.910 --> 01:05:02.870
also ich wüsste jetzt nicht,

01:05:02.970 --> 01:05:04.810
dass es da irgendwas in Python gibt, was man da nehmen

01:05:04.810 --> 01:05:06.730
kann. Kann sein, dass es mittlerweile auch

01:05:06.730 --> 01:05:08.290
mit Buket oder so geht, keine Ahnung.

01:05:09.070 --> 01:05:10.750
Aber mit D3 geht das natürlich schön. Da gibt's

01:05:10.750 --> 01:05:12.730
einige sehr, sehr witzige, interaktive

01:05:12.730 --> 01:05:14.150
Visualisierungsgeschichten

01:05:14.150 --> 01:05:16.810
und das kann man halt auch im Notebook verwenden.

01:05:17.690 --> 01:05:18.810
Aber es ist so ein bisschen

01:05:18.810 --> 01:05:20.250
fummelig, aber geht auch.

01:05:20.750 --> 01:05:22.790
Habt ihr eine Lieblingslösung, um dann noch mal

01:05:22.790 --> 01:05:24.610
so ein bisschen komplexer, wirklich so Dashboards zu

01:05:24.610 --> 01:05:26.170
bauen, die für euch gut funktioniert?

01:05:27.950 --> 01:05:28.190
Nee,

01:05:28.390 --> 01:05:29.930
ich habe davon gehört, dass,

01:05:30.710 --> 01:05:31.550
wie hieß das noch?

01:05:31.710 --> 01:05:34.430
Das ist quasi die Variante, die da so

01:05:34.430 --> 01:05:35.290
kommt, aber irgendwie

01:05:35.290 --> 01:05:38.450
habe ich bisher nicht so wirklich

01:05:38.450 --> 01:05:40.350
verwendet, weil ich ja also in der

01:05:40.350 --> 01:05:42.250
Django-Welt

01:05:42.250 --> 01:05:44.490
zu Hause bin und da habe ich das halt immer selber gebaut

01:05:44.490 --> 01:05:46.450
bisher, also meistens mache ich halt irgendwelche

01:05:46.450 --> 01:05:48.310
APIs, so Rest-APIs oder so,

01:05:48.790 --> 01:05:50.270
hinter denen dann halt irgendein Modell ist und dann

01:05:50.270 --> 01:05:52.330
meistens auch irgendwie ein View, der dann halt

01:05:52.330 --> 01:05:54.330
ein Dashboard ist, was die Modelle

01:05:54.330 --> 01:05:55.810
so getan haben über die Zeit.

01:05:56.990 --> 01:05:58.430
Ja, und nee, aber

01:05:58.430 --> 01:05:59.950
genau, eigentlich,

01:06:00.190 --> 01:06:02.130
was man gerne hätte, wäre sowas wie Shiny

01:06:02.130 --> 01:06:04.590
für R, aber ich glaube da...

01:06:04.590 --> 01:06:06.510
Ja, Dash versucht genau das zu sein,

01:06:06.690 --> 01:06:08.470
aber aktuell ist es das, finde ich, noch nicht.

01:06:08.470 --> 01:06:10.510
Ja, ich bastel auch gerade an so einem

01:06:10.510 --> 01:06:11.910
eigenen Visualisierungsding da rum, aber

01:06:11.910 --> 01:06:13.450
das ist noch nicht soweit.

01:06:14.590 --> 01:06:14.710
Ja.

01:06:16.670 --> 01:06:18.590
Ja gut, haben wir unsere Daten

01:06:18.590 --> 01:06:20.070
ausreichend visualisiert, würde ich sagen.

01:06:20.670 --> 01:06:22.470
Genau. Wollen wir uns mal dem Modelltraining

01:06:22.470 --> 01:06:23.790
widmen? Ja.

01:06:26.970 --> 01:06:27.370
Okidoki.

01:06:28.770 --> 01:06:30.290
So. Ja.

01:06:31.850 --> 01:06:32.490
Wie trainieren

01:06:32.490 --> 01:06:34.410
wir denn das Modell? Also wir haben

01:06:34.410 --> 01:06:36.530
jetzt die ganzen Daten, wir haben den schon mal angeguckt,

01:06:36.610 --> 01:06:38.470
wir wissen so ein bisschen was, du hast ja rausgeschrieben, was man

01:06:38.470 --> 01:06:39.430
damit so alles anstehen könnte.

01:06:40.690 --> 01:06:42.570
Warum, wieso, weshalb man irgendwelche Features braucht

01:06:42.570 --> 01:06:44.190
und wir wissen natürlich, was wir vielleicht

01:06:44.190 --> 01:06:45.830
rausbekommen wollen oder wissen wir es nicht.

01:06:46.550 --> 01:06:48.450
Also hier dabei wissen wir, dass wir irgendwelche Zusammenhänge

01:06:48.450 --> 01:06:50.530
finden möchten, aber. Genau und wir

01:06:50.530 --> 01:06:52.190
haben ja jetzt in dem Fall ein

01:06:52.190 --> 01:06:54.230
Super-West-Machine-Loading-Problem, weil

01:06:54.230 --> 01:06:56.370
wir wissen halt eben für diese ganzen

01:06:56.370 --> 01:06:58.270
Artikel, welche Tags

01:06:58.270 --> 01:07:00.270
da hinten nachher dranstehen sollen. Also

01:07:00.270 --> 01:07:02.230
wir versuchen ja quasi für einen Artikel

01:07:02.230 --> 01:07:04.070
einen gewissen Tag zu identifizieren

01:07:04.070 --> 01:07:06.330
und den

01:07:06.330 --> 01:07:07.950
kennen wir. Wenn wir den nicht kennen würden,

01:07:08.270 --> 01:07:10.290
dann wäre es quasi unbekannt, dann könnten wir

01:07:10.290 --> 01:07:12.310
nur versuchen, irgendwie ähnliche Artikel

01:07:12.310 --> 01:07:13.510
zusammen zu gruppieren,

01:07:13.890 --> 01:07:16.010
aber dadurch, dass wir die kennen,

01:07:16.590 --> 01:07:18.050
können wir jetzt halt eben versuchen,

01:07:18.850 --> 01:07:20.230
einige von denen zu

01:07:20.230 --> 01:07:22.050
nehmen, da so zu tun, als würden

01:07:22.050 --> 01:07:23.930
wir sie nicht kennen, auf den anderen, wo wir sie

01:07:23.930 --> 01:07:25.890
kennen, unser Modell zu trainieren und

01:07:25.890 --> 01:07:27.970
dann eben quasi auf den, wo wir sie

01:07:27.970 --> 01:07:29.830
quasi weggestrichen haben, eine Prognose zu machen und

01:07:29.830 --> 01:07:31.290
es zu vergleichen. Das ist halt eben

01:07:31.290 --> 01:07:33.730
wesentlich, was man tut mit einem Training

01:07:33.730 --> 01:07:35.910
und eben so einem sogenannten Test-Set.

01:07:37.230 --> 01:07:37.530
Genau.

01:07:38.250 --> 01:07:39.870
Ja, also da gibt es zum Beispiel

01:07:39.870 --> 01:07:41.370
das Notebook einfach nur

01:07:41.370 --> 01:07:42.750
Linear-Model

01:07:42.750 --> 01:07:45.590
und genau,

01:07:45.770 --> 01:07:47.950
wenn man da sozusagen die ersten paar

01:07:47.950 --> 01:07:49.890
Zeilen ausführt, sieht man auch schon nochmal

01:07:49.890 --> 01:07:51.850
quasi, da hat man die Trainings- und

01:07:51.850 --> 01:07:52.530
Testdaten

01:07:52.530 --> 01:07:58.130
und das sind irgendwie 7.770

01:07:58.130 --> 01:07:59.730
Trainingsdokumente,

01:07:59.990 --> 01:08:01.810
3.000 Testdokumente

01:08:01.810 --> 01:08:03.330
in dem vorgegebenen Split

01:08:03.330 --> 01:08:04.990
und

01:08:04.990 --> 01:08:07.990
ja, man hat ja jetzt

01:08:07.990 --> 01:08:09.510
sozusagen die

01:08:09.510 --> 01:08:11.810
Labels eher als Liste

01:08:11.810 --> 01:08:13.870
von Klassen, in denen

01:08:13.870 --> 01:08:15.850
also wenn ich mir jetzt

01:08:15.850 --> 01:08:17.190
zum Beispiel Train Labels

01:08:17.190 --> 01:08:19.830
mal anschaue,

01:08:19.890 --> 01:08:34.650
Dann ist es halt eine Liste von Listen und jedes Element dieser Liste, der großen Liste außenrum, ist halt sozusagen eine Liste der Tags, die halt zu dem entsprechenden Dokument gehören.

01:08:34.870 --> 01:08:43.850
Das ist halt in dem Fall jetzt so, weil wir jetzt eben so ein Multiclass-Multilabel-Problem haben. Also Multiclass besagt ja einfach nur, dass wir eben diese verschiedenen Klassen haben.

01:08:43.990 --> 01:08:50.150
Also wenn wir nicht nur Ja oder Nein sagen, sondern hier halt eben diese 90 Texte, die es gibt, quasi haben, dann haben wir erstmal nur ein Multiclass-Problem.

01:08:50.630 --> 01:08:54.850
Aber jetzt kann es halt auch sein, dass einer dieser Artikel eben mehreren von diesen Texten zugewiesen ist.

01:08:55.250 --> 01:08:59.030
In dem Moment haben wir dann halt eben auch ein sogenanntes Multilabel-Problem.

01:08:59.450 --> 01:09:06.710
Ja, und diesem Format kann ich halt die Labels in einem Modell nicht geben.

01:09:06.710 --> 01:09:09.970
Also ich gebe dem Modell, was ich jetzt trainieren möchte, immer eben zwei Sachen.

01:09:10.070 --> 01:09:21.250
Ich gebe dem einmal eine Feature, eine Matrix der, Feature-Matrix nennt sich das, also quasi eine Matrix, in der die Zeilen, die einzelnen Beobachtungen, Samples sind.

01:09:21.250 --> 01:09:39.950
Und die Spalten sind halt die unterschiedlichen Features und die Labels oder Targets oder wie auch immer man das nennt, die irgendwie eine Information darüber enthalten, was denn jetzt sozusagen da richtig rauskommen sollte, wenn man sich diese Zeile anguckt.

01:09:40.070 --> 01:09:41.850
und wenn man jetzt

01:09:41.850 --> 01:09:43.790
ein Multilabel-Dataset hat, dann

01:09:43.790 --> 01:09:45.970
man kann jetzt das nicht

01:09:45.970 --> 01:09:47.730
sozusagen als diese Liste von Listen übergeben.

01:09:48.730 --> 01:09:50.050
Listen wären sowieso schlecht,

01:09:50.150 --> 01:09:51.770
weil Listen sind halt, brauchen in Python

01:09:51.770 --> 01:09:53.710
relativ viel Hauptspeicher und

01:09:53.710 --> 01:09:55.770
im Grunde, wenn man jetzt, also

01:09:55.770 --> 01:09:57.790
bei Scikit-Learn ist es jedenfalls so, aber

01:09:57.790 --> 01:09:59.990
eigentlich orientieren sich fast alle

01:09:59.990 --> 01:10:02.390
anderen Maschinen-Learning-

01:10:02.390 --> 01:10:03.930
Bibliotheken, die es so gibt, auch

01:10:03.930 --> 01:10:06.050
an der entsprechenden API

01:10:06.050 --> 01:10:07.770
von Scikit-Learn,

01:10:08.250 --> 01:10:11.670
das ist die Estimator-API für Modelle eben,

01:10:12.570 --> 01:10:15.870
da übergibt man immer Arrays, also NumPy-Arrays.

01:10:16.890 --> 01:10:18.750
Und sowas wie Listen oder so kann man da nicht übergeben.

01:10:20.930 --> 01:10:23.290
Das heißt, man muss erst mal das so in Format bringen,

01:10:23.390 --> 01:10:25.730
dass man das überhaupt den entsprechenden Modellen übergeben kann.

01:10:26.330 --> 01:10:27.910
Und für Multilabel ist es eben so,

01:10:27.910 --> 01:10:31.910
dass das richtige Format dann halt ist,

01:10:33.610 --> 01:10:35.570
ein NumPy-Array zu haben,

01:10:35.750 --> 01:10:40.970
das halt auch wieder genauso viele Zeilen hat,

01:10:41.130 --> 01:10:42.610
wie man in der Feature-Matrix hat

01:10:42.610 --> 01:10:43.610
oder eben genauso viele Zeilen,

01:10:43.730 --> 01:10:45.090
wie es eben Dokumente gibt,

01:10:45.190 --> 01:10:46.810
die zum Training-Set gehören

01:10:46.810 --> 01:10:49.250
und dann so viel spalten,

01:10:49.470 --> 01:10:55.050
wie es Kategorien gibt oder Labels gibt,

01:10:55.050 --> 01:10:57.270
in denen ein Dokument liegen kann

01:10:57.270 --> 01:10:59.930
und sozusagen die,

01:11:00.530 --> 01:11:01.850
für jede Spalte gibt es dann halt sozusagen,

01:11:02.090 --> 01:11:03.370
also jede Spalte ist halt eine Kategorie

01:11:03.370 --> 01:11:05.070
und wenn dann ein Null drin steht,

01:11:05.230 --> 01:11:07.290
bedeutet das im Grunde, das Dokument liegt

01:11:07.290 --> 01:11:09.070
nicht in dieser Kategorie oder hat dieses Tag eben nicht.

01:11:09.490 --> 01:11:11.050
Wenn da 1 drin steht, dann heißt das,

01:11:11.190 --> 01:11:13.270
okay, ja, das ist sozusagen die richtige

01:11:13.270 --> 01:11:15.370
Kategorie für dieses Dokument.

01:11:16.510 --> 01:11:16.790
Und

01:11:16.790 --> 01:11:18.910
genau, dafür gibt es

01:11:18.910 --> 01:11:20.890
aus dem Scikit-Learn

01:11:20.890 --> 01:11:23.070
Pre-Processing-Modul halt ein Ding,

01:11:23.150 --> 01:11:24.590
das nennt sich Multilabel-Binarizer

01:11:24.590 --> 01:11:26.750
und dem gibt man einfach diese Liste von Listen

01:11:26.750 --> 01:11:29.090
und dann spuckt das halt eine richtig formatierte

01:11:29.090 --> 01:11:33.170
richtig formatiertes NumPy-Array aus.

01:11:33.770 --> 01:11:34.750
Also das ist auch sowas, das muss man,

01:11:34.750 --> 01:11:36.890
also diese ganze Transformation, das muss man nicht selber machen.

01:11:36.990 --> 01:11:38.790
Da gibt es eigentlich für alle Geschichten, die man da so

01:11:38.790 --> 01:11:40.270
haben kann, fertige

01:11:40.270 --> 01:11:42.310
Lösungen schon.

01:11:42.750 --> 01:11:44.870
Man kann sich, glaube ich, auch aussuchen, was da mit den Werten,

01:11:44.890 --> 01:11:46.710
die da nicht reinpassen, irgendwie geschehen soll und sowas.

01:11:48.070 --> 01:11:48.390
Ja,

01:11:48.590 --> 01:11:50.650
bestimmt. Ich weiß jetzt gar nicht genau, was der

01:11:50.650 --> 01:11:52.550
Multilabel-Bannerizer da sonst auch so macht.

01:11:52.830 --> 01:11:54.530
Und langfristig ist es vor allem auch nicht sinnvoll,

01:11:54.590 --> 01:11:56.830
sich das zu machen. Also am Anfang, wenn man das noch nie gemacht hat,

01:11:56.910 --> 01:11:58.810
denkt man so, also man muss ja

01:11:58.810 --> 01:12:00.670
schon auch einmal erstmal durchsteigen, wie das

01:12:00.670 --> 01:12:02.530
überhaupt alles funktioniert mit diesen

01:12:03.910 --> 01:12:05.370
Prozessen und den Modellen und so weiter

01:12:05.370 --> 01:12:07.590
und dann denkt man, ich will doch eigentlich nur so ein Modell

01:12:07.590 --> 01:12:09.650
benutzen, ich kann den ganzen Rest auch von Hand machen

01:12:09.650 --> 01:12:11.630
und fängt damit gerne erstmal

01:12:11.630 --> 01:12:13.510
an, weil man auch gerne ein bisschen programmiert

01:12:13.510 --> 01:12:15.550
und nicht ewig Doku liest,

01:12:15.730 --> 01:12:17.710
aber faktisch ist man halt letztendlich

01:12:17.710 --> 01:12:19.550
dann doch viel schneller, wenn man sich das halt einmal

01:12:19.550 --> 01:12:21.530
aneignet, wie denn diese Binarizer und so weiter

01:12:21.530 --> 01:12:22.450
funktionieren.

01:12:25.670 --> 01:12:27.290
Genau, ja.

01:12:28.050 --> 01:12:29.310
Und dann

01:12:29.310 --> 01:12:31.410
hat man quasi das gleiche Problem,

01:12:31.410 --> 01:12:32.950
nur irgendwie ein bisschen anders.

01:12:33.910 --> 01:12:35.850
auf der Feature-Matrix-Seite halt eben

01:12:35.850 --> 01:12:37.470
auch, da man hatte erstmal Text.

01:12:38.730 --> 01:12:39.910
Den kann man jetzt so in ein Modell

01:12:39.910 --> 01:12:41.470
nicht reinwerfen, weil

01:12:41.470 --> 01:12:44.090
ja, ist halt

01:12:44.090 --> 01:12:45.870
also

01:12:45.870 --> 01:12:48.190
letztlich ist eine Feature-Matrix eigentlich immer

01:12:48.190 --> 01:12:53.950
sollten das eigentlich immer mehr oder weniger

01:12:53.950 --> 01:12:56.070
Float-Werte sein, die da letztlich drin landen

01:12:56.070 --> 01:12:57.750
und das ist halt ein NumPy-Array von

01:12:57.750 --> 01:12:59.690
irgendwie Float-Geschichten und das ist Text

01:12:59.690 --> 01:13:01.470
halt nicht. Man muss jetzt erstmal Text irgendwie

01:13:01.470 --> 01:13:03.190
in Zahlen

01:13:03.190 --> 01:13:05.570
irgendwie umwandeln und das ist halt

01:13:05.570 --> 01:13:07.490
schon so eine Art, man nennt das halt

01:13:07.490 --> 01:13:08.290
Feature-Extraktion.

01:13:10.430 --> 01:13:11.470
Also man macht

01:13:11.470 --> 01:13:13.770
sozusagen aus Text

01:13:13.770 --> 01:13:15.610
irgendwie eine

01:13:15.610 --> 01:13:17.070
Reihe von Features,

01:13:17.650 --> 01:13:19.410
also Spalten in einer Feature-Matrix.

01:13:20.850 --> 01:13:21.270
Und

01:13:21.270 --> 01:13:23.110
so eine ganz

01:13:23.110 --> 01:13:25.870
alte Standard-Methode,

01:13:25.930 --> 01:13:27.370
wie man das halt tun kann, ist

01:13:27.370 --> 01:13:31.670
einmal man repräsentiert

01:13:31.670 --> 01:13:33.410
Text halt als Back of Words

01:13:33.410 --> 01:13:35.670
nennt sich das. Das bedeutet,

01:13:36.210 --> 01:13:37.910
man

01:13:37.910 --> 01:13:39.610
wirft die Reihenfolgeinformation

01:13:39.610 --> 01:13:41.550
der Wörter weg, was irgendwie schlimm klingt, aber

01:13:41.550 --> 01:13:42.850
dann doch nicht so schlimm ist

01:13:42.850 --> 01:13:45.690
und merkt sich

01:13:45.690 --> 01:13:47.350
sozusagen, also

01:13:47.350 --> 01:13:49.630
jede, man kann sich das ungefähr so

01:13:49.630 --> 01:13:51.510
vorstellen, man hat jetzt, ja,

01:13:51.870 --> 01:13:53.490
weiß nicht, ob das eine gute Idee ist,

01:13:53.530 --> 01:13:55.390
zu sagen, man sollte sich das wie eine Excel-Tabelle vorstellen.

01:13:55.610 --> 01:13:56.250
Wahrscheinlich eher nicht.

01:13:57.630 --> 01:13:58.830
Das hat jemand schon niemals

01:13:58.830 --> 01:14:00.610
gesehen. Also warum nicht?

01:14:01.250 --> 01:14:04.590
Ja, es ist auch so ein bisschen so ähnlich wie bei den Labels.

01:14:04.690 --> 01:14:06.490
Es ist auch so eine Art One-Hot-Encoding.

01:14:07.290 --> 01:14:10.850
Man hat halt pro Spalte quasi, also man macht eine Spalte pro Wort.

01:14:12.370 --> 01:14:17.330
Und wenn das Wort in dem Text vorkommt, dann macht man da eine Eins rein,

01:14:17.430 --> 01:14:19.810
ansonsten macht man da eine Null rein in die Spalten.

01:14:19.930 --> 01:14:22.850
Also man hat sozusagen so viele Spalten, wie es überhaupt unterschiedliche Worte

01:14:22.850 --> 01:14:26.810
im gesamten Dokument-Korpus gibt, also über alle Dokumente drüber.

01:14:28.710 --> 01:14:31.650
Wobei Back of Words macht doch schon auch die Anzahl gleich rein, oder?

01:14:32.750 --> 01:14:40.430
Ja, ich weiß nicht, man kann auch die Anzahl direkt rein, also der einfachste Fall wäre, dass man einfach nur reinschreibt, ist es da oder nicht, binär.

01:14:43.690 --> 01:14:55.130
Und genau, dann die nächste etwas, also das funktioniert auch schon erstaunlich gut, aber das hat halt auch diverse Probleme.

01:14:55.130 --> 01:15:10.050
Unter anderem ist es halt so, dass längere Texte natürlich viel, bei denen steigt die Wahrscheinlichkeit, dass sie in allen möglichen Kategorien sind. Einfach deswegen, weil eine Menge Worte darin auftauchen, die halt in allen möglichen Kategorien auftauchen.

01:15:10.330 --> 01:15:13.390
Oder derjenige, die den Nachrichtenbeitrag geschrieben hat, war SEO-Experte oder so.

01:15:13.950 --> 01:15:37.790
Ja, ja, genau. Das wäre halt etwas, was man versuchen wollen würde zu verhindern, dass das halt so eine große Auswirkung hat, wenn da irgendwie eine lange Liste von vielen unterschiedlichen Wörtern drinsteht. Und das ist eine klassische Methode, die man da verwendet. Es kommt auch aus dem Information Retrieval Bereich, ist halt einmal zu zählen, wie oft ein Wort drin vorkommt.

01:15:37.890 --> 01:16:07.870
Das braucht man halt vor allen Dingen deswegen, weil man damit mit der Information, wie oft kommt ein Wort in einem Text vor plus wie lang ist der Text, kann man halt die Frequenz ausrechnen, also sozusagen wie ist die Frequenz von dem Wort in dem Text. Das ist einfach nur wie oft kommt es vor, geteilt durch die Länge des Textes und das funktioniert dann schon besser, also da könnte man dann irgendwie einen Count Vectorizer nehmen, der würde halt dann zählen, nicht nur binär irgendwie einen großen Vektor bauen, in dem 1 und 0 drinstehen, je nachdem ob ein Wort drin ist.

01:16:07.890 --> 01:16:09.610
kommt oder nicht. Das wäre dann schon die

01:16:09.610 --> 01:16:11.950
Term-Frequency, oder? Ja, damit

01:16:11.950 --> 01:16:13.130
hätte man erstmal nur die Counts und dann

01:16:13.130 --> 01:16:15.730
ich weiß nicht, ob es noch einen, aber es gibt

01:16:15.730 --> 01:16:17.810
keinen Vectorizer, der dann nur

01:16:17.810 --> 01:16:19.430
Term-Frequenz macht, sondern dann

01:16:19.430 --> 01:16:21.410
würde man direkt sowas nehmen wie TF-EDF

01:16:21.410 --> 01:16:23.990
Vectorizer. Das Problem

01:16:23.990 --> 01:16:25.870
bei der Term-Frequenz ist halt... Ich glaube,

01:16:25.930 --> 01:16:27.630
das habt ihr alle ein bisschen abgehängt. Erstmal, was ist ein

01:16:27.630 --> 01:16:28.970
Term-Vectorizer, was ist ein TF-ID?

01:16:30.210 --> 01:16:30.670
Ja, also

01:16:30.670 --> 01:16:33.790
im Grunde kann man eigentlich direkt mit dem TF-EDF

01:16:33.790 --> 01:16:35.890
einsteigen.

01:16:35.890 --> 01:16:37.510
Das ist halt sozusagen eine

01:16:37.510 --> 01:16:48.050
Wenn man sich jetzt einen Vektor anguckt, wo nur drinsteht, ob ein Wort in einem Text vorkommt oder nicht, da stehen nur Einsen und Nullen drin, dann ist das halt schlecht.

01:16:48.130 --> 01:16:54.890
Man möchte eigentlich ein anderes Gewicht darin stehen haben für Worte, weil manche Worte sind halt wichtiger oder charakteristischer für eine Kategorie als andere.

01:16:54.890 --> 01:17:12.750
Also wenn ich die Kategorie Politik habe und da kommt irgendwie Parlament drin vor, dann ist das sozusagen dafür irgendwie eine aussagekräftigere Geschichte, als wenn jetzt das Wort das drin vorkommt oder so, was einfach in jedem Text vorkommt.

01:17:12.750 --> 01:17:30.750
Und wenn man jetzt einfach nur ein 1 und ein 0 reinschreibt, dann würde das aber gleich behandelt irgendwie und das kann ja nicht so richtig sein. Und die Methode, mit der man das versucht, besser zu machen, ist uralt, ich glaube mittlerweile über 40 Jahre alt.

01:17:32.710 --> 01:17:34.390
Ich glaube, Anfang der 70er oder so, dass

01:17:34.390 --> 01:17:36.770
Karen Speck-Jones, glaube ich, irgendwie sich mal

01:17:36.770 --> 01:17:37.650
überlegt. Ich weiß es nicht genau.

01:17:39.290 --> 01:17:40.970
Eben, TF-EDF

01:17:40.970 --> 01:17:42.410
vor allen Dingen für Suchmaschinen entwickelt.

01:17:43.150 --> 01:17:45.010
Da möchte man das halt auch haben.

01:17:45.170 --> 01:17:46.830
Man hat halt ein Query und möchte dazu

01:17:46.830 --> 01:17:48.750
die relevantesten Dokumente irgendwie

01:17:48.750 --> 01:17:49.330
rausfiltern.

01:17:51.690 --> 01:17:51.970
Und

01:17:51.970 --> 01:17:53.970
dieses Gewichtungs...

01:17:53.970 --> 01:17:56.650
Dieses Gewichtungsding nennt sich halt

01:17:56.650 --> 01:17:58.350
TF-EDF, also Term Frequency

01:17:58.350 --> 01:17:59.750
mal

01:17:59.750 --> 01:18:01.790
Inverse Document Frequency.

01:18:02.010 --> 01:18:04.270
Term Frequency ist einfach nur die

01:18:04.270 --> 01:18:06.410
Frequenz von dem Wort

01:18:06.410 --> 01:18:08.390
in dem Text. Also das ist einfach nur Count,

01:18:08.490 --> 01:18:09.410
wie oft kommt das Wort vor

01:18:09.410 --> 01:18:12.370
in dem Text, geteilt durch, wie lang ist der Text,

01:18:12.710 --> 01:18:13.050
mal

01:18:13.050 --> 01:18:16.590
Logarithmus von

01:18:16.590 --> 01:18:22.590
Ja, genau. Ich kann den an der Stelle auch nicht genau

01:18:22.590 --> 01:18:24.350
geteilt durch, wie oft kommt

01:18:24.350 --> 01:18:25.450
das Wort irgendwie

01:18:25.450 --> 01:18:28.010
in allen Texten vor, sozusagen. Also

01:18:28.010 --> 01:18:30.090
das Ding wird halt höher. Je höher, desto

01:18:30.090 --> 01:18:31.610
seltener es ist. Also sozusagen

01:18:31.610 --> 01:18:33.690
und man nimmt dann mal den Logarithmus,

01:18:33.770 --> 01:18:35.270
damit es nicht ganz so schlimm wird, damit es halt so ein bisschen

01:18:35.270 --> 01:18:37.410
ein bisschen flacher wird. Genau.

01:18:37.950 --> 01:18:40.090
Weil man möchte halt auch nicht so total krasse

01:18:40.090 --> 01:18:41.650
Unterschiede haben.

01:18:41.790 --> 01:18:43.270
Es sollte sich so ein bisschen auswirken, aber

01:18:43.270 --> 01:18:46.050
Genau. Das ist vom Prinzip her die Spezifität

01:18:46.050 --> 01:18:46.970
des Wortes. Also

01:18:46.970 --> 01:18:49.470
wie charakteristisch, wie

01:18:49.470 --> 01:18:51.770
ist das ein Wort, was ständig vorkommt oder was halt eben

01:18:51.770 --> 01:18:53.710
relativ selten vorkommt. Gewichtet

01:18:53.710 --> 01:18:55.910
mit wie häufig kommt dieses Wort in dem Text vor.

01:18:56.330 --> 01:18:57.690
Gibt halt ein ganz gutes Maß darüber.

01:18:59.010 --> 01:18:59.830
Ja, ist das speziell

01:18:59.830 --> 01:19:01.490
für diese Kategorie? Da oder nicht?

01:19:01.610 --> 01:19:04.690
Da müsste man tatsächlich aber auch

01:19:04.690 --> 01:19:06.750
eine Datenbank haben, der alle Wörter irgendwo

01:19:06.750 --> 01:19:08.510
schon in gewisser Häufigkeit vorkommen, also zumindest

01:19:08.510 --> 01:19:10.230
die, die so allgemein rausfallen.

01:19:10.230 --> 01:19:11.930
Das ist natürlich so eine interessante Geschichte.

01:19:12.150 --> 01:19:14.170
Wie kommt man an diese Gewichte

01:19:14.170 --> 01:19:16.250
eigentlich ran? Und wenn man jetzt zum Beispiel

01:19:16.250 --> 01:19:18.030
irgendwie das mit dem Cross-Validation und

01:19:18.030 --> 01:19:20.190
Trennen in Trainings- und Test-Sets selber machen

01:19:20.190 --> 01:19:22.090
würde, dann läuft man direkt in solche

01:19:22.090 --> 01:19:24.090
Probleme rein. Wo berechnet man eigentlich

01:19:24.090 --> 01:19:26.150
die Gewichte? Nimmt man alle Daten, die man hat, um die

01:19:26.150 --> 01:19:27.430
auszurechnen?

01:19:29.270 --> 01:19:30.070
Liegt man da nicht

01:19:30.070 --> 01:19:31.970
die Tester, dann legt man nicht die

01:19:31.970 --> 01:19:33.850
Informationen über das Test-Dataset schon

01:19:33.850 --> 01:19:36.310
in das Training mit rein? Darf man das machen?

01:19:36.470 --> 01:19:37.830
Ja, vor allem ist halt auch die Frage, wie gut sind deine

01:19:37.830 --> 01:19:39.990
Tester? Sind die halt verteilt? Sind die homogen? Hast du da

01:19:39.990 --> 01:19:41.710
eine schiefe Verteilung zum Beispiel oder sowas?

01:19:42.030 --> 01:19:43.430
Das wäre dann auch irgendwie doof, weil

01:19:43.430 --> 01:19:46.010
dann die Sachen, die schief drin liegen,

01:19:46.150 --> 01:19:48.010
dann überprofessionell drin vertreten sind und du

01:19:48.010 --> 01:19:50.010
vielleicht von den Sachen, die da

01:19:50.010 --> 01:19:51.870
selten drin sind, nicht so viele. Genau, aber

01:19:51.870 --> 01:19:53.890
dieses Problem, was du gerade sagst mit dem Training

01:19:53.890 --> 01:19:55.490
und den Testarten, ist halt wirklich so ein klassisches.

01:19:56.050 --> 01:19:57.850
Also du hast eigentlich nur zwei Optionen.

01:19:58.130 --> 01:19:59.850
Entweder ich sage,

01:20:00.030 --> 01:20:02.530
ich trainiere mein TF-IDF

01:20:02.530 --> 01:20:04.030
auf allen meinen Daten, auch

01:20:04.030 --> 01:20:06.170
vom Test-Set, dann habe ich halt alle Wörter

01:20:06.170 --> 01:20:08.210
wirklich drin, die potenziell vorkommen können

01:20:08.210 --> 01:20:09.990
nachher, aber dann habe ich halt eben

01:20:09.990 --> 01:20:11.910
die Gefahr von Information Leakage,

01:20:12.050 --> 01:20:13.950
also das heißt einfach, die Daten, die mir

01:20:13.950 --> 01:20:16.090
eigentlich ja potenziell unbekannt sind, ich will ja nachher

01:20:16.090 --> 01:20:18.050
auf Daten generalisieren, die

01:20:18.050 --> 01:20:20.170
ich noch wirklich gar nicht kenne. Das Test-Set

01:20:20.170 --> 01:20:22.090
ist ja nur eine Abstraktion, um irgendwie am Anfang

01:20:22.090 --> 01:20:23.410
damit trainieren zu können.

01:20:24.810 --> 01:20:24.970
Dann

01:20:24.970 --> 01:20:28.130
tue ich so, als würde ich diese Informationen

01:20:28.130 --> 01:20:30.010
eigentlich nicht kennen, aber in Wirklichkeit habe ich sie ja

01:20:30.010 --> 01:20:32.050
doch irgendwie verarbeitet. Auf der anderen

01:20:32.050 --> 01:20:33.950
Seite, wenn ich das nicht mache, passiert es mir halt, dass

01:20:33.950 --> 01:20:35.970
ich im Testset irgendwelche Wörter habe, die ich

01:20:35.970 --> 01:20:38.130
so gar nicht habe und dann habe ich dazu quasi

01:20:38.130 --> 01:20:40.150
keinen IDF-Score, keinen validen.

01:20:41.850 --> 01:20:42.050
Genau.

01:20:42.170 --> 01:20:44.050
Und dann gibt es halt im Endeffekt, brauchst du halt

01:20:44.050 --> 01:20:46.030
entweder ein sehr, sehr großes Datenset, dass du das

01:20:46.030 --> 01:20:47.950
irgendwie selber machen kannst und

01:20:47.950 --> 01:20:49.910
hast oder du kannst halt auch quasi

01:20:49.910 --> 01:20:51.290
ein Datenset benutzen,

01:20:51.990 --> 01:20:54.370
quasi, also für so eine Generalität

01:20:54.370 --> 01:20:56.090
von Wörtern könntest du jetzt auch ein

01:20:56.090 --> 01:20:57.890
öffentliches Datenset benutzen. Wikipedia

01:20:57.890 --> 01:21:00.290
oder sowas. Genau, aber dann ist es halt nicht so spezifisch

01:21:00.290 --> 01:21:02.010
aus deinem Anwendungsfall wahrscheinlich und

01:21:02.010 --> 01:21:03.970
vielleicht ist das Wort

01:21:03.970 --> 01:21:06.310
Enzyklopädie in der

01:21:06.310 --> 01:21:08.170
Wikipedia selbst irgendwie viel häufiger

01:21:08.170 --> 01:21:10.510
und viel unspezifischer,

01:21:10.630 --> 01:21:12.090
als es bei dir jetzt im Wort vielleicht wäre.

01:21:12.410 --> 01:21:14.230
Bei dir in deinen Daten vielleicht wäre.

01:21:15.390 --> 01:21:16.270
Genau, also es ist auch

01:21:16.270 --> 01:21:18.130
wieder so ein Abwägungsding, wie geht man damit um?

01:21:18.650 --> 01:21:18.750
Ja.

01:21:20.570 --> 01:21:22.170
Und ja, hier ist es zum Glück halt

01:21:22.170 --> 01:21:24.090
irgendwie alles schon sozusagen

01:21:24.090 --> 01:21:26.150
sind diese Geschichten vorgegeben und wir

01:21:26.150 --> 01:21:28.310
ermitteln die Zahlen halt sozusagen nur auf den

01:21:28.310 --> 01:21:29.970
Trainingsdaten und

01:21:29.970 --> 01:21:31.950
fitten das halt nur auf den Testdaten, also

01:21:31.950 --> 01:21:33.110
ja.

01:21:35.090 --> 01:21:36.210
Fitten das nur auf den Trainingsdaten

01:21:36.210 --> 01:21:37.670
und transformieren nur die Testdaten, also

01:21:37.670 --> 01:21:39.010
sozusagen, ja.

01:21:41.570 --> 01:21:42.390
Und es ist gerade spannend,

01:21:42.490 --> 01:21:44.170
mir kommt gerade der Gedanke, ist es denn

01:21:44.170 --> 01:21:46.110
tatsächlich dann so, dass nicht ein größeres

01:21:46.110 --> 01:21:47.590
Daten-Set eine bessere Methode

01:21:47.590 --> 01:21:50.230
verursacht, sondern tatsächlich das richtige

01:21:50.230 --> 01:21:52.090
Daten-Set, was das Wichtige ist, als

01:21:52.090 --> 01:21:52.970
die Menge an Daten?

01:21:54.050 --> 01:21:56.070
Hört es sich gerade ein bisschen so an, also ich fette jetzt

01:21:56.070 --> 01:21:57.890
intuitiv andersrum gedacht.

01:21:58.690 --> 01:22:00.570
Das heißt, je mehr Testdaten

01:22:00.570 --> 01:22:02.550
ich zur Verfügung hätte, auf denen ich meinen Algorithmus

01:22:02.550 --> 01:22:04.390
testen kann, desto besser wird mein Ergebnis

01:22:04.390 --> 01:22:06.310
und das, was gerade so ein bisschen durchgehen war,

01:22:06.310 --> 01:22:08.010
dass Trainingsdaten sind

01:22:08.010 --> 01:22:09.750
das, was dein Modell besser macht.

01:22:10.230 --> 01:22:12.270
Ja, genau. Testdaten. Also das meinte ich

01:22:12.270 --> 01:22:14.170
mit. Achso, gerade nochmal verwechselt wahrscheinlich.

01:22:14.190 --> 01:22:15.930
Ja, okay, ja, genau. Ja, ja, je mehr

01:22:15.930 --> 01:22:18.110
Trainingsdaten hast, desto besser, aber. Also weil dann würde man

01:22:18.110 --> 01:22:20.190
Wikipedia zum Beispiel schon nehmen können, wenn das korrekt

01:22:20.190 --> 01:22:22.290
gelabelt ist. Ja, dann würde das dazu

01:22:22.290 --> 01:22:23.670
führen, selbst wenn da mehr

01:22:23.670 --> 01:22:26.750
Aber Wikipedia ist ja jetzt für deinen Anwendungsfall

01:22:26.750 --> 01:22:27.330
nicht gelabelt.

01:22:28.370 --> 01:22:30.230
Wenn ich das gelabelt hätte, das war ja dann das.

01:22:30.230 --> 01:22:32.530
Und das ist natürlich wahrscheinlich eben anders. Das ist halt das Problem.

01:22:32.690 --> 01:22:33.530
Das ist anders verteilt als

01:22:33.530 --> 01:22:36.250
das, was du irgendwie benutzen

01:22:36.250 --> 01:22:38.310
willst. Also es ist dann aber doch halt nicht die Menge der Daten,

01:22:38.370 --> 01:22:40.310
sondern die müssen halt schon matchen. Also ich brauche halt so den Scope

01:22:40.310 --> 01:22:42.250
in die richtige Richtung schon. Das heißt, da kann halt

01:22:42.250 --> 01:22:44.070
ein Riesenproblem daraus entstehen, wenn ich irgendwas

01:22:44.070 --> 01:22:46.130
rausfinden will, was ich überhaupt nicht beschrieben habe in den Daten.

01:22:46.270 --> 01:22:48.430
Dann ist Murks. Genau. Und ein Stück weit

01:22:48.430 --> 01:22:50.390
muss man da jetzt auch nochmal unterscheiden. Wir haben ja gerade so ein bisschen

01:22:50.390 --> 01:22:52.090
davon geredet, wie kriege ich denn die

01:22:52.090 --> 01:22:54.090
Spezifizität von den Wörtern, da geht es ja darum,

01:22:54.490 --> 01:22:55.930
wie überführe ich unseren Text

01:22:55.930 --> 01:22:58.410
überhaupt erstmal in so eine Zahlenmatrix,

01:22:58.410 --> 01:23:00.310
auf den wir dann basierend unser Training

01:23:00.310 --> 01:23:01.970
ausführen können. Und um das

01:23:01.970 --> 01:23:04.250
transformieren von den

01:23:04.250 --> 01:23:06.630
Textdaten zu so einer Zahlenmatrix

01:23:06.630 --> 01:23:08.230
zu machen, da kann ich vielleicht durchaus einen

01:23:08.230 --> 01:23:10.390
größeren, globalen

01:23:10.390 --> 01:23:12.410
Korpus nehmen, den ich da quasi für die Wörter

01:23:12.410 --> 01:23:13.490
benutze zum Umwandeln.

01:23:14.170 --> 01:23:16.110
Wenn ich dann allerdings wirklich mein Modell trainiere, dann

01:23:16.110 --> 01:23:18.290
macht es natürlich überhaupt keinen Sinn, das irgendwie mit Wikipedia

01:23:18.290 --> 01:23:20.130
Daten zu machen, wenn ich eigentlich dann

01:23:20.130 --> 01:23:22.570
meine Art Artikel machen möchte,

01:23:22.690 --> 01:23:24.610
weil das ist wahrscheinlich dann anders.

01:23:24.990 --> 01:23:25.090
Ja.

01:23:26.750 --> 01:23:28.330
Das gibt es auch noch in diversen

01:23:28.330 --> 01:23:29.010
anderen,

01:23:31.690 --> 01:23:31.970
also

01:23:31.970 --> 01:23:34.430
das Problem kriegt man halt auch immer wieder, also wenn man jetzt

01:23:34.430 --> 01:23:34.870
zum Beispiel

01:23:34.870 --> 01:23:38.150
das jetzt TF-IDF ist

01:23:38.150 --> 01:23:39.990
halt auch so ein klassisches Verfahren und

01:23:39.990 --> 01:23:41.970
man kann es auch noch relativ leicht verstehen, insofern

01:23:41.970 --> 01:23:44.050
ist das eigentlich, glaube ich, ein ganz guter Kandidat, um das

01:23:44.050 --> 01:23:46.150
da zu benutzen, was man jetzt, wenn man

01:23:46.150 --> 01:23:48.350
ein echtes Problem hätte, auf jeden Fall

01:23:48.350 --> 01:23:49.990
wahrscheinlich auch noch machen wollen würde,

01:23:50.130 --> 01:23:51.930
ist sogenannte

01:23:51.930 --> 01:23:53.650
Word Embeddings. Also man würde halt

01:23:53.650 --> 01:23:55.430
nicht nur, einfach nur

01:23:55.430 --> 01:23:57.770
sozusagen pro Wort eine Dimension nehmen, sondern

01:23:57.770 --> 01:23:58.270
man würde

01:23:58.270 --> 01:24:01.030
ja, diese

01:24:01.030 --> 01:24:03.590
Worte halt aus

01:24:03.590 --> 01:24:05.910
jedem Wort mehrere Dimensionen erzeugen

01:24:05.910 --> 01:24:08.350
und die sozusagen eingebettet in so ein

01:24:08.350 --> 01:24:13.910
Ja, also was man

01:24:13.910 --> 01:24:15.530
mit Word Embeddings macht, ist man

01:24:15.530 --> 01:24:17.750
projiziert jedes Wort

01:24:17.750 --> 01:24:19.390
in einen mehrdimensionalen Vektorraum

01:24:19.390 --> 01:24:21.910
und dadurch, dass in diesem

01:24:21.910 --> 01:24:23.730
Vektorraum alle Wörter irgendwie abgebildet sind,

01:24:23.810 --> 01:24:25.650
kann ich jetzt mathematische Operationen darauf abbilden

01:24:25.650 --> 01:24:27.810
und kann vor allem gucken, ob sich zwei

01:24:27.810 --> 01:24:29.910
Wörter ungefähr im selben Bereich dieses Vektorraums

01:24:29.910 --> 01:24:31.710
befinden

01:24:31.710 --> 01:24:33.670
und damit kriege ich sowas hin,

01:24:34.130 --> 01:24:35.670
wie das irgendwie Kirche und

01:24:35.670 --> 01:24:37.870
Kathedrale plötzlich irgendwie vergleichbar

01:24:37.870 --> 01:24:39.650
sind, obwohl die jetzt in einem normalen Text natürlich

01:24:39.650 --> 01:24:41.630
jetzt irgendwie nichts gemein haben, das sind komplett unterschiedliche

01:24:41.630 --> 01:24:43.670
Wörter, auch wenn sie halt eine ähnliche

01:24:43.670 --> 01:24:45.130
inhaltliche Bedeutung haben

01:24:45.130 --> 01:24:47.430
und das ist halt was, was halt eben mit

01:24:47.430 --> 01:24:48.930
Wörter-Empendings vor irgendwie

01:24:48.930 --> 01:24:50.750
drei, vier, fünf Jahren irgendwie

01:24:50.750 --> 01:24:52.910
sehr, sehr populär wurde und

01:24:52.910 --> 01:24:55.390
ja, inzwischen überall... Wie kommen die da an die gleiche

01:24:55.390 --> 01:24:56.950
Stelle in diesem Vektorraum? Das habe ich jetzt noch nicht ganz...

01:24:56.950 --> 01:24:58.610
Ja, das ist ein relativ kompliziertes Verfahren.

01:24:59.230 --> 01:25:00.990
Ich muss da halt vorher quasi

01:25:00.990 --> 01:25:03.270
trainieren und was ich vom Prinzip her mache, ist so eine Art

01:25:03.270 --> 01:25:04.610
Color-Vertical-Filtering, glaube ich.

01:25:05.250 --> 01:25:07.150
Aber ich glaube, das würde an der Stelle jetzt

01:25:07.150 --> 01:25:09.110
zu weit führen. Also die würde man jetzt an der Stelle auch

01:25:09.110 --> 01:25:10.990
vor allem nicht selber trainieren. Wenn, würdest du

01:25:10.990 --> 01:25:12.470
die einfach laden aus dem Internet

01:25:12.470 --> 01:25:15.050
und die quasi dann für jedes

01:25:15.050 --> 01:25:16.850
der Wörter, die ich habe, quasi nachgucken, okay,

01:25:16.950 --> 01:25:18.530
was ist denn diese Dimensionalität?

01:25:18.910 --> 01:25:20.890
Weil um so ein Word-Embedding wirklich selber zu

01:25:20.890 --> 01:25:22.790
trainieren, dann brauchst du zum einen sehr, sehr viele

01:25:22.790 --> 01:25:24.790
Trainingsdaten und zum anderen halt auch wirklich viel

01:25:24.790 --> 01:25:26.870
Rechenleistung für eine ganze Weile. Wo

01:25:26.870 --> 01:25:28.350
würde ich solche Modelle runterladen?

01:25:28.650 --> 01:25:30.810
Ja, es gibt zum Beispiel Word2Vec, das Modell von

01:25:30.810 --> 01:25:32.970
Google, das kann man halt benutzen.

01:25:33.730 --> 01:25:34.190
Das ist nett.

01:25:34.750 --> 01:25:35.250
Ja, genau.

01:25:36.150 --> 01:25:38.750
Ja, und es hängt aber dann,

01:25:39.070 --> 01:25:40.650
ist halt die Frage, worauf das dann trainiert ist.

01:25:40.790 --> 01:25:42.450
Also wahrscheinlich ist viel Wikipedia dabei, aber

01:25:42.450 --> 01:25:44.210
bei Google ist bestimmt auch noch

01:25:44.210 --> 01:25:46.490
diverse Webseiten mit drunter.

01:25:46.950 --> 01:25:51.790
Ja, und das sind halt so ein paar Gigabyte,

01:25:51.870 --> 01:25:52.970
die man dann so runterladen kann.

01:25:54.010 --> 01:25:56.290
Und das verbessert halt,

01:25:56.350 --> 01:25:59.830
wenn man jetzt eben statt TF-IDF,

01:25:59.950 --> 01:26:01.410
oder normalerweise würde man nicht sagen statt,

01:26:01.530 --> 01:26:03.490
sondern man nimmt die TF-IDF-Scores

01:26:03.490 --> 01:26:05.230
natürlich auch mit dazu als Features

01:26:05.230 --> 01:26:08.590
und nimmt dann aber auch die Vektoren

01:26:08.590 --> 01:26:10.830
aus den Word-Embeddings für jedes Wort mit dazu,

01:26:12.610 --> 01:26:14.450
dann verbessert das halt irgendwie

01:26:14.450 --> 01:26:16.690
so ein Klassifikationsergebnis schon deutlich.

01:26:16.950 --> 01:26:19.070
Also, aber

01:26:19.070 --> 01:26:21.030
da hat man halt auch das Problem, man weiß halt

01:26:21.030 --> 01:26:22.910
dann nicht, wenn man das jetzt einfach so, diese vortrainierten

01:26:22.910 --> 01:26:23.690
Geschichten benutzt.

01:26:25.090 --> 01:26:27.090
Ja, aber das ist ja schon wieder, das Nussen der Schwarmintelligenz,

01:26:27.170 --> 01:26:28.910
das ist ja keine eigene Entwicklung in dem Sinne, sondern

01:26:28.910 --> 01:26:31.090
man nutzt halt das, was irgendwie einer der Großen

01:26:31.090 --> 01:26:32.930
dann schon angestellt hat mit seiner Hardware,

01:26:33.510 --> 01:26:35.110
auf so einer ganzen Sprache, auf so einer ganzen

01:26:35.110 --> 01:26:37.230
Grammatik und das Knowledge, das man dann irgendwie

01:26:37.230 --> 01:26:38.990
Sagen wir mal so, wenn du genug Trainingsdaten hättest

01:26:38.990 --> 01:26:40.890
und auch genug

01:26:40.890 --> 01:26:42.790
Rechenkraft, um das dann halt alles auszurechnen, wäre es

01:26:42.790 --> 01:26:44.650
wahrscheinlich besser, wenn du das auf deine eigenen Daten machst

01:26:44.650 --> 01:26:46.910
und nicht die auf Wikipedia trainiert

01:26:46.910 --> 01:26:48.630
nimmst. Wie viel, also hast du gesagt,

01:26:48.690 --> 01:26:50.670
es waren bei der Reuters-Daten drin 20.000 irgendwie

01:26:50.670 --> 01:26:52.650
Datensätze und das heißt, das war nicht historisch, weil

01:26:52.650 --> 01:26:53.630
da sind sicher mehr.

01:26:56.710 --> 01:26:58.610
Das ist ein bestimmter

01:26:58.610 --> 01:27:00.490
Ausschnitt. Ich weiß nicht genau, nach welchen Kriterien

01:27:00.490 --> 01:27:02.470
die jetzt ausgewählt worden sind, aber es sind ein paar

01:27:02.470 --> 01:27:04.590
halt nur. Es gibt jetzt auch ein neueres Dataset

01:27:04.590 --> 01:27:06.550
RCV1 und das heißt irgendwie, da sind dann

01:27:06.550 --> 01:27:07.710
800.000 drin oder so.

01:27:09.510 --> 01:27:09.690
Ja.

01:27:10.930 --> 01:27:12.750
Genau, aber wie gesagt, an der Stelle

01:27:12.750 --> 01:27:15.170
würde man halt in der Stelle jetzt eigentlich

01:27:15.170 --> 01:27:16.750
erstmal diesen Back-of-Words-Ansatz

01:27:16.750 --> 01:27:19.190
wählen oder halt vielleicht auch mit

01:27:19.190 --> 01:27:20.830
Wörter-Embeddings, aber

01:27:20.830 --> 01:27:23.030
genau, wir waren ja so ein bisschen

01:27:23.030 --> 01:27:25.510
stehen geblieben bei den Label-Binarizern

01:27:25.510 --> 01:27:27.190
und ich finde, man sollte

01:27:27.190 --> 01:27:29.230
da nochmal so dieses Interface ein bisschen beschreiben,

01:27:29.290 --> 01:27:31.190
was wir benutzen, weil das ist

01:27:31.190 --> 01:27:32.950
sowas ganz generisch, was sich auch inzwischen alle

01:27:32.950 --> 01:27:34.830
möglichen Bibliotheken auch außerhalb von

01:27:34.830 --> 01:27:36.450
Circuit Learn eigentlich abgeschaut haben.

01:27:36.870 --> 01:27:39.250
Da gibt es halt immer im Wesentlichen zwei Operationen.

01:27:39.590 --> 01:27:40.730
Es gibt eben Fit

01:27:40.730 --> 01:27:41.730
und Transform.

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

01:28:03.330 --> 01:28:12.930
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.290 --> 01:28:23.690
Und der nimmt dann quasi diese selbe Abbildungsmatrix von Wörtern zu Zahlen und überträgt die auf den neuen Text.

01:28:24.510 --> 01:28:29.250
Und ich kann natürlich auch beides gleichzeitig anwenden, dann mache ich halt eben so wie in dem Notebook hier Fit-Transform.

01:28:30.050 --> 01:28:33.290
Dann fittet er erst darauf und dann transformiert er auch gleich die Eingangsdaten.

01:28:33.330 --> 01:28:53.730
Genau. Ja, das ist jetzt halt inzwischen echt so ein super Standard-Interface geworden und das Schöne ist halt, dass ich im Grunde jedes Modell, wenn ich jetzt eine Klasse habe in Python, die diese Methoden implementiert, ich brauche vielleicht noch ein bisschen mehr, muss man nochmal gucken,

01:28:53.730 --> 01:29:01.630
aber kann ich die halt auch in allen, dazu kommen wir dann später auch nochmal, Pipelines und so verwenden.

01:29:02.850 --> 01:29:07.750
Und Modelle, die halt diese API implementieren, werden dadurch austauschbar.

01:29:07.850 --> 01:29:14.230
Das ist halt auch total toll, weil ich dann halt sozusagen einfach nur über eine Liste von Modellen gehen kann

01:29:14.230 --> 01:29:17.110
und dann werfe ich die da rein und gucke, ob hinterher was rauskommt.

01:29:17.190 --> 01:29:20.570
Und ich muss das halt nicht für jedes Modell irgendwie einzeln nochmal anpassen.

01:29:21.210 --> 01:29:27.550
Ja, genau. Was wollten wir machen? Wir wollten Texte vektorisieren.

01:29:27.570 --> 01:29:31.850
Ja, jetzt haben wir eigentlich unsere Zahlmatrix. Eigentlich sind wir jetzt bereit, um darauf Modelle langsam zu trainieren, oder?

01:29:32.170 --> 01:29:39.230
Genau, ich habe hier einen TF-EDF-Vectorizer sozusagen instanziiert, dann den gefittet auf den Trainingsdaten.

01:29:40.810 --> 01:29:47.590
Dem kann man auch noch alle möglichen Optionen mitgeben, was ich jetzt hier nicht getan habe, aber man kann eben noch sagen, wie er trainieren soll.

01:29:48.390 --> 01:29:51.190
Ein gewisses Top-Wörter-Rauswerfen, was man auf jeden Fall machen würde, aber ja.

01:29:51.190 --> 01:30:00.830
Ja, genau. Aber halt irgendwie, dass man irgendwie smoothen soll oder man kann, welche Norm, man kann alles Mögliche da angeben.

01:30:02.470 --> 01:30:16.290
Und genau, den habe ich im Trainingsdaten gefüttert und ich benutze jetzt die Transform-Methode, um damit sozusagen die Texte aus den Trainingsdaten und aus den Testdaten in so Feature-Matrizen zu verwandeln.

01:30:17.970 --> 01:30:21.550
Das sind dann hinterher

01:30:21.550 --> 01:30:26.250
das ist auch nochmal so eine kleine Spezialität.

01:30:29.190 --> 01:30:29.810
Das ist jetzt natürlich

01:30:29.810 --> 01:30:32.190
das, was dabei rauskommt, hat relativ

01:30:32.190 --> 01:30:36.130
die Matrix, die da rauskommt. Normalerweise würde man jetzt denken, da kommt einfach nur ein NumPy

01:30:36.130 --> 01:30:39.930
Array raus, irgendwie Zahlen so viel wie es Dokumente gibt,

01:30:40.650 --> 01:30:44.450
Spalten so viele wie es Wörter gibt. Das Problem dabei ist natürlich so ein bisschen

01:30:44.450 --> 01:30:47.290
die allermeisten

01:30:47.290 --> 01:30:49.070
Werte in dieser Tabelle sind null, weil

01:30:49.070 --> 01:30:50.830
ja die allermeisten Worte halt nicht

01:30:50.830 --> 01:30:53.010
in allen Texten vorkommen, sondern

01:30:53.010 --> 01:30:54.830
ja,

01:30:55.590 --> 01:30:55.850
also

01:30:55.850 --> 01:30:58.910
pro Text habe ich halt eine Teilmenge der Worte, die

01:30:58.910 --> 01:31:00.670
überhaupt vorkommen, aber eben nicht alle

01:31:00.670 --> 01:31:03.030
und die allermeisten kommen halt

01:31:03.030 --> 01:31:03.750
nicht in den Text vor.

01:31:04.030 --> 01:31:06.490
Je mehr Nullen, je mehr Texte man hat?

01:31:07.050 --> 01:31:08.950
Ja. Je mehr unterschiedliche Wörter

01:31:08.950 --> 01:31:10.570
man hat. Ja, genau, richtig.

01:31:11.050 --> 01:31:12.990
Ja, genau, es ist ja dann mehr wahrscheinlicher, dass du mehr Texte hast,

01:31:13.050 --> 01:31:14.010
dass du mehr unterschiedliche Wörter hast.

01:31:14.450 --> 01:31:24.770
Ja, wobei, also genau, wenn ich dann Texte habe, die alle sehr, sehr ähnlich sind, habe ich dann natürlich auch viele Einser vom Prinzip her. Das heißt einfach quasi wie sparse ist meine Matrix das Wort dafür.

01:31:24.770 --> 01:31:26.370
Genau, sparse.

01:31:27.390 --> 01:31:29.110
Die Daten sind halt sehr sparse

01:31:29.110 --> 01:31:30.830
und das ist halt

01:31:30.830 --> 01:31:32.890
ein Problem oder

01:31:32.890 --> 01:31:35.050
ist halt sehr verschwenderisch, was Hauptsprecher angeht,

01:31:35.110 --> 01:31:36.650
wenn man tatsächlich die Werte speichern würde.

01:31:37.390 --> 01:31:38.290
Und es gibt dann so

01:31:38.290 --> 01:31:40.670
aus dem SciPy

01:31:40.670 --> 01:31:42.550
Modul

01:31:42.550 --> 01:31:44.850
irgendwie gibt es dann Klassen, die sich halt

01:31:44.850 --> 01:31:46.590
mit sparse, mit dem

01:31:46.590 --> 01:31:48.810
Speichern von sparsen Matrizen irgendwie

01:31:48.810 --> 01:31:49.310
beschäftigen.

01:31:51.450 --> 01:31:51.950
Und

01:31:51.950 --> 01:31:54.490
ja, da

01:31:54.490 --> 01:31:56.890
der Trick ist im Grunde, dass man halt die ganzen Nullen

01:31:56.890 --> 01:31:58.310
einfach nicht speichert. Was man sagt,

01:31:58.610 --> 01:32:00.830
man speichert nur, an welchen

01:32:00.830 --> 01:32:02.830
Stellen irgendwie Zahlen sind. Alles andere

01:32:02.830 --> 01:32:03.490
ist halt

01:32:03.490 --> 01:32:06.650
defaultmäßig null und muss man halt auch nicht speichern.

01:32:07.430 --> 01:32:08.690
Und man kann sich das auch im Grunde so

01:32:08.690 --> 01:32:10.490
vorstellen, also die interessante Operation,

01:32:10.750 --> 01:32:12.670
die man jetzt auf sowas ausführt, zum Beispiel wenn man jetzt

01:32:12.670 --> 01:32:14.510
eine Suchmaschine hat, würde man irgendwie

01:32:14.510 --> 01:32:16.150
eine Cosinus-Distanz

01:32:16.150 --> 01:32:18.890
ausrechnen zwischen einem Dokument

01:32:18.890 --> 01:32:19.490
und einer Query.

01:32:20.390 --> 01:32:22.670
Das heißt sozusagen einfach nur das Scalar-Produkt.

01:32:22.730 --> 01:32:24.810
man würde den Query in Vektor verwandeln,

01:32:25.770 --> 01:32:26.450
ein Dokument

01:32:26.450 --> 01:32:28.790
in Vektor verwandeln und dann bildet man

01:32:28.790 --> 01:32:30.110
einfach das Skalarprodukt zwischen den beiden

01:32:30.110 --> 01:32:32.870
und dafür muss man ja sozusagen nur

01:32:32.870 --> 01:32:34.750
die Teile miteinander multiplizieren,

01:32:34.850 --> 01:32:36.870
die nicht Null sind, weil

01:32:36.870 --> 01:32:38.550
die anderen sind alle EU-Null,

01:32:38.710 --> 01:32:40.450
das wird aufsummiert, also

01:32:40.450 --> 01:32:42.830
es ist einfach weg und

01:32:42.830 --> 01:32:44.790
daher ist das natürlich toll, wenn man eine Struktur

01:32:44.790 --> 01:32:46.950
hat, wo sowieso nur die Teile gespeichert

01:32:46.950 --> 01:32:48.370
sind, die nicht Null sind und dann

01:32:48.370 --> 01:32:50.830
muss man nicht so viel speichern und

01:32:50.830 --> 01:32:53.370
hat trotzdem alles, was man braucht,

01:32:53.470 --> 01:32:54.750
um halt damit rechnen zu können.

01:32:56.310 --> 01:32:56.970
Ja, das

01:32:56.970 --> 01:32:58.990
funktioniert auch

01:32:58.990 --> 01:33:01.170
tatsächlich irgendwie als Eingabe

01:33:01.170 --> 01:33:03.250
für diverse Modelle, aber halt

01:33:03.250 --> 01:33:05.090
auch nicht für alle. Also da muss man dann halt auch wieder

01:33:05.090 --> 01:33:07.210
aufpassen, das ist so ein bisschen blöd. Also es gibt

01:33:07.210 --> 01:33:09.070
halt Modelle, die gut damit klarkommen, wenn man

01:33:09.070 --> 01:33:11.130
den Feature-Matrizen

01:33:11.130 --> 01:33:11.970
gibt, die sparse sind.

01:33:13.370 --> 01:33:15.010
Es gibt auch welche, bei denen das nicht geht.

01:33:15.170 --> 01:33:17.130
Und da muss man halt unter Bestimmten auch nochmal ein bisschen was

01:33:17.130 --> 01:33:19.250
machen, was man

01:33:19.250 --> 01:33:21.230
üblicherweise tun würde, also was ein Modell,

01:33:21.370 --> 01:33:23.230
was immer gut funktioniert, was man

01:33:23.230 --> 01:33:25.030
normalerweise immer braucht, aber was halt nicht

01:33:25.030 --> 01:33:27.310
klarkommt mit sparsen Daten, wäre halt sowas wie

01:33:27.310 --> 01:33:29.250
XGBoost zum Beispiel,

01:33:29.530 --> 01:33:31.130
so ein

01:33:31.130 --> 01:33:33.050
Decision Tree Modell.

01:33:34.210 --> 01:33:34.690
XGBoost?

01:33:35.610 --> 01:33:36.950
XGBoost, für Extreme

01:33:36.950 --> 01:33:38.690
Gradient Boosting.

01:33:38.690 --> 01:33:39.250
Ah, okay.

01:33:42.350 --> 01:33:42.750
Und

01:33:42.750 --> 01:33:44.610
da

01:33:44.610 --> 01:33:46.570
macht man das eigentlich, oder

01:33:46.570 --> 01:33:48.430
für alle, ich meine auch, was auch nicht mit

01:33:48.430 --> 01:33:50.490
Neuronalen Netze kommen auch normalerweise nicht mit Spasen

01:33:50.490 --> 01:33:51.390
Eingaben klar.

01:33:52.190 --> 01:33:54.610
Was man da vorher macht, ist, man reduziert

01:33:54.610 --> 01:33:56.610
die Dimensionen. Also wenn

01:33:56.610 --> 01:33:58.030
das, ich weiß jetzt nicht, was das,

01:33:58.450 --> 01:34:00.510
was ich glaube auch irgendwas, 25.000 Wörter gibt es da drin

01:34:00.510 --> 01:34:00.910
oder so.

01:34:02.310 --> 01:34:04.690
Wenn man jetzt aus diesen 25.000 Dimensionen

01:34:04.690 --> 01:34:06.510
etwas machen möchte, was

01:34:06.510 --> 01:34:08.370
dense, was dicht ist, dann

01:34:08.370 --> 01:34:10.530
projiziert man halt das aus dem

01:34:10.530 --> 01:34:12.770
aus diesem hochdimensionalen

01:34:12.770 --> 01:34:14.670
Vektorraum halt runter auf irgendwas

01:34:14.670 --> 01:34:16.310
mit 200 Dimensionen oder 300 oder so.

01:34:17.210 --> 01:34:19.250
Und dafür gibt es dann unterschiedliche Verfahren, aber das, was man

01:34:19.250 --> 01:34:21.530
normalerweise immer verwendet, ist Singular Value

01:34:21.530 --> 01:34:23.150
Decomposition

01:34:23.150 --> 01:34:25.150
und dann auch die Truncated-Variante

01:34:25.150 --> 01:34:27.270
davon, also Truncated Singular Value

01:34:27.270 --> 01:34:29.230
Decomposition. Das ist halt immer so das Ding,

01:34:29.270 --> 01:34:31.210
was man dann nutzt und projiziert, um

01:34:31.210 --> 01:34:32.250
die Sachen runter zu projizieren.

01:34:32.810 --> 01:34:35.070
Es muss einem halt irgendwie mal klar sein, wenn man halt so einen

01:34:35.070 --> 01:34:36.770
Korpus hat und dann hat man jetzt in

01:34:36.770 --> 01:34:38.350
seinen Daten irgendwie

01:34:38.350 --> 01:34:40.950
eine Million Dokumente und

01:34:40.950 --> 01:34:42.830
diese Millionen Dokumente haben halt irgendwie

01:34:42.830 --> 01:34:45.130
30.000 unterschiedliche

01:34:45.130 --> 01:34:46.990
Wörter, dann habe ich halt nachher prinzipiell

01:34:46.990 --> 01:34:49.270
erstmal eine Matrix, wenn ich jetzt nichts davon wegwerfe

01:34:49.270 --> 01:34:50.790
oder so, von

01:34:50.790 --> 01:34:52.270
1.000.000 mal 30.000

01:34:52.270 --> 01:34:55.170
und das kann natürlich dann beliebig

01:34:55.170 --> 01:34:57.030
mit größeren Datensätzen noch größer

01:34:57.030 --> 01:34:58.890
werden und der Gedanke

01:34:58.890 --> 01:35:00.850
an der Stelle ist einfach, mit

01:35:00.850 --> 01:35:02.410
so einer Dimensionalitätsreduktion

01:35:02.410 --> 01:35:04.450
verliere ich theoretisch Informationen,

01:35:05.430 --> 01:35:05.870
aber

01:35:05.870 --> 01:35:08.790
es gibt halt viele Dimensionen

01:35:08.790 --> 01:35:10.650
oder viele dieser Spalten, die sich sehr, sehr ähnlich

01:35:10.650 --> 01:35:11.690
verhalten werden. Also

01:35:11.690 --> 01:35:14.730
der Optimalfall für eine

01:35:14.730 --> 01:35:16.730
Dimensionalitätsreduktion ist, dass zwei

01:35:16.730 --> 01:35:18.670
Spalten oder zwei Zahlen

01:35:18.670 --> 01:35:20.470
quasi komplett gleich sind,

01:35:21.050 --> 01:35:22.410
weil dann verliere ich quasi keine

01:35:22.410 --> 01:35:24.470
Informationen darüber, wenn ich einfach sage, dass

01:35:24.470 --> 01:35:26.470
diese beiden Spalten, wenn ich

01:35:26.470 --> 01:35:27.590
die beiden quasi zusammenlege.

01:35:28.850 --> 01:35:30.170
Und wenn zwei

01:35:30.170 --> 01:35:32.590
Spalten sehr, sehr stark korreliert

01:35:32.590 --> 01:35:34.310
sind, dann

01:35:34.310 --> 01:35:36.490
verliere ich auch nicht viele Informationen in dem Moment,

01:35:36.590 --> 01:35:38.590
wo ich die beiden irgendwie zusammen auf 1 abbilde.

01:35:38.690 --> 01:35:40.450
Also die, wenn die Spalten ja Wörter

01:35:40.450 --> 01:35:42.350
sind, dann ist ja gleiche Wörter relativ

01:35:42.350 --> 01:35:44.010
unwahrscheinlich, aber dann muss man tatsächlich diese

01:35:44.010 --> 01:35:45.850
Kombination finden aus der Grammatik, die

01:35:45.850 --> 01:35:48.050
wir eben hatten, halt das Modul laden dann, was war das?

01:35:48.330 --> 01:35:50.130
Word Conf, irgendwas

01:35:50.130 --> 01:35:51.990
von Google. Achso,

01:35:52.130 --> 01:35:53.390
WordSpec, aber. WordSpec, genau.

01:35:54.150 --> 01:35:56.010
Das könnte man ja nehmen als Information, um irgendwie

01:35:56.010 --> 01:35:57.890
so eine Kovarianz in den Wörtern festzustellen

01:35:57.890 --> 01:35:59.950
und die halt dann so zu gruppieren, dass

01:35:59.950 --> 01:36:01.990
die halt dann zusammenfassen. Theoretisch kann es aber

01:36:01.990 --> 01:36:03.850
auch vorher der Fall sein. Also mal angenommen, ich habe

01:36:03.850 --> 01:36:05.910
zum Beispiel einen Namen drin, mit einem Vornamen

01:36:05.910 --> 01:36:08.070
und einem Nachnamen und der kommt halt tatsächlich nur in einem

01:36:08.070 --> 01:36:10.170
der Texte vor. Dann habe ich da

01:36:10.170 --> 01:36:12.110
natürlich zwei Spalten für.

01:36:12.930 --> 01:36:14.030
Einmal der Vorname, einmal der

01:36:14.030 --> 01:36:16.230
Nachnamen und die haben genau einmal eine 1 für ein Dokument,

01:36:17.030 --> 01:36:18.130
dann sind

01:36:18.130 --> 01:36:20.450
diese beiden Spalten natürlich perfekt korreliert.

01:36:20.690 --> 01:36:22.230
Und dann können die natürlich auch beliebig

01:36:22.230 --> 01:36:24.090
von der Dimensionalität

01:36:24.090 --> 01:36:26.290
auf einer projiziert werden.

01:36:27.250 --> 01:36:28.490
Also würde man da nur einen von beiden

01:36:28.490 --> 01:36:30.150
wegschmeißen oder sagt man einfach, ja, das ist eigentlich nur

01:36:30.150 --> 01:36:31.210
in einem Dokument, ist eigentlich egal?

01:36:31.610 --> 01:36:34.290
Letztendlich machst du das selber gar nicht, sondern der Algorithmus

01:36:34.290 --> 01:36:36.090
überlegt sich einfach selbstständig, wo

01:36:36.090 --> 01:36:38.250
verliere ich am wenigsten Informationen, indem ich die

01:36:38.250 --> 01:36:40.050
runtergebe und was ich von außen nur sage, ist

01:36:40.050 --> 01:36:42.550
auf welche Zieldimension will ich gerne?

01:36:42.690 --> 01:36:44.330
Also dass da einfach 300 reicht.

01:36:44.610 --> 01:36:46.710
Genau. Und der projiziert es für dich runter,

01:36:46.810 --> 01:36:48.030
aber das ist die Logik, die dahinter steht.

01:36:50.410 --> 01:36:50.810
Genau.

01:36:51.010 --> 01:36:52.090
Und dabei geht praktisch

01:36:52.090 --> 01:36:54.410
nur sehr wenig Information verloren.

01:36:54.510 --> 01:36:55.610
Das funktioniert halt ziemlich gut.

01:36:56.930 --> 01:36:57.330
Genau.

01:36:58.450 --> 01:37:00.350
Also das ist halt auch so. Aber das ist halt irgendwie

01:37:00.350 --> 01:37:02.250
dann doch so eine Geschichte, wo man

01:37:02.250 --> 01:37:04.170
nicht immer irgendwie alles gleich

01:37:04.170 --> 01:37:06.250
verwenden kann. Weil es gibt halt Modelle, die kommen halt

01:37:06.250 --> 01:37:07.590
mit Spasen-Daten klar und manche halt nicht.

01:37:09.850 --> 01:37:10.110
Ja.

01:37:11.130 --> 01:37:12.090
Genau, genau, genau.

01:37:12.490 --> 01:37:13.910
Gut, aber jetzt wollen wir mal ein Modell trainieren.

01:37:13.930 --> 01:37:16.250
Ja, ein Modell trainieren, genau. Dafür gibt es dann halt auch

01:37:16.250 --> 01:37:17.330
irgendwie einmal

01:37:17.330 --> 01:37:19.830
eine Abstraktionsgeschichte, um halt dieses

01:37:19.830 --> 01:37:21.110
Multilevel-Ding

01:37:21.980 --> 01:37:25.140
Es gibt einige Modelle, die automatisch Multiclass können,

01:37:25.380 --> 01:37:29.580
aber Multilabel, da braucht man halt noch so einen Wrapper außenrum.

01:37:30.760 --> 01:37:34.320
Und eine einfache Art, wie man halt sozusagen aus einem Modell,

01:37:34.440 --> 01:37:36.760
also was alle Modelle können, ist halt binäre Klassifikation.

01:37:36.860 --> 01:37:37.780
Das ist halt auch das Einfachste.

01:37:38.520 --> 01:37:40.820
Und man kann jetzt natürlich aus binärer Klassifikation

01:37:40.820 --> 01:37:43.680
quasi automatisch eine Multilabel-Klassifikation machen,

01:37:43.680 --> 01:37:48.900
indem man einfach für jede Klasse eins gegen alle anderen ein Modell trainiert,

01:37:49.000 --> 01:37:50.380
was dann binäre Klassifikation macht.

01:37:51.980 --> 01:38:10.120
Und dann, das muss man aber auch nicht selber machen, sondern da gibt es dann halt schon ein vorgefertigtes Ding aus Scikit-Learn Multiclass, das Ding heißt One Versus REST Classifier und der tut das dann und man kriegt das gar nicht mit, sondern steckt einfach nur das eigene Modell, was man verwenden möchte, da rein und dann passiert das automatisch.

01:38:10.500 --> 01:38:26.940
Und dann gibt es halt noch aus dem Scikit-Learns-Metrics-Modul eine Classification-Report-Funktion, die einem dann so eine ganz schöne Übersicht gibt, was dann jetzt passiert ist mit den Testdaten, wenn man die dann nochmal durch das trainierte Modell durchgibt.

01:38:28.700 --> 01:38:44.480
Und ja, so eines der ersten Modelle, die man immer so ausprobieren würde, denke ich mal, ist so Logistic Regression. Das ist ein Klassifikationsmodell. Das heißt bloß Regression, das ist nicht so.

01:38:45.420 --> 01:39:02.680
Ja, das ist auch total, habe ich am Anfang auch lange Zeit verwirrt, dass eine Methode, die Regression im Namen hat, in Wirklichkeit eine Klassifikation ist, aber das ist halt der Algorithmus, der im Endeffekt dahinter steht, da sollte man nicht zu tief drauf reingehen.

01:39:02.680 --> 01:39:03.400
Genau, genau.

01:39:04.340 --> 01:39:05.980
Und das ist halt so ein Standardding.

01:39:06.060 --> 01:39:07.620
Das ist immer etwas, was man immer am Anfang verwendet,

01:39:07.700 --> 01:39:09.340
weil das ist halt, funktioniert auf

01:39:09.340 --> 01:39:11.800
vielen Sachen ganz gut. Es ist sehr schnell.

01:39:13.540 --> 01:39:13.940
Ja.

01:39:15.060 --> 01:39:15.460
Daher

01:39:15.460 --> 01:39:18.000
man kann gut verstehen, was es macht.

01:39:20.060 --> 01:39:20.460
Daher

01:39:20.460 --> 01:39:22.060
man würde gar nicht mit so totalen

01:39:22.060 --> 01:39:23.880
Fancy-Verfahren anfangen, sondern

01:39:23.880 --> 01:39:25.940
eher so mit simplen und dann erstmal gucken, was da überhaupt

01:39:25.940 --> 01:39:27.920
passiert. Und dann kann man ja immer

01:39:27.920 --> 01:39:29.820
noch kompliziertere Dinge machen, wenn das halt nicht reicht.

01:39:31.720 --> 01:39:31.900
Ja.

01:39:32.680 --> 01:39:56.840
Genau, Model ist jetzt sozusagen einfach nur Run-versus-Rest-Classifier und da das Logistic Regression-Modell reingesteckt und dann einmal Fit auf, um das Modell zu trainieren und dann einmal Predict, um die Voraussagen zu bekommen für die Testdokumente.

01:39:57.160 --> 01:40:26.040
Ich finde, das ist ein sehr gutes Beispiel für, wie so ein echtes Welt-Data-Science-Projekt aussieht, weil wenn man jetzt irgendwie sagt, also wenn man von außen dann naiv drauf schaut und denkt sich so, so schwer kann es doch nicht sein, du machst irgendwie Hello World, irgendwie Regression oder Klassifikation, dann findest du halt einfach, irgendwo werden Daten vorgefertigt, richtig geladen und dann nimmst du dieses Modell, importierst es, machst ein Fit, machst ein Predict und hast dein Ergebnis.

01:40:26.340 --> 01:40:49.060
Also das eigentliche Modell trainieren ist kein Problem, aber wir reden jetzt hier schon eine Stunde, eine halbe oder so darüber, wie wir da hinkommen und das ist die Schwierigkeit bei dem Ganzen, dass es halt in Wirklichkeit dann doch nicht so trivial ist, dass man halt eben irgendwie Multiclass oder Multilabel hat oder sehr große Matrizen oder Dimensionalitäten reduzieren muss und Features ingenieren und genau, dieser Weg dahin ist das Komplizierte.

01:40:50.360 --> 01:40:57.880
Ja, und dann haben wir aber jetzt eine Prognose raus und müssen uns überlegen, wie gehen wir mit der um, wo es auch wieder anfängt komplizierter zu werden.

01:40:58.500 --> 01:41:19.720
Genau, es wäre wahrscheinlich ein bisschen unübersichtlich beim Classification Report das halt über alle 90 Kategorien zu machen, deswegen habe ich jetzt einfach mal die Top 10 Kategorien genommen. Das ist auch so, wenn man sich dafür interessiert, gibt es halt die Doktorarbeit von Thorsten Joachim, die ist glaube ich eines der meist zitierten Papers sozusagen im Textklassifikationsbereich, irgendwie ist es anderthalb tausend Mal zitiert worden oder so.

01:41:20.360 --> 01:41:30.640
Der hat sich damit zuerst 1998 irgendwie beschäftigt und das Ding gibt es als Buch oder man kann halt irgendwie zu so einer Schattenbibliothek gehen, da gibt es das auch.

01:41:31.580 --> 01:41:47.360
Und da kann man sich halt auch, da guckt man sich auch mal die Top 10 Kategorien an und kann das einfach mal vergleichen, die Zahlen, die er da rauskriegt mit dem, was man da selber irgendwie dann sozusagen da als Ergebnis hat und ja, sieht eigentlich alles ganz gut aus.

01:41:48.700 --> 01:42:02.700
Genau, was man da in Spalten in dem Klassifikationsreport drinstehen hat, sind halt einmal die Namen der Kategorien, dann Precision, Recall, F1-Score und ja, wie viele Beispiele es gab.

01:42:05.020 --> 01:42:07.800
Genau, und das ist was, womit man den Umgang auf jeden Fall wirklich lernen muss.

01:42:07.940 --> 01:42:12.240
Da hat mich ganz am Anfang, als ich angefangen habe mit Data Science, konnte ich mit den ganzen Zahlen auch nicht wirklich was anfangen.

01:42:13.780 --> 01:42:19.220
Was man ja immer im Wesentlichen hat, ist, man hat prinzipiell vier Fälle.

01:42:19.940 --> 01:42:25.800
Ich kann einfach, bei einer binären Klassifikation, was so das Einfachste ist,

01:42:26.220 --> 01:42:29.180
da kann es sein, dass ein Ergebnis quasi wahr ist.

01:42:29.620 --> 01:42:32.520
Und ich habe auch gesagt, dass es wahr ist, das ist das Einfachste.

01:42:32.600 --> 01:42:34.120
Dann habe ich ein True Positive.

01:42:35.200 --> 01:42:37.540
Es kann auch sein, dass es falsch ist.

01:42:37.900 --> 01:42:40.380
Und ich habe aber gesagt, dass es wahr ist.

01:42:40.380 --> 01:42:43.880
Dann habe ich ein false positive.

01:42:45.660 --> 01:42:49.340
Ich kann sein, dass ich richtig gelegen habe

01:42:49.340 --> 01:42:50.600
und es negativ ist.

01:42:50.920 --> 01:42:52.040
Dann habe ich ein true negative.

01:42:52.860 --> 01:42:54.260
Oder es kann negativ sein

01:42:54.260 --> 01:42:55.880
und ich lag auch noch daneben.

01:42:56.060 --> 01:42:57.680
Dann habe ich ein false negative.

01:42:58.580 --> 01:43:02.140
So, und jetzt gibt es quasi Kombinationen

01:43:02.140 --> 01:43:04.480
von diesen Feldern für Precision und Recall.

01:43:04.480 --> 01:43:07.200
Und die inhaltliche Bedeutung davon ist vom Prinzip,

01:43:07.340 --> 01:43:08.620
also man kann sich das auch in den Formeln anschauen,

01:43:08.700 --> 01:43:09.660
ich finde das hilft aber weniger,

01:43:10.120 --> 01:43:16.040
als einfach zu sagen, die Precision ist, wie viele von meinen Daten,

01:43:16.040 --> 01:43:18.620
wo ich gesagt habe, dass sie wahr sind, sind auch wirklich wahr.

01:43:19.560 --> 01:43:23.740
Und Recall ist, wie viele von denen, die prinzipiell wahr sind,

01:43:23.860 --> 01:43:27.680
die ich quasi prognostizieren wollte, habe ich denn auch erwischt.

01:43:28.900 --> 01:43:29.800
Das sind so die beiden.

01:43:30.380 --> 01:43:32.060
Und dazwischen habe ich so einen Trade-off.

01:43:32.460 --> 01:43:34.240
Und da muss ich halt abwägen.

01:43:34.380 --> 01:43:36.320
Und das ist, was der F1-Score im Endeffekt macht.

01:43:36.800 --> 01:43:38.620
der tut nämlich einfach quasi

01:43:38.620 --> 01:43:40.200
die beiden so verrechnen,

01:43:40.540 --> 01:43:42.520
dass nachher ein Zahlenwert rauskommt

01:43:42.520 --> 01:43:44.520
zwischen 0 und 1 und wenn ich quasi die

01:43:44.520 --> 01:43:46.380
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.480
komplett falsch und der gibt so

01:43:52.480 --> 01:43:54.460
eine Art Bonus, durch das wie er

01:43:54.460 --> 01:43:56.560
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.460
da quasi die Precision auf 1 habe, aber den

01:44:00.460 --> 01:44:02.340
Recall bei 0, dann bin ich da nachher trotzdem

01:44:02.340 --> 01:44:02.800
bei einer 0.

01:44:04.940 --> 01:44:06.760
Das sind die drei wesentlichen

01:44:06.760 --> 01:44:08.760
Metriken dieses Reports und dann gibt es halt

01:44:08.760 --> 01:44:10.780
eben noch den Support, der einfach quasi

01:44:10.780 --> 01:44:12.700
aussagt, okay, wie häufig ist denn der Fall

01:44:12.700 --> 01:44:14.800
überhaupt, um mir so eine Absolut-Skala

01:44:14.800 --> 01:44:16.680
zu geben, weil diese Zahlenwerte sind jetzt

01:44:16.680 --> 01:44:18.680
natürlich alles relativ, wenn ich nur ein Beispiel

01:44:18.680 --> 01:44:20.620
habe und das habe ich richtig klassifiziert, dann

01:44:20.620 --> 01:44:22.740
habe ich einen F1-Score von 1 und alles ist super,

01:44:23.120 --> 01:44:24.740
aber wenn es halt nur ein Beispiel war, dann hilft

01:44:24.740 --> 01:44:26.460
mir das real im echten Leben natürlich wenig.

01:44:26.920 --> 01:44:28.640
Deswegen ist dieser F1-Score, äh, dieser

01:44:28.640 --> 01:44:30.620
Support dann so eine Matrix für, wie

01:44:30.620 --> 01:44:32.260
wichtig ist es denn in absoluten Zahlen.

01:44:33.320 --> 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.760 --> 01:44:39.060
also so F1-Core finde ich

01:44:39.060 --> 01:44:40.800
es mal, also man braucht das

01:44:40.800 --> 01:44:42.740
sowas in der Art häufig, wenn man jetzt

01:44:42.740 --> 01:44:44.800
zum Beispiel Modelle ranken möchte, man möchte

01:44:44.800 --> 01:44:46.760
jetzt das beste Modell haben, wo man jetzt Precision

01:44:46.760 --> 01:44:48.900
und Recall-Werte hat, dann ist es halt blöd, man kann halt nicht so

01:44:48.900 --> 01:44:50.860
richtig gut nach, wenn man jetzt 2-Werte

01:44:50.860 --> 01:44:52.380
hat, irgendwie, wie will man dann sortieren?

01:44:54.580 --> 01:44:54.900
Daher

01:44:54.900 --> 01:44:56.820
muss man das halt irgendwie

01:44:56.820 --> 01:44:57.400
in einen Wert

01:44:57.400 --> 01:45:00.680
zusammenfassen und dann nimmt man halt einen F1-Wert,

01:45:00.760 --> 01:45:02.400
man kann das auch irgendwie anders ausrechnen, aber

01:45:02.400 --> 01:45:04.780
das ist halt das, was meistens gemacht wird.

01:45:06.760 --> 01:45:31.580
Ja, und einer der Gründe, weshalb man da sowas überhaupt machen muss, man kann sich jetzt nicht einfach vorstellen, warum immer nicht einfach Accuracy oder so, ja, das geht halt nicht so gut, also Accuracy funktioniert halt dann gut, wenn alle Klassen irgendwie die gleiche Anzahl von Beispielen haben und so, dann geht das vielleicht, aber das wird auch schwer sich vorzustellen, wenn man jetzt irgendwie was anderes hat als nur zwei.

01:45:33.980 --> 01:45:53.120
Aber es hat auch sonst irgendwie blöde Eigenschaften. Also wenn man sich jetzt nochmal das Beispiel mit dem Spam und Nicht-Spam vorstellt. Also bei dir scheint das ja nicht so zu sein. Du kriegst ja auch nicht so viel Spam, aber bei mir mag das schon so mit dem, was andere Leute auch beobachten, übereinstimmen, dass halt 99% der Mails, die ich bekomme, sind halt Spam.

01:45:55.780 --> 01:45:57.720
was dann noch darunter fällt vielleicht.

01:45:58.340 --> 01:45:58.780
Ja.

01:46:00.080 --> 01:46:01.560
Also ich habe sozusagen eine sehr ungleiche

01:46:01.560 --> 01:46:02.320
Verteilung der

01:46:02.320 --> 01:46:05.620
der Klassen und wenn ich

01:46:05.620 --> 01:46:07.420
jetzt sozusagen Accuracy

01:46:07.420 --> 01:46:09.660
nehme als Maß oder als Metrik dafür,

01:46:09.780 --> 01:46:10.880
wie gut ist das jetzt,

01:46:11.460 --> 01:46:13.740
dann könnte ich jetzt einen Classifier bauen, der sagt

01:46:13.740 --> 01:46:15.160
irgendwie immer, es ist Spam.

01:46:16.140 --> 01:46:17.820
Und der hätte dann Accuracy von 99%.

01:46:17.820 --> 01:46:19.620
Klingt doch super, voll gut. Aber der macht

01:46:19.620 --> 01:46:21.560
ja eigentlich gar nichts oder macht auf jeden Fall

01:46:21.560 --> 01:46:23.660
nichts Sinnvolles, weil hinterher kriege ich

01:46:23.660 --> 01:46:25.220
halt gar keine Mail mehr und

01:46:25.220 --> 01:46:28.660
diese Irrtumswahrscheinlichkeit

01:46:28.660 --> 01:46:30.420
ist tatsächlich, glaube ich, relativ relevant, auch für den

01:46:30.420 --> 01:46:32.160
Untersuchungsgegenstand, den man hat. Ich weiß nicht, ob wir

01:46:32.160 --> 01:46:34.280
Alpha- oder Beta-Fehler nennt man das, glaube ich, so in der klassischen

01:46:34.280 --> 01:46:36.280
Statistik. Ja, oder viele Erste Ordnung

01:46:36.280 --> 01:46:37.660
oder Zweite Ordnung oder sowas.

01:46:38.040 --> 01:46:39.180
Und das ist ja schon

01:46:39.180 --> 01:46:42.100
sehr entscheidend, also was für Untersuchungsgegenstand

01:46:42.100 --> 01:46:43.880
man hat. Manchmal ist 5% Abweichung

01:46:43.880 --> 01:46:45.800
dann ganz okay, weil 95 Treffer Wahrscheinlichkeit ist

01:46:45.800 --> 01:46:47.620
ausreichend irgendwie. Vielleicht bei Hund, Katze

01:46:47.620 --> 01:46:49.660
unterscheiden, vielleicht auch nicht ganz so wichtig. Aber

01:46:49.660 --> 01:46:52.020
bei anderen Dingen ist halt dann das 1%,

01:46:52.020 --> 01:46:53.640
1% zu viel. Also gerade, wenn man so

01:46:53.640 --> 01:46:55.380
Häufigkeitsverteilung hat, wie es kommt nur

01:46:55.380 --> 01:46:57.360
ein Prozent der Fälle sowas raus

01:46:57.360 --> 01:46:59.540
und dann falsch liegt es vielleicht nicht so super.

01:46:59.820 --> 01:47:01.520
Ja, aber eben bei Accuracy würde man

01:47:01.520 --> 01:47:03.460
halt gar nicht sehen, dass man da ein riesen Problem hat, wenn man

01:47:03.460 --> 01:47:06.180
die 99 Prozent sieht.

01:47:06.980 --> 01:47:07.720
Aber vielleicht muss man dann

01:47:07.720 --> 01:47:09.480
einen negativen Fehler nehmen, dann muss man vielleicht nicht versuchen

01:47:09.480 --> 01:47:10.380
einen Spam zu tracken, sondern eine richtige Mail.

01:47:10.380 --> 01:47:12.180
Aber wenn man jetzt Precision Recall nehmen würde,

01:47:12.300 --> 01:47:14.180
würde man sagen, okay, dann sieht man es halt sofort, weil

01:47:14.180 --> 01:47:14.840
Precision wäre null.

01:47:16.400 --> 01:47:18.280
Andersrum ist halt tatsächlich dieses Ding,

01:47:18.360 --> 01:47:20.520
wenn du halt den Spam immer versuchst zu tracken

01:47:20.520 --> 01:47:22.160
und er sagt immer Spam, dann müsstest du halt

01:47:22.160 --> 01:47:24.240
das umdrehen, musst du sagen, hey, ich möchte richtigen Text tracken

01:47:24.240 --> 01:47:26.320
und dann hättest du halt vielleicht eine bessere Erkennungsrate

01:47:26.320 --> 01:47:28.180
oder so, ja, weil du das halt

01:47:28.180 --> 01:47:30.180
nicht wegschmeißen würdest durch die Fehlerwahrscheinlichkeit.

01:47:31.860 --> 01:47:32.040
Ja,

01:47:32.180 --> 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:40.320
Labels hat und unterschiedlich

01:47:40.320 --> 01:47:40.940
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:50.000
Accuracy. Daher nimmt man das als, es gibt

01:47:50.000 --> 01:47:52.100
auch noch andere Metriken, die man irgendwie benutzen

01:47:52.100 --> 01:47:54.020
kann, aber das ist schon irgendwie so

01:47:54.020 --> 01:47:56.300
das verbreitetste,

01:47:56.420 --> 01:47:58.000
denke ich mal. Das kommt halt auch so aus

01:47:58.000 --> 01:47:59.380
diesem Information Retrieval-Bereich.

01:48:01.160 --> 01:48:02.120
Genau, und diese Metriken

01:48:02.120 --> 01:48:02.940
sind halt so ein bisschen,

01:48:04.300 --> 01:48:05.800
ja, man muss damit halt lernen umzugehen.

01:48:05.900 --> 01:48:07.580
Jedes Problem ist ein bisschen anders. Also,

01:48:07.880 --> 01:48:10.020
wir haben jetzt hier, wie gesagt, so eine Multilabel-Klassifikation.

01:48:11.240 --> 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.320
andere Metriken, die ich da benutze.

01:48:17.000 --> 01:48:18.060
Ich setze mich gerade das erste

01:48:18.060 --> 01:48:20.140
Mal in meinem Leben so ein bisschen mit Recommender-Engines

01:48:20.140 --> 01:48:22.360
auseinander, wo man quasi gleich ganze

01:48:22.360 --> 01:48:24.120
Listen immer zurückgibt

01:48:24.120 --> 01:48:26.240
und quasi sagt, okay, ich glaube

01:48:26.240 --> 01:48:28.100
das Erste ist das Wahrscheinlichste, das

01:48:28.100 --> 01:48:30.060
Zweite ist das Zweitwahrscheinlichste und so weiter, dann braucht man

01:48:30.060 --> 01:48:31.940
auch wieder ganz andere Metriken. Also

01:48:31.940 --> 01:48:34.520
genau, gerade in diesem Metrikenfeld

01:48:34.520 --> 01:48:36.260
wird es dann interessant, in welchem

01:48:36.260 --> 01:48:38.260
Bereich von Data Science man sich begibt

01:48:38.260 --> 01:48:39.880
und was man gerne machen möchte.

01:48:41.440 --> 01:48:42.160
Ja, da kann man

01:48:42.160 --> 01:48:43.840
viel Zeit reinstecken. Das ist auch wichtig.

01:48:45.680 --> 01:48:46.140
Genau, und

01:48:46.140 --> 01:48:47.940
das ist halt, das ist teilweise auch sehr schwer zu erklären,

01:48:48.060 --> 01:48:49.320
also wenn man dann irgendwie

01:48:49.320 --> 01:48:51.960
ja, dass dann halt

01:48:51.960 --> 01:48:53.640
auch Ergebnisse irgendwie

01:48:53.640 --> 01:48:54.400
reportet,

01:48:55.500 --> 01:48:57.940
ist manchmal nicht so einfach zu erklären,

01:48:58.100 --> 01:48:59.920
warum man das jetzt so macht und nicht irgendwie

01:48:59.920 --> 01:49:01.760
einen einfachen einzelnen Wert nimmt oder so.

01:49:03.320 --> 01:49:03.520
Ja,

01:49:03.740 --> 01:49:05.900
muss man halt gut sein im

01:49:05.900 --> 01:49:06.660
Erklären, keine Ahnung.

01:49:08.280 --> 01:49:09.780
Genau, beim Wesentlichen sind wir jetzt die

01:49:09.780 --> 01:49:11.840
Basispipeline ja einmal durch. Also wir haben unsere Daten

01:49:11.840 --> 01:49:13.620
geladen, wir haben sie uns ein bisschen

01:49:13.620 --> 01:49:15.060
angeschaut, wir haben

01:49:15.060 --> 01:49:17.660
darauf jetzt zwar kein großes

01:49:17.660 --> 01:49:19.620
Feature-Engineering gemacht, also wir haben jetzt nicht versucht,

01:49:19.720 --> 01:49:21.680
irgendwie noch zusätzlich sowas

01:49:21.680 --> 01:49:23.620
dran zu spielen, wie zum Beispiel die Textlänge, die

01:49:23.620 --> 01:49:25.620
noch nicht vorher in den Daten so mit drin war und auf

01:49:25.620 --> 01:49:27.640
denen mitzulernen oder sowas man machen könnte, aber wir

01:49:27.640 --> 01:49:29.820
haben zumindest den ganzen Text umgewandelt

01:49:29.820 --> 01:49:31.780
in eine Zahlenmatrix und die reduziert

01:49:31.780 --> 01:49:33.880
und darauf jetzt halt eben ein Modell

01:49:33.880 --> 01:49:35.780
berechnet und können sagen,

01:49:35.960 --> 01:49:37.440
wie gut dieses Modell ist.

01:49:38.820 --> 01:49:39.560
Wenn man jetzt

01:49:39.560 --> 01:49:41.660
einfach da eine Spalte dran hängt, geht

01:49:41.660 --> 01:49:43.620
das einfach so? Also wenn man das schon so ein bisschen modelliert hat,

01:49:43.980 --> 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:47.660 --> 01:50:08.960
Ähm, genau, also hier erzeuge ich ja sozusagen die Feature-Matrizen direkt aus dem Text, aber wenn wir uns jetzt zum Beispiel mal angucken, na, ich glaube, das Grid-Search-Ding macht das dann halt auch schon so ein bisschen anders.

01:50:08.960 --> 01:50:37.720
Was man da normalerweise dann hat, ist halt eben nicht so eine naive Geschichte, wo man das einfach so erzeugt, sondern man hat halt eine, die Feature Matrix wird erzeugt durch, oder überhaupt das komplette Ding ist halt eine Pipeline, ist halt auch eine Klasse aus Cycle Learn und die kombiniert im Grunde viele Schritte sozusagen zu einem Ding, das sich insgesamt wieder so verhält wie ein Modell.

01:50:38.960 --> 01:50:53.860
Also zum Beispiel jetzt bei dieser, in diesem Notebook ist es halt so, da sind die Schritte, aus denen die Pipeline besteht, halt, ja, das ist eine zweite Geschichte, die ich irgendwie da noch einführen muss.

01:50:54.360 --> 01:51:06.540
Das Ding nennt sich Feature Union und man kann sich das im Grunde so vorstellen, also Feature Union macht genau das, was du jetzt vorhattest, einfach irgendwie Dinge an die Feature Matrix spalten, an die Feature Matrix dran bauen, sozusagen.

01:51:06.880 --> 01:51:23.080
Ich habe unterschiedliche Spalten und ich möchte die zusammen kombinieren zu einer Feature-Matrix. Dann nehme ich Feature-Union, das fügt die Spalten zusammen und die Pipeline integriert die ganzen Schritte, die nötig sind, um irgendwas zu tun.

01:51:23.080 --> 01:51:24.920
halt, also

01:51:24.920 --> 01:51:26.700
Feature-Extraktionen,

01:51:26.760 --> 01:51:29.240
unterschiedliche Arten von Feature-Extraktionen

01:51:29.240 --> 01:51:31.080
und halt am Schluss irgendwie ein Modell

01:51:31.080 --> 01:51:32.040
trainieren und

01:51:32.040 --> 01:51:35.300
ja, auf den Testdaten

01:51:35.300 --> 01:51:37.000
halt Predictions machen.

01:51:39.300 --> 01:51:40.980
Sodass das Ganze sich wieder als ein

01:51:40.980 --> 01:51:42.660
Modell irgendwie benutzen lässt.

01:51:43.560 --> 01:51:44.940
Und was das hier tut, ist

01:51:44.940 --> 01:51:47.240
ja, ich übergib

01:51:47.240 --> 01:51:48.400
der Feature-Union

01:51:48.400 --> 01:51:51.020
halt irgendwie eine Liste von Transformern,

01:51:51.080 --> 01:51:52.800
die irgendwie Dinge tun und

01:51:52.800 --> 01:51:55.360
man kann die jetzt ineinander

01:51:55.360 --> 01:51:57.220
wieder verschachteln. Das ist jetzt wieder eine Pipeline.

01:51:57.660 --> 01:51:58.260
Und die Pipeline,

01:51:58.840 --> 01:52:01.380
die da drin ist, die macht halt

01:52:01.380 --> 01:52:03.340
der erste Schritt, der nimmt

01:52:03.340 --> 01:52:04.860
eine Spalte aus dem

01:52:04.860 --> 01:52:07.400
DataFrame, und zwar den Titel

01:52:07.400 --> 01:52:09.260
und

01:52:09.260 --> 01:52:11.520
macht dann eben so etwas wie

01:52:11.520 --> 01:52:15.680
Textstatistiken

01:52:15.680 --> 01:52:17.420
drauf. Also sowas wie, wie lang ist der Titel?

01:52:18.580 --> 01:52:19.420
Wie viele Buchstaben sind

01:52:19.420 --> 01:52:21.460
da drin? Wie viele Wörter sind da drin?

01:52:21.540 --> 01:52:23.140
oder sowas, ich weiß jetzt gar nicht mehr genau, was das tut.

01:52:24.000 --> 01:52:25.380
Und dann skaliert er halt diese,

01:52:25.640 --> 01:52:27.480
weil bei TF-EDF ist das halt

01:52:27.480 --> 01:52:28.720
automatisch drin, das ist halt

01:52:28.720 --> 01:52:30.220
irgendwie

01:52:30.220 --> 01:52:33.600
sozusagen

01:52:33.600 --> 01:52:36.640
skaliert ist auf

01:52:36.640 --> 01:52:39.320
einen Intervall zwischen, weiß ich nicht,

01:52:39.360 --> 01:52:40.300
0 und 1 und

01:52:40.300 --> 01:52:43.420
normalisiert, sodass es halt

01:52:43.420 --> 01:52:45.080
irgendwie alle Vektoren, die Länge 1 haben.

01:52:46.360 --> 01:52:47.620
Bei den Textstatistiken

01:52:47.620 --> 01:52:49.560
ist das natürlich nicht, da kommt dann halt so eine Zahl raus,

01:52:49.560 --> 01:52:50.820
wie, der Titel hat jetzt

01:52:50.820 --> 01:52:53.340
25 Buchstaben und

01:52:53.340 --> 01:52:55.280
da, was man eigentlich immer

01:52:55.280 --> 01:52:57.300
macht, wenn man jetzt solche Zahlen hat, ist

01:52:57.300 --> 01:52:59.460
das so zu skalieren,

01:52:59.700 --> 01:53:01.420
dass alle Features irgendwie

01:53:01.420 --> 01:53:02.400
immer zwischen

01:53:02.400 --> 01:53:05.480
minus 1 und 1

01:53:05.480 --> 01:53:06.540
oder zwischen 0 und 1 sind

01:53:06.540 --> 01:53:09.280
und auch eine Standardabweichung

01:53:09.280 --> 01:53:09.880
von 1 haben.

01:53:10.460 --> 01:53:13.420
Das hängt halt auch mal viel damit zusammen, was für ein Algorithmus du im Nachhinein

01:53:13.420 --> 01:53:15.360
dann benutzt. Manche Algorithmen

01:53:15.360 --> 01:53:17.400
können gut umgehen mit

01:53:17.400 --> 01:53:19.660
komplett absolut skalierten

01:53:19.660 --> 01:53:21.900
Werten, also so im Entscheidungsbaum zum Beispiel,

01:53:22.000 --> 01:53:23.820
dem ist das relativ egal, wo er

01:53:23.820 --> 01:53:25.640
jetzt zwischen, ob du jetzt die Werte zwischen

01:53:25.640 --> 01:53:27.600
0 und 1 reingibst und Werte

01:53:27.600 --> 01:53:29.700
zwischen 0 und 10.000, weil der

01:53:29.700 --> 01:53:31.740
entscheidet einfach irgendwo, okay, zwischen diesen

01:53:31.740 --> 01:53:33.780
zwei bitte splitte und

01:53:33.780 --> 01:53:35.520
das rechte Ast, das linke Ast,

01:53:36.060 --> 01:53:37.800
aber bei so einer linearen

01:53:37.800 --> 01:53:39.760
Regression zum Beispiel, da ist es

01:53:39.760 --> 01:53:41.780
halt von Bedeutung, wenn deine

01:53:41.780 --> 01:53:43.680
Achsen alle ganz unterschiedlich

01:53:43.680 --> 01:53:45.680
sind. Also ich könnte, das Wichtige ist eigentlich nur, dass

01:53:45.680 --> 01:53:47.540
sie halbwegs miteinander vergleichbar sind.

01:53:48.360 --> 01:53:50.400
Ich könnte sie auch alle von 0 bis 100 skalieren

01:53:50.400 --> 01:53:51.980
oder so, aber die Konvention ist halt einfach,

01:53:52.160 --> 01:53:54.100
man macht das halt einfach alles zwischen 0 und 1 oder

01:53:54.100 --> 01:53:56.160
minus 1 und 1, je nachdem, was man da vielleicht

01:53:56.160 --> 01:53:56.840
bezwecken möchte.

01:53:57.960 --> 01:53:59.720
Und damit macht man in der Regel nichts falsch.

01:54:00.500 --> 01:54:01.920
Also kann man sich ganz einfach vorstellen,

01:54:01.980 --> 01:54:03.860
bei einem linearen Modell, ein lineares Modell bedeutet,

01:54:04.040 --> 01:54:05.560
dass du im Grunde

01:54:05.560 --> 01:54:08.020
einen Vektor

01:54:08.020 --> 01:54:09.840
hast, der genau die gleiche

01:54:09.840 --> 01:54:12.100
Dimension hat, wie du Spalten hast,

01:54:12.240 --> 01:54:12.460
sozusagen.

01:54:14.580 --> 01:54:16.080
Und die Klassifikation ist einfach

01:54:16.080 --> 01:54:18.260
nur das Skalarprodukt aus einem neuen Feature-Vektor

01:54:18.260 --> 01:54:19.020
und diesem Modell.

01:54:20.420 --> 01:54:21.940
Und jetzt gibt es

01:54:21.940 --> 01:54:24.100
ganz viele unterschiedliche Arten,

01:54:24.300 --> 01:54:26.200
dieses Modell zu trainieren,

01:54:26.320 --> 01:54:28.180
aber das ist immer das Gleiche, wenn das ein lineares

01:54:28.180 --> 01:54:30.300
Modell ist. Also ob ich jetzt eine Support-Vector-Maschine

01:54:30.300 --> 01:54:32.140
nehme, die das halt

01:54:32.140 --> 01:54:34.280
trainiert oder halt Logistic Regression

01:54:34.280 --> 01:54:35.940
oder halt irgendwie sonst

01:54:35.940 --> 01:54:36.820
eins von den

01:54:36.820 --> 01:54:40.000
Generalized Linear Models oder so,

01:54:40.040 --> 01:54:42.100
die es da so gibt, da fällt immer so ein Vektor

01:54:42.100 --> 01:54:44.160
dabei raus und die Klassifikation ist eigentlich immer gleich.

01:54:45.060 --> 01:54:46.200
Und ich kann mir natürlich

01:54:46.200 --> 01:54:48.100
jetzt leicht vorstellen, was passiert, wenn ich

01:54:48.100 --> 01:54:50.140
irgendwie überall Werte zwischen 0 und 1

01:54:50.140 --> 01:54:52.120
habe in den Spalten. Nur in einer Spalte habe ich jetzt

01:54:52.120 --> 01:54:53.400
Werte um die 10.000 oder so.

01:54:53.840 --> 01:54:55.600
Dann dominiert diese Spalte natürlich das

01:54:55.600 --> 01:54:57.880
Klassifikationsergebnis massiv. Das heißt,

01:54:57.940 --> 01:54:59.980
ich muss die alle so normiert haben,

01:55:00.100 --> 01:55:02.120
dass hinterher die Länge der Vektoren

01:55:02.120 --> 01:55:03.620
1 ist, damit nicht

01:55:03.620 --> 01:55:06.140
ein Feature halt da so

01:55:06.140 --> 01:55:08.000
irgendwie, so alle Features sollten

01:55:08.000 --> 01:55:09.840
irgendwie so quasi numerisch gleich

01:55:09.840 --> 01:55:10.360
wichtig sein.

01:55:12.200 --> 01:55:13.840
Ja, deswegen muss ich das halt skalieren am Schluss.

01:55:14.620 --> 01:55:16.000
Und dafür nimmt man halt, ja, gibt es auch

01:55:16.000 --> 01:55:17.720
unterschiedliche Skalierer und

01:55:17.720 --> 01:55:20.060
Standard Scaler macht, glaube ich, irgendwie

01:55:20.060 --> 01:55:20.780
ja,

01:55:22.240 --> 01:55:22.940
weiß ich gar nicht.

01:55:24.420 --> 01:55:25.500
Ja, es skaliert halt.

01:55:25.580 --> 01:55:26.900
Es skaliert halt irgendwie runter, genau.

01:55:27.140 --> 01:55:29.040
Der wesentliche Punkt eigentlich bei diesen Pipelines ist,

01:55:29.460 --> 01:55:31.960
ich könnte diese ganzen Schritte auch alle nacheinander

01:55:31.960 --> 01:55:34.140
ausführen. Also ich kann prinzipiell

01:55:34.140 --> 01:55:35.780
in meinem Notebook, das haben wir

01:55:35.780 --> 01:55:37.620
vorher quasi auch gesehen, in dem

01:55:37.620 --> 01:55:39.320
linearen Regressionsnotebook,

01:55:40.100 --> 01:55:41.900
ich kann

01:55:41.900 --> 01:55:43.660
erst meinen Text umwandeln,

01:55:43.840 --> 01:55:45.600
Dimensionalitätsreaktionen ausführen in der nächsten

01:55:45.600 --> 01:55:47.820
Zelle und quasi immer dazwischen meine Werte

01:55:47.820 --> 01:55:49.700
irgendwie in ein neues DataFrame schreiben

01:55:49.700 --> 01:55:51.300
und das wieder in das nächste reinführen.

01:55:52.240 --> 01:55:53.760
Ist zum Debuggen vielleicht auch mal

01:55:53.760 --> 01:55:55.860
ganz hilfreich, aber wenn ich nachher quasi

01:55:55.860 --> 01:55:57.620
dann einfach damit spielen möchte,

01:55:57.720 --> 01:55:59.580
verschiedene Werte zu verändern, dann will ich, dass das

01:55:59.580 --> 01:56:01.800
möglichst einfach hintereinander durchläuft

01:56:01.800 --> 01:56:03.720
und ich weiß nicht, cashen so

01:56:03.720 --> 01:56:05.580
Pipelines auch zwischendrin Schritte? Genau.

01:56:06.220 --> 01:56:07.940
Genau, das heißt, das macht es auch deutlich effizienter,

01:56:08.080 --> 01:56:09.560
wenn ich dann quasi in einem

01:56:09.560 --> 01:56:11.580
relativ späten Step in der Pipeline

01:56:11.580 --> 01:56:13.440
eine Kleinigkeit ändere, dann muss die halt nicht

01:56:13.440 --> 01:56:14.940
komplett von vorne durchgeführt werden

01:56:14.940 --> 01:56:17.760
und genau, das mache ich

01:56:17.760 --> 01:56:19.660
prinzipiell eher, wenn ich

01:56:19.660 --> 01:56:21.440
schon so die erste Exploration

01:56:21.440 --> 01:56:23.600
durch habe, dann würde ich anfangen, sowas in eine Pipeline

01:56:23.600 --> 01:56:25.140
zu stecken oder machst du das wirklich von Anfang an?

01:56:25.220 --> 01:56:27.480
Ne, genau, ich mache das auch erst, wenn ich ungefähr weiß,

01:56:27.560 --> 01:56:29.620
was ich damit tun möchte

01:56:29.620 --> 01:56:31.520
und ja,

01:56:32.060 --> 01:56:33.520
genau, man braucht es halt auch

01:56:33.520 --> 01:56:35.560
vor allen Dingen deswegen, wenn man jetzt unterschiedliche Sachen

01:56:35.560 --> 01:56:37.140
ausprobieren möchte, das ist halt

01:56:37.140 --> 01:56:39.080
Stichwort wäre

01:56:39.080 --> 01:56:41.500
Hyperparameter-Optimierung, also sozusagen, welche

01:56:41.500 --> 01:56:42.380
Features verwende ich.

01:56:43.720 --> 01:56:44.940
Man kann ja im Moment ja dann doch

01:56:44.940 --> 01:56:46.140
wieder gewichten, wenn man möchte, oder?

01:56:46.860 --> 01:56:48.300
Oder mit so Gewichten so ein bisschen umspielen?

01:56:48.460 --> 01:56:50.500
Natürlich, man kann auch einzelne Teile davon,

01:56:50.760 --> 01:56:52.960
man könnte jetzt unterschiedliche Feature-Unions

01:56:52.960 --> 01:56:54.720
bauen, so eine zum Beispiel, die sich nur mit dem

01:56:54.720 --> 01:56:56.880
also das ist ja

01:56:56.880 --> 01:56:58.900
im Grunde hier auch schon so, also ein Ding,

01:56:58.980 --> 01:57:00.460
das sich halt nur mit dem Text beschäftigt oder

01:57:00.460 --> 01:57:02.280
eins, was sich mit dem Body,

01:57:02.700 --> 01:57:04.580
mit dem Titel beschäftigt und eins, was sich mit dem

01:57:04.580 --> 01:57:06.720
Body dieser Ticker-Meldung

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.840 --> 01:57:11.660
Das auf jeden Fall.

01:57:13.720 --> 01:57:16.840
Ja, aber all diese Änderungen, die man macht,

01:57:17.280 --> 01:57:19.480
wenn man jetzt da an irgendwelchen Parametern dreht,

01:57:20.100 --> 01:57:21.420
die möchte man ja hinterher auch,

01:57:21.900 --> 01:57:23.180
also das muss man sich ja irgendwie merken

01:57:23.180 --> 01:57:25.600
und eigentlich möchte man das ja auch systematisch durchprobieren

01:57:25.600 --> 01:57:27.580
und das nicht von Hand immer wieder verändern.

01:57:28.620 --> 01:57:30.980
Und ein Verfahren, um das halt systematisch durchzuprobieren,

01:57:31.100 --> 01:57:34.020
ist halt GridSearch und das ist halt auch ein Vorteil,

01:57:34.060 --> 01:57:35.760
wenn man jetzt so eine Feature-Pipeline hat,

01:57:35.760 --> 01:57:38.760
dass man sozusagen die Bereiche für die Parameter,

01:57:39.480 --> 01:57:41.380
die man halt durchprobieren möchte,

01:57:41.460 --> 01:57:42.420
die gibt man halt irgendwie an

01:57:42.420 --> 01:57:45.180
und dann ruft man das halt

01:57:45.180 --> 01:57:47.000
mit GridSearch auf und dann werden diese ganzen

01:57:47.000 --> 01:57:49.220
Parameter, dieses Parameter-Grid halt durchprobiert

01:57:49.220 --> 01:57:50.600
und am Schluss

01:57:50.600 --> 01:57:54.960
fällt halt das Modell raus, was

01:57:54.960 --> 01:57:56.580
am besten funktioniert hat, beziehungsweise alle anderen

01:57:56.580 --> 01:57:58.980
Ergebnisse werden auch gespeichert. Normalerweise will man jetzt

01:57:58.980 --> 01:58:00.940
da irgendwie aus diesem GridSearch

01:58:00.940 --> 01:58:03.500
Ding halt rausholen

01:58:03.500 --> 01:58:05.140
und irgendwo ein CSV schreiben oder irgendwie

01:58:05.140 --> 01:58:06.980
und dann kann man sich das halt hinterher visualisieren

01:58:06.980 --> 01:58:09.060
und dann halt gucken, okay, wann

01:58:09.060 --> 01:58:11.140
habe ich das mit welchen Parametern irgendwie ausprobiert

01:58:11.140 --> 01:58:12.000
und was dabei rausgekommen.

01:58:13.340 --> 01:58:14.800
Genau, ich würde da die

01:58:14.800 --> 01:58:17.360
Hyperparameter-Tuning nochmal kurz ein bisschen aufgreifen.

01:58:19.480 --> 01:58:21.060
Jeder dieser Algorithmen, die wir jetzt

01:58:21.060 --> 01:58:23.040
erwähnt haben, die haben jede Menge Parameter,

01:58:23.120 --> 01:58:24.120
die man da mitgeben kann.

01:58:25.380 --> 01:58:26.960
Eine ganz einfache lineare Regression

01:58:26.960 --> 01:58:28.520
ist vielleicht noch relativ beschränkt,

01:58:28.980 --> 01:58:30.940
aber sobald wir die jetzt zum Beispiel

01:58:30.940 --> 01:58:32.980
regularisieren,

01:58:32.980 --> 01:58:34.640
das heißt irgendwie verhindern, dass die

01:58:34.640 --> 01:58:36.600
zu stark sich den Daten anpasst,

01:58:36.860 --> 01:58:39.040
bekommt die Hyperparameter oder noch einfacher

01:58:39.040 --> 01:58:41.020
finde ich es sich vorzustellen, bei so einem Entscheidungsbaum

01:58:41.020 --> 01:58:57.480
Der hat halt eine gewisse Tiefe, der kann irgendwie auf 100 Leveln verschachtelt sein oder nur auf 2 und der kann auch zum Beispiel beschränkt werden in der Anzahl der letztendlichen Blätter, also wie viele mögliche Output-Ergebnisse kommen dahin oder wie viele Samples müssen in jede dieser Blätter letztendlich fallen.

01:58:57.480 --> 01:59:13.920
Das sind zum Beispiel schon drei verschiedene Parameter, die man da so mitgeben kann und die können die Art, wie gut dieses Modell performt, extrem beeinflussen. Das ist wirklich sehr, sehr entscheidend und deswegen ist es wichtig, die einfach nach und nach durchzuprobieren.

01:59:13.920 --> 01:59:40.940
Und man sagt jetzt, wir haben doch irgendwie selbstlernende Algorithmen, irgendwie, warum muss ich denn da jetzt noch Parameter tunen? Aber ich passe ja quasi einfach die, man muss, es sind halt zwei verschiedene Arten von Parametern. Die einen sind quasi die internen, die berechnet werden innerhalb des Algorithmuses, die lernt er aus den Daten und das andere sind quasi so die Konfigurationsobjekte, wie man das, wie die Berechnung von diesen anderen Parametern zustande kommt.

01:59:41.880 --> 02:00:06.320
Und die muss ich ihm halt eben mitgeben oder ich versuche sie halt einfach alle, probiere sie halt einfach alle durch. Und das ist, was ich mehr oder weniger bei so einem Hyperparameter-Search mache. Ich überlege mir irgendeine Strategie, dass er einfach möglichst viele von denen durchprobiert. Da gibt es auch Algorithmen, die versuchen quasi selbstständig so ein bisschen zu wählen, an welcher Schraube drehe ich als nächstes, um halt dann den Algorithmus an der Stelle optimal zu tunen.

02:00:06.320 --> 02:00:10.060
Und das ist halt ein ganz entscheidender Prozess innerhalb von so einem Data-Science-Projekt.

02:00:11.340 --> 02:00:16.340
Ja, auch um halt die, man möchte es auch deshalb schon formalisieren,

02:00:16.420 --> 02:00:18.420
damit man die Ergebnisse kommuniziert bekommt,

02:00:18.520 --> 02:00:20.440
weil wenn ich jetzt im Notebook irgendwie Parameter ändere

02:00:20.440 --> 02:00:22.560
und das durchprobiere, dann weiß ich das vielleicht noch,

02:00:22.660 --> 02:00:24.720
obwohl meistens vergisst man das ja auch relativ schnell wieder,

02:00:24.760 --> 02:00:25.520
was man alles probiert hat.

02:00:26.700 --> 02:00:27.500
Dann weiß man vielleicht noch so,

02:00:27.560 --> 02:00:28.720
ach, vor zwei Wochen hatte ich da irgendwas gemacht,

02:00:28.760 --> 02:00:29.300
das war ziemlich gut.

02:00:29.420 --> 02:00:30.120
Oh, was war das nochmal?

02:00:31.660 --> 02:00:34.100
Man möchte das ja auch, wenn da mehrere Leute dran arbeiten,

02:00:34.220 --> 02:00:35.800
denen das ja auch irgendwie kommunizieren

02:00:35.800 --> 02:00:38.580
und da ist es natürlich dann schon gut,

02:00:38.620 --> 02:00:39.760
wenn man das systematisch gemacht hat,

02:00:39.760 --> 02:00:41.640
weil dann fallen da eben solche CSVs

02:00:41.640 --> 02:00:43.540
einfach schon bei raus und man kann halt auch gucken, was andere Leute

02:00:43.540 --> 02:00:45.440
schon probiert haben und muss das dann auch nicht nochmal

02:00:45.440 --> 02:00:47.940
selber machen. Genau, und diese Hyper-Parameter-Search

02:00:47.940 --> 02:00:49.560
gibt einem halt am Ende auch so eine

02:00:49.560 --> 02:00:51.580
Operation irgendwie Best Parameter

02:00:51.580 --> 02:00:53.700
oder Best Fit oder sowas und dann

02:00:53.700 --> 02:00:55.580
gibt der einem halt einfach das Beste

02:00:55.580 --> 02:00:56.840
von allen, die er ausprobiert hat, wieder.

02:00:58.800 --> 02:00:59.660
Aber ansonsten,

02:00:59.840 --> 02:01:01.480
wenn du quasi auch so tracken möchtest,

02:01:01.560 --> 02:01:03.600
was hat gut funktioniert und auch Features reiningenieren

02:01:03.600 --> 02:01:05.540
möchtest, du schreibst es dann einfach in CSVs weg

02:01:05.540 --> 02:01:07.700
oder wie machst du das? Ja, meistens

02:01:07.700 --> 02:01:08.480
tatsächlich, ja.

02:01:09.480 --> 02:01:11.520
Weil das finde ich immer noch ein bisschen

02:01:11.520 --> 02:01:13.480
überraschend, dass da Second Learn an der Stelle irgendwie

02:01:13.480 --> 02:01:14.680
nichts von sich aus bietet.

02:01:15.540 --> 02:01:17.200
Also ich habe mir jetzt gerade da auch diverse Tools

02:01:17.200 --> 02:01:19.100
angeschaut. Ich finde da jetzt

02:01:19.100 --> 02:01:20.400
MLflow von

02:01:20.400 --> 02:01:22.480
Dataprix ganz cool,

02:01:23.160 --> 02:01:25.300
die ja auch quasi Spark gebaut haben.

02:01:25.860 --> 02:01:27.140
Die haben da ein Tool für gebaut.

02:01:27.260 --> 02:01:29.100
Es gibt da auch irgendwie Sacred und DVC,

02:01:29.240 --> 02:01:30.800
die ich mir alle mal angeschaut habe, aber

02:01:30.800 --> 02:01:32.080
irgendwie finde ich es merkwürdig,

02:01:32.820 --> 02:01:35.220
jeder kommt in diese Predulie, dass er jetzt

02:01:35.220 --> 02:01:37.060
quasi ein bisschen damit rumspielt und seine ganzen

02:01:37.060 --> 02:01:38.640
Ergebnisse an und nach noch tracken möchte

02:01:38.640 --> 02:01:40.400
und jeder schreibt sich die irgendwie so ein bisschen

02:01:40.400 --> 02:01:41.680
auf seine eigene Art weg, aber

02:01:41.680 --> 02:01:44.380
ja, der Standardsupport irgendwie

02:01:44.380 --> 02:01:46.320
von irgendwelchen Bibliotheken ist da, finde ich, noch ein bisschen

02:01:46.320 --> 02:01:47.640
jung und schwach.

02:01:48.420 --> 02:01:49.180
Ja, ja.

02:01:50.860 --> 02:01:52.240
Wie fandest du DVC?

02:01:52.340 --> 02:01:54.040
Das wollte ich mir demnächst mal irgendwie angucken.

02:01:54.800 --> 02:01:55.980
DVC ist halt nicht

02:01:55.980 --> 02:01:57.920
Pythonic, ja.

02:01:58.040 --> 02:02:00.600
Also das basiert halt komplett auf

02:02:00.600 --> 02:02:02.540
Kommandozahlenaufrufen

02:02:02.540 --> 02:02:03.560
und Shell-Skripten. Ich habe

02:02:03.560 --> 02:02:06.360
letztendlich quasi so die Abwägung, würde ich sagen,

02:02:06.780 --> 02:02:07.940
wenn du schnell

02:02:07.940 --> 02:02:10.280
Sachen ausprobieren willst

02:02:10.280 --> 02:02:12.460
und mehr so in der

02:02:12.460 --> 02:02:14.560
Exploration bist, dann guck dir lieber ML-Flow

02:02:14.560 --> 02:02:16.340
an. Das finde ich dafür deutlich angenehmer.

02:02:16.820 --> 02:02:18.640
Wenn du sehr viel Wert

02:02:18.640 --> 02:02:20.980
auf Reproduzierbarkeit deiner Experimente

02:02:20.980 --> 02:02:22.560
legst und vielleicht auch große

02:02:22.560 --> 02:02:24.400
Experimente machst und dafür bereit bist,

02:02:24.500 --> 02:02:25.680
mehr Zeit zu investieren

02:02:25.680 --> 02:02:28.380
und mehr so ein höheres Maturity-Level

02:02:28.380 --> 02:02:30.340
vom Prinzip her hast und auch im Team arbeitest,

02:02:30.500 --> 02:02:31.980
dann ist DVC meiner Meinung nach

02:02:31.980 --> 02:02:34.360
die bessere Wahl. Also ich habe Kollegen, die benutzen das eine

02:02:34.360 --> 02:02:36.400
als das andere. Das hängt ein bisschen mehr

02:02:36.400 --> 02:02:38.460
von deinem Projekt ab, aber gerade für die Exploration

02:02:38.460 --> 02:02:40.300
finde ich DVC einfach

02:02:40.300 --> 02:02:42.400
zu viel Boilerplate-Code.

02:02:48.680 --> 02:02:50.160
Ich verlinke dazu mal

02:02:50.160 --> 02:02:52.060
meinen Artikel, den ich auch gerade noch

02:02:52.060 --> 02:02:53.140
geschrieben habe, genau darüber.

02:02:57.120 --> 02:02:57.600
Ja.

02:02:59.500 --> 02:03:00.280
Jetzt könnte man

02:03:00.280 --> 02:03:02.100
natürlich alle möglichen verschiedenen Algorithmen

02:03:02.100 --> 02:03:04.200
draufwerfen und so, aber ich würde sagen, das überlassen

02:03:04.200 --> 02:03:06.140
wir mal den Hörern. Da könnte man jetzt auch ewig

02:03:06.140 --> 02:03:07.100
Zeit drauf werfen.

02:03:11.320 --> 02:03:12.220
Haben wir irgendwas

02:03:12.220 --> 02:03:13.020
Wesentliches vergessen?

02:03:13.940 --> 02:03:16.660
Den grundsätzlichen Prozess, dieses Datenbeispiel

02:03:16.660 --> 02:03:17.900
da von Reuters mal kurz so

02:03:17.900 --> 02:03:20.140
zu skizzieren, haben wir schon durch, oder?

02:03:21.180 --> 02:03:22.480
Also es funktioniert auf jeden Fall.

02:03:22.560 --> 02:03:24.200
Wir haben jetzt tatsächlich gelernt,

02:03:25.120 --> 02:03:26.420
wie man so eine neue

02:03:26.420 --> 02:03:28.360
Nachricht dann mit so einem Label versieht, dass dann

02:03:28.360 --> 02:03:30.760
die Klasse so, was ist das für eine Kategorie,

02:03:31.300 --> 02:03:32.040
rausfällt unten, oder?

02:03:32.520 --> 02:03:34.700
Genau. Also wir sind jetzt in der Lage,

02:03:35.480 --> 02:03:54.960
Wir haben jetzt ein Modell da liegen, was auf den Testdaten Prognosen rechnen könnte und wenn jetzt ein neuer vergleichbarer Textartikel reinkommt, der dieselben Spalten hat, egal wo der herkommt, dann können wir den auch reinwerfen und dann wird der einen der Tags voraussagen, die wir jetzt quasi da drin hatten.

02:03:54.960 --> 02:03:57.100
da können jetzt kein originär neuer

02:03:57.100 --> 02:03:59.060
Artikel natürlich rausfallen

02:03:59.060 --> 02:04:00.640
oder so, aber

02:04:00.640 --> 02:04:02.860
das haben wir

02:04:02.860 --> 02:04:04.780
und können auch bewerten, wie gut wir daran sind.

02:04:07.860 --> 02:04:09.140
Ja, also

02:04:09.140 --> 02:04:10.780
haben wir quasi unser erstes Projekt erfolgreich

02:04:10.780 --> 02:04:12.940
abgeschlossen und wenn wir das jetzt auf dem Server implementiert haben,

02:04:13.080 --> 02:04:14.360
dann läuft das so auch.

02:04:14.600 --> 02:04:16.800
Ja, wir könnten eben jetzt so ein Modell hinter

02:04:16.800 --> 02:04:18.640
so einer API

02:04:18.640 --> 02:04:20.420
irgendwie deployen und

02:04:20.420 --> 02:04:22.920
dann schicken wir da einen Artikel dahin

02:04:22.920 --> 02:04:24.820
und bekommen dann halt zurück, in welchen

02:04:24.820 --> 02:04:26.680
Dingern das liegt und dann muss man sich

02:04:26.680 --> 02:04:28.540
natürlich noch überlegen, okay, gibt man halt

02:04:28.540 --> 02:04:30.640
zurück, mit welcher Wahrscheinlichkeit

02:04:30.640 --> 02:04:32.600
das in welcher oder einfach nur

02:04:32.600 --> 02:04:34.580
eine Liste der Kategorien, in denen

02:04:34.580 --> 02:04:35.000
es liegt

02:04:35.000 --> 02:04:38.600
und wann sagt man

02:04:38.600 --> 02:04:40.220
eigentlich, es liegt drin oder nicht.

02:04:41.200 --> 02:04:42.120
Genau, und das ist,

02:04:42.500 --> 02:04:43.660
da müssen wir natürlich noch eine Menge

02:04:43.660 --> 02:04:46.340
Entscheidungen treffen. Das hängt halt auch

02:04:46.340 --> 02:04:48.540
davon ab, wie das Problem aussieht. Ist es wichtig,

02:04:48.640 --> 02:04:51.040
möglichst alle Kategorien,

02:04:51.160 --> 02:04:52.620
in denen ein Artikel liegen könnte,

02:04:53.320 --> 02:04:54.440
mitzuliefern oder

02:04:54.440 --> 02:04:56.480
ist es besonders wichtig, möglichst keine Fehler

02:04:56.480 --> 02:04:58.480
zu machen und das hängt dann halt davon ab,

02:04:59.020 --> 02:05:00.240
welche Art von Problem man gerade

02:05:00.240 --> 02:05:02.340
hat und dann, ja,

02:05:02.620 --> 02:05:04.600
genau, dann würde

02:05:04.600 --> 02:05:06.200
man das halt entsprechend machen, aber

02:05:06.200 --> 02:05:07.920
Wie groß ist das Modell auf dem Server?

02:05:09.640 --> 02:05:10.340
Die hier sind

02:05:10.340 --> 02:05:12.380
relativ klein, wenige Megabyte, denke ich,

02:05:12.460 --> 02:05:13.760
sind die groß, also das ist also

02:05:13.760 --> 02:05:16.580
Hängt vor allem auch viel von der

02:05:16.580 --> 02:05:18.380
Art des Modells ab, was du jetzt benutzt,

02:05:18.480 --> 02:05:20.480
also so ein Entscheidungsbaum zum Beispiel ist relativ klein,

02:05:20.900 --> 02:05:22.420
wenn du jetzt halt komplexere Algorithmen

02:05:22.420 --> 02:05:24.420
nimmst, wie zum Beispiel dein Random Forest,

02:05:24.440 --> 02:05:26.160
was quasi einfach ganz, ganz viele

02:05:26.160 --> 02:05:28.260
Entscheidungsbäume sind oder ein

02:05:28.260 --> 02:05:30.040
Boosting-Tree, was quasi verschachtelte

02:05:30.040 --> 02:05:32.140
Entscheidungsbäume sind, dann hast du natürlich ein

02:05:32.140 --> 02:05:34.240
Vielfaches dessen. Genau. Dann kommst du

02:05:34.240 --> 02:05:35.260
auf mehrere Megabyte

02:05:35.260 --> 02:05:38.440
einzelne Entscheidungsbäume, ist wahrscheinlich sogar im Kilobyte-Bereich.

02:05:39.820 --> 02:05:40.480
Je nachdem,

02:05:40.580 --> 02:05:41.640
wie tief du den halt eben machst.

02:05:41.980 --> 02:05:44.060
Und hängt halt auch davon ab, wie deine

02:05:44.060 --> 02:05:46.080
Trainingsdaten, also bei den linearen Modellen,

02:05:46.120 --> 02:05:48.040
die sind halt einfach genauso groß wie deine

02:05:48.040 --> 02:05:50.320
Feature-Matrix, also sozusagen haben genauso viele Dimensionen

02:05:50.320 --> 02:05:52.220
wie deine Feature-Matrix. Und dann kannst du

02:05:52.220 --> 02:05:54.080
es ja einfach ausrechnen, irgendwie, wenn du

02:05:54.080 --> 02:05:56.140
pro Gewicht irgendwie

02:05:56.140 --> 02:05:56.760
4 Byte

02:05:56.760 --> 02:06:00.340
brauchst für ein Float,

02:06:01.020 --> 02:06:02.220
Single Precision Float,

02:06:02.300 --> 02:06:03.100
dann ist das halt

02:06:03.100 --> 02:06:06.460
4 mal, bei dem

02:06:06.460 --> 02:06:07.940
ist es 25.000 wahrscheinlich mal,

02:06:08.020 --> 02:06:09.440
also 4 mal 25.000,

02:06:10.880 --> 02:06:11.660
also 100

02:06:11.660 --> 02:06:13.420
Kilobyte, das ist ja nichts.

02:06:15.720 --> 02:06:16.120
Aber

02:06:16.120 --> 02:06:18.140
wenn du jetzt zum Beispiel viele Trainingsdaten hast und

02:06:18.140 --> 02:06:19.200
du hast halt ein,

02:06:19.980 --> 02:06:21.840
also das ist ja auch noch so eine Geschichte, es gab

02:06:21.840 --> 02:06:22.720
in dem

02:06:22.720 --> 02:06:25.580
Explorations-Notebook auch so ein

02:06:25.580 --> 02:06:27.980
quasi manuellen

02:06:27.980 --> 02:06:29.920
Entscheidungsbaum dafür,

02:06:30.580 --> 02:06:31.200
welches

02:06:31.200 --> 02:06:34.060
Modell man denn jetzt für welches

02:06:34.060 --> 02:06:35.780
Klassifikationsproblem nehmen könnte.

02:06:36.260 --> 02:06:37.840
Und da gibt es halt auch so irgendwie zum Beispiel

02:06:37.840 --> 02:06:39.400
so rekurrente

02:06:39.400 --> 02:06:42.080
neuronale Netze,

02:06:42.120 --> 02:06:43.700
die man nehmen kann. Und die können halt unter Umständen

02:06:43.700 --> 02:06:45.000
sehr, sehr viel mehr Parameter haben.

02:06:45.380 --> 02:06:47.760
Das Ding macht natürlich

02:06:47.760 --> 02:06:49.280
nur Sinn, wenn man viel, viel mehr Trainingsdaten hat.

02:06:49.280 --> 02:06:50.720
Aber wenn man jetzt irgendwie ein Modell hat,

02:06:50.800 --> 02:06:52.940
50 Millionen Parametern, dann muss man die halt irgendwie

02:06:52.940 --> 02:06:54.740
speichern. Das ist halt dann das Modell und dann

02:06:54.740 --> 02:06:57.380
wird das halt auch sehr, sehr groß unter Umständen.

02:06:58.160 --> 02:06:58.920
Ja, aber selbst

02:06:58.920 --> 02:07:00.800
das ist ja für Server heute alles nicht mehr so.

02:07:01.560 --> 02:07:02.800
Es wird dann interessant noch, wenn man

02:07:02.800 --> 02:07:04.820
das nicht irgendwie auf einen Server deployen möchte,

02:07:05.000 --> 02:07:06.740
sondern, was heute oft

02:07:06.740 --> 02:07:08.460
gemacht wird, auch auf ein

02:07:08.460 --> 02:07:10.700
Telefon. Und da

02:07:10.700 --> 02:07:12.900
muss man halt vielleicht nochmal ein bisschen gucken, was die Größe angeht, aber

02:07:12.900 --> 02:07:14.700
ja.

02:07:14.700 --> 02:07:17.040
Das Schöne ist ja vor allem, eben eine Prognose

02:07:17.040 --> 02:07:18.480
jetzt mit so einem Modell zu berechnen, ist

02:07:18.480 --> 02:07:20.540
überhaupt nicht mehr kompliziert. Also

02:07:20.540 --> 02:07:22.780
aufwendig ist es natürlich, Modelle zu trainieren,

02:07:22.880 --> 02:07:24.640
wobei das mit den Modellen, die wir jetzt hier haben,

02:07:25.100 --> 02:07:26.600
alles relativ schnell geht und man das einfach

02:07:26.600 --> 02:07:28.840
auf dem lokalen Rechner mal durchspielen

02:07:28.840 --> 02:07:29.140
kann.

02:07:31.460 --> 02:07:32.740
Bei einem neuronalen

02:07:32.740 --> 02:07:34.540
Netzwerk wäre das bei dem Training was anderes,

02:07:34.760 --> 02:07:36.600
aber die Prognose ist hier nachher dann trotzdem super

02:07:36.600 --> 02:07:38.580
einfach, weil dann gehe ich halt

02:07:38.580 --> 02:07:40.440
einfach nur einmal quasi den Entscheidungsbaum lang oder

02:07:40.440 --> 02:07:42.620
laufe einmal mein neuronales Netzwerk von vorne

02:07:42.620 --> 02:07:44.200
nach hinten durch und fertig.

02:07:44.800 --> 02:07:46.260
Und das kann dann halt auch...

02:07:46.260 --> 02:07:48.720
Wenn man den Weg kennenlernt, dann kann ich natürlich relativ schnell sagen, wo ich hin soll.

02:07:49.020 --> 02:07:50.680
Genau, es kann auf schwache Hardware laufen.

02:07:52.960 --> 02:07:53.580
Ja, cool.

02:07:54.360 --> 02:07:57.020
Dann habe ich tatsächlich heute wieder ganz viel über Machine Learning gelernt.

02:07:57.400 --> 02:07:58.600
Ich hoffe, ihr habt auch noch irgendwas mitgenommen.

02:08:00.320 --> 02:08:01.740
Ja, wenn du noch ein bisschen mehr lernen willst.

02:08:01.860 --> 02:08:05.000
Also ich finde immer, so eigene Projekte sind super.

02:08:05.620 --> 02:08:09.500
Und ansonsten einfach bei Kaggle mal einen Account machen.

02:08:09.520 --> 02:08:09.960
Ja, Kaggle, ja.

02:08:10.600 --> 02:08:12.600
Selbst wenn man da am Anfang nicht mitmacht.

02:08:12.600 --> 02:08:14.520
Also selber mitmachen ist sehr viel Aufwand.

02:08:15.040 --> 02:08:18.460
Aber es reicht eigentlich auch einfach nur mal ein paar Challenges zu beobachten

02:08:18.460 --> 02:08:19.920
und mal ein paar Kernels sich aufmessen.

02:08:19.920 --> 02:08:21.860
Oder mal so nachbauen oder so welche, die es schon gab.

02:08:21.940 --> 02:08:23.940
Mal gucken, wie gut man an die tollen Lösungen irgendwann rankommt.

02:08:24.100 --> 02:08:26.260
Genau, also beziehungsweise das Schöne ist ja bei Kaggle,

02:08:26.340 --> 02:08:28.640
dass diese ganzen Lösungen eigentlich immer einfach alle online sind.

02:08:28.640 --> 02:08:31.640
Also diese Kernels, die da sind,

02:08:31.700 --> 02:08:33.180
die sind ja wirklich immer sehr, sehr gut.

02:08:33.460 --> 02:08:35.380
Gerade auch bei der Exploration, wo man,

02:08:35.720 --> 02:08:38.640
also so ein Kernel ist ja vom Prinzip her so ein Notebook.

02:08:39.240 --> 02:08:41.260
Ja, vielleicht noch ganz kurz, in Kaggle gibt es Bounties dafür,

02:08:41.360 --> 02:08:43.040
wenn man total tolle Prognosen herstellt.

02:08:43.320 --> 02:08:44.400
Also nur das vielleicht mal so für die Leute,

02:08:44.500 --> 02:08:45.100
die das noch nicht gesehen hatten.

02:08:45.760 --> 02:08:48.100
Genau, genau. Es ist also ein Wettbewerb

02:08:48.100 --> 02:08:49.960
für Data Science Projekte und

02:08:49.960 --> 02:08:52.040
Leute sind da so nett und stellen halt quasi

02:08:52.040 --> 02:08:54.100
ihre Kernels online, ihre Notebooks online

02:08:54.100 --> 02:08:56.020
und man kann da einfach mal gucken, wie die das

02:08:56.020 --> 02:08:57.940
lösen. Da kriegt man sowohl mit, welche

02:08:57.940 --> 02:08:59.740
Tools sind gerade irgendwie angesagt,

02:09:00.140 --> 02:09:01.860
wie geht man damit um, man lernt so die

02:09:01.860 --> 02:09:03.480
Syntax und

02:09:03.480 --> 02:09:05.940
genau, also ich lerne da auch jedes Mal,

02:09:06.000 --> 02:09:07.900
wenn ich so eins der top gerateten

02:09:07.900 --> 02:09:09.880
Notebooks da durchlese, lerne ich

02:09:09.880 --> 02:09:10.600
jedes Mal wieder was.

02:09:12.160 --> 02:09:13.900
Ja, finde ich auch super hilfreich.

02:09:15.400 --> 02:09:17.000
Ja, schön, dass ihr wieder alle eingeschaltet habt.

02:09:17.540 --> 02:09:18.560
Ihr findet immer die

02:09:18.560 --> 02:09:19.660
Informationen in den Shownotes.

02:09:20.960 --> 02:09:22.580
Genau, die werden nicht mehr, glaube ich, ziemlich lang.

02:09:22.880 --> 02:09:23.820
Ja, das kennen wir schon.

02:09:24.980 --> 02:09:26.240
Und ja, dann

02:09:26.240 --> 02:09:27.620
hört wieder rein, bleibt gewogen.

02:09:28.720 --> 02:09:29.540
Wann auch immer ihr uns hört.

02:09:30.560 --> 02:09:32.480
Wenn ihr irgendwelche Feedback habt, schickt eine E-Mail

02:09:32.480 --> 02:09:34.880
an uns, hallo at peißenpodcast.de

02:09:34.880 --> 02:09:35.700
oder Nico.

02:09:36.520 --> 02:09:38.220
Und ja, bis dahin.

02:09:39.700 --> 02:09:40.680
Genau, hört

02:09:40.680 --> 02:09:42.240
wieder rein und bis bald.

02:09:42.240 --> 02:09:42.920
Tschüss.
