人肉工程在機器學習實踐中的作用

水石頭stone發表於2015-08-25

關於人肉工程,包括業務知識、領域知識,經驗等,在實際的機器學習問題中的應用,是一個屢見不鮮的話題,典型的有苦逼的資料清洗、人肉特徵工程等。大家都想把儘可能多的過程由機器自動完成,但是目前的狀態是,大部分機器學習問題中,最困難也最重要的部分,還是依靠人的經驗來生成特徵。那麼人的經驗為什麼重要,能否用機器完成這個過程,本文試作一簡單分析。

機器和人看待資料的區別

首先要看一下,從機器的角度看,機器學習是怎樣一個問題?在機器看來,機器學習的問題通常是在一組特徵上,最大化某個目標函式。注意,對於這組特徵而言,機器是理解不了它的含義的。舉例來說,下面一組資料(第一列是targe)

0, 1, 1, 0
1, 0, 1, 1
1, 0, 0, 1

你能看出這組資料是什麼含義嗎?顯然不能。但是完全可以用它訓練一個分類模型,比如logistic regression。

然後檢視一下關於這組資料的描述,知道這是關於某個班某次考試的結果,第一列表示物理是否及格,後面三個特徵分別是性別、文理科班、數學是否及格,那麼現在我知道這組資料的含義了。這樣又可以訓練一個logistic regression模型。問題來了,這兩個模型有區別嗎?顯然沒有。也就是說,人是如何理解資料含義的,對於演算法並沒有任何影響。因為從機器的角度看,這都是一堆數字而已。

現在看另一個例子,這裡有一個特徵是這樣的

1, …, 1431174193, …
1, …, 1431087793, …
0, …, 1431001393, …
1, …, 1430914993, …
0, …, 1430828593, …

能看出這個特徵是什麼嗎?如果你猜測這是時間(timestamp)——那麼,你已經開始使用領域知識了。對於機器來說,這只是一個整數序列而已。如果我們把這組資料代入一個線性模型,那麼意味著預設預測目標和特徵之間是線性關係。也就是說,學習演算法的假設空間僅包含timestamp的線性函式。

機器能否通過“學習”達到和人的知識相同的效果

現在,我們既然知道這是日期,就可以增加特徵,比如從日期中提取月份、星期、小時等。假設增加“小時”這麼一個特徵,注意,這個變換是非線性的,這裡使用了人的知識。對於機器而言,沒有這樣的知識。如果要求機器能自動提取出這個特徵,那麼學習演算法的假設空間至少應該覆蓋timestamp到小時的轉換函式,類似於(timestamp/3600)%24。這會增加假設空間的維度。如果知道函式的形式也還好,比如知道(timestamp/a)%b, 這樣只需要擬合a、b兩個引數。但是實際問題往往是,我怎麼知道特徵的轉換函式是怎樣的?也許是log(sin(a x)) / (exp(x) + x^2),如果要求假設空間涵蓋各種可能的函式形式,那必然大大增加假設空間的維度,很容易導致過擬合。比如神經網路,三層網路就可以逼近任意函式(有個什麼連續性還是可導條件,忘了),但是太容易過擬合了,而且存在區域性最優的問題。

所以,人的知識的作用在於特徵變換。更進一步說,如果人的知識可以給出有效的特徵變換,那麼可以大大降低搜尋空間的維度。對於線性模型而言,模型本身可以處理所有線性的情況,如果人的知識所產生的特徵變換也是線性的,那麼對於模型沒有任何提升,只有非線性的變換才對模型有影響。而如果要求模型能夠自動的學習出相同的非線性變換,則會造成模型的特徵空間維度大大提高。

而人類的知識是千萬年間積累下來的,其中包含了很多複雜的變換,而且知識之間相互依賴,如果要理解一個概念,往往需要首先理解其他的很多概念,所以,從這個意義上將,要求機器學習出人類的知識結構是不太現實的。當然,機器不必模仿人類的知識,可以學習出另外的特徵變換,只要最後的模型是有效的。所以為什麼現在的deep learning這麼火,因為它在控制過擬合的前提下,能夠在一定程度上學習出特徵變換的形式,也就是在一定程度上完成了人肉特徵工程的工作,目前大概也只有deep learning能做到這一點。不過,從目前的實踐情況來看,人的知識仍然在具體問題中起著重要的作用。

“演算法工程師”的角色和職責

基於此,可以把典型的機器學習建模過程分成三個階段:

資料清洗、預處理、特徵變換 -> 代入標準機器學習演算法 -> 將結果應用到業務問題

其中,只有中間的部分是標準化的(所以一般大家都是呼叫現成的軟體包),而兩頭的,則需要由人工完成,也就是把資料解釋、變換成機器要求的形式,以及對結果的含義做出解釋。因為機器理解不了資料的含義。

如果從這個角度看待“演算法工程師”,或者“資料科學家”之類的角色,這種職業的作用在於解釋資料,而不是演算法研究或者程式設計。機器學習演算法將會越來越標準化、平臺化,使用門檻降低,資料科學家將不再需要處理大量的程式設計細節,而是越來越類似傳統的醫療或金融行業的資料分析師,重在理解業務和資料。演算法的研究由科研人員負責,而工程細節由通用的(分散式)平臺解決。演算法工程師的重點在於資料的預處理、特徵生成以及模型選擇和引數優化,這也是和現實情況相符的。

目前機器學習的應用還處於粗放階段,要搭建一個系統,必須應付大量的程式設計細節。比如一個使用LR進行CTR預測的系統,即使使用開源的模組搭建,也往往要處理許多介面、測試和訓練集劃分、甚至資料儲存的細節。然而,這些細節都和問題的本質無關。將來,這些技術細節將被遮蔽。例如,用一種類似SQL的語言執行模型訓練過程,類似於

這段程式碼比較接近自然語言了,意思是以click為目標,以time, pos, user_id, ad_id為特徵,ad_show_dataset中2015-07-01到2015-07-31之間的資料為樣本,訓練logistic regression模型,其中隨機選擇40%作為訓練集,其他作為測試集。模型以auc為評估指標。最後將訓練出的模型以PRML格式匯出到file_path。(如果你看了上面的程式碼後不明白,還要看這段解釋,說明我的語法設計的不好。)

從更廣的範圍來說,計算機技術的發展過程,就是一個不斷降低人們使用計算機門檻的過程,用Brooks大神的話說,是“消除軟體領域的非本質性困難”。最初的程式設計師,需要寫彙編程式碼、直接處理CPU與記憶體。C語言和作業系統出現以後,程式設計門檻降低了,但是仍然免不了處理底層細節。而Java、python、php等語言出現後,程式設計門檻進一步降低,只要稍微經過一些培訓的人,都可以寫程式碼。而有關程式排程、記憶體管理、IO、快取一致性等底層細節,被少數專業化的製作編譯器、作業系統、虛擬機器等的程式設計師掩蓋。而大部分程式設計師的職責,是把業務邏輯“翻譯”成計算機聽得懂的語言。

機器學習和分散式系統也將沿著這個路線發展。少數專業化程度很高的程式設計師負責平臺開發,遮蔽技術細節,消除“非本質性困難”,使得演算法工程師或資料科學家可以專注於業務邏輯和資料含義。這個職業的性質將越來越接近產品經理,而不是工程師。工程師的技術是通用的,比如一個音樂網站的php工程師,到一個網際網路金融公司寫php,技術上沒什麼區別。而產品經理就不一樣了,因為音樂和金融的業務、使用者、商業模式有很大不同。

結論

所以,直白的說,演算法工程師的本質就是資料解釋、清洗、預處理、人肉特徵工程、引數調優等。究其根本原因,在於計算機理解不了資料的含義。如果有一天計算機能夠理解資料含義了,那就像計算機能聽懂自然語言一樣,大部分程式設計師可以下崗了。

相關文章