基於 XGBoost 對 Santander 銀行用戶購買行為進行預測
來自專欄數據池塘7 人贊了文章
Santander Product Recommendation 是我去年做的一個數據挖掘 project,簡單來說就是,給了一定量的數據,用合適的演算法對這些數據進行建模分析,給出預測,從而挖掘出有價值的信息。這也是目前互聯網金融公司重點關注的工作內容之一,由於最近在準備面試,回顧之前做過的項目,想重點總結一下這個項目。
項目簡介
Santander 銀行成立於西班牙,也稱作西班牙國際銀行,是西班牙最大銀行、歐元區最大銀行,在美國街頭也是隨處可見。關於這個產品推薦項目,Santander 官方發布在 Kaggle 上,給出了 2.29G 的數據集,有 48 個 column,其中包括用戶個人資料和歷史購買產品記錄。我們要基於這些數據來預測新用戶在未來可能的購買行為,從而幫助 Santander 構建一個高效的產品推薦系統。
數據初探
首先需要對數據集進行清洗,之前在專欄里也記錄過相關的步驟:
- Kaggle 數據清洗挑戰 Day 1 - 手把手教你五步處理缺失值
- Kaggle 數據清洗挑戰 Day 2 - 數據縮放及標準化處理
- Kaggle 數據清洗挑戰 Day 3 - 快速解析日期(date)數據
- Kaggle 數據清洗挑戰 Day 4 - 字元編碼(Character Encoding)處理
- Kaggle 數據清洗挑戰 Day 5 - 處理不一致數據
詳細內容不再贅述,只記錄一下特殊的點,例如:有一個 column 叫做 renta,代表該用戶的家庭總收入 (gross income of household),其中一些用戶的 renta 數據是缺失的,那麼就需要我們去填充,對於這個指標,用 renta 的中位數來填補就比用平均數合理得多,因為可以排除貧富差距過大帶來的誤差。
數據清洗完成後,就可以藉助各種工具包進行分析了。
上面是 Santander 用戶的年齡分布圖,我們發現有兩個波峰,大量用戶分布在 20~30 和 40~50 這兩個年齡段之間。
上圖左側列出的是各種產品的代號,我們發現同一個群體會傾向於選擇相同產品,這也是我們做大多數數據挖掘工作的基礎。
演算法介紹
該項目是基於 XGBoost 演算法的,XGBoost 是改進自 GBDT (Gradient Boosting Decision Tree) 的,下面簡單介紹一下這個演算法的原理。Gradient Boosting 是一種機器學習策略,具體來說就是我們先建立一些簡單的小模型,也就是 model tree,這些決策樹是非常淺的,所以它們給出的結果的準確度也比較低。但把它們結合起來就可以得到一個高級的決策樹,這裡體現了 boosting 的概念。在每一層的決策中,給出一個得分,最後得到一個總分,來給出最終判斷結果。
下面這個圖片簡單呈現了決策樹的工作原理:
相比於神經網路,決策樹的工作過程更加清晰,我們可以看到它是如何得到最終的結果的。
關於 GBDT 演算法的原理之後會再寫一篇文章來詳細介紹,XGBoost 相比於 GBDT 更加複雜,做了很多細節改進,包括損失函數、正則化、稀疏感知演算法、並行化演算法設計等等。XGBoost 近幾年在各種競賽中也頻頻被大神們選中,並取得很好的結果。
XGBoost 相比於 GBDT 的改進點有很多,其中重要的幾個為(基於網上大神們的總結再做二次總結):
1. 傳統 GBDT 以 CART 作為基分類器,XGBoost 還支持線性分類器,這個時候 XGBoost 相當於帶 L1 和 L2 正則化項的邏輯斯蒂回歸(Logistic Regression)或者線性回歸(Linear Regression)。
2. 傳統 GBDT 在優化時只用到一階導數信息,XGBoost 則對代價函數進行了二階泰勒展開,同時用到了一階和二階導數。3. XGBoost 在代價函數里加入了正則項,用於控制模型的複雜度。4. Shrinkage(縮減),相當於學習速率(XGBoost 中的 eta)。XGBoost 在進行完一次迭代後,會將葉子節點的權重乘上該係數,主要是為了削弱每棵樹的影響,讓後面有更大的學習空間。實際應用中,一般把 eta 設置得小一點,然後迭代次數設置得大一點。5. 列抽樣(Column Subsampling)。XGBoost 借鑒了隨機森林的做法,支持列抽樣,不僅能降低過擬合,還能減少計算,這也是 XGBoost 異於傳統 GBDT 的一個特性。6. 可以處理稀疏、缺失數據。對於特徵的值有缺失的樣本,XGBoost 可以自動學習出它的分裂方向。7. XGBoost 工具支持並行。特徵列排序後以塊的形式存儲在內存中,在迭代中可以重複使用;雖然 boosting 演算法迭代必須串列,但 XGBoost 的並行是基於特徵列的。決策樹的學習最耗時的一個步驟就是對特徵值進行排序(因為要確定最佳分割點),XGBoost 在訓練之前,預先對數據進行了排序,然後保存為塊結構,後面的迭代中重複使用這個結構,大大減小計算量。這個塊結構使並行成為可能,在進行節點分裂時,需要計算每個特徵的增益,最終選增益最大的那個特徵去做分裂,那麼各個特徵的增益計算就可以多線程進行。
XGBoost 基於 block 結構的存儲形式,實現了並行計算,尤其對於這個包含 48 個 column 的數據集,大大提高了速度。
特徵工程
所謂機器學習,就是讓機器對大量的數據進行學習分析,然後給出有用的結論和預測結果。而這個學習過程中很重要的一個部分就是特徵工程,即把原始數據轉變為模型的訓練數據的過程,以獲取更好的訓練數據特徵。一般來說,特徵工程包括特徵構建、特徵生成、特徵選擇三個部分。
特徵構建是指從原始數據中,人工找出一些對後續數據挖掘有意義的特徵,需要花時間去觀察原始數據,對實戰經驗的要求較高。屬性分割和結合是特徵構建的常用方法,可以將一個屬性分割成多個特徵,也可以組合幾個不同的屬性成新的特徵。
特徵生成和特徵構建有一些相似,但也存在區別。比如通過主成分分析對原始數據進行降維,那麼降維後,每個主成分就代表一個新的特徵。
通俗來講,特徵構建和特徵生成都是想辦法來生成新的特徵,以用來讓機器學習。
由於該項目中數據集的 column 都很簡單,沒有進行新的特徵構建和生成,只用到了特徵選擇,提取了一些顯著性比較高的特徵,去除掉對結果影響較小的特徵。
我們看到選取的特徵有兩種,一種是 numeric,另一種是 categrical,具體項目中有許多 column 的值是非數字的,這就需要我們使用工具來對其進行轉化,關於這個步驟我在以前的文章中也有寫過 —— 《數據預處理之將類別數據數字化的方法 —— LabelEncoder VS OneHotEncoder》。
全部準備就緒後,就要使用 cross validation 進行調參啦。關於 XGBoost 中的參數介紹,可以查看官方文檔~
我用到的 parameter 有:
num_round = 500early_stop = 10xgb_params = { booster: gbtree, max_depth: 2, learning_rate: 0.03, nthread: 4, objective: multi:softprob, num_class: 15, silent: 1, eval_metric: mlogloss, seed: 500,}
booster:基學習器類型,有兩種選擇,分別是樹模型(gbtree)和線性模型(linear models),此處選擇的是樹模型;
max_depth:樹的最大深度,控制樹的複雜度,可以用來避免過擬合,max_depth 越大,模型能學到的樣本也越具體;
learning_rate:學習速率;
nthread:控制並發執行的個數,即在幾個核上運行,如果不設置,即默認開啟計算機全部的核;
objective:定義需要被最小化的損失函數,這裡選擇的是 multi:softprob,設置 XGBoost 進行多類別分類,返回的是數據屬於每個類別的概率,然後需要多設置一個 num_class;
num_class:即上述多類別分類中的類別數目;
eval_metric:設置評估函數,這裡選擇的是 mlogloss,即 Multiclass logloss;
seed:隨機數的種子,用於調參。
提交預測
做完 cross validation 得到合適的參數後,就可以進行結果預測了。根據預測的概率大小,提交每個用戶未來可能購買的產品,按概率進行排序,可以設置循環的次數決定輸出的產品數目。最後的預測結果保存在 csv 文件中,如下:
推薦閱讀:
※機器學習評估指標
※Python 數據分析(四):數據的處理
※Smart乾貨知識分享丨自然語言處理系統在餐飲業中的應用
※推薦系統必讀論文清單
※牢地基築高樓,美林數據在電力和製造業穩紮穩打