常规参数
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