卸下技術債務!數據科學家需要簡潔的Python代碼

2020-12-11 讀芯術

全文共6616字,預計學習時長19分鐘

來源:Pexels

數據科學團隊傾向於向兩個互相競爭的領域發展。

一方面,有一些數據工程師非常看重高度可靠,穩固的代碼,這些代碼承擔的技術債務少。另一方面,有些數據科學家非常重視概念驗證(e.g.設置)中想法和算法的快速原型設計。

雖然更成熟的數據科學功能使雙方之間擁有卓有成效的工作夥伴關係,建立了完善的CI / CD管道,並明確定義了職責分工,但早期團隊通常由經驗不足的數據科學家主導。所以,代碼質量受到損害,技術債務以膠合代碼,流水線叢林,無效的實驗代碼路徑和配置債務的形式呈指數級累積[1]。

你能想像沒有xkcd的生活嗎?

最近,我寫了一篇關於為什麼數據科學家的代碼傾向於遭受平庸之苦的評論文章,在這篇文章中,我希望介紹一些方法供新手數據科學家編寫更清晰的Python代碼並更好地構建小型項目,以及闡明減少技術債務在不經意間給你和所在團隊帶來的負作用。

下面的內容既不詳盡也不足夠嚴謹,旨在以淺顯的方式介紹深層次建立數據科學項目的方式。有些要點很明顯,有些則有點隱晦。

以下是本文內容的快速概述:(1)樣式準則,(2)文檔,(3)類型檢查,(4)項目文件夾結構,(5)代碼版本控制,(6)模型版本控制,(7)環境,(8)Jupyter筆記本,(9)單元測試,(10)記錄。

Python 代碼樣式指引——PEP 8和linting

可讀性非常重要,PEP8就是為此而打造,提供了編寫簡潔python代碼的慣例。

符合PEP8規範是Pythonic代碼的最基本要求。它表明你已經了解了Python開發人員的最基本預期。表明你能夠與其他開發人員更輕鬆地協同合作,最重要的是,你的代碼將更具可讀性和一致性,並且更加方便自己理解。

在這裡複製和重新格式化PEP8樣式指南屬於無用功。因此,你可以根據自己的喜好瀏覽pep8.org,查看示例並了解在微觀層面(與在宏觀層面或系統級別上編寫簡潔代碼相反)上編寫簡潔代碼的意義。

PEP8中提供的示例包括設置命名約定,縮進,導入和行長的標準。

順便說一句, PEP8是應使用成熟的IDE(如看來像高級Python IDE的PyCharm)而非Sublime這樣的簡單文本編輯器來編寫代碼的原因之一。適用於Python的重量級IDE通常會遵循PEP8樣式指南,它會在違反PEP8原則或自動重新格式化代碼庫時發出警告。

以下是四個(儘管實際上還有許多種)命令行工具,通過對原始碼執行靜態分析,以保持其簡潔和一致性:

1. PyLint-最受歡迎的linter。它能夠檢查原始碼,並充當錯誤和質量檢查器。它比PEP8具有更多的驗證檢查和選項。但是,根據默認設置,它的輸出有點過於繁瑣,輸出量偏大。

2. Black-自動重新格式化Python代碼。 Black將重新格式化整個文件的格式,並格式化字符串以使其添上雙引號。

3. PyCodeStyle——官方的linter工具,用於根據PEP8 python的樣式規範檢查python代碼。

4. Flake8——封裝pyflakes,pycodestyle和mccabe,它會驗證封裝pep8的封裝器,pyflakes和循環複雜性。

旁註1. linter不會告訴你變量的命名方式是否正確。這項遭新手開發人員嘲笑的技能仍是值得掌握的技能。

旁註2. 在安裝這些軟體包之前,最好先處於虛擬環境中。此點會在後文闡述。

來源:Pexels

記錄項目— PEP257 and Sphynx

PEP8概述了Python的編碼規範,PEP257則對文檔字符串的高級結構,語義和約定進行了標準化:基本內容及表達方式。與PEP8一樣,這些並不是硬性規定,但是你應該明智地遵循這些準則。

如果違背了這些規範,那麼代碼看起來可能不太美觀。

那文檔字符串又是什麼呢?

docstring是一個字符串文字,作為模塊,函數,類或方法定義中的第一條語句出現。這樣的文檔字符串賦予該對象__doc__特殊屬性。與PEP8一樣,我並不會複製並重新格式化整個PEP格式,你應該在其他時間瀏覽它,此處僅提供函數文檔字符串的兩個示例。

1. 函數添加的單行文檔字符串示例

defadd(a, b):"""Sum twonumbers."""return a + b

2.複合函數的多行文檔字符串示例:

defcomplex(real=0.0, imag=0.0):"""Form a complexnumber.Keyword arguments:real -- the real part (default 0.0)imag -- the imaginary part (default0.0)"""if imag == 0.0 and real == 0.0:return complex_zero...Sphynx

畢竟,格式正確的文檔字符串已經到位了,接下來,你要將其轉換為美化的項目文檔。Sphynx是一款分解Python文檔的生成器,它可以輸出html,pdf,unix幫助頁面等等。

這是Sphynx入門的很好的教程。

簡而言之,在某個目錄(通常是docs目錄)中初始化Sphynx並設置其配置後,使用reStructuredText(* .rst)文件,在調用make之後,這些文件將轉換為首選的輸出文檔類型。

另外,可以直接從文檔字符串創建對Python程序其他部分的引用,這些字符串在輸出文檔中顯示為連結。

為了說明Sphynx文檔生成器的典型輸出,此處是一個利用Sphynx生成文檔的Python項目列表,雖然並不完整,但也足夠學習了。示例包括matplotlib, networkX, Flask和 pandas。

類型檢查 — PEP484, PEP526, 和 mypy

由於Python是一種動態類型的語言,因此默認情況下不會進行靜態類型檢查,優點是靈活性和快速的開發進度,但是也有弊端,因為不會在運行系統(編譯時)之前捕獲簡單的錯誤,而是在運行時捕獲它們。通常,像Python這樣的動態類型化語言比靜態類型化語言需要更多的單元測試。這很繁瑣。在諸如Scala或Java或C#之類的語言中,類型聲明以代碼形式出現,並且編譯器檢查變量是否合法通過類型傳遞。

最終,靜態類型扮演安全網的角色,在某些情況下你應該明智地使用。好消息是Python實際上提供了所謂的類型提示。

這是一個函數注釋類型提示的示例。這意味著name應為str類型,函數也應返回str。

defgreeting(name: str) -> str:return 'Hello ' + name

這是變量注釋類型提示的示例。這意味著變量i應該是整數。請注意,以下語法適用於Python 3.6及更高版本。

i: int =5

但壞消息是,類型解釋被Python解釋器忽略,並且沒有運行時的效果(PEP當前仍在進行中)。

但是,如果沒有運行時效果,為什麼還要使用類型提示呢?有兩個原因。首先,代碼的作用更明確,知道如何運行。其次,由於可以在Python中使用靜態類型檢查器,因此默認情況下它不會運行。主要的靜態類型檢查器是mypy。

旁註1:由於類型提示的可選性,可以將它們放在代碼中的任何位置,某些位置或不放置。試圖使其與放置位置保持一致。

旁註2:如前所述,PyCharm能很好地施行PEP8標準。但是Pycharm在類型提示的情況下也同樣很有用。它會自動檢查類型提示,並在違背預期時給予提示。默認情況下,在PyCharm中,這些設置為警告提示,但也可以將其設置為錯誤提示。

來源:Pexels

項目文件夾結構— cookiecutter

正如凌亂的辦公桌映射著頭腦混亂,凌亂的文件夾結構也是如此。

從一開始,許多項目就受益於經過深思熟慮的目錄結構。不幸的是,開始項目的一種常見方法是創建一個基本項目目錄,並將所有內容直接歸於目錄中——從數據到筆記本到模型生成再到輸出,而不考慮由於簡單項目變得越來越複雜的參數化管道產生的不良影響。

最終,會面臨某種形式的技術債務,此後必須以時間和精力去償還。真的完蛋了嗎?只需從一開始有遠見地正確構造項目,就能避免這些。

我們為此苦苦掙扎的一部分原因是因為創建項目文件夾結構很繁瑣。我們想深入探索數據並建立機器學習模型。但是相對較小的精力投入可以節省很多工作。

精簡的文件夾結構促進最佳實踐,簡化關注點分離,並使學習(或重新學習)舊代碼更加愉悅。

幸運的是,由於開源者的辛勤工作,有一種剛出爐的現成解決方案,用於創建我們想要的文件夾結構:cookiecutter。

創建許多數據科學項目共有的簡潔文件夾結構只是一個命令。觀看下面的視頻,了解如何設置cookiecutter項目結構。

cookiecutter-數據科學

由 ericmjalbertasciinema.org錄製

請注意,cookiecutter功能非常強大,實際上除了生成簡潔項目文件夾結構外,還有更多功能。有關更多信息,請查看優秀的cookiecutter文檔,它詳實地闡明了數據科學項目的基本原理。

代碼版本控制— git

這一點廣為人知,我將不作贅述。軟體開發的現代世界已經遠離2000年代以前陰暗的狂野西部。每個人和他的下屬都應該使用某種版本控制其項目。簡單的協作,高效的版本控制,回溯和代碼備份,這就足夠了。

學會使用git是第一步,而用好git則是另外一碼事了。

提交代碼:「提早提交並經常提交」是合理的建議。避免提交大量代碼,而建議提交小的獨立功能。提交時,編寫描述性的提交消息以準確記錄更改。

多用戶最佳實踐:這在很大程度上取決於具體情境。我與團隊合作的方式是擁有一個永遠不會直接推送的master分支(主分支),一個正在運行代碼的運行版本但從未直接對其進行開發的develop分支(開發分支),然後是團隊中各個成員進行編碼的feature分支(功能分支),這些功能隨後合併到開發分支。當develop分支準備發布時,它會合併到master分支。這種封裝的工作方式使多個開發人員在不幹擾主代碼庫的情況下即可輕鬆地處理特定功能,降低了合併衝突的可能性。有關更多信息,請查看此連結。

模型和數據的版本控制— dvc

來源:Pexels

模型和數據與代碼不同,因此絕不應將其歸入代碼存儲庫中。它們具有獨特的生命周期管理要求,並具有不同的操作約束。但是,適用於代碼版本控制的同一原理同樣適用於數據和模型版本控制。

有一個優秀的開源工具dvc,它基於git構建。其本質上是一個數據管道構建工具,在一定程度上有助於解決數據科學中的重現性危機。它可以有效地將你的數據和模型推送到伺服器,無論是本地數據,AWS S3,GCS,Azure,SSH,HDFS還是HTTP。

dvc 有3個核心主題:

1.大文件的版本控制

2.內置可重現的輕質管道

3.基於git的版本控制和實驗管理

旁註:版本控制整個數據集的另一種方法是存儲重新創建這些數據集所需的元數據,並在該參考元數據的背面創建模型引用。

基於環境構建— virtualenv

如果不在常規練習手冊中劃分環境,那麼平衡系統範圍的庫版本可能會花費一到兩個下午。也許你正在處理一個項目,然後移至另一個更新了numpy和poof的項目!那麼第一個項目的依賴關係中斷。

想像一下另一種情況,項目是由另一名團隊成員從git撤出的,該團隊成員正在使用項目中某個庫的其他版本。他們編寫了一些代碼,這些代碼依賴於自己版本缺乏的新功能,然後將其歸為主分支(明智的選擇是永遠不要直接歸為主分支)。你的代碼因此中斷了。

通過使用虛擬環境避免這種情況。對於簡單的Python項目,請使用virtualenv。如果有複雜的環境需求,請使用類似docker的工具。這是一個簡單的virtualenv工作流程:

1.在創建新項目時運行mkvirtualenv

2. pip安裝分析所需的軟體包

3.運行pip Frozen>requirements.txt來固定用於重新創建分析的確切軟體包版本

4.如果發現需要安裝另一個軟體包,請再次運行pip Frozen>requirements.txt並將更改提交給版本控制。

關於Notebooks的提醒 — jupytext

Jupyter Notebooks廣泛應用於數據科學。它們圍繞可讀性高的編程範例構建,並充當強大的媒介,使快速原型製作和易開發性融合,中間代碼段與輸出和說明文字交織,生成精美的演示文稿,非常美觀。

但是,儘管Jupyter Notebooks有各種優勢,也帶來了不少的麻煩。你的計算機存儲了多少個未命名的7.ipynb文件?Jupyter Notebooks最大的缺點可能就是它們與版本控制的配合太低效了。

原因是因為它們屬於一類編輯器——「所見即所得」,此編輯軟體允許用戶查看與最終結果非常相似的內容。這就意味著該文檔正在提取元數據,而Jupyter Notebooks是通過將代碼封裝在大型JSON數據結構中來嵌入代碼的,其中包含二進位數據,如保存為base-64編碼blob的圖像。

這裡聲明一下,Git可以處理Notebook,因為你可以將它們推送到存儲庫中,但在比較不同版本的Notebooks時,Git無法很好地進行處理,並且難以提供對其中代碼的可靠分析。

如果在公司內的Notebooks中或是在公開的GitHub上四處尋找信息,則很可能會發現資料庫憑據,敏感數據,「請勿運行此單元格」代碼塊以及許多其他不良做法。為了避免這種麻煩,可以在每次準備登入Notebooks時都清除輸出。但這這意味著每次都必須手動重新運行代碼以生成輸出,如果有多個用戶使用同一Notebooks,已清除的筆記本元數據甚至也會發生變化。

這兒有多種工具可供選擇。最受歡迎的一種是jupytext。這是作者撰寫的很棒的教程,介紹了如何使用它。你所要做的就是安裝jupytext,它將提供一個整潔的筆記本內下拉列表,用於下載代碼的markdown版本,並省略輸出,然後忽略.gitignore中的所有. ipynb文件。

單元測試— unittest

對代碼進行單元測試可能是確保獨立代碼塊按預期工作的有效方法。它允許自動化測試過程,及早發現錯誤,使過程更加敏捷,並最終幫助你設計更好的系統。python中最常用的測試框架是「unitest」的內置電池和內置模塊,該模塊提供了豐富的工具來構建和運行測試。另一個測試工具是pytest。

關於如何進行單元測試的教程有很多,本文提供一些關鍵的技巧。就像異常處理可以最大程度地減少你要捕獲潛在錯誤的功能一樣,每個單元測試都應側重於一小部分功能以證明其正常工作。每個單元測試應完全獨立,並且可以單獨運行。測試套件應在開發新功能之前或之後運行;實際上,在將代碼推送到共享存儲庫之前,使用hook以自動運行所有測試是一個好主意,這種類型的測試通常是某些CI / CD管道的一部分,開原始碼示例服務之一叫做travis。

嘗試加快測試速度吧!對每個測試函數使用長的描述性名稱。測試應位於原始碼的單獨目錄中,有關更多信息,請參見文件夾結構部分。

這裡是一份教程,這是一份測試風格指南

日誌記錄 — PEP282,

日誌記錄是超越POC領域系統的關鍵部分。日誌記錄可以跟蹤程序執行過程中發生的情況並將該信息保存到磁碟。通過保存瀏覽路徑記錄,它極大程度地促進調試並識別錯誤。

日誌記錄通常用於兩個目的。診斷日誌記錄了與應用程式操作相關的事件。而審計日誌記錄了用於MI報告的基本運行時分析。每個日誌消息有幾種類型:debug、info、warning、error和critical。

logging是用於日誌記錄的內置Python標準庫。

來源:Pexels

結語

如果堅持閱讀到了結尾,那非常值得鼓勵。希望你能有所收穫。現在趕快去編程實踐吧。

留言點讚關注

我們一起分享AI學習與發展的乾貨

如轉載,請後臺留言,遵守轉載規範

相關焦點

  • 四種高性能數據類型,Python collections助你優化代碼、簡潔任務
    選自gitconnected作者:George Seif機器之心編譯參與:王子嘉、杜偉在這篇文章中,機器學習工程師 George Seif 介紹了 Python collections 模塊最受歡迎的四種數據類型以及它們各自的使用方法。這些數據類型可以對代碼進行優化,進而實現更簡潔的任務執行。
  • 一文總結數據科學家常用的Python庫(下)
    一文總結數據科學家常用的Python庫(上)用於建模的Python庫我們已經到達了本文最受期待的部分 - 構建模型!這就是我們大多數人首先進入數據科學領域的原因,不是嗎?讓我們通過這三個Python庫探索模型構建。
  • Python做數據分析-簡潔、易讀、強大
    使用過Python的用戶都會被其簡潔、易讀、強大的庫所折服,其pythonic語言特性,對人極其友好,可以說,一個完全不懂程式語言的人,看懂python
  • 已經會Excel了還需要學python嗎?
    作為數據處理的日常辦公軟體,Excel以其優秀的數據分析處理功能,簡單易用的操作成為大家的最愛。也許你不知道python是什麼,但是一定知道Excel。作為一名小白,我也曾有過這樣的想法:數據處理,用Excel就可以了,用python這種高級程式語言簡直就是殺雞用牛刀。但是當我當了一年查數姑之後,我就深刻地感受到我是多麼需要python這樣子的牛刀來解放我的雙手。
  • 敏捷開發社區:工程師技術/代碼債務完整指南
    千萬別說你來過 OSChttps://www.oschina.net/project/top_cn_2020近日,有敏捷開發社區發布《工程師技術債務完整指南》。根據其定義,技術債務也稱為代碼債務,指開發團隊為了加快項目或功能的交付速度,而之後會在某一時間需要重構的情況。
  • 如何編寫簡潔美觀的Python代碼
    介紹你有沒有遇到過一段寫得很糟糕的Python代碼?我知道你們很多人都會點頭的。編寫代碼是數據科學家或分析師角色的一部分。另一方面,編寫漂亮整潔的Python代碼完全是另一回事。作為一個精通分析或數據科學領域(甚至軟體開發)的程式設計師,這很可能會改變你的形象。
  • 開發者和IT人士成為數據科學家的學習路線
    在你轉行數據分析的起步階段,這會是個巨大的優勢。儘管你沒有使用數據科學領域程式語言的經驗,但是你在理解一些諸如指數、函數、對象、引用等概念上有很大的優勢。邏輯思維:數據科學家是按邏輯思考的,他們基於數據做決策。所以你呢?碼代碼需要邏輯,這是編程邏輯。你的大腦適應了那樣去思考,這當然是你的加分項。數學能力:數學是數據科學的核心。數學好是一個人能取得的最大成就。
  • 作為數據科學家你應該知道這些 python 多線程、進程知識
    每個數據科學項目遲早都會面臨一個不可避免的挑戰:速度問題。使用更大的數據集會導致處理速度變慢,因此最終必須想辦法優化算法的運行時間。正如你們大多數人已經知道的,並行化是這種優化的必要步驟。python 為並行化提供了兩個內置庫:多處理和線程。在這篇文章中,我們將探討數據科學家如何在兩者之間進行選擇,以及在這樣做時應注意哪些因素。
  • 為什麼入門大數據選擇Python而不是Java?
    Python是一種面向對象的解釋型電腦程式設計語言,Python是純粹的自由軟體, 原始碼和解釋器CPython遵循 GPL(GNU General Public License)協議。Python語法簡潔清晰,特色之一是強制用空白符(white space)作為語句縮進。Python具有豐富和強大的庫。
  • 一行代碼簡化Python異常信息:錯誤清晰指出,排版簡潔美觀
    只需一個import,報錯也能整齊劃一,錯誤代碼位置、錯誤原因清晰明了,一眼就能看清。debug仿佛都沒有那麼痛苦了。一行代碼簡化報錯先來試試一個簡單的錯誤。輸出變成了這個樣子:是不是清晰簡潔了許多?還可以自定義顏色。bug少的時候,還不覺得有什麼太大區別。當報錯信息鋪滿一整頁,美觀不美觀,對心靈的打擊程度就完全不同了。使用指南像Python的所有第三方庫一樣,PrettyErrors的安裝十分簡單。
  • 八行python代碼展現程式設計師從入門到大神的八種階段
    人生苦短,我用python。python的世界裡無處不在的簡潔和短小,往往一行代碼可以實現很多有意思功能。你敢想像你從入門python代碼、網絡達人、反重力怪才、愛情自由怪、資源盜獵者、頓悟入禪、無所不能或者卷鋪跑路8個狀態只用了簡簡單單的8行代碼嗎?
  • Kaggle首次定義數據科學家:30歲,年薪5萬刀,愛Python,最恨髒數據
    這份調查問卷的受訪者囊括了來自50多個國家的16,000+位從業者,根據他們的問卷結果,Kaggle給出了一些有趣的結論:1、Python可能是機器學習最常用的程式語言,而統計學家更多地使用R語言;2、數據科學家的年齡中位數是30歲,而各國差異巨大,比如,印度的受訪人比澳大利亞平均年齡年輕9歲;3、受訪者中碩士學位所佔比重最大,但薪水最高的從業者($150k
  • 代碼這樣寫更優雅(Python版)
    題圖:unsplash.comPython 這門語言最大的優點之一就是語法簡潔,好的代碼就像偽代碼一樣,乾淨、整潔、一目了然。1、變量交換大部分程式語言中交換兩個變量的值時,不得不引入一個臨時變量:>>> a = 1>>> b = 2>>> tmp = a>>> a = b>>> b = tmppythonic>>>
  • 成為數據科學家路上需要掌握的基礎知識(附代碼)
    現在有很多數據科學家採用 Python 作為研究數據科學的工具,今天我們就分享一下將 Python 應用在數據科學領域中的基礎知識。Pyton 數據類型Python 包含多種數據類型,常見的有:float(浮點類型)、int(整型)、str(字符串)、bool(布爾類型)和 list。
  • 自動生成pandas代碼,python數據處理神器
    熟悉我的同學都知道,我的大部分教程最終都希望教會你怎麼節省代碼。今天我要說的不是怎麼寫代碼,而是介紹一款我親手打造的小工具,它作為探索數據的工具,你不僅不需要寫任何的代碼,它最終還會自動生成pandas代碼。
  • Python數據科學實踐 | 初步搭建數據科學工作環境
    ⽆⼈否認,在⽇新⽉異的現代社會,「⼤數據」時代已經悄然降臨。由於其在多個⾏業和學科領域中的⾼度滲透,並且在不同專業領域的數據研究中表現出⾼度融合的趨勢,⼤數據已經成為包含計算機科學和統計學在內的多個學科領域的新研究⽅向。同時,由於在⼤數據⽅⾯的研究尚且存在諸多誤區,⼈們迫切地需要對「⼤數據」時代的新現象、 理論、⽅法、技術、⼯具和實踐進⾏系統的研究。因⽽,「數據科學」應運⽽⽣。
  • 基於python的大數據分析-pandas數據讀取(代碼實戰)
    書籍推薦《大話軟體測試》出版啦,內容包括但不限於性能、自動化、接口、安全、移動APP非功能測試、抓包、loadrunner、jmeter、soapui、Appium、python
  • Python和人工智慧有什麼關係?Python 和人工智慧的區別是什麼?
    人工智慧人工智慧是一個大的概念,在人工智慧下有計算機視覺,語音識別,自然語言處理等不同的技術領域,這些技術領域中在Github上又有許多開源的代碼可以直接用來開發,而這些代碼往往需要或者只支持人工智慧是一個大的範疇,包括很多方面的應用,比如機器學習,在機器學習中的回歸算法,它們是通過統計分析所有數據來建立多因式,然後求解式子,而在這個過程中程式語言起到的作用是清洗數據、處理數據、建立關係求解結果的作用,python適用於數據清洗且學習成本低,所以在一定程度上,好一部分人傾向於將python應用於人工智慧應用領域。
  • vscode寫Python數據處理分析代碼,由安裝配置到cell交互模式
    此系列文章可在以下公眾號目錄找到 : 數據大宇宙 > Python入門必備 > 必備知識最近有許多小夥伴問我要入門 Python 的資料,還有小夥伴完全沒有入門 Python 就直接購買了我的 pandas 專欄。因此我決定寫幾篇 Python 數據處理分析必備的入門知識系列文章,以幫助有需要的小夥伴們更好入門。
  • Python代碼如何升級為Pythonic 代碼
    python的特點和功能,可以讓我們的代碼更加的簡潔, 有更好的可讀性, 很多情況下也會帶來更好的性能。符合這樣要求的代碼也被python社區稱為pythonic的代碼。正文共:7841 字預計閱讀時間:20 分鐘Python是當今最流行的語言之一。相對較新的領域如數據科學、人工智慧、機器人和數據分析,以及傳統的專業如Web開發和科學研究等,都在擁抱Python。對於用Python這樣的動態語言編寫代碼的程式設計師來說,確保代碼的高質量和無錯誤變得越來越重要。