常規參數
XGBoost全名叫(eXtreme Gradient Boosting)極端梯度提升,經常被用在一些比賽中,其效果顯著。它是大規模並行boosted tree的工具,它是目前最快最好的開源boosted tree工具包。XGBoost 所應用的算法就是 GBDT(gradient boosting decision tree)的改進,既可以用於分類也可以用於迴歸問題中。
1、迴歸與分類
事實上,分類與迴歸是一個型號的東西,只不過分類的結果是離散值,迴歸是連續的,本質是一樣的,都是特徵(feature)到結果/標籤(label)之間的映射。分類樹的樣本輸出(即響應值)是類的形式,如判斷蘑菇是有毒還是無毒,週末去看電影還是不去。而回歸樹的樣本輸出是數值的形式,比如給某人發放房屋貸款的數額就是具體的數值,可以是0到120萬元之間的任意值。
2、背景
對某個query召回的多條list進行排序
檢索詞條(query):query分析----------->------------文檔(doc):檢索結果----------->------------搜索結果(list),排序處理
搜索這一過程的本質是自動選取與用戶輸入的關鍵詞(query)最相關的一組文檔(docs,或稱網頁,urls)的過程。目前主要通過如下兩個步驟實現:
(1)query-doc匹配:尋找與當前輸入的query相關度高的docs(粗排)
(2)高相關度docs精確排序:對(1)中返回的docs,選取更多特徵並按照用戶點擊該doc的可能性大小精確排序。有時我們還會選擇不同的特徵,召回多組(1)並將它們通過排序算法融合爲一組。(精排)
Learning to Rank是一種用來實現步驟(2)的機器學習模型。它使用機器學習的方法,可以把各個現有排序模型的輸出作爲特徵,然後訓練一個新的模型,並自動學得這個新模型的參數,從而很方便的可以組合多個現有的排序模型來生成新的排序模型。
Learning to Rank算法
下圖爲機器學習排序的原理圖,機器學習排序系統由4個步驟組成——人工標註訓練數據、文檔特徵抽取、學習分類函數、在實際搜索系統中採用機器學習模型。
- 關於樣本集
選取了兩個月用戶的搜索數據特徵,以用戶的點擊行爲爲標籤。
數據處理:每個不同query會存在多個召回列表,有的存在點擊行爲,有的無點擊行爲,需要對同query不同list及不同query的list的點擊行爲量化,使其具有可比性,由於不同query的熱度有差異,所以不同query的點擊行爲沒有可比性,因此對query召回的list做歸一化處理(包括特徵和點擊),這樣每個query的點擊及各特徵都是一個歸一化的數據,從而使得不同query的list具有可比性。
訓練前進一步處理,雖然已經歸一化處理過,但在訓練前對數據進一步歸一化是很有必要的,代碼如下,實驗證明該部分對模型的準確性影響很大。
ss = MinMaxScaler()
ss=StandardScaler()
X_train = ss.fit_transform(X_train)
- 關於特徵
搜索引擎會使用一系列特徵來決定結果的排序。一個特徵稱之爲一個“feature”。按照我的理解,
feature可以分爲3大類:
(1)Doc本身的特徵:Pagerank、內容豐富度、是否是spam、質量值、CTR等
(2)Query-Doc的特徵:Query-Doc的相關性、Query在文檔中出現的次數,査詢詞的Proximity值(即在文檔中多大的窗口內可以出現所有査詢詞)等。當然,有些Query-Doc的特徵不是顯式的,而是有Semantic的,即雖然Query在文檔中沒有出現,但是語義上是有關係的。
(3)Query的特徵:Query 在所有Query 中的出現次數、比率等。此階段就是要抽取出所有的特徵,供後續訓練使用。
特徵選擇:type_id,num_comment,num_photo,text_score,recall_intention,recall_term,recall_food,recall_prefix,recall_match,tag_match
type_id:POI類型
num_comment:峯評數num_photo:圖片數text_score:質量分recall_intention:意圖召回源標記recall_term:精準召回源標記recall_food:美食召回源標記recall_prefix:前綴召回源標記recall_match:模糊召回源標記tag_match:標籤召回源標記
- 關於模型
Learning to Rank主要包含pointwise方法、pairwise方法和listwise方法三種類型。
(1)pointwise方法:對於某一個query,它將每個doc分別判斷與這個query的相關程度,由此將docs排序問題轉化爲了分類(比如相關、不相關)或迴歸問題(相關程度越大,迴歸函數的值越大)。
(2)pairwise方法:pairwise方法並不關心某一個doc與query相關程度的具體數值,而是將排序問題轉化爲任意兩個不同的docs di和dj誰與當前的query更相關的相對順序的排序問題。一般分爲di比dj更相關、更不相關和相關程度相等三個類別,分別記爲{+1, -1, 0},由此便又轉化爲了分類問題。
(3)listwise方法:將一個query對應的所有相關文檔看做一個整體,作爲單個訓練樣本。
3、代碼
- 模型的訓練:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Mon Oct 14 15:29:52 2019
poi排序模塊xgb模型訓練
@author: huamin
"""
import numpy as np
import pandas as pd
from xgboost.sklearn import XGBClassifier
from sklearn import metrics
import xgboost as xgb
# from sklearn.grid_search import GridSearchCV
from sklearn.model_selection import GridSearchCV
from sklearn.preprocessing import MinMaxScaler # 最大最小歸一化
from sklearn.preprocessing import StandardScaler # 標準化
from sklearn.model_selection import train_test_split # 劃分數據集
from sklearn.model_selection import cross_val_score
from xgboost import plot_importance
import matplotlib.pyplot as plt
def trainandTest(X_train, y_train, X_test, y_test):
# XGBoost訓練過程,下面的參數就是剛纔調試出來的最佳參數組合
model = xgb.XGBRegressor(
base_score=0.5,
booster='gbtree',
colsample_bylevel=1,
colsample_bytree=0.9,
gamma=0,
importance_type='gain',
learning_rate=0.1,
max_delta_step=0,
max_depth=5,
min_child_weight=0.2,
missing=None,
n_estimators=250,
n_jobs=1,
nthread=None,
objective='reg:linear',
random_state=0,
reg_alpha=0,
reg_lambda=0.8,
scale_pos_weight=1,
seed=None,
silent=True,
subsample=1
)
model.fit(X_train, y_train)
model.save_model('/Users/huamin/Desktop/xgb1029d.model') # 用於存儲訓練出的模型
test_preds = pd.DataFrame({"label": y_test})
test_preds['y_pred'] = model.predict(X_test)
stdm = metrics.r2_score(test_preds['label'], test_preds['y_pred'])
print(stdm)
ans = model.predict(X_test)
ans_len = len(ans)
id_list = np.arange(10441, 177441)
data_arr = []
for row in range(0, ans_len):
data_arr.append([int(id_list[row]), ans[row]])
np_data = np.array(data_arr)
pd_data = pd.DataFrame(np_data, columns=['id', 'y'])
pd_data.to_csv('submit.csv', index=None)
# 顯示重要特徵
plot_importance(model)
plt.show()
print(model.feature_importances_)
if __name__ == '__main__':
data = pd.read_csv('/Users/huamin/Desktop/file/iris11.csv', header=None)
# 0-9列爲特徵
X = data.iloc[:, 0:10]
# 第10列爲標籤
y = data.iloc[:, 10]
# 劃分訓練集和測試集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=0)
# 此處採用最大最小歸一化, 可以換成StandardScaler()歸一化方法,如果用StandardScaler()方法的話,則不能使用MultinomialNB()模型
ss = MinMaxScaler()
ss=StandardScaler()
X_train = ss.fit_transform(X_train)
X_test = ss.transform(X_test)
trainandTest(X_train, y_train, X_test, y_test)
- 預測效果:
def predict():
#測試數據
dtest = loadtxt( '/Users/huamin/Desktop/ttt.csv', delimiter=",")
dtest = dtest[:,1:11]
dt = loadtxt( '/Users/huamin/Desktop/ttt.csv', delimiter=",",usecols=(0,0), dtype=int )#每條數據對應的id信息
dtest=xgb.DMatrix(dtest)
model = xgb.Booster(model_file='/Users/huamin/Desktop/xgb111.model')
plot_importance(model)
plt.show()
print(model.feature_importances_)
ans = model.predict(dtest) #預測的結果,標籤
#print(ans)
ans_len = len(ans)
data_arr = []
for row in range(0, ans_len):
data_arr.append([dt[row][0], ans[row]]) #預測結果poiid,得分值對
np_data = np.array(data_arr)
pd_data = pd.DataFrame(np_data)
#將預測結果寫入文件
pd_data.to_csv('/Users/huamin/Desktop/submit.csv', index=None)
test = loadtxt( '/Users/huamin/Desktop/submit.csv', delimiter=",")
print(test)
print("預測結束,請查看桌面submit.csv")
- 調參篇:
if __name__ == '__main__':
data=pd.read_csv('/Users/huamin/Desktop/iris0.csv',header=None)
#0-10列爲特徵
file_out = '/Users/huamin/Desktop/data/cvsdata.csv'
file_in = '/Users/huamin/Desktop/data/data.txt'
file_mid = '/Users/huamin/Desktop/data/mid.csv'
file_result = "/Users/huamin/Desktop/data/result.csv"
mfile = '/Users/huamin/Desktop/xgb111.model'
X=data.iloc[:,0:10]
#第11列爲標籤
y=data.iloc[:,10]
#劃分訓練集和測試集
X_train,X_test,y_train,y_test=train_test_split(X,y,test_size=0.3,random_state=0)
#此處採用最大最小歸一化, 可以換成StandardScaler()歸一化方法,如果用StandardScaler()方法的話,則不能使用MultinomialNB()模型
ss=MinMaxScaler()
ss=StandardScaler()
X_train=ss.fit_transform(X_train)
X_test=ss.transform(X_test)
#trainandTest(X_train, y_train, X_test)
pred(mfile, file_out,file_mid)
'''
cv_params = {'n_estimators': [0,10,20,30,40,45,50,55,60,70,80,90, 100,150, 200]}
other_params = {'learning_rate': 0.1, 'n_estimators': 500, 'max_depth': 5, 'min_child_weight': 1, 'seed': 0,
'subsample': 0.8, 'colsample_bytree': 0.8, 'gamma': 0, 'reg_alpha': 0, 'reg_lambda': 1}
#參數的最佳取值:{'n_estimators': 45}
#最佳模型得分:0.40957357613460915
'''
'''
cv_params = {'max_depth': 4, 'min_child_weight': [1, 2, 3, 4, 5, 6]}
other_params = {'learning_rate': 0.1, 'n_estimators': 45, 'max_depth': 5, 'min_child_weight': 1, 'seed': 0,
'subsample': 0.8, 'colsample_bytree': 0.8, 'gamma': 0, 'reg_alpha': 0, 'reg_lambda': 1}
#參數的最佳取值:{'max_depth': 4, 'min_child_weight': 3}
#最佳模型得分:0.41168308360707423
'''
'''
cv_params = {'gamma': [0.1, 0.2, 0.3, 0.4, 0.5, 0.6]}
other_params = {'learning_rate': 0.1, 'n_estimators': 45, 'max_depth': 4, 'min_child_weight': 3, 'seed': 0,
'subsample': 0.8, 'colsample_bytree': 0.8, 'gamma': 0, 'reg_alpha': 0, 'reg_lambda': 1}
#參數的最佳取值:{'gamma': 0.2}
#最佳模型得分:0.410086903491763
'''
'''
cv_params = {'subsample': [0.6, 0.7, 0.8, 0.9], 'colsample_bytree': [0.6, 0.7, 0.8, 0.9]}
other_params = {'learning_rate': 0.1, 'n_estimators': 45, 'max_depth': 4, 'min_child_weight': 3, 'seed': 0,
'subsample': 0.8, 'colsample_bytree': 0.8, 'gamma': 0.2, 'reg_alpha': 0, 'reg_lambda': 1}
#參數的最佳取值:{'colsample_bytree': 0.8, 'subsample': 0.8}
#最佳模型得分:0.410086903491763
'''
'''
cv_params = {'reg_alpha': [0,0.05, 0.1, 1, 2, 3], 'reg_lambda': [2,2.5, 3,3.5, 4,5,6]}
other_params = {'learning_rate': 0.1, 'n_estimators': 45, 'max_depth': 4, 'min_child_weight': 3, 'seed': 0,
'subsample': 0.8, 'colsample_bytree': 0.8, 'gamma': 0.2, 'reg_alpha': 0, 'reg_lambda': 1}
#參數的最佳取值:{'reg_alpha': 0.05, 'reg_lambda': 3}
#最佳模型得分:0.4104793873864756
'''
'''
cv_params = {'learning_rate': [0.01, 0.05, 0.07, 0.1,0.15, 0.2]}
other_params = {'learning_rate': 0.1, 'n_estimators': 45, 'max_depth': 4, 'min_child_weight': 3, 'seed': 0,
'subsample': 0.8, 'colsample_bytree': 0.8, 'gamma': 0.2, 'reg_alpha': 0.05, 'reg_lambda': 3}
#參數的最佳取值:{'learning_rate': 0.1}
#最佳模型得分:0.4104793873864756
model = xgb.XGBRegressor(**other_params)
optimized_GBM = GridSearchCV(estimator=model, param_grid=cv_params, scoring='r2', cv=5, verbose=1, n_jobs=4)
optimized_GBM.fit(X_train, y_train)
evalute_result = optimized_GBM.cv_results_['mean_test_score']
print('每輪迭代運行結果:{0}'.format(evalute_result))
print('參數的最佳取值:{0}'.format(optimized_GBM.best_params_))
print('最佳模型得分:{0}'.format(optimized_GBM.best_score_))
'''
4、參數
模型參數
n_estimatores:總共迭代的次數,即決策樹的個數
early_stopping_rounds:在驗證集上,當連續n次迭代,分數沒有提高後,提前終止訓練。防止overfitting。
max_depth:樹的深度,默認值爲6,典型值3-10。值越大,越容易過擬合;值越小,越容易欠擬合。
min_child_weight:默認值爲1。值越大,越容易欠擬合;值越小,越容易過擬合(值較大時,避免模型學習到局部的特殊樣本)。
subsample:訓練每棵樹時,使用的數據佔全部訓練集的比例。默認值爲1,典型值爲0.5-1。防止overfitting。
colsample_bytree:訓練每棵樹時,使用的特徵佔全部特徵的比例。默認值爲1,典型值爲0.5-1。防止overfitting。
學習任務參數
learning_rate:學習率,控制每次迭代更新權重時的步長,默認0.3。值越小,訓練越慢,典型值爲0.01-0.2。
objective 目標函數,迴歸任務
reg:linear
reg:logistic
二分類
binary:logistic 概率
binary:logitraw 類別
多分類
multi:softmax num_class=n 返回類別
multi:softprob num_class=n 返回概率
rank:pairwise
eval_metric
迴歸任務(默認rmse)
rmse--均方根誤差
mae--平均絕對誤差
分類任務(默認error)
auc--roc曲線下面積
error--錯誤率(二分類)
merror--錯誤率(多分類)
logloss--負對數似然函數(二分類)
mlogloss--負對數似然函數(多分類)
gamma
懲罰項係數,指定節點分裂所需的最小損失函數下降值。
調參數:https://blog.csdn.net/sinat_35512245/article/details/79700029
參考:https://blog.csdn.net/sinat_35512245/article/details/79700029
https://blog.csdn.net/u012735708/article/details/83651832