在過去的幾年間,資料科學這個概念已經被非常多的行業所接受。資料科學(源自于一個科學研究課題)最早是來自于一些試圖去了解人類的智能并創造人工智能的科學家,但現在它已經被證明是完全可以帶來真正的商業價值。
例如,我所在的公司:zalando(歐洲最大的時尚品零售店)。在這裡,資料科學和其他工具一起被用來提供資料驅動的推薦。推薦本身作為後端服務,被提供給很多地方,包括産品頁面、分類目錄頁面、通訊電郵以及重新定位目标客戶等。
圖1:圖檔來自mikio braun的演講頁
實際上,有非常多的方法可以由資料驅動産生推薦。例如在所謂的“協同過濾”裡,所有使用者的行為(比如浏覽商品、對想買商品清單的操作、以及購買行為)都可以被收集起來作為推薦的基礎,然後分析發現哪些商品有相似的使用者行為模式。這種方法的優美之處在于計算機根本不用知道這些商品是什麼。而它的缺點則是商品必須要有足夠多的使用者行為資訊資料才能保證這個方法起作用。另外一類産生推薦的方法是隻看商品的屬性。例如,推薦具有相同品牌的或者相同顔色的商品。當然,對這些方法還有非常多的擴充或者組合。
圖2:圖檔由antonio freno友情提供并授權使用。引用自發表在kdd 2015會議的《one-pass ranking models for low-latency product recommendations》論文
更簡單一些的方法就是隻通過計數來做推薦。但這種方法在實踐裡會有非常多的複雜的變形。例如,對個性化推薦,我們曾使用過“學習排序”的方法,即對商品集做個性化的排序。上圖裡所顯示的就是這個方法需要最小化的損失函數。不過,這裡畫出這個圖的主要目的還是來展示資料科學可能會引入的複雜度。這個函數自身使用了成對的權重名額,并帶有正則化條件。這個函數的數學展現是很簡化的,當然也就很抽象。這個方法不僅對于電商的推薦場景有用,還對當物品有足夠特征的時候的所有類型的排序問題也有用。
為了把類似上圖的非常複雜的數學算法引入到生産系統中,我們需要做什麼?資料科學和軟體工程之間的界面應該是什麼樣?什麼樣的組織架構和隊伍結構才最适合使用這些資料科學的方法。這些都是非常相關和合理的問題。因為這些問題的答案将會決定對于一個資料科學家或者是整個資料科學團隊的投資是否能最終得到回報。
在下文裡,我會根據我作為一個機器學習的研究人員以及在zalando帶領一個資料科學家和工程師團隊的經驗,來對這些問題做一些探讨。
讓我首先從了解資料科學系統與後端生産系統的關系開始,看看如果将兩者進行內建。
圖3:圖檔來自mikio braun的演講頁
典型的資料科學工作流程(管道)如上圖裡所示:第一步總是從發現問題和收集一些資料(來自于資料庫或者生産系統的日志)開始。取決于機構的資料準備好的程度,這一步有可能就是很困難的。首先,你有可能需要搞清楚誰能讓你接觸到所需的資料,并搞清楚誰能給你權限去使用這個資料。當資料可用後,它們就可能需要被再次處理,以便提取特征值。你希望這些特征可以為解決問題提供有用的資訊。接着這些特征值被導入學習的算法,并用測試資料對産生的結果模型做評估,以決定這個模型是否能較好地對新資料做預測。
上述的這個分析管道通常都是短期一次性的工作。一般是由資料科學家手工完成所有的步驟。資料科學家可能會用到如python這樣的程式設計語言,并包括很多的資料分析和可視化的庫。取決于資料數量,有時候資料科學家也使用類似spark和hadoop這樣的計算架構。但一般他們在一開始都隻會使用整個資料集的一小部分來做分析。
開始隻用一小部分資料的主要原因是:整個分析管道過程并不是一錘子買賣,而是非常多次反複疊代的過程。資料科學項目從本質上講是探索性的,甚至在某種程度上是開放式的命題。雖然項目目标很清楚,但什麼資料可用,或可用的資料是否适合分析,這些在項目一開始都不是很清楚。畢竟,選擇機器學習作為方法就已經意味着不能僅僅隻是通過寫代碼來解決問題。而是要訴諸于資料驅動的方法。
這些特點都意味着上述的分析管道是疊代的,并需要有多次改進,嘗試不同的特征、不同的預處理模式、不同的學習方法,甚至是重回起點并尋找和實驗更多的資料來源。
這整個過程本質上就是反複的,而且經常是高度探索性的。當做出的模型的整體的表現不錯後,資料科學家就會對真實的資料運用開發的分析管道。到這時,我們就會面臨與生成系統的內建問題。
圖4:圖檔來自mikio braun的演講頁
生産系統和一個資料科學系統的最主要差別就是生産系統是一個實時地、在持續運作的系統。資料一定要被處理而模型必須是經常更新的。産生的事件也通常會被用來計算關鍵業務性能名額,比如點選率等。而模型則通常會每隔幾個小時就被用新資料再進行訓練,然後再導入生産系統中去服務于新來的(例如通過rest接口送入的)資料。
這些生産系統一般都是用如java這樣的程式設計語言寫的,可以支援高性能和高可靠性。
圖5:圖檔來自mikio braun的演講頁
如果你把生産系統和資料科學系統并排放置,那麼就會得到一個類似上圖的情況。在右上角,是資料科學的部分。其典型特征是使用類似python的語音或者是spark的系統,但一般是一次性的手工觸發的計算任務,并經過疊代來優化整個系統。它的産出就是一個模型,本質上就是一堆學習到的數字。這個模型随後被導入進生成系統。而生産系統則是一個典型的企業應用系統,用諸如java語言寫成的,并持續運作。
當然,上面的這個圖有一些簡化了。現實中,模型都是需要被重新訓練的,是以一些版本的資料處理管道會和生成系統內建在一起,以便不時地更新生産系統裡的模型。
請注意那個在生成系統裡運作的a/b測試。它對應于資料科學一側的評估部分。但這兩部分經常并不完全具有可比性。例如不把離線的推薦結果展示給客戶,就很難去模拟一個推薦的效果,但有這樣做可能會帶來性能的提升。
最後,必須要意識到,這個系統并不是在安裝部署完成後就“萬事大吉了”。就如資料科學側的人需要疊代多次來優化資料分析管道,整個實時系統也必須随着資料分布漂移來做疊代演進。由此新的資料分析任務就成為可能。對我而言,能正确做好這個“外部疊代”是對生産系統的最大的挑戰,同時也是最重要的一步。因為這将決定你能否持續地改善生産系統,并確定你在資料科學上的初期投資取得回報。
到目前為止,我們主要關注的是生産環境裡的系統是什麼樣。當然對于如何保證生産系統穩定和高效則有很多種方法。有時候,直接部署python寫的模型就足夠了,但生産系統和探索分析部分的分離是肯定存在的。
你将會面對的艱巨挑戰之一就是如何協調資料科學家與程式員的合作。“資料科學家”依然是一個新的角色,但他們所做的工作與典型的程式員有着明顯差異。由此導緻的誤解和溝通障礙就不可避免了。
資料科學家的工作通常是探索性的。資料科學項目一般始于一個模糊的目标、哪些資料可用的一些想法、以及可能的算法。但非常常見的情況是,資料科學家必須嘗試多種想法,并從資料裡擷取洞察。資料科學家會寫很多的代碼,但是大部分都是用于測試想法,并不會被用于最終的解決方案。
圖6:圖檔來自mikio braun的演講頁
與資料科學家相反,程式員通常非常關注于程式設計。他們的目标是開發一個系統,實作所要求的功能。程式員有時會做一些探索性的工作,比如建構原型、驗證概念或是測試性能基準。但他們的工作的主要目标還是寫代碼。
他們間的不同還明顯地展現在代碼的變化上。程式員通常會堅持一個非常明确定義的代碼開發流程。一般包括建立自己工作流的分支,在開發完成後做評測檢查,然後把自己的分支合并進主分支。大家可以并行開發,但必須在協商後才能把他們的分支合并進主分支。然後這個過程再重複進行。這整個過程都是確定主分支會以一個有序的方式演進。
圖7:圖檔來自mikio braun的演講頁
資料科學家也會寫很多的代碼。但正如我之前所說的,這些代碼通常是為了驗證想法。是以資料科學家可能是會寫出一個版本1,但它并沒有實作需求。然後又針對一個新的想法寫了版本2,随後是2.1和2.2,直到發現還是不能實作需求而停止。再對更新的想法去寫版本3和3.1。也許在這個時候,資料科學家意識到,如果采用2.1版裡的某些方法并結合3.1版裡的某些方法,就能獲得一個更好的解決方案。這就帶來了版本3.3和3.4,并可能由此形成了最終解決方案。
圖8:圖檔來自mikio braun的演講頁
一個有意思的事情是,資料科學家實際上可能希望保留所有這些沒成功的版本。因為之後的某個時間,也許它們又會被拿來測試新的想法。也許有些部分可以被放入一個“工具箱”裡,逐漸形成資料科學家自己的私人機器學習庫。程式員更希望去删除“無用的代碼”(因為他們知道如何快速地找回這些代碼),而資料科學家則喜歡保留代碼以防萬一。
上述的兩大不同意味着,在現實中,直接讓程式員和資料科學家共同工作可能會出問題。标準的軟體工程流程對資料科學家的探索性工作模式并不合适,因為他們的目标是不同的。引入代碼評測檢查和有序的分支管理、評測、合并分支的工作流對資料科學家而言并不合适,還會減慢他們的工作。同樣的,把探索性的模式引入生産系統開發也不會成功。
為此,如何才能建構一個合作模式來保證兩邊都能高産出的工作?可能第一直覺就是讓他們互相分離地工作。例如,完全分開代碼庫,并讓資料科學家獨立工作,産出需求文檔,再由程式員團隊實作。這種方法也行得通,但流程通常會非常得慢,且容易出錯。因為重新開發實作一遍就可能會引入錯誤,尤其是在程式員并不熟悉資料分析算法的情況下。同時能否進行外部疊代來改進系統的表現也依賴于程式員是否有足夠的能力來實作資料科學家的需求。
圖9:圖檔來自mikio braun的演講頁
幸運的是,很多資料科學家實際上是希望能成為好的程式員,或是反過來。是以我們已經開始試驗一些更直接和更能幫助加快流程的合作模式,
例如,資料科學家和程式員的代碼庫依然是分離的,但部分生産系統會提供清晰定義的接口來友善資料科學家把他們的方法嵌入進系統。與這些生産系統的接口進行溝通的代碼必須嚴格地依據軟體開發實踐流程,但這是資料科學家的工作。用這種方式,資料科學團隊可以在自己的代碼快速地疊代,同時也就是完成了對生産系統的疊代。
圖10:圖檔來自mikio braun的演講頁
這種架構模式的一個具體實作是采用“微服務”方法。即讓生産系統去調用資料科學家團隊開發的微服務來擷取推薦。用這個方式,整個資料科學家使用的離線分析管道還可以被調整用來做a/b測試,甚至是加入生産系統而不用程式員團隊重新開發實作。這種模式會要求資料科學家具有更多的軟體工程技能,但我們看到越來越多的資料科學家已經具有這樣的技能集。事實上,後來我們修改了zalando的資料科學家的職銜為“研究工程師(資料科學)”來反應這種實際情況。
采用類似這樣的方法,資料科學家可以快速實踐,對離線資料做疊代研究,并在生産系統環境裡疊代開發。整個團隊可以持續地把穩定的資料分析方法遷移進生産系統。
至此,我概述了一個能把資料科學引入生産系統的架構的典型模式。需要了解的一個關鍵概念就是這樣的系統需要持續地适應并改進(這和幾乎所有的針對實際資料的資料驅動項目類似)。能夠快速疊代,實驗新的方法,使用a/b測試驗證結果,這一切都非常重要。
依據我的經驗,保持資料科學家團隊和程式員團隊的分離是不可能達成這些目标的。與此同時,很重要的是我們也要承認他們兩個團隊的工作方式确實是不同的,因為他們的目标不一樣(資料科學家的工作更加具有探索性,而程式員更關注于開發軟體和系統)。通過允許各自團隊能工作在更适合他們的目标的方式,并定義一些清晰的接口,是有可能內建兩個團隊,并保證新的方法可以被快速地試錯的。這會要求資料科學家團隊具有更多的軟體工程技能,或是至少能有軟體工程師來橋接起兩個世界。
原文釋出時間為:2016-12-02
本文來自雲栖社群合作夥伴“大資料文摘”,了解相關資訊可以關注“bigdatadigest”微信公衆号