Xgboost算法

1.介绍

1
2
3
4
5
6
7
8
1.Xgboost本质上还是GBDT(梯度提升树),Xgboost算法是对GBDT算法的改进
2.Xgboost是Boosting算法的其中一种,Boosting算法的思想是将许多弱分类器集成在一起,形成一个强分类器。因为Xgboost是一种提升树模型,所以它是将许多树模型集成在一起,形成一个很强的分类器。而所用到的树模型则是CART回归树模型
3.xgboost中的基学习器除了可以是CART也可以是线性分类器
4.做二分类的时候输出的是模型预测的所有概率中最大的那个值(连续值中取概率最大的)
xgboost即可以做回归也可以做分类,但是通常都是做回归
5.用到了加法模型和前项分布算法(每次只学习一个基函数及系数,逐步逼近最优解),-->将同时求所有树的参数问题转换成求每个树
6.用二阶导数会收敛的更快,从一维向量到二维矩阵,再往后不成熟(张量),算起来慢点
单一的回归树不够-->boosting框架-->回归树改良,GBDT-->进一步提升,Xgboost

机器学习常用名词解释

正则化: 向你的模型加入某些规则,加入先验,缩小解空间,减小求出错误解的可能性,有效防止过拟合

超参数: 是人为设置值的参数,而不是通过训练得到的参数数据,如学习率

稀疏数据: 数据框中绝大多数数值缺失或者为零的数据,类推稀疏矩阵

离散数据(变量):指其数值只能用自然数或整数单位计算.例如,企业个数,职工人数,设备台数等,只能按计量单位数计数

连续数据(变量):指在一定区间内可以任意取值,相邻的两个数值可作无限分割(即可取无限个值)。比如身高,身高可以是183,也可以是183.1,也可以是183.111……1

离散特征:其数值只能用自然数来表示,只能用计量单位统计,如个数,人数等

连续特征:是按测量或者计量方法得到。连续特征是指在一段长度内可以任意获得的特征,其数值是不间断。比如[0,1]之间的数,可以取n个数。

总之,记住,离散只能用自然数表示,是统计得到的。连续是按测量或者计量到得到数,比如各种传感器采集得到的数。

核外计算: (内存外计算),大数据的数据规模下,一次性把训练数据导到内存里面计算是不实际的

1
2
3
三个计算级别:(速度越来越慢,数据量越来越大)
内存里(核内)
内存外(核外)

分布式 spark,Hadoop方面
其他:待补充

Cart分类树和回归树实现原理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
决策树三种方式:ID3(信息增益)   C4.5(信息增益率)  Cart(基尼指数)
二叉
Cart分类树
离散特征:(CART的处理思想与C4.5是相同的,即将连续特征值离散化)
1.训练数据集为D,计算现有特征对训练数据集的基尼指数,此时对于每一个特征A,对其可能取得每一个值a,根据此值将训练样本切分为D1和D2两部分,然后根据上式计算A=a基尼指数
2.在所有可能的特征以及所有可能的值里面选择基尼指数最小的特征及其切分点作为最优的特征及切分点,从结点生成两个子结点,将训练数据集分配到子结点中去
3.递归的调用1 2 直到满足停止的条件
4.生成分类决策树
Cart回归树
连续特征:
1.训练数据集为D,依次遍历每个特征,以及该特征的每个取值,计算每个切分点的损失函数(平方损失),选择损失函数最小的切分点,y为每个数值,y^为划分的左右两边各自的均值
2.递归的调用1直到满足停止的条件
树停止条件:
1.只有一个元素,或者元素全部相同时
2.达到设置的最大深度
3.特征已经划分完
4.样本个数小于预定阀值
二者区别:
1.分类树与回归树的区别在样本的输出,如果样本输出是离散值,这是分类树;样本输出是连续值,这是回归树。分类树的输出是样本的类别,回归树的输出是一个实数。
2.连续值的处理方法不同。
3.决策树建立后做预测的方式不同。
分类模型:采用基尼系数的大小度量特征各个划分点的优劣。
回归模型:平方误差最小准则
对于决策树建立后做预测的方式,CART分类树采用叶子节点里概率最大的类别作为当前节点的预测类别。回归树输出不是类别,采用叶子节点的均值或者中位数来预测输出结果。
剪枝策略:(解决过拟合)
预剪枝:在节点划分前来确定是否继续增长,是否继续划分---->降低过拟合,减少训练时间,存在欠拟风险
方法:1.节点内数据样本低于某一阈值
2.所有节点特征都已分裂
3.节点划分前准确率比节点划分后准确率高
后剪枝:创建完整的决策树,然后再尝试消除多余的节点,也就是采用减枝的方法
区别:
预剪枝:运算量小,但是不一定精准,欠拟合风险大
后剪枝:运算量大,比较精准,欠拟合风险小

2.Xgboost的优点

1
2
3
4
5
6
7
1.正则化项防止过拟合
2.xgboost不仅使用到了一阶导数,还使用二阶导数,损失更精确
3.XGBoost的并行优化,XGBoost的并行是在特征粒度上的
4.考虑了训练数据为稀疏值的情况,可以为缺失值或者指定的值指定分支的默认方向,这能大大提升算法的效率
5.列抽样。xgboost借鉴了随机森林的做法,支持列抽样,不仅能降低过拟合,还能减少计算,这也是xgboost异于传统gbdt的一个特性。
6.一种新颖的用于处理稀疏数据的树学习算法
7.XGBoost利用了核外计算

正则化

内容:包含L1正则化、L2正则化

以线性回归为例

imgL1正则化

图片L2正则化

L1正则化最大的特点是能生成稀疏矩阵(主要用于特征选择,0和非0)

L2正则能够有效的防止模型过拟合

作用:解决过拟合,降低模型复杂度,防止参数过大(限制模型的参数)

正则化能实现过拟合原因:

1.作为惩罚项,惩罚特征权重w,当λ越大w越小,权重影响越小

2.直观的理解,如果我们的正则化系数λ无穷大,则权重w就会趋近于0。权重变小,非线性程度自然就降低了

##

3.Xgboost与GBDT的区别

1
2
3
4
5
6
GBDT:梯度提升算法利用损失函数的负梯度作为残差拟合的方式,如果其中的基函数采用决策树的话,就得到了梯度提升决策树
1.XGBoost对损失函数做了二阶泰勒展开,GBDT只用了一阶导数信息.并且在损失函数一阶,二阶可导的条件下XGBoost可以自定义损失函数。
2.XGBoost的目标函数加了正则项,相当于预剪枝,使得学习出来的模型更加不容易过拟合。
3.XGBoost支持列抽样,与随机森林类似,用于防止过拟合
对树中的每个非叶子节点,XGBoost可以自动学习出它的默认分裂方向。如果某个样本该特征值确缺失,会将其划入默认分支。
4.XGBoost支持特征维度的并行

拟合残差:最后结果相加就是预测的

图片

4.算法的实现过程

图片

分别代表训练损失和树的复杂度

图片

图片

前t-1颗树的结构已经确定,认定为常数

图片

图片表示损失函数,如平方损失图片

图片表示正则化项,考虑树的复杂度,防止过拟合

图片

图片表示常数项

损失函数使用平方损失

平方损失函数有许多友好的地方,它具有一阶项(通常称为残差)和二次项。对于其他形式的损失函数,并不容易获得这么好的形式

图片

损失函数不是平方损失

泰勒二阶展开

图片

图片

图片

图片

代入原公式:

图片

化简树结构

定义一棵树q(x)为输入x然后输出叶子结点索引,w为叶子结点向量

图片

图片

树的复杂度

图片

图片

图片

图片

这样就将样本累加操作转换为叶子节点的操作

Gj 表示映射为叶子节点 j 的所有输入样本的一阶导之和

G和H都是常数,那么这个问题就变成了一个二次问题了,求解最小值

图片

####

5.Xgboost的实现(案例:回归预测房价)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
train=pd.read_csv(r'C:\Users\Administrator\Desktop\train.csv', header=0)
test=pd.read_csv(r'C:\Users\Administrator\Desktop/test.csv', header=0)
c_test  = test.copy()
c_train  = train.copy()
c_train['train']  = 1
c_test['train']  = 0
df = pd.concat([c_train, c_test], axis=0,sort=False)
NAN = [(c, df[c].isna().m ean()*100) for c in df]
NAN = pd.DataFrame(NAN, columns=["column_name", "percentage"])
NAN = NAN[NAN.percentage > 50]
NAN.sort_values("percentage", ascending=False)#得到缺失率超过50%的字段
df = df.drop(['Alley','PoolQC','Fence','MiscFeature'],axis=1)
object_columns_df = df.select_dtypes(include=['object'])
numerical_columns_df =df.select_dtypes(exclude=['object'])
null_counts = object_columns_df.isnull().sum() #object数据中每个特征空值的数量
columns_None = ['BsmtQual','BsmtCond','BsmtExposure','BsmtFinType1','BsmtFinType2','GarageType','GarageFinish','GarageQual','FireplaceQu','GarageCond']
object_columns_df[columns_None]= object_columns_df[columns_None].fillna('None')
columns_with_lowNA = ['MSZoning','Utilities','Exterior1st','Exterior2nd','MasVnrType','Electrical','KitchenQual','Functional','SaleType']
object_columns_df[columns_with_lowNA] = object_columns_df[columns_with_lowNA].fillna(object_columns_df.mode().iloc[0]) #object_columns_df.mode()返回频数最高的
null_counts = numerical_columns_df.isnull().sum()
#YearBuilt无空值
print((numerical_columns_df['YrSold']-numerical_columns_df['YearBuilt']).median()) #35
print(numerical_columns_df["LotFrontage"].median()) #68
numerical_columns_df['GarageYrBlt'] = numerical_columns_df['GarageYrBlt'].fillna(numerical_columns_df['YrSold']-35)
numerical_columns_df['LotFrontage'] = numerical_columns_df['LotFrontage'].fillna(68)
numerical_columns_df= numerical_columns_df.fillna(0)
#作图找出方差小的特征,将他们删除(方差小,离散程度低,特征无明显区分左右,故删除)
object_columns_df['Utilities'].value_counts().plot(kind='bar',figsize=[10,3])
object_columns_df['Utilities'].value_counts() 
object_columns_df['Street'].value_counts().plot(kind='bar',figsize=[10,3])
object_columns_df['Street'].value_counts() 
object_columns_df['Condition2'].value_counts().plot(kind='bar',figsize=[10,3])
object_columns_df['Condition2'].value_counts() 
object_columns_df['RoofMatl'].value_counts().plot(kind='bar',figsize=[10,3])
object_columns_df['RoofMatl'].value_counts()
object_columns_df['Heating'].value_counts().plot(kind='bar',figsize=[10,3])
object_columns_df['Heating'].value_counts() #======> Drop feature one Type
object_columns_df = object_columns_df.drop(['Heating','RoofMatl','Condition2','Street','Utilities'],axis=1)
#创造特征
numerical_columns_df['Age_House']= (numerical_columns_df['YrSold']-numerical_columns_df['YearBuilt'])
numerical_columns_df['Age_House'].describe() #对特征分析
Negatif = numerical_columns_df[numerical_columns_df['Age_House'] < 0]
numerical_columns_df.loc[numerical_columns_df['YrSold'] < numerical_columns_df['YearBuilt'],'YrSold' ] = 2009
numerical_columns_df['Age_House']= (numerical_columns_df['YrSold']-numerical_columns_df['YearBuilt'])
numerical_columns_df['Age_House'].describe()
numerical_columns_df['TotalBsmtBath'] = numerical_columns_df['BsmtFullBath'] + numerical_columns_df['BsmtFullBath']*0.5
numerical_columns_df['TotalBath'] = numerical_columns_df['FullBath'] + numerical_columns_df['HalfBath']*0.5 
numerical_columns_df['TotalSA']=numerical_columns_df['TotalBsmtSF'] + numerical_columns_df['1stFlrSF'] + numerical_columns_df['2ndFlrSF']
bin_map  = {'TA':2,'Gd':3, 'Fa':1,'Ex':4,'Po':1,'None':0,'Y':1,'N':0,'Reg':3,'IR1':2,'IR2':1,'IR3':0,"None" : 0,
            "No" : 2, "Mn" : 2, "Av": 3,"Gd" : 4,"Unf" : 1, "LwQ": 2, "Rec" : 3,"BLQ" : 4, "ALQ" : 5, "GLQ" : 6
            }
object_columns_df['ExterQual'] = object_columns_df['ExterQual'].map(bin_map)
object_columns_df['ExterCond'] = object_columns_df['ExterCond'].map(bin_map)
object_columns_df['BsmtCond'] = object_columns_df['BsmtCond'].map(bin_map)
object_columns_df['BsmtQual'] = object_columns_df['BsmtQual'].map(bin_map)
object_columns_df['HeatingQC'] = object_columns_df['HeatingQC'].map(bin_map)
object_columns_df['KitchenQual'] = object_columns_df['KitchenQual'].map(bin_map)
object_columns_df['FireplaceQu'] = object_columns_df['FireplaceQu'].map(bin_map)
object_columns_df['GarageQual'] = object_columns_df['GarageQual'].map(bin_map)
object_columns_df['GarageCond'] = object_columns_df['GarageCond'].map(bin_map)
object_columns_df['CentralAir'] = object_columns_df['CentralAir'].map(bin_map)
object_columns_df['LotShape'] = object_columns_df['LotShape'].map(bin_map)
object_columns_df['BsmtExposure'] = object_columns_df['BsmtExposure'].map(bin_map)
object_columns_df['BsmtFinType1'] = object_columns_df['BsmtFinType1'].map(bin_map)
object_columns_df['BsmtFinType2'] = object_columns_df['BsmtFinType2'].map(bin_map)
PavedDrive =   {"N" : 0, "P" : 1, "Y" : 2}
object_columns_df['PavedDrive'] = object_columns_df['PavedDrive'].map(PavedDrive)
rest_object_columns = object_columns_df.select_dtypes(include=['object'])
#独热编码
object_columns_df = pd.get_dummies(object_columns_df, columns=rest_object_columns.columns) 
df_final = pd.concat([object_columns_df, numerical_columns_df], axis=1,sort=False)
df_final = df_final.drop(['Id',],axis=1)
df_train = df_final[df_final['train'] == 1]
df_train = df_train.drop(['train',],axis=1)
df_test = df_final[df_final['train'] == 0]
df_test = df_test.drop(['SalePrice'],axis=1)
df_test = df_test.drop(['train',],axis=1)
target= df_train['SalePrice']
df_train = df_train.drop(['SalePrice'],axis=1)
x_train,x_test,y_train,y_test = train_test_split(df_train,target,test_size=0.33,random_state=0)
#前面全是创建特征工程,数据预处理
xgb =XGBRegressor( booster='gbtree', colsample_bylevel=1,
             colsample_bynode=1, colsample_bytree=0.6, gamma=0,
             importance_type='gain', learning_rate=0.01, max_delta_step=0,
             max_depth=4, min_child_weight=1.5, n_estimators=2400,
             n_jobs=1, nthread=None, objective='reg:linear',
             reg_alpha=0.6, reg_lambda=0.6, scale_pos_weight=1
             silent=None, subsample=0.8, verbosity=1)
xgb.fit(x_train, y_train)
predict1 = xgb.predict(x_test)
xgb.fit(df_train, target)
predicty = xgb.predict(df_test)
predicty

6.Xgboost的参数详解以及使用

一般参数:控制总体的功能

1
2
1.booster[default=gbtree]选择基分类器 gbtree、gblinear 树或线性分类器
2.nthread [default to maximum number of threads available if not set]线程数默认最大

Tree Booster参数:控制单个学习器的属性

1
2
3
4
5
6
7
8
9
1. learning_rate[default=0.3]:学习率learning rate,步长.一般常用的数值: 0.01-0.2
2. min_child_weight [default=1]:这个参数用来控制过拟合,如果数值太大可能会导致欠拟合
3. max_depth [default=6]: 每颗树的最大深度,树高越深,越容易过拟合。
4. gamma [default=0]:如果分裂能够使loss函数减小的值大于gamma,则这个节点才分裂。gamma设置了这个减小的最低阈值。如果gamma设置为0,表示只要使得loss函数减少,就分裂,通常设置为0
6. subsample [default=1]:对原数据集进行随机采样来构建单个树。这个参数代表了在构建树时候 对原数据集采样的百分比。eg:如果设为0.8表示随机抽取样本中80%的个体来构建树。
7. colsample_bytree [default=1]:创建树的时候,从所有的列中选取的比例。e.g:如果设为0.8表示随机抽取80%的列 用来创建树.一般设置为: 0.5-1
8. lambda [default=1]:控制模型复杂度的权重值的L2正则化项参数,参数越大,模型越不容易过拟合。
9. alpha [default=0]:控制模型复杂程度的权重值的 L1 正则项参数,参数值越大,模型越不容易过拟合。
10. scale_pos_weight [default=1]在各类别样本十分不平衡时,把这个参数设定为一个正值,可以使算法更快收敛。通常可以将其设置为负样本的数目与正样本数目的比值。

学习任务参数:控制调优的步骤

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
1.objective [缺省值=reg:linear]
reg:linear– 线性回归
reg:logistic – 逻辑回归
binary:logistic – 二分类逻辑回归,输出为概率
binary:logitraw – 二分类逻辑回归,输出的结果为wTx
count:poisson – 计数问题的poisson回归,输出结果为poisson分布。在poisson回归中,max_delta_step的缺省值为0.7 (used to safeguard optimization)
multi:softmax – 设置 XGBoost 使用softmax目标函数做多分类,需要设置参数num_class(类别个数)
multi:softprob – 如同softmax,但是输出结果为ndata*nclass的向量,其中的值是每个数据分为每个类的概率

2.seed [ default=0 ]随机种子,为了产生能够重现的结果。因为如果不设置这个种子,每次产生的结果都会不同。
3.eval_metric [缺省值=通过目标函数选择]
rmse: 均方根误差
mae: 平均绝对值误差
logloss: negative log-likelihood
error: 二分类错误率。
merror: 多分类错误率,计算公式为(wrong cases)/(all cases)
mlogloss: 多分类log损失
auc: 曲线下的面积
ndcg: Normalized Discounted Cumulative Gain
map: 平均正确率

调参方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
需要借助一个模块sklearn.model_selection.GridSearchCV(模型调参利器,网格搜索)
参数:
1.estimator,优化器,即你建立的模型,这里选xgboost
2.param_grid 一般用字典(通常,也可列表),输入优化的参数
3.scoring 模型评价标准,如roc,auc等
调参顺序:
1.n_estimators 迭代次数,就是生成树的个数 如,cv_params = {'n_estimators': [550, 575, 600, 650, 675]}
2.min_child_weight和max_depth 这两个参数是控制树生成的,树的结构对于最终的结果影响还是很大
3.gamma控制节点分裂标准 cv_params = {'gamma': [0.1, 0.2, 0.3, 0.4, 0.5, 0.6]}
4.subsample和colsample_bytree 采样比例,cv_params = {'subsample': [0.6, 0.7, 0.8, 0.9], 'colsample_bytree': [0.6, 0.7, 0.8, 0.9]}
5. alpha和lambda, 正则化的参数 cv_params = {'alpha': [0.05, 0.1, 1, 2, 3], 'lambda': [0.05, 0.1, 1, 2, 3]}
6.learning_rate 学习率,从较小的开始 cv_params = {'learning_rate': [0.01, 0.05, 0.07, 0.1, 0.2]}
7.调参可以提高模型性能,但是更重要的还是特征选择,数据清洗,特征融合

控制过拟合
当您观察到较高的训练准确率,但测试精度较低时,很可能遇到了过拟合问题。
通常可以通过两种方式来控制xgboost中的过拟合
第一种方式是直接控制模型的复杂性
这包括max_depth,min_child_weight 和 gamma
第二种方法是增加随机性,使训练对噪声更加鲁棒
这包括subsample,colsample_bytree,eta

样本不均衡问题
1) 设置scale_pos_weight,有时会遇到样本不均衡的问题,比如正例占99%,反例占1%,那么如果预测为全正例或者随机抽机,正确率也占99%。此时可使用scale_pos_weight提高反例权重,默认为1,不增加权重。
2)使用xgb自带的调用接口 (非sklearn接口),需要把数据转成DMatrix格式,如果想给不同实例分配不同权重,可以转换时使用weight参数,它传入与实例个数等长的数组,数组中每个数对应一个实例的权重,在xgb每次迭代后调整权重时也会将它计算在内。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import xgboost as xgb
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import GridSearchCV

cancer = load_breast_cancer()
x = cancer.data[:50]
y = cancer.target[:50]
train_x, valid_x, train_y, valid_y = train_test_split(x, y, test_size=0.333, random_state=0)
parameters = {
    'max_depth': [5, 10, 15, 20, 25],
    'learning_rate': [0.01, 0.02, 0.05, 0.1, 0.15],
    'n_estimators': [50, 100, 200, 300, 500],
    'min_child_weight': [0, 2, 5, 10, 20],
    'max_delta_step': [0, 0.2, 0.6, 1, 2],
    'subsample': [0.6, 0.7, 0.8, 0.85, 0.95],
    'colsample_bytree': [0.5, 0.6, 0.7, 0.8, 0.9],
    'reg_alpha': [0, 0.25, 0.5, 0.75, 1],
    'reg_lambda': [0.2, 0.4, 0.6, 0.8, 1],
    'scale_pos_weight': [0.2, 0.4, 0.6, 0.8, 1]
}

xlf = xgb.XGBClassifier(max_depth=10,
                        learning_rate=0.01,
                        n_estimators=2000,
                        silent=True,
                        objective='binary:logistic',
                        nthread=-1,
                        gamma=0,
                        min_child_weight=1,
                        max_delta_step=0,
                        subsample=0.85,
                        colsample_bytree=0.7,
                        colsample_bylevel=1,
                        reg_alpha=0,
                        reg_lambda=1,
                        scale_pos_weight=1,
                        seed=1440,
                        missing=None)

# 有了gridsearch我们便不需要fit函数
gsearch = GridSearchCV(xlf, param_grid=parameters, scoring='accuracy', cv=3)
gsearch.fit(train_x, train_y)
print("Best score: %0.3f" % gsearch.best_score_)
print("Best parameters set:")
best_parameters = gsearch.best_estimator_.get_params()
for param_name in sorted(parameters.keys()):
    print("\t%s: %r" % (param_name, best_parameters[param_name]))
#比较耗费时间,穷举法

案例2:https://www.jianshu.com/p/7aab084b7f47

https://blog.csdn.net/weixin_30838921/article/details/94989933?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-3.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-3.channel_param

7.Xgboost的注意事项

1
2
3
4
5
6
7
8
9
10
1.windows安装推荐方式,直接pip会各种报错
https://blog.csdn.net/qq_20412595/article/details/79771490?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param
2.在Xgb中需要将离散特征one-hot编码,和连续特征一起输入训练
3.Xgb中支持稀疏矩阵训练模型,导致数据稀疏的原因如下
缺省值
稠密数据中零元素
离散特征one-hot编码后产生的0
4.win和mac平台运行相同的xgboost代码,效果如果可能不同,将参数colsample_bytree设置为1
5.xgboost提供两种调用方式,一种是自身接口,一种是类似sklearn的接口,建议使用自身接口,因为很多重要功能,如存取模型,评估功能都无法通过sklearn接口调用。
6.Xgboost可以处理二分类,多分类,回归问题。处理不同问题,主要的区别在于指定不同的误差函数,xgboost会根据不同误差函数计算的结果调整权重进行下一次迭代。通过参数objective可设置xgb自带的误差函数:回归一般用reg:xxx(如reg:linear),二分类用binary:xxx(如binary:logistic),多分类用multi:xxx(如multi:softmax)

Xgboost原生接口和Sklearn接口的区别

1
2
1.xgboost原生接口,数据需要经过标签标准化(LabelEncoder().fit_transform)、输入数据标准化(xgboost.DMatrix)和输出结果反标签标准化(LabelEncoder().inverse_transform),训练调用train预测调用predict.
2.xgboost的sklearn接口,可以不经过标签标准化(即将标签编码为0~n_class-1),直接喂给分类器特征向量和标签向量,使用fit训练后调用predict就能得到预测向量的预测标签,它会在内部调用sklearn.preprocessing.LabelEncoder()将标签在分类器使用时transform,在输出结果时inverse_transform。

图片

xgb在选择最佳分裂点,进行枚举的时候并行!

xgboost的并行是在特征粒度上的。我们知道,决策树的学习最耗时的一个步骤就是对特征的值进行排序(因为要确定最佳分割点),在进行节点的分裂时,需要计算每个特征的增益,最终选增益最大的那个特征去做分裂,那么各个特征的增益计算就可以开多线程进行

拟合残差只是考虑到损失函数为平方损失的特殊情况,负梯度是更加广义上的拟合项,更具普适性。

无论损失函数是什么形式,每个决策树拟合的都是负梯度。准确的说,不是用负梯度代替残差,而是当损失函数是均方损失时,负梯度刚好是残差,残差只是特例。

为啥要去用梯度拟合不用残差?代价函数除了loss还有正则项,正则中有参数和变量,很多情况下只拟合残差loss变小但是正则变大,代价函数不一定就小,这时候就要用梯度啦,梯度的本质也是一种方向导数,综合了各个方向(参数)的变化,选择了一个总是最优(下降最快)的方向;