Jupyter可能並非理想的Notebook

机器之心發表於2019-03-09

Jupyter 是一款免費、開源的互動式 web 工具,在資料科學家中備受歡迎。但本文作者卻對這一工具存在很多不滿,認為其不是理想的 Notebook。

據報導,Jupyter notebook 是資料科學家首選的實戰工具。本文展示了從 EDA(探索性資料分析)到API 的快節奏,並沒有Jupyter。

Jupyter的主要特點是:

  • 行內程式碼執行

  • 簡單的構思結構

  • 對圖片和資料幀的良好展示

與更加質樸的 iPython 命令列相比,這種整體的靈活性讓它成為了一款首選工具。但是,值得記住的是,這不過是一款 REPL(讀取-求值-輸出-迴圈),你可以在整個歷史記錄中有效地導航。因此,這並不是一款生產工具。

但是,很多機器學習開發者在生產中都經歷過把一個深度學習 notebook 重構成一個實際演算法時深深的痛苦(reddit 和 Stack Overflow 上也有類似的討論)。

保持精益生產的思想,我們應該努力減少浪費。

簡介

在 Sicara,我們為客戶構建基於機器學習的產品。

  • 機器學習:客戶帶來了業務需求,我們必須儘快提供令人滿意的演算法;

  • 我們構建的產品:我們需要以一種生產就緒的思想來開發產品。演算法被部署在雲端,以 API 等多種形式進行服務和更新。

首先,你肯定需要一個版本控制工具,這對 Jupyter 來說是一種痛苦(在 Reddit 和 quora 上也有相關討論)。不僅僅是針對你的程式碼,還有你的實驗。你需要有十足的把握能夠重新執行目前得到的所有結果。結果無法復現對於資料科學家來說多麼常見?

此外,使用 notebook 的人往往容易混淆下面三種用途:

  1. 開發:定義一些實用的方法和工具;

  2. 除錯/應用:用真實的資料執行一段程式碼,看看會發生什麼;

  3. 視覺化:以一種整潔、可復現的輸出來呈現結果。

為了減少浪費,應該明確地定義和分離這些步驟,以便可以在改變一個步驟的時候不會改變其他步驟,反之亦然。我得到的結論是:

  • 為了產生高質量的測試程式碼,應該使用一流的 IDE

  • 為了除錯程式碼,應該使用可視除錯工具

  • 為了寫報告,我對錶達性標記語言更為滿意(如 markdown、reST 及 LaTeX)

幸運的是,一個配置得當的IDE可以完成所有的事情。例如,如果你來自於R社群的話,你肯定會使用RStudio,它允許你進行這些工作:

  • 本機程式碼完成、自動修復等等。

  • 直接的可視除錯

  • 使用 Rmarkdown/knitr/Sweave 來生成好看的動態報告。

開發出生產就緒的程式碼

只要你想做一個實驗,也就是說,寫一個可以在你的資料上有所作為的方法,你就應該思考一下用法、極限案例等等。在一個單獨的檔案、文件和單元測試中來做。這樣可以確保:

  • 使用你的方法可以達到你的目的;

  • 你的程式碼可以安全地用在專案中的其他地方。

因為你必須組織你的工具,所以這會讓你思考流程的結構、你所需要的東西、你最可能改變的東西等等。Python 和 R 都支援這種快速測試。最好花十分鐘時間寫一下那些需要十小時除錯錯誤輸出的極限案例。

為了清楚起見,單元測試絕不能與定義方法的檔案存在於同一個資料夾中。但是使用Jupyter 的話,這點就無法避免了。

除錯和顯示

在這一步,你有了全新的功能程式碼。是時候在實際的資料上試一試了!這是notebook非常方便的所在了,因其存在單元格機制(cell mechanism)。但這顯然是一次工具切換。你為什麼要放棄具有所有快捷鍵和舒適度的IED,去在web瀏覽器上執行程式碼呢?你所需要的是將你的程式碼直接在 IDE 中行內執行( inline execution)。

像pycharm這樣的工具就有對這個功能的原生支援:使用一個鍵盤快捷鍵就能夠執行選定的程式碼或指令碼(在控制檯中選擇執行或者執行塊)。此外,它的控制檯中執行著iPython,還具有很好的變數工具視窗。在科學模式下,你還可以在IDE中顯示和改變影像、資料/陣列。或者你還可以使用像VSCode或者Atom with Hydrogen這些具備這種功能的工具。

彙報和分享

這裡你應該已經在專案路徑下有了測試程式碼,並在資料上執行一個純Python檔案。

|-- project
     |-- notebooks
           |-- data_analysis.py
     |-- tests
           |-- do_something_test.py
     |-- utils
           |-- do_something.py

你已經將程式碼在你的IDE中內聯地執行了並檢查了結果,非常棒!你的工作基本已經完成了:現在需要向團隊做彙報了,以證明將你的演算法移植到新的版本中的合理性,或者也許你將要寫一篇論文投稿到下一屆的NeurIPS會議上。

你需要解釋你的邏輯,並逐步證明你的結果。當然你不想在另一個檔案中重新輸入所有的內容,這太無聊了。

這就是存在用於文學式程式設計(literate programming)的工具的原因了。像Sphinx這類文件工具就是以這種思路構建的:將你的程式碼和文件寫進同一個檔案中,並從中生成一個可讀版本。

對於你的 Python notebook,我建議你使用 Pweave。這是我發現的目前為止最好用的 knitr 搬運包。也是一個完全支援 Python cell(或者Python和R的混合)的Rmarkdown。

在任何情況下,我發現使用 Pweave 的 pypublish 命令是最有效的。僅僅需要在你的指令碼上寫下注釋並執行:

pypublish data_analysis.py

從中生成一個清晰的可分享HTML。每一個註釋行都是markdown解釋的,每個cell(或者程式碼塊)都可以被顯示或者被隱藏。

例如,用這個notebook執行 pypublish(注意特殊的註釋標記#'、#+以及# %%)。

# %% # This is the title of the notebook
#+ setup, echo=False
import pandas as pd
df = pd.DataFrame({'a': list(range(4))})
#' Let us see what a plot looks like
#+ plot_df, echo=False
df.plot.bar()
#' Let us make now some visible computation
#+ echo=True
a = 1
print(a)
#' Also it is possible to use variable in context: a is <% a %>
#+ echo=True
a = 2
#' a is now <% a %>

生成如下報告:
Jupyter可能並非理想的Notebook

我推薦在PyCharm中設定一個外部工具來一鍵釋出notebook,配置如下(如有必要,請注意新增環境變數的技巧):
Jupyter可能並非理想的NotebookPweave作為外部工具配置

結論

這不是另一篇《為啥Jupyter notebook糟糕極了》(Why Jupyter notebooks suck )的文章。我對這個流行工具並無任何個人偏見,只是希望分享一些我在使用過程中的個人體驗。尤其是身處一個生產驅動的環境中,我已經進入了另一個工作流程。你怎麼看呢?

相關文章