廣州中醫(yī)藥大學(xué)醫(yī)學(xué)信息工程學(xué)院 羅曉牧
?
淺談如何從程序開發(fā)的角度入門機(jī)器學(xué)習(xí)
廣州中醫(yī)藥大學(xué)醫(yī)學(xué)信息工程學(xué)院 羅曉牧
【摘要】機(jī)器學(xué)習(xí)是最近十分熱門的研究領(lǐng)域。本文討論了如何從程序開發(fā)的角度入門機(jī)器學(xué)習(xí),包括設(shè)計(jì)系統(tǒng)流程、使用最新的工具、針對(duì)性的練習(xí)、記錄成果等。采用自上而下的學(xué)習(xí)方法,十分適合大學(xué)本科學(xué)生、程序員的自學(xué),有效的解決端到端的問題,激發(fā)學(xué)習(xí)熱情,循序漸進(jìn)的全面掌握機(jī)器學(xué)習(xí)領(lǐng)域。
【關(guān)鍵詞】機(jī)器學(xué)習(xí);程序開發(fā);系統(tǒng)流程
機(jī)器學(xué)習(xí)最近十分火熱,尤其在Alphago 與李世石的圍棋人機(jī)大戰(zhàn)之后[1],更掀起了一股機(jī)器學(xué)習(xí)的熱潮。如何更好的學(xué)習(xí)這一領(lǐng)域的知識(shí),是不少同學(xué)的疑惑。機(jī)器學(xué)習(xí)算法的傳統(tǒng)學(xué)習(xí)路徑是從統(tǒng)計(jì)學(xué)、概率論、線性代數(shù)、微積分等多種數(shù)學(xué)知識(shí)開始的。但作為計(jì)算機(jī)專業(yè)的學(xué)生、專業(yè)程序員、機(jī)器學(xué)習(xí)愛好者,這種自下而上的方法停留在算法層面,沒有考慮到項(xiàng)目的開發(fā)和交付;同時(shí),書本上的知識(shí)通常過于數(shù)學(xué)化,公式化,理論化,令人感到枯燥。雖然網(wǎng)上也已經(jīng)有不少視頻公開課,如Coursera [2]上面的機(jī)器學(xué)習(xí)公開課,但是內(nèi)容與教科書、博客差不多,沒有將相關(guān)的知識(shí)融會(huì)貫通到一起。有沒有更適合初學(xué)者的方法呢?在本文中,將探討如何學(xué)習(xí)這一領(lǐng)域。
打開任意一本與機(jī)器學(xué)習(xí)相關(guān)的書籍,一般都會(huì)從問題的定義開始,然后到概念和算法的數(shù)學(xué)描述,復(fù)雜性不斷增加。概念的定義與數(shù)學(xué)描述是十分清晰和簡(jiǎn)潔的,然而要對(duì)它們充分的掌握,則需要相關(guān)的數(shù)學(xué)背景去理解[3]。這也是為什么機(jī)器學(xué)習(xí)課程通常在研究生階段才開設(shè)的原因。因?yàn)橐虝?huì)某一特定科目的前提是需要足夠的先修課程。例如,通常需要對(duì)以下科目具有良好的基礎(chǔ):統(tǒng)計(jì)、概率、線性代數(shù)、多元統(tǒng)計(jì)學(xué),微積分等等。這種自下而上并且以算法為導(dǎo)向的學(xué)習(xí)方法,在機(jī)器學(xué)習(xí)領(lǐng)域相當(dāng)主流。不少的網(wǎng)絡(luò)論壇上,對(duì)于“如何開始機(jī)器學(xué)習(xí)”的問題,通常也是會(huì)得到類似的答案[4]。各種在線課程和公開課,也都是模仿學(xué)校的方法去進(jìn)行教學(xué)。如果你已經(jīng)有相當(dāng)?shù)膶W(xué)術(shù)背景,或已經(jīng)具有碩士或博士學(xué)位,這種方法是不錯(cuò)的選擇。然而,對(duì)于一般的程序開發(fā)者,這樣的方法并不可取。這會(huì)讓腳踏實(shí)地的軟件工程師覺得應(yīng)該重回學(xué)校,獲得一個(gè)碩士或博士學(xué)位,然后才有資格去“做”機(jī)器學(xué)習(xí)。
這種自下而上的學(xué)習(xí)方法是錯(cuò)誤的。為什么呢?假設(shè)你是一個(gè)年輕的軟件開發(fā)人員,已經(jīng)學(xué)會(huì)了某種編程語言,并開發(fā)出一些單機(jī)版的軟件。當(dāng)你告訴你的朋友和家人,想以每天編程作為職業(yè),那么他們通常會(huì)告訴你,你需要在計(jì)算機(jī)科學(xué)方面取得一個(gè)學(xué)位,才有可以得到一份程序員的工作。然后,你就開始注冊(cè)和修讀計(jì)算機(jī)學(xué)位。幾個(gè)學(xué)期之后,你已經(jīng)接觸到越來越多復(fù)雜的代數(shù)、微積分和離散數(shù)學(xué)。但你正在使用過時(shí)的編程語言,對(duì)編程和開發(fā)軟件的熱情也慢慢發(fā)生動(dòng)搖了。
看到問題所在了嗎?如果一個(gè)程序開發(fā)者想“做”機(jī)器學(xué)習(xí),他真的需要花幾年時(shí)間和數(shù)萬元去獲得數(shù)學(xué)知識(shí)和更高的學(xué)位嗎?答案當(dāng)然不是,還有一個(gè)更好的方法。
我們不能僅僅將模式翻轉(zhuǎn)為自上而下,卻使用相同的教學(xué)材料。正如計(jì)算機(jī)科學(xué)的課程從來沒有把軟件開發(fā)和軟件交付等實(shí)際問題涵蓋到課程內(nèi)容當(dāng)中,機(jī)器學(xué)習(xí)課程和教科書也遠(yuǎn)遠(yuǎn)不夠,它們一般都停留在算法層面上。你需要一個(gè)自上而下的方法來學(xué)習(xí)機(jī)器學(xué)習(xí)。一種專注于實(shí)際效果的方法是:使用最新和最好的工具和平臺(tái),處理實(shí)際的端到端的機(jī)器學(xué)習(xí)問題,這才是正確的途徑[5]。這種方法主要包括三個(gè)方面:設(shè)計(jì)系統(tǒng)流程、選擇最新的工具、針對(duì)性的練習(xí)。
2.1設(shè)計(jì)系統(tǒng)流程
一旦學(xué)會(huì)了使用某種工具和算法,很多同學(xué)可能馬上會(huì)認(rèn)為解決某一問題相當(dāng)容易,并認(rèn)為這個(gè)問題已經(jīng)“解決”了。然而,這是遠(yuǎn)遠(yuǎn)不夠的。怎么確定問題已經(jīng)解決了呢?怎么確定結(jié)果是好的呢?怎么確定這些結(jié)果在實(shí)際的數(shù)據(jù)集上是可靠的呢?在解決機(jī)器學(xué)習(xí)問題上,需要一個(gè)系統(tǒng)化的流程。這類似于一個(gè)軟件工程項(xiàng)目,一個(gè)好的系統(tǒng)流程才可以得到一個(gè)高質(zhì)量的,可重復(fù)性的結(jié)果。系統(tǒng)流程包括以下幾個(gè)方面:?jiǎn)栴}的定義、數(shù)據(jù)準(zhǔn)備、檢查算法、改進(jìn)結(jié)果,如圖1所示。
圖1 系統(tǒng)流程
2.2使用最新的工具
機(jī)器學(xué)習(xí)工具和庫總在不斷更新中,但是無論在任何時(shí)候都應(yīng)該選擇使用最新最適合的工具,而不是過時(shí)的算法或庫文件,這樣才可能自動(dòng)化處理系統(tǒng)流程中的大部分環(huán)節(jié),并得到可靠的高質(zhì)量結(jié)果??梢酝ㄟ^咨詢有經(jīng)驗(yàn)的人,他們正在使用的最新工具,然后自己根據(jù)實(shí)際情況做出選擇。針對(duì)不同類型的工作,可以使用不同的平臺(tái)和工具。例如:
1) 一次性的預(yù)測(cè)模型:對(duì)于“通過去年的銷售數(shù)據(jù)預(yù)測(cè)今年的銷售數(shù)據(jù)”等簡(jiǎn)單任務(wù),可以使用Weka 平臺(tái)[6]。因?yàn)橥ㄟ^Weka可以加載一個(gè)CSV文件,設(shè)計(jì)一個(gè)實(shí)驗(yàn)并馬上得到最佳的模型,而無需寫任何一行代碼。
2) 嵌入式的預(yù)測(cè)模型:在現(xiàn)有的軟件工程項(xiàng)目中增加預(yù)測(cè)功能模塊,可以選擇Python [7]中的scikit-learn庫[8],因?yàn)槟菢泳涂梢栽陂_發(fā)模型和部署項(xiàng)目時(shí)使用相同的語言。Ipython[9]是一種向更大的團(tuán)隊(duì)展示工作流程和預(yù)測(cè)結(jié)果的方式。
3) 深入研究的模型:對(duì)于需要深入理解并不斷優(yōu)化的預(yù)測(cè)模型,可以選擇R平臺(tái)[10]以及Caret擴(kuò)展包[11],因?yàn)槟菢泳涂梢钥焖俨⒆詣?dòng)地嘗試很多最新的模型,并使用整個(gè)R平臺(tái)實(shí)現(xiàn)更精準(zhǔn)的特征選擇以及算法優(yōu)化實(shí)驗(yàn)。
事實(shí)上,這三種工具將根據(jù)具體的實(shí)際問題混合使用,需要不斷學(xué)習(xí)并充分利用它們;但同時(shí)眼觀六路、耳聽八方,當(dāng)更新更好的工具可以出現(xiàn)時(shí),馬上使用最新的工具,并將它們嵌入到你的系統(tǒng)流程中。
2.3針對(duì)性的練習(xí)
通過大量的練習(xí)可以有效的學(xué)習(xí)軟件開發(fā),同樣的方法也適用于機(jī)器學(xué)習(xí)。在每個(gè)項(xiàng)目中練習(xí)的環(huán)節(jié)越多,對(duì)機(jī)器學(xué)習(xí)則掌握得越好(最理想的是端到端的實(shí)際問題)。選擇練習(xí)的數(shù)據(jù)集應(yīng)該是真實(shí)的而不是人為的?,F(xiàn)在已經(jīng)有成百上千的公開數(shù)據(jù)集可以免費(fèi)獲取,并且數(shù)據(jù)集的復(fù)雜性不斷增加:
1) 建議從規(guī)模較小的可以裝進(jìn)內(nèi)存的數(shù)據(jù)集開始,如UCI機(jī)器學(xué)習(xí)庫 [12]。它們是公開的并且相對(duì)干凈的數(shù)據(jù)集,可以作為建立系統(tǒng)流程和學(xué)習(xí)新工具的一個(gè)良好開端。
2) 在此基礎(chǔ)上,可以研究規(guī)模更大一點(diǎn)的卻仍然可以裝進(jìn)內(nèi)存的數(shù)據(jù)集,比如來自Kaggle [13] 和KDD cup [14] 的比賽數(shù)據(jù)集。它們本身含有一定的噪聲,需要更靈活的處理并使用不同的技巧。
2.4記錄成果
為每一個(gè)機(jī)器學(xué)習(xí)項(xiàng)目建立和維護(hù)一個(gè)半正式的工作成果:將所學(xué)所做詳細(xì)記錄下來,生成一個(gè)單獨(dú)的文件夾,以便在日后的項(xiàng)目中參考并再次使用。這類似于軟件開發(fā)者為每一個(gè)項(xiàng)目保留一個(gè)文件夾,用于日后參考和代碼重用。這種做法將大大加速機(jī)器學(xué)習(xí)的進(jìn)程。保留所有的腳本、代碼以及生成的圖片很重要,但更重要的是寫下學(xué)習(xí)的感悟和發(fā)現(xiàn),把它們想象為代碼的注釋。一個(gè)單獨(dú)的記錄文件可以是一個(gè)簡(jiǎn)單的PPT或文本文件形式,更加詳細(xì)的記錄文件可以是會(huì)議中的演講稿或者是生成視頻上傳到Y(jié)ouku中 [15]。
將每一個(gè)項(xiàng)目保存到公共的版本控制庫(如GitHub)中 [16],這樣其他的初學(xué)者可以借鑒你的項(xiàng)目并拓展你的工作。將你項(xiàng)目的鏈接放在博客、微博、微信、Linkedln或其他任何地方,通過網(wǎng)絡(luò)平臺(tái)展示你不斷提升的技術(shù)和能力。GitHub中的項(xiàng)目文件正是公司在招聘過程中,在簡(jiǎn)歷上真正關(guān)心的技能和已經(jīng)取得的成果。
使用上面所說的方法,可以作為軟件開發(fā)者學(xué)習(xí)機(jī)器學(xué)習(xí)的開始,并能不斷取得進(jìn)步。開始使用這個(gè)方法,通??赡軙?huì)產(chǎn)生一些疑慮,然而這些疑慮是不必要的,例如:
1) 不需要去寫代碼: 與web開發(fā)類似,學(xué)習(xí)機(jī)器學(xué)習(xí)不需要寫大量的代碼。例如像Weka這樣的工具,可以在不需要任何編程的前提下,使得設(shè)計(jì)機(jī)器學(xué)習(xí)算法和建立預(yù)測(cè)模型的過程變得十分簡(jiǎn)單。編寫代碼可以讓你掌握更多的不同工具,但這不是必須的。
2) 你不需要精通數(shù)學(xué):如同軟件開發(fā)者一樣,不需要懂得計(jì)算復(fù)雜度或者O(n)再去編寫代碼。同理,可以在沒有統(tǒng)計(jì)、概率論、線性代數(shù)的背景下解決端到端的機(jī)器學(xué)習(xí)問題。需要強(qiáng)調(diào)的是,我們的方法沒有從理論開始學(xué)習(xí),并不意味著忽視理論。當(dāng)需要研究理論的時(shí)候,可以從開發(fā)中分離出來深入研究。事實(shí)上,因?yàn)榻鉀Q機(jī)器學(xué)習(xí)問題是令人著迷的過程,理論的學(xué)習(xí)是在不知不覺中的。為了追求更好的結(jié)果和更精確的預(yù)測(cè),你將使用任何可以找到的資源,提取其中的精華并運(yùn)用到你的問題上。以軟件開發(fā)的流程來學(xué)習(xí)機(jī)器學(xué)習(xí),對(duì)初學(xué)者來說這個(gè)方法則是相當(dāng)有意義的。
3) 不需要一個(gè)更高的學(xué)位:機(jī)器學(xué)習(xí)方面的知識(shí)都是公開的,可以今天馬上進(jìn)行自學(xué),并不需要通過大量的時(shí)間和金錢去獲得一個(gè)學(xué)位再開始。開始解決機(jī)器學(xué)習(xí)問題并完成了一個(gè)小型的項(xiàng)目后,再去考慮獲得學(xué)位的事情。到那時(shí)候,你將對(duì)整個(gè)領(lǐng)域和自己感興趣的部分有更深入的理解。
4) 不需要一個(gè)大數(shù)據(jù)集:機(jī)器學(xué)習(xí)算法在小數(shù)據(jù)集上設(shè)計(jì)和理解更佳。數(shù)據(jù)足夠小則可以全部加載到內(nèi)存中,并使用普通的臺(tái)式計(jì)算機(jī)進(jìn)行處理。大數(shù)據(jù)并不等于機(jī)器學(xué)習(xí)。
5) 不需要一臺(tái)超級(jí)計(jì)算機(jī):雖然某些最先進(jìn)的算法,如深度學(xué)習(xí)確實(shí)需要非常強(qiáng)悍的多核GPU資源,但同時(shí)它們也是可以解決小問題的算法,使用你的臺(tái)式計(jì)算機(jī)CPU就可以了。你可以馬上開始機(jī)器學(xué)習(xí)算法,不必等到擁有一臺(tái)超級(jí)的計(jì)算機(jī)才開始。在決定去買一臺(tái)超級(jí)計(jì)算機(jī)或者租用昂貴的EC2 [17] 之前,最好花時(shí)間用于理解這些算法如何用于更小但更加容易理解的數(shù)據(jù)集之上,從中獲得最大的收益。
6) 不需要大量的時(shí)間:如前所述,處理機(jī)器學(xué)習(xí)問題會(huì)讓人上癮。如果在機(jī)器學(xué)習(xí)競(jìng)賽中被超越了,你會(huì)很樂意犧牲一個(gè)月晚上看電視的時(shí)間將算法的準(zhǔn)確度提高幾個(gè)百分點(diǎn)。其實(shí),如果一開始就有一個(gè)清晰的系統(tǒng)流程和最新的工具,你就可以在一兩天之內(nèi)處理一個(gè)從端到端的問題。將問題分解為多個(gè)小問題,然后一個(gè)一個(gè)的解決。
綜上所述,通過正確的流程和方法,可以在最大程度上激發(fā)初學(xué)者的學(xué)習(xí)熱情,迅速入門并不斷提高。無論對(duì)于程序開發(fā)者還是自學(xué)的大學(xué)生,通過這種自上而下的系統(tǒng)流程可以全面的掌握機(jī)器學(xué)習(xí)算法,并隨時(shí)運(yùn)用最新的算法,有效的解決端到端的實(shí)際問題。
參考文獻(xiàn)
[1]新浪科技,"http://tech.sina.com.cn/d/AlphaGo/."
[2]Coursera.https://www.coursera.org/learn/machine-learning.
[3]周志華,機(jī)器學(xué)習(xí).清華大學(xué)出版社,2016.
[4]A.Smola,"https://www.quora.com/session/Alex-Smola-1/1."
[5]J.Brownlee,"http://machinelearningmastery.com/machinelearning-for-programmers/."
[6]WEKA.http://www.cs.waikato.ac.nz/ml/index.html.
[7]Python,"https://www.python.org/."
[8]Scikit-Learn,"http://scikit-learn.org/."
[9]IPython,"https://ipython.org/."
[10]R語言,"https://cran.r-project.org/."
[11]Caret,"http://topepo.github.io/caret/index.html."
[12]UCI數(shù)據(jù)庫,"https://archive.ics.uci.edu/ml/index.html."
[13]Kaggle,"https://www.kaggle.com/."
[14]KDD比賽,"http://www.kdnuggets.com/datasets/kddcup.html."
[15]Youku優(yōu)酷,"http://www.youku.com/."
[16]GitHub,"https://github.com/."
[17]EC2,https://aws.amazon.com/cn/.
羅曉牧(1980-),男,廣東廣州人,講師,工科博士研究生畢業(yè),研究方向:機(jī)器學(xué)習(xí),無線傳感器網(wǎng)絡(luò),生物信息獲取。
作者簡(jiǎn)介:
基金項(xiàng)目:國家自然科學(xué)基金(編號(hào):61301294)。