99999久久久久久亚洲,欧美人与禽猛交狂配,高清日韩av在线影院,一个人在线高清免费观看,啦啦啦在线视频免费观看www

熱線電話:13121318867

登錄
首頁精彩閱讀解密Airbnb的數(shù)據(jù)科學(xué)部門如何使用R語言
解密Airbnb的數(shù)據(jù)科學(xué)部門如何使用R語言
2016-05-08
收藏

解密Airbnb的數(shù)據(jù)科學(xué)部門如何使用R語言

我之所以在aribnb希望成為一名數(shù)據(jù)科學(xué)家是因為這里可以有一個非常多元化的團(tuán)隊來一起解決重要的現(xiàn)實問題。我們不僅僅在性別上多樣化,而且在教育背景和工作經(jīng)歷也是霄壤之別。我們的團(tuán)隊包括數(shù)理統(tǒng)計的專家,從教育學(xué)到基因計算的博士,甚至也包括前職業(yè)橋牌選手和退伍老兵。這個訓(xùn)練和經(jīng)歷的差異性是我們團(tuán)隊創(chuàng)造性思維的強大源泉動力和理解用戶的最好武器,但是它在團(tuán)隊協(xié)作和知識共享上也對我們提出了挑戰(zhàn)。新加入Airbnb的團(tuán)隊成員通常都掌握各式各樣的編程語言,包括R、Python、Matlab、Stata、SAS或者SPSS。為了擴大協(xié)作范圍,我們借助工具、培訓(xùn)和基礎(chǔ)設(shè)施來統(tǒng)一我們的數(shù)據(jù)科學(xué)品牌。本文,我們將專注于我們在Airbnb所構(gòu)建的R語言工具和一些列的R語言教程,其中大多數(shù)的課程都是適用于Python的。

在普及R語言上,我們還是兩條腿走路:一條腿是包的構(gòu)建,另一條腿是教程。一方面,我們通過構(gòu)建包來為常見問題來開發(fā)協(xié)作方案,將可視化工作標(biāo)準(zhǔn)化并且避免重復(fù)造輪子。另一方面,教程的努力目標(biāo)在于給所有的數(shù)據(jù)科學(xué)家暴露我們所使用的特定包,并且提供深入學(xué)習(xí)各自想要學(xué)習(xí)的技能的機會。

為什么要統(tǒng)一R包

在小的數(shù)據(jù)科學(xué)團(tuán)隊中,獨立貢獻(xiàn)者經(jīng)常寫一個函數(shù)、腳本或者模板來優(yōu)化他們的工作流。而隨著團(tuán)隊成長,不同的人會開發(fā)他們自己的工具來解決類似的問題。這就帶來了三個主要的挑戰(zhàn):


  1. 團(tuán)隊在制作工具和代碼審查上重復(fù)勞動。
  2. 缺乏有效的文檔和工具使用的透明度將導(dǎo)致不正確的工具使用和bug頻頻。
  3. 對新的開發(fā)在不同開發(fā)者之間將很難共享,這進(jìn)一步導(dǎo)致開發(fā)效率的下降。


什么是 Rbnb

R開發(fā)中遇到的挑戰(zhàn)

通過GitHub企業(yè)版共享R包可以解決這三個挑戰(zhàn),這使對我們的需求是一個完美的解決方案。具體來說:


  1. 多用戶可以同時協(xié)作,共同改進(jìn)工具和解決bug。
  2. 貢獻(xiàn)者是相互評審代碼的。
  3. 新版本可以為所有用戶按需部署。
    包是R代碼可重用的最小單元。他們可以包括函數(shù)、文檔、數(shù)據(jù)、測試、插件、教程甚至是Rmarkdown模板。在兩年以前,我為內(nèi)部開發(fā)了我的第一個的R包,它后來被稱為 Rbnb。它起初只是一些函數(shù),后來這個包囊括了超過60個函數(shù),有許多積極的開發(fā)者還持續(xù)為這個包做貢獻(xiàn),這個包現(xiàn)在服務(wù)于工程部門、數(shù)據(jù)科學(xué)部門、分析部門、用戶體驗部門。時至今日,我們內(nèi)部知識倉庫已經(jīng)有將近500個使用 Rbnb包 的 R Markdown 調(diào)查報告。


這個包放在我們內(nèi)部的Github企業(yè)版?zhèn)}庫,相應(yīng)的,用戶可以提交問題和改進(jìn)建議。如果在一個分支上有新代碼被提交,那么這些代碼可以被Rbnb組內(nèi)的開發(fā)者互相審查。一旦這個改變被大家認(rèn)可并形成文檔,他們就會將新代碼融入到主分支,形成一個新版本的包。團(tuán)隊成員可以用devtools直接從Github安裝最新版本的Rbnb。我們現(xiàn)在致力于添加風(fēng)格和語法審查,并且用testthat測試覆蓋率。

Rbnb的構(gòu)成

Rbnb主要有四個組件:


  1. 一個基于我們數(shù)據(jù)基礎(chǔ)設(shè)施上的不同地點之間移動數(shù)據(jù)的一致API。
  2. 為ggplot2做了品牌化的可視化主題、拓展等
  3. 為不同類型的報告制作Rmarkdown模板,并且自定義函數(shù)來優(yōu)化我們工作流的不同部分。


Rbnb的作用

大多數(shù)我們在 Rbnb 中使用的函數(shù)允許我們從Hadoop或者SQL環(huán)境將數(shù)據(jù)移動、聚合或篩選到R里面,然后用來做可視化、自然地完成基于內(nèi)存的分析工作。在Rbnb之前,從Presto獲取數(shù)據(jù)到R里面來運行一個模型需要許多步驟。 數(shù)據(jù)科學(xué)家們需要對集群的準(zhǔn)入做認(rèn)真、打開SSH隧道、為Presto輸入主機、端口、模型、目錄數(shù)據(jù)來下載一個 csv 文件加載到R里面,這一切只是為了跑一下我們想要的模型?,F(xiàn)在,所有的這些工作可以通過兩個函數(shù)完成管道化操作。隨著 Rbnb 將這些過程隱藏在蒼穹之下,我們搞了一個像RPresto一樣維護(hù)良好的包。類似地,從R獲取數(shù)據(jù)然后移動到AWS的S3也是一行代碼搞定。數(shù)據(jù)科學(xué)家不再需要從R保存csv文件,通過我們的API秘鑰直接完成AWS的多用戶認(rèn)證配置,并且支持直接通過shell腳本將csv文件移動到云端。更加重要的是,所有函數(shù)都遵循一個類似的標(biāo)準(zhǔn)(比如,place_action(orgin,destination))。

Rbnb的優(yōu)勢

如果我們的數(shù)據(jù)基礎(chǔ)設(shè)施有所變化,-比如,如果一個集群移動或者AWS S3 認(rèn)證的細(xì)節(jié)變動 – 我們可以修改我們的Rbnb包的內(nèi)部,而不用修改我們之前定義好的函數(shù)接口。

這里展示了Rbnb中的一些函數(shù)。所有函數(shù)遵循一個類似的規(guī)范,通過綜合的代碼審查和對我們工作流的抽象減少了我們很多平常的工作。

品牌化

這個包通過一致的數(shù)據(jù)可視化風(fēng)格也幫助我們的工作在Airbnb內(nèi)部品牌化 – 比如這些又 Bar Ifrach 和 Lisa Qian 提交的示例。我們也已經(jīng)為 ggplot2、htmlwidgets、Shiny、不同報告的Rmarkdown模板的CSS樣式 構(gòu)建了自定義主題、縮放規(guī)則和設(shè)計對象。這些特性重構(gòu)了 R 字體和顏色默認(rèn)的設(shè)置,使得整體上和Airbnb的品牌保持一致。


這個 Rbnb 包也有許多函數(shù)幫助我們來完成自動化任務(wù),比如缺失值處理、按年趨勢計算、提升數(shù)據(jù)聚合性能、我們用來分析實驗的可重用模式等等。添加一個函數(shù)到這個包里可能花費很多時間,但是這最初的投資將帶來長期的回報。通過使用一樣的R包作為我們的構(gòu)建模板來開發(fā)一樣的語言、數(shù)據(jù)可視化風(fēng)格以及相互評審。

如何普及R語言

集訓(xùn)營與導(dǎo)師制

如果人們不知道怎么使用工具的話,你做了多少個工具都沒用。在一系列快速增長之后,我么年開始每月為新成員和現(xiàn)有成員做為期一周的數(shù)據(jù)集訓(xùn)營。他們包括3個小時的 R 培訓(xùn)以及一些用R和R Markdown完成的有可選導(dǎo)師的集訓(xùn)營項目。

這個R集訓(xùn)營班專注于 Rbnb 包和一些常用數(shù)據(jù)操作包的使用,包括數(shù)據(jù)框操作(比如tidyr和dplyr)、數(shù)據(jù)可視化(ggplot2)、以及動態(tài)報告撰寫(R Markdown)。我們在課程開始前會為參與者發(fā)放學(xué)習(xí)指南和資料。在上課期間,我們使用自己的數(shù)據(jù)貫穿一個結(jié)構(gòu)化的教程,包括我們以工作實例的形式展現(xiàn)一些我們在工作中遇到的挑戰(zhàn)。

這個方法允許用戶在剛開始的幾個小時里不需要熟悉R的代碼就可以開始寫代碼了,并且完全不必?fù)?dān)心高級編程方法的復(fù)雜性。我們也介紹用戶使用我們內(nèi)部風(fēng)格指南和其他許多有用的R包,比如 formattable、diagrammeR以及broom。最后,我們給他們尋求幫助和網(wǎng)絡(luò)資源的一些方向。

在集訓(xùn)營之后,我們鼓勵用戶持續(xù)學(xué)習(xí)。我們贊助每個人參加 DataCamp 來幫助團(tuán)隊成員根據(jù)自己的學(xué)習(xí)進(jìn)度組織學(xué)習(xí)小組完成可交互性的在線課程。我們也讓新人和導(dǎo)師結(jié)對,這些導(dǎo)師幫新人帶上數(shù)據(jù)科學(xué)家的臺階。我們有一個內(nèi)部R語言問答的Slack頻道。我們團(tuán)隊成員組織學(xué)習(xí)的課程主題有 SparkR、R 對象系統(tǒng)、包的開發(fā)等等。最近,我們團(tuán)隊成員參加一個由RStudio組織的高級的R開發(fā)者沙龍,并且分享了我們從團(tuán)隊成長中的點點滴滴。

我們的數(shù)據(jù)科學(xué)團(tuán)隊的成員也鼓勵Rbnb貢獻(xiàn)代碼。通過一個全面的代碼評審的過程允許用戶開發(fā)新技能將為將來的項目帶來有價值。此外,他們對一個重要的內(nèi)部工具有了主人翁精神并且從同行那里知道如何從各自的貢獻(xiàn)中受益。我們在最佳實踐、功能文檔,測試,和風(fēng)格方面都會指導(dǎo)新的貢獻(xiàn)者。

R語言社區(qū)

我們也致力于在Airbnb之外擴展R語言社區(qū)。我們贊助像即將開始的 rOpenSci Unconf 大會,為開源項目貢獻(xiàn)代碼(比如ggtech、ggradar),以及在 Shiny 開發(fā)者大會 和 UseR 大會做一些分享。去年,我們很榮幸影響到了許多R 開發(fā)者,包括 Hadley Wickham 和 Ramnath Vaidyanathan 他們也拜訪了我們在三藩市的總部。

在結(jié)構(gòu)化學(xué)習(xí)資源中這個工具變得越來越有影響力。

基礎(chǔ)設(shè)施建設(shè)

在工具和教程之外,我們也發(fā)明一些強大的數(shù)據(jù)基礎(chǔ)設(shè)施。在過去的3年間,我們的 Shiny 應(yīng)用從我們的服務(wù)器開始運行的第一天就已經(jīng)有將近10萬個頁面瀏覽量。我們最近開始支持一個新的 RStudio Server 和 SparkR 集群。我們有一個獨立主廚的R包配方以及橫跨我們集群上的版本控制,這允許我們產(chǎn)出快速的更新并且大規(guī)模部署。

總結(jié)

強大的 R 語言工具、持續(xù)學(xué)習(xí)、與R社區(qū)的緊密結(jié)合、強大的數(shù)據(jù)基礎(chǔ)設(shè)施,這些都幫助我么你的數(shù)據(jù)科學(xué)團(tuán)隊不斷成長。自從兩年以前我們開始這個動議,我們看過的團(tuán)隊成員有從未打開R到轉(zhuǎn)變成強大的開發(fā)人員現(xiàn)在都開始給我們的新員工教R。這個我們已經(jīng)建立的基礎(chǔ)允許我們雇傭一個大范圍的數(shù)據(jù)科學(xué)家來分享成長心態(tài)和學(xué)習(xí)新技能的興奮。這個方法幫助我們建立一個能為我們的工作帶來新的見解和觀點的多元化團(tuán)隊。

Rbnb R包的創(chuàng)建也激發(fā)了Python開發(fā)人員發(fā)布數(shù)據(jù)科學(xué)家的內(nèi)部稱為Airpy的Python包。我們的R開發(fā)人員也在合作開發(fā)這個包,所以這個包有一個類似的接口和函數(shù)集。我們鼓勵團(tuán)隊成員同時為Rbnb何Airpy來貢獻(xiàn)代碼,我們也在一起工作來開發(fā)更多有效的教育資源和工具來加持我們的團(tuán)隊。今天,許多我們團(tuán)隊的成員同時精通Python和R,同時用這兩張語言都可以評審和寫出可靠的代碼。在最近的一個為數(shù)66人的團(tuán)隊成員調(diào)查中,我們發(fā)現(xiàn)80%的數(shù)據(jù)科學(xué)家和分析師在R的數(shù)據(jù)分析的自我評價都是偏向于”專家”而不是”初學(xué)者”,即使其中只有64%的人將R作為他們首選的數(shù)據(jù)分析語言。類似地,47%的團(tuán)隊成員認(rèn)為自己用Python做數(shù)據(jù)分析已經(jīng)進(jìn)入專家的行列,即使只有31%的人將Python作為首選分析工具。這保留了5%表明他們同時均衡地使用這兩種工具。我們專注于建立一個同時精通兩種語言的平衡團(tuán)隊,在我們招聘的過程中也不會帶有任何偏好或偏見。這是個讓我們技能、經(jīng)歷、背景多樣化的方法又進(jìn)一步提升了團(tuán)隊的影響力。


數(shù)據(jù)分析咨詢請掃描二維碼

若不方便掃碼,搜微信號:CDAshujufenxi

數(shù)據(jù)分析師資訊
更多

OK
客服在線
立即咨詢
客服在線
立即咨詢
') } function initGt() { var handler = function (captchaObj) { captchaObj.appendTo('#captcha'); captchaObj.onReady(function () { $("#wait").hide(); }).onSuccess(function(){ $('.getcheckcode').removeClass('dis'); $('.getcheckcode').trigger('click'); }); window.captchaObj = captchaObj; }; $('#captcha').show(); $.ajax({ url: "/login/gtstart?t=" + (new Date()).getTime(), // 加隨機數(shù)防止緩存 type: "get", dataType: "json", success: function (data) { $('#text').hide(); $('#wait').show(); // 調(diào)用 initGeetest 進(jìn)行初始化 // 參數(shù)1:配置參數(shù) // 參數(shù)2:回調(diào),回調(diào)的第一個參數(shù)驗證碼對象,之后可以使用它調(diào)用相應(yīng)的接口 initGeetest({ // 以下 4 個配置參數(shù)為必須,不能缺少 gt: data.gt, challenge: data.challenge, offline: !data.success, // 表示用戶后臺檢測極驗服務(wù)器是否宕機 new_captcha: data.new_captcha, // 用于宕機時表示是新驗證碼的宕機 product: "float", // 產(chǎn)品形式,包括:float,popup width: "280px", https: true // 更多配置參數(shù)說明請參見:http://docs.geetest.com/install/client/web-front/ }, handler); } }); } function codeCutdown() { if(_wait == 0){ //倒計時完成 $(".getcheckcode").removeClass('dis').html("重新獲取"); }else{ $(".getcheckcode").addClass('dis').html("重新獲取("+_wait+"s)"); _wait--; setTimeout(function () { codeCutdown(); },1000); } } function inputValidate(ele,telInput) { var oInput = ele; var inputVal = oInput.val(); var oType = ele.attr('data-type'); var oEtag = $('#etag').val(); var oErr = oInput.closest('.form_box').next('.err_txt'); var empTxt = '請輸入'+oInput.attr('placeholder')+'!'; var errTxt = '請輸入正確的'+oInput.attr('placeholder')+'!'; var pattern; if(inputVal==""){ if(!telInput){ errFun(oErr,empTxt); } return false; }else { switch (oType){ case 'login_mobile': pattern = /^1[3456789]\d{9}$/; if(inputVal.length==11) { $.ajax({ url: '/login/checkmobile', type: "post", dataType: "json", data: { mobile: inputVal, etag: oEtag, page_ur: window.location.href, page_referer: document.referrer }, success: function (data) { } }); } break; case 'login_yzm': pattern = /^\d{6}$/; break; } if(oType=='login_mobile'){ } if(!!validateFun(pattern,inputVal)){ errFun(oErr,'') if(telInput){ $('.getcheckcode').removeClass('dis'); } }else { if(!telInput) { errFun(oErr, errTxt); }else { $('.getcheckcode').addClass('dis'); } return false; } } return true; } function errFun(obj,msg) { obj.html(msg); if(msg==''){ $('.login_submit').removeClass('dis'); }else { $('.login_submit').addClass('dis'); } } function validateFun(pat,val) { return pat.test(val); }