[轉]噹噹推薦團隊的機器學習實踐

轉自:http://www.csdn.net/article/2015-10-16/2825925前端

 

先說一下個人初衷。機器學習系統如今多紅多NB這件事情我已沒必要贅述。可是因爲機器學習系統的特殊性,構建一個靠譜好用的系統卻並非件容易的事情。每當看到同行們精彩的分享時,我都會想到,這些複雜精妙的系統,是怎樣構建起來的?構建過程是怎樣的?這背後是否有一些坑?有一些經驗?是否能夠「偷」來借鑑?web

因此我但願作一個更側重「面向過程」的分享,與你們分享一下咱們在構建系統時的一些實踐,一些坑,以及如何從坑裏爬出來。算法

另外,我本次分享更側重的是「小團隊」,一是由於噹噹目前作ML的團隊確實還比較小,其次是由於據我瞭解並非每一個企業都像BAT那樣陣容龐大整齊。因此小團隊的經歷和實踐或許會有獨特的借鑑意義,但願此次分享能從不同的角度給你們提供一些參考。瀏覽器

 

今天分享的實踐經從來自當當推薦組的ML小團隊。微信

 

咱們的團隊負責噹噹推薦/廣告中機器學習系統從0開始的搭建、調優、維護和改進。除計算平臺爲其餘團隊負責維護之外,ML pipeline中的每一個環節均要負責。生產的模型用於部分推薦模塊和部分廣告模塊的排序。架構

 

分享開始以前,有必要闡明一下本次分享的定位。如上圖所示,本次分享不涉及這些內容,對此有需求的同窗可參考CSDN上其餘精彩的分享。app

 

上面這些,是本次分享所涉及到的,其中「面向過程」是本次的重點。分享的人羣定位以下:框架

 

不管你處於構建機器學習系統的哪一個階段,若是能從本次分享有所收穫,或者有所啓發,那筆者帶着「長假後綜合症」作的這個PPT就沒白忙活……機器學習

 

這是咱們本次分享的大綱:先簡單談一下我對「小團隊」的一些認識,再花主要的時間和你們分享一下噹噹的小團隊機器學習實踐。接着我會總結一些咱們實踐中猜到的坑,以及從這些坑中學到的東西。而後我會以一些參考文獻爲例,作一些對將來工做和可能方向的展望。最後是問答環節。工具

簡論小團隊

首先談談我對小團隊的認識。

 

爲何會出現小團隊?這個問題乍一看有點像是句廢話,由於每一個團隊都是從小到大發展起來的。這沒錯,可是機器學習的團隊仍是有一些屬於本身的特色的。

 

  1. 相比一些功能性系統,機器學習系統的特色之一是不肯定性,也就是這個系統搭起來的效果,是沒法從開頭就量化的。這致使決策層在投入上比較謹慎,不會在剛開始就投入太多人。
  2. 這方面人才確實比較稀缺,招聘難。簡歷看着漂亮的挺多,有實際能力或經驗的其實不多。本着寧缺毋濫的原則,小而精的團隊是一個更好的選擇。

 

 

小團隊作系統的挑戰在哪裏?這是咱們關心的首要問題。小團隊挑戰的本質其實就是兩個字:人少。從這個根本限制會衍生出多個具體的挑戰。

 

  1. 首先是對單兵能力的高要求。這很容易理解,人少就意味着每一個人都須要發揮很大的做用,所以對單兵能力要求比較高。對於這個問題,其實沒有太多好的辦法,主要就是外部招聘和內部培養。
  2. 其次是在系統開發過程當中,你們通常都須要交叉負責多個任務,這既是對我的能力的挑戰,也是對協做能力挑戰。可是另外一方面,這實際上是對員工最好的培養,可以讓你們以最快的速度成長。
  3. 再次就是方向和需求選擇的問題。由於人少,因此在決定下一步行動時,須要很是謹慎,儘可能減小無產出的投入。這有時確實是一種限制,可是換個角度來看,這「逼迫」咱們把精力集中在最重要的部分,好鋼都是用在刀刃上。
  4. 最後一點,就是單點風險較高。因爲每一個人都負責了比較多的部分,因此每一個人的離職、休假等異動,都會對系統形成較大影響。這個問題一樣主要是經過內部培養和外部招聘來解決,不過還有一個方法,就是用有挑戰的事情留住人。哪一種方法好使,就要看具體環境的具體狀況了。

 

這樣一看,小團隊挑戰不小,可是反過來看,小團隊也有一些獨特的優點。

 

 

  1. 首先就是團隊易於凝聚。這也是任何小團隊的自然優點。
  2. 其次是易於協做。不少事情不須要開會,轉身幾句話就能夠搞定。
  3. 再次是迭代速度的優點。因爲流程所涉及的事情所有由少數幾我的負責,不須要協調過多的資源,那麼只要這幾我的使勁,迭代速度就會快起來。
  4. 最後一點,也是很是重要的一點,就是團隊的成長。因爲你們都要負責不少事情,那麼成長速度天然就會很快,同時我的的成就感也會比較高,若是調配得當,會讓整個團隊處於一種很是有活力的積極狀態。

 

噹噹推薦機器學習實踐

下面咱們花一些時間來分享一下噹噹的機器學習團隊是如何撬動機器學習系統這塊大石頭的。

上圖所示的是咱們推薦後臺的總體架構。從上面的架構簡圖中能夠看出,機器學習系統是做爲一個子系統存在的,與推薦做業平臺(生成推薦結果的離線做業平臺)發生直接互動。

這幾個架構圖只是讓你們知道機器學習系統在在整個推薦系統中的位置和做用,不是本次分享的重點,不必必定看懂。

 

這一頁的架構圖是上一頁圖中紅框中部分的細節放大。從圖中能夠看出,機器學習系統是在結果排序中發揮做用的。關於這個架構的細節我在這裏不作展開,感興趣的同窗可參照美團的同窗前段時間的分享,是比較相似的架構。

 

上面的架構圖是上一頁架構中紅框部分的進一步展開,也就是機器學習系統自己的一個架構簡圖。有經驗的同窗能看出來,這張簡圖中包括了機器學習系統的主要流程部件。

後面咱們會說到這一套系統是如何搭建起來的,經歷的過程是怎樣的。系統初始階段,是一個探索的階段。這個階段的意義在於,搞明白你的問題到底是不是一個適合用ML技術解決的問題。

機器學習很厲害,但不是萬能的,尤爲是某些須要強人工先驗的領域,可能不是最合適的方案,尤爲不適合做爲系統啓動的方案。在這個階段,咱們使用的工具是R和Python。

 

上頁右側的圖中,紅色框住的部分是能夠用R來解決的,藍色框住的部分是用Python更合適的,綠色框住的部分是二者都須要。

爲何選擇R和Python呢?

先說R。

 

  1. 是由於R的全能性,堪稱數據科學界的瑞士軍刀。
  2. 是由於R已經流行不少年了,屬於成熟的工具,遇到問題容易找到解決方案。
  3. 當時(2013年)sklearn之類的還不夠完善好用,並且有問題也不容易找到解決方案。

 

再說Python。

 

  1. Python的開發效率高,適合快速開發、迭代,固然要注意工程質量。
  2. Python的文本處理能力較強,適合處理文本相關的特徵。
  3. Python和Hadoop以及Spark等計算平臺的結合能力較強,在數據量擴張時具備可擴展性。

 

不過,R的部分如今其實也能夠用Python來替代,由於以sklearn,Pandas,Theano等爲表明的工具包都已經更加成熟。

可是當過了初期探索的階段,到了大數據量的系統時,R就再也不適合了。主要緣由就是兩個:可處理數據量小和處理速度慢

 

  1. 第一個是由於純的R只支持單機,而且數據必須所有載入內存,這顯然對於大數據處理是個很明顯的障礙,不過如今的一些新技術對這一問題或許會有所緩解,可是咱們沒有嘗試過。
  2. 其次就是計算速度相對慢,這固然指的也是在大數據量下的速度。

 

因此,如架構圖中左邊,一旦到了大數據量階段,以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最高。

因此雖然機器學習是以算法爲主的系統,可是也不能思惟僵化,凡事都只想着用算法解決,有的地方,仍是小米加步槍比較合適。

關鍵流程和數據沒有掌握在本身團隊

這個坑,能夠說不是一個容易發現的坑,尤爲是在系統初期,是比較隱蔽的。咱們也是在吃了一些虧以後才發現這個問題的。

在不少公司裏,前端展現,日誌收集等工做是有專門的團隊負責的,而諸如推薦廣告這樣的團隊是直接拿來用的。這樣作的好處很明顯,可讓機器學習團隊專一於本職工做,可是很差的一面是,他們收集到的數據並不老是咱們指望獲得的。

舉個例子。咱們一開始使用的曝光數據是兄弟團隊幫咱們作的,可是咱們拿來以後發現和其餘數據不太對的上,找了好久才找到問題。這個問題直接影響到咱們拿到的樣本的正確與否,因此對咱們的影響很是的大。

那形成這個問題的緣由是什麼呢?其實並非兄弟團隊不認真,而是他們並不徹底理解咱們對數據的需求,他們也不使用該數據,因此數據的質量就會有風險。吃了這一虧以後,咱們如今把這部分工做也拿來本身作,這樣數據正確與否咱們能夠全程監控,出了問題也能夠本身內部解決,不用協調各類資源。

團隊不夠「全棧」

這個坑是一個比較複雜的坑。在上一個坑中,我提到咱們發現了數據質量有問題,以後本身作了這部分曝光收集的工做。可是定位問題緣由和本身接手並非在數據一有問題的時候就作到的。緣由既簡單又殘酷:咱們組裏當時沒有前端人才。

由於曝光問題涉及到從瀏覽器到後臺系統的一系列動做,而前端是這些動做的第一個環節。可是咱們在組件機器學習團隊的時候,並無意識到這裏面會有前端什麼事,覺得有後臺+模型的人就夠了。因此致使咱們面對這個問題比較無力。直到後來有一位有着豐富前端經驗的同事加入咱們組,咱們才定位到問題,而且作出了本身接手的決定。

這個問題給咱們的教訓是:組建團隊的時候要更謹慎一些,要從更系統的角度看待,不能說作機器學習就只招算法工程師,這樣會致使團隊級的短板,爲一些問題埋下伏筆。

不過有的問題在遇到以前可能也難以預測,因此這個坑確實比較複雜。

巨型系統

最後一個坑,固然也要留給一個大坑。這個坑我稱之爲「巨型系統」。

巨型系統是什麼意思呢?簡單來講,就是把整個系統作成「一個」系統,而不是分模塊作成多個子系統。作成一個系統的含義就是系統內部的模塊之間有着高耦合性,強關聯性,樣本、特徵、訓練、預測等等所有粘在一塊兒,沒法分離。這樣作的後果是什麼?

直接舉例子。咱們初版的系統,光上線就上了得有一週。並且以後的維護至關困難,想改東西很是困難。爲何會作成這樣的,個人反思是:在學習理論的時候,就想固然得把樣本、特徵、訓練這個pipeline當作一套東西了,這種思惟直接反應到系統裏就是一個巨型系統。或許在你只有十幾個特徵,幾百條樣本的時候沒有問題。可是當你特徵漲到幾百萬,樣本漲到幾千萬的時候,就須要好好想一下,你的系統是否是有點大得失控了。

那更好的作法是什麼呢?咱們後來的解決方法是:大系統小作。「大系統小作」這個說法不是我發明的,是今年春節後(或者是去年)看到微信團隊在說搶紅包系統架構時說到的一個概念。我以爲這個說法提煉得很好,表示很是贊同。這個作法的意思就是,雖然你的系統很龐大,很複雜,可是作的時候仍是要作好模塊分離,這樣利於開發,也利於擴展、維護。

機器學習系統的特色在於,剛開始你可能用的特徵什麼的都不多,因此以爲一個系統裏就能夠搞定,可是作着作着,須要對特徵作各類變換,樣本作各類處理,系統會在不知不覺中變得龐大,而若是你只關注模型的話,很容易造出一個沒法維護的巨型系統來。

萬里長征剛起步

咱們的團隊在經歷了剛剛這許多「坑」以後,一個系統能夠說是搭建起來了,可是這只是萬里長征的第一步。對於咱們如此,其實對於機器學習系統這個新事物,自己也有着不一樣於傳統軟件系統的諸多複雜之處,還有不少的挑戰須要去解決。我在這裏用兩篇參考文獻簡單介紹一下這些複雜之處,以及面對的挑戰。有興趣深刻了解的同窗能夠找文章具體看看。

 

第一篇是Google Research的一篇paper,講的是機器學習技術債。題目也頗有意思,能夠翻譯爲:「機器學習:高利息的技術債信用卡」。

這篇文章主要說的是機器學習系統的搭建很是地複雜,若是缺少經驗,或者不夠謹慎,在許多環節就容易「欠債」,這些債務當時以爲影響不大,可是因爲「利息」很高,到後來會讓你還起來很痛苦。

上圖是我看了文章以後根據文章本身整理的,技術債的幾個具體維度。這幾個維度和咱們本身的實踐也是高度吻合的,當時看文章也是滿膝蓋的箭。

例如圖中右上提到的「子系統邊界模糊」,和我以前說過的「巨型系統」有相似之處,說的也是系統內部無分割。

再例如右下提到的「system-level spaghtti(系統級意大利麪)」。意大利麪代碼經常使用來指代亂成一團的代碼,因爲機器學習系統通常都是在探索中搭建起來的,不像其餘系統那樣徹底設計好再搭建,因此很容易產生意大利麪代碼。

若是能在搭系統以前參照這些維度加以考慮,那麼系統的開發、升級和維護會輕鬆不少。相信這些經驗也是Google這樣的巨頭公司摔了不少坑總結出來的。巨頭尚且如此,對咱們來講天然也不簡單。

 

接下來這篇文章是如今在FB的SGD大牛Leon Bottou在ICML 2015上作的一個tutorial。題目叫:Two big challenges in machine learning,是一篇比較偏系統實踐的文章,說的是機器學習面臨的兩個新的挑戰。

第一點就很是地駭人聽聞:機器學習破壞了軟件工程。可是仔細想來,確實如此。機器學習系統的開發流程大可能是探索式、漸進式的,這一點和傳統的軟件工程很是不一樣,這就給系統開發者們提出了挑戰。我以爲之後極可能會出現專門的「機器學習系統架構師」職位。

第二點說的是當前的實驗方式方法也遇到了極限。這一點乍一看是說科學實驗的,其實否則。機器學習系統開發因爲是探索式的,因此在開發中要常常作各類實驗,驗證各類效果,這個總體方法框架,也是須要精心設計的。顯然在Bottou看來,目前的方法都不太合適。

相關文章
相關標籤/搜索