+++翻譯自Shuaiw's Blog, 轉(zhuǎn)載請注明原作者出處+++
數(shù)據(jù)科學(xué)是一個相對較新的領(lǐng)域,沒有首選的版本控制標(biāo)準(zhǔn)。 在這篇文章中,我將討論數(shù)據(jù)科學(xué)周期,其獨特的版本控制策略以及一些可能的解決方案。
數(shù)據(jù)科學(xué)循環(huán)
數(shù)據(jù)科學(xué)不同于傳統(tǒng)的軟件工程, 尤其對于探索性數(shù)據(jù)分析, 特征工程, 機器學(xué)習(xí)建模和驗證階段. 但是數(shù)據(jù)科學(xué)和軟件開發(fā)領(lǐng)域相似之處是都需要進行代碼的i安歇, 數(shù)據(jù)科學(xué)傾向于代碼的迭代性和循環(huán)性, 通常, 該循環(huán)開始與最初的數(shù)據(jù)理解, 然后是數(shù)據(jù)收集, 探索, 清洗和轉(zhuǎn)換階段, 并且最終轉(zhuǎn)向數(shù)據(jù)建模和模型驗證和相應(yīng)機器學(xué)習(xí)模型的部署過程, 而且該循環(huán)將加深最初的數(shù)據(jù)理解并且成為下一個循環(huán)的開始.

數(shù)據(jù)科學(xué)同時也更具有交互性, 我們經(jīng)??吹綌?shù)據(jù)科學(xué)家更傾向于使用notebook, 例如(Jupyter, Zeppelin, or Beaker), 而不是僅僅使用IDE, 因為notebook相比后者更具有交互性, 能夠快速實現(xiàn)code-result的循環(huán).
這要求不同的版本控制范例, 因為簡單的復(fù)制軟件開發(fā)領(lǐng)域的VCS(版本控制系統(tǒng))應(yīng)用到數(shù)據(jù)科學(xué)是不適合的. 數(shù)據(jù)科學(xué)需要它自身獨有的版本系統(tǒng), 以至于數(shù)據(jù)科學(xué)家和數(shù)據(jù)工程師能夠更好的協(xié)作, 測試, 共享和復(fù)用.
目前,雖然我們看到了一些進展,, 但是數(shù)據(jù)科學(xué)領(lǐng)域的版本控制系統(tǒng)仍然相對不成熟, 并且擁有大量的優(yōu)化空間, 在這篇blog剩下的部分, 我將討論數(shù)據(jù)科學(xué)領(lǐng)域獨有的版本策略.
版本策略
重復(fù)性
數(shù)據(jù)科學(xué)的指導(dǎo)原則是人們能夠輕松地看到和復(fù)制彼此的工作。Cookiecutter Data Science有一段很好的評論
A well-defined, standard project structure means that a newcomer can begin to understand an analysis without digging in to extensive documentation. It also means that they don’t necessarily have to read 100% of the code before knowing where to look for very specific things.(定義明確的標(biāo)準(zhǔn)項目結(jié)構(gòu)意味著新手可以理解分析,而無需深入了解大量文檔。 這也意味著在知道在哪里尋找非常具體的東西之前,他們不一定必須閱讀100%的代碼。)
重復(fù)性要求對于每個結(jié)果,跟蹤它的生成方式,以及所包含的隨機性的分析,記下底層的隨機seeds。 所有自定義腳本都需要進行版本控制。
需要意識到的一件重要的事情是為了確保數(shù)據(jù)科學(xué)的復(fù)用性, 我們不僅僅需要在類似GitHub, Bitbucket, and GibLab等平臺上備份相應(yīng)的代碼, 同時需要對相應(yīng)的數(shù)據(jù)以及模型進行版本控制.
數(shù)據(jù)版本化
相比代碼, 通常, 數(shù)據(jù)因為它的大小因素很難進行版本控制. 當(dāng)數(shù)據(jù)在GB范疇內(nèi), 應(yīng)該感到為之慶幸, 因為在大數(shù)據(jù)時代, 通常數(shù)據(jù)規(guī)模都在TB或PB級別.
一個好的辦法是, 保留原始數(shù)據(jù)不變更, 并且至少保留一個版本的原始數(shù)據(jù).
有時, 某部分?jǐn)?shù)據(jù), 可能是經(jīng)過一個耗時且繁重的程序運行的結(jié)果, 我們可能想要將某個中間步驟中所處理的數(shù)據(jù)dump到本地. 確保標(biāo)記好生成這部分?jǐn)?shù)據(jù)的腳本和該腳本的版本. 同時盡量不要變更數(shù)據(jù)路徑, 否則其他腳本所指向的數(shù)據(jù)路徑將發(fā)生嚴(yán)重崩潰.(注, 盡量在一開始便進行相應(yīng)的文件路徑規(guī)劃).
同時, 開源或商業(yè)的數(shù)據(jù)版本控制方案也由很多, 例如, 像Amazon和Google的云供應(yīng)商, 在他們的S3 and cloud storage服務(wù), 因此數(shù)據(jù)科學(xué)家能夠從偶然的錯誤操作或者軟件故障中進行恢復(fù). 同時, Git Large File Storage是一個對于大文件的版本控制擴展, 并且它可以在本地服務(wù)器進行部署. 但要記住的一件事是,更改原始文件并保存更新版本可以輕松地在版本控制系統(tǒng)中使用你的磁盤(假設(shè)你有一個5GB的文件,更改1個字節(jié)也會從硬盤再消耗另外的5GB)。
模型版本化
模型也應(yīng)該不可變更. 模型因為特征工程, 參數(shù)調(diào)優(yōu), 新數(shù)據(jù)的增加會導(dǎo)致其版本呈現(xiàn)指數(shù)式增加.因此在版本控制中需要更多細(xì)節(jié)。通常,遵循以下規(guī)則將是不錯的選擇:
- 指定模型的名稱,版本和訓(xùn)練腳本。 擁有統(tǒng)一的命名約定, 例如
(時間)-(模型名稱)-(模型版本)-(訓(xùn)練腳本ID) - 確保具有唯一的文件名(避免重寫)
- 擁有一個全局json文件去存儲模型名稱和分?jǐn)?shù)映射, 例如,
{'model name' : (training score, validation score, test set scores)} - 擁有一個腳本根據(jù)不同的標(biāo)準(zhǔn)(例如測試集評分)去轉(zhuǎn)換模型, 并且根據(jù)標(biāo)準(zhǔn)去清理legacy模型(例如根據(jù)標(biāo)準(zhǔn)低于x%或者未服務(wù)于某一年中的某一月).
Notebook版本化
Notebook是數(shù)據(jù)科學(xué)工作不可或缺的一部分,我們需要它來分享結(jié)果(特別是探索階段的圖表和發(fā)現(xiàn))。

雖然Notebook是JSON格式, 但是對于版本控制來說卻非常不易. 具體, 有以下方式可以解決這個問題:
除去notebook的輸出. 可以很容易手動去除Notebook輸出單元格中的內(nèi)容, 或者使用例如
nbstripout庫通過編程方式實現(xiàn).重構(gòu)好的部分. 不要使用重復(fù)的代碼, 數(shù)據(jù)科學(xué)家不應(yīng)該使用不同notebooks去處理相同的任務(wù). 假設(shè)我們需要去讀入
.csv文件, 并且將所有的非數(shù)值列進行編碼處理. 在Notebook中, 我們可以看到類似的代碼:
import pandas as pd
df = pd.read_csv('path/to/data')
### code block ###
for c in df:
if df[c].dtype == 'object':
df[c] = df[c].factorize()[0]
##################
相比粘貼復(fù)制代碼段到新的Notebook中, 我們應(yīng)該構(gòu)建一個utils.py文件, 重構(gòu)腳本為一個函數(shù), 并且在下次使用時,導(dǎo)入該函數(shù).
# uitls.py
def encode_object_col(df):
# put code block here
# johndoe-eda-2017-02-30.ipynb
import pandas as pd
from utils import encode_object_col
df = pd.read_csv('path/to/data')
df = encode_object_col(df)
為了更好, 我們可以增加一些處理步驟, 例如處理缺失值, 分割數(shù)據(jù)等等, 我們可以使用另一個類似管道的函數(shù)來調(diào)用所有重構(gòu)函數(shù),將每個步驟作為二進制或閾值進行參數(shù)化并將它們鏈接在一起:
# utils.py
def make_data_for_ml(*params):
... # read in data and process step by step
# johndoe-eda-2017-02-30.ipynb
from utils import make_data_for_ml
X_train, X_test, y_train, y_test = make_data_for_ml(*params)
重構(gòu)雖好, 但是大部分人包括我自己會經(jīng)常忽視這個工作(因為重構(gòu)需要耗費時間和精力). 但是長期不重構(gòu), 只會使得數(shù)據(jù)工程越來越亂, 并且更難管理. 因此, 無論何時, 將重構(gòu)的想法根植于心, 盡可能的使Notebook文件中的代碼盡可能保持高利用度,同時利用VCS在腳本中對相對較低級別的代碼進行版本控制。
最后, 我想說的是對于notebook文件的命名習(xí)慣問題. 因為他們通常是探索性腳本, 我們可能需要多次打開他們(因此就涉及到一個搜索相應(yīng)notebook的問題). 常用的命名模式是(日期-作者-主題.ipynb), 因此我們可以通過以下方式搜索:
- 時間(
ls 2017-01-*.ipynb) - 作者(
ls 2017*-johndoe-*.ipynb) - 主題(
ls *-*-feature_creation.ipynb)
所有字段當(dāng)然都需要遵循一個共同的標(biāo)準(zhǔn)(2017-01-30或01-30-2017,JohnDoe,JDoe或jd)。
其他版本控制策略
設(shè)置分支借鑒于軟件工程,分支可用于多用戶和多階段情況下的數(shù)據(jù)科學(xué),其中典型的數(shù)據(jù)科學(xué)階段(采集,EDA,特征工程等)可以跨越多個分支。
設(shè)置虛擬環(huán)境安裝所有的軟件或package相當(dāng)耗時, 并且還需要隨著時間對其進行升級, 因此一個好的想法是, 測試或者整合虛擬環(huán)境進入你的版本控制系統(tǒng). 例如使用Data Science Toolbox, Virtualenv, Anaconda, or even Docker container去構(gòu)建一個統(tǒng)一的環(huán)境.
JSON化超參數(shù)無論在腳本中放置參數(shù)多么誘人,都不要這樣做。而是將它們放入全局JSON文件中, 如果創(chuàng)建了種子,也將它們放在此文件中。更好的是,將模型得分JSON文件與此結(jié)合起來,這樣您的數(shù)據(jù)項目就會有一個參考來跟蹤機器學(xué)習(xí)模型的性能,不同的參數(shù)設(shè)置如何影響性能,以及模型如何隨著時間的推移而發(fā)展。
創(chuàng)建域知識流 經(jīng)常被忽視或者至少是管理不善的一件事是領(lǐng)域知識的版本化。 數(shù)據(jù)科學(xué)的一個關(guān)鍵部分是領(lǐng)域?qū)S屑夹g(shù),它的使用程度如何影響數(shù)據(jù)結(jié)果的質(zhì)量。 而不是使用Excel或Word來跟蹤SME的研究結(jié)果或筆記,而是在版本控制系統(tǒng)中創(chuàng)建專用流。
數(shù)據(jù)科學(xué)版本化方案
就像用于軟件開發(fā)的VCS一樣,我們面臨著兩種數(shù)據(jù)科學(xué)版本化的選擇:托管方案和本地方案。 然而,數(shù)據(jù)科學(xué)版本化有點不同,因為數(shù)據(jù)和模型隱私和合規(guī)性有時會使事情復(fù)雜化,因此托管解決方案不是一種選擇。
在大多數(shù)情況下,Github或Bitbucket等托管服務(wù)以及云存儲(S3或Google云存儲)將為大多數(shù)數(shù)據(jù)科學(xué)版本打下基礎(chǔ)。 如果公司不希望他們的任何數(shù)據(jù)(甚至加密數(shù)據(jù))位于其他人的磁盤中,他們可以在本地服務(wù)器上設(shè)置Git和Git大文件存儲或其他分布式文件系統(tǒng)(如HDFS)來實現(xiàn)相同的目標(biāo)。
無論我們選哪種方案,都需要集中式版本控制系統(tǒng)。 以下是一些不錯的方案:
數(shù)據(jù)版本控制(DVC)DVC是一個新的開源項目,通過自動構(gòu)建數(shù)據(jù)依賴圖(DAG)使數(shù)據(jù)科學(xué)可重現(xiàn)。 它與Git,AWS S3,Google Storage集成,允許從單個DVC環(huán)境中單獨共享代碼和數(shù)據(jù)。

Pachyderm另一種選擇是Pachyderm,一種用于生產(chǎn)數(shù)據(jù)管道的工具。 在Docker和Kubernetes的基礎(chǔ)上,Pachyderm可以在本地安裝并部署在AWS, GCP, Azure, and more.等上。
Cookiecutter Data Science第三種選擇是Cookiecutter Data Science,它具有邏輯的,合理標(biāo)準(zhǔn)化但靈活的項目結(jié)構(gòu),用于執(zhí)行和共享數(shù)據(jù)科學(xué)工作。 它將為數(shù)據(jù)科學(xué)項目創(chuàng)建一個目錄結(jié)構(gòu)(模板),并為您的數(shù)據(jù)流構(gòu)建一個DAG。 也可以在本地安裝。
Luigi由Spotify構(gòu)建的Luigi是一個Python模塊,可幫助您構(gòu)建批處理作業(yè)的復(fù)雜管道。 它處理依賴項解析,工作流管理,可視化等。它還內(nèi)置了Hadoop支持。查看源代碼了解更多信息。
Further Reading
How to Version Control your Machine Learning task (Towards Data Science) – “A component of software configuration management, version control, also known as revision control or source control, is the management of changes to documents, computer programs, large web sites, and other collections of information. Revisions can be compared, restored, and with some types of files, merged.”
Version Control for Data Science (DataCamp) – “Keeping track of changes that you or your collaborators make to data and software is a critical part of any project, whether it’s research, data science, or software engineering. Being able to reference or retrieve a specific version of the entire project aids in reproducibility for you leading up to publication, when responding to reviewer comments, and when providing supporting information for reviewers, editors, and readers.”
Managing and versioning Machine Learning models in Python (SlideShare) – “Practical machine learning is becoming messy, and while there are lots of algorithms, there is still a lot of infrastructure needed to manage and organize the models and datasets. Estimators and Django-Estimators are two python packages that can help version data sets and models, for deployment and effective workflow.”
Data Version Control: iterative machine learning (KDnuggets) – “Today, we are pleased to announce the beta version release of new open source tool — data version control or DVC. DVC is designed to help data scientists keep track of their ML processes and file dependencies. Your existing ML processes can be easily transformed into reproducible DVC pipelines regardless of which programming language or tool was used.”