機器之心報道
機器之心編輯部
每年千萬下載量,科學(xué)計算開源庫 SciPy,你已經(jīng)是個成熟的小伙伴了。
作為科學(xué)計算中的中流砥柱,SciPy 從 2001 年到現(xiàn)在已經(jīng)走過了十九個年頭,它為最優(yōu)化、積分、微分方程等各種數(shù)值計算提供了完整的流程,也為科研分析人員提供了最好用與高效的開源庫。
前天 2 月 3 日,SciPy 的維護者在 Nature Methods 上發(fā)表了一篇論文,其回顧了 SciPy 發(fā)展的里程碑與關(guān)鍵技術(shù)。并借助 SciPy 1.0 這個成熟的象征,展現(xiàn)了當(dāng)前科學(xué)計算以及未來發(fā)展方向都是什么樣的。
- 論文地址:https://www.nature.com/articles/s41592-019-0686-2
- SciPy 項目地址:https://github.com/scipy/scipy
為什么 SciPy 那么重要?
SciPy 是一個面向 Python 的開源科學(xué)計算庫。自 2001 年首次發(fā)布以來,SciPy 已經(jīng)成為 Python 語言中科學(xué)算法的行業(yè)標(biāo)準(zhǔn)。該項目擁有超過 800 個獨特的代碼貢獻者,數(shù)以千計的相關(guān)開發(fā)包,和超過 150,000 個依賴存儲庫以及每年數(shù)以百萬計的下載量。在下述簡介中,會概述 SciPy 1.0 的功能和開發(fā)實踐,并著重闡述一些最新的技術(shù)發(fā)展與更新。(注:數(shù)據(jù)更新來自 Github 最新反饋)
SciPy 是一個基于 Python 和 Numeric 的開源代碼包,當(dāng)前模塊集包括了上圖中的內(nèi)容。
項目覆蓋范圍
SciPy 提供了科學(xué)計算的基本算法,這些算法涵蓋了現(xiàn)有數(shù)學(xué)軟件分類系統(tǒng)中的算法。在迭代相對緩慢的領(lǐng)域(如:線性代數(shù)),SciPy 旨在提供完整的算法覆蓋。
而在其他領(lǐng)域,它提供基本的構(gòu)件,并與該領(lǐng)域的其他軟件包進行良好的互動于兼容。例如,SciPy 提供了人們期望在統(tǒng)計學(xué)教科書中能找到的基本算法(概率分布、假設(shè)檢驗、頻率統(tǒng)計、相關(guān)函數(shù)等),但 Statsmodels 提供了更先進的統(tǒng)計預(yù)估及推斷方法。雖然 scikit-learn 涵蓋了機器學(xué)習(xí),但 PyMC、emcee 和 PyStan 涵蓋了貝葉斯統(tǒng)計和概率建模等。
SciPy 能干什么
我們知道 SciPy 是一個用于數(shù)學(xué)、科學(xué)、工程領(lǐng)域的常用庫,可以處理插值、積分、最優(yōu)化、常微分方程數(shù)值解的求解、信號處理等問題。因此自然科學(xué)領(lǐng)域絕大多數(shù)涉及計算的工作都能用它來完成,例如我們熟知的統(tǒng)計學(xué)習(xí),擬合個分布、做了 K 最近鄰算法都是非常便捷的。
當(dāng)然目前新冠肺炎疫情廣受關(guān)注,研究者也可以用它模擬各種關(guān)鍵信息。例如之前中國疾病預(yù)防控制中心、國內(nèi)各省市疾控中心等機構(gòu)在新英格蘭醫(yī)學(xué)雜志發(fā)表的《新型冠狀病毒肺炎在中國武漢的早期傳播》論文。
在獲取數(shù)據(jù)之后,進行各種統(tǒng)計學(xué)分析很多都可以用 Scipy 完成,具體而言:
- 研究者根據(jù)發(fā)病日期構(gòu)建傳染曲線;
- 使用對數(shù)高斯分布擬合暴露歷史和發(fā)病日期數(shù)據(jù),估計潛伏期分布;
- 使用韋伯分布擬合發(fā)病日期、首次就診日期和住院日期,并估計發(fā)病離就診的時間間隔分布、發(fā)病離住院的時間間隔分布;
- 使用伽瑪分布擬合病例集群數(shù)據(jù),從而估計人際傳播的時間間隔(serial interval)分布。
這些分析任務(wù)主要在于利用統(tǒng)計分布擬合對應(yīng)的數(shù)據(jù),該肺炎論文的研究者采用 MATLAB 做的擬合。但實際上,scipy.status 包含了 100 多個概率分布,這些統(tǒng)計分析也能通過 SciPy 完成。
面對洶涌的疫情,不論我們是有第一手?jǐn)?shù)據(jù),還是從各網(wǎng)站爬取疫情信息,利用 SciPy 建模與分析都是非常好的選擇。
SciPy 發(fā)展里程碑
20 世紀(jì) 90 年代末期,美國梅奧醫(yī)學(xué)中心的博士生 Travis Oliphant 發(fā)布了一系列構(gòu)建于數(shù)值數(shù)組之上的包,并提供了用于信號處理、特殊函數(shù)、稀疏矩陣、正交、最優(yōu)化和快速傅里葉變換等的算法。
這些包中的 Multipack 是一組包裝了 Fortran 和 C 語言的擴展模塊,用于解決非線性方程和最小二乘問題、求微分方程的積分以及擬合曲線。
隨后,編程環(huán)境愈加豐富,也具備了適當(dāng)?shù)臄?shù)值數(shù)組對象,開發(fā)全??茖W(xué)軟件的時機成熟了。2001 年,Eric Jones 和 Travis Vaught 創(chuàng)建了 Enthought 科學(xué)計算解決方案。
之后,為了簡化工具堆棧,他們創(chuàng)建了以 SciPy 庫為中心的 SciPy 項目。該項目的發(fā)展勢頭很猛,2001 年 2 月推出網(wǎng)站和代碼庫,6 月宣布郵件列表,8 月推出了 SciPy 0.1 版。
SciPy 早期版本的文檔較少,但隨著 2006 年發(fā)布 Numpy 指南(Guide to Numpy),這種情況開始改變。2007 年,Sphinx 文檔生成器使得 SciPy 能夠從包含 Python 代碼的純文本中自動呈現(xiàn)超文本和 PDF 文檔。2008 年,Pydocweb 工具使得 SciPy 又能夠以維基百科的方式進行協(xié)作文檔開發(fā)。
在早期的 SciPy workshop 中,反復(fù)出現(xiàn)的一些主題反映了 SciPy 的開發(fā)狀態(tài),它將重心放在了底層數(shù)組包、繪圖、并行處理、加速/包裝和用戶界面上。到了 2004 年,關(guān)于 SciPy 應(yīng)用于科學(xué)計算問題上的內(nèi)容開始出現(xiàn)。
圖 1:自 2001 年發(fā)布 0.1 版到 2017 年推出 1.0 版本,SciPy 發(fā)展過程中的一些里程碑式事件。
SciPy 近三年的關(guān)鍵技術(shù)
從 2001 年發(fā)布的 0.1,到近幾年發(fā)布成熟版的 SciPy 1.0,最近三年 SciPy 在科學(xué)計算上有了更多的技術(shù)累積。我們可以用更少的算力運行更大的矩陣計算,用更精簡的方式擬合更復(fù)雜與多樣的概率分布,也可以跑一跑最新的最優(yōu)化方法。研究者在這篇論文中著重介紹了 SciPy 一路走來的關(guān)鍵技術(shù)。
數(shù)據(jù)結(jié)構(gòu):稀疏矩陣
scipy.sparse 提供了 7 種稀疏矩陣數(shù)據(jù)結(jié)構(gòu),或者稱之為稀疏格式。其中最重要的一種是壓縮行/壓縮列的稀疏格式,它們分別為 CSR 與 CSC。這兩種方法都提供了快速的主軸索引與快速的矩陣-向量乘法,這兩種稀疏格式在 SciPy 及依賴的庫中得到了廣泛的應(yīng)用。
從新特性的角度來看,scipy.sparse 矩陣與線性運算子現(xiàn)在都已經(jīng)支持 Python 矩陣乘法(@)。
cKDTree
scipy.spatial.ckdtree 模塊實現(xiàn)了空間分割的數(shù)據(jù)結(jié)構(gòu),該結(jié)構(gòu)會在 K 維空間中組織數(shù)據(jù)點。整個 cKDTree 模塊通過模板化類用 C 重寫了,并新增對周期性邊界條件的支持,它經(jīng)常用于物理過程的模擬。
2013 年,基于 cKDTree.query 的 K 最近鄰算法時間復(fù)雜度逼近了對數(shù)線性。2015 年,cKDTree 二元樹計數(shù)算法通過加強以支持加權(quán),這對于很多科學(xué)應(yīng)用來說都是非常重要的,例如計算星系的相關(guān)性函數(shù)。
統(tǒng)一捆綁到已編譯代碼:LowLevelCallable
到了 SciPy 0.19,用戶就可以直接使用 scipy.LowLevelCallable 對象包裝底層函數(shù),從而減少直接從 Python 調(diào)用已編譯 C 函數(shù)的開銷,這種編譯的 C 函數(shù)可能是由 Numba 或 Cython 生成的。
數(shù)學(xué)優(yōu)化
scipy.optimize 子包提供了數(shù)學(xué)解決方案,用于解決多種類型的「root finding」和優(yōu)化問題。
研究者在表 1 中詳細(xì)比較了所有最小化方法的特征,這些特征說明了 SciPy 如果要達到比較完整的水平,它需要涵蓋的數(shù)值方法或主題。
統(tǒng)計分布
scipy.status 包含了 100 多個概率分布:96 個連續(xù)分布和 13 個離散單變量分布,以及 10 個多變量分布。該實現(xiàn)依賴于一個一致的框架,該框架提供了抽樣隨機變量的方法,用以評估累積分布函數(shù)指數(shù)(CDF)和概率密度函數(shù)指數(shù)(PDF),并適合每一個分布的參數(shù)。
測試套件
在更改代碼時,測試驅(qū)動的開發(fā)被認(rèn)為是一種管理不確定性的方法。對于 SciPy 的每個組件,研究者都編寫了多種能夠驗證它們預(yù)期行為的可執(zhí)行小測試。這些可執(zhí)行小測試的集合被稱為『測試套件』,增強了對正確性和準(zhǔn)確度的置信度,并允許用戶在修改已有代碼時不會改變預(yù)期行為。
圖 2:不同版本 SciPy 中的 Python 和編譯代碼量。
除了保證單元測試通過之外,重要的是確保 SciPy 代碼庫的性能能夠隨時間推移而提升。比如,下圖 3 展示了在大約 9 年的項目發(fā)展歷程中,scipy.spatial. cKDTree.query 的性能提升情況。
圖 3:從 cKDTree 的提出到 SciPy 1.0 的發(fā)布,scipy.spatial.cKDTree.query 的基準(zhǔn)測試的結(jié)果。圖中的每個標(biāo)記表示 SciPy 主分支中提交的基準(zhǔn)測試的執(zhí)行時間。
SciPy 仍在路上
SciPy 項目每 6 個月進行一次更新。任何感興趣、有技術(shù)能力的開發(fā)者都可以參與貢獻代碼。雖然 SciPy 的研發(fā)成本已經(jīng)超過了 1 千萬美元,但是項目依然是沒有資金支持的。這些代碼都是由大學(xué)研究生、學(xué)術(shù)界和工業(yè)界的人們在閑暇時間完成的。
SciPy 有著一個很大的開發(fā)社區(qū),用戶基數(shù)也很龐大。在 2017 年,通過 PyPI 下載的次數(shù)是 13,096,468 次,而通過 conda 下載的次數(shù)則有 5,776,017 次。
盡管如此,SciPy 依然在繼續(xù)進步。下圖的表格是一個持續(xù)更新的文檔,描述了團隊正在項目中進行改進和提升的工作。這份文檔也提到了一些需要改進的地方。
版權(quán)聲明:本文內(nèi)容由互聯(lián)網(wǎng)用戶自發(fā)貢獻,該文觀點僅代表作者本人。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如發(fā)現(xiàn)本站有涉嫌抄襲侵權(quán)/違法違規(guī)的內(nèi)容, 請發(fā)送郵件至 舉報,一經(jīng)查實,本站將立刻刪除。