Prismatic:用機器學習分析用戶興趣只需10秒鐘

摘要:斯坦福大學和伯克利的四位年輕的計算機科學博士創立了Prismatic。他們不僅是科學家同時也是實幹家,他們放棄了Hadoop等重量級框架,通過過程化語言的深度使用,簡單並且高效的實現了大數據的處理,高度併發,實時等優異的特性。

這篇文章主要描述的是Prismatic公司系統架構,作者是Todd Hoff,本文出自Todd對Prismatic的程序員Jason Wolfe的郵件專訪。

關於Prismatic,首先有幾個事情要說明下。他們的創業隊伍很小,僅僅由4個計算機科學家構成,其中的三個都是年輕有爲的斯坦福以及伯克利博士。他們是在用智慧解決信息超載這個問題,然而這些博士也同時擔任着程序員的角色:開發網站、iOS程序、大數據以及機器學習需要的後臺程序。Prismatic系統架構的亮點是如和使用機器學習實時地解決社交媒體流的處理問題。由於商業機密的原因,他沒有透露他們的機器學習技術,但是我們可以通過架構看個大概。Prismatic創始人之一Bradford Cross把Prismatic的系統簡潔地描述爲:“它是一個提供大規模、實時以及動態的個性化信息排名、分類以及分組功能的綜合系統。”接下來就把這個系統的架構展現給大家。

Prismatic主要功能是發現我們的興趣,爲我們推薦閱讀

今天你應該讀點什麼呢?任何一個現代人每天都會陷入這個困境,大家通常使用一些很隱祕的途徑去找到自己想要讀的東西:Twitter、RSS、Facebook、Pinterest、G+、email以及Techmeme等這些信息源。Prismatic回答了“今天我應該讀什麼?”的問題,Jason Wolfe慷慨的同意並且詳細地描述下他們正在使用的解決方案,言語中包含了許多時髦的技術名詞,例如機器學習,社交圖譜,大數據,過程化編程以及事實需求等等。然而結果是他們的方法更隱祕,但和其他一些相似應用不一樣的地方在於他們會發掘你的興趣,無論這些興趣在你的信息中藏得有多深。

正如大家預料的,他們的做法有點特別。他們選了Clojure做爲開發語言,它是一個編譯成Java bytecode的現代Lisp語言。主要目的是充分利用過程化語言去構建具有豐富粒度,結構自由的程序,從而滿足各種問題帶來的特殊需求。列舉兩個他們用到的過程化語言的優點的例子:第一個是他們幾乎每個地方都使用圖庫。對於每個用戶來說,他們的圖形計算可以被稱爲低延遲,流程化的map-reduce任務集;另外一個例子是他們使用子圖實現了模塊化的服務配置。 

他們把系統設計的焦點放在過程化開發上來,避免了使用像Hadoop那樣的巨型框架,轉去使用小型的,這使得系統更可靠,更容易糾錯,更容易擴展以及更容易理解。Prismatic的機器學習做法的難點在於要求一個非常長的訓練週期。需要指出的是:首先,獲得優質分析源內容並不需要多少時間;其次,使用基於機器學習的推薦系統需要對用戶從幼兒到現在的一生的所有數據進行訓練;這個可擴展的思維數字模擬系統扮演着信息的收集者以及生產者雙重的角色。

圖:越來越多的應用開始關注用戶的閱讀推薦

統計數據

  • 現在每天有幾千萬篇文章、博客以及其他一些內容通過Twitter,Facebook,Google Reader以及互聯網發佈。
  • 但是僅僅需要用戶登錄時的那幾秒鐘,Prismatic就能夠使用他們之前的閱讀歷史進而去分析用戶的興趣,然後推薦閱讀,使用用戶在社交網絡上的活動,從而將聯繫人發表的、符合用戶胃口的文章推薦過來。同時,Prismatic也會記錄用戶在它本身上的動作,也將它做爲分析的一個來源。
  • Prismatic只需要數十秒鐘去訪問用戶的個人主頁,通過和用戶興趣模型對比,便可以分析出用戶最感興趣的東西。
  • 現在每週有數百萬的優秀文章通過Prismatic成功分享給用戶。

平臺

  • Prismatic的主機託管在AWS的EC2上,使用Linux操作系統。
  • Prismatic99.9%的後臺通道和API服務都用Clojure開發。
  • Prismatic所有的重量級框架部署在JVM中。
  • Prismatic使用MongoDB存儲服務器參數和用戶分析數據。
  • Prismatic使用了MySQL。
  • Prismatic使用了S3。
  • Prismatic使用了Dynamo。
  • Prismatic將重點放在開發能解決特殊問題產生的需求的代碼上。

數據存儲和輸入輸出

  • 和典型的結構不同,Prismatic的服務都圍繞着數據而設計,可以提供實時讀寫數據的能力。
  • 大部分數據都直接在後端管道之間傳輸,不會和磁盤發生I/O。
  • Prismatic把數據保持在離CPU儘可能近的地方,這樣就讓API的請求幾乎沒有IO延遲,同時把API綁定到CPU上,巧妙的擴展了系統的規模。
  • Prismatic使用了許多現成的解決方案:MongoDB,MySQL以及Amazon的S3和Dynamo。每個都是經過對實際需求仔細研究的,包括規模,接入模式和數據存儲相關的其他特性。

服務

從外部來看,Prismatic的系統被分成了10個獨立的服務模塊,大致可以歸總爲5種類型:數據採集;新用戶管理;API;其他客戶機服務;批處理。每個服務都是爲一個功能而設計,通過一種特殊的方式進行橫向擴展,通常受1到2個特殊資源限制(IO,CPU,RAM)。

  • 數據採集——後臺

每天都會有大量內容(包括文章,博客和網頁等)產生,Prismatic想要儘可能多的捕捉到他們。爲了讓用戶可以評論每個內容,並和自己興趣相投的朋友進行分享,Prismatic必須識別每個內容的作者,分享者以及一些比較有價值的評論。做這些的第一步就是收集和分析內容和關係數據

首先在採集通道入口執行下面這些步驟:通過喜好在RSS上找到新文章;通過API將用戶Twitter和Facebook上的最新評論和動態收集上來。執行這些功能的服務非常簡單,而且沒有狀態信息,唯一的狀態和有意思的地方是如何確定哪些信息是已經收集過的了和怎樣智能的分析接下來該收集哪個信息。其中最難的就是前者,因爲有些人他可能在多個地方發過同一個信息。

接着,把RSS、Twitter以及Facebook等信息源收集上來的資料送入到一個過濾器中,讓它決定哪些需要進入通道進行分析。首先把垃圾郵件和其他垃圾信息丟掉,URL將被送到管道中去,此時會有很多有趣的事情發生,Prismatic會建立一個URL隊列,將每個隊列送入一個圖運算中,使用它將URL進行詳細描述,抓取它的HTML代碼,使用機器學習的算法把文章的內容抓取出來,識別最好的圖片,抓取出作者,標籤以及話題等等。爲了讓這些過程儘可能快速進行,能夠裝入內存以及提高表現力,他們投入了很大一部分時間,當然,處理這些URL的方式是高度併發的。

最後是文檔控制器,它的作用是接收上面處理好的詳細的文章和社交內容,將他們進行匹配,把文章集整理成故事系列,決定把哪些設爲當前要處理的文檔,並且管理這些API相關的機器目錄。

  • 新用戶管理——後臺

新用戶管理模塊主要負責收集新註冊的用戶的信息。它主要由兩個部分構成:通過用戶的Twitter,Facebook以及GoogleReader找出他喜歡的主題以及喜歡的文章來源;分析他的社交圖譜,找出他最喜歡哪些朋友分享的文章。

執行這些功能的服務也是高度並行的。社交圖譜分析非常複雜,關鍵是這些服務如何能夠實現如此低的延遲以及如此可靠的吞吐量:對於Twitter,Facebook和Google Reader的活躍用戶來說,準確找出數百個用戶喜歡的話題對於Prismatic來說只需要15秒,甚至更少。用戶授權以後,Prismatic就可以非常快地分析出用戶的興趣,用戶常常在註冊的時候(填寫密碼和點擊確認的過程中)這個工作就已經完成了。看看在這15秒內,發生了什麼:Prismatic把用戶最近在Twitter和Facebook上發表的內容以及Google Reader中標記爲喜歡的東西都抓取進來,這一般是10秒鐘左右;然後把用戶和他的聯繫人等共享的1000個URL收集上來;再將這些數據送入上面提到的文檔控制器,使用相同機器學習堆棧進行採集/分析的通道;這些分析結果經過聚合,後期處理,最終都存儲到DynamoDB和S3裏去。

這個過程對延遲的要求非常嚴格,所以這些進程不能串行,必須併發執行,所以他們不得不儘可能多地使用通道和並行處理的技術。這個過程對吞吐能力要求和很高,因爲每個進程並不小,同時一旦有許多用戶同時來註冊,要想降低延遲你就必須做更多的事情。這裏也是Prismatic的獨到之處,他們的流處理和聚合類都將重量級降了下來,把性能做到了極致,達到了每個用戶使用一個低延遲map-reduce任務的效果。對於多個用戶的情況,他們系統使用的併發處理幾乎發揮了機器的全部性能。

API——面向客戶機

數據採集和新用戶管理都部署在API機器上。系統主要的設計目標和挑戰是:最近的文章必須被編入索引並且可以滿足低延遲的需求,索引並不算小(常常是許多GB),而且必須實時更新,只有這樣才能把最近更新的文章傳遞給用戶,這些需要爲用戶設計跨機器的負載均衡,同時要求必須能快速簡單地將任務劃分到新機器(當然還有關閉合並);如果要想找到用戶的真正需求,僅僅使用索引是不夠的,同時還需要用戶的“指紋”(他們的愛好,社交關係,最近讀過的文章等),這些指紋數據非常大而且在不斷髮生變化。

對於前幾個問題需要用到文檔控制器(上面提到了)。文檔控制器組織當前的文檔集,對他們進行預處理,每隔幾分鐘就把剛剛做好的的索引集存儲S3中去。當一個新的API機器啓動時,文檔控制器首先讀取這些文件,將他們放入內存,再將最新的索引副本傳遞給它。文檔控制器也負責將所有索引的改動(新增文檔/新增評論/刪除等)實時地傳遞給所有正在運行的API機器上去。其他一些API機器常用的功能也由文檔控制器從S3中讀入內存,週期性的更新到S3,如果數據超過了S3的存儲大小限制,就將它存入DynamoDB。

剩下的問題就是如何在保證延遲需求前提下,提取和更新每個請求裏的用戶“指紋”。Prismatic這裏使用的方法是使用粘性會話(Session),把用戶綁定到一臺API機器上。當用戶第一次登錄的時候,就把他的信息存入一個具有有效期的回寫式緩存中。在用戶會話的生命期週期內,把其中的數據放入內存進行興趣分析。在這個過程中用戶進行的所有操作都會通過同一個API機器進行處理,對於那很小的一部分不關鍵的用戶指紋,每隔幾分鐘,會話到期或者關閉時再分批進行更新。更多的關鍵指紋直接進行同步或者至少使用一個直寫式緩存進行更新。

其他的服務——面向客戶機

  • 公共興趣功能,主要是爲沒有登錄的用戶服務,通過常規的API收集他們的需求,按照年齡分區,將不同的需求放在不同的頁面上。
  • 用戶功能,管理創建賬戶,登錄等功能。通常就部署在SQL數據庫上,存儲用戶的主要數據,但這些常常需要週期性地拍下快照並且進行備份。
  • URL簡化服務
  • 批處理以及其他服務
  • 另外還有一些其他的服務,用於機器語言訓練,數據歸檔和事件追蹤和分析。

圖庫

這是一個聲明性的描述圖形計算的好方法,充分發揮了Clojure的優點。一個圖就是一個Clojure示意圖,在裏面定義鍵值對,鍵裏存儲的是關鍵詞,值裏存的是使用示意圖中其他方法對關鍵詞計算後得到的功能,這樣就達到了外部參數的效果。

這個方法幾乎在所有的地方得到了應用。例如文檔分析通道就是一個圖,其中每個文件中的核心內容都依賴於它(舉個例子,如果要定義某個文檔的主題,前提是先要提取它的文字內容);訂閱生成進程就是一個由查詢和排名兩個步驟組成的圖;每個訂閱生成服務本身就是一個圖,其中的每個資源(如數據存儲,內存,HTTP控制器等)就是這個圖一個節點,他們互相依賴。這樣就爲下面這些工作提供了方便:

模塊化對服務配置進行簡潔描述(例如使用子圖);使用進行和服務之間的相互依賴關係繪製出圖表;測量每個節點在進行像文檔分析,或者在每個複雜服務(例如API)的資源上進行的活動等複雜運算時,所需要的計算時間和發生的錯誤;智能爲每個計算的不同線程規劃節點(在理論層面甚至到機器層面);通過用模擬的方式替換掉圖中的一些節點,從而可以對全部生產服務進行簡單的測試。

Prismatic把機器學習的技術用於了文檔和用戶這兩個領域。

機器學習用於文檔

對於HTML文檔的處理:提取出頁面中的核心文本(而不是它的側欄,頁腳,評論等),標題,作者,有用的圖片等;確定文檔相關的一些特點(例如文章是關於什的,主題等)。這些任務的模式很典型。模型通過其他機器大型批任務進行訓練,首先將數據從S3讀入,然後再把學到的參數文件存儲S3上,之後在內容提取通道中將S3中的模型讀入(同時也要定期刷新)。所有從系統輸出的數據也會反饋給通道,這樣就對了解用戶的興趣更有幫助,做到了隨時從錯誤中學習。

Prismatic研發的框架“flop”庫是軟件工程師最感興趣的,它實現了最先進的機器學習訓練和推理代碼,它和普通的漂亮的Clojure代碼非常相似,但確編譯(使用神奇的宏)成低級的數組執行循環,這使得它和Java中的metal非常相似,不用藉助於JNI便可以使用這個框架。

這個代碼框架比一個重量級的Java更簡潔,更容易讀懂,同時和Java的執行速度基本持平。Prismatic將大部分的功夫都花在創建一個能快速運行的故事機器組件上了。

機器學習用於用戶

使用社交網絡數據推測用戶都有哪些興趣並且使用應用中的明顯標誌(用戶增加一些或者刪除一些文章)去優化這些推測。

使用這些明顯標誌的問題很有意思,因爲用戶的輸入必須要非常快速的在他們的訂閱中反饋。如果一個用戶將一個推薦的出版物中5個文章都刪除了,接着馬上就不要再把這個出版物中的其他文章給用戶繼續展示了,第二天也不要。這意味着沒有時間爲所有的用戶執行另一個批處理任務,解決的辦法就是在線進行學習:當用戶提交了那些明顯的標誌時,立刻對用戶的模型進行更新。

用戶和應用交互時產生的原始數據流要保存下來。這樣就可以稍後重新運行對用戶興趣進行機器學習所需要的原始流數據,同時還能避免由於脆弱的緩存在上傳這些數據的過程中出現錯誤,從而導致這些數據丟失。引入在線學習可以糾正並且更加準確地對模型進行計算。

學到的東西

  1. 找到你的定位。仔細考慮下整個通道和流過它的所有數據。在衆多的挑戰上多做些工作,針對每個問題提出特定的解決方案。每個服務都有它自己的規模,同時服務間使用一個非常容易擴展的方式進行的通信,這種方式還不能給其他的服務帶來太大的壓力。Prismatic沒有使用Hadoop構建系統,所有的數據都以原始數據的形式存在分佈式數據庫和文件系統中。
  2. 發現並充分利用高度並行的機會。 
  3. 當用戶在等待時進行並行運算。新用戶註冊過程,例如新用戶上傳通道要在用戶等待時併發工作,這樣就可以實現在幾秒內就完成註冊。
  4. 使用過程化語言開發豐富粒度的,自由抽象的程序。這些抽象層次可以用於構成特殊問題的邏輯層。
  5. 避免重量級,大規模的框架,例如Hadoop。這樣產生的是較小的代碼庫,相同條件下,更不容易出錯,更容易理解並且更容易進行擴展。構建自己的代碼庫的理由很簡單,因爲大部分開源的功能都被鎖入了重量級的框架中,很難進行代碼複用,擴展和問題出現時很難進行調試。
  6. 找到合適的人開發對系統很重要。目前Prismatic後臺服務開發團隊是由3個計算機科學博士組成,他們負責所有的開發工作,包括從機器學習的算法研究到低層次的web和iPhone客戶端系統工程的所有代碼。
  7. 將所有的代碼儘早投入生產,儘管投資早期經常在構建和調試工具,但這使創建和調試產品服務變得簡單和有趣。
  8. 保持簡單。不要花太多精力在複雜的代碼庫或者框架上,使用簡單的東西,當有一個更簡單的解決方案足夠好時就不要再幻想了。例如使用簡單的機遇HTTP的通信協議,而不要再去考慮什麼流行的框架了。如果能夠工作,要很樂意去買一些現成的管理解決方案,例如S3或者Dynamo。
  9. 多在構建強大的開發工具和類庫上下些功夫。例如,Prismatic的“flop”庫,它允許他們寫出和Java處理速度一樣快,代碼量只有十分之一的數字運算機器學習算法;“Store”抽象了許多不重要的鍵值存儲細節,允許在各種環境下高度的對緩存,批處理和傳遞流數據進行抽象;“graph”使的寫數據,測試和管理分佈式流進程服務變得簡易可行。
  10. 對每一種數據類型要慎重考慮,不要期望能找到一個I/O和存儲的通用解決方案。

最後分享下使用的感受:

我(譯者)登錄到Prismatic首頁的時候,簡單大方的風格在我使用之前就感受到了技術氣息十足(這時系統會推薦大衆興趣)。當我點擊註冊的時候,界面提示可以用Facebook賬號登錄,輸入了用戶名和密碼的時候(這時他已經把我Facebook,Twitter和Google Reader裏的數據進行了分析),之後展現給我的是一篇一篇雲計算和大數據的文章,當然也包含一些移動新聞等(果然實時的250ms不是吹噓的)。

這讓我想到了國內的應用,第一個是有道閱讀,用過的朋友都應該知道,它其實只提供了Prismatic未註冊用戶效果,即推薦了很多的大衆熱點興趣,然後要求用戶在裏面勾選。第二個我想到了的是網易郵箱,當你訂閱的關鍵詞比較準確時,他推薦的文章也大都比較符合用戶的口味。然而可惜的是Prismatic目前只支持Facebook,Twitter和Google Reader等國外的社交工具,內容抓取的範圍也僅是國外的知名出版物,所以我很期待國內能夠出現與之媲美的應用,將微博,QQ,人人等國內社交工具集成進來,將閱讀推薦做到每個人都不一樣,每篇文章都符合用戶的口味。

相關鏈接:Prismatic系統架構解析:機器學習在社交數據分析和用戶分析上的實踐

原文鏈接:Prismatic Architecture - Using Machine Learning On Social Networks To Figure Out What You Should Read On The Web 


發佈了14 篇原創文章 · 獲贊 11 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章