XGB for Rank

常规参数

  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

           https://blog.csdn.net/anshuai_aw1/article/details/86018105

           https://blog.csdn.net/seasongirl/article/details/100178083

发布了22 篇原创文章 · 获赞 6 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/baidu_18891025/article/details/103053489
xgb
今日推荐