机器学习之提升-XgBoost

本文介绍AdaBoost算法原理及实现过程,通过不断调整训练样本权重,学习多个分类器并线性组合,提高整体分类性能。

算法的引入

       在平时的算法中,基本分类器可分为强分类器与弱分类器,强弱之分主要是指分类器分类的准确率,在随机森林中,算法是生成很多颗树,将这些树的结果集成,生成一个分类效果较好的分类器,随机森林中,树的建立是相互独立的,如果我们换一个想法,已经有N棵树,那么建N+1棵树时可以受前面N棵树的影响,让分类得到提升?

算法概论

      提升算法是将弱分类器集成为一个强分类器,这类算法的工作机制是:

1. 选用一个基学习器
2. 用初始的数据集对基学习器进行训练
3. 根据训练结果对样本的分布进行调整,得到一个新的训练本样集,调整是让分错的样本后面得到更多的关注
4. 用得到的新样本集对基学习器进行训练
5. 重复步骤3,4直到达到指定指标。

AdaBoost算法

     AdaBoost算法在分类问题中的主要特点是:通过改变训练样本的权重,学习多个分类器,并将这个分类器进行线性的组合,提高分类的性能

训练数据集:

                                                        \\D=\{ (x^1,y^1),(x^2,y^2)\dots (x^M,y^M)\} \\y^i \in \{-1,+1\}

  1.  初始化训练数据的权值分布,假设训练数据有均匀的权值分布D_1 = (w_{11},w_{12},\dots,w_{1i}\dots,w_{1M}),w_{1i}=\frac{1}{N}
  2. 使用当前的权值分布D_1对训练数据学习,得到基本的分类器G_1(x)(采用使分错误差率最小为目标函数)
  3. 计算G_1(x)上分错的误差率                                                                                                                                                                                                       \\e_1 = P(G_1(x^i)!=y^i)= \sum_{i=0}^M w_{1i}I(G_1(x^i)!=y^i) \\I(G_1(x^i),y^i) = \begin{cases} 0 & G_1(x^i) == y^i \\ 1 & G_1(x^i) != y^i \end{cases}
  4. 计算G<sub>1</sub>的系数                                                                                                                                                                                                      a_1 = \frac{1}{2}ln\frac{1-e_1}{e_1}
  5. 更新数据集的权值分布                                                                                                                                                                                                             \\D_2 = (w_{21},w_{22},\dots,w_{2i}\dots,w_{2M}) \\ w_{2i} = \frac{w_{1i}}{Z_k}e^{-a_1y^iG_1(x^i)} \\ Z_k = \sum_{i=1}^{M}w_{1i}e^{-a_1y^iG_1(x^i)}
  6. D_2,替换D_1,重复上面的2-5,可得到分类器G_2(x)分类器,依次下可以得到G_k(x)分类器
  7.  构建分类器的线性组合                                                                                                                                                                                                           \\f(x) = \sum_{k=1}^{K}a_kG_k(x)\\ G(x) = sign(f(x))

程序示例

import numpy as np
import math

def loadData():
    x = np.arange(0, 10).reshape(-1,1)
    y = np.array([1, 1, 1, -1, -1, -1, 1, 1, 1, -1]).reshape(-1,1)
    D = np.ones_like(x) * 1.0/np.size(x)
    return x, y, D

def minErrorClassify(x, y, Di):
    gx = np.ones_like(x)

    b = np.repeat(np.arange(0, 10).reshape(-1, 1), 9, axis=1)
    xsize, ysize = b.shape
    for i in range(0, xsize, 1):
        for j in range(0, ysize, 1):
            if i > j:
                b[i][j] = 1
            else:
                b[i][j] = -1
    ry = np.repeat(y, 9, axis=1)
    ry2 = ry * b * np.repeat(Di, 9, axis=1)
    error = np.where(ry2 < 0, ry2, 0)
    error = abs(np.sum(error,axis=0)) # [-1, 1]
    error2 = 1 - error # [1 -1]
    if error.min() < error2.min():
        index = np.where(error == error.min())
        gx[0:index[0][0]+1] = -1
        return error.min(), gx
    else:
        index = np.where(error2 == error2.min())
        gx[index[0][0]+1:] = -1
        return error2.min(), gx

def predictYError(x, y, gxlist):
    predict_y = np.empty_like(y)*0
    for gxinfo in gxlist:
        a = gxinfo['a']
        gx = gxinfo['gx']
        predict_y = predict_y + a * gx
    predict_y = np.sign(predict_y)
    error = predict_y * y
    error = np.where(error < 0, error, 0)
    return predict_y,abs(error.sum())/np.size(x)


if __name__ == '__main__':
    x, y, D = loadData()
    gxlist = []
    exp = lambda t: math.exp(t)
    vfunc = np.vectorize(exp)

    D_next = D
    predict_error = 1
    min_error = 1
    while predict_error > 0.001:

        min_error,  gx = minErrorClassify(x, y, D_next)

        a = 0.5 * math.log((1-min_error)/min_error)

        gxlist.append({'a': a, 'gx': gx})
        predict_y, predict_error = predictYError(x, y, gxlist)
        print "predict_y,predict_error\n",predict_y, predict_error
        D_next = vfunc(-a*y*gx) * D_next
        D_next = D_next/D_next.sum()
        D = np.append(D,D_next,axis=1)
    print "D=", D
    print gxlist

 结果显示经过3次就可以完全分正确。修改y的值,可以测试代码。关于算法的理论明就不给出了,可以参考下在面的链接,讲的都比较好

1. https://plushunter.github.io/2017/01/26/%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0%E7%AE%97%E6%B3%95%E7%B3%BB%E5%88%97%EF%BC%888%EF%BC%89%EF%BC%9AXgBoost/
2. https://blog.youkuaiyun.com/qq_39521554/article/details/80691421
3. https://www.youkuaiyun.com/gather_26/MtTacg5sNjM1MC1ibG9n.html
4. https://blog.youkuaiyun.com/weiyongle1996/article/details/77856131
5. http://www.sohu.com/a/161539462_642762
6. https://blog.youkuaiyun.com/sb19931201/article/details/52506157
7. https://blog.youkuaiyun.com/suipingsp/article/details/42264413
8. https://blog.youkuaiyun.com/sb19931201/article/details/52506157
9. https://blog.youkuaiyun.com/akon_wang_hkbu/article/details/77621631

XGBoost(eXtreme Gradient Boosting)是一种基于梯度提升框架的优化分布式计算的机器学习算法。其核心原理在于通过迭代构建多个弱预测模型(通常是决策树),并不断减少模型偏差和方差,最终将这些弱模型组合成一个强预测模型。XGBoost在传统梯度提升决策树(GBDT)的基础上进行了多项改进,包括正则化项引入、支持自定义损失函数、对缺失值的处理以及利用二阶泰勒展开优化目标函数等[^1]。 ### 基本原理 XGBoost的核心思想是通过加法训练的方式逐步构建模型。在每一步中,新的树模型被训练以拟合当前模型的残差。具体来说,XGBoost的目标函数由两部分组成:一是衡量当前模型与真实值之间的误差(损失函数),二是对模型复杂度的惩罚项(正则化项)。目标函数的形式可以表示为: $$ \text{Obj}(\theta) = \sum_{i=1}^{n} L(y_i, \hat{y}_i) + \sum_{k=1}^{K} \Omega(f_k) $$ 其中,$L$ 是损失函数,$\Omega$ 是正则化项,$f_k$ 表示第 $k$ 棵树的输出。为了优化这个目标函数,XGBoost采用了二阶泰勒展开的方法来近似损失函数,从而使得每次迭代中可以更精确地找到最优解。此外,XGBoost还引入了特征列采样机制,类似于随机森林中的做法,进一步提升了模型的泛化能力[^2]。 ### 算法细节 XGBoost算法流程主要包括以下几个步骤: 1. 初始化模型,通常设置初始预测值为常数。 2. 对于每一次迭代,计算当前模型的残差。 3. 使用残差作为目标变量,训练一个新的决策树。 4. 将新训练得到的树加入到现有模型中,同时调整学习率以控制每棵树的影响。 5. 重复上述步骤直到达到预设的最大迭代次数或者满足提前停止条件。 在构建单棵树的过程中,XGBoost通过贪心算法选择最佳分裂点,即对于每个节点尝试分割后增益最大的特征及阈值。这种增益计算考虑到了一阶导数和二阶导数的信息,有助于找到更加精确的分裂位置。此外,XGBoost还实现了高效的内存管理和缓存优化技术,提高了大规模数据集上的运行效率[^1]。 ### 应用场景 XGBoost因其出色的性能和灵活性,在众多领域得到了广泛应用。例如,在金融行业,XGBoost可用于信用评分卡建模、欺诈检测等任务;在电商领域,它可以用来进行用户购买行为预测、点击率预估等工作;而在生物信息学中,则可能用于基因表达数据分析或蛋白质结构预测等问题。除此之外,XGBoost也是许多Kaggle竞赛获胜方案中的常见选择之一,尤其是在处理表格型数据时表现尤为突出。 ### 示例代码 以下是一个简单的XGBoost分类任务的Python实现示例: ```python import xgboost as xgb from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split from sklearn.metrics import accuracy_score # 加载数据集 iris = load_iris() X, y = iris.data, iris.target # 划分训练集和测试集 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) # 转换为DMatrix格式 dtrain = xgb.DMatrix(X_train, label=y_train) dtest = xgb.DMatrix(X_test, label=y_test) # 设置参数 params = { 'objective': 'multi:softmax', 'num_class': 3, 'max_depth': 3, 'eta': 0.3, 'eval_metric': 'merror' } # 训练模型 model = xgb.train(params, dtrain, num_boost_round=20) # 预测 y_pred = model.predict(dtest) # 计算准确率 accuracy = accuracy_score(y_test, y_pred) print(f"Accuracy: {accuracy:.2f}") ``` 这段代码演示了如何使用XGBoost库来进行多类分类任务,其中包括了数据准备、模型训练、预测以及评估的基本流程。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值