精华内容
参与话题
问答
  • python机器学习手写算法系列——线性回归

    万次阅读 多人点赞 2019-05-06 19:51:29
    本文致力于手把手教你实现一个最简单的机器学习模型--一元线性回归模型。短短的14行代码,就实现了。希望读完以后,你也能自己实现它。并对线性回归有更好的了解,或者从不了解到了解。

    本系列另一篇文章《决策树》
    https://blog.csdn.net/juwikuang/article/details/89333344

    本文源代码:
    https://github.com/juwikuang/machine_learning_step_by_step

    最近我发现我之前写的一篇文章《一个公式告诉你为什么程序员要转算法工程师》
    http://blog.csdn.net/juwikuang/article/details/73057194
    有很多人访问。我想,很多程序员和我当初一样,想从程序员转算法工程师。

    说说我当初为什么会想到升级成算法工程师。记得三年前,我还在印孚瑟斯(Infosys),我们的CFO非常自豪的宣布公司已经成功的让专科生的比例提高了,让本科生的比例降低了。我作为一个本科程序员,听了十分难受。当然,公司这样做是为了利润,也合理合法。换了我是CFO,我也会这样做,不过,我应该不会像他一样大声说。有些事,可以做,不能说。

    后来,机缘巧合,我学习了机器学习,走上了算法工程师这条路。当时我学机器学习,是从吴恩达(Andrew Ng)的Coursera课程开始的。很多人和我一样,也是开了这门课,开始机器学习的。这门课挺好,可惜开发语言用了Octave,以至于我每次写作业,都很痛苦,因为我还要学Octave语言,而且这东西学了也没啥用。另外,这门课是英语的,只有少数人能看懂。

    本文的目的,就是从最基本,最简单的机器学习算法讲起,手把手的教你实现这个算法。一边编程,一边就明白这个算法的原理了。我本人也是程序员转的算法工程师,我们的强项就是编程,弱项就是数学。我针对这个特点,专门做了以下教程。

    言归正传。首先我们看看线性回归在整个机器学习里的位置。

    从机器学习到线性回归

    线性回归在整个机器学习

    今天,我们只关注机器学习到线性回归这条线上的概念。别的以后再说。为了让大家听懂,我这次也不查维基百科了,直接按照自己的理解用大白话说,可能不是很严谨。

    机器学习就是机器可以自己学习,而机器学习的方法就是利用现有的数据和算法,解出算法的参数。从而得到可以用的模型。

    监督学习就是利用已有的数据(我们叫X,或者特征),和数据的标注(我们叫Y),找到x和y之间的对应关系,或者说是函数f。

    回归分析是一种因变量为连续值得监督学习。

    线性回归是一种x和y之间的关系为线性关系的回归分析。y=a1x1+a2x2+by=a_1x_1+a_2x_2+b,这个叫线性关系。如果这里出现了x2x^2,log(x)log(x), sin(x)sin(x)之类的,那就不是线性关系了。

    一元线性回归说的是,自变量x是一个纯量(scalar)。scalar类型的变量,是不可再分的。

    我希望你能说明白这些概念的关系。不过,我自己也是花了很久才了解清楚的。如果你没听明白,也没关系。毕竟都是概念,没什么实际的例子,也很难理解。等你看完了本文,了解了一元线性回归。回过头来再看这些概念,就能更好的理解了。

    问题

    这里,我们的问题是,找出算法工程师和程序员之间的工资关系。这里直接给出北京,上海,杭州,深圳,广州的工资。

    城市 x-程序员工资 y-算法工程师工资
    北京 1.3854 2.1332
    上海 1.2213 2.0162
    杭州 1.1009 1.9138
    深圳 1.0655 1.8621
    广州 0.09503 1.8016

    把他们用图打出来看看他们之间的关系。

    程序员和算法工程师工资

    由图可见,他们之间大致是一个线性关系,这时候,我们就可以试着用一元线性回归去拟合(fit)他们之间的关系。

    数学模型

    一元线性回归公式

    以下是公式
    y=ax+b+εy=ax+b+ε

    y 为应变量 dependent variable
    x 为自变量 independent variable
    a 为斜率 coeffient
    b 为截距 intercept
    ε (读作epsilon)为误差,正态分布
    线性回归的目标是,找到一组a和b,使得ε最小
    y^=ax+b\hat{y}=ax+b
    ε=yy^ε=y-\hat{y}

    y^\hat{y} 读作y hat,也有人读作y帽子。这里的帽子一般表示估计值,用来区别真实值y。

    下图可以更好的帮助你理解。

    一元线性回归
    (图片来自互联网)

    黑色的点为观测样本,即y=ax+b+εy=ax+b+ε

    x红色的线为回归线,即y^=ax+b\hat{y}=ax+b

    x蓝色的线段为误差,即ε=yy^ε=y-\hat{y}

    方差 - 损失函数 Cost Function

    在机器学习中,很多时候,我们需要找到一个损失函数。有了损失函数,我们就可以经过不断地迭代,找到损失函数的全局或者局部最小值(或者最大值)。损失函数使得我们的问题转化成数学问题,从而可以用计算机求解。在线性回归中,我们用方差作为损失函数。我们的目标是使得方差最小。

    下面的表格解释了什么是方差。

    方差

    其中SSE(Sum of Square Error)是总的方差,MSE(Mean Square Error)是方差的平均值。

    而这里的损失函数,用的是0.5 * MSE。即:

    J(a,b)=12ni=0n(yiy^i)2J(a,b)=\frac{1}{2n}\sum_{i=0}^{n}(y_i−\hat{y}_i )^2

    记住,这里的损失函数是针对参数a和b的函数,y和y^\hat{y} 其实都是已知的。

    优化方法 Optimization Function

    有了损失函数,我们还需要一个方法,使得我们可以找到这个损失函数的最小值。机器学习把他叫做优化方法。这里的优化方法,就是算损失的方向。或者说,当我的参数变化的时候,我的损失是变大了还是变小了。如果a变大了,损失变小了。那么,说明a增大这个方向是正确的,我们可以朝着这个方向继续小幅度的前进。反之,就应该考虑往相反的方向试试看。因为每个参数(a和b)都是一维的,所以,所谓的方向,无非就是正负符号。

    这里,我们需要用偏微分的方法,得到损失函数的变化量。即:

    Ja=12ni=0n(yiy^i)2a\frac{\partial J}{\partial a} = \frac{\partial \frac{1}{2n}\sum_{i=0}^{n}(y_i−\hat{y}_i )^2}{\partial a}
    =1ni=0n(yiaxib)(yiaxib)a= \frac{1}{n}\sum_{i=0}^{n}(y_i-ax_i-b) \frac{\partial (y_i-ax_i-b)}{\partial a}
    =1ni=0n(yiaxib)(xi)= \frac{1}{n}\sum_{i=0}^{n}(y_i-ax_i-b) (-x_i)
    =1ni=0nx(y^iyi)= \frac{1}{n}\sum_{i=0}^{n}x(\hat{y}_i-y_i)

    Jb=12ni=0n(yiy^i)2a\frac{\partial J}{\partial b} = \frac{\partial \frac{1}{2n}\sum_{i=0}^{n}(y_i−\hat{y}_i )^2}{\partial a}
    =1ni=0n(yiaxib)(yiaxib)b= \frac{1}{n}\sum_{i=0}^{n}(y_i-ax_i-b) \frac{\partial (y_i-ax_i-b)}{\partial b}
    =1ni=0n(yiaxib)(1)= \frac{1}{n}\sum_{i=0}^{n}(y_i-ax_i-b) (-1)
    =1ni=0n(y^iyi)= \frac{1}{n}\sum_{i=0}^{n}(\hat{y}_i-y_i)

    如果你已经忘了微积分,你暂时可以不必纠结上面的公式,只要知道公式给出了损失函数的变化就可以了。伟大的python还提供了sympy,你可以用sympy做微积分。这部分我也放在附件代码里了,有兴趣的可以看一下。

    之前说到,整过迭代过程是小幅度进行的。这里,就需要一个超参数来控制这个过程。这个超参数就是α\alpha,通常是0.01.

    这时,我们就可以去更新a和b的值:
    a=aαJaa = a - \alpha \frac{\partial J}{\partial a}
    b=bαJbb = b - \alpha \frac{\partial J}{\partial b}

    到这里,在你继续往下读之前,你先自己考虑一下,为什么这里是负号?

    你考虑好了么,如果你考虑好了,我就公布答案了。

    本身Ja\frac{\partial J}{\partial a}Jb\frac{\partial J}{\partial b} 是损失函数的变化量。如果损失函数随着a变大了,即 Ja\frac{\partial J}{\partial a} 为正。说明a的增大会导致损失函数的增大。那么是不是说,a的减小会使得损失函数减小呢?而我们的目标是使得J最小,所以,这个时候,我们的a要减小一点点。

    损失的方向
    (图片来自互联网)

    算法步骤

    1. a和b的起始值设置为零
    2. 通过模型y^=ax+b\hat{y}=ax+b,我们可以算出y^\hat{y}
    3. 有了y^\hat{y},就可以用优化方法算去更新参数
    4. 重复2和3,直到找到J的最小值

    流程图如下:

    Created with Raphaël 2.2.0开始a=0, b=0计算模型y_hat=ax+b计算a和b的微分更新a和b找到损失函数的最小值结束yesno

    下图解释了模型,损失函数和优化方法之间的关系。

    模型,损失函数和优化方法之间的关系

    Python 实现

    理论部分先告一段落,我们现在开始写代码,实现一元线性回归。

    首先是模型,这个很简单:

    def model(a, b, x):
        return a*x + b
    

    接着,是损失函数:

    def cost_function(a, b, x, y):
        n = 5
        return 0.5/n * (np.square(y-a*x-b)).sum()
    

    最后,是优化函数:

    def optimize(a,b,x,y):
        n = 5
        alpha = 1e-1
        y_hat = model(a,b,x)
        da = (1.0/n) * ((y_hat-y)*x).sum()
        db = (1.0/n) * ((y_hat-y).sum())
        a = a - alpha*da
        b = b - alpha*db
        return a, b
    

    以上三个函数中a和b是标量(scalar value),x和y是向量(vector)
    至此,一元线性回归的主要部分就完成了。一共才14行代码,是不是很简单。

    训练模型

    有了模型,损失函数,优化函数,我们就可以训练模型了。具体过程请见附件代码。

    这里给出分别训练1次,再训练5次,再训练10次,再训练100,再训练10000次的模型。

    1次

    5次

    10次

    100次

    10000次

    从上面几幅图,我们可以看到,随着训练次数的增加,回归线越来越接近样本了。我们自己写的线性回归比较简单,我只能目测,凭直觉感觉损失函数已经达到了最小值,我们就停在10000次吧。

    看得再多,不如自己动手。阅读下一章节之前,请自己实现一元线性回归。

    这里有现成的代码,供你参考。

    http://download.csdn.net/download/juwikuang/10050886

    模型评价

    在机器学习中,模型的好坏是有标准的。在回归模型中,我们用R2R^2 来评价模型。公式:
    R2=SSR/SSTR^2=SSR/SST
    其中
    SSR=i=0n(y^iyˉ)SSR=\sum_{i=0}^{n}(\hat{y}_i-\bar{y})
    SST=i=0n(yiyˉ)SST=\sum_{i=0}^{n}(y_i-\bar{y})
    yˉ\bar{y} 读作y bar,是y的平均值。
    可以证明SST=SSR+SSESST=SSR+SSE,证明过程又会涉及到期望等概念,我们这里不展开了。

    好了,现在你应该回到代码中去计算R2R^2 了。

    用scikit-learn训练和评价模型

    平时在工作中,我们不可能自己去写回归模型,最常用的第三方工具是scikit-learn。
    其官网是:
    http://scikit-learn.org/

    以下是ipython代码。

    import numpy as np
    from sklearn.linear_model import LinearRegression
    import matplotlib.pyplot as plt
    %matplotlib inline
    
    x = [13854,12213,11009,10655,9503] #程序员工资,顺序为北京,上海,杭州,深圳,广州
    x = np.reshape(x,newshape=(5,1)) / 10000.0
    y =  [21332, 20162, 19138, 18621, 18016] #算法工程师,顺序和上面一致
    y = np.reshape(y,newshape=(5,1)) / 10000.0
    # 调用模型
    lr = LinearRegression()
    # 训练模型
    lr.fit(x,y)
    # 计算R平方
    print lr.score(x,y)
    # 计算y_hat
    y_hat = lr.predict(x)
    # 打印出图
    plt.scatter(x,y)
    plt.plot(x, y_hat)
    plt.show()
    
    

    恭喜你,看完了本文,也学会了一元线性回归。如果对你有帮助,请给我一个赞。你的支持和鼓励是我继续写下去的动力。

    如果有疑问,请下面留言。

    python机器学习手写算法系列

    完整源代码:

    https://github.com/juwikuang/machine_learning_step_by_step

    欢迎阅读本系列其他文章:

    《python机器学习手写算法系列——线性回归》

    《python机器学习手写算法系列——逻辑回归》

    《python机器学习手写算法系列——决策树》

    《python机器学习手写算法系列——kmeans聚类》

    展开全文
  • Python机器学习实训营(原理推导+代码复现+实验分析)课程旨在帮助同学们在机器学习领域打下坚实基础。课程注重算法原理讲解与数学公式推导并基于Python语言给出完整的代码实现,从零开始实现每一模块功能(非调用...
  • python机器学习库xgboost——xgboost算法

    万次阅读 多人点赞 2018-04-12 08:56:40
    python数据挖掘系列教程 安装 xgboost目前还不能pip在线安装,所以先在网址https://www.lfd.uci.edu/~gohlke/pythonlibs/#xgboost 中下载whl文件,然后参考...

    分享一个朋友的人工智能教程。零基础!通俗易懂!风趣幽默!还带黄段子!大家可以看看是否对自己有帮助:点击打开

    ad1.jpg

    全栈工程师开发手册 (作者:栾鹏)
    python数据挖掘系列教程

    安装

    xgboost目前还不能pip在线安装,所以先在网址https://www.lfd.uci.edu/~gohlke/pythonlibs/#xgboost 中下载whl文件,然后参考https://blog.csdn.net/luanpeng825485697/article/details/77816740 进行离线安装,就可以正常导入xgboost库了。

    更新:现在已经可以通过pip install xgboost在线安装库了。

    xgboost简介

    xgboost一般和sklearn一起使用,但是由于sklearn中没有集成xgboost,所以才需要单独下载安装。

    xgboost是在GBDT的基础上进行改进,使之更强大,适用于更大范围。

    1. XGBoost的优点

    2.1 正则化

    XGBoost在代价函数里加入了正则项,用于控制模型的复杂度。正则项里包含了树的叶子节点个数、每个叶子节点上输出的score的L2模的平方和。从Bias-variance tradeoff角度来讲,正则项降低了模型的variance,使学习出来的模型更加简单,防止过拟合,这也是xgboost优于传统GBDT的一个特性。

    2.2 并行处理

    XGBoost工具支持并行。Boosting不是一种串行的结构吗?怎么并行的?注意XGBoost的并行不是tree粒度的并行,XGBoost也是一次迭代完才能进行下一次迭代的(第t次迭代的代价函数里包含了前面t-1次迭代的预测值)。XGBoost的并行是在特征粒度上的。

    我们知道,决策树的学习最耗时的一个步骤就是对特征的值进行排序(因为要确定最佳分割点),XGBoost在训练之前,预先对数据进行了排序,然后保存为block结构,后面的迭代中重复地使用这个结构,大大减小计算量。这个block结构也使得并行成为了可能,在进行节点的分裂时,需要计算每个特征的增益,最终选增益最大的那个特征去做分裂,那么各个特征的增益计算就可以开多线程进行。

    2.3 灵活性

    XGBoost支持用户自定义目标函数和评估函数,只要目标函数二阶可导就行。

    2.4 缺失值处理

    对于特征的值有缺失的样本,xgboost可以自动学习出它的分裂方向

    2.5 剪枝

    XGBoost 先从顶到底建立所有可以建立的子树,再从底到顶反向进行剪枝。比起GBM,这样不容易陷入局部最优解。

    2.6 内置交叉验证

    XGBoost允许在每一轮boosting迭代中使用交叉验证。因此,可以方便地获得最优boosting迭代次数。而GBM使用网格搜索,只能检测有限个值。

    1. XGBoost详解

    3.1 数据格式

    XGBoost可以加载多种数据格式的训练数据:

    libsvm 格式的文本数据;

    Numpy 的二维数组;

    XGBoost 的二进制的缓存文件。加载的数据存储在对象 DMatrix 中。

    下面一一列举:

    加载libsvm格式的数据

     dtrain1 = xgb.DMatrix('train.svm.txt')
    

    加载二进制的缓存文件

    dtrain2 = xgb.DMatrix('train.svm.buffer')
    

    加载numpy的数组

    data = np.random.rand(5,10) # 5行10列数据集
    label = np.random.randint(2, size=5) # 2分类目标值
    dtrain = xgb.DMatrix( data, label=label) # 组成训练集
    

    将scipy.sparse格式的数据转化为 DMatrix 格式

    csr = scipy.sparse.csr_matrix( (dat, (row,col)) )
    dtrain = xgb.DMatrix( csr )
    

    将 DMatrix 格式的数据保存成XGBoost的二进制格式,在下次加载时可以提高加载速度,使用方式如下

     dtrain = xgb.DMatrix('train.svm.txt')
    dtrain.save_binary("train.buffer")
    

    可以用如下方式处理 DMatrix中的缺失值:

    dtrain = xgb.DMatrix( data, label=label, missing = -999.0)
    

    当需要给样本设置权重时,可以用如下方式

    w = np.random.rand(5,1)
    dtrain = xgb.DMatrix( data, label=label, missing = -999.0, weight=w)
    

    3.2 参数设置

    XGBoost使用key-value字典的方式存储参数:

    params = {
        'booster': 'gbtree',
        'objective': 'multi:softmax',  # 多分类的问题
        'num_class': 10,               # 类别数,与 multisoftmax 并用
        'gamma': 0.1,                  # 用于控制是否后剪枝的参数,越大越保守,一般0.1、0.2这样子。
        'max_depth': 12,               # 构建树的深度,越大越容易过拟合
        'lambda': 2,                   # 控制模型复杂度的权重值的L2正则化项参数,参数越大,模型越不容易过拟合。
        'subsample': 0.7,              # 随机采样训练样本
        'colsample_bytree': 0.7,       # 生成树时进行的列采样
        'min_child_weight': 3,
        'silent': 1,                   # 设置成1则没有运行信息输出,最好是设置为0.
        'eta': 0.007,                  # 如同学习率
        'seed': 1000,
        'nthread': 4,                  # cpu 线程数
    }
    

    3.3 训练模型

    有了参数列表和数据就可以训练模型了

    num_round = 10
    bst = xgb.train( plst, dtrain, num_round, evallist )
    

    3.4 模型预测

    # X_test类型可以是二维List,也可以是numpy的数组
    dtest = DMatrix(X_test)
    ans = model.predict(dtest)
    

    3.5 保存模型

    在训练完成之后可以将模型保存下来,也可以查看模型内部的结构

     bst.save_model('test.model')
    

    导出模型和特征映射(Map)

    你可以导出模型到txt文件并浏览模型的含义:

    # 导出模型到文件
    bst.dump_model('dump.raw.txt')
    # 导出模型和特征映射
    bst.dump_model('dump.raw.txt','featmap.txt')
    

    3.6 加载模型

    通过如下方式可以加载模型:

    bst = xgb.Booster({'nthread':4}) # init model
    bst.load_model("model.bin")      # load data
    

    XGBoost参数详解

    在运行XGboost之前,必须设置三种类型成熟:general parameters,booster parameters和task parameters:

    通用参数 :该参数参数控制在提升(boosting)过程中使用哪种booster,常用的booster有树模型(tree)和线性模型(linear model)。

    Booster参数 :这取决于使用哪种booster。

    学习目标参数 :控制学习的场景,例如在回归问题中会使用不同的参数控制排序。

    4.1 通用参数

    booster [default=gbtree]:有两中模型可以选择gbtree和gblinear。gbtree使用基于树的模型进行提升计算,gblinear使用线性模型进行提升计算。缺省值为gbtree

    silent [default=0]:取0时表示打印出运行时信息,取1时表示以缄默方式运行,不打印运行时信息。缺省值为0

    nthread:XGBoost运行时的线程数。缺省值是当前系统可以获得的最大线程数

    num_pbuffer:预测缓冲区大小,通常设置为训练实例的数目。缓冲用于保存最后一步提升的预测结果,无需人为设置。

    num_feature:Boosting过程中用到的特征维数,设置为特征个数。XGBoost会自动设置,无需人为设置。

    4.2 tree booster参数

    eta [default=0.3] :为了防止过拟合,更新过程中用到的收缩步长。在每次提升计算之后,算法会直接获得新特征的权重。 eta通过缩减特征的权重使提升计算过程更加保守。缺省值为0.3
    取值范围为:[0,1]。典型值为0.01-0.2。

    gamma [default=0] :在节点分裂时,只有分裂后损失函数的值下降了,才会分裂这个节点。Gamma指定了节点分裂所需的最小损失函数下降值。
    这个参数的值越大,算法越保守。这个参数的值和损失函数息息相关,所以是需要调整的。
    取值范围为:[0,∞]

    max_depth [default=6] :数的最大深度。缺省值为6 。取值范围为:[1,∞]。需要使用CV函数来进行调优。典型值:3-10

    min_child_weight [default=1] :孩子节点中最小的样本权重和。如果一个叶子节点的样本权重和小于min_child_weight则拆分过程结束。在现行回归模型中,这个参数是指建立每个模型所需要的最小样本数。这个参数用于避免过拟合。当它的值较大时,可以避免模型学习到局部的特殊样本。
    但是如果这个值过高,会导致欠拟合。这个参数需要使用CV来调整。取值范围为:[0,∞]

    max_delta_step [default=0] :我们允许每个树的权重被估计的值。如果它的值被设置为0,意味着没有约束;如果它被设置为一个正值,它能够使得更新的步骤更加保守。通常这个参数是没有必要的,但是如果在逻辑回归中类极其不平衡这时候他有可能会起到帮助作用。把它范围设置为1-10之间也许能控制更新。 取值范围为:[0,∞]

    subsample [default=1] :用于训练模型的子样本占整个样本集合的比例。如果设置为0.5则意味着XGBoost将随机的从整个样本集合中随机的抽取出50%的子样本建立树模型,这能够防止过拟合。 取值范围为:(0,1]

    colsample_bytree [default=1] :在建立树时对特征采样的比例。缺省值为1 。取值范围为:(0,1]

    4.3 Linear Booster参数

    lambda [default=0] :L2 正则的惩罚系数

    alpha [default=0] :L1 正则的惩罚系数

    lambda_bias :在偏置上的L2正则。缺省值为0(在L1上没有偏置项的正则,因为L1时偏置不重要)

    4.4 学习目标参数

    objective [ default=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的向量,可以将该向量reshape成ndata行nclass列的矩阵。没行数据表示样本所属于每个类别的概率。
    • “rank:pairwise” –set XGBoost to do ranking task by minimizing the pairwise loss

    base_score [ default=0.5 ]

    所有实例的初始化预测分数,全局偏置;
    当有足够的迭代次数时,改变这个值将不会有太大的影响。

    eval_metric [ default according to objective ]

    校验数据所需要的评价指标,不同的目标函数将会有缺省的评价指标(rmse for regression, and error for classification, mean average precision for ranking)-

    用户可以添加多种评价指标,对于Python用户要以list传递参数对给程序,而不是map参数list参数不会覆盖’eval_metric’

    可供的选择如下:

    • rmse 均方根误差(∑i=1Nϵ2N\sqrt {\frac{\sum_{i=1}^Nϵ^2}{N}}Ni=1Nϵ2)
    • mae 平均绝对误差(∑i=1N∣ϵ∣N\frac{\sum_{i=1}^N|ϵ|}{N}Ni=1Nϵ)
    • logloss 负对数似然函数值
    • error 二分类错误率(阈值为0.5)
    • merror 多分类错误率
    • mlogloss 多分类logloss损失函数
    • auc 曲线下面积

    seed [ default=0 ]

    随机数的种子。缺省值为0

    xgboost 基本方法和默认参数

    函数原型:

    xgboost.train(params,dtrain,num_boost_round=10,evals=(),obj=None,feval=None,maximize=False,early_stopping_rounds=None,evals_result=None,verbose_eval=True,learning_rates=None,xgb_model=None)  
    

    params :这是一个字典,里面包含着训练中的参数关键字和对应的值,形式是params = {‘booster’:’gbtree’, ’eta’:0.1}
    dtrain :训练的数据
    num_boost_round :这是指提升迭代的个数
    evals :这是一个列表,用于对训练过程中进行评估列表中的元素。形式是evals = [(dtrain,’train’), (dval,’val’)]或者是evals = [ (dtrain,’train’)], 对于第一种情况,它使得我们可以在训练过程中观察验证集的效果。
    obj:自定义目的函数
    feval:自定义评估函数
    maximize: 是否对评估函数进行最大化
    early_stopping_rounds: 早期停止次数 ,假设为100,验证集的误差迭代到一定程度在100次内不能再继续降低,就停止迭代。这要求evals 里至少有一个元素,如果有多个,按最后一个去执行。返回的是最后的迭代次数(不是最好的)。如果early_stopping_rounds 存在,则模型会生成三个属性,bst.best_score, bst.best_iteration, 和bst.best_ntree_limit
    evals_result :字典,存储在watchlist 中的元素的评估结果。
    verbose_eval(可以输入布尔型或数值型):也要求evals 里至少有 一个元素。如果为True, 则对evals中元素的评估结果会输出在结果中;如果输入数字,假设为5,则每隔5个迭代输出一次。
    learning_rates :每一次提升的学习率的列表,
    xgb_model:在训练之前用于加载的xgb model。

    1. XGBoost实战

    XGBoost有两大类接口:XGBoost原生接口 和 scikit-learn接口 ,并且XGBoost能够实现 分类 和 回归 两种任务。因此,本章节分四个小块来介绍!

    5.1 基于XGBoost原生接口的分类

    # ================基于XGBoost原生接口的分类=============
    from sklearn.datasets import load_iris
    import xgboost as xgb
    from xgboost import plot_importance
    from matplotlib import pyplot as plt
    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=1234565) # 数据集分割
    
    # 算法参数
    params = {
        'booster': 'gbtree',
        'objective': 'multi:softmax',
        'num_class': 3,
        'gamma': 0.1,
        'max_depth': 6,
        'lambda': 2,
        'subsample': 0.7,
        'colsample_bytree': 0.7,
        'min_child_weight': 3,
        'silent': 1,
        'eta': 0.1,
        'seed': 1000,
        'nthread': 4,
    }
    
    plst = params.items()
    
    
    dtrain = xgb.DMatrix(X_train, y_train) # 生成数据集格式
    num_rounds = 500
    model = xgb.train(plst, dtrain, num_rounds) # xgboost模型训练
    
    # 对测试集进行预测
    dtest = xgb.DMatrix(X_test)
    y_pred = model.predict(dtest)
    
    # 计算准确率
    accuracy = accuracy_score(y_test,y_pred)
    print("accuarcy: %.2f%%" % (accuracy*100.0))
    
    # 显示重要特征
    plot_importance(model)
    plt.show()
    

    输出预测正确率以及特征重要性:

    Accuracy: 96.67 %

    这里写图片描述

    5.2 基于XGBoost原生接口的回归

    # ================基于XGBoost原生接口的回归=============
    
    import xgboost as xgb
    from xgboost import plot_importance
    from matplotlib import pyplot as plt
    from sklearn.model_selection import train_test_split
    from sklearn.datasets import load_boston
    from sklearn.metrics import mean_squared_error
    
    # 加载数据集
    boston = load_boston()
    X,y = boston.data,boston.target
    
    # XGBoost训练过程
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)
    
    params = {
        'booster': 'gbtree',
        'objective': 'reg:gamma',
        'gamma': 0.1,
        'max_depth': 5,
        'lambda': 3,
        'subsample': 0.7,
        'colsample_bytree': 0.7,
        'min_child_weight': 3,
        'silent': 1,
        'eta': 0.1,
        'seed': 1000,
        'nthread': 4,
    }
    
    dtrain = xgb.DMatrix(X_train, y_train)
    num_rounds = 300
    plst = params.items()
    model = xgb.train(plst, dtrain, num_rounds)
    
    # 对测试集进行预测
    dtest = xgb.DMatrix(X_test)
    ans = model.predict(dtest)
    
    # 显示重要特征
    plot_importance(model)
    plt.show()
    
    

    重要特征(值越大,说明该特征越重要)显示结果:

    这里写图片描述

    xgb使用sklearn接口(推荐)

    XGBClassifier

    from xgboost.sklearn import XGBClassifier
    clf = XGBClassifier(
    silent=0 ,#设置成1则没有运行信息输出,最好是设置为0.是否在运行升级时打印消息。
    #nthread=4,# cpu 线程数 默认最大
    learning_rate= 0.3, # 如同学习率
    min_child_weight=1, 
    # 这个参数默认是 1,是每个叶子里面 h 的和至少是多少,对正负样本不均衡时的 0-1 分类而言
    #,假设 h 在 0.01 附近,min_child_weight 为 1 意味着叶子节点中最少需要包含 100 个样本。
    #这个参数非常影响结果,控制叶子节点中二阶导的和的最小值,该参数值越小,越容易 overfitting。
    max_depth=6, # 构建树的深度,越大越容易过拟合
    gamma=0,  # 树的叶子节点上作进一步分区所需的最小损失减少,越大越保守,一般0.1、0.2这样子。
    subsample=1, # 随机采样训练样本 训练实例的子采样比
    max_delta_step=0,#最大增量步长,我们允许每个树的权重估计。
    colsample_bytree=1, # 生成树时进行的列采样 
    reg_lambda=1,  # 控制模型复杂度的权重值的L2正则化项参数,参数越大,模型越不容易过拟合。
    #reg_alpha=0, # L1 正则项参数
    #scale_pos_weight=1, #如果取值大于0的话,在类别样本不平衡的情况下有助于快速收敛。平衡正负权重
    #objective= 'multi:softmax', #多分类的问题 指定学习任务和相应的学习目标
    #num_class=10, # 类别数,多分类与 multisoftmax 并用
    n_estimators=100, #树的个数
    seed=1000 #随机种子
    #eval_metric= 'auc'
    )
    clf.fit(X_train,y_train,eval_metric='auc')
    

    5.3 基于Scikit-learn接口的分类

    # ==============基于Scikit-learn接口的分类================
    from sklearn.datasets import load_iris
    import xgboost as xgb
    from xgboost import plot_importance
    from matplotlib import pyplot as plt
    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=1234565) # 数据集分割
    
    # 训练模型
    model = xgb.XGBClassifier(max_depth=5, learning_rate=0.1, n_estimators=160, silent=True, objective='multi:softmax')
    model.fit(X_train, y_train)
    
    # 对测试集进行预测
    y_pred = model.predict(X_test)
    
    # 计算准确率
    accuracy = accuracy_score(y_test,y_pred)
    print("accuarcy: %.2f%%" % (accuracy*100.0))
    
    # 显示重要特征
    plot_importance(model)
    plt.show()
    
    

    输出结果:Accuracy: 96.67 %

    这里写图片描述

    基于Scikit-learn接口的回归

    # ================基于Scikit-learn接口的回归================
    import xgboost as xgb
    from xgboost import plot_importance
    from matplotlib import pyplot as plt
    from sklearn.model_selection import train_test_split
    from sklearn.datasets import load_boston
    
    boston = load_boston()
    X,y = boston.data,boston.target
    
    # XGBoost训练过程
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)
    
    model = xgb.XGBRegressor(max_depth=5, learning_rate=0.1, n_estimators=160, silent=True, objective='reg:gamma')
    model.fit(X_train, y_train)
    
    # 对测试集进行预测
    ans = model.predict(X_test)
    
    # 显示重要特征
    plot_importance(model)
    plt.show()
    
    

    这里写图片描述

    参数调优的一般方法

    我们会使用和GBM中相似的方法。需要进行如下步骤:

    1. 选择较高的学习速率(learning rate)。一般情况下,学习速率的值为0.1。但是,对于不同的问题,理想的学习速率有时候会在0.05到0.3之间波动。选择对应于此学习速率的理想决策树数量。XGBoost有一个很有用的函数“cv”,这个函数可以在每一次迭代中使用交叉验证,并返回理想的决策树数量。
    2. 对于给定的学习速率和决策树数量,进行决策树特定参数调优(max_depth, min_child_weight, gamma, subsample, colsample_bytree)。在确定一棵树的过程中,我们可以选择不同的参数,待会儿我会举例说明。
    3. xgboost的正则化参数的调优。(lambda, alpha)。这些参数可以降低模型的复杂度,从而提高模型的表现。
    4. 降低学习速率,确定理想参数。

    咱们一起详细地一步步进行这些操作。

    第一步:确定学习速率和tree_based 参数调优的估计器数目。

    为了确定boosting 参数,我们要先给其它参数一个初始值。咱们先按如下方法取值:
    1、max_depth = 5 :这个参数的取值最好在3-10之间。我选的起始值为5,但是你也可以选择其它的值。起始值在4-6之间都是不错的选择。
    2、min_child_weight = 1:在这里选了一个比较小的值,因为这是一个极不平衡的分类问题。因此,某些叶子节点下的值会比较小。
    3、gamma = 0: 起始值也可以选其它比较小的值,在0.1到0.2之间就可以。这个参数后继也是要调整的。
    4、subsample,colsample_bytree = 0.8: 这个是最常见的初始值了。典型值的范围在0.5-0.9之间。
    5、scale_pos_weight = 1: 这个值是因为类别十分不平衡。
    注意哦,上面这些参数的值只是一个初始的估计值,后继需要调优。这里把学习速率就设成默认的0.1。然后用xgboost中的cv函数来确定最佳的决策树数量。

    第二步: max_depth 和 min_weight 参数调优

    我们先对这两个参数调优,是因为它们对最终结果有很大的影响。首先,我们先大范围地粗调参数,然后再小范围地微调。
    注意:在这一节我会进行高负荷的栅格搜索(grid search),这个过程大约需要15-30分钟甚至更久,具体取决于你系统的性能。你也可以根据自己系统的性能选择不同的值。

    第三步:gamma参数调优

    第四步:调整subsample 和 colsample_bytree 参数

    第五步:正则化参数调优。

    第6步:降低学习速率
    最后,我们使用较低的学习速率,以及使用更多的决策树。我们可以用XGBoost中的CV函数来进行这一步工作。

    展开全文
  • python机器学习案例系列教程——LightGBM算法

    万次阅读 多人点赞 2018-05-08 16:23:08
    安装pip install lightgbmgitup网址:https://github.com/Microsoft/LightGBM中文教程http://lightgbm.apachecn.org/cn/latest/index.htmllightGBM简介xgboost的出现,让数据民工们告别了传统的机器学习算法们:RF、...

    分享一个朋友的人工智能教程。零基础!通俗易懂!风趣幽默!还带黄段子!大家可以看看是否对自己有帮助:点击打开


    全栈工程师开发手册 (作者:栾鹏)
    python教程全解

    安装

    pip install lightgbm
    

    gitup网址:https://github.com/Microsoft/LightGBM

    中文教程

    http://lightgbm.apachecn.org/cn/latest/index.html

    lightGBM简介

    xgboost的出现,让数据民工们告别了传统的机器学习算法们:RF、GBM、SVM、LASSO………。现在微软推出了一个新的boosting框架,想要挑战xgboost的江湖地位。

    顾名思义,lightGBM包含两个关键点:light即轻量级,GBM 梯度提升机。

    LightGBM 是一个梯度 boosting 框架,使用基于学习算法的决策树。它可以说是分布式的,高效的,有以下优势:

    • 更快的训练效率

    • 低内存使用

    • 更高的准确率

    • 支持并行化学习

    • 可处理大规模数据

    xgboost缺点

    其缺点,或者说不足之处:

    每轮迭代时,都需要遍历整个训练数据多次。如果把整个训练数据装进内存则会限制训练数据的大小;如果不装进内存,反复地读写训练数据又会消耗非常大的时间。

    预排序方法(pre-sorted):首先,空间消耗大。这样的算法需要保存数据的特征值,还保存了特征排序的结果(例如排序后的索引,为了后续快速的计算分割点),这里需要消耗训练数据两倍的内存。其次时间上也有较大的开销,在遍历每一个分割点的时候,都需要进行分裂增益的计算,消耗的代价大。

    对cache优化不友好。在预排序后,特征对梯度的访问是一种随机访问,并且不同的特征访问的顺序不一样,无法对cache进行优化。同时,在每一层长树的时候,需要随机访问一个行索引到叶子索引的数组,并且不同特征访问的顺序也不一样,也会造成较大的cache miss。

    lightGBM特点

    以上与其说是xgboost的不足,倒不如说是lightGBM作者们构建新算法时着重瞄准的点。解决了什么问题,那么原来模型没解决就成了原模型的缺点。

    概括来说,lightGBM主要有以下特点:

    • 基于Histogram的决策树算法

    • 带深度限制的Leaf-wise的叶子生长策略

    • 直方图做差加速

    • 直接支持类别特征(Categorical Feature)

    • Cache命中率优化

    • 基于直方图的稀疏特征优化

    • 多线程优化

    前2个特点使我们尤为关注的。

    Histogram算法

    直方图算法的基本思想:先把连续的浮点特征值离散化成k个整数,同时构造一个宽度为k的直方图。遍历数据时,根据离散化后的值作为索引在直方图中累积统计量,当遍历一次数据后,直方图累积了需要的统计量,然后根据直方图的离散值,遍历寻找最优的分割点。

    带深度限制的Leaf-wise的叶子生长策略

    Level-wise过一次数据可以同时分裂同一层的叶子,容易进行多线程优化,也好控制模型复杂度,不容易过拟合。但实际上Level-wise是一种低效算法,因为它不加区分的对待同一层的叶子,带来了很多没必要的开销,因为实际上很多叶子的分裂增益较低,没必要进行搜索和分裂。

    Leaf-wise则是一种更为高效的策略:每次从当前所有叶子中,找到分裂增益最大的一个叶子,然后分裂,如此循环。因此同Level-wise相比,在分裂次数相同的情况下,Leaf-wise可以降低更多的误差,得到更好的精度。

    Leaf-wise的缺点:可能会长出比较深的决策树,产生过拟合。因此LightGBM在Leaf-wise之上增加了一个最大深度限制,在保证高效率的同时防止过拟合。

    xgboost和lightgbm

    决策树算法

    XGBoost使用的是pre-sorted算法,能够更精确的找到数据分隔点;

    • 首先,对所有特征按数值进行预排序。
    • 其次,在每次的样本分割时,用O(# data)的代价找到每个特征的最优分割点。
    • 最后,找到最后的特征以及分割点,将数据分裂成左右两个子节点。

    优缺点:

    这种pre-sorting算法能够准确找到分裂点,但是在空间和时间上有很大的开销。

    • i. 由于需要对特征进行预排序并且需要保存排序后的索引值(为了后续快速的计算分裂点),因此内存需要训练数据的两倍。
    • ii. 在遍历每一个分割点的时候,都需要进行分裂增益的计算,消耗的代价大。

    LightGBM使用的是histogram算法,占用的内存更低,数据分隔的复杂度更低。

    其思想是将连续的浮点特征离散成k个离散值,并构造宽度为k的Histogram。然后遍历训练数据,统计每个离散值在直方图中的累计统计量。在进行特征选择时,只需要根据直方图的离散值,遍历寻找最优的分割点。

    Histogram 算法的优缺点:

    • Histogram算法并不是完美的。由于特征被离散化后,找到的并不是很精确的分割点,所以会对结果产生影响。但在实际的数据集上表明,离散化的分裂点对最终的精度影响并不大,甚至会好一些。原因在于decision tree本身就是一个弱学习器,采用Histogram算法会起到正则化的效果,有效地防止模型的过拟合。
    • 时间上的开销由原来的O(#data * #features)降到O(k * #features)。由于离散化,#bin远小于#data,因此时间上有很大的提升。
    • Histogram算法还可以进一步加速。一个叶子节点的Histogram可以直接由父节点的Histogram和兄弟节点的Histogram做差得到。一般情况下,构造Histogram需要遍历该叶子上的所有数据,通过该方法,只需要遍历Histogram的k个捅。速度提升了一倍。

    决策树生长策略

    XGBoost采用的是按层生长level(depth)-wise生长策略,如Figure 1所示,能够同时分裂同一层的叶子,从而进行多线程优化,不容易过拟合;但不加区分的对待同一层的叶子,带来了很多没必要的开销。因为实际上很多叶子的分裂增益较低,没必要进行搜索和分裂。

    这里写图片描述

    LightGBM采用leaf-wise生长策略,如Figure 2所示,每次从当前所有叶子中找到分裂增益最大(一般也是数据量最大)的一个叶子,然后分裂,如此循环。因此同Level-wise相比,在分裂次数相同的情况下,Leaf-wise可以降低更多的误差,得到更好的精度。Leaf-wise的缺点是可能会长出比较深的决策树,产生过拟合。因此LightGBM在Leaf-wise之上增加了一个最大深度的限制,在保证高效率的同时防止过拟合。

    这里写图片描述

    网络通信优化

    XGBoost由于采用pre-sorted算法,通信代价非常大,所以在并行的时候也是采用histogram算法;LightGBM采用的histogram算法通信代价小,通过使用集合通信算法,能够实现并行计算的线性加速。

    LightGBM支持类别特征

    实际上大多数机器学习工具都无法直接支持类别特征,一般需要把类别特征,转化one-hotting特征,降低了空间和时间的效率。而类别特征的使用是在实践中很常用的。基于这个考虑,LightGBM优化了对类别特征的支持,可以直接输入类别特征,不需要额外的0/1展开。并在决策树算法上增加了类别特征的决策规则。

    lightGBM调参

    所有的参数含义,参考:http://lightgbm.apachecn.org/cn/latest/Parameters.html

    调参过程:

    (1)num_leaves

    LightGBM使用的是leaf-wise的算法,因此在调节树的复杂程度时,使用的是num_leaves而不是max_depth。

    大致换算关系:num_leaves = 2^(max_depth)

    (2)样本分布非平衡数据集:可以param[‘is_unbalance’]=’true’

    (3)Bagging参数:bagging_fraction+bagging_freq(必须同时设置)、feature_fraction

    (4)min_data_in_leaf、min_sum_hessian_in_leaf

    sklearn接口形式的LightGBM示例

    这里主要以sklearn的使用形式来使用lightgbm算法,包含建模,训练,预测,网格参数优化。

    import lightgbm as lgb
    import pandas as pd
    from sklearn.metrics import mean_squared_error
    from sklearn.model_selection import GridSearchCV
    from sklearn.datasets import load_iris
    from sklearn.model_selection import train_test_split
    from sklearn.datasets import  make_classification
    # 加载数据
    print('Load data...')
    
    iris = load_iris()
    data=iris.data
    target = iris.target
    X_train,X_test,y_train,y_test =train_test_split(data,target,test_size=0.2)
    
    # df_train = pd.read_csv('../regression/regression.train', header=None, sep='\t')
    # df_test = pd.read_csv('../regression/regression.test', header=None, sep='\t')
    # y_train = df_train[0].values
    # y_test = df_test[0].values
    # X_train = df_train.drop(0, axis=1).values
    # X_test = df_test.drop(0, axis=1).values
    
    print('Start training...')
    # 创建模型,训练模型
    gbm = lgb.LGBMRegressor(objective='regression',num_leaves=31,learning_rate=0.05,n_estimators=20)
    gbm.fit(X_train, y_train,eval_set=[(X_test, y_test)],eval_metric='l1',early_stopping_rounds=5)
    
    print('Start predicting...')
    # 测试机预测
    y_pred = gbm.predict(X_test, num_iteration=gbm.best_iteration_)
    # 模型评估
    print('The rmse of prediction is:', mean_squared_error(y_test, y_pred) ** 0.5)
    
    # feature importances
    print('Feature importances:', list(gbm.feature_importances_))
    
    # 网格搜索,参数优化
    estimator = lgb.LGBMRegressor(num_leaves=31)
    
    param_grid = {
        'learning_rate': [0.01, 0.1, 1],
        'n_estimators': [20, 40]
    }
    
    gbm = GridSearchCV(estimator, param_grid)
    
    gbm.fit(X_train, y_train)
    
    print('Best parameters found by grid search are:', gbm.best_params_)
    
    

    原生形式使用lightgbm

    # coding: utf-8
    # pylint: disable = invalid-name, C0111
    import json
    import lightgbm as lgb
    import pandas as pd
    from sklearn.metrics import mean_squared_error
    from sklearn.datasets import load_iris
    from sklearn.model_selection import train_test_split
    from sklearn.datasets import  make_classification
    
    iris = load_iris()
    data=iris.data
    target = iris.target
    X_train,X_test,y_train,y_test =train_test_split(data,target,test_size=0.2)
    
    
    # 加载你的数据
    # print('Load data...')
    # df_train = pd.read_csv('../regression/regression.train', header=None, sep='\t')
    # df_test = pd.read_csv('../regression/regression.test', header=None, sep='\t')
    #
    # y_train = df_train[0].values
    # y_test = df_test[0].values
    # X_train = df_train.drop(0, axis=1).values
    # X_test = df_test.drop(0, axis=1).values
    
    # 创建成lgb特征的数据集格式
    lgb_train = lgb.Dataset(X_train, y_train)
    lgb_eval = lgb.Dataset(X_test, y_test, reference=lgb_train)
    
    # 将参数写成字典下形式
    params = {
        'task': 'train',
        'boosting_type': 'gbdt',  # 设置提升类型
        'objective': 'regression', # 目标函数
        'metric': {'l2', 'auc'},  # 评估函数
        'num_leaves': 31,   # 叶子节点数
        'learning_rate': 0.05,  # 学习速率
        'feature_fraction': 0.9, # 建树的特征选择比例
        'bagging_fraction': 0.8, # 建树的样本采样比例
        'bagging_freq': 5,  # k 意味着每 k 次迭代执行bagging
        'verbose': 1 # <0 显示致命的, =0 显示错误 (警告), >0 显示信息
    }
    
    print('Start training...')
    # 训练 cv and train
    gbm = lgb.train(params,lgb_train,num_boost_round=20,valid_sets=lgb_eval,early_stopping_rounds=5)
    
    print('Save model...')
    # 保存模型到文件
    gbm.save_model('model.txt')
    
    print('Start predicting...')
    # 预测数据集
    y_pred = gbm.predict(X_test, num_iteration=gbm.best_iteration)
    # 评估模型
    print('The rmse of prediction is:', mean_squared_error(y_test, y_pred) ** 0.5)
    
    
    展开全文
  • Python机器学习--四大基础库

    千人学习 2017-09-06 13:48:15
    科学计算库Numpy ,数据分析处理库Pandas,可视化库Matplotlib与Seaborn 是Python机器学习中最基本的四大机器学习库,也是Python机器学习的发展主线。本课程重点介绍了Python库的基本知识点,使用方法并配合案列...
  • python机器学习库sklearn——Lasso回归(L1正则化)

    万次阅读 多人点赞 2018-04-06 09:00:56
    python数据挖掘系列教程 The Lasso 是估计稀疏系数的线性模型。 它在一些情况下是有用的,因为它倾向于使用具有较少参数值的情况,有效地减少给定解决方案所依赖变量的数量。 因此,Lasso 及其变体是压缩感知领域的...

    分享一个朋友的人工智能教程。零基础!通俗易懂!风趣幽默!还带黄段子!大家可以看看是否对自己有帮助:点击打开

    ad1.jpg

    全栈工程师开发手册 (作者:栾鹏)
    python数据挖掘系列教程

    Lasso

    The Lasso 是估计稀疏系数的线性模型。 它在一些情况下是有用的,因为它倾向于使用具有较少参数值的情况,有效地减少给定解决方案所依赖变量的数量。 因此,Lasso 及其变体是压缩感知领域的基础。 在一定条件下,它可以恢复一组非零权重的精确集。

    在数学公式表达上,它由一个带有$ \ell_1 $先验的正则项的线性模型组成。 其最小化的目标函数是:

    min w12nsamples∣∣Xw−y∣∣22+α∣∣w∣∣1\underset{w}{min\,} { \frac{1}{2n_{samples}} ||X w - y||_2 ^ 2 + \alpha ||w||_1}wmin2nsamples1Xwy22+αw1

    lasso 估计解决了加上罚项$ \alpha ||w||_1 的最小二乘法的最小化,其中,的最小二乘法的最小化,其中, \alpha$ 是一个常数,$ ||w||_1 $是参数向量的 ℓ1−norm\ell_1-norm1norm 范数。

    Lasso 类的实现使用了 coordinate descent (坐标下降算法)来拟合系数。

    设置正则化参数

    scikit-learn 通过交叉验证来公开设置 Lasso中α\alphaα 参数的对象: LassoCV 和 LassoLarsCV。 LassoLarsCV 是基于下面解释的 最小角回归 算法。

    对于具有许多线性回归的高维数据集, LassoCV 最常见。 然而,LassoLarsCV 在寻找 α\alphaα 参数值上更具有优势,而且如果样本数量与特征数量相比非常小时,通常 LassoLarsCV 比 LassoCV 要快。

    与 SVM 的正则化参数的比较

    α\alphaα 和 SVM 的正则化参数CCC之间的等式关系是 α=1/C\alpha = 1 / Cα=1/C 或者 $\alpha = 1 / (n_{samples} * C) $,并依赖于估计器和模型优化的确切的目标函数。

    主参数设置

    alpha : float, 可选,默认 1.0。当 alpha 为 0 时算法等同于普通最小二乘法,可通过 Linear Regression 实现,因此不建议将 alpha 设为 0.

    fit_intercept : boolean
    是否进行拦截计算(intercept)。若 false,则不计算(比如数据已经经过集中了)。此处不太明白,仿佛与偏度有关。

    normalize : boolean, 可选, 默认 False
    若 True,则先 normalize 再 regression。若 fit_intercept 为 false 则忽略此参数。当 regressors 被 normalize 的时候,需要注意超参(hyperparameters)的学习会更稳定,几乎独立于 sample。对于标准化的数据,就不会有此种情况。如果需要标准化数据,请对数据预处理。然后在学习时设置 normalize=False。

    copy_X : boolean, 可选, 默认 True
    若 True,则会复制 X;否则可能会被覆盖。

    precompute : True | False | array-like, 默认=False
    是否使用预计算的 Gram 矩阵来加速计算。如果设置为 ‘auto’ 则机器决定。Gram 矩阵也可以 pass。对于 sparse input 这个选项永远为 True。

    max_iter : int, 可选
    最大循环次数。

    tol : float, 可选
    优化容忍度 The tolerance for the optimization: 若更新后小于 tol,优化代码检查优化的 dual gap 并继续直到小于 tol 为止。

    warm_start : bool, 可选
    为 True 时, 重复使用上一次学习作为初始化,否则直接清除上次方案。

    positive : bool, 可选
    设为 True 时,强制使系数为正。

    selection : str, 默认 ‘cyclic’
    若设为 ‘random’, 每次循环会随机更新参数,而按照默认设置则会依次更新。设为随机通常会极大地加速交点(convergence)的产生,尤其是 tol 比 1e-4 大的情况下。

    random_state : int, RandomState instance, 或者 None (默认值)
    pseudo random number generator 用来产生随机 feature 进行更新时需要用的

    seed。仅当 selection 为 random 时才可用。

    代码实现

    import numpy as np # 快速操作结构数组的工具
    import matplotlib.pyplot as plt  # 可视化绘制
    from sklearn.linear_model import Lasso,LassoCV,LassoLarsCV   # Lasso回归,LassoCV交叉验证实现alpha的选取,LassoLarsCV基于最小角回归交叉验证实现alpha的选取
    
    
    # 样本数据集,第一列为x,第二列为y,在x和y之间建立回归模型
    data=[
        [0.067732,3.176513],[0.427810,3.816464],[0.995731,4.550095],[0.738336,4.256571],[0.981083,4.560815],
        [0.526171,3.929515],[0.378887,3.526170],[0.033859,3.156393],[0.132791,3.110301],[0.138306,3.149813],
        [0.247809,3.476346],[0.648270,4.119688],[0.731209,4.282233],[0.236833,3.486582],[0.969788,4.655492],
        [0.607492,3.965162],[0.358622,3.514900],[0.147846,3.125947],[0.637820,4.094115],[0.230372,3.476039],
        [0.070237,3.210610],[0.067154,3.190612],[0.925577,4.631504],[0.717733,4.295890],[0.015371,3.085028],
        [0.335070,3.448080],[0.040486,3.167440],[0.212575,3.364266],[0.617218,3.993482],[0.541196,3.891471]
    ]
    
    
    #生成X和y矩阵
    dataMat = np.array(data)
    X = dataMat[:,0:1]   # 变量x
    y = dataMat[:,1]   #变量y
    
    
    
    # ========Lasso回归========
    model = Lasso(alpha=0.01)  # 调节alpha可以实现对拟合的程度
    # model = LassoCV()  # LassoCV自动调节alpha可以实现选择最佳的alpha。
    # model = LassoLarsCV()  # LassoLarsCV自动调节alpha可以实现选择最佳的alpha
    model.fit(X, y)   # 线性回归建模
    print('系数矩阵:\n',model.coef_)
    print('线性回归模型:\n',model)
    # print('最佳的alpha:',model.alpha_)  # 只有在使用LassoCV、LassoLarsCV时才有效
    # 使用模型预测
    predicted = model.predict(X)
    
    # 绘制散点图 参数:x横轴 y纵轴
    plt.scatter(X, y, marker='x')
    plt.plot(X, predicted,c='r')
    
    # 绘制x轴和y轴坐标
    plt.xlabel("x")
    plt.ylabel("y")
    
    # 显示图形
    plt.show()
    
    
    

    这里写图片描述

    多任务回归

    MultiTaskLasso 是一个估计多元回归稀疏系数的线性模型: $y $是一个 (nsamples,ntasks)(n_{samples}, n_{tasks})(nsamples,ntasks) 的二维数组,其约束条件和其他回归问题(也称为任务)是一样的,都是所选的特征值。
    下图比较了通过使用简单的 Lasso 或 MultiTaskLasso 得到的 W 中非零的位置。 Lasso 估计产生分散的非零值,而 MultiTaskLasso 的一整列都是非零的。

    在数学上,它由一个线性模型组成,以混合的 $\ell_1 \ell_2 $作为正则化器进行训练。目标函数最小化是:

    min w12nsamples∣∣XW−Y∣∣Fro2+α∣∣W∣∣21\underset{w}{min\,} { \frac{1}{2n_{samples}} ||X W - Y||_{Fro} ^ 2 + \alpha ||W||_{21}}wmin2nsamples1XWYFro2+αW21

    其中 Fro 表示 Frobenius 标准:

    ∣∣A∣∣Fro=∑ijaij2||A||_{Fro} = \sqrt{\sum_{ij} a_{ij}^2}AFro=ijaij2

    并且 ℓ1ℓ2\ell_1 \ell_212 读取为:

    ∣∣A∣∣21=∑i∑jaij2||A||_{2 1} = \sum_i \sqrt{\sum_j a_{ij}^2}A21=ijaij2

    MultiTaskLasso 类的实现使用了坐标下降作为拟合系数的算法。

    import matplotlib.pyplot as plt
    import numpy as np
    from sklearn.linear_model import MultiTaskLasso, Lasso
    
    rng = np.random.RandomState(42)
    # ===========================产生模拟样本数据=========================
    # 用随机的频率、相位产生正弦波的二维系数
    n_samples, n_features, n_tasks = 100, 30, 40  # n_samples样本个数,n_features特征个数,n_tasks估计值的个数
    n_relevant_features = 5 # 自定义实际有用特征的个数
    coef = np.zeros((n_tasks, n_features)) # 系数矩阵的维度
    
    times = np.linspace(0, 2 * np.pi, n_tasks)
    for k in range(n_relevant_features):
        coef[:, k] = np.sin((1. + rng.randn(1)) * times + 3 * rng.randn(1)) # 自定义数据矩阵,用来生成模拟输出值
    
    X = rng.randn(n_samples, n_features)  # 产生随机输入矩阵
    Y = np.dot(X, coef.T) + rng.randn(n_samples, n_tasks) # 输入*系数+噪声=模拟输出
    # ==============================使用样本数据训练系数矩阵============================
    coef_lasso_ = np.array([Lasso(alpha=0.5).fit(X, y).coef_ for y in Y.T])
    coef_multi_task_lasso_ = MultiTaskLasso(alpha=1.).fit(X, Y).coef_  # 多任务训练
    
    # #############################################################################
    # Plot support and time series
    fig = plt.figure(figsize=(8, 5))
    plt.subplot(1, 2, 1)
    plt.spy(coef_lasso_)
    plt.xlabel('Feature')
    plt.ylabel('Time (or Task)')
    plt.text(10, 5, 'Lasso')
    plt.subplot(1, 2, 2)
    plt.spy(coef_multi_task_lasso_)
    plt.xlabel('Feature')
    plt.ylabel('Time (or Task)')
    plt.text(10, 5, 'MultiTaskLasso')
    fig.suptitle('Coefficient non-zero location')
    
    feature_to_plot = 0
    plt.figure()
    lw = 2
    plt.plot(coef[:, feature_to_plot], color='seagreen', linewidth=lw,
             label='Ground truth')
    plt.plot(coef_lasso_[:, feature_to_plot], color='cornflowerblue', linewidth=lw,
             label='Lasso')
    plt.plot(coef_multi_task_lasso_[:, feature_to_plot], color='gold', linewidth=lw,
             label='MultiTaskLasso')
    plt.legend(loc='upper center')
    plt.axis('tight')
    plt.ylim([-1.1, 1.1])
    plt.show()
    

    这里写图片描述

    展开全文
  • Python机器学习经典案例实战

    千人学习 2017-03-24 08:54:50
    Python机器学习领域应用是非常广泛的,比如,我们可以使用机器学习进行验证码识别,使用机器学习实现计算机视觉项目,或者,我们也可以使用机器学习技术实现网页分类、文本挖掘、情感分析等等各种各样的事情。机器...
  • 全栈工程师开发手册 (作者:栾鹏) python数据挖掘系列教程 学习预测函数的参数,并在相同数据集上进行测试... 为了避免这种情况,在进行(监督)机器学习实验时,通常取出部分可利用数据作为 test set(测试...
  • python机器学习库sklearn——DBSCAN密度聚类

    万次阅读 多人点赞 2018-03-05 11:13:12
    python数据挖掘系列教程 DBSCAN密度聚类的相关的知识内容可以参考 http://blog.csdn.net/luanpeng825485697/article/details/79438025 DBSCAN The DBSCAN 算法将聚类视为被低密度区域分隔的高密度区域。由于...
  • python机器学习库sklearn——神经网络

    万次阅读 2018-01-15 15:02:16
    python数据挖掘系列教程 神经网络算法详情参考: https://blog.csdn.net/luanpeng825485697/article/details/79009050 https://blog.csdn.net/luanpeng825485697/article/details/79009154 https://blog...
  • Python机器学习算法和实践

    千人学习 2018-06-22 15:49:25
    机器学习算法实战教程,包括各种常用机器学习算法,该课程教学视频以手写形式+普通话授课(类似斯坦福大学授课方式),+Python代码。经典算法进行原理推导与案例实战双管齐下,具体课程内容包括K-Means算法、KNN算法...
  • Python 机器学习经典实例

    万次阅读 2018-04-12 10:44:15
    内容介绍 在如今这个处处以数据驱动的世界中,机器学习正变得越来越大众化。它已经被广泛地应用于不同领域,如搜索...用最火的 Python 语言、通过各种各样的机器学习算法来解决实际问题! 书中介绍的主要问题如下。 ...
  • Python机器学习进阶实战视频教学

    千人学习 2018-11-14 14:51:56
    进阶实战课程旨在帮助同学们掌握机器学习进阶算法原理并应用Python工具包进行实战任务,学习过程中建议大家先掌握机器学习经典算法再加入进阶实战课程中。课程整体风格通俗易懂,用最接地气的方式带大家轻松入门...
  • python机器学习库sklearn——支持向量机svm

    万次阅读 多人点赞 2018-04-03 22:04:12
    python数据挖掘系列教程 支持向量机svm的相关的知识内容可以参考 https://blog.csdn.net/luanpeng825485697/article/details/78823919 支持向量机的优势在于: 在高维空间中非常高效.即使在数据维度比样本数量...
  • Python常用的机器学习Python在科学计算中用途广泛:计算机视觉、人工智能、数学、天文等。它同样适用于机器学习也是意料之中的事。 这篇文章就列举并描述Python的最有用的机器学习工具和库。这个列表中,我们不...
  • 机器学习(数据挖掘或预测分析)
  • Python机器学习之Logistic回归

    万次阅读 2016-04-14 17:11:38
    大数据时代,数据犹如一座巨大的金矿,等待我们去发掘。而机器学习和数据挖掘的相关技术,无疑就是...作为一个范例,今天将演示在Python 中利用Scikit-Learn所提供的函数来实现基于Logistic Regression分类机器学习技术
  • 简介:课程以目前流行的两个框架scikit-learn 以及大名鼎鼎的Tensorflow作为作为实战工具,让学员系统完整掌握机器学习和深度学习这两个在目前人工只能炙手可热的技能,让人生事业更上一个台阶。 本课程以基础原理+...
  • 问题来自慕课斯坦福机器学习课程 更多内容访问omegaxyz.com问题·输入数据只有一维:房子的面积 ·目标的数据只有一维:房子的价格 根据已知房子的面积和价格进行机器学习和模型预测 数据见文章末尾 数据需要...
  • 点击打开链接
  • python机器学习库sklearn——朴素贝叶斯分类器

    万次阅读 多人点赞 2018-01-04 08:52:24
    python数据挖掘系列教程 文档贝叶斯分类器的相关的知识内容可以参考 http://blog.csdn.net/luanpeng825485697/article/details/78769233 在scikit-learn中,一共有3个朴素贝叶斯的分类算法类。分别是GaussianNB...
  • python机器学习框架

    千次阅读 2018-08-29 14:32:07
    转载奶爸码农,非常感谢大神分享。原文 随着2016年Alpha Go在围棋击败李世石,2017年初卡内基梅隆大学人工智能系统Libratus在长达20天的鏖战中,打败4名世界顶级德州扑克玩家,这标志着人工智能技术又达到了一个新...
  • python 机器学习类库

    千次阅读 2013-08-13 15:40:18
    链接地址: 点击打开链接 有空的时候再学习
  • Python机器学习算法》的写作历程

    万次阅读 多人点赞 2016-09-28 14:30:59
    一开始写博客,给自己的文章建了一个响亮的标题《简单易学的机器学习算法》,但是发现写着写着,每一个算法也变得没那么简单易学,因此想对这些零散的知识点做一次全面的整理。最初是一年前有了这个念头,一直没有去...
  • Python机器学习预测算法

    千次阅读 2019-07-16 16:45:09
    a bytes-like object is required, not 'str'Python机器学习核心预测算法第2章 通过理解数据来了解问题2.1 解剖一个新问题2.1.1 属性和标签的不同类型决定模型的选择2.1.2 新数据集的注意事项2.2 分类问题:用声呐...
  • python机器学习TensorFlow框架

    千次阅读 2018-08-07 22:02:42
    ​ TensorFlow是谷歌基于DistBelief进行研发的第二代人工智能学习系统,其命名来源于本身的运行原理。 ​ Tensor(张量)意味着N维数组,Flow(流)意味着基于数据流图的计算,TensorFlow为张量从流图的一端流动到...

空空如也

1 2 3 4 5 ... 20
收藏数 46,939
精华内容 18,775
关键字:

python机器学习

python 订阅