做者:Norman Niemerhtml
Norman Niemer是一家大規模資產管理公司的首席數據科學家,他在其中發佈數據驅動的投資看法。他有哥倫比亞大學的金融工程專業理學碩士學位,和卡斯商學院(倫敦)的銀行與金融專業理學學士學位。python
本文爲Norman Niemer資深數據科學家爲你們羅列的10個常見錯誤及其解決方案。git
數據科學家是「比軟件工程師更擅長統計學,比統計學家更擅長軟件工程的人」。許多數據科學家都具備統計學背景,可是在軟件工程方面的經驗甚少。我是一名資深數據科學家,在Stackoverflow的python編程方面排名前1%,並與許多(初級)數據科學家共事。如下是我常常看到的10大常見錯誤,本文將爲你相關解決方案:github
不共享代碼中引用的數據web
對沒法訪問的路徑進行硬編碼數據庫
將代碼與數據混合apache
在Git中和源碼一塊兒提交數據編程
編寫函數而不是DAG數組
寫for循環cookie
不編寫單元測試
不寫代碼說明文檔
將數據保存爲csv或pickle文件
使用jupyter notebook
1. 不共享代碼中引用的數據
數據科學須要代碼和數據。所以,爲了讓別人能夠復現你的結果,他們須要可以訪問到數據。道理很簡單,可是不少人忘記分享他們代碼中的數據。
解決方案:使用d6tpipe(https://github.com/d6t/ d6tpipe)來共享你的代碼中的數據文件、將其上傳到S3/web/google驅動等,或者保存到數據庫,以便於別人能夠檢索到文件(可是不要將其添加到git,緣由見下文)。
2. 對沒法訪問的路徑進行硬編碼
與錯誤1類似,若是你對別人沒法訪問的路徑進行硬編碼,他們將沒法運行你的代碼,而且必須仔細查看代碼來手動更改路徑。使人崩潰!
解決方案:使用相對路徑、全局路徑配置變量或d6tpipe,使你的數據易於訪問。
d6tpipe:
3. 將代碼與數據混合
既然數據科學的代碼中包含數據,爲何不把它們放到同一目錄中?那樣你還能夠在其中保存圖像、報告和其餘垃圾。哎呀,真是一團糟!
解決方案:將你的目錄進行分類,好比數據、報告、代碼等。請參閱Cookiecutter Data Science或d6tflow項目模板[見#5],並使用#1中提到的工具來存儲和共享數據。
Cookiecutter Data Science:
https://drivendata.github.io/cookiecutter-data-science/
d6tflow項目模板:
https://github.com/d6t/d6tflow-templat
4. 在Git中和源碼一塊兒提交數據
如今,大多數人對他們的代碼使用版本控制(若是你不使用,那就是另一個錯誤,請參閱git:https://git-scm.com/)。在嘗試共享數據時,很容易將數據文件添加到版本控制中。當文件很小時是能夠的,可是git並無針對數據進行優化,尤爲是大文件。
解決方案:使用第1點中提到的工具來存儲和共享數據。若是你真的但願對數據進行版本控制,請參閱d6tpipe,DVC和Git大文件存儲。
d6tpipe:
https://github.com/d6t/d6tpipe
DVC:
Git大文件存儲:
5. 編寫函數而不是DAG
關於數據部分已經夠多了,如今來談一談實際的代碼!在學習編程時最早學習的內容之一就是函數,數據科學代碼一般由一系列線性運行的函數組成。
這會致使一些問題,請參閱「爲何你的機器學習代碼可能很差的4個緣由」:
https://github.com/d6t/d6t-python/blob/master/blogs/reasons-why-bad-ml-code.rst
解決方案:數據科學代碼不是一系列線性鏈接的函數,而是一組具備依賴關係的任務集合。請使用d6tflow或airflow。
d6tflow:
https://github.com/d6t/d6tflow-template
airflow:
6. 寫for循環
與函數相似,for循環也是你學習編程時最初學習的內容。它們易於理解,可是運行緩慢且過於冗長,一般意味着你不瞭解矢量化的替代方案。
解決方案:Numpy,scipy和pandas爲你須要for循環的狀況提供了矢量化函數。
Numpy:
scipy:
pandas:
7. 不編寫單元測試
隨着數據、參數或用戶輸入的改變,你的代碼可能會出現問題,有時你並無注意到。這可能會致使糟糕的輸出結果,而若是有人基於你的輸出作出決策,那麼糟糕的數據將會致使糟糕的決策。
解決方案:使用assert語句來檢查數據質量。pandas有相等測試,d6tstack有數據提取檢查以及用於數據鏈接的d6tjoin。
pandas相等測試:
https://pandas.pydata.org/pandas-docs/stable/reference/general_utility_functions.html
d6tstack:
https://github.com/d6t/d6tstack
d6tjoin:
https://github.com/d6t/d6tjoin/blob/master/examples-prejoin.ipyn
如下是數據檢查的示例代碼:
8. 不寫代碼說明文檔
我明白,你急着作出一些分析結果。你把事情彙總到一塊兒分析,將結果交給你的客戶或老闆。一個星期以後,他們回來講,「能夠把XXX改一下嗎」或者「能夠更新一下這裏嗎」。你看着你的代碼,可是並不記得你當初爲何這麼寫。如今就像是在運行別人的代碼。
解決方案:即便在你已經提交分析報告後,也要花費額外的時間,來對你作的事情編寫說明文檔。之後你會感謝本身,別人更會感謝你。那樣顯得你很專業!
9. 將數據保存爲csv或pickle文件
回到數據,畢竟是在講數據科學。就像函數和for循環同樣,CSV和pickle文件很經常使用,可是並很差用。CSV文件不包含綱要(schema),所以每一個人都必須再次解析數字和日期。Pickle文件解決了這個問題,可是它只能在python中使用,而且不能壓縮。二者都不是存儲大型數據集的最優格式。
解決方案:使用parquet或其餘帶有數據綱要的二進制數據格式,在理想狀況下能夠壓縮數據。d6tflow將任務的數據輸出保存爲parquet,無需額外處理。
parquet:
https://github.com/dask/fastparquet
d6tflow:
https://github.com/d6t/d6tflow-template
10. 使用jupyter notebook
最後一個是很有爭議的錯誤:jupyter notebook和csv文件同樣廣泛。許多人使用它們,可是這並不意味着它們很好。jupyter notebook滋長了上述提到的許多不良編程習慣,尤爲是:
把全部文件保存在一個目錄中
編寫從上至下運行的代碼,而不是DAG
沒有對代碼進行模塊化
很難調試
代碼和輸出混在一個文件中
沒有很好的版本控制
它容易上手,可是擴展性不好。
解決方案:使用pycharm和/或spyder。
pycharm:
https://www.jetbrains.com/pycharm/
spyder:
原文標題:Top 10 Coding Mistakes Made by Data Scientists