LogoLogo
  • README
  • 前端编程
    • 01 Node JS
    • 02-ES6详解
    • 03-NPM详解
    • 04-Babel详解
    • 05-前端模块化开发
    • 06-WebPack详解
    • 07-Vue详解
    • 08-Git详解
    • 09-微信小程序
  • 人工智能
    • 机器学习
      • 二次分配问题
      • 非负矩阵
      • 概率潜在语义分析
      • 概率图模型
      • 集成学习
      • 降维
      • 距离度量
      • 决策树
      • 逻辑回归
      • 马尔可夫决策过程
      • 马尔可夫链蒙特卡洛法
      • 朴素贝叶斯法
      • 谱聚类
      • 奇异值分解
      • 潜在狄利克雷分配
      • 潜在语义分析
      • 强化学习
      • 社区算法
      • 时间序列模型
      • 特征工程
      • 条件随机场
      • 图论基础
      • 线性分类
      • 线性回归
      • 信息论中的熵
      • 隐马尔科夫模型
      • 支持向量机
      • 主成分分析
      • EM算法
      • Hermite 矩阵的特征值不等式
      • k-means聚类
      • k近邻法
      • PageRank算法
    • 深度学习
      • Pytorch篇
        • 01-线性模型
        • 02-梯度下降法
        • 03-反向传播
        • 04-pytorch入门
        • 05-用pytorch实现线性回归
        • 06-logistic回归
        • 07-处理多维特征的输入
        • 08-加载数据集
        • 09-多分类问题
        • 10-卷积神经网络
        • 11-循环神经网络
    • 图神经网络
      • 图神经网络笔记01
        • 01-图(Graphs)的结构
        • 02-网络的性质和随机图模型
        • 03-网络工具
        • 04-网络中的主题和结构角色
        • 05-网络中的社区结构
      • 图神经网络笔记02
        • 01-深度学习引言
        • 02-神经网络基础
        • 03-卷积神经网络
        • 04-图信号处理与图卷积神经网络
        • 05-GNN的变体与框架-
        • [06-Google PPRGo 两分钟分类千万节点的最快GNN](人工智能/图神经网络/图神经网络笔记02/06-Google%20PPRGo 两分钟分类千万节点的最快GNN.md)
        • 07-序列模型
        • 08-变分自编码器
        • 09-对抗生成网络
  • 日常记录
    • 健身日记
    • 面经记录
    • 自动生成Summary文件
  • 实战项目
    • 谷粒商城
      • 00-项目概述
      • 01-分布式基础-全栈开发篇
      • 02-分布式高级-微服务架构篇
      • 03-高可用集群-架构师提升篇
  • 数据库
    • MySQL笔记
      • 01-MySQL基础篇
      • 02-MySQL架构篇
      • 03-MySQL索引及调优篇
      • 04-MySQL事务篇
      • 05-MySQL日志与备份篇
    • Redis笔记
      • 01-Redis基础篇
      • 02-Redis高级篇
    • 02-Redis篇
  • 算法笔记
    • 01-算法基础篇
    • 02-算法刷题篇
  • 职能扩展
    • 产品运营篇
  • Go编程
    • 01-Go基础
      • 01-Go基础篇
  • Java编程
    • 01-Java基础
      • 01-Java基础篇
      • 02-多线程篇
      • 03-注射与反解篇
      • 04-JUC并发编程篇
      • 05-JUC并发编程与源码分析
      • 06-JVM原理篇
      • 07-Netty原理篇
      • 08-设计模式篇
    • 02 Java Web
      • 01-Mybatis篇
      • 01-Mybatis篇(新版)
      • 02-Spring篇
      • 02-Spring篇(新版)
      • 03-SpringMVC篇
      • 04-MybatisPlus篇
    • 03-Java微服务
      • 01-SpringBoot篇
      • 01-SpringBoot篇(新版)
      • 02-SpringSecurity篇
      • 03-Shiro篇
      • 04-Swagger篇
      • 05-Zookeeper篇
      • 06-Dubbo篇
      • 07-SpringCloud篇
      • 08-SpringAlibaba篇
      • 09-SpringCloud篇(新版)
    • 04-Java中间件
      • 数据库篇
        • 01-分库分表概述
        • 02-MyCat篇
        • 03-MyCat2篇
        • 04-Sharding-jdbc篇
        • 05-ElasticSearch篇
      • 消息中间件篇
        • 01-MQ概述
        • 02-RabbitMQ篇
        • 03-Kafka篇
        • 04-RocketMQ篇
        • 05-Pulsar篇
    • 05-扩展篇
      • Dubbo篇
      • SpringBoot篇
      • SpringCloud篇
    • 06-第三方技术
      • 01-CDN技术篇
      • 02-POI技术篇
      • 03-第三方支付技术篇
      • 04-第三方登录技术篇
      • 05-第三方短信接入篇
      • 06-视频点播技术篇
      • 07-视频直播技术篇
    • 07-云原生
      • 01-Docker篇
      • 02-Kubernetes篇
      • 03-Kubesphere篇
  • Linux运维
    • 01-Linux篇
    • 02-Nginx篇
  • Python编程
    • 01-Python基础
      • 01.配置环境
      • 02.流程控制
      • 03.数值
      • 04.操作符
      • 05.列表
      • 06.元祖
      • 07.集合
      • 08.字典
      • 09.复制
      • 10.字符串
      • 11.函数
      • 12.常见内置函数
      • 13.变量
      • 14.异常和语法错误
      • 15.时间和日期
      • 16.正则表达式
    • 02 Python Web
      • flask篇
        • 01.前言
        • 02.路由
        • 03.模板
        • 04.视图进阶
        • 05.flask-sqlalchemy
        • 06.表单WTForms
        • 07.session与cookie
        • 08.上下文
        • 09.钩子函数
        • 10.flask 信号
        • 11.RESTFUL
        • 13.flask-mail
        • 14.flask+celery
        • 15.部署
        • 16.flask-login
        • 17.flask-cache
        • 18.flask-babel
        • 19.flask-dashed
        • 20.flask-pjax
        • 21.flask上传文件到第三方
        • 22.flask-restless
        • 23.flask-redis
        • 24.flask-flash
        • 25.消息通知
        • 26.分页
    • 03-Python数据分析
      • Matplotlib
      • Numpy
      • Pandas
      • Seaborn
    • 04-Python爬虫
      • 1.准备工作
      • 2.请求模块的使用
      • 3.解析模块的使用
      • 4.数据存储
      • 5.识别验证码
      • 6.爬取APP
      • 7.爬虫框架
      • 8.分布式爬虫
由 GitBook 提供支持
在本页
  • 最小二乘法
  • 前提
  • 定义
  • 问题
  • 代码实现
  • 噪声为高斯分布的 MLE(极大似然估计)
  • 权重先验为高斯分布的 MAP
  • 正则化
  • 过拟合
  • L1 Lasso
  • L2 Ridge
  • L1与L2结合--ElasticNet回归

这有帮助吗?

在GitHub上编辑
  1. 人工智能
  2. 机器学习

线性回归

最小二乘法

前提

假设数据集D={(x1,y1),(x2,y2),⋯ ,(xN,yN)}\mathcal{D}=\{(x_1, y_1),(x_2, y_2),\cdots,(x_N, y_N)\}D={(x1​,y1​),(x2​,y2​),⋯,(xN​,yN​)},xi∈R,yi∈R,i=1,2,⋯ ,Nx_i\in\mathbb{R},y_i\in\mathbb{R},i=1,2,\cdots,Nxi​∈R,yi​∈R,i=1,2,⋯,N,记为:

X=(x1,x2,⋯ ,xN)T=[x1Tx2T⋮xNT]N×p=[x11x12⋯x1px21x22⋯x2p⋮⋮⋱⋮xN1xN2⋯xNp]N×p\begin{align} X&=(x_1,x_2,\cdots,x_N)^T \\ &= \begin{bmatrix} x_{1}^T \\x_{2}^T \\\vdots \\x_{N}^T \\ \end{bmatrix}_{N\times p} \\ & = \begin{bmatrix}x_{11} & x_{12} & \cdots & x_{1p} \\x_{21} & x_{22} & \cdots & x_{2p} \\ \vdots & \vdots & \ddots & \vdots \\x_{N1} & x_{N2} & \cdots & x_{Np} \\ \end{bmatrix}_{N\times p} \\ \end{align}X​=(x1​,x2​,⋯,xN​)T=​x1T​x2T​⋮xNT​​​N×p​=​x11​x21​⋮xN1​​x12​x22​⋮xN2​​⋯⋯⋱⋯​x1p​x2p​⋮xNp​​​N×p​​​
Y=(y1,y2,⋯ ,yN)T=[y1Ty2T⋮yNT]N×p=[y11y12⋯y1py21y22⋯y2p⋮⋮⋱⋮yN1yN2⋯yNp]N×p\begin{align} Y&=(y_1,y_2,\cdots,y_N)^T \\ &= \begin{bmatrix} y_{1}^T \\ y_{2}^T \\ \vdots \\ y_{N}^T \\ \end{bmatrix}_{N\times p} \\ & = \begin{bmatrix} y_{11} & y_{12} & \cdots & y_{1p} \\ y_{21} & y_{22} & \cdots & y_{2p} \\ \vdots & \vdots & \ddots & \vdots \\ y_{N1} & y_{N2} & \cdots & y_{Np} \\ \end{bmatrix}_{N\times p} \\ \end{align}Y​=(y1​,y2​,⋯,yN​)T=​y1T​y2T​⋮yNT​​​N×p​=​y11​y21​⋮yN1​​y12​y22​⋮yN2​​⋯⋯⋱⋯​y1p​y2p​⋮yNp​​​N×p​​​

线性回归假设:

f(w)=wTxf(w)=w^Txf(w)=wTx

构造数据

X=[xT,1]TX=[x^T,1]^TX=[xT,1]T,利用等式y=3x+2y=3x+2y=3x+2造些伪数据,并给xxx添加一些噪声数据,其中w=[3,2]Tw=[3,2]^Tw=[3,2]T,即X.dot(w)X.dot(w)X.dot(w)。

import numpy as np

"""
	构造数据
"""
X = np.linspace(0,100,100) # 生成100个样本数据
X = np.c_[X,np.ones(100)]
w = np.asarray([3,2])
Y = X.dot(w) # 矩阵点乘
X = X.astype('float')
Y = Y.astype('float')
X[:,0] += np.random.normal(size=(X[:,0].shape))*3 #添加噪声
Y = Y.reshape(Y.size,1)

xxx如图所示

XXX如图所示

绘制图形

import matplotlib.pyplot as plt

# 绘制(x,y)
plt.scatter(X[:,0],Y)
plt.plot(np.arange(0,100).reshape((100,1)),Y,'y.')
plt.xlabel("X")
plt.ylabel("Y")

如图:

Text(0, 0.5, 'Y')

定义

直接求闭式解

采用二范数定义的平方误差来定义损失函数:

lossfunction:L(w)=∑i=1N∣∣wTxi−yi∣∣22=∑i=1N(wTxi−yi)2=(wTx1−y1,⋯ ,wTxN−yN)⋅(wTx1−y1,⋯ ,wTxN−yN)T=(wTXT−YT)⋅(Xw−Y)=wTXTXw−YTXw−wTXTY+YTY=wTXTXw−2wTXTY+YTY\begin{align} loss function: L(w)&=\sum\limits_{i=1}^N||w^Tx_i-y_i||^2_2 \\ & = \sum\limits_{i=1}^N(w^Tx_i-y_i)^2 \\ &=(w^Tx_1-y_1,\cdots,w^Tx_N-y_N)\cdot (w^Tx_1-y_1,\cdots,w^Tx_N-y_N)^T\nonumber \\ &=(w^TX^T-Y^T)\cdot (Xw-Y) \\ &=w^TX^TXw-Y^TXw-w^TX^TY+Y^TY\nonumber \\ &=w^TX^TXw-2w^TX^TY+Y^TY \end{align}lossfunction:L(w)​=i=1∑N​∣∣wTxi​−yi​∣∣22​=i=1∑N​(wTxi​−yi​)2=(wTx1​−y1​,⋯,wTxN​−yN​)⋅(wTx1​−y1​,⋯,wTxN​−yN​)T=(wTXT−YT)⋅(Xw−Y)=wTXTXw−YTXw−wTXTY+YTY=wTXTXw−2wTXTY+YTY​​

(wTxi−yi)2=(Y−Xw)T(Y−Xw)(w^Tx_i-y_i)^2=(Y−Xw)^T(Y−Xw)(wTxi​−yi​)2=(Y−Xw)T(Y−Xw)

最小化值w^ \hat{w}w^ ,,进行求导:

w^=argminwL(w)⟶∂∂wL(w)=0⟶2XTXw^−2XTY=0⟶w^=(XTX)−1XTY=X+Y\begin{align} \hat{w}=\mathop{argmin}\limits_wL(w)&\longrightarrow\frac{\partial}{\partial w}L(w)=0\nonumber\\ &\longrightarrow2X^TX\hat{w}-2X^TY=0\nonumber\\ &\longrightarrow \hat{w}=(X^TX)^{-1}X^TY=X^+Y \end{align}w^=wargmin​L(w)​⟶∂w∂​L(w)=0⟶2XTXw^−2XTY=0⟶w^=(XTX)−1XTY=X+Y​​

(XTX)−1XT(X^TX)^{-1}X^T(XTX)−1XT记为X+X^+X+(伪逆)

这个式子中 (XTX)−1XT(X^TX)^{-1}X^T(XTX)−1XT 又被称为伪逆。对于行满秩或者列满秩的 XXX,可以直接求解,但是对于非满秩的样本集合,需要使用奇异值分解(SVD)的方法,对 XXX 求奇异值分解,得到:

X=UΣVTX=U\Sigma V^TX=UΣVT

于是:

X+=VΣ−1UTX^+=V\Sigma^{-1}U^TX+=VΣ−1UT

在几何上,最小二乘法相当于模型(这里就是直线)和试验值的距离的平方求和,假设我们的试验样本张成一个 $p$ 维空间(满秩的情况):X=Span(x1,⋯ ,xN)X=Span(x_1,\cdots,x_N)X=Span(x1​,⋯,xN​),而模型可以写成 f(w)=wTx=XTβf(w)=w^Tx=X^T\betaf(w)=wTx=XTβ,反过来看,也就是 x1,⋯ ,xNx_1,\cdots,x_Nx1​,⋯,xN​ 的某种组合,而最小二乘法就是说希望 YYY 和这个模型距离越小越好,于是它们的差应该与这个张成的空间垂直:

XT⋅(Y−Xβ)=0⟶β=(XTX)−1XTYX^T\cdot(Y-X\beta)=0\longrightarrow\beta=(X^TX)^{-1}X^TYXT⋅(Y−Xβ)=0⟶β=(XTX)−1XTY

提示:a⃗⊥b⃗=>aT⋅b=0\vec a \perp\vec b => a^T \cdot b = 0a⊥b=>aT⋅b=0

通过伪逆求解到的结果有如下优点:

(1)当www有解时,w=X+Yw=X^+Y w=X+Y是所有解中欧几里得距离∣∣w∣∣2||w||^2∣∣w∣∣2最小的一个;

(2)当www无解时,通过伪逆得到的www是使得XwXwXw与YY Y的欧几里得距离(wTxi−yi)2(w^Tx_i-y_i)^2 (wTxi​−yi​)2最小

  • 求逆

# np.linalg.inv(X) <==> np.matrix(X).I
  • 求伪逆

np.linalg.pinv(X)

XXX数据如图所示,

YYY数据如图所示,

求出参数www结果为:

np.linalg.inv(X.T.dot(X)).dot(X.T).dot(Y)

求出Y1Y1Y1​为:

w = np.linalg.inv(X.T.dot(X)).dot(X.T).dot(Y)
Y1 = X.dot(w)
Y1[:15]

绘图:

# 绘制(x,y)
plt.scatter(X[:,0],Y)
plt.plot(X[:,0],Y1,'y')
plt.xlabel("X")
plt.ylabel("Y")

梯度下降求解

随机梯度下降法

但对于数据量很大的情况,求闭式解的方式会让内存很吃力,我们可以通过随机梯度下降法(SGD)对www进行更新,首先随机初始化www,然后使用如下的迭代公式对www进行迭代更新:

w:=w−ηdLdw,其中η参数取值一般很小,比如0.0001w:=w-\eta \frac{dL}{dw},其中\eta 参数取值一般很小,比如0.0001w:=w−ηdwdL​,其中η参数取值一般很小,比如0.0001

其中dLdw=2XTXw^−2XTY=2XT(Xw^−Y)(1)\frac{dL}{dw}=2X^TX\hat{w}-2X^TY=2X^T(X\hat{w}-Y) (1)dwdL​=2XTXw^−2XTY=2XT(Xw^−Y)(1),(wTxi−yi)2=(Y−Xw)T(Y−Xw)(2) (w^Tx_i-y_i)^2=(Y−Xw)^T(Y−Xw) (2)(wTxi​−yi​)2=(Y−Xw)T(Y−Xw)(2)

# 初始化
w = np.random.random(size=(2,1))
# 迭代次数
epoches = 100
# eta参数
eta = 0.0000001

#记录loss变化(损失)
losses = []
for e in range(epoches):
    nw = 2*X.T.dot(X.dot(w)-Y) #(1)
    w = w - eta*nw
    # reshape(-1):变成一维数组
    losses.append((Y-X.dot(w)).T.dot(Y-X.dot(w)).reshape(-1)) # (2)
w

参数η\etaη以及迭代次数,不要设置太低或者太高,可能会使loss变化达不到预期目标

求出www结果为:

可视化:

loss变化:

plt.plot(losses)
plt.xlabel("iterations")
plt.ylabel("loss")

小批量梯度下降法

问题

在上面的梯度下降的例子中存在一个问题,w1w1w1基本能收敛到3附近,而w2w2w2却基本在0附近,很难收敛到2,说明w1比w2w1比w2w1比w2更容易收敛(w=[w1,w2]Tw=[w1,w2]^Tw=[w1,w2]T),这很容易理解,模型可以写作:f(x)=x∗w1+1⋅w2f(x)=x∗w1+1⋅w2f(x)=x∗w1+1⋅w2,如果xxx量纲比1大很多,为了使f(x) f(x)f(x)变化,只需更新少量的w1w1w1就能达到目的,而w2w2w2的更新动力略显不足;可以考虑用如下方式:

(1)对输入XX X进行归一化,使得x无量纲,w1,w2w1,w2 w1,w2的更新动力一样(后面封装代码时添加上),如下图;

代码实现

from sklearn.linear_model import LinearRegression

lr = LinearRegression()
lr.fit(X[:,:-1],Y) #训练数据
predict = lr.predict(X[:,:-1])
#查看w系数,b常量
print('w:',lr.coef_,'b:',lr.intercept_)
#查看标准差
np.std(Y-predict)

假设函数为y=wx+ϵy=wx+\epsilon y=wx+ϵ,

  • lr.coef_:为ww w,即系数

  • lr.intercept_:为ϵ\epsilon ϵ,即常量

噪声为高斯分布的 MLE(极大似然估计)

对于一维的情况,记 y=wTx+ϵ,ϵ∼N(0,σ2)y=w^Tx+\epsilon,\epsilon\sim\mathcal{N}(0,\sigma^2)y=wTx+ϵ,ϵ∼N(0,σ2),那么 y∼N(wTx,σ2)y\sim\mathcal{N}(w^Tx,\sigma^2) y∼N(wTx,σ2)。代入极大似然估计中:

其中正态分布函数的概率密度为p(y∣xiw)=12πσe−(yi−wTxi)22σ2p(y|x_iw)=\frac{1}{\sqrt{2\pi}\sigma}e^{-\frac{(y_i-w^Tx_i)^2}{2\sigma^2}}p(y∣xi​w)=2π​σ1​e−2σ2(yi​−wTxi​)2​

L(w)=log⁡p(Y∣X,w)=log⁡∏i=1Np(yi∣xi,w)=∑i=1Nlog⁡(12πσe−(yi−wTxi)22σ2)=∑i=1N(log⁡12πσ+log⁡e−(yi−wTxi)22σ2)=∑i=1N(log⁡12πσ−(yi−wTxi)22σ2)argmaxwL(w)=argmaxw∑i=1N−12σ2(yi−wTxi)2=argminw∑i=1N(yi−wTxi)2(进而转化为求最小)\begin{align} L(w)=\log p(Y|X,w)&=\log\prod\limits_{i=1}^Np(y_i|x_i,w)\nonumber\\ &=\sum\limits_{i=1}^N\log(\frac{1}{\sqrt{2\pi}\sigma}e^{-\frac{(y_i-w^Tx_i)^2}{2\sigma^2}})\\ &=\sum\limits_{i=1}^N\big ( \log\frac{1}{\sqrt{2\pi}\sigma}+\log e^{-\frac{(y_i-w^Tx_i)^2}{2\sigma^2}} \big )\\ &=\sum\limits_{i=1}^N \big ( \log\frac{1}{\sqrt{2\pi}\sigma}- \frac{(y_i-w^Tx_i)^2}{2\sigma^2} \big )\\ \mathop{argmax}\limits_wL(w) &=\mathop{argmax}\limits_w\sum \limits_{i=1}^N -\frac 1{2\sigma^2} (y_i-w^Tx_i)^2\\ &=\mathop{argmin}\limits_w\sum\limits_{i=1}^N (y_i-w^Tx_i)^2 (进而转化为求最小) \end{align}L(w)=logp(Y∣X,w)wargmax​L(w)​=logi=1∏N​p(yi​∣xi​,w)=i=1∑N​log(2π​σ1​e−2σ2(yi​−wTxi​)2​)=i=1∑N​(log2π​σ1​+loge−2σ2(yi​−wTxi​)2​)=i=1∑N​(log2π​σ1​−2σ2(yi​−wTxi​)2​)=wargmax​i=1∑N​−2σ21​(yi​−wTxi​)2=wargmin​i=1∑N​(yi​−wTxi​)2(进而转化为求最小)​​

LSE(最小二乘估计)<==> MLE(极大似然估计),其中噪声为高斯分布

(正则化)Regularized LSE <==> MAP,其中噪声为高斯分布

权重先验为高斯分布的 MAP

取先验分布 w∼N(0,σ02)w\sim\mathcal{N}(0,\sigma_0^2)w∼N(0,σ02​)。于是:

概率密度为p(w)=12πσe−w22σ02p(w)=\frac{1}{\sqrt{2\pi\sigma}}e^{-\frac{w^2}{2\sigma_0^2}}p(w)=2πσ​1​e−2σ02​w2​,p(y∣w)=12πσe−(y−wTx)22σ2p(y|w)=\frac{1}{\sqrt{2\pi\sigma}}e^{-\frac{(y-w^Tx)^2}{2\sigma^2}}p(y∣w)=2πσ​1​e−2σ2(y−wTx)2​。

有p(y∣w)⋅p(w)=12πσ0⋅12πσ⋅e−(y−wTx)22σ2⋅e−∣∣w∣∣22σ2p(y|w) \cdot p(w) =\frac{1}{\sqrt{2\pi}\sigma_0}\cdot \frac{1}{\sqrt{2\pi}\sigma} \cdot e^{-\frac{(y-w^Tx)^2}{2\sigma^2}} \cdot e^{-\frac{||w||^2}{2\sigma^2}}p(y∣w)⋅p(w)=2π​σ0​1​⋅2π​σ1​⋅e−2σ2(y−wTx)2​⋅e−2σ2∣∣w∣∣2​

w^=argmaxwp(w∣y)=argmaxwp(y∣w)p(w)=argmaxwlog⁡p(y∣w)p(w)=argmaxw(log⁡p(y∣w)+log⁡p(w))=argminw[(y−wTx)22σ2+∣∣w∣∣22σ02]=argminw[(y−wTx)2+σ2σ02wTw]\begin{align} \hat{w}&=\mathop{argmax}\limits_wp(w|y) \\ &=\mathop{argmax}\limits_wp(y|w)p(w)\nonumber\\ &=\mathop{argmax}\limits_w\log p(y|w)p(w)\nonumber\\ &=\mathop{argmax}\limits_w(\log p(y|w)+\log p(w))\nonumber\\ &=\mathop{argmin}\limits_w[\frac {(y-w^Tx)^2} {2\sigma^2} +\frac {||w||^2} {2\sigma_0^2}] \\ &=\mathop{argmin}\limits_w[(y-w^Tx)^2+\frac{\sigma^2}{\sigma_0^2}w^Tw]\\ \end{align}w^​=wargmax​p(w∣y)=wargmax​p(y∣w)p(w)=wargmax​logp(y∣w)p(w)=wargmax​(logp(y∣w)+logp(w))=wargmin​[2σ2(y−wTx)2​+2σ02​∣∣w∣∣2​]=wargmin​[(y−wTx)2+σ02​σ2​wTw]​​

这里省略了 $X$,$p(Y)$和 $w$ 没有关系,同时也利用了上面高斯分布的 MLE的结果。

将会看到,超参数 $\sigma_0$的存在和下面会介绍的 Ridge 正则项可以对应,同样的如果将先验分布取为 Laplace 分布,那么就会得到和 L1 正则类似的结果。

正则化

过拟合

演示

  • 伪造数据

import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline

#造伪样本
X=np.linspace(0,100,100)
X=np.c_[X,np.ones(100)]
w=np.asarray([3,2])
Y=X.dot(w)
X=X.astype('float')
Y=Y.astype('float')
X[:,0]+=np.random.normal(size=(X[:,0].shape))*3#添加噪声
Y=Y.reshape(100,1) # 一维数组转变为二维矩阵
  • 拟合数据并可视化

#拟合数据并可视化
w = np.linalg.inv(X.T.dot(X)).dot(X.T).dot(Y)
Y1 = X.dot(w)
# 绘制(x,y)
plt.scatter(X[:,0],Y)
plt.plot(X[:,0],Y1,'y')
plt.xlabel("X")
plt.ylabel("Y")
# 初始化
w = np.random.random(size=(2,1))
# 迭代次数
epoches = 100
# eta参数
eta = 0.0000001

#记录loss变化(损失)
losses = []
for e in range(epoches):
    nw = 2*X.T.dot(X.dot(w)-Y) #(1)
    w = w - eta*nw
    # reshape(-1):变成一维数组
    losses.append((Y-X.dot(w)).T.dot(Y-X.dot(w)).reshape(-1)) # (2)

plt.plot(losses)
  • 加入几个异常点

# np.concatenate(x,y)将x和y两个矩阵垂直拼接在一起
X=np.concatenate([X,np.array([[100,1],[101,1],[102,1],[103,1],[104,1]])])
Y=np.concatenate([Y,np.array([[3000],[3300],[3600],[3800],[3900]])])

#拟合数据并可视化
w = np.linalg.inv(X.T.dot(X)).dot(X.T).dot(Y)
Y1 = X.dot(w)
# 绘制(x,y)
plt.scatter(X[:,0],Y)
plt.plot(X[:,0],Y1,'y')
plt.xlabel("X")
plt.ylabel("Y")

因此在实际应用时,如果样本容量不远远大于样本的特征维度,很可能造成过拟合,对这种情况,有下面三个解决方式:

  1. 加数据

  2. 特征选择/特征提取(降低特征维度)如 PCA 算法。

  3. 正则化

正则化一般是在损失函数(如上面介绍的最小二乘损失)上加入正则化项(表示模型的复杂度对模型的惩罚),下面我们介绍一般情况下的两种正则化框架。

(lassoregression)L1:argminwL(w)+λ∣∣w∣∣1,λ>0(ridgeregression/岭回归/权值衰减)L2:argminwL(w)+λ∣∣w∣∣22,λ>0\begin{align} (lasso \quad regression) \quad L1&:\mathop{argmin}\limits_wL(w)+\lambda||w||_1,\lambda\gt0\\ (ridge \quad regression/岭回归/权值衰减) \quad L2&:\mathop{argmin}\limits_wL(w)+\lambda||w||^2_2,\lambda \gt 0 \end{align}(lassoregression)L1(ridgeregression/岭回归/权值衰减)L2​:wargmin​L(w)+λ∣∣w∣∣1​,λ>0:wargmin​L(w)+λ∣∣w∣∣22​,λ>0​​

∣∣w∣∣2=wT⋅w||w||^2 = w^T \cdot w∣∣w∣∣2=wT⋅w


$\text{当}||w|| = |w_1| + |w_2| + ··· + |w_n| \text{,称之为L1正则化}$。

当∣∣w∣∣=w12+w22+⋅⋅⋅+wn2\text{当}||w|| = w_1^2 + w_2^2 + ··· + w_n^2当∣∣w∣∣=w12​+w22​+⋅⋅⋅+wn2​。

这里∣∣w∣∣||w||∣∣w∣∣也被称为惩罚因子,那么,为什么加上惩罚因子之后,就能避免过拟合呢?


L1 Lasso

L1正则化可以引起稀疏解。

从最小化损失的角度看,由于 L1 项求导在0附近的左右导数都不是0,因此更容易取到0解。

从另一个方面看,L1 正则化相当于:

argminwL(w)s.t.∣∣w∣∣1<Cw^=(XTX)−1(XTY−λI2)(后面会用这个)\mathop{argmin}\limits_wL(w)\\ s.t. ||w||_1\lt C\\ \hat{w}=(X^TX)^{-1}(X^TY-\frac{\lambda I}2)(后面会用这个)wargmin​L(w)s.t.∣∣w∣∣1​<Cw^=(XTX)−1(XTY−2λI​)(后面会用这个)

我们已经看到平方误差损失函数在 $w$ 空间是一个椭球,因此上式求解就是椭球和 $||w||_1=C$的切点,因此更容易相切在坐标轴上。

下面分别对LASSO的cost function的两部分求解:

  1. RSSRSSRSS部分

RSS(w)=∑i=1m(wTxi−yi)2=∑i=1m(∑j=1nxijwj−yi)2\begin{align} RSS(w) &= \sum_{i=1}^m(w^Tx_i-y_i)^2 \\ &= \sum_{i=1}^m(\sum_{j=1}^n{x_{ij}w_j}-y_i)^2 \end{align}RSS(w)​=i=1∑m​(wTxi​−yi​)2=i=1∑m​(j=1∑n​xij​wj​−yi​)2​​

求导:

(对wk进行求导,wi≠k为常数)(对w_k进行求导,w_{i≠k}为常数)(对wk​进行求导,wi=k​为常数)

∂∂wkRSS(w)=2∑i=1mxik(∑j=1nxijwj−yi)=2∑i=1m(xik∑j=1nxijwj−yixik)=2∑i=1m(xik∑j=1,j≠knxijwj+xik2wk−yixik)=2∑i=1mxik(∑j=1,j≠knxijwj−yi)+2wk∑i=1mxik2\begin{align} \frac{\partial}{\partial w_k}RSS(w) &= 2\sum_{i=1}^m{x_{ik}}(\sum_{j=1}^nx_{ij}w_j-y_i) \\ &= 2\sum_{i=1}^m(x_{ik}\sum_{j=1}^nx_{ij}w_j-y_ix_{ik}) \\ &=2\sum_{i=1}^m(x_{ik}\sum_{j=1,j≠k}^nx_{ij}w_j+x_{ik}^2w_k-y_ix_{ik}) \\ &=2\sum_{i=1}^mx_{ik}(\sum_{j=1,j≠k}^nx_{ij}w_j-y_i)+2w_k\sum_{i=1}^m x_{ik}^2 \\ \end{align}∂wk​∂​RSS(w)​=2i=1∑m​xik​(j=1∑n​xij​wj​−yi​)=2i=1∑m​(xik​j=1∑n​xij​wj​−yi​xik​)=2i=1∑m​(xik​j=1,j=k∑n​xij​wj​+xik2​wk​−yi​xik​)=2i=1∑m​xik​(j=1,j=k∑n​xij​wj​−yi​)+2wk​i=1∑m​xik2​​​
令pk=∑i=1mxik(yi−∑j=1,j≠knxijwj),zk=∑i=1mxik2令p_k=\sum_{i=1}^mx_{ik}(y_i-\sum_{j=1,j≠k}^nx_{ij}w_j),z_k=\sum_{i=1}^m x_{ik}^2令pk​=i=1∑m​xik​(yi​−j=1,j=k∑n​xij​wj​),zk​=i=1∑m​xik2​

有,

∂∂wkRSS(w)=−2pk+2zkwk\begin{align} \frac{\partial}{\partial w_k}RSS(w) &= -2p_k+2z_kw_k \end{align}∂wk​∂​RSS(w)​=−2pk​+2zk​wk​​​
  1. 惩罚项的求导

\begin{align} \lambda \frac{\partial \sum_{i=1}^n|w_i| }{\partial w_k} &= \left\{ \begin{array}{**lr**} -\lambda, & w_k<0\\ [-\lambda,\lambda], & w_k=0\\ \lambda, & w_k>0\\ \end{array} \right. \end{align}

进行整体的求导可得:

\begin{align} \frac{\partial}{\partial w_k}L(w) &=\frac{\partial}{\partial w_k}RSS(w) +\lambda \frac{\partial \sum_{i=1}^n|w_i| }{\partial w_k}\\ &= 2z_kw_k-2p_k+ \left\{ \begin{array}{**lr**} -\lambda, & w_k<0\\ [-\lambda,\lambda], & w_k=0\\ \lambda, & w_k>0\\ \end{array} \right. \\ &= \left\{ \begin{array}{**lr**} 2z_kw_k-2p_k-\lambda, & w_k<0\\ [-2p_k-\lambda,-2p_k+\lambda], & w_k=0\\ 2z_kw_k-2p_k+\lambda, & w_k>0\\ \end{array} \right. \\ & = 0 \end{align}

得到:

\begin{align} \hat{w_k} &= \left\{ \begin{array}{**lr**} (\lambda/2+p_k)/z_k, & p_k<-\lambda/2,\\ 0, & -\lambda/2 \leq p_k \leq \lambda/2\\ (p_k-\lambda/2)/z_k, & p_k>\lambda/2\\ \end{array} \right. \\ 其中,p_k&=\sum_{i=1}^mx_{ik}(y_i-\sum_{j=1,j≠k}^nx_{ij}w_j),z_k=\sum_{i=1}^m x_{ik}^2,\\& (w^Tx_i-y_i)^2=(Y−Xw)^T(Y−Xw) \end{align}

手动实现代码

  • 利用公式(1)直接求解w

import numpy as np
import matplotlib.pyplot as plt

# 计算残差
def RSS(X,y,w):
     return (Y-X.dot(w)).T.dot(Y-X.dot(w))

#造伪样本
X=np.linspace(0,100,100)
X=np.c_[X,np.ones(100)]
w=np.asarray([3,2])
print(w)
Y=X.dot(w)
X=X.astype('float')
Y=Y.astype('float')
X[:,0]+=np.random.normal(size=(X[:,0].shape))*3#添加噪声
Y=Y.reshape(Y.shape[0],1) # 一维数组转变为二维矩阵

# np.concatenate(x,y)将x和y两个矩阵垂直拼接在一起
X=np.concatenate([X,np.array([[100,1],[101,1],[102,1],[103,1],[104,1]])])
Y=np.concatenate([Y,np.array([[3000],[3300],[3600],[3800],[3900]])])
#拟合数据并可视化

lam = 1000000
i = np.eye(X.shape[1])
w = np.linalg.pinv(X.T.dot(X)).dot((X.T.dot(Y))-(lam*i)/2)
Y1=X.dot(w[:,0])
plt.scatter(X[:,:-1],Y)
plt.plot(X[:,:-1],Y1)
  • 利用公式(2)直接求解w

import numpy as np
import matplotlib.pyplot as plt

# 计算残差
def RSS(X,y,w):
     return (Y-X.dot(w)).T.dot(Y-X.dot(w))

#造伪样本
X=np.linspace(0,100,100)
X=np.c_[X,np.ones(100)]
w=np.asarray([3,2])
print(w)
Y=X.dot(w)
X=X.astype('float')
Y=Y.astype('float')
X[:,0]+=np.random.normal(size=(X[:,0].shape))*3#添加噪声
Y=Y.reshape(Y.shape[0],1) # 一维数组转变为二维矩阵

# np.concatenate(x,y)将x和y两个矩阵垂直拼接在一起
X=np.concatenate([X,np.array([[100,1],[101,1],[102,1],[103,1],[104,1]])])
Y=np.concatenate([Y,np.array([[3000],[3300],[3600],[3800],[3900]])])
#拟合数据并可视化
m,n = X.shape
lambda_params = 100

z = [0 for i in range(n)]
p = [0 for i in range(n)]
w = np.eye(n,1)

for k in range(n):
    z[k] = np.sum(X[:,k]*X[:,k],axis=0)
    p[k] = np.sum([X[i,k]* (Y[i]-np.sum([X[i,j]*w[j] for j in range(n)])) for i in range(m)],axis=0)
    if p[k] > lambda_params/2:
        w_k = (p[k]-lambda_params/2) / z[k]
    elif p[k] < -lambda_params/2:
        w_k = (lambda_params/2+p[k]) / z[k]
    else:
        w_k = 0
    w[k] = w_k
y = X.dot(w)
plt.scatter(X[:,:-1],Y)
plt.plot(X[:,:-1],y)
w

使用sklearn

from sklearn.linear_model import Lasso
from sklearn.preprocessing import StandardScaler

# 特征值和目标值是都必须进行标准化处理, 实例化两个标准化API
std_x = StandardScaler()
std_y = StandardScaler()
X = std_x.fit_transform(X)
Y = std_y.fit_transform(Y.reshape(-1,1))

lasso = Lasso()
lasso.fit(X[:,:-1],Y)
predict = lasso.predict(X[:,:-1])
plt.plot(X[:,:-1],predict)
plt.scatter(X[:,:-1],Y)

L2 Ridge

s.t.∣∣w∣∣22<Cs.t. ||w||_2^2\lt C\\s.t.∣∣w∣∣22​<C
w^=argminwL(w)+λwTw⟶∂∂wL(w)+2λw=0⟶2XTXw^−2XTY+2λw^=0⟶w^=(XTX+λI)−1XTY\begin{align} \hat{w}=\mathop{argmin}\limits_wL(w)+\lambda w^Tw&\longrightarrow\frac{\partial}{\partial w}L(w)+2\lambda w=0\nonumber\\ &\longrightarrow2X^TX\hat{w}-2X^TY+2\lambda \hat w=0\nonumber\\ &\longrightarrow \hat{w}=(X^TX+\lambda \mathbb{I})^{-1}X^TY \end{align}w^=wargmin​L(w)+λwTw​⟶∂w∂​L(w)+2λw=0⟶2XTXw^−2XTY+2λw^=0⟶w^=(XTX+λI)−1XTY​​

可以看到,这个正则化参数和前面的 MAP 结果不谋而合。利用2范数进行正则化不仅可以是模型选择 www 较小的参数,同时也避免 XTX X^TXXTX不可逆的问题。

I是一个单位矩阵\mathbb{I}是一个单位矩阵I是一个单位矩阵

定义符号函数并进行向量化,用于对L1正则化项的梯度计算:

手动实现代码

alpha = 100.0

w = np.linalg.pinv(
  X.T.dot(X)+alpha*np.eye(X.T.dot(X).shape[0])
).dot(X.T.dot(Y))
y = X.dot(w)
plt.scatter(X[:,:-1],Y)
plt.plot(X[:,:-1],y)

使用sklearn

from sklearn.linear_model import Ridge
from sklearn.preprocessing import StandardScaler

std_x = StandardScaler()
std_y = StandardScaler()
X2 = std_x.fit_transform(X)
Y2 = std_y.fit_transform(Y.reshape(-1,1))

ridge = Ridge(alpha=100)
ridge.fit(X2[:,:-1],Y2)
predict = ridge.predict(X2[:,:-1])
plt.plot(X2[:,:-1],predict)
plt.scatter(X2[:,:-1],Y2)

L1与L2结合--ElasticNet回归

from sklearn.linear_model import ElasticNet

std_x = StandardScaler()
std_y = StandardScaler()
X3 = std_x.fit_transform(X)
Y3 = std_y.fit_transform(Y.reshape(-1,1))

lasso = ElasticNet()
lasso.fit(X3[:,:-1],Y3)
predict = lasso.predict(X3[:,:-1])
plt.plot(X3[:,:-1],predict)
plt.scatter(X3[:,:-1],Y3)
  1. 当岭参数λ=0\lambda=0λ=0时,得到的解是最小二乘解。

  2. 当岭参数 λ\lambdaλ 趋向更大时,岭回归系数 wiw_iwi​ 趋向于0,约束项 ttt 很小。

上一页线性分类下一页信息论中的熵

最后更新于3年前

这有帮助吗?

image-20200907012354184
image-20200907012518791
img
image-20200906231454458
image-20200907020120635
image-20200907020130512
image-20200907020311234
image-20200907020513426
img
image-20200907022959395
img
img
avatar

(2)梯度更新时,w1,w2使用了一样的学习率,可以让w1,w2使用不一样的学习率进行更新,比如对w2使用更大的学习率进行更新(可以利用学习率自适应一类的梯度下降法,比如adam),如下图:

image-20200907030158945
img
img
img
拟合
img
img
img
img
img
img
avatar