近期,comSysto公司分享了該公司研發(fā)團隊利用Spark平臺解決Kaggle競賽問題的經(jīng)歷,為Spark等平臺應(yīng)用于數(shù)據(jù)科學(xué)領(lǐng)域提供了借鑒。
主辦方提供了一個包含5萬個匿名駕駛員線路的數(shù)據(jù)集,競賽的目的是根據(jù)路線研發(fā)出一個駕駛類型的算法類簽名,來表征駕駛員的特征。例如,駕駛員是否長距離駕駛?短距離駕駛?高速駕駛?回頭路?是否從某些站點急劇加速?是否高速轉(zhuǎn)彎?所有這些問題的答案形成了表征駕駛員特征的獨特標(biāo)簽。
面對此挑戰(zhàn),comSysto公司的團隊想到了涵蓋批處理、流數(shù)據(jù)、機器學(xué)習(xí)、圖處理、SQL查詢以及交互式定制分析等多種處理模型的Spark平臺。他們正好以此挑戰(zhàn)賽為契機來增強Spark方面的經(jīng)驗。接下來,本文就從數(shù)據(jù)分析、機器學(xué)習(xí)和結(jié)果等三個方面介紹comSysto團隊解決以上問題的過程。
數(shù)據(jù)分析
作為解決問題的第一個步驟,數(shù)據(jù)分析起著非常關(guān)鍵的作用。然而,出乎comSysto公司團隊意料的是,競賽提供的原始數(shù)據(jù)非常簡單。該數(shù)據(jù)集只包含了線路的若干匿名坐標(biāo)對(x,y),如(1.3,4.4)、(2.1,4.8)和(2.9,5.2)等。如下圖所示,駕駛員會在每條線路中出發(fā)并返回到原點 (0,0),然后從原點挑選隨機方向再出發(fā),形成多個折返的路線。
拿到數(shù)據(jù)后,comSysto公司的團隊有些氣餒:只看坐標(biāo)很難表征一個駕駛員吧?!
信息指紋的定義
因此,在原始數(shù)據(jù)如此簡單的情況,該團隊面臨的一個問題就是如何將坐標(biāo)信息轉(zhuǎn)換為有用的機器學(xué)習(xí)數(shù)據(jù)。經(jīng)過認(rèn)證思考,其采用了建立信息指紋庫的方法,來搜集每一個駕駛員有意義和特殊的特征。為了獲得信息指紋,團隊首先定義了一系列特征:
距離:所有相鄰兩個坐標(biāo)歐氏距離的總和。絕對距離:起點和終點的歐氏距離。線路中停頓的總時間:駕駛員停頓的總時間。線路總時間:某個特定線路的表項個數(shù)(如果假設(shè)線路的坐標(biāo)值為每秒鐘記錄的數(shù)值,路線中表項的個數(shù)就是線路的總秒數(shù))。速度:某個點的速度定義為該點和前一個點之間的歐氏距離。假設(shè)坐標(biāo)單位為米、坐標(biāo)之間的記錄時間間隔為1秒,該定義所給出的速度單位就為m/s。然而,本次分析中,速度主要用于對比不同點或者不同駕駛員。只要速度的單位相同即可,并不追求其絕對值。對于加速、減速和向心加速度,該說明同樣成立。加速度:加速時,該點和前一點速度的差值減速度:減速時,該點和前一點速度的差值向心加速度:其中,v為速度、r為曲線路徑所形成圓的半徑。半徑計算需要用到當(dāng)前點、之前和之后的若干個點的坐標(biāo)信息。而,向心加速度是對駕駛員高速駕駛風(fēng)格的體現(xiàn):該值越大表明轉(zhuǎn)彎的速度越快。
一個駕駛員所有線路的上述特征組成了其簡歷(信息指紋)。根據(jù)經(jīng)驗,城市道路和高速道路上的平均速度是不同的。因此,一個駕駛員在所有線路上的平均速度并沒有很多意義。ecoSysto選擇了城市道路、長距離高速道路和鄉(xiāng)村道路等不同路線類型的平均速度和最大速度作為了研究對象。
數(shù)據(jù)統(tǒng)計:根據(jù)統(tǒng)計,本次競賽的數(shù)據(jù)集中共包含了2700個駕駛員,共54000個線路的信息。所有的線路共包含3.6億個X/Y坐標(biāo)——以每秒記錄一個坐標(biāo)來算,共包含10萬個小時的線路數(shù)據(jù)。
機器學(xué)習(xí)
在初步的數(shù)據(jù)準(zhǔn)備和特征提取后,ecoSysto團隊開始選擇和測試用于預(yù)測駕駛員行為的機器學(xué)習(xí)模型。
聚類
機器學(xué)習(xí)的第一步就是把路線進行分類——ecoSysto團隊選擇k-means算法來對路線類型進行自動分類。這些類別根據(jù)所有駕駛員的所有路線推導(dǎo)得到,并不針對單個駕駛員。在拿到聚類結(jié)果后,ecoSysto團隊的第一感覺就是,提取出的特征和計算得到的分類與路線長度相關(guān)。這表明,他們能夠作為路線類型的一個指針。最終,根據(jù)交叉驗證結(jié)果,他們選擇了8種類型——每條路線指定了一種類型的ID,用于進一步分析。
預(yù)測
對于駕駛員行為預(yù)測,ecoSysto團隊選擇一個隨機森林(random forest)算法來訓(xùn)練預(yù)測模型。該模型用于計算某個特定駕駛員完成給定路線的概率。首先,團隊采用下述方法建立了一個訓(xùn)練集:選擇一個駕駛員的約 200條路線(標(biāo)為“1”——匹配),再加隨機選擇的其他駕駛員的約200條路線(標(biāo)為“0”——不匹配)。然后,這些數(shù)據(jù)集放入到隨機森林訓(xùn)練算法中,產(chǎn)生每個駕駛員的隨機森林模型。之后,該模型進行交叉驗證,并最終產(chǎn)生Kaggle競賽的提交數(shù)據(jù)。根據(jù)交叉驗證的結(jié)果,ecoSysto團隊選擇了10 棵樹和最大深度12作為隨機森林模型的參數(shù)。有關(guān)更多Spark機器學(xué)習(xí)庫(MLib)中用于預(yù)測的集成學(xué)習(xí)算法的對比可參考Databrick的博客。
流水線
ecoSysto團隊的工作流劃分為了若干用Java應(yīng)用實現(xiàn)的獨立步驟。這些步驟可以通過“spark-submit”命令字節(jié)提交給Spark執(zhí)行。流水線以Hadoop SequenceFile作為輸入,以CSV文件作為輸出。流水線主要包含下列步驟:
轉(zhuǎn)換原始輸入文件:將原有的55萬個小的CSV文件轉(zhuǎn)換為一個單獨的Hadoop SequenceFile。提取特征并計算統(tǒng)計數(shù)字:利用以上描述的定義計算特征值,并利用Spark RDD變換API計算平均值和方差等統(tǒng)計數(shù)字,寫入到一個CSV文件中。計算聚類結(jié)果:利用以上特征和統(tǒng)計值以及Spark MLlib的API來對路線進行分類。隨機森林訓(xùn)練:選取maxDepth和crossValidation等配置參數(shù),結(jié)合每條線路的特征,開始隨機森林模型的訓(xùn)練。對于實際Kaggle提交的數(shù)據(jù),ecoSysto團隊只是加載了串行化的模型,并預(yù)測每條線路屬于駕駛員的概率,并將其以CSV格式保存在文件中。結(jié)果
最終,ecoSysto團隊的預(yù)測模型以74%的精度位列Kaggle排行榜的670位。該團隊表示,對于只花2天之間就完成的模型而言,其精度尚在可接受范圍內(nèi)。如果再花費一定的時間,模型精度肯定可以有所改進。但是,該過程證明了高性能分布式計算平臺可用于解決實際的機器學(xué)習(xí)問題。