關于數據科學,書上不曾提及的三點經驗

這是數據科學大行其道的時代。各類課程、博客、培訓學校如雨后春筍般出現。然而,每次我瀏覽這些學習資料時,我發現它們過于強調一些具體的算法。理解邏輯回歸或者深度學習的原理當然很酷,可是一旦從事數據相關工作,你會發現還有其它一些同樣重要的事情,甚至更為重要的。
我真不應該去責備這些課程。我在大學任教機器學習課程很多年了,課堂上主要是講解具體算法。你掌握了支持向量機(SVM)、高斯混合模型(GMM)、k均值(k-Means)聚類等算法的細枝末節,但是直到寫碩士論文的時候才學會如何正確地處理數據。
那么何謂正確?最終結果難道不能驗證處理方法嗎?得到出色的預測效果是否意味著一切順利呢?顯然沒錯,但關鍵是確保算法在未來數據上仍舊得到出色的效果。我在別處也寫過,如果僅憑著訓練數據的表現就輕信自己的算法,實在是太自欺欺人了。
那么下面是我的三個主要見解,其它書本里很少提及。
1、評價方法是關鍵
數據分析/機器學習/數據科學(或者無論你如何稱呼它)的主要目標就是搭建一套系統并且將來在測試數據上效果好。監督式學習(例如分類)和非監督式學習(例如聚類)的差異導致很難籠統地解釋它,但無非都是你收集一個數據集合,在其之上搭建系統和設計算法。但最終你需要將這種算法應用于未來的數據,同時希望確保在新數據上的表現和在原始數據集上的表現幾乎一樣好。
初學者常犯的錯誤就是僅僅關注手頭數據集上的表現效果,然后認為在未來數據上同樣奏效。不幸的是這種情況非常稀罕。我們暫且以監督式學習為例,它的目標是根據你的輸入預測輸出結果,比如把郵件分為垃圾郵件和正常郵件兩類。
如果你只考慮訓練集數據,那么機器很容易記住整個訓練集,然后返回完美的測試結果(除非數據自相矛盾)。事實上,對人來說這種情況也很正常。還記得你在學外語背單詞的時候,總是把單詞順序打亂來測試嗎?因為否則大腦就會憑著之前單詞的順序來回憶。
機器憑借它們存儲和讀取大量數據的強大能力,輕而易舉地完成同類的任務。這就造成過擬合現象,還缺乏泛化能力。
因此合適的評價方法是模擬有未來數據的場景,把數據集一分為二,一部分做訓練集,然后在另一部分測試集數據上做預測。通常,訓練集被分得大一些,這個過程也會重復很多遍以得到一系列測試結果,來觀察算法的穩定性。這整個過程就稱為交叉驗證。

為了模擬在未來數據上的性能,,你需要把現有的數據一分為二,一份用來訓練模型,另一份僅用于模型評估。
然而,差錯還是會時常發生,尤其當數據集是非靜態的,也就是說,數據的分布隨著時間而發生變化。現實世界的數據往往如此。一月份的銷售圖表和六月份的看上去會迥然不同。
或者數據點之間相關性很高,就是說若你知道一個數據點,那另一個樣本數據的信息也八九不離十了。打個比方,拿股票價格來說,天與天的波動并不劇烈,那么以天為單位隨機切分訓練/測試數據集會導致訓練集和測試集的數據高度相關。
上述情況一旦發生了,你就會得到過度優化的結果,而這個算法在真實測試數據上的表現并不盡如人意。在最壞的情況下,你費盡精力說服別人采用你的算法,而算法卻失效了,因此學會正確地評估模型是關鍵!
2、特征提取是根本
學習一種新算法令人激動,可事實上大多數復雜算法的效果大同小異,真正造成差異的是原始數據如何轉化為用以學習的特征這個步驟。
現代學習算法十分強大,處理上萬維的特征和幾十萬的樣本都是小菜一碟,然而事實卻是這些算法最后來看都是愚蠢的。尤其是那些學習線性模型的算法(如邏輯回歸,線性支持向量機)簡直和計算器一般簡陋。
它們從足夠的數據樣本里鑒別出有效信息的本領很強大,但如果有效信息并不被包含其中,或者不能用輸入特征的線性組合所表示,它們就沒有了用武之地。它們本身也無法通過“洞察”數據來完成數據精簡這一環節。
換句話說,如果找到合適的特征,數據量就能被大大縮減。理想情況下,如果把所有特征縮減到只剩下你想預測的方程,那就沒什么可學習的了,對吧?這就是特征提取的強大之處!
需要提醒兩點:首先,你必須確保完全理解這些等價算法中的一種,然后就可以一直用下去了。因此你并不真的需要邏輯回歸加上線性SVM,選一種就夠了。這還包括明白哪些算法幾乎是等價的,使用這些模型的關鍵點在哪里。深度學習有些區別,但是各種線性模型的表達能力幾乎一樣。盡管,訓練時間、解的稀疏性等會有差別,但大多數情況下它們的預測能力是相近的。
其次,你必須完全掌握特征工程。不幸的是,這更像是一門藝術,而且因為理論不完善書本里很少提及。特征值歸一化是一條捷徑。有時候,特征值需要取對數計算。若是能夠降低一部分自由度,也就是說去掉數據中對預測結果沒影響的那部分變量,你所需要訓練的數據量將會大大降低。
有時候這些轉換很容易被發現。例如,如果你要做手寫字符識別,只要有前景和背景的區分,那么字符的顏色對識別顯然是不重要的。
我知道課本總是推銷一些看起來很強大的算法,似乎只要你把數據扔給它們就萬事大吉了。從理論觀點和無窮的數據來源角度來說,這也許是正確的。但現實中,數據和我們的時間是有限的,尋找高信息量的特征絕對是至關重要的。
3、時間瓶頸是模型選擇,而非數據集規模
這是個在大數據時代你不愿大肆提及的事物,可是大多數數據集都能被完全加載到主存里。你的算法同樣可能也不需要消耗太多時間計算。但你需要花費大量時間從原始數據中提取特征,通過交叉驗證來比較不同特征提取方法和不同算法參數的效果差異。

在選擇模型時,你嘗試無數次各種參數的組合,并在相同的數據集上評價效果差異。
問題歸根結底在于組合項的爆發式增長。假設現在只有兩個參數,并且訓練模型和在測試集上評價效果(按照上述正確的評價方式)需要大約一分鐘時間。如果每個參數有5個候選值,采取5折交叉驗證(把數據集分成5份,重復訓練測試過程5次,每次用不同的一份數據作為測試集),這意味著你需要125輪計算來確定哪種算法效果最好,你的等待時間也將是大約2小時而不是1分鐘。
一個好消息是上述過程很容易并行化,因為每輪計算都是相互獨立的。特征提取也是如此,通常也是對每個數據集獨立地進行相同操作(解析、提取、轉換等),導致了所謂的“密集并行”(沒錯,這是個專業術語)。
一個壞消息主要針對大數據而言,因為所有的這些意味著對大規模實現復雜算法的需求很少,然而多數情況下目前用非分布式算法并行計算內存中的數據已經很有幫助了。
當然,也存在一些應用,比如針對廣告優化的TB級日志的全局模型和百萬用戶級推薦系統,但常規的使用案例都是這里羅列的那些類型。
最后,擁有大量數據也不意味著你真的需要這么多。關鍵在于學習過程的復雜度。如果問題用簡單的模型可以解決,就不要用過多的數據來訓練模型參數。那樣的話,隨機抽樣數據集的一部分就足夠用了。另外如我在上文中提到的那樣,有時候準確的特征表達也能大幅度削減需要的數據量。
總結
總之,知道如何正確評價結果能降低算法在未來測試數據上失敗的風險。特征提取準確也許是提升效果的最佳途徑,最后,大數據并不總是需要,盡管分布式計算能幫助減少訓練時間。



