Jupyter ist nicht so schlecht

Der Grund, warum ich den letzten Eintrag geschrieben habe, ist eigentlich, dass ich die Präsentation "I Don't Like Notebooks" gelesen habe. Die Slides sind einfach toll, es lohnt sich, sie durchzulesen, obwohl sie relative lang sind.

Der Autor der Präsentation ist bekannt, weil er ein Buch über Data Science geschrieben hat. Ich habe die PDF-Version des Buches gekauft. (Ich hoffe, dass O'Reilly nochmal PDF verkauft...) Das Buch ist eine gute Einführung zum Data Science in Python.

Er schreibt natürlich über den Stil des Codes. Auf Seite 18 erwähnt er kurz eine Regel in Bezug auf lambda-expression.

Mach das nicht

Das ist eine der Regeln von PEP8. Er hat so viel Witz, dass er sofort auf der Seite 40 gegen die Regel verstoßt.

assign lambda to a variable

Vermutlich hasst er PEP8 wie ich. In der Tat verstoßt er mehr gegen PEP8.

Reproduzierbarkeit ist wichtiger als der Zustand

Ich hasse REPL. Das liegt daran, dass der Zustand einfach unordentlich wird, wenn man lang mit REPL arbeitet. Herr Grus sagt, dass man alle Geschichte überprüfen kann, wenn man das REPL (statt Notebook) benutzt. Aber mir ist das egal. Wichtig ist, zu ermitteln, ob ich den Zustand reproduzieren kann.

Soweit ich weiß, gibt es eine einzige Methode, zu ermitteln, ob etwas reproduziert werden kann: Alles neu ausführen. Das heißt,

  1. Minimales relevantes Code im Text-Editor kopieren/schreiben.
  2. REPL neu starten.
  3. Das kopierte/geschriebene Code ausführen.

NB: Natürlich gibt es noch zu beachtenden Punkte für Reproduzierbarkeit.

Wenn man mit REPL arbeitet, braucht man die Geschichte, um das ausgeführte Code abzuholen. Aber wenn man mit Jupyter arbeitet, nötig ist "Restart Kernel". Herr Grus zeigt, wie man mit einem Editor und iPython REPL arbeiten kann. In der Demonstration führt er oft %run sk.py aus. Er macht nämlich etwas Ähnliches.

Angenommen, dass man ein Problem hat, wenn er mit REPL arbeitet. Sollte man die ganze Geschichte beispielsweise auf stackoverflow kopieren und einfügen, um eine Frage zu stellen? Nein, zweifellos nicht.

Wenn es um den blutige Anfänger geht, ist es genug zu sagen, "Restarten und führe das nochmal aus!" Oder möchten Sie wirklich eine unordentliche Geschichte überprüfen, ob es einen Tippfehler gibt?

Aber trotzdem bin ich auch der Meinung, dass Jupyter Notebook zu den blutigen Anfänger gar nicht passt. Aber ich würde sagen, dass REPL auch nicht passt. Am besten ist es, ein normales Skript zu schreiben.

Wie kann man "gute Software-Engineering" für Analyse verwenden?

good software engineering is the safest/easiest way

(Das originelles Tweet kann nicht gefunden werden...)

Im Bezug auf das gute Verhalten erwähnt Herr Grus Modularität und Testbarkeit. Aber ich will wirklich wissen, wie man ein Skript zur Analyse testen kann, um sicherzugehen, dass das Code richtig und effizient läuft.

In seiner Präsentation testet er die Große der Daten durch Unittest:

assert data.shape == (1797,64)

Macht das wirklich Sinn? Er schreibt eine Funktion, um die Daten zu importieren. (Das Type-Hint habe ich entfernt, weil das Highlighting noch nicht damit umgehen kann.)

def load_data(filename: str = None):
    digits = load_digits()

    data = digits['data']
    target = digits['target']

    return data, target

In der Funktion wird die Input-Variable filename nicht benutzt. OK, wir nehmen an, dass wir später load_digits() durch pandas.read_csv oder etwas Ähnliches ersetzen. Dann was wir testen sollen, ist meiner Meinung nach folgend:

def test_load_data(self):
    data, target = load_data(path_to_test_data)

    assert len(data.shape) == 2
    assert data.shape[1] == 64
    assert len(target.shape) == 1
    assert data.shape[0] == target.shape[0]

NB: Wenn ich unittest benutze, verwende ich assertEqual Methode.

Angenommen dass wir die Daten für die Preise von Häusern haben. Wir müssen die folgenden Sache machen und das Ergebnis präsentieren.

  • Deskriptive Analyse (Einige Statistik und Diagramme)
  • Datenverarbeitung
  • Einige mathematischen Modell erstellen und bewerten.
    • Train-Test Splitting
    • Verschiedene Algorithmen versuchen
    • Optimierung der Hyperparameter durch CV
  • Bewertung des (besten) trainierten Modell.

Diese sind ein typischer Vorgang für einen Bericht. Was sollte man durch den Unit-Test testen? Meiner Meinung nach gibt es nur einen Vorgang unter diesen Vorgängen: Datenverarbeitung.

def munging(df):

    ## ... Daten verarbeiten ... 

    return X, y

Eigentlich schreibe ich normalerweise eine solche Funktion. Aber nicht wegen der Modularität. Es gibt zwei Gründe:

  1. Um den sauberen internen Zustand zu behalten. Also die Funktion verändert den originellen DataFrame nicht.

    Ich modifiziere nicht direkt die importierten Daten. Das liegt daran, dass ich nochmal die Daten importieren muss, wenn ich neu die Daten verarbeiten wollte. Stellen Sie Sich vor, dass Sie eine Spalte falsch verarbeitet haben.

    df["col"] = df["col"].apply(wrong_function)
    

    Dann Sie müssen nochmal die Daten importieren, um die originelle Darstellung zu haben.

  2. Diese Funktion verwende ich für Training-Daten und Test-Daten. Natürlich kann man nach der Datenverarbeitung die Daten in Training- und Testdaten teilen. Aber ich mache nicht so, weil ich theoretisch "den Test-Daten" benutze, wenn ich Feature Engineering mache. (e.g. eine numerische Spalte in einer diskrete Spalte konvertieren.)

NB: Es gibt auch Ausnahmen.

  • Wenn das Skript sicherlich nicht in ein produktives System integriert wird, konvertiere ich normalerweise die Datentypen nach dem Datenimport.
  • Wenn man als deskriptive Analyse absolute Zahlen berichten muss, benutze ich die ganzen Daten für die Statistik, danach verwende ich die Funktion für die ganzen Daten. Die Teilung in die Training- und Test-Daten folgt danach.
  • Oft ist BinaryEncoder (a.k.a. one-hot encoder) nötig. In diesem Fall trainiere ich einen Encoder im Voraus, dann gebe ich ihn als Input der Funktion.

Welchen Vorgang kann man noch außer Datenverarbeitung modularisieren?

Nichts mehr!

Ich habe niemals einen Test gesehen, den man für Analyse verwenden kann. Herr Grus hat niemals in seinem Buch unittest importiert.

Nach der Präsentation entwickelt er eine Bibliothek für NLP. Dann muss er natürlich Modularität sichergehen und Unittest schreiben. Aber wir diskutieren eine Analyse.

Wie kann man richtig ein effizient laufendes Code überprüfen?

Dieser Punkt ist zu wichtig, um in einem Eintrag zu integrieren. Deshalb schreibe ich darüber in nächstem Eintrag.

Jupyter Notebook zu importieren, ist nicht schlecht

From the slide

Zuerst würde ich sagen, dass es mehrere Art gibt, das Code vom Notebook zu entfernen. Deshalb ist die Import-Funktion mit dem genannten Punkt gar nicht verbunden.

Man kann ein Jupyter Notebook in einem anderen Notebook importieren, so dass man die Funktionen, die im ersten Notebook definiert werden, im zweiten Notebook verwenden kann. Wenn man eine modularisierbare Funktion im Notebook definiert, kann anderer Analyst mit einem anderen Notebook die Funktion testen.

Test mit Notebook

Ja, man kann den Vorteil genießen, wenn man die modularisierbare Funktion schreibt. Was ist wirklich falsch denn?

Gemeinsamer Kern

Test mit Notebook

Nein! Bitte nicht!

Was gleiches hat auch RStudio. Ich hasse wirklich diese Funktion. Ein Notebook/Rmarkdown soll ein Kontext sein. Ein Notebook darf nur von den Bibliotheken abhängen. Die einzige Ausnahme ist ein Notebook für den Test. Dass ein Notebook von einem anderen Notebook abhängig ist, ist einfach ein Albtraum.

Meine Bewertung von Jupyter

Wenn man einen Bericht für Analyse in Python erstellen wollte, muss man Jupyter Notebook benutzen. Es gibt nämlich keinen anderen Weg.

Man muss das Ergebnis und die Diagramme gleichzeitig zeigen. Natürlich kann man mit dem Code nur Diagramme erstellen und die Diagramme in einer Dokumentation (e.g. Word) hinzufügen. Aber der Vorgang ist sehr aufwändig.

Wenn es eine bessere Möglichkeit gibt, möchte ich gerne die andere Benutzen. Wie Herr Grus in der Präsentation sagt, ist die Funktionalität des Editors in Jupyter Notebook richtig schlecht.

Aber ich danke gar nicht, dass Herr Grus Idee (VS Code + REPL) Alternative zu Jupyter ist. Mit der Kombination einen Bericht zu erstellen, ist auch ein Albtraum. Darüber hinaus ist es absurd, jedes Mal das ganze Code durch %run auszuführen.

Also ich finde Jupyter OK und hoffe, dass irgendwann ein besseres Tool entsteht.

Share this page on        
Categories: #data-mining