天天看點

MDD Cup 2017 小記 (美團點評内部算法比賽)

gbdt版本

    MDD Cup 2017,是 美團點評内部首屆算法大賽,主要是預測外賣的送達時間,是一個回歸問題,簡單說一說比賽過程自己的所思所想,記錄一下。     拿到資料後,根據大賽的說明簡單分析了一下,訓練集給出的是一個月的部分資料,測試集是下一個月的資料,需要注意的是訓練集給出的是每天24h的資料,而測試集隻需要預測11點和17點高峰時期兩個小時的資料,而且給出了10點和16點的資料用來輔助分析(測試集每天隻有4個小時的資料)。因為測試隻需要高峰期的資料,訓練資料集需要和測試資料集分布一緻,首先看一下訓練資料集每天每個小時的訂單分布(如下圖),用來篩選資料,去除無效的資料。根據圖中每個小時的訂單數量分布,我們隻留下了10點到20點的資料。我們希望盡量保留多的資料用來訓練,模型的效果取決于資料、特征和參數,有效資料越多,泛化性就越好。

MDD Cup 2017 小記 (美團點評内部算法比賽)

    還有就是,驗證集合的劃分我們隻保留了11點和17點的資料,保證驗證集合和測試集合的資料分布一緻,當然為了保證資料的一緻性,還有很多更細緻的工作需要做,這是一大塊内容。 再看一下我們的label(每一個訂單的配送時間),首先需要去除噪音,過濾掉配送時間太短和太長的資料。然後看分布,訓練資料的label原始分布如下左圖,做平滑後分布如右圖,目的是希望label的分布盡量符合正态分布,這裡用的是np.log1p(label),後面需要對應用np.expm1()做還原,同樣這裡可以進一步往下做,例如我們訓練資料中30分鐘左右的資料都可把label變成30分鐘的來做。這裡做到這一步已經差不多了,模型訓練好以後,預測的lable也可以用同樣方式做分析。

MDD Cup 2017 小記 (美團點評内部算法比賽)

    下面看一下特征,特征決定了模型的上限,在比賽宣講中燕鵬大神就反複提醒大家,最後模型融合的效果取決于單模型的好壞,而單模型的好壞取決于特征的好壞,其實大部分人都會用到原始特征、統計特征、組合特征、複雜特征和未來的資訊的特征,最後再模型融合應該是可以進入400的(這個比賽的評價名額是MAE,機關是秒),但以後更進一步,就需要在每一個環節做更多更細緻的工作,下足功夫才行。     先說幾個點, 因為往往其中任何一個出現問題,就會讓人崩潰到放棄。一個是在類别特征的處理上,xgboost是不支援類别型特征的,如果要使用它需要進行one-hot編碼,如果編碼之後次元增加的很大,就會導緻單機訓練特别慢,有時可以慢到一天疊代不了幾次,疊代的速度太慢是比賽的大忌,也很容易讓人崩潰,這裡給一個針對xgboost的解決方案,就是把類别型的特征變成數值型,再放到xgboost裡面,其實我碰到的很多比賽,包括工作中,這種方式是和one-hot編碼之後的效果差不太多的,但速度卻可以提高很多。至于如何解釋這種現象,就是當樹很深的時候,其實就可以看成是一種one-hot的編碼了,但實際中樹完全不用很深就可以達到one-hot的效果,也可能這些個别的案例都讓我碰到了。     lightGBM是支援類别特征處理的,就是不需要我們做one-hot編碼,直接表識出類别型的特征,lightGBM就會自己處理。這裡需要說的一點是,有幾個版本中如果辨別了類别特征,lightGBM就會挂掉,這其實是一個bug,最新版的lightGBM已經修複了。     還有就是比賽中,如果能用lightGBM就不要用xgboost,因為後期當特征提取到一定數量時候,xgboost就會慢到讓人崩潰的地步,一天疊代不了幾次,而lightGBM幾分鐘就可以疊代一次,真是讓人爽爆。     因為每天的送出次數不超過5次,是以如何劃分資料集,能夠使得,離線的提升,送出後同樣可以得到提升是至關重要的,這就相當于你可以無限送出,但是一般比賽中都是很難找到離線有提升,送出後就一定有提升的資料集劃分方式,對于比賽中碰到離線有提升,而送出之後反而下降的情況是再正常不過的了,離線突然提升很多,送出後效果大幅下降,一般都是提取了過拟合的特征。     先說下第一名的方案,就是用的cv交叉驗證方式,假設每天都是獨立的,将資料按照天平均劃分然後做交叉驗證。第三名的做法是巧妙的利用了測試集前一個小時後十五分鐘的資料作為離線的驗證集,認為每天前一個小時和測試資料最相近。一種是離線用20天訓練,5天測試,5天驗證,還有很多其他方式這裡不一一列舉,當然還可以憑感覺,例如每次gbdt每次疊代的輪數。     模型訓練完之後,我們就要分析下特征重要性,其實初次入手xgboost和lightGBM的一般都會隻使用預設的F值特征重要性排序,而沒有認識到gain排序的作用,要說明一點這些名額都是輔助我們分析模型的,排序靠前的特征并不一定說明這個特征很重要,就是說如果我們在模型中去掉這維特征,模型的效果不一定會下降,有可能還會提升,特别是當提取的特征重要性高,但是模型效果沒有提升反而下降的時候,不要急于把這個特征丢掉,可以用來做其他模型,然後進行模型融合,這就是用多個gbdt融合的原因之一。     xgboost版本:model.get_score(importance_type='gain')     lightGBM版本:model.feature_importance(importance_type='gain')

    說到如何才能提取到有效的特征,除了盲目的按照套路來各種提取特征,各種嘗試之外,最重要的就是要了解業務,首先要想明白到底哪些因素,決定了騎手的送餐時間,本次比賽官方給出的有

  • 訂單:下單時刻、價格、菜品數
  • 使用者:使用者位置
  • 騎手:騎手負載
  • 商家:出餐能力、地理位置、積壓的訂單
  • 區域:騎手數、單量
  • 時間:午高峰期、晚高峰期、非高峰期
  • 天氣資料:溫度、風速、降水量

    我們提取特征的時候,應該圍繞着這些因素,我私下和部分騎手聊過這個問題(從騎手的角度來看,每次送餐到底什麼決定了送餐的時間),了解到的關鍵因素有商家的出餐能力和本區域的負載情況,還有最重要的是騎手每次送餐系統都會有一個預估時間,騎手如果超出這個時間,會有懲罰,這個預估時間對騎手至關重要,如果騎手有多單要送,會根據這個時間來調整配送的先後順序,是以,我當時也在想是不是模型越接近系統給出預估時間的這個模型,預測的就越準确,搞來搞去不就是在拟合原來的模型麼。總之一路做下來,感覺隻有我們足夠深入的了解接觸這個業務,才能給提取出更多有效的特征,比賽是需要大量時間和精力的,每次想到這裡我都要顫抖下,因為想到我的中間頁排序還有好多好多的工作要做。 

美團 算法工程師 目前主要負責中間頁排序

繼續閱讀