标签: 机器学习 python 线性模型 逻辑回归 线性判别分析
2017年08月12日 09:55:49776人阅读 评论(0) 收藏 举报
 分类:
机器学习(4) 

版权声明:如果你觉得写得还可以的话,转载请联系我一下。 http://blog.csdn.net/u011974639/article/details/77102663

目录(?)[+]

  • 引言

    • 先验条件
    • 好了下面开始正文本节的主角是线性模型
  • 线性模型理论
    • 概述
    • 线性回归
      • 什么是回归
      • 什么是线性回归
      • 如何确定参数w和b
      • 如何求解w和b
      • 线性回归小结
    • 广义线性模型
      • 概述
    • 逻辑回归
      • 怎么用线性模型做分类
      • 什么样的函数满足分类要求
      • 怎么计算逻辑回归模型的参数估计
        • 极大似然估计

          • 从感性上认识
          • 数学表示
      • 多分类回归模型该怎么办
      • 逻辑回归总结
    • 线性判别分析
      • 什么线性判别分析
      • 怎样找到线性判别分析的优化目标
      • 怎样计算LDA模型中参数
      • 怎样在多分类任务中使用LDA
      • 线性判别分析小结
  • Python实战线性模型
    • 使用模块与数据集介绍

      • 使用的模块
      • 数据集
        • 数据归一化的作用
    • 线性回归模型
      • 线性回归

        • LinearRegression类介绍
        • 本节程序小结
        • 输出
    • 带正则化的线性回归模型
      • 概述
      • 岭回归
        • Ridge类介绍
        • 本节程序小结
        • 输出
      • Lasso回归
        • Lasso类介绍
        • 本节程序小结
        • 输出
      • ElasticNet回归
        • ElasticNet类介绍
        • 本节程序小结
        • 输出
    • 逻辑回归模型
      • LogisticRegression回归

        • LogisticRegression类介绍
        • 本节程序小结
        • 输出
    • 线性判别分析
      • LinearDiscriminantAnalysis

        • LinearDiscriminantAnalysis类介绍
        • 本节程序小结
  • 参考资料
 
hello world!
 

引言

前段时间一直在看深度学习和TensorFlow的教程,在学习的过程中,深感自己的数学基础较差,尤其是在对数据做预处理等操作时,看着书上那一堆公式,整个人都是懵逼的。看着桌上三本机器学习相关的书:西瓜书《机器学习》、《Python大战机器学习》、《机器学习实战》,思索再三,我决定接下来三个月时间努力啃完它们,顺带写blog,算是一边记笔记一边督促自己坚持下去。

先验条件

在啃这三本书之前,我已经看了一段时间的Andrew Ng在Coursera上的机器学习视频,也看了一点台大的《机器学习基石》.也建议大家先看这些视频,了解一下机器学习中的基本概念.

好了,下面开始正文,本节的主角是线性模型.




线性模型理论

概述

概述

相信看过Andrew Ng在Coursera上关于机器学习的教程的同学都知道(没看过也没关系),该教程讲的第一个模型就是线性模型(预测房价)。这里我们也以房价预测做例子。打个比方:我们现在要预测某地方的房价price,我们已有的信息是住房的面积size和离市区中心的距离s,我们可以列出一个定性的关系式(关系式根据是生活经验,当然这只是一个假设式):

预测房价:price=α∗size+β∗s.(其中α和β为预测模型的参数)预测房价:price=α∗size+β∗s.(其中α和β为预测模型的参数)

上式是基于size和s对于房价的预测,在实际问题中,我们可能多种数据,例如本地房产均价、周围教育设施、体育馆、住房楼层、住房受光面积等,这些因素都会影响房价。

现在,我们拓展一下,如果我们给定了d个属性(size和s就是两种属性)描述的样本如下:

x=(x1;x2;...;xd);其中xi是x在第i个属性上的取值x=(x1;x2;...;xd);其中xi是x在第i个属性上的取值

线性模型试图学习到一个通过属性的线性组合来进行预测的函数,即

f(x)=ω1x1+ω2x2+...+ωdxd+b;(b为偏置单元)f(x)=ω1x1+ω2x2+...+ωdxd+b;(b为偏置单元)

我们可以用向量形式表示

f(x)=ωTx+b;f(x)=ωTx+b;
其中ω=(ω1;ω2;...;ωd),ω和b是学习得到的,确定后模型就确定了其中ω=(ω1;ω2;...;ωd),ω和b是学习得到的,确定后模型就确定了

上面的式子就是线性模型的一般表达式了,可以看到线性模型的形式很简洁,而且易于建模。线性模型蕴含着机器学习中一些重要的基本思想.许多功能更为强大的非线性模型可在线性模型的基础上通过引入层次结构或高维映射而得。线性模型还有多种推广形式,常见的有广义线性模型:逻辑回归、岭回归等。接下来我们将介绍多种线性回归的基本思想、优缺点以及如何使用Python实现。


线性回归

线性回归

1. 什么是回归?

回归分析本质上是一个函数估计问题,通俗的来说,就是找出因变量和自变量之间的因果关系。回归分析的因变量应该是连续变量(房价是连续的,或者预测某些病症发病的概率值);若因变量为离散变量(预测图片分类等),则问题就是分类问题,回归分析是一个有监督学习问题。

 

2.什么是线性回归?

线性回归(linear regression)是一种回归分析技术,例如在给定数据集DD。线性回归试图学习到一个线性模型以尽可能准确地预测实值输出标记。通过在数据集上建立线性模型,建立代价函数(loss function),最终以优化代价函数为目标确定模型参数w和bw和b,从而得到模型用以后续的预测。整个线性回归算法流程如下:

 

3.如何确定参数w和b?

根据已知的数据集D

D=((x1,y1);(x2,y2);...;(xm,ym))其中xi=(xi1;xi2;...;xid),yi∈RD=((x1,y1);(x2,y2);...;(xm,ym))其中xi=(xi1;xi2;...;xid),yi∈R
(xi为对于的属性数据,yi为对于的标签值)(xi为对于的属性数据,yi为对于的标签值)

来计算参数w和b,对于给定的样本数据xixi其预测值为yi~=wxi+byi~=wxi+b,这时候我们需要一个可以衡量预测值与数据集真实值之间差距的函数,我们称之为代价函数,可想而知如果代价函数在整个数据集上的值越小,就代表的预测值与真实值越接近,而这就是我们想要的,所以我们的优化目标就是让代价函数的值最小。

这里代价函数我们选用均方误差(square loss),即在样本xixi上预测值为yi~yi~,故均方误差为(yi~−yi)2(yi~−yi)2,则在整个数据集D上,模型的代价函数为L(f) = \sum_{i=1}^D(\tilde{y_i}-y_i)^2=\sum_{i=1}^D(\boldsymbol{w}x_i+b-y_i)^2

L(f)=∑i=1D(yi~−yi)2=∑i=1D(wxi+b−yi)2L(f)=∑i=1D(yi~−yi)2=∑i=1D(wxi+b−yi)2

我们的要确定的参数为:

(w∗,b∗)=argminw,b(∑i=1D(wxi+b−yi)2)(w∗,b∗)=argminw,b(∑i=1D(wxi+b−yi)2)

这样的基于均方误差最小化来进行模型求解的方法称为“最小二乘法”(least square method,LSM)。有趣的是当年数学王子高斯在推测行星运动时用的就是这个最小二乘法。

到此,我们的优化目标已经确定了,接下来就是求解问题了。

 

4.如何求解w和b?

求解ww 和bb使L(f)L(f)最小化的的过程,称为线性回归模型的最小二乘“参数估计”(parameter estimation).由凸优化知识可知,L(w,b)L(w,b)是关于ww 和bb的凸函数(证明略过),在数学上我们可知,在凸函数上当函数在导数为0处取极值,同时极值就是函数的最值。故当L(w,b)L(w,b)关于ww 和bb的导数均为零时,得到ww 和bb的最优解。

我们考虑更为一般的情况,在数据集D上,样本由d个属性描述,此时线性回归又称为“多元线性回归”。为了便于讨论,我们把w和b统一记为w^=(w;b)w和b统一记为w^=(w;b)与之对应的,数据集D表示为一个m⋅(d+1)m⋅(d+1)大小的矩阵X,表示为

X=⎛⎝⎜⎜⎜⎜⎜xT1xT2⋮xTm11⋮1⎞⎠⎟⎟⎟⎟⎟,y=(y1,y2,...,ym)X=(x1T1x2T1⋮⋮xmT1),y=(y1,y2,...,ym)

可以得到新的优化目标表达式为:

w^∗=argminw(y−Xw^)T(y−Xw^)w^∗=argminw(y−Xw^)T(y−Xw^)

新的代价函数为

Lw^=(y−Xw^)T(y−Xw^)Lw^=(y−Xw^)T(y−Xw^)

我们可以对Lw^关于w^Lw^关于w^求导,得到

∂Lw^∂w^=2XT(Xw^−y)∂Lw^∂w^=2XT(Xw^−y)

令上式为零,可以得到w^w^ 的最优闭式解,此时需要分类讨论:

  • 如果XTXXTX为满秩矩阵或正定矩阵时,可得: 
    \hat{\boldsymbol{w}}^*=(\boldsymbol{X^TX})^{-1}\boldsymbol{X^Ty}

    w^∗=(XTX)−1XTyw^∗=(XTX)−1XTy

    线性回归模型为: 
    f(\hat{x_i})=\hat{x_i}^T\hat{\boldsymbol{w}}^*=\hat{x_i}^T(\boldsymbol{X^TX})^{-1}\boldsymbol{X^Ty}

    f(xi^)=xi^Tw^∗=xi^T(XTX)−1XTyf(xi^)=xi^Tw^∗=xi^T(XTX)−1XTy
  • 如果XTXXTX不是满秩矩阵时(样本数量小于属性数量),XX的行数大于列数,必然不满秩,存在多个解析解,它们都能使得损失函数最小化,选择哪一个解析解作为输出,由学习算法的归纳偏好决定,这时候常常引入正则化(regularization)项.常见的正则化项如L1正则化或L2正则化,我们以L2正则化为例L1正则化或L2正则化,我们以L2正则化为例: 
    \hat{\boldsymbol{w}}^*=arg\min_{\boldsymbol{w}}[(\boldsymbol{y-X\hat{w}})^T(\boldsymbol{y-X\hat{w}})+\lambda||\boldsymbol{\hat{w}}_2^2||];( \lambda>0为正则比例 )

    w^∗=argminw[(y−Xw^)T(y−Xw^)+λ||w^22||];(λ>0为正则比例)w^∗=argminw[(y−Xw^)T(y−Xw^)+λ||w^22||];(λ>0为正则比例)

    则线性回归模型为: 
    f(\hat{x_i})=\hat{x_i}^T\hat{\boldsymbol{w}}^*=arg\min_{\boldsymbol{w}}[(\boldsymbol{y-X\hat{w}})^T(\boldsymbol{y-X\hat{w}})+\lambda||\boldsymbol{\hat{w}}_2^2||]

    f(xi^)=xi^Tw^∗=argminw[(y−Xw^)T(y−Xw^)+λ||w^22||]f(xi^)=xi^Tw^∗=argminw[(y−Xw^)T(y−Xw^)+λ||w^22||]
 

5.线性回归小结


广义线性模型

广义线性模型

概述

线性模型虽然简单,却有丰富的变化.当我们希望线性模型的预测值逼近真实标记值yy时,就得到了线性回归模型.为了便于观察,我们简写线性回归模型为y=wTx+by=wTx+b ,此时我们可以让线性回归模型去逼近yy的其他目标,例如lnylny. 
照着这个想法,我们可以更一般地,考虑单调可导函数h(⋅),令h(y)=wTx+bh(·),令h(y)=wTx+b,这样wTx+bwTx+b可以逼近一个h(⋅)h(·),如果我们选好的h(⋅)h(·)就可以使用线性模型去逼近不同的函数了,我们称这样的模型为广义线性模型(generalized linear model). 上述表达式可以记为:

y=h−1(wTx+b)y=h−1(wTx+b)

有一个典型的例子,当h(⋅)=ln(⋅)h(·)=ln(·) 时广义线性模型就是对数线性回归,即

y=e(wTx+b)y=e(wTx+b)

可以看到,虽然是叫广义线性模型,其实大部分时候变换函数h−1h−1都是非线性变换,即实质上已经是非线性的。



逻辑回归

逻辑回归

1.怎么用线性模型做分类?

在一开始我们说到,回归分析本质上是一个函数估计问题,就是找出因变量和自变量之间的因果关系。如果因变量是连续值那就叫回归,如果因变量是离散值那就叫分类。前面说的都是使用线性模型进行回归学习,下面我们就说说怎么用线性模型做分类。

其实用线性模型做分类的办法已经在上一节介绍,就是广义线性模型,考虑到在广义线性模型中,如果我们找到一个单调可微函数h(⋅)h(·)可以将分类任务和线性回归联系到一起,那就可以用线性模型完成分类任务了。

 

2.什么样的函数满足分类要求?

这里,我们先简化分类任务,考虑二分类问题,即预测值为y=0或y=1y=0或y=1,考虑到z=wTx+b的取值z为(−∞,+∞)z=wTx+b的取值z为(−∞,+∞),如果我们有这样一个理想函数(信号分析里面的阶跃函数):

当z<0取值为0时即取负例,z>0时取值为1时即取正例z<0取值为0时即取负例,z>0时取值为1时即取正例,可以看到,这样的函数能够很好的解决分类问题。这样的函数能作为广义线性模型里面的h(⋅)h(·)吗?答案是不能。这是因为这样的函数有一个问题:函数不连续故不可导。那我们能不能找到一个类似这样的函数,并且连续可导?答案当然是有的:例如对数概率函数(logistic function),下图为对数概率函数的示意图:

由图可以看出对数概率函数将自变量zz转化为一个接近0或者1的yy值,且输出值在z=0z=0处变化剧烈,重要的是对数概率函数满足连续可微的条件,故我们可将对数概率函数和广义线性模型结合到一起:

y=11+e−z,z=wTx+by=11+e−z,z=wTx+b

看到这里,或许你和我有一样的问题,为什么我们非要选用这样的一个函数,难道就是因为它连续可微和阶跃函数很像就足够了吗? 那么下面这些函数也有类似的性质: 

为啥不选它们,这个其实是考虑到对数概率函数的导函数,我们看一下它的导函数形式:

dydz=e−z(1+e−z)2=ye−z1+e−z=y(1−y)dydz=e−z(1+e−z)2=ye−z1+e−z=y(1−y)

对数概率函数的导函数可以直接通过原函数很方便的计算出来,我们做参数估计时是需要作求导操作的,函数有这样的特性是非常方便的。也就是它在众多函数中脱颖而出的原因之一


我们将上面的线性模型称为逻辑回归,为啥叫逻辑回归。这是因为有

lny1−y=wT+blny1−y=wT+b

如果我们将yy的输出值认为是P(y=1|x)P(y=1|x),那么1−y就是P(y=0|x)1−y就是P(y=0|x),而y1−y=P(y=1|x)P(y=0|x)y1−y=P(y=1|x)P(y=0|x)称为概率(又称几率,odds),概率反映了xx作为正例的相对可能性,对概率取对数则到了“对数概率”,所以这个函数又叫对数概率函数(logistic function),而对应的模型称为“逻辑回归”(logistic regression)。虽然叫做逻辑回归,实际上却是一种分类学习方法,这种方法有许多优点,例如对数概率函数的任意阶可导的凸函数,这有这很多很好的数学性质,有许多数值优化算法都可以直接应用求解。

 

3.怎么计算逻辑回归模型的参数估计?

确定好逻辑回归的模型后,下面该计算模型中的参数w和bw和b,这里我们依旧是把w和b统一记为w^=(w;b)w和b统一记为w^=(w;b),此时有 
P(y=1|\boldsymbol{x})=\frac{e^{\hat{\boldsymbol{w}}^Tx}}{1+e^{\hat{\boldsymbol{w}}^Tx}}

P(y=1|x)=ew^Tx1+ew^TxP(y=1|x)=ew^Tx1+ew^Tx

P(y=0|\boldsymbol{x})=\frac{1}{1+e^{\hat{\boldsymbol{w}}^Tx}}

P(y=0|x)=11+ew^TxP(y=0|x)=11+ew^Tx

我们可以通过极大似然法来估计w^w^,学过数理统计的同志们应该对极大似然估计法不陌生,我当年是背着公式勉强没挂科,没怎么理解这到底是干啥的,现在用到了,就好好的回顾一下极大似然法。


极大似然估计

事实上,我们认为概率模型的训练过程就是参数估计过程。对于参数估计,统计学界有两个学派提供不同的解决方法:

  • 频率主义学派(Frequentist):认为参数虽然未知,但却是客观存在的固定值,因此,可以通过优化似然函数等准则来确定参数值
  • 贝叶斯学派(Bayesian):认为参数是未观察到的随机变量,其本身也可有分布,因此,可假设参数服从一个先验分布,然后基于观测到的数据来计算参数的后验分布.

极大似然估计(Maximum Likelihood Estimation,MLE)是源于频率主义学派的根据数据采样来估计概率分布参数的经典方法。

从感性上认识

我们尽量的感性的去理解极大似然估计,假设我们现在已经拿到了很多样本(即因变量),极大似然估计就是去找未知的参数估计值,使得样本发生的概率最大(因为我已经有了很多样本,所有我认为能使得样本发生概率最大的参数才是合逻辑的)。这个时候是在求样本所有观测的联合概率最大化,而这样的计算时一个连乘,我们可以通过取对数,变换为连加。然后在通过对未知参数求导,令导数为零,就得到了最大似然估计值。

数学表示

讲完了感性的认识,下面我们看一下怎样用数学表示: 
令DcDc表示训练集D中第c类样本组成的集合,假设这样的样本是独立同分布的,参数θc对于数据集Dc的似然是θc对于数据集Dc的似然是

P(Dc|θc)=∏x∈DcP(x|θc)P(Dc|θc)=∏x∈DcP(x|θc)

对θcθc进行极大似然估计,就是去寻找能最大化似然P(Dc|θc)的参数值θ^cP(Dc|θc)的参数值θ^c,直观上看,极大似然估计是试图在θcθc所有可能的取值中,找到一个能使数据出现的“可能性”最大的值。 而这个找最大值的我们常用的方法就是求导。 
上式的连成不易计算,且容易造成下溢,通常使用对数似然将连乘转换为连加,这不改变数据极值点。

L(θc)=logP(Dc|θc)=∏x∈DclogP(x|θc)L(θc)=logP(Dc|θc)=∏x∈DclogP(x|θc)

此时参数θc的极大似然估计θc^为θc的极大似然估计θc^为:

θc^=argθcmaxL(θc)θc^=argθcmaxL(θc)

一般到这步就是对参数求偏导取零求参数值了。

需要注意这种参数化的方法虽能使类条件概率估计变得相对简单,单估计结果的准确性严重依赖于所假设的概率分布形式是否符合潜在的真实数据分布,在应用时想要做出能较好地接近潜在真实分布的假设,需要在一定程度上利用关于应用任务本身的经验知识。


回顾了下极大似然估计,现在我们继续计算w^w^,上面我们说了可以通过极大似然法来估计w^w^,在给定数据集{(xi,yi)}mi=1{(xi,yi)}i=1m,逻辑回归模型的对数似然函数为:

L(w^)=ln(∏i=1m[p(y=1|x)]yi[p(y=0|x)]1−yi)=∑i=1m[yip(y=1|x)+(1−yi)p(y=0|x)]L(w^)=ln(∏i=1m[p(y=1|x)]yi[p(y=0|x)]1−yi)=∑i=1m[yip(y=1|x)+(1−yi)p(y=0|x)]

因为有

P(y=1|x)=ew^Tx1+ew^TxP(y=1|x)=ew^Tx1+ew^Tx
P(y=0|x)=11+ew^TxP(y=0|x)=11+ew^Tx

故带入可得

L(w^)=∑i=1m(−yiw^Txi+ln(1+ew^Txi))L(w^)=∑i=1m(−yiw^Txi+ln(1+ew^Txi))

上式是关于w^w^的高阶可导连续凸函数,可用梯度下降法或者拟牛顿法求解。

 

4.多分类回归模型该怎么办?

以上的讨论都是二分类的逻辑回归模型,我们可以顺势推广到多分类逻辑回归模型,这里考虑到一对多等可能,我们可以设因变量Y的离散值取值集合为{1,2,…,K},则多分类逻辑回归模型为:

P(Y=k|x)=ewk^Tx1+∑K−1k=1ewk^Tx;k=1,2,...,K−1P(Y=k|x)=ewk^Tx1+∑k=1K−1ewk^Tx;k=1,2,...,K−1
P(Y=K|x)=11+∑K−1k=1ew^TxP(Y=K|x)=11+∑k=1K−1ew^Tx

参数估计方法类似二分类逻辑回归模型的参数估计的方法

 

5.逻辑回归总结



线性判别分析

线性判别分析

1.什么线性判别分析?

线性判别分析(Linear Discriminant Analysis,LDA)是一种经典的线性学习方法,思想是:

  • 训练时:设法将训练样本投影到一条直线上,使得同类样本的投影点尽可能地接近、异类的样本投影点尽可能的远
  • 预测时:将待预测样本投影到学到的直线上,根据它的投影点的位置判断类别

两类样本的线性判别分析示意图如下: 
(图中直线方程y=wTx省略了参数by=wTx省略了参数b,是因为我们计算的是样本在直线上的投影,而我们总可以平移直线过原点且保持投影不变,故可以省略b。)

这里你可能会想,为什么非要投影搞来搞去的这么麻烦,为啥不是在两类样本中找到一条直线分开两类样本就好,对啊,我也是这么想的,这样的方法就是支持向量机(support vector machine,SVM)的思想。这里我们先不介绍SVM,继续探讨LDA.

 

2.怎样找到线性判别分析的优化目标?

给定数据集D={(xi,yi)}mi=1,yi∈{0,1},令Xi、μi、∑iD={(xi,yi)}i=1m,yi∈{0,1},令Xi、μi、∑i分别表示第i∈{0,1}i∈{0,1}类样本的集合、均值向量、协方差矩阵.若将数据投影到直线上,则:

  • 两类样本的中心在直线上的投影分别是wTμ0和wTμ1wTμ0和wTμ1
  • 两类样本的协方差(多变量的方差)分别为wT∑0w和wT∑1wwT∑0w和wT∑1w

我的优化目标:

  • 同类样本投影点尽可能的近,故wT∑0w+wT∑1wwT∑0w+wT∑1w尽可能的小
  • 异类样本投影点尽可能的远,故是||wTμ0−wTμ1||22||wTμ0−wTμ1||22尽可能的大

故联合起来,我们的优化目标为: 
J=\frac{{||w^T\mu_0-w^T\mu_1||_2^2}}{w^T\sum_0w+w^T\sum_1w}=\frac{w^T(\mu_0-\mu_1)(\mu_0-\mu_1)^Tw}{w^T(\sum_0+\sum_1)w}

J=||wTμ0−wTμ1||22wT∑0w+wT∑1w=wT(μ0−μ1)(μ0−μ1)TwwT(∑0+∑1)wJ=||wTμ0−wTμ1||22wT∑0w+wT∑1w=wT(μ0−μ1)(μ0−μ1)TwwT(∑0+∑1)w

这里我们定义类内散度矩阵(within-class scatter matrix):

Sw=∑0+∑1=∑x∈X0(x−μ0)(x−μ0)T+∑x∈X1(x−μ1)(x−μ1)TSw=∑0+∑1=∑x∈X0(x−μ0)(x−μ0)T+∑x∈X1(x−μ1)(x−μ1)T

定义类间散度矩阵(between-class scatter matrix):

Sb=(μ0−μ1)(μ0−μ1)TSb=(μ0−μ1)(μ0−μ1)T

带入优化目标,我们可得到LDA最终的优化目标:

J=wTSbwwTSwwJ=wTSbwwTSww
 

3.怎样计算LDA模型中参数?

由上面的优化目标确定ww的求解问题为:

w^=argmaxw^wTSbwwTSwww^=argmaxw^wTSbwwTSww

注意观察上式,无论是分母还是分子,都是wT_wwT_w的结构,这说明了分子分母都是关于ww的二次项,故对w^w^的求解与ww的长度无关。只与其方向有关。既然与长度无关,我们就简化计算,令wTSww=1wTSww=1,则新的优化目标写为:

w^=argmaxw^wTSbw=arg−minw^wTSbww^=argmaxw^wTSbw=arg−minw^wTSbw
s.t.wTSww=1s.t.wTSww=1

可以看到优化目标与限制条件之间的关系,很自然的想到了拉格朗日乘子法(看过SVM的证明很容易想到,想不到拉倒),由拉格朗日乘子法,得:

−wTSbw+λwTSww=0−wTSbw+λwTSww=0
化简为:Sbw=λSww;λ是拉格朗日乘子化简为:Sbw=λSww;λ是拉格朗日乘子

注意到

∵类间散度矩阵定义为:Sb=(μ0−μ1)(μ0−μ1)T,这是向量(μ0−μ1)与自身的外积∵类间散度矩阵定义为:Sb=(μ0−μ1)(μ0−μ1)T,这是向量(μ0−μ1)与自身的外积
∵Sbw=(μ0−μ1)(μ0−μ1)Tw∵Sbw=(μ0−μ1)(μ0−μ1)Tw
令λw=(μ0−μ1)Tw令λw=(μ0−μ1)Tw
那么Sbw=λw(μ0−μ1)=λSww,因为与w的长度无关,我们可令λw=λ,则有那么Sbw=λw(μ0−μ1)=λSww,因为与w的长度无关,我们可令λw=λ,则有
Sww=(μ0−μ1)⇒w=S−1w(μ0−μ1)Sww=(μ0−μ1)⇒w=Sw−1(μ0−μ1)

上述讨论的就是w^w^的求解,考虑到数值解的稳定性,在实践中通常是对SwSw进行奇异值分解(数据量大时候).

 

4.怎样在多分类任务中使用LDA?

我们可以将LDA推广到多分类任务中,假定存在M个类,属于第i个类的样本集合为TiTi,则样本的样例集合为i=1,2,...,Mi=1,2,...,M; TiTi中的样例个数为mimi,则有∑Mi=1mi=N,N∑i=1Mmi=N,N为样本总数,我们可以得到样例的均值向量为:

μi=(μ(1)i,μ(2)i,...,μ(n)i)T=1mi∑xi∈Tixi=1N∑x=1Nxiμi=(μi(1),μi(2),...,μi(n))T=1mi∑xi∈Tixi=1N∑x=1Nxi

这些样例的特征之间协方差矩阵为∑i∑i.

  • 要使得同类样例的投影点尽可能的近,主要到所有类内散度矩阵SwSw定义为每个类别的散度矩阵之和,故

    Sw=∑i=1MSwi;其中Swi=∑x∈Ti(xi−μi)(xi−μi)TSw=∑i=1MSwi;其中Swi=∑x∈Ti(xi−μi)(xi−μi)T
  • 要使得异类间的投影距离尽可能的远,则可以使异类样例的中心点投影距离尽可能的远,这里有多个中心点。这里用每一类样例的中心点和总样例中心点的距离作为度量,考虑到每一类样例的样本集大小可能不同,故我们队这个距离作加权处理,因此定义类间散度矩阵为:

    Sb=∑i=1Mmi(μi−μ)(μi−μ)TSb=∑i=1Mmi(μi−μ)(μi−μ)T

    (μi−μ)(μi−μ)T(μi−μ)(μi−μ)T也是一个协方差矩阵,刻画的是第i类与总体之间的关系。

我们的优化目标为:

J=maxWtr(WTSbW)tr(WTSwW)J=maxWtr(WTSbW)tr(WTSwW)

WW的闭式解是S−1wSb的d′个最大非零广义特征值所对应的特征向量组成的矩阵,d′≤M−1Sw−1Sb的d′个最大非零广义特征值所对应的特征向量组成的矩阵,d′≤M−1

若将WW视为一个投影矩阵,则多分类LDA将样本投影到一个d′d′维空间,而d′常小于数据原有的属性数Md′常小于数据原有的属性数M,于是,可以通过这个投影来减少样本点的维数,且投影过程中使用了训练样本的类别信息,故这是一个经典的监督降维技术.

 

线性判别分析小结




Python实战线性模型

说完了理论部分,接下来就是Python代码实现了

使用模块与数据集介绍

使用模块与数据集介绍

1.使用的模块

导入线性模型需要用到的模块

    import numpy as np   import matplotlib.pyplot as pltfrom sklearn import datasets, linear_model,cross_validation
  • 1
  • 2
  • 3

上述用到的numpy和matplotlib都是老相识了,最近也在系统的学习numpy模块. 
sklearn是机器学习的常用的工具包,sklearn包含了大部分常见的机器学习模型,且还有一些自带的数据集。 
上述的开发包如果一个一个安装还是比较麻烦的,建议直接安装一个Python的发行版,我安装是Anaconda,配合的是Pycharm IDE,感觉还是很方便的。

下图是我的开发环境: 

 

2.数据集

在线性回归问题中,使用的数据集是scikit-learn自带的一个糖尿病人的数据集,该数据集特点如下:

  • 数据集有442个样本
  • 每个样本有10个特征
  • 每个特征都是浮点数,数据都在-0.2~0.2之间
  • 样本的目标在整数25~346之间

给出加载数据集的函数:

def load_data():'''加载用于回归问题的数据集:return: 一个元组,用于回归问题。元组元素依次为:训练样本集、测试样本集、训练样本集对应的值、测试样本集对应的值'''diabetes = datasets.load_diabetes()#使用 scikit-learn 自带的一个糖尿病病人的数据集return cross_validation.train_test_split(diabetes.data,diabetes.target,test_size=0.25,random_state=0) # 拆分成训练集和测试集,测试集大小为原始数据集大小的 1/4
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

数据归一化的作用

数据集上有一点值得我们注意:数据都在-0.2~0.2之间,这是原数据集帮我们做了特征归一化工作,在机器学习中,我们常使用梯度下降法求解最优化问题,在使用梯度下降法时,要注意特征归一化(Feature Scaling).特征归一化有两个明显的好处:

  • 1.提升模型的收敛速度,例如模型只有两个特征x1和x2,x1x1和x2,x1的取值为0~2000,而x2x2的取值为1~5,如果对其优化,会得到一个窄长的椭圆形,导致在梯度下降时,梯度的方向在垂直等高线的方向而走之字形路线,这样迭代速度很降低。如果归一化,会使一个椭圆,梯度的方向为直接指向圆心,迭代速度就会很快。
  • 2.提升模型的精度,这在涉及一些距离计算的算法时效果显著,比如算法要计算欧式距离,上面的x2x2的取值范围较小,计算时对结果的影响远比x1x1带来的小,可能会造成精度的损失.

在逻辑回归问题中,使用的数据集是鸢尾花数据集,该数据集特点如下:

  • 数据集有150个
  • 数据分为3类(分别为setora、versicolor、virginica)
  • 每类有50个数据
  • 每个数据包含4个属性:萼片(sepal)长度、萼片宽度、花瓣(petal)长度、花瓣宽度

给出加载数据集的函数:

    def load_data():'''加载用于分类问题的数据集:return: 一个元组,用于分类问题元组元素依次为:训练样本集、测试样本集、训练样本集对应的标记、测试样本集对应的标记'''iris=datasets.load_iris() # 使用 scikit-learn 自带的 iris 数据集X_train=iris.datay_train=iris.targetreturn cross_validation.train_test_split(X_train, y_train,test_size=0.25,random_state=0,stratify=y_train)# stratify=y_train指定分层采样,拆分成训练集和测试集,测试集大小为原始数据集大小的 1/4
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

这里有一点要注意的是,原数据中,前50个数据都是类别0,中间50是类别1,后50数据是类别2。如果我们按顺序切分采样,那么切分的测试数据就不是无偏的了(都是类型2了),故我们指定了stratify=y_train,采取分层采样.

线性回归模型

线性回归模型

1.线性回归

linear_model是sklearn包下提供的一个有关于线性模型的工具包。本次使用的是linear_model下提供了LinearRegression线性回归模型

LinearRegression类介绍

  • LinearRegression类原型为:

     class LinearRegression(LinearModel, RegressorMixin): '''Ordinary least squares Linear Regression.'''
    • 1
    • 2
  • 父类

    LinearModel:'''Linear Models的基类'''方法:predict(self, X):Predict class labels for samples in XRegressorMixin:'''Mixin class for all regression estimators in scikit-learn'''方法:score(self, X, y, sample_weight=None)'''返回预测性能得分。'''
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    这里要讲一下score函数的原理,设预测集TtestTtest,真实值为yiyi,真实值的均值为y¯y¯ ,预测值为yi^yi^,则:

    socre=1−∑Ttest(yi−yi^)2(yi−y¯)2socre=1−∑Ttest(yi−yi^)2(yi−y¯)2
    • score不超过1,可能为负值(预测效果太差)
    • score越大,预测性能越好
  • 参数

    def __init__(self, fit_intercept=True, normalize=False, copy_X=True,n_jobs=1):----------fit_intercept : boolean, optional是否计算b值,为false不计算normalize : boolean, optional, default False为True,训练样本在使用前会被归一化,This parameter is ignored when `fit_intercept` is set to False.When the regressors are normalized, note that this makes thehyperparameters learnt more robust and almost independent of the numberof samples. copy_X : boolean, optional, default TrueIf True, 会复制Xn_jobs : int, optional, default 1使用任务并行时指定的CPU数量If -1 all CPUs are used.
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
  • 属性

            ----------coef_ : array, shape (n_features, ) or (n_targets, n_features)权重系数intercept_ : arrayb值    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
  • 方法

            fit(self, X, y, sample_weight=None) : 训练模型predict(self, X):  :用模型进行预测 (从父类继承)score(self, X, y, sample_weight=None)  :返回预测性能得分。(从父类继承)
    • 1
    • 2
    • 3
    • 4
    • 5
  • 使用LinearRegression的示例函数如下

    def test_LinearRegression(*data):'''测试 LinearRegression 的用法param:*data: 可变参数。它是一个元组要求其元素依次为:训练样本集、测试样本集、训练样本的值、测试样本的值:return: None'''X_train,X_test,y_train,y_test=dataregr = linear_model.LinearRegression()regr.fit(X_train, y_train)print('Coefficients:%s, intercept %.2f'%(regr.coef_,regr.intercept_))# 求方差:  先求残差平方和  在使用np.mean为求均值 print("Residual sum of squares: %.2f"% np.mean((regr.predict(X_test) - y_test) ** 2))# 预测分数print('Score: %.2f' % regr.score(X_test, y_test))
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

本节程序小结:

    # -*- coding: utf-8 -*-"""广义线性模型~~~~~~~~~~~~~~~~~~~~~~~~~~LinearRegression"""import matplotlib.pyplot as pltimport numpy as npfrom sklearn import datasets, linear_model,cross_validationdef load_data():'''加载用于回归问题的数据集'''diabetes = datasets.load_diabetes()#使用 scikit-learn 自带的一个糖尿病病人的数据集return cross_validation.train_test_split(diabetes.data,diabetes.target,test_size=0.25,random_state=0) # 拆分成训练集和测试集,测试集大小为原始数据集大小的 1/4def test_LinearRegression(*data):'''测试 LinearRegression 的用法:return: None'''X_train,X_test,y_train,y_test=dataregr = linear_model.LinearRegression()regr.fit(X_train, y_train)print('Coefficients:%s, intercept %.2f'%(regr.coef_,regr.intercept_))print("Residual sum of squares: %.2f"% np.mean((regr.predict(X_test) - y_test) ** 2))print('Score: %.2f' % regr.score(X_test, y_test))if __name__=='__main__':X_train,X_test,y_train,y_test=load_data() # 产生用于回归问题的数据集test_LinearRegression(X_train,X_test,y_train,y_test) # 调用 test_LinearRegression
  • 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

输出:

   Coefficients:[ -43.26774487 -208.67053951  593.39797213  302.89814903 -560.27689824261.47657106   -8.83343952  135.93715156  703.22658427   28.34844354], intercept 153.07Residual sum of squares: 3180.20Score: 0.36
  • 1
  • 2
  • 3
  • 4

均方误差为3180.20,预测性能得分为0.36(效果不咋的)


带正则化的线性回归模型

带正则化的线性回归模型

1.概述

在前面的理论部分,我们讲到了对于线性回归问题,如果XTXXTX不是满秩矩阵时存在多个解析解,都能使得均方误差最小,在求解的过程中,常引入正则项来求解。正则项说白了就是对模型的参数添加一些先验假设,控制模型空间,达到使得模型复杂度较小的目的.根据不同的正则化项,有不同的方法:

  • 岭回归:Ridge Regression. 正则化项为α||w||22,α≥0α||w||22,α≥0,即加入L2范数惩罚项
  • Lasso回归: Lasso Regression. 正则化项为α||w||1,α≥0α||w||1,α≥0,即加入L1范数惩罚项
  • ElasticNet回归:Elastic Net.正则化项为αρ||w||1+α(1−ρ)2||w||22,α≥0,1≥ρ≥0αρ||w||1+α(1−ρ)2||w||22,α≥0,1≥ρ≥0,混合L1范数和L2范数惩罚项

正则化系数αα的选择很关键,一般在选择αα时,会先调节αα为0,确定好一个learning rate,在调节αα的值并观察validation accuracy,经过粗调到微调的过程确定好的αα.(下面使用的都是集成好的函数,没有涉及到learning rate的调整)

 

2.岭回归

Ridge Regression通过在代价函数中加入L2范数惩罚项,从而控制线性模型的复杂程度,使得模型更为robust.inear_model下提供了Ridge类实现岭回归模型。

Ridge类介绍

  • Ridge类原型为:

     class Ridge(_BaseRidge, RegressorMixin):  '''Linear least squares with l2 regularizationn.'''
    • 1
    • 2
  • 父类

        _BaseRidge:''' Ridge Models的基类'''            方法:fit(self, X, y, sample_weight=None):训练模型RegressorMixin:介绍见前面
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
  • 参数

    def __init__(self, alpha=1.0, fit_intercept=True, normalize=False,copy_X=True, max_iter=None, tol=1e-3, solver="auto",random_state=None):----------alpha : {float, array-like}, shape (n_targets)a值,越大代表正则化占比越大copy_X : boolean, optional, default TrueIf True, 会复制Xfit_intercept : boolean为False就不计算b(e.g. 模型会假设你的数据已经中心化了).max_iter : int, optional指定最大迭代次数,If None,则为默认值(不同的solver默认值不同)normalize : boolean, optional, default FalseIf True, 数据在使用前会归一化solver : {'auto', 'svd', 'cholesky', 'lsqr', 'sparse_cg', 'sag'}选择不同的求解最优化问题的算法.- 'auto' 依据数据集自动选择.- 'svd' 使用奇异值分解来计算回归系数.比'cholesky'稳定.- 'cholesky' 使用scipy.linalg.solve求解- 'sparse_cg' 使用scipy.sparse.linalg.cg求解.对于大型数据,比'cholesky'合适- 'lsqr' uses 使用scipy.sparse.linalg.lsqr求解,速度快但是可能不支持低版本(0.17以下)- 'sag' 使用 Stochastic Average Gradient descent求解。当n_samples and n_feature比较大时候,这个方法速度更快.tol : float指定判别迭代收敛的阈值.random_state : int seed, RandomState实例, or None (default),在slover=sag时使用- 如果为整数,指定了随机数生成器的种子- 如果为RandomState实例,指定了随机数生成器- 如果为None,使用默认的随机数生成器
    • 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
  • 属性

            ----------coef_ : array, shape (n_features, ) or (n_targets, n_features)权重系数intercept_ : arrayb值   n_iter_ : array or None, shape (n_targets,)实际的迭代次数   
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
  • 方法

            fit(self, X, y, sample_weight=None) : 训练模型predict(self, X):  :用模型进行预测 (从父类继承)score(self, X, y, sample_weight=None)  :返回预测性能得分。(从父类继承)
    • 1
    • 2
    • 3
    • 4
    • 5
  • 使用Ridge的函数如下(观察函数预测性能随着正则系数变化趋势)

def test_Ridge_alpha(*data):'''测试 Ridge 的预测性能随 alpha 参数的影响:param data: 可变参数。它是一个元组这里要求其元素依次为:训练样本集、测试样本集、训练样本的值、测试样本的值:return: None'''X_train,X_test,y_train,y_test=dataalphas=[0.01,0.02,0.05,0.1,0.2,0.5,1,2,5,10,20,50,100,200,500,1000]  #使用不同的正则系数scores=[]for i,alpha in enumerate(alphas):regr = linear_model.Ridge(alpha=alpha)regr.fit(X_train, y_train)scores.append(regr.score(X_test, y_test))## 绘图  fig=plt.figure()ax=fig.add_subplot(1,1,1)ax.plot(alphas,scores)ax.set_xlabel(r"$\alpha$")ax.set_ylabel(r"score")ax.set_xscale('log')ax.set_title("Ridge")plt.show()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

本节程序小结:

    # -*- coding: utf-8 -*-"""广义线性模型~~~~~~~~~~~~~~~~~~~~~~~~~~Ridge回归"""import matplotlib.pyplot as pltimport numpy as npfrom sklearn import datasets, linear_model,cross_validationdef load_data():'''加载用于回归问题的数据集'''diabetes = datasets.load_diabetes()return cross_validation.train_test_split(diabetes.data,diabetes.target,test_size=0.25,random_state=0) def test_Ridge_alpha(*data):'''测试 Ridge 的预测性能随 alpha 参数的影响:param data: 可变参数。它是一个元组这里要求其元素依次为:训练样本集、测试样本集、训练样本的值、测试样本的值:return: None'''X_train,X_test,y_train,y_test=dataalphas=[0.01,0.02,0.05,0.1,0.2,0.5,1,2,5,10,20,50,100,200,500,1000]scores=[]for i,alpha in enumerate(alphas):regr = linear_model.Ridge(alpha=alpha)regr.fit(X_train, y_train)scores.append(regr.score(X_test, y_test))## 绘图fig=plt.figure()ax=fig.add_subplot(1,1,1)ax.plot(alphas,scores)ax.set_xlabel(r"$\alpha$")ax.set_ylabel(r"score")ax.set_xscale('log')ax.set_title("Ridge")plt.show()if __name__=='__main__':X_train,X_test,y_train,y_test=load_data() # 产生用于回归问题的数据集test_Ridge_alpha(X_train,X_test,y_train,y_test) # 调用 test_Ridge_alpha
  • 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

输出:

可以看到,当αα超过1时,随着αα增长,模型预测性能急剧下降。这是因为αα较大,正则化项α||w||22α||w||22影响变大,模型趋于简单。极端的来讲当α→∞α→∞,而正则化项α||w||22α||w||22对损失函数的影响非常大,我们的目标是损失函数尽量小,故此时||w||22||w||22会尽量的小,也就是ww会趋于0,这时候模型基本就剩下一个b了(输入啥都预测b)。这样就会导致模型变得简单,从而预测性能大大降低。


 

3.Lasso回归

Lasso Regression和岭回归的区别在于引入的是入L1范数惩罚项,可以将系数控制收缩到0,从而达到变量选择的效果(参数稀疏的功能)。linear_model下提供了Lasso类实现Lasso回归模型

Lasso类介绍

  • Lasso类原型为:

     class Lasso(ElasticNet):  '''Linear Model trained with L1 prior as regularizer (aka the Lasso).'''
    • 1
    • 2
  • 父类

        _ElasticNet:''' 后面会讲解'''
    
    • 1
    • 2
    • 3
  • 参数

    def __init__(self, alpha=1.0, fit_intercept=True, normalize=False,precompute=False, copy_X=True, max_iter=1000,tol=1e-4, warm_start=False, positive=False,random_state=None, selection='cyclic'):----------precompute : True | False | array-like, default=False是否提前计算Gram矩阵来加速计算.warm_start : bool, optionalWhen set to True, 使用前一次训练的结果训练positive : bool, optionalWhen set to ``True``, 强制要求权值向量都是正数selection : {'random','cyclic'} default 'cyclic'  每次迭代的时候,选择权重向量的哪个分量来更新- 'random':随机选择权重向量的一个分量来更新- 'cyclic':从前向后依次选择权重向量的一个分量来更新alpha : {float, array-like}, shape (n_targets)a值,越大代表正则化占比越大copy_X : boolean, optional, default TrueIf True, 会复制Xfit_intercept : boolean为False就不计算b(e.g. 模型会假设你的数据已经中心化了).max_iter : int, optional指定最大迭代次数,If None,则为默认值(不同的solver默认值不同)normalize : boolean, optional, default FalseIf True, 数据在使用前会归一化tol : float指定判别迭代收敛的阈值.random_state : int seed, RandomState实例, or None (default),在slover=sag时使用- 如果为整数,指定了随机数生成器的种子- 如果为RandomState实例,指定了随机数生成器- 如果为None,使用默认的随机数生成器
    • 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
  • 属性

            ----------coef_ : array, shape (n_features, ) or (n_targets, n_features)权重系数intercept_ : arrayb值   n_iter_ : array or None, shape (n_targets,)实际的迭代次数   
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
  • 方法

            fit(self, X, y, sample_weight=None) : 训练模型predict(self, X):  :用模型进行预测 (从父类继承)score(self, X, y, sample_weight=None)  :返回预测性能得分。(从父类继承)
    • 1
    • 2
    • 3
    • 4
    • 5
  • 使用Lasso的函数如下(观察函数预测性能随着正则系数变化趋势)

    def test_Lasso_alpha(*data):'''测试 Lasso 的预测性能随 alpha 参数的影响:param data: 可变参数。它是一个元组要求其元素依次为:训练样本集、测试样本集、训练样本的值、测试样本的值:return: None'''X_train,X_test,y_train,y_test=dataalphas=[0.01,0.02,0.05,0.1,0.2,0.5,1,2,5,10,20,50,100,200,500,1000]scores=[]for i,alpha in enumerate(alphas):regr = linear_model.Lasso(alpha=alpha)regr.fit(X_train, y_train)scores.append(regr.score(X_test, y_test))## 绘图fig=plt.figure()ax=fig.add_subplot(1,1,1)ax.plot(alphas,scores)ax.set_xlabel(r"$\alpha$")ax.set_ylabel(r"score")ax.set_xscale('log')ax.set_title("Lasso")plt.show()
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

本节程序小结:

    # -*- coding: utf-8 -*-"""广义线性模型~~~~~~~~~~~~~~~~~~~~~~~~~~Lasso"""import matplotlib.pyplot as pltimport numpy as npfrom sklearn import datasets, linear_model,cross_validationdef load_data():'''加载用于回归问题的数据集'''diabetes = datasets.load_diabetes()return cross_validation.train_test_split(diabetes.data,diabetes.target,test_size=0.25,random_state=0) def test_Lasso_alpha(*data):'''测试 Lasso 的预测性能随 alpha 参数的影响:param data: 可变参数。它是一个元组这里要求其元素依次为:训练样本集、测试样本集、训练样本的值、测试样本的值:return: None'''X_train,X_test,y_train,y_test=dataalphas=[0.01,0.02,0.05,0.1,0.2,0.5,1,2,5,10,20,50,100,200,500,1000]scores=[]for i,alpha in enumerate(alphas):regr = linear_model.Lasso(alpha=alpha)regr.fit(X_train, y_train)scores.append(regr.score(X_test, y_test))## 绘图fig=plt.figure()ax=fig.add_subplot(1,1,1)ax.plot(alphas,scores)ax.set_xlabel(r"$\alpha$")ax.set_ylabel(r"score")ax.set_xscale('log')ax.set_title("Lasso")plt.show()if __name__=='__main__':X_train,X_test,y_train,y_test=load_data() # 产生用于回归问题的数据集test_Lasso_alpha(X_train,X_test,y_train,y_test) # 调用 test_Lasso_alpha
  • 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

输出:

和Ridge差不多。


 

4.ElasticNet回归

ElasticNet是对岭回归和Lasso回归的综合,惩罚项是对L1和L2的均衡。linear_model下提供了ElasticNet类实现ElasticNet回归模型.

ElasticNet类介绍

  • ElasticNet类原型为:

     class ElasticNet(LinearModel, RegressorMixin):  '''Linear regression with combined L1 and L2 priors as regularizer.'''
    • 1
    • 2
  • 父类

        LinearModel:"""Base class for Linear Models"""RegressorMixin:"""Mixin class for all regression estimators in scikit-learn."""
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
  • 参数

    def __init__(self, alpha=1.0, l1_ratio=0.5, fit_intercept=True,normalize=False, precompute=False, max_iter=1000,copy_X=True, tol=1e-4, warm_start=False, positive=False,random_state=None, selection='cyclic'):----------l1_ratio : floatp值.alpha : {float, array-like}, shape (n_targets)a值,越大代表正则化占比越大copy_X : boolean, optional, default TrueIf True, 会复制Xfit_intercept : boolean为False就不计算b(e.g. 模型会假设你的数据已经中心化了).max_iter : int, optional指定最大迭代次数,If None,则为默认值(不同的solver默认值不同)normalize : boolean, optional, default FalseIf True, 数据在使用前会归一化precompute : True | False | array-like, default=False是否提前计算Gram矩阵来加速计算.warm_start : bool, optionalWhen set to True, 使用前一次训练的结果训练positive : bool, optionalWhen set to ``True``, 强制要求权值向量都是正数selection : {'random','cyclic'} default 'cyclic'  每次迭代的时候,选择权重向量的哪个分量来更新- 'random':随机选择权重向量的一个分量来更新- 'cyclic':从前向后依次选择权重向量的一个分量来更新tol : float指定判别迭代收敛的阈值.random_state : int seed, RandomState实例, or None (default),在slover=sag时使用- 如果为整数,指定了随机数生成器的种子- 如果为RandomState实例,指定了随机数生成器- 如果为None,使用默认的随机数生成器
    • 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
  • 属性

            ----------coef_ : array, shape (n_features, ) or (n_targets, n_features)权重系数intercept_ : arrayb值   n_iter_ : array or None, shape (n_targets,)实际的迭代次数   
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
  • 方法

            fit(self, X, y, sample_weight=None) : 训练模型predict(self, X):  :用模型进行预测 (从父类继承)score(self, X, y, sample_weight=None)  :返回预测性能得分。(从父类继承)
    • 1
    • 2
    • 3
    • 4
    • 5
  • 使用ElasticNet的函数如下(观察函数预测性能随着正则系数变化趋势)

    def test_ElasticNet_alpha_rho(*data):'''测试 ElasticNet 的预测性能随 alpha 和 l1_ratio 的影响:param data: 可变参数。它是一个元组要求其元素依次为:训练样本集、测试样本集、训练样本的值、测试样本的值:return: None'''X_train,X_test,y_train,y_test=dataalphas=np.logspace(-2,2)rhos=np.linspace(0.01,1)scores=[]for alpha in alphas:for rho in rhos:regr = linear_model.ElasticNet(alpha=alpha,l1_ratio=rho)regr.fit(X_train, y_train)scores.append(regr.score(X_test, y_test))## 绘图alphas, rhos = np.meshgrid(alphas, rhos) #  np.meshgrid接收两个一维数组,并产生两个二维矩阵 alphas(50,50) rhos(50,50)scores=np.array(scores).reshape(alphas.shape) #转换为array并转换为二维矩阵 scores(50,50)from mpl_toolkits.mplot3d import Axes3D  #两个超参数,为三维图像from matplotlib import cmfig=plt.figure()ax=Axes3D(fig)  surf = ax.plot_surface(alphas, rhos, scores, rstride=1, cstride=1, cmap=cm.jet,linewidth=0, antialiased=False)fig.colorbar(surf, shrink=0.5, aspect=5)ax.set_xlabel(r"$\alpha$")ax.set_ylabel(r"$\rho$")ax.set_zlabel("score")ax.set_title("ElasticNet")plt.show()
    • 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

本节程序小结:

     # -*- coding: utf-8 -*-"""广义线性模型~~~~~~~~~~~~~~~~~~~~~~~~~~ElasticNet"""import matplotlib.pyplot as pltimport numpy as npfrom sklearn import datasets, linear_model,cross_validationdef load_data():'''加载用于回归问题的数据集'''diabetes = datasets.load_diabetes()return cross_validation.train_test_split(diabetes.data,diabetes.target,test_size=0.25,random_state=0) def test_ElasticNet_alpha_rho(*data):'''测试 ElasticNet 的预测性能随 alpha 和 l1_ratio 的影响:param data: 可变参数。它是一个元组要求其元素依次为:训练样本集、测试样本集、训练样本的值、测试样本的值:return: None'''X_train,X_test,y_train,y_test=dataalphas=np.logspace(-2,2) # 默认50个点 从10^-2到10^2取等分向量rhos=np.linspace(0.01,1) #默认100个点 从0.01到1取等分向量scores=[]for alpha in alphas:for rho in rhos:regr = linear_model.ElasticNet(alpha=alpha,l1_ratio=rho)regr.fit(X_train, y_train)scores.append(regr.score(X_test, y_test))## 绘图alphas, rhos = np.meshgrid(alphas, rhos) #  np.meshgrid接收两个一维数组,并产生两个二维矩阵 alphas(50,50) rhos(50,50)scores=np.array(scores).reshape(alphas.shape) #转换为array并转换为二维矩阵 scores(50,50)from mpl_toolkits.mplot3d import Axes3D  #两个超参数,为三维图像from matplotlib import cmfig=plt.figure()ax=Axes3D(fig)  surf = ax.plot_surface(alphas, rhos, scores, rstride=1, cstride=1, cmap=cm.jet,linewidth=0, antialiased=False)fig.colorbar(surf, shrink=0.5, aspect=5)ax.set_xlabel(r"$\alpha$")ax.set_ylabel(r"$\rho$")ax.set_zlabel("score")ax.set_title("ElasticNet")plt.show()if __name__=='__main__':X_train,X_test,y_train,y_test=load_data() # 产生用于回归问题的数据集test_ElasticNet_alpha_rho(X_train,X_test,y_train,y_test) # 调用 test_ElasticNet_alpha_rho
  • 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

输出:

随着αα的增大,预测性能下降。而ρρ主要影响性能下降的速度,因为这个参数控制L1和L2的比例.


逻辑回归模型

逻辑回归模型

LogisticRegression回归

linear_model下提供了LogisticRegression类实现逻辑回归模型。

LogisticRegression类介绍

  • LogisticRegression类原型为:

     class LogisticRegression(BaseEstimator, LinearClassifierMixin,_LearntSelectorMixin, SparseCoefMixin):  '''Logistic Regression (aka logit, MaxEnt) classifier.'''
    • 1
    • 2
    • 3
  • 父类

        BaseEstimator:"""Base class for all estimators in scikit-learn"""LinearClassifierMixin"""Mixin for linear classifiers._LearntSelectorMixin'''Transformer mixin selecting features based on importance weights.'''SparseCoefMixin:"""Mixin for converting coef_ to and from CSR format."""
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
  • 参数

    def __init__(self, penalty='l2', dual=False, tol=1e-4, C=1.0,fit_intercept=True, intercept_scaling=1, class_weight=None,random_state=None, solver='liblinear', max_iter=100,multi_class='ovr', verbose=0, warm_start=False, n_jobs=1)----------penalty : str, 'l1' or 'l2', default: 'l2'指定了正则化策略. The 'newton-cg','sag' and 'lbfgs' solvers support only l2 penalties.
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • penalty=’l2’,则优化目标函数为:0.5||w||22+CL(w),C>0;L(w)0.5||w||22+CL(w),C>0;L(w)为极大似然函数
    • penalty=’l1’,则优化目标函数为:||w||1+CL(w),C>0;L(w)||w||1+CL(w),C>0;L(w)为极大似然函数
                dual : bool, default: False如果为True,则求解对偶形式(penalty='l2'且solver=’liblinear‘有对偶形式)False求解原形式C : float, default: 1.0指定正则化惩罚系数的倒数,值越小,正则化项越大fit_intercept : boolean为False就不计算b(e.g. 模型会假设你的数据已经中心化了).intercept_scaling : float, default 1.只有当solver='liblinear'才有意义,采用intercept_scaling时,相当于人造一个特征出来,特征恒为1,权重为b.计算正则化项的时候,这个项也被考虑进去了,为了降低这个人造特征的影响,需要提供intercept_scalingclass_weight : dict or 'balanced', default: None- dict: 字典给出了每个分类的权重,如{class_label:weight}- 'balanced':每个分类的权重与该分类在样本集中出现频率成反比- 未指定:每个分类的权重都为1max_iter : int, default: 100Useful only for the newton-cg, sag and lbfgs solvers.最大迭代次数random_state : int seed, RandomState instance, default: NoneUsed only in solvers 'sag' and 'liblinear'.- 如果为整数,指定了随机数生成器的种子- 如果为RandomState实例,指定了随机数生成器- 如果为None,使用默认的随机数生成器 solver : {'newton-cg', 'lbfgs', 'liblinear', 'sag'}, default: 'liblinear'指定求解最优化问题的算法.- 对于小数据集, 'liblinear' is a good choice- 对于大数据集,whereas 'sag' is faster for large ones.- 对于多分类问题, only 'newton-cg', 'sag' and 'lbfgs' handlemultinomial loss; 'liblinear' is limited to one-versus-restschemes.- 'newton-cg', 'lbfgs' and 'sag' only 针对 L2 正则化.tol : float指定判别迭代收敛的阈值.multi_class : str, {'ovr', 'multinomial'}, default: 'ovr'指定对于多分类问题的策略- 'ovr', 采用one-vs-rest策略- 'multinomial':直接采用多分类了逻辑回归策略verbose : int, default: 0用于开启/关闭迭代中间输出日志功能warm_start : bool, optionalWhen set to True, 使用前一次训练的结果训练n_jobs : int, default: 1指定任务并行时的CPU数量如果为-1, all cores are used.
    • 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
  • 属性

            ----------coef_ : array, shape (n_features, ) or (n_targets, n_features)权重系数intercept_ : arrayb值   n_iter_ : array or None, shape (n_targets,)实际的迭代次数   
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
  • 方法

            fit(self, X, y, sample_weight=None) : 训练模型predict(self, X):  :用模型进行预测 (从父类继承)predict_log_proba(self, X): 返回一个数组,数组的元素依次是X预测为各个类别的概率的对数值predict_proba(self, X):返回一个数组,数组元素依次是X预测为各个类别的概率值score(self, X, y, sample_weight=None)  :返回预测性能得分。(从父类继承)
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
  • 使用LogisticRegression的函数如下(观察多分类下影响、观察函数预测性能随着正则系数变化趋势)

    def test_LogisticRegression(*data):'''测试 LogisticRegression 的用法简单地从训练集中学习,参数都使用默认的:param data: 可变参数。它是一个元组这里要求其元素依次为:训练样本集、测试样本集、训练样本的标记、测试样本的标记:return: None'''X_train,X_test,y_train,y_test=dataregr = linear_model.LogisticRegression()regr.fit(X_train, y_train)print('Coefficients:%s, intercept %s'%(regr.coef_,regr.intercept_))print('Score: %.2f' % regr.score(X_test, y_test))def test_LogisticRegression_multinomial(*data):'''测试 LogisticRegression 的预测性能随 multi_class 参数的影响:param data: 可变参数。它是一个元组要求其元素依次为:训练样本集、测试样本集、训练样本的标记、测试样本的标记:return: None'''X_train,X_test,y_train,y_test=dataregr = linear_model.LogisticRegression(multi_class='multinomial',solver='lbfgs')regr.fit(X_train, y_train)print('Coefficients:%s, intercept %s'%(regr.coef_,regr.intercept_))print('Score: %.2f' % regr.score(X_test, y_test))def test_LogisticRegression_C(*data):'''测试 LogisticRegression 的预测性能随  C  参数的影响:param data: 可变参数。它是一个元组要求其元素依次为:训练样本集、测试样本集、训练样本的标记、测试样本的标记:return: None'''X_train,X_test,y_train,y_test=dataCs=np.logspace(-2,4,num=100)scores=[]for C in Cs:regr = linear_model.LogisticRegression(C=C)regr.fit(X_train, y_train)scores.append(regr.score(X_test, y_test))## 绘图fig=plt.figure()ax=fig.add_subplot(1,1,1)ax.plot(Cs,scores)ax.set_xlabel(r"C")ax.set_ylabel(r"score")ax.set_xscale('log')ax.set_title("LogisticRegression")plt.show()
    • 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

本节程序小结:

    # -*- coding: utf-8 -*-"""广义线性模型~~~~~~~~~~~~~~~~~~~~~~~~~~Logistic 回归"""import matplotlib.pyplot as pltimport numpy as npfrom sklearn import datasets, linear_model,cross_validationdef load_data():'''加载用于分类问题的数据集'''iris=datasets.load_iris() # 使用 scikit-learn 自带的 iris 数据集X_train=iris.datay_train=iris.targetreturn cross_validation.train_test_split(X_train, y_train,test_size=0.25,random_state=0,stratify=y_train)# 分层采样拆分成训练集和测试集,测试集大小为原始数据集大小的 1/4def test_LogisticRegression(*data):'''测试 LogisticRegression 的用法'''X_train,X_test,y_train,y_test=dataregr = linear_model.LogisticRegression()regr.fit(X_train, y_train)print('Coefficients:%s, intercept %s'%(regr.coef_,regr.intercept_))print('Score: %.2f' % regr.score(X_test, y_test))def test_LogisticRegression_multinomial(*data):'''测试 LogisticRegression 的预测性能随 multi_class 参数的影响'''X_train,X_test,y_train,y_test=dataregr = linear_model.LogisticRegression(multi_class='multinomial',solver='lbfgs')regr.fit(X_train, y_train)print('Coefficients:%s, intercept %s'%(regr.coef_,regr.intercept_))print('Score: %.2f' % regr.score(X_test, y_test))def test_LogisticRegression_C(*data):'''测试 LogisticRegression 的预测性能随  C  参数的影响:return: None'''X_train,X_test,y_train,y_test=dataCs=np.logspace(-2,4,num=100)scores=[]for C in Cs:regr = linear_model.LogisticRegression(C=C)regr.fit(X_train, y_train)scores.append(regr.score(X_test, y_test))## 绘图fig=plt.figure()ax=fig.add_subplot(1,1,1)ax.plot(Cs,scores)ax.set_xlabel(r"C")ax.set_ylabel(r"score")ax.set_xscale('log')ax.set_title("LogisticRegression")plt.show()if __name__=='__main__':X_train,X_test,y_train,y_test=load_data() # 加载用于分类的数据集print('调用  test_LogisticRegression')print('=========================================================================')test_LogisticRegression(X_train,X_test,y_train,y_test) # 调用  test_LogisticRegressionprint('调用  test_LogisticRegression_multinomial')print('=========================================================================')test_LogisticRegression_multinomial(X_train,X_test,y_train,y_test) # 调用  test_LogisticRegression_multinomialprint('调用  test_LogisticRegression_C')print('=========================================================================')test_LogisticRegression_C(X_train,X_test,y_train,y_test) # 调用  test_LogisticRegression_C
  • 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

输出:

调用  test_LogisticRegression=========================================================================Coefficients:[[ 0.39310895  1.35470406 -2.12308303 -0.96477916][ 0.22462128 -1.34888898  0.60067997 -1.24122398][-1.50918214 -1.29436177  2.14150484  2.2961458 ]], intercept [ 0.24122458  1.13775782 -1.09418724]Score: 0.97调用  test_LogisticRegression_multinomial=========================================================================Coefficients:[[-0.38336889  0.85483782 -2.27270458 -0.98438566][ 0.34335964 -0.37376524 -0.03024797 -0.86146323][ 0.04000925 -0.48107258  2.30295255  1.84584889]], intercept [  8.79968016   2.46967258 -11.26935274]Score: 1.00调用  test_LogisticRegression_C=========================================================================
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

注意到C是正则化系数的倒数,越小则正则化的权重越大。可以看到随着C的增大,准确率在上升,增大到一定程度后,准确率保持在一个高水平.


线性判别分析

线性判别分析

LinearDiscriminantAnalysis

discriminant_analysis下提供了LinearDiscriminantAnalysis类实现线性判别分析(这是使用的包不一样了)

LinearDiscriminantAnalysis类介绍

  • LinearDiscriminantAnalysis类原型为:

     class LinearDiscriminantAnalysis(BaseEstimator, LinearClassifierMixin,TransformerMixin): '''Linear Discriminant Analysis. '''
    • 1
    • 2
  • 父类

        BaseEstimator:"""Base class for all estimators in scikit-learn"""LinearClassifierMixin"""Mixin for linear classifiers.TransformerMixin'''Mixin class for all transformers in scikit-learn.'''
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
  • 参数

    def __init__(self, solver='svd', shrinkage=None, priors=None,n_components=None, store_covariance=False, tol=1e-4):----------solver : string, {'svd','lsqr','eigen'}optional , default:'svd'Solver to use, possible values:- 'svd': 奇异值分解,对于大规模特征数据,推荐用这个- 'lsqr':最小平方差算法, can be combined with shrinkage.- 'eigen': 特征值分解算法, can be combined with shrinkage.shrinkage : string('auto') or float, optional- None: no shrinkage (default).- 'auto': 根据Ledoit-Wolf引理自动决定shrinkage参数- float between 0 and 1: 指定shrinkage parameter.Note that shrinkage works only with 'lsqr' and 'eigen' solvers.priors : array, optional, shape (n_classes,)指定每个类别的先验概率,为None则说明每个类别等可能n_components : int, optional指定数据降维后的维度(该值必须小于n_classes-1).store_covariance : bool, optional  ,default FalseIf Ture,需要额外计算每个类别的协方差矩阵 .tol : float, optional指定用 SVD solver判别迭代收敛的阈值
    • 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
  • 属性

            ----------coef_ : array, shape (n_features,) or (n_classes, n_features)权重系数intercept_ : array, shape (n_features,)b值covariance_ : array-like, shape (n_features, n_features)依次给出每个类别的协方差矩阵.means_ : array-like, shape (n_classes, n_features)给出每个类别的均值向量.priors_ : array-like, shape (n_classes,)Class priors (sum to 1).scalings_ : array-like, shape (rank, n_classes - 1)Scaling of the features in the space spanned by the class centroids.xbar_ : array-like, shape (n_features,)整体样本的均值向量.classes_ : array-like, shape (n_classes,)Unique class labels.n_iter_ : array or None, shape (n_targets,)实际的迭代次数
    • 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
  • 方法

            fit(self, X, y, sample_weight=None) : 训练模型predict(self, X):  :用模型进行预测 (从父类继承)predict_log_proba(self, X): 返回一个数组,数组的元素依次是X预测为各个类别的概率的对数值predict_proba(self, X):返回一个数组,数组元素依次是X预测为各个类别的概率值score(self, X, y, sample_weight=None)  :返回预测性能得分。(从父类继承)
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
  • 使用LinearDiscriminantAnalysis的函数如下

    def test_LinearDiscriminantAnalysis(*data):'''测试 LinearDiscriminantAnalysis 的用法:param data: 可变参数。它是一个元组要求其元素依次为:训练样本集、测试样本集、训练样本的标记、测试样本的标记:return:  None'''X_train,X_test,y_train,y_test=datalda = discriminant_analysis.LinearDiscriminantAnalysis()lda.fit(X_train, y_train)print('Coefficients:%s, intercept %s'%(lda.coef_,lda.intercept_))print('Score: %.2f' % lda.score(X_test, y_test))
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    输出:

    Coefficients:[[  6.575853     9.75807593 -14.34026669 -21.39076537][ -1.98385061  -3.49791089   4.21495042   2.60304299][ -4.47116022  -6.09542385   9.85886057  18.29330864]], intercept [-15.33097142   0.46730077 -30.53297367]Score: 1.00
    • 1
    • 2
    • 3
    • 4

    还算可以.

  • 检查LinearDiscriminantAnalysis分析后的降维数据集:

    def plot_LDA(converted_X,y):'''绘制经过 LDA 转换后的数据:param converted_X: 经过 LDA转换后的样本集(150,3)降维后的表示方法:param y: 样本集的标记(150,1):return:  None'''from mpl_toolkits.mplot3d import Axes3Dfig=plt.figure()ax=Axes3D(fig)colors='rgb'markers='o*s'for target,color,marker in zip([0,1,2],colors,markers):  #zip()方法用在for循环中,支持并行迭代pos=(y==target).ravel()  #由标签转换为bool矩阵,分成不同标签类型的矩阵(150,) 用于拆分数据X=converted_X[pos,:]        # 取出对应pos中True的元素,目的是将降维后的数据拆分为三类X(50,3)ax.scatter(X[:,0], X[:,1], X[:,2],color=color,marker=marker,  #  X[:,0]取出第一行的数据label="Label %d"%target)ax.legend(loc="best")fig.suptitle("Iris After LDA")plt.show()def run_plot_LDA():'''执行 plot_LDA 。其中数据集来自于 load_data() 函数:return: None'''# X_train(112,4)  X_test(38,4) y_train(112,) y_test(38,)X_train,X_test,y_train,y_test=load_data()# X(150,4)X=np.vstack((X_train,X_test))  # 考虑到lda的fit接受的参数问题,这里需要组合X_Train和X_test# Y(150,1)  原本维度为1,所以要先reshapeY=np.vstack((y_train.reshape(y_train.size,1),y_test.reshape(y_test.size,1))) # 组合y_train和y_testlda = discriminant_analysis.LinearDiscriminantAnalysis()lda.fit(X, Y)# converted_X(150,3) 对数据降维了    权值lda.coef_(3, 4)  lda.intercept_(3,)converted_X=np.dot(X,np.transpose(lda.coef_))+lda.intercept_  # X*权值+偏置b  就是输出值plot_LDA(converted_X,Y)
    • 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

    输出:

    可以看到不同的鸢尾花之间间隔较远,已经聚类到一起了.

  • 检查LinearDiscriminantAnalysis中不同solver对预测性能的影响:

    def test_LinearDiscriminantAnalysis_solver(*data):'''测试 LinearDiscriminantAnalysis 的预测性能随 solver 参数的影响:param data: 可变参数。它是一个元组要求其元素依次为:训练样本集、测试样本集、训练样本的标记、测试样本的标记:return:  None'''X_train,X_test,y_train,y_test=datasolvers=['svd','lsqr','eigen']for solver in solvers:if(solver=='svd'):lda = discriminant_analysis.LinearDiscriminantAnalysis(solver=solver)else:lda = discriminant_analysis.LinearDiscriminantAnalysis(solver=solver,shrinkage=None)lda.fit(X_train, y_train)print('Score at solver=%s: %.2f' %(solver, lda.score(X_test, y_test)))
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    输出:

                Score at solver=svd: 1.00Score at solver=lsqr: 1.00Score at solver=eigen: 1.00
    • 1
    • 2
    • 3

    数据集不大,效果都差不多.

  • 检查LinearDiscriminantAnalysis中solver=lsqr中引入抖动(相当于正则化):

    def test_LinearDiscriminantAnalysis_shrinkage(*data):'''测试  LinearDiscriminantAnalysis 的预测性能随 shrinkage 参数的影响:param data: 可变参数。它是一个元组,这里要求其元素依次为:训练样本集、测试样本集、训练样本的标记、测试样本的标记:return:  None'''X_train,X_test,y_train,y_test=datashrinkages=np.linspace(0.0,1.0,num=20)scores=[]for shrinkage in shrinkages:lda = discriminant_analysis.LinearDiscriminantAnalysis(solver='lsqr',shrinkage=shrinkage)lda.fit(X_train, y_train)scores.append(lda.score(X_test, y_test))## 绘图fig=plt.figure()ax=fig.add_subplot(1,1,1)ax.plot(shrinkages,scores)ax.set_xlabel(r"shrinkage")ax.set_ylabel(r"score")ax.set_ylim(0,1.05)ax.set_title("LinearDiscriminantAnalysis")plt.show()
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    输出:

    还算可以.


本节程序小结:

    # -*- coding: utf-8 -*-"""广义线性模型~~~~~~~~~~~~~~~~~~~~~~~~~~线性判别分析"""import matplotlib.pyplot as pltimport numpy as npfrom sklearn import datasets, discriminant_analysis,cross_validation  #注意这里导入模型的包变了def load_data():'''加载用于分类问题的数据集'''iris=datasets.load_iris() X_train=iris.datay_train=iris.targetreturn cross_validation.train_test_split(X_train, y_train,test_size=0.25,random_state=0,stratify=y_train)def test_LinearDiscriminantAnalysis(*data):'''测试 LinearDiscriminantAnalysis 的用法:return:  None'''X_train,X_test,y_train,y_test=datalda = discriminant_analysis.LinearDiscriminantAnalysis()lda.fit(X_train, y_train)print('Coefficients:%s, intercept %s'%(lda.coef_,lda.intercept_))print('Score: %.2f' % lda.score(X_test, y_test))def plot_LDA(converted_X,y):'''绘制经过 LDA 转换后的数据:param converted_X: 经过 LDA转换后的样本集(150,3)降维后的表示方法:param y: 样本集的标记(150,1):return:  None'''from mpl_toolkits.mplot3d import Axes3Dfig=plt.figure()ax=Axes3D(fig)colors='rgb'markers='o*s'for target,color,marker in zip([0,1,2],colors,markers):  #zip()方法用在for循环中,支持并行迭代pos=(y==target).ravel()  #由标签转换为bool矩阵,分成不同标签类型的矩阵(150,) 用于拆分数据X=converted_X[pos,:]        # 取出对应pos中True的元素,目的是将降维后的数据拆分为三类X(50,3)ax.scatter(X[:,0], X[:,1], X[:,2],color=color,marker=marker,  #  X[:,0]取出第一行的数据label="Label %d"%target)ax.legend(loc="best")fig.suptitle("Iris After LDA")plt.show()def run_plot_LDA():'''执行 plot_LDA 。其中数据集来自于 load_data() 函数:return: None'''# X_train(112,4)  X_test(38,4) y_train(112,) y_test(38,)X_train,X_test,y_train,y_test=load_data()# X(150,4)X=np.vstack((X_train,X_test))  # 考虑到lda的fit接受的参数问题,这里需要组合X_Train和X_test# Y(150,1)  原本维度为1,所以要先reshapeY=np.vstack((y_train.reshape(y_train.size,1),y_test.reshape(y_test.size,1))) # 组合y_train和y_testlda = discriminant_analysis.LinearDiscriminantAnalysis()lda.fit(X, Y)# converted_X(150,3) 对数据降维了    权值lda.coef_(3, 4)  lda.intercept_(3,)converted_X=np.dot(X,np.transpose(lda.coef_))+lda.intercept_  # X*权值+偏置b  就是输出值plot_LDA(converted_X,Y)def test_LinearDiscriminantAnalysis_solver(*data):'''测试 LinearDiscriminantAnalysis 的预测性能随 solver 参数的影响:return:  None'''X_train,X_test,y_train,y_test=datasolvers=['svd','lsqr','eigen']for solver in solvers:if(solver=='svd'):lda = discriminant_analysis.LinearDiscriminantAnalysis(solver=solver)else:lda = discriminant_analysis.LinearDiscriminantAnalysis(solver=solver,shrinkage=None)lda.fit(X_train, y_train)print('Score at solver=%s: %.2f' %(solver, lda.score(X_test, y_test)))def test_LinearDiscriminantAnalysis_shrinkage(*data):'''测试  LinearDiscriminantAnalysis 的预测性能随 shrinkage 参数的影响:return:  None'''X_train,X_test,y_train,y_test=datashrinkages=np.linspace(0.0,1.0,num=20)scores=[]for shrinkage in shrinkages:lda = discriminant_analysis.LinearDiscriminantAnalysis(solver='lsqr',shrinkage=shrinkage)lda.fit(X_train, y_train)scores.append(lda.score(X_test, y_test))## 绘图fig=plt.figure()ax=fig.add_subplot(1,1,1)ax.plot(shrinkages,scores)ax.set_xlabel(r"shrinkage")ax.set_ylabel(r"score")ax.set_ylim(0,1.05)ax.set_title("LinearDiscriminantAnalysis")plt.show()if __name__=='__main__':X_train,X_test,y_train,y_test=load_data() # 产生用于分类的数据集#test_LinearDiscriminantAnalysis(X_train,X_test,y_train,y_test) # 调用 test_LinearDiscriminantAnalysis# run_plot_LDA() # 调用 run_plot_LDA# test_LinearDiscriminantAnalysis_solver(X_train,X_test,y_train,y_test) # 调用 test_LinearDiscriminantAnalysis_solvertest_LinearDiscriminantAnalysis_shrinkage(X_train,X_test,y_train,y_test) # 调用 test_LinearDiscriminantAnalysis_shrinkage
  • 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
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128




参考资料

《机器学习》 周志华 
《Python大战机器学习》 华校专 
https://www.zhihu.com/question/20447622 关于最大似然估计的通俗理解

机器学习(线性模型)相关推荐

  1. 【数学基础】算法工程师必备的机器学习--线性模型(下)

    作者:华校专 作者信息: 华校专,曾任阿里巴巴资深算法工程师.智易科技首席算法研究员,现任腾讯高级研究员,<Python 大战机器学习>的作者. 编者按: 算法工程师必备系列更新啦!继上次 ...

  2. 【数学基础】算法工程师必备的机器学习--线性模型(上)

    作者:华校专 作者信息: 华校专,曾任阿里巴巴资深算法工程师.智易科技首席算法研究员,现任腾讯高级研究员,<Python 大战机器学习>的作者. 编者按: 算法工程师必备系列更新啦!继上次 ...

  3. 机器学习 - 线性模型

    一.线性回归-LR 线性回归是一种监督学习下的线性模型,线性回归试图从给定数据集中学习一个线性模型来较好的预测输出(可视为:新来一个不属于D的数据,我们只知道他的x,要求预测y,D如下表示). 首先我 ...

  4. Python机器学习——线性模型

    最近断断续续地在接触一些python的东西.按照我的习惯,首先从应用层面搞起,尽快入门,后续再细化一 些技术细节.找了一些资料,基本语法和数据结构搞定之后,目光便转到了scikit-learn这个包. ...

  5. 周志华机器学习--线性模型

    系列文章目录 第一章 绪论 第二章 模型评估与选择 第三章 线性模型 第四章 决策树 第五章 支持向量机 第六章 神经网络 第七章 贝叶斯分类器 第八章 集成学习和聚类 文章目录 系列文章目录 一.线 ...

  6. 机器学习-线性模型及广义线性模型

    线性模型(linear model) 线性模型试图学得一个通过属性的线性组合来进行预测的函数,即: ...  (其中;...;为输入属性,;...;和b为模型参数) 向量表示为:   (其中为输入属性 ...

  7. 机器学习——线性模型之Softmax回归

    问:Softmax回归模型是一种典型处理多分类任务的非线性分类模型 答:错误.Softmax回归是线性分类模型.实际上是逻辑回归的拓展,它将逻辑回归的二分类推广到了多分类,用逻辑回归的方法解决多分类问 ...

  8. 机器学习——线性模型学习

    线性回归 线性回归 多元线性回归 对数线性回归 对数几率回归 线性判别分析(LDA) 多分类任务中的LDA 多分类学习 OvR.OvO MvM 线性回归 主要目标确定 如何确定w和b呢?关键在于如何衡 ...

  9. 搜集的一些机器学习和数据挖掘的实践项目

    实战项目方向: 23个机器学习最佳实战项目 里面针对不同的阶段都有提供建议 (1)卷积神经网络:Emojify –使用Python创建自己的表情符号 (2)机器学习线性模型:使用机器学习进行贷款预测 ...

  10. 邱锡鹏教授--神经网络和深度学习(一)

    邱锡鹏教授--神经网络和深度学习(一) 机器学习 线性模型 long time no see-今天开始会把之前或平时的学习笔记记录到这里,有误请大家帮我指正一下,开始冲了!对应的资源我会上传到这里,大 ...

最新文章

  1. 学习javascript 非常好的博客
  2. mysql5.6启动占用内存很大的解决方法
  3. Sharepoint学习笔记—ECMAScript对象模型系列-- 7、获取和修改List的Lookup字段
  4. SaltStack之salt-key管理
  5. 嵌套的Try-Catch块--------异常处理(3)
  6. wxWidgets:wxMemoryInputStream类用法
  7. mysql 给列增加索引
  8. 【玩转树莓派】使用 sinopia 搭建私有 npm 服务器
  9. [Err] 1055 - Expression #1 of ORDER BY clause is not in GROUP BY clause and contains nonaggregated c
  10. For input string:
  11. 演练 多班分数录入统计优秀人数
  12. R语言实现混频数据分析
  13. 微软OneDrive使用体验
  14. 测试软硬件系统信息的工具 -- EVEREST Ultimate Edition
  15. eclipse默认指向 WebContent 目录 修改为 webRoot
  16. p17.matplotlib:图中图
  17. Chapter16/17-项目2:数据可视化
  18. 如何去掉图片上的水印,四个步骤,方法超级容易又简单
  19. php安装zend loader,PHP5.3安装Zend Guard Loader图文教程
  20. 华硕路由器修改 Hosts 以达到局域网内自定义解析

热门文章

  1. linux输出数量大于一行,linux top命令详解
  2. 排列组合c几几怎么用计算机算,排列组合C几几怎么算的?
  3. 【ICML 2020对比学习论文解读】SimCLR: A Simple Framework for Contrastive Learning of Visual Representations
  4. 中级工程师的职称好评吗?怎么评中级工程师?需要什么材料?
  5. 学校校园学生信息管理系统 毕业设计毕业源码毕业论文开题报告参考(1)功能概要
  6. 2021美赛C题数据(完整有解压密码)
  7. 第二章第二节.把梳子卖给和尚
  8. 学习记录01:使用pyqt5搭建yolo3目标识别界面
  9. 硬盘主要参数详解(上)
  10. g4600黑苹果efi_【玩机教程】最全黑苹果安装教程 之 小白也能掌握(完结篇)