用于大數據的嵌入式分析和統計已經成為了業內一個重要的主題。隨著數據量的不斷增長,我們需要軟件工程師對數據分析提供支持,并對數據進行一些統計計算。本文概要地介紹了嵌入式數據分析和統計的相關工具及類庫,其中包括獨立的軟件包和帶有統計能力的編程語言。我期待著收到本專欄讀者和潛在的專欄作者的反饋,告訴我你們對這個專欄的想法,以及你們想要了解哪些相關技術。—Christof Ebert
不管在信息技術界還是嵌入式技術界,大數據都已經變成了非常關鍵的概念。1 這樣的軟件系統通常都有眾多的異構連接,包括軟件應用程序、中間件和傳感器之類的組件。隨著云設施的使用不斷增長,可用的數據資源變得更加豐富了;智能電網、智能車輛技術、醫藥最近都出現了這種相互連接的數據源。我們每年生產的數據將近1,200艾字節,并且這一數字有增無減。2,3 這樣海量的非結構化數據是業務和IT主管無法回避的巨大挑戰。
大數據的定義由四個維度組成:數據量、數據源的復雜度、生產速度,以及潛在用戶數。這些數據需要被組織起來,將無數的位和字節轉換成可操作的信息—除非我們能提煉出其中的含義,否則數據再豐富都沒用。在以前,程序員是寫代碼的,而統計學家是做統計的。程序員一般用通用的編程語言,而統計學家一般用專門的程序完成自己的日常工作,比如IBM的SPSS (用于社會科學的統計軟件包)。統計學家擺弄的國家統計數據或市場調研通常只有選定人群能用,而程序員處理的大量數據都是放在數據庫或日志文件中的。從云到幾乎所有人都可用的大數據改變了這一切。
隨著數據量和數據類型的不斷增加,越來越需要軟件工程師參與進來對它們做不同的統計分析。軟件工程師積極地以前所未有的規模收集和分析數據,讓它們變得有價值,拓展新的業務模型。1 比如說,考慮一下主動性維護。我們可以持續地對機器、網絡進行監測,一旦發現違規和失效,則立即處理,從而讓我們可以在破壞發生或系統癱瘓之前糾正它們。這可以從材料成本以及人工介入兩方面降低維護成本。處理數據并找出其中的含義通常只是一個大項目中的一部分工作,或者只是嵌在某些軟件中,配置中,或硬件優化問題中。幸運的是,大數據社區已經對這種需求作出了響應,他們創建了一系列的工具,可以將統計學家的一些魔力交給程序員—實際上,這些工具通常要比傳統的統計工具更強大,因為它們能處理的數據量在規模上要比老的統計樣本幅度更大。
用于嵌入式分析和統計的技術
可以執行統計分析的軟件有很多;表一給出了一些最流行的軟件。它們的區別在于用戶對它們統計復雜度的要求,易用性,以及它們是獨立的軟件包,還是帶有統計能力的編程語言。
表一中有三項很值得我們注意:R、Python、D3 (數據驅動文檔Data- Drives-Documents)。R是一門面向統計的語言。Python是一門通用的編程語言,并且已經證實在科學家和研究人員中間很流行,他們會用它作科學及統計計算。D3是一個JavaScript庫,用戶可以用它創建可視化圖形,并使用Web瀏覽器與之交互(比如放大、縮小、收起和展開) 。R、Python和D3都非常適用于嵌入式統計,有幾個原因:
因為它們是獨立的編程語言,可以輕松地通過標準語言機制跟其它系統交互,或者也可以通過導入及導出各種格式的數據。
Python和R中的腳本可以直接嵌入到更大的分析工作流中。
Python和R程序可以直接用來構建應用程序,這些應用程序可以從各種數據源讀取數據,用戶可以直接通過Web跟這些應用程序做數據分析及可視化的交互。
借助D3,用戶可以通過Web瀏覽器交互式地操作統計圖形,將分析提升到更高水平。
它們比專業的統計包更靠近程序員的思維框架。
除了D3,這個表中的所有東西都提供了進行高級統計(比如多元和時間序列分析)的設施,或者自身具備,或者通過類庫實現。盡管其中的每一個都有側重點,更適合解決特定的目標問題。比如Python的Pandas包,善于支持時間序列分析,因為它就是為了對財務數據做這樣的分析而寫的。
Python的統計生態系統
現如今用來做統計的最流行的通用編程語言就是Python。在科學計算方面它總是受到青睞,還有幾個優秀的Python工具可以用來完成更復雜的統計任務。Python中的基本科學庫是NumPy。它對Python的主要貢獻是一個同構的多維數組,可以用來放操作數據的方法。它可以集成C/C++和Fortran,還有幾個函數可以用來執行高級的數學及統計計算。它內部主要用的是自己的數據結構,用本地代碼實現,所以在NumPy中執行的矩陣計算比在Python中執行相同的計算快得多。構建在NumPy 之上的SciPy,提供了一些高層的數學和統計函數。SciPy再次處理了NumPy的數組;這些數組雖然很適合做數學計算,但處理可能會有缺失值的異構數據時有一點繁瑣。為了解決這個問題,Pandas提供了靈活的異構數據結構,很容易索引、切片,甚至合并和連接(類似于SQL表之間的連接)。 引入iPython是個很吸引人的設置,它是一個交互式的Python shell,有命令行補足、很好的歷史記錄,以及很多其它特性,在操作數據時特別有用。然后還可以用Matplotlib對結果可視化。
舉例說明
世界銀行是一個信息寶庫,并且它的很多數據都可以通過Web訪問。對于更復雜的分析,公眾可以從世界銀行的數據目錄下載數據,或通過API訪問它。最受歡迎的數據集是世界發展指標(WDI)。根據世界銀行的說法,WDI包含“最新、最準確的全球發展數據,包含國家、地球和全球的估算。” WDI有兩種可下載的格式:Microsoft Excel和逗號分隔值(CSV)文件。 (因為 Microsoft Excel文件不適合編程分析,所以我們在這里處理的是CSV文件。)
圖1.計算世界發展指標相關性的Python程序。這個程序采集了最前面30個測量最多的指標,計算斯皮爾曼相關系數,并用圖形顯示結果。
WDI CSV包是一個42.5M的壓縮文檔。下載并解壓后,你會見到主文件WDI_Data.csv。獲得該文件內容概覽的好辦法是交互地檢查它。因為我們要用Python,所以跟我們要用的那些工具交互的最好辦法是發起一個iPython會話,然后加載數據:
In [1]: import pandas as pd
In [2]: data = pd.read_csv(“WDI_Data.csv”)
結果在data中,一個包含數據的DataFrame。你可以把DataFrame看作一個二維數組,有一些易于操作的額外功能。在一個DataFrame中,數據被組織為幾列和一個索引 (與行對應)。如果我們輸入
In [3]: data.columns
我們會得到顯示列名的輸出:國家名、國家代碼、指標名、指標代碼。這些后面都跟著從1960到2012年每年的數據列。類似的,如果我們輸入
In [4]: data.index
我們會看到數據有317,094行。每一行都對應一個國家一個特定指標從1960到2012年的值;一行中沒有值的年份表明那一年在那個國家中沒有測量這一指標。我們先看一下有多少指標
In [5]: len(data[‘Indicator Name’].unique())
Out[5]: 1289
然后看一下有多少國家
In [6]: len(data[‘Country Name’].unique())
Out[6]: 246
現在我們有一個要解決的問題:這些指標是彼此獨立的,還是其中有些相互關聯?
因為我們是按年份和國家測量的指標,所以我們必須確定讓哪個參數保持恒定,從而更精確地定義這個問題。一般而言,當樣本增加時,我們會得到更好的統計結果。然后重新表述這個問題就變得有意義了:哪一年的測量結果最多,測量最多的指標是獨立的,還是其中一些彼此相關?所謂“測量最多的指標”,是指那些在更多國家中測量的指標。事實證明,我們可以在大約50個LOC中找到問題的答案。圖一中是完整的程序。
代碼1–10行導入了我們將要用到的庫。第11行讀取數據。在第13行中,我們給出了一個數值,這是我們要檢查的測量最多的指標的個數。在第15行,我們找到了從0開始的帶有年度測量值的第一列。在那之后,我們可以在第17行找到有最多測量值的那一列(2005年)。然后我們去掉了沒有那些測量結果的所有數據。在第20到26行,我們獲取了測量最多的指標。
真正的統計計算從第28行開始,我們準備了一個表,用來存放每對指標相關性的結果值。在接下來的循環中,我們計算每對指標的相關性,并把它放在之前準備好的表中。最后,在第41到52行,我們把這些結果顯示在屏幕上,并保存為一個PDF文件(見圖二)。我們還把相關矩陣的垂直順序做了反向處理,以便讓最重要的指標出現在矩陣的頂部(代碼41和49行)。
對角線上有完美的相關性—理應如此,因為那里檢查的是相同的指標。除此之外,我們的確看到了有些指標之間有相關性—有些是正相關的,甚至很強,也有些是負相關或者非常的負相關。
圖2. 圖一中的Python程序創建出來的世界發展指標相關矩陣。
Python生態系統中更高級的組件
因為Python受到了科研界的青睞,一些專業化的工具也隨之出現。其中有構建在NumPy、SciPy和matplotlib之上的Scikit-learn,它提供了完備的機器學習工具包。對于符合層級結構的超大型數據集,Python提供了PyTables,它以HDF5 庫為基礎。這是一個行業熱點, DARPA 在2013年從XDATA項目基金中拿出300萬美元給Continuum Analytics作為獎勵,讓它進一步推進Python數據分析工具的開發。可以預料到的是接下來的幾年這個生態系統仍將穩步發展。
用于統計計算的R項目
R是做統計的語言。可以這么說,Python讓做統計變成了程序員的活,而R讓寫程序變成了統計人員的任務。這門語言的中心是有效操作表示統計數據集的對象。這些對象通常是向量、列表,和表示按行和列組織的數據集的數據幀。R有常用的流程控制結構,甚至用到了面向對象編程的思想(盡管它的面向對象實現跟我們在更傳統的面向對象語言中的概念有很大差別)。R的卓越之處在于它所提供的各種統計類庫。R的類庫中幾乎實現了所有的統計測試或方法(然而在Python中,有時你可能會發現你必須推出自己的實現)。為了讓你明白它看起來是什么樣的,圖三給出了一個跟圖一一樣的程序,相同的邏輯,但實現用的是R而不是Python。圖四是結果。
圖3. 用R實現圖一中那個計算世界發展指標相關性的程序。
組合、聯合、整合嵌入式分析技術
我們在本文中給出的例子是不同應用程序合并到一起處理大數據的典型辦法。數據從源頭(以某種原始格式)流向我們的統計包可接受的格式。統計包必須有一些能夠操作和查詢數據的辦法,以便我們能取得想要檢查的數據子集。這些都是統計分析必須有的。統計分析的結果可以用文本格式或圖形渲染出來。我們可以在本地計算機上執行這一處理,也可以通過Web完成(此時數據的運算和處理是由服務器執行的,參數、結果和圖形要通過Web瀏覽器)。這是一個很強大的概念,因為許多不同的設定,從ERP框架到汽車診斷軟件,都可以將數據導出為CSV這樣簡單的格式—實際上,當我們遇到一個不允許導出任何東西,封閉并且有專有數據格式的軟件時,應該視作是一種警告。
要想按你想要的方式分析數據,你必須首先能夠訪問到它。所以你應該通過各種手段選擇那些可以促進數據交換的技術,或者通過簡單的導出機制,或者通過適當的調用,比如通過一個REST(表述性狀態轉移)API。
數據一直在變大,所以你必須進行調研,看你正在考慮的工具能否勝任你的數據處理工作。你沒必要在主存中處理所有數據。比如說,R有一個 大內存 庫,讓我們用共享內存和內存映射文件處理超大數據集。還有,要確保軟件包不僅能處理大量輸入,還要能處理大型數據結構:比如說,如果表的大小被限定在32位整型之內,你就不能處理有5百萬條記錄的表。
在上面的例子中,警覺的讀者可能已經注意到了,我們將數據變成適于統計分析的格式所用的代碼,要比統計分析本身的代碼還多,不管怎么說,那是由已經寫好的函數做的。我們的例子有點兒小,所以預處理和真正的處理兩者的比例可能尤其顯得頭重腳輕,但這個例子也表明了這一事實,即數據操作通常和數據分析同樣重要(和苛刻)。實際上,R和NumPy/SciPy 真正的實力并不在于它們掌握了統計算法,而是在于它們知道如何有效地處理它們提供的數據結構。并且這基本上是程序員的工作,不是統計學家的。別處還有更深入的資源可供閱讀。