• <menu id="w2i4a"></menu>
  • logo Hadoop教程

    文檔首頁>>Hadoop教程>>為何有些公司在機器學習業(yè)務(wù)方面傾向使用 R + Hadoop方案?

    為何有些公司在機器學習業(yè)務(wù)方面傾向使用 R + Hadoop方案?


    因為他們在不懂R和Hadoop的特征應(yīng)用場景的情況下,恰好抓到了一根免費,開源的稻草。

    R:

    R的應(yīng)用場景不在于無與倫比的統(tǒng)計學習能力,而在于結(jié)構(gòu)化數(shù)據(jù)下無與倫比的單位代碼產(chǎn)出量。神經(jīng)網(wǎng)絡(luò),決策樹等基于結(jié)構(gòu)化數(shù)據(jù)的算法一行代碼搞定,預測又只是一行代碼。這樣,商業(yè)數(shù)據(jù)庫(如包括Oracle,Netezza,Teradata,SAP HANA等)提供了R接口供統(tǒng)計分析人員進行高效實施。 同樣的,SAS和IBM SPSS也做到了一部分高效實施能力,他們沒有的是R獨有的龐大cran packages群。但相似的一點是,R的package群也把它的用戶慣壞了,慣壞到這些人只是覺得這是一個SAS或者SPSS的免費版,而不是去通過代碼學習如何做機器學習哪怕一點點核心原理。你要做的,就是高效的最新結(jié)構(gòu)化數(shù)據(jù)算法的實施。

    最重要的是,從Hadoop上的數(shù)據(jù)加載到這些庫,不僅保證了數(shù)據(jù)本身的正確性和結(jié)構(gòu)化,也已經(jīng)保證了數(shù)據(jù)模型的第二、第三范式化(CAErwin的第一課),想做任何一個分析,你手邊的數(shù)據(jù)庫簡單的join就形成了你需要的分析寬表。想想SQL里sum over的設(shè)計含義:為什么它要制造數(shù)據(jù)的冗余?那一定是為了BI或者分析存在的。

    Hadoop:

    Hadoop的應(yīng)用場景不在于給統(tǒng)計分析軟件提供強力的支持,而只是提供了一個分布式數(shù)據(jù)的泛用免費框架,基于鍵值對(key value pair)高效的對原始非結(jié)構(gòu)化數(shù)據(jù)進行存儲。

    結(jié)構(gòu)化和非結(jié)構(gòu)化數(shù)據(jù)庫結(jié)合的R+Hadoop看起來很美,實則困難重重。我的看法是,任何一家在數(shù)據(jù)分析領(lǐng)域(Text Mining暫時除外,見后)決定以一個穩(wěn)健的態(tài)度涉足的企業(yè),都無一例外的基于數(shù)據(jù)強一致性的考慮,選擇傳統(tǒng)的結(jié)構(gòu)化數(shù)據(jù)庫作為后續(xù)結(jié)構(gòu)化分析的依托—— 哪怕他們是收費的。如果習慣代碼開發(fā),Hadoop+python自己做初步的數(shù)據(jù)處理,而后使用基于java的Mahout是一個很自然的選擇。

    R+Hadoop的幻覺:

    不管什么和Hadoop結(jié)合,都喜歡以word count這種典型的鍵值對開始。事實上R可以做這件事,但是覺得R做的無與倫比,就有點進入誤區(qū)。還是那句R的美在于結(jié)構(gòu)化數(shù)據(jù)下無與倫比的單位代碼產(chǎn)出量。一旦你發(fā)現(xiàn)你作為專注于數(shù)據(jù)的分析師,同時也是一個并不骨灰的代碼開發(fā)者,開始用R操作列表和數(shù)據(jù)結(jié)構(gòu),開始用R重寫Mapper和Reducer,你就會產(chǎn)生一個疑問:

    為嘛不學Java、Python?這種分析“不傳統(tǒng)”,就算你不想學吧,為嘛不找懂它們的人來干?

    Python基于鍵值對存儲,也具有相當高的單位代碼產(chǎn)出量,也有很多科學計算包。從這個意義上你可以做出一個白箱,單機縮水版的mahout,而且適合處理有增量算法的大數(shù)據(jù)學習(看看NumPy,SciPy,)。一樣免費。

    數(shù)據(jù)挖掘的幻覺:

    數(shù)據(jù)挖掘是什么,很難嗎?

    廣義的數(shù)據(jù)挖掘,包括數(shù)據(jù)分析和機器學習,只說最核心的數(shù)學概念的話,估計就幾句話;恰好R的簡潔性也是能用幾句話做完這幾句話的:

    0 數(shù)據(jù)清洗,標準化。和1-4,理解真實世界是相輔相成的
    1 最先學的數(shù)學技巧是空間分解:LL',PCA,SVD,回歸以及L2/L0懲罰變種
    2 再學最優(yōu)化算法:L1懲罰回歸,SVM(使用的Newton-Raphson/Gauss-Newton/Levenberg-Marquadt(還是1的內(nèi)容?。?;MonteCarlo Markov Chain
    3 數(shù)據(jù)結(jié)構(gòu):決策樹(列表類),詞頻統(tǒng)計(鍵值對或者字典類),F(xiàn)P-growth(一個樹的加強版)。學到這,所謂“貝葉斯”根本就不能叫算法,只能叫一個指導思想。
    4 模型集成:Adaboost,神經(jīng)網(wǎng)絡(luò),bootstrap。對方法,對模型參數(shù)都能集成(大雜燴?。?/p>

    任何一個聽起來很裝逼的算法,逃不過被解析成這4類方法組合的命運。

    可以看到,大數(shù)據(jù)分析的瓶頸在哪?

    第0步,和曾經(jīng)的大Boss討論過,傳統(tǒng)行業(yè)數(shù)據(jù)倉庫實施起碼還能打10年,而"實體-關(guān)系"概念和"鍵-值"概念這兩種抽象起碼還能打30年,數(shù)據(jù)的組織,過濾,元數(shù)據(jù)維護都是數(shù)據(jù)產(chǎn)生價值的必經(jīng)之路,這方面的工作很枯燥但是很基礎(chǔ),大數(shù)據(jù)和傳統(tǒng)數(shù)據(jù)都需要;

    第1步是最基本最重要的分析手段,也最容易在大數(shù)據(jù)語境下導致單機無法分析的億階稀疏大矩陣產(chǎn)生:例1,用戶User對商品SKU的購買記錄,;例2,在特定的經(jīng)緯度,特定的時間,特定的用戶發(fā)生了動作;這兩個例子是典型的“匯總還不如不匯總”的情況,必須要有分布式稀疏矩陣處理技術(shù);

    第2步,序貫MCMC的串行性可以通過并行集成方法模擬,但是收斂性還仍然較低,需要暴力并行堆FLOPS;對應(yīng)的,因為SVM/Lasso都有增量算法、分布式算法方案,核心思想在于“世界的真實,模型的本質(zhì),都是稀疏的”,鎖少量資源,分布式地更新模型系數(shù)或者是梯度,這些算法在理論上得到突破后,往往依賴分析型數(shù)據(jù)庫或者大數(shù)據(jù)平臺靈活的并發(fā)調(diào)度,靈活的行列混合存儲模式,這一點是單機、小集群、傳統(tǒng)數(shù)據(jù)庫難以企及的;

    第3、4步,這里雖然舉了很簡單的例子,但這些是在數(shù)學模型和數(shù)據(jù)模型上是最沒有開發(fā)壓力的,需要關(guān)心的只是資深程序員的功底了。舉例說明,文本挖掘(NLP)統(tǒng)計完詞頻你還是得會空間里做PCA(或者其他形式的大矩陣加工);如果不然,只引入HMM模型和基礎(chǔ)字典樹的話,學習成本就只有學習貝葉斯理論了,并且仍然可以高效并行的解決NLP問題,有興趣的可以參考Viterbi算法和CRF算法。

    大數(shù)據(jù)的幻覺:存儲和計算的沖突

    大數(shù)據(jù)處理,多大算大?像我說的,在3,4步出來的數(shù)據(jù),原始數(shù)據(jù)很大,加工匯總完了很小,或者處理起來是高度獨立的。分布式存儲不影響分析,說是大數(shù)據(jù),其實和小數(shù)據(jù)處理沒差別。

    需要隨時交換資源的聚類,回歸,SVD,PCA,QR,LU等關(guān)系到矩陣分解的計算甚至是高效訪問,這才是大數(shù)據(jù)真正的挑戰(zhàn)。

    那些有監(jiān)督的分類樹,把數(shù)據(jù)集切成1000份并且有冗余的給500臺機器每臺3-5份數(shù)據(jù)最后得到集成的分類結(jié)果,我很難稱其為“大數(shù)據(jù)計算技術(shù)”,它的本質(zhì)和挖礦機每秒能做無數(shù)個高度同質(zhì)化的hash計算一樣,不需要資源交換,不需要大量通信,它只是小數(shù)據(jù)的范圍內(nèi)打轉(zhuǎn)。
    內(nèi)存內(nèi)的分析和數(shù)據(jù)探索,展現(xiàn)(單節(jié)點):

    百萬級,R的上限;千萬級-億級,SAS的上限;億級,Python的上限。我的使用經(jīng)驗是,400M數(shù)據(jù),Python加載內(nèi)存500M,R加載占內(nèi)存2G,SAS加載600M,經(jīng)過表級壓縮150M。而后續(xù)的原始處理(尤其是字符串操作這種數(shù)據(jù)清洗),R幾乎不能做。這就需要你輸入到R的數(shù)據(jù)幾乎就能直接開始跑分析了。若不信邪,我推薦你用readLines加上strsplit來操作讀入R的文件,看看他數(shù)據(jù)清洗的效率和read.delim,和SAS proc import 以及 Python的with as語法相差多少。

    同時另一方面,只要數(shù)據(jù)量低于剛才提到的限度,R又提供了最好的展現(xiàn)方案,因為“展現(xiàn)方案是專用而非泛用”的。最著名的ggplot2,基于百度echarts產(chǎn)品的recharts(by taiyun on Github),還有Yihui Xie的作品knitr(markdown語法動態(tài)將數(shù)據(jù)挖掘結(jié)果,圖片,視頻生成html),要比Python現(xiàn)有的可視化包(甚至是GUI包)更友好,易于操作,更適合小數(shù)據(jù)集快速展現(xiàn)。如果你恰好是SAS用戶,還是不要說自己懂數(shù)據(jù)展現(xiàn)會比較好。

    我的理解是,R的產(chǎn)出類似html+js+CSS一樣,適合輕量分析,輕量展現(xiàn),更適合個人用戶。

    非結(jié)構(gòu)化大數(shù)據(jù)處理:

    你的算法已經(jīng)走到了“萬事俱備,只差跑全量” 這樣一個對手中的數(shù)據(jù)很了解的地步了。Wiki 對Revolution Analytics的介紹講:R didn't natively handle datasets larger than main memory。非結(jié)構(gòu)化大數(shù)據(jù)應(yīng)用的場景只能是:

    -你很懂數(shù)據(jù)分布的細節(jié)(也許你花了很久在其他項目或者本項目的樣本數(shù)據(jù)上研究過也在大數(shù)據(jù)集上稍微驗證了一下)
    -什么算法適合你了然于胸,已知增量算法是存在的,或者你覺得暴力并行沒問題
    -你覺得把類似Mahout計算的步驟經(jīng)過代碼包裝交付給R來做沒問題
    -你完全不care交互式探索

    這是你需要的R應(yīng)用場景么?或者換一種說法,這種應(yīng)用場景R有什么優(yōu)勢?要知道算法效率排名上R<java<C++。算法月內(nèi)要上線,自己看著辦。

    說下鄙team(一個不是專業(yè)做數(shù)據(jù)挖掘的數(shù)據(jù)部門)的經(jīng)驗:

    講了半天R+Hadoop,不上Mahout,隨便搞搞RSnow,準備買SAS。

    因為我會SAS(少量用Macro,沒用過矩陣,因為沒必要)和R(沒有學習成本),Python的并行包pp使用中,考慮mahout。

    更新:當大數(shù)據(jù)平臺用戶不滿足于存儲,簡單加工以及成型算法實施,也開始關(guān)注最小查詢、交互式探索效率了,諸如Spark的內(nèi)存解決方案將會更合適。

    結(jié)束語:

    順便也給數(shù)據(jù)分析師,以及他們的領(lǐng)導們提醒一句:如果A有B沒有的代碼開發(fā)能力,R又完全替B把數(shù)學的事情做完了,形成了依賴,那B存在的意義是什么?國人強調(diào)數(shù)學理論這么一點點優(yōu)勢也都不復存在了。機器學習算法在不同的階段適合使用不同的工具,研究和使用接不上也就算了,千萬別連工具適合的環(huán)境都不懂,作為互聯(lián)網(wǎng)從業(yè)人員,這就太難堪了。

    在米國,精英的研究者是自己做開發(fā)的——這話也可以這么說,精英的開發(fā)者們自己做研究。每一個模型都不完美,現(xiàn)有的模型很可能不滿足你的分析需要。所以才要以開放的心態(tài)接納新技術(shù),發(fā)展深入數(shù)據(jù)挖掘研究,從代碼優(yōu)化改造(山寨)走向技術(shù)原創(chuàng)。 

    參考內(nèi)容:

    作者: 王Frank (知乎)

    掃碼咨詢


    添加微信 立即咨詢

    電話咨詢

    客服熱線
    023-68661681

    TOP
    三级成人熟女影院,欧美午夜成人精品视频,亚洲国产成人乱色在线观看,色中色成人论坛 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();