小团队 机器学习
小團隊撬動大數據——當當推薦團隊的機器學習實踐
發表于2015-10-16 09:15| 5147次閱讀| 來源CSDN| 10 條評論| 作者張相於
大數據機器學習推薦系統當當 width="22" height="16" src="http://hits.sinajs.cn/A1/weiboshare.html?url=http%3A%2F%2Fwww.csdn.net%2Farticle%2F2015-10-16%2F2825925&type=3&count=&appkey=&title=%E5%BD%93%E5%BD%93%E4%B8%AA%E6%80%A7%E5%8C%96%E6%8E%A8%E8%8D%90%E5%BC%80%E5%8F%91%E7%BB%8F%E7%90%86%E5%BC%A0%E7%9B%B8%E6%96%BC%E6%B7%B1%E5%BA%A6%E5%88%86%E4%BA%AB%E5%BD%93%E5%BD%93%E6%8E%A8%E8%8D%90%E5%9B%A2%E9%98%9F%E7%9A%84%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0%E5%AE%9E%E8%B7%B5%E7%BB%8F%E9%AA%8C%E3%80%82%E6%9C%AC%E6%AC%A1%E5%88%86%E4%BA%AB%E6%9B%B4%E4%BE%A7%E9%87%8D%E2%80%9C%E9%9D%A2%E5%90%91%E8%BF%87%E7%A8%8B%E2%80%9D%E2%80%94%E2%80%94%E5%9C%A8%E6%9E%84%E5%BB%BA%E7%B3%BB%E7%BB%9F%E6%97%B6%E7%9A%84%E4%B8%80%E4%BA%9B%E5%AE%9E%E8%B7%B5%EF%BC%8C%E4%B8%80%E4%BA%9B%E5%9D%91%EF%BC%8C%E4%BB%A5%E5%8F%8A%E5%A6%82%E4%BD%95%E4%BB%8E%E5%9D%91%E9%87%8C%E7%88%AC%E5%87%BA%E6%9D%A5%EF%BC%8C%E4%BB%A5%E5%8F%8A%E2%80%9C%E5%B0%8F%E5%9B%A2%E9%98%9F%E2%80%9D%E3%80%82&pic=&ralateUid=&language=zh_cn&rnd=1445118969128" frameborder="0" scrolling="no" allowtransparency="true">摘要:當當個性化推薦開發經理張相於深度分享當當推薦團隊的機器學習實踐經驗。本次分享更側重“面向過程”——在構建系統時的一些實踐,一些坑,以及如何從坑里爬出來,以及“小團隊”。【編者按】當當個性化推薦開發經理張相於深度分享當當推薦團隊的機器學習實踐經驗,側重介紹一個小團隊在構建系統時的一些實踐,一些坑,以及如何從坑里爬出來。當當構建機器學習系統過程中踩過的坑主要包括:只見模型,不見系統;不重視可視化分析工具;過于依賴算法;關鍵流程和數據沒有掌握在自己團隊;團隊不夠“全棧”;巨型系統。工具方面,當當在探索階段選擇的是R和Python,大數據階段則主要依靠Hadoop和Spark,目前集群是幾百臺的規模。在“全流程構建”的不斷迭代中,當當還總結提取出的一套特征工程相關的工具——dmilch。
先說一下我的初衷。機器學習系統現在多紅多NB這件事情我已不必贅述。但是由于機器學習系統的特殊性,構建一個靠譜好用的系統卻并不是件容易的事情。每當看到同行們精彩的分享時,我都會想到,這些復雜精妙的系統,是怎樣構建起來的?構建過程是怎樣的?這背后是否有一些坑?有一些經驗?是否可以“偷”來借鑒?
所以我希望做一個更側重“面向過程”的分享,與大家分享一下我們在構建系統時的一些實踐,一些坑,以及如何從坑里爬出來。
另外,我本次分享更側重的是“小團隊”,一是因為當當目前做ML的團隊確實還比較小,其次是因為據我了解并不是每個企業都像BAT那樣陣容龐大整齊。所以小團隊的經歷和實踐或許會有獨特的借鑒意義,希望這次分享能從不一樣的角度給大家提供一些參考。
今天分享的實踐經歷來自當當推薦組的ML小團隊。
我們的團隊負責當當推薦/廣告中機器學習系統從0開始的搭建、調優、維護和改進。除計算平臺為其他團隊負責維護以外,ML pipeline中的每個環節均要負責。生產的模型用于部分推薦模塊和部分廣告模塊的排序。
分享開始之前,有必要闡明一下本次分享的定位。如上圖所示,本次分享不涉及這些內容,對此有需求的同學可參考CSDN上其他精彩的分享。
上面這些,是本次分享所涉及到的,其中“面向過程”是本次的重點。分享的人群定位如下:
無論你處于構建機器學習系統的哪個階段,如果能從本次分享有所收獲,或者有所啟發,那筆者帶著“長假后綜合癥”做的這個PPT就沒白忙活……
這是我們本次分享的大綱:先簡單談一下我對“小團隊”的一些認識,再花主要的時間和大家分享一下當當的小團隊機器學習實踐。接著我會總結一些我們實踐中猜到的坑,以及從這些坑中學到的東西。然后我會以一些參考文獻為例,做一些對未來工作和可能方向的展望。最后是問答環節。
簡論小團隊
首先談談我對小團隊的認識。
為什么會出現小團隊?這個問題乍一看有點像是句廢話,因為每個團隊都是從小到大發展起來的。這沒錯,但是機器學習的團隊還是有一些屬于自己的特點的。
小團隊做系統的挑戰在哪里?這是我們關心的首要問題。小團隊挑戰的本質其實就是兩個字:人少。從這個根本限制會衍生出多個具體的挑戰。
這樣一看,小團隊挑戰不小,但是反過來看,小團隊也有一些獨特的優勢。
當當推薦機器學習實踐
下面我們花一些時間來分享一下當當的機器學習團隊是如何撬動機器學習系統這塊大石頭的。
上圖所示的是我們推薦后臺的整體架構。從上面的架構簡圖中可以看出,機器學習系統是作為一個子系統存在的,與推薦作業平臺(生成推薦結果的離線作業平臺)發生直接互動。
這幾個架構圖只是讓大家知道機器學習系統在在整個推薦系統中的位置和作用,不是本次分享的重點,沒必要一定看懂。
這一頁的架構圖是上一頁圖中紅框中部分的細節放大。從圖中可以看出,機器學習系統是在結果排序中發揮作用的。關于這個架構的細節我在這里不做展開,感興趣的同學可參照美團的同學前段時間的分享,是比較類似的架構。
上面的架構圖是上一頁架構中紅框部分的進一步展開,也就是機器學習系統本身的一個架構簡圖。有經驗的同學能看出來,這張簡圖中包括了機器學習系統的主要流程部件。
后面我們會說到這一套系統是如何搭建起來的,經歷的過程是怎樣的。系統初始階段,是一個探索的階段。這個階段的意義在于,搞明白你的問題究竟是不是一個適合用ML技術解決的問題。
機器學習很厲害,但不是萬能的,尤其是某些需要強人工先驗的領域,可能不是最合適的方案,尤其不適合作為系統啟動的方案。在這個階段,我們使用的工具是R和Python。
上頁右側的圖中,紅色框住的部分是可以用R來解決的,藍色框住的部分是用Python更合適的,綠色框住的部分是兩者都需要。
為什么選擇R和Python呢?
先說R。
再說Python。
不過,R的部分現在其實也可以用Python來替代,因為以sklearn,Pandas,Theano等為代表的工具包都已經更加成熟。
但是當過了初期探索的階段,到了大數據量的系統時,R就不再適合了。主要原因就是兩個:可處理數據量小和處理速度慢。
所以,如架構圖中左邊,一旦到了大數據量階段,以Hadoop和Spark為代表的工具們就會登上舞臺,成為主要使用的工具。
過了初期探索、驗證的階段后,就要進入工程迭代的步驟了。
如圖所示的是我們開發的一個典型流程。
驗證通過之后,就進入下一個重要環節,我稱之為“全流程構建”,指的是將要構建的ML系統,以及后面的使用方,全部構建起來,形成一個完整的開發環境。
這里需要強調的是“完整”,也就是不只是要搭建起ML模型相關的樣本、特征、訓練等環節,后面使用模型的環節,例如排序展示等,也要一同搭建起來。關于這一點在后面還會再次提到。
如果是初次構建系統,那么“全流程構建”將會花費比較長的時間完成。但這一步是后面所有工作的基石,投入的時間和精力都是值得的。
這個步驟完成之后,一個系統其實就已經構建好了 ,當然是一個只有型沒有神的系統,因為每個部分可能都是完全未優化的,而且有的部分可能是只有軀殼沒有內容。
之后就進入優化迭代這個“無間道”了,這部分的工作就是不斷尋找可以優化的點,然后嘗試各種解決方案,做線下驗證,如何覺得達到上線標準,就做線上AB。在系統流程構建起來之后,后面基本就是在不停的在這個迭代中輪回。(無間道的本來含義是指18層地獄的第18層,寓意著受苦的無限輪回。)
其實這個開發流程,特別像蓋房子的流程,先要打地基,之后建一個毛坯房,之后就是不斷裝修,各種驗工,直到可以入住。住進去一段時間可能覺得哪里又不滿意了,或者又出現了什么新的、更漂亮的裝修方法,那可能又會再次裝修。如此反復。直到有一天你發財了,要換房子了,那也就是系統整體重構、升級的時候了。
這一頁介紹的我們使用的工具,都是一些市面上常見的主流工具,除了dmilch這套工具。
dmilch(milch為德語牛奶的意思):Dangdang MachIne Learning toolCHain是我們在不斷迭代中總結提取出的一套特征工程相關的工具。包含了一些特征處理的常用工具,例如特征正則化、歸一化,常用指標計算等。和linkedin前段時間開源出來的FeatureFu目的類似,都是為了方便特征處理,但是角度不同。
這一頁介紹幾個我們在工作流程中的關鍵點。其實小團隊在這個方面是有著天然優勢的,所以我們的中心思想就是“小步快跑”。
第一個關鍵點就是改動之間的串行性。這或許是機器學習這種算法類系統的獨有特點,多個改進一起上的話,有時就無法區分究竟是什么因素起到了真正的作用,就像一副中藥一樣,不知道起效的是什么,而我們希望的是能把真正的“青蒿素”提取出來。
第二點就是項目推進機制。我們大概每周會有一到兩次的會議討論,主要內容是驗證改進效果,方案討論等,并當場確認下一步的動作。
技術人員其實是不喜歡開會的,那為什么每周還有開呢?我認為最重要的一個目的就是讓大家參與討論,共同對項目負責,共同成長。承擔的工作有分工,但是在討論時無分工,每個人都要對系統有想法,有建議。這也能確保大家互相吸收自己不熟悉的地方,更有利于成長。
還有一個不得不說的話題就是關于新技術的嘗試。如果沿用我們之前的蓋房子的例子,新技術就好比高大上的家具擺設之類的,家里沒個一兩件鎮宅的,都不好意思跟人打招呼。
這方面我們的經驗是,先把已有的技術吃透,用透,再說新技術,不遲。例如推薦中的協同過濾算法,一般會在購買、瀏覽、評論、收藏等不同數據,不同維度都去加以計算,看哪個效果更好。當把熟悉的技術的價值都“榨取”干了之后,再嘗試新技術也不遲。
還有一點很重要,就是別人的技術,未必適合你。不同公司的業務場景,數據規模,數據特點都不盡相同,對于他人提出的新技術,要慎重采納。
我們曾經滿懷信心的嘗試過某國際大廠的某技術,但是反復嘗試都沒有得到好的效果,反而徒增了很大的復雜性。后來和一些同行交流之后發現大家也都沒有得到好的效果。所以外國的月亮,有可能只是在外國比較圓。上什么技術,還是要看自己系統所在的土壤適合種什么樣的苗。
這部分結束之前我簡單介紹一下我們的模型在推薦廣告上上線后的效果:推薦首屏點擊率提升了15%~20%。廣告的點擊率提升了30%左右,RPM提升了20%左右。可以看出效果還是很明顯的。
那些年,我們踩過的坑
下面進入今天分享的下一個重要環節,那就是我們踩過的各種坑。
“前事不忘,后事之師”,坑或許是每個分享中最有價值的一部分。我們在構建系統時也踩過很多坑,在這里和大家分享幾個我認為比較大的坑,希望對大家有所幫助。我會先介紹幾個坑,之后再說一下我們從坑里爬出來的感覺、收獲。
只見模型,不見系統。
如果要把我們踩過的坑排個名,這個坑一定是第一名。因為如果掉進了這個坑,那么指導你系統方向的依據有可能完全是錯的。
具體來說,這個問題指的是在構建系統時,我們一開始基本只關注機器學習模型的好壞,AUC如何,NE如何,但是沒有關注這個模型到了線上的最終效果是如何。這樣做的后果是,我們覺得模型從指標等各方面來看已經非常好了,但是一上線發現完全沒有效果。因為我們忽略了模型是被如何使用的,一直在閉門造成一樣的“優化”模型,最后的效果自然不會好。
那正確的姿勢是怎樣的呢?從我們的經驗來看,在系統搭建的初期,就要明確地知道:你構建的不是一個模型,而是一個以模型為中心的系統。時刻要知道模型出來之后要干什么,要怎么用,這種大局觀非常重要。
模型雖然是系統的中心,但不是系統的全部。在系統設計、開發、調優的各個階段,都要從系統的角度去看問題,不能眼里只有模型,沒有系統(產品)。否則可能等你調出一個AUC=0.99的模型的時候,一抬頭發現已經和系統越走越遠了。
所以,做機器學習系統要注意模型和系統并重,如果只看到模型而看不到系統,很可能會做出指標漂亮但是沒有實效的“花瓶系統”來。
不重視可視化分析工具
這是一個開始很容易被忽視,但是到后期會導致你很難受的一個問題(這里指的是非深度學習的系統)。
因為機器學習系統某種程度上是個黑盒子,所以我們的精力會習慣性地集中在參數、模型這些東西上,本能地覺得模型的內部工作是不需要關心的。但是我們的經驗是,如果只關注黑盒子的外面,完全不關心里面,那么如果模型效果不好,那么將很難定位到問題的所在。反過來,如果效果好了,也會有點莫名其妙,就好比你家廁所的燈忽然自己亮了,或者電視機忽然自己開了,總會讓人很不踏實。
這個問題上我們的感觸是很深的。我們最早在做系統的時候,發現效果不好,其實是沒有太多章法能夠幫助定位問題的。只能是把各種特征來回特征,樣本處理上變一下花樣,如果效果好了,就好了,不好,接著折騰。
后來我們做了一套web頁面,上面把每條樣本、每個case的特征及其參數,樣本的出現次數,在候選集里的排序等等,全部展示出來。如同把整個系統加模型給做了一次解剖,希望能夠盡量多地看到系統的內部細節,對于分析問題有很大幫助。
這個系統幫了我們很大的忙,雖然也不能算是“有章法”的做法,但是把很多東西呈現在你面前之后,你會發現有些東西和你想的不一樣,也會發現一些你壓根不會想到的東西。這對于機器學習這種有點像黑盒子的系統來說,尤為寶貴。到現在,這個系統是我們每次效果驗證時非常依賴的一個東西,可以說是我們的另一雙眼睛。
過于依賴算法
這個坑相信很多同學也遇到過。我就舉一個例子吧。我們當時遇到一個文本處理的問題,要過濾掉大量無關無用的文本詞匯。一開始上了很多各種算法,各種調優,但是遲遲得不到滿意的效果。
最后我們亮出了絕招:人肉過濾。具體說就是三個人花了三天時間純人工把文本過了一遍(幾千個上萬個詞),效果立竿見影。當時那個問題,或許是存在效果更好的算法的,但是從系統、工程角度整體衡量一下,還是人工的ROI最高。
所以雖然機器學習是以算法為主的系統,但是也不能思維僵化,凡事都只想著用算法解決,有的地方,還是小米加步槍比較合適。
關鍵流程和數據沒有掌握在自己團隊
這個坑,可以說不是一個容易發現的坑,尤其是在系統初期,是比較隱蔽的。我們也是在吃了一些虧之后才發現這個問題的。
在很多公司里,前端展示,日志收集等工作是有專門的團隊負責的,而諸如推薦廣告這樣的團隊是直接拿來用的。這樣做的好處很明顯,可以讓機器學習團隊專注于本職工作,但是不好的一面是,他們收集到的數據并不總是我們期望得到的。
舉個例子。我們一開始使用的曝光數據是兄弟團隊幫我們做的,但是我們拿來之后發現和其他數據不太對的上,找了很久才找到問題。這個問題直接影響到我們拿到的樣本的正確與否,所以對我們的影響非常的大。
那造成這個問題的原因是什么呢?其實并不是兄弟團隊不認真,而是他們并不完全理解我們對數據的需求,他們也不使用該數據,所以數據的質量就會有風險。吃了這一虧之后,我們現在把這部分工作也拿來自己做,這樣數據正確與否我們可以全程監控,出了問題也可以自己內部解決,不用協調各種資源。
團隊不夠“全?!?/span>
這個坑是一個比較復雜的坑。在上一個坑中,我提到我們發現了數據質量有問題,之后自己做了這部分曝光收集的工作。但是定位問題原因和自己接手并不是在數據一有問題的時候就做到的。原因既簡單又殘酷:我們組里當時沒有前端人才。
因為曝光問題涉及到從瀏覽器到后臺系統的一系列動作,而前端是這些動作的第一個環節。但是我們在組件機器學習團隊的時候,并沒有意識到這里面會有前端什么事,以為有后臺+模型的人就夠了。所以導致我們面對這個問題比較無力。直到后來有一位有著豐富前端經驗的同事加入我們組,我們才定位到問題,并且做出了自己接手的決定。
這個問題給我們的教訓是:組建團隊的時候要更謹慎一些,要從更系統的角度看待,不能說做機器學習就只招算法工程師,這樣會導致團隊級的短板,為一些問題埋下伏筆。
不過有的問題在遇到之前可能也難以預測,所以這個坑確實比較復雜。
巨型系統
最后一個坑,當然也要留給一個大坑。這個坑我稱之為“巨型系統”。
巨型系統是什么意思呢?簡單來說,就是把整個系統做成“一個”系統,而不是分模塊做成多個子系統。做成一個系統的含義就是系統內部的模塊之間有著高耦合性,強關聯性,樣本、特征、訓練、預測等等全部粘在一起,無法分離。這樣做的后果是什么?
直接舉例子。我們第一版的系統,光上線就上了得有一周。而且之后的維護相當困難,想改東西非常困難。為什么會做成這樣的,我的反思是:在學習理論的時候,就想當然得把樣本、特征、訓練這個pipeline當做一套東西了,這種思維直接反應到系統里就是一個巨型系統?;蛟S在你只有十幾個特征,幾百條樣本的時候沒有問題。但是當你特征漲到幾百萬,樣本漲到幾千萬的時候,就需要好好想一下,你的系統是不是有點大得失控了。
那更好的做法是什么呢?我們后來的解決方法是:大系統小做?!按笙到y小做”這個說法不是我發明的,是今年春節后(或者是去年)看到微信團隊在說搶紅包系統架構時說到的一個概念。我覺得這個說法提煉得很好,表示非常贊同。這個做法的意思就是,雖然你的系統很龐大,很復雜,但是做的時候還是要做好模塊分離,這樣利于開發,也利于擴展、維護。
機器學習系統的特點在于,剛開始你可能用的特征什么的都很少,所以覺得一個系統里就可以搞定,但是做著做著,需要對特征做各種變換,樣本做各種處理,系統會在不知不覺中變得龐大,而如果你只關注模型的話,很容易造出一個無法維護的巨型系統來。
萬里長征剛起步
我們的團隊在經歷了剛剛這許多“坑”之后,一個系統可以說是搭建起來了,但是這只是萬里長征的第一步。對于我們如此,其實對于機器學習系統這個新事物,本身也有著不同于傳統軟件系統的諸多復雜之處,還有很多的挑戰需要去解決。我在這里用兩篇參考文獻簡單介紹一下這些復雜之處,以及面對的挑戰。有興趣深入了解的同學可以找文章具體看看。
第一篇是Google Research的一篇paper,講的是機器學習技術債。題目也很有意思,可以翻譯為:“機器學習:高利息的技術債信用卡”。
這篇文章主要說的是機器學習系統的搭建非常地復雜,如果缺乏經驗,或者不夠謹慎,在許多環節就容易“欠債”,這些債務當時覺得影響不大,但是由于“利息”很高,到后來會讓你還起來很痛苦。
上圖是我看了文章之后根據文章自己整理的,技術債的幾個具體維度。這幾個維度和我們自己的實踐也是高度吻合的,當時看文章也是滿膝蓋的箭。
例如圖中右上提到的“子系統邊界模糊”,和我之前說過的“巨型系統”有類似之處,說的也是系統內部無分割。
再例如右下提到的“system-level spaghtti(系統級意大利面)”。意大利面代碼常用來指代亂成一團的代碼,由于機器學習系統一般都是在探索中搭建起來的,不像其他系統那樣完全設計好再搭建,所以很容易產生意大利面代碼。
如果能在搭系統之前參照這些維度加以考慮,那么系統的開發、升級和維護會輕松很多。相信這些經驗也是Google這樣的巨頭公司摔了很多坑總結出來的。巨頭尚且如此,對我們來說自然也不簡單。
接下來這篇文章是現在在FB的SGD大牛Leon Bottou在ICML 2015上做的一個tutorial。題目叫:Two big challenges in machine learning,是一篇比較偏系統實踐的文章,說的是機器學習面臨的兩個新的挑戰。
第一點就非常地駭人聽聞:機器學習破壞了軟件工程。但是仔細想來,確實如此。機器學習系統的開發流程大多是探索式、漸進式的,這一點和傳統的軟件工程非常不同,這就給系統開發者們提出了挑戰。我覺得以后很可能會出現專門的“機器學習系統架構師”職位。
第二點說的是當前的實驗方式方法也遇到了極限。這一點乍一看是說科學實驗的,其實不然。機器學習系統開發由于是探索式的,所以在開發中要經常做各種實驗,驗證各種效果,這個整體方法框架,也是需要精心設計的。顯然在Bottou看來,目前的方法都不太合適。
總結
- 上一篇: 覆盖你 80 % 网络生活的,竟是这样一
- 下一篇: 用RPython在云端运行可扩展数据科学