Pump it Up ! 資料競賽心得

David Lai
Practicode
Published in
6 min readJul 19, 2017

前幾週在一個機會下參加了人生第一個公開的資料競賽,是 DrivenData 上的 Pump it Up: Data Mining the Water Table,這個題目的動機相當單純:運用「水井」的各項特徵資料來預測這個水井的狀態是「可用的」、「需要被修復的」或是「已壞的」,這些水井大多是位於水源較缺乏的非洲,因此能夠掌握、預測這些資料對他們來說應該相當有價值。

這次競賽大概採取了以下步驟:

  1. 資料前處理
  2. Train Model
  3. Tune 出一個較好的參數

通常應該要在 2, 3 這兩點間不斷徘徊,試試不同的 Model 以及相關參數,這篇文章將會以 RandomForest 來做簡單的分享。

一、資料前處理

觀察一下這份資料可以發現一些較大的問題,首先有些 feature 存在很多 missing data,例如 population大約有 36% 是空白,再者有些 feature 間重複性很高,例如 extraction_type 以及 extraction_type_group ,另外也有 feature 的 level 太高:總共有五萬多筆資料,某個 feature 值的種類就有兩萬多個。

基於資料相當複雜,這個部分參考了討論區一位大大的作法,主要是做:

  1. 刪除一些重複、Level 過高、無意義的 feature。
  2. 有鑑別力但 Level 過高的 feature 取出前 10 大類,其餘轉換成「Other」
  3. 補上 missing data,例如 population 使用其他筆資料相同 subvillage 或更上級區域的人口數來補。
  4. 將類別資料轉換為 dummy variable,假設 extraction_type 有五種,就把每一種分別拆成一種 feature (extraction_type_A , extraction_type_B …)並以 0 或 1 表示是否是這個 extraction_type
  5. 各個 feature 進行 Normalization,這次使用的是標準化的方法。

總之,去除鑑別力低的、降低 level 減少 feature 數量、轉換成數值型態,以方便接下來進行 training。

經過處理後資料的樣子

二、Train Model

我選用的是 RandomForest 分類器,並使用 R 的 library 來實作。

在 R 中進行 RF training 的程式大致是這樣寫:

rf = randomForest(x=<training_features>, y=<training_categories>, ntree=rfntree, mtry=best_mtry, xtest=<testing_features>, ytest=<testing_features>)

介紹一下幾個用到的參數:

  1. x:訓練資料的 features,EX: training_data[,2:ncol(training_data)] (假設 2~n 行為 features)
  2. y:訓練資料的 categories,EX: training_data[,1] (假設類別在第一行)
  3. ntree:訓練時進行 ensemble(投票) 的 tree 數量
  4. mtry:訓練時每個 tree 隨機選擇的 features 數量
  5. xtest:model 訓練完成後進行 testing 的 x (features)
  6. ytest:model 訓練完成後進行 testing 的 y (categories)

這樣得到的 rf 就是一個訓練完成並且使用 xtest, ytestvalidate 的結果了,可以使用 rf$test$predicted 去得到 test data 的預測值,並與 ytest 的正確結果比對來計算 Accuracy。

三、Tune 出好的參數

能會使用 RandomForest 後,我們就要試著讓它的 Accuracy 更好。

Accuracy = 正確預測的數量 / 總共的數量

在 RandomForest 之中最重要的兩個參數是 ntree 以及 mtry,分別是指在 Training 的過程中建構的決策樹數量和每棵樹選擇多少 features 作為決策因子,我們可以藉由持續調整這兩個參數來實驗在這次的資料中最適合的參數。

ntree 我實驗了 200, 250, 300, 350 … 600,每 50 一個間隔,得到大約 400 棵樹有較好的 Accuracy。

mtry 是建構樹使用 feature 的數量,因此可以知道最小為 1,最大為總共 feature 的數量,而我們要決定要使用 n 個 mtry 來 tune。 RandomForest 的特色之一就是讓每棵樹都是選擇不同的 feature set 建成,因此各自有各自的專長,遇到問題再來投票決定,因此若是每棵樹都選擇過多的 feature 來建構反而可能使的樹之間的差異太小,所以 mtry 的值並不是在 1~max 之間平均間隔,而是偏向少一點的多選一點,因此採用 Log Linear 的取法:

min, max 分別取 Log 後取出 n 個間隔相等的值,再分別用指數算回來,寫成 R code 大概是

mtries = unique(round(exp(seq(log(min), log(max), length=n))))

例如 min = 1, max = 600, n = 15 得到的結果會是:1, 2, 4, 6, 10, 16, 24, 39, 61, 96, 152, 241, 380, 600。

分別下去實驗後可以找出在哪個區間有較好的 Accuracy,再進一步在那個區間內更仔細的調整參數。

在 tuning 的過程中我們其實也只能對已經有答案的資料做 validate,線上的測試資料是拿不到的,因此我們要盡量讓驗證資料的分布與線上的測試資料相符,這樣 tune 出來的參數才能盡可能的有效。

結論

最後藉由以上的方法,在這項比賽中得到 0.8209 的準確率,名次在比賽的前 7%,還有相當多的進步空間。

資料競賽其實是一個不斷嘗試的過程,從前處理的方式、選擇 Model、調整參數等等,都需要很多的 trial and error,不過在嘗試的過程中也能慢慢了解到各個 Model 的特性,建立起在 data mining 中的一些概念。

鼓勵大家也去尋找自己有興趣的競賽來參與、累積經驗以及與其他參賽者互相交流!

--

--

David Lai
Practicode

Work in recommendation system and NLP algorithms. Microsofter in Redmond, Suzhou and Taiwan