线性回归

模型

自变量x和因变量y为线性关系。
x:数据点集合,y:目标值,(x, y):一个训练样本。

y=ax+b+e

e 为误差,这里假设服从均值0的正态分布。
机器学习中,一般描述为
hθ(x)=θ0+θ1x1++θnxn

假设函数:
hθ(x)=k=0nθkxk=θTx

x 是向量。矩阵表示
X=1,1,1,x11,x21,xm1,x12x22,xm2,,,,x1nx2nxmnΘ=θ0θ1θn

其中, xjijimn

已知训练集 x=(x0,x1,,xn) 估计 θ ,MSE为点估计的一种评价标准。
注:已假定e服从正态分布,MSE也就自然了。比如SAE绝对差和,无法给出可解的优化问题。

代价函数(可以通过最大似然估计推导出):

J(θ)=12mk=1m(hθ(xk)yk)2

目的,寻找最小化 J(θ) θ ,几何意义上,就是试图找一条直线,使所有样本与直线的欧式距离之和最小。
θ=argmin(J(θ))

策略及算法

最小二乘

zTz=iz2i

J(θ)=12m(XΘy)T(XΘy)

正规方程组

XTX 为满秩矩阵或小样本少特征情况下:

L(Θ)=12(XΘy)T(XΘy)=12[ΘTXTXΘΘTxTyyTXΘ+yTy]=12[ΘTXTXΘ2ΘTxTy+yTy]

这里
   L(Θ)Θ=0L(Θ)Θ=12(XTXΘ+XTXΘ2XTy)=0XTXΘ=XTyΘ=(XTX)1XTy

梯度下降法

迭代逼近,一般采用批量下降,为了减少收敛至局部最优解的概率,随机初始化多次,从中选择最优解。

迭代规则:

θi:=θiαJ(θ)θi

其中, α 为学习速率,值过小会导致迭代收敛慢,值过大会导致徘徊在最优解附近无法收敛。
J(θ)θi=θi12(hθ(x)y)2=(hθ(x)y)θi(hθ(x)y)=(hθ(x)y)θik=0mθkxk=(hθ(x)y)xi

迭代规则:
θi:=θiαk=0m(hθ(xkyk)xki

随机梯度下降法:更新参数时,不必遍历所有样本,随机选择一个就可以。
θi:=θiα(hθ(xkyk)xki

梯度下降中,由于样本分布不同,可能会遇到局部最小值点、鞍点、下降速度过慢、跳过最小值点等问题。

过拟合

模型泛化能力差,高方差。

来自网络的图片,很形象:

一般由于:

  • 训练集和测试集特征分布不一致
  • 样本和特征数量不匹配,模型复杂

解决办法:

  • 合理化样本和特征数量(比如相应减少特征或增加样本)
  • 交叉验证
  • 正则化

正则化

L1_normal(lasso、L1正则化),使用L1_normal的建模称为lasso(least absolute shrinkage and selection operator)回归

J(θ)=12m(XΘy)T(XΘy)+λΘ1

L2_normal(ridge、L2正则化),使用L2_normal的建模称为ridge(岭)回归
J(θ)=12m(XΘy)T(XΘy)+λΘ22

一些解释:

  • L1、L2都是一种通过对权值向量引入额外约束以避免产生过拟合的方法。

  • L1产生稀疏权值矩阵,某些权值项为0,挑选样本特征,降低模型复杂度。

  • L2 减小某些权值的影响,降低模型复杂度。

矩阵解释:

  • Θ 为非奇异矩阵时,矩阵可逆,代价函数有唯一解。如果其为近似奇异矩阵时,微小的样本变化都可能导致模型巨大的变化,模型泛化能力差。

  • 增强矩阵求逆数值稳定性,可在方阵 XTX 的主对角线上增加 λ

    Θ^=(XTX+λI)1XTy

    L2的求解刚好能获取上面公式。

关于 λ 选择

  • λ 越大,对参数修正越明显,模型相对简单

  • 一般通过交叉验证获取

  • 这是一个bias-var-tradeoff 偏差、方差权衡的问题

code

# -*- coding:utf-8 -*-  

import numpy as np  
from sklearn.linear_model import LinearRegression, RidgeCV, LassoCV
from sklearn.preprocessing import PolynomialFeatures  
import matplotlib.pyplot as plt  
from sklearn.pipeline import Pipeline  
import matplotlib as mpl  
import warnings  

if __name__ == "__main__":  
    warnings.filterwarnings("ignore")

    np.random.seed(0)

    ORDER = 8
    N = 10
    x = np.linspace(0, 6, N) + np.random.randn(N)  
    x = np.sort(x)

    y = 1.2 * x**2 - 3.1*x - 3 + np.random.randn(N)
    x = x.reshape(-1, 1)
    y = y.reshape(-1, 1)

    models = [
        Pipeline([('poly', PolynomialFeatures()), ('linear',                LinearRegression(fit_intercept=False))]),
        Pipeline([('poly', PolynomialFeatures()), ('linear', RidgeCV(alphas=np.logspace(-3, 2, 50), fit_intercept=False))]),  
        Pipeline([('poly', PolynomialFeatures()), ('linear', LassoCV(alphas=np.logspace(-3, 2, 50), fit_intercept=False))]),  
    ]

    mpl.rcParams['font.sans-serif'] = [u'simHei']  
    mpl.rcParams['axes.unicode_minus'] = False  
    np.set_printoptions(suppress=True)

    plt.figure(figsize=(18, 12), facecolor='w')  
    d_pool = np.arange(1, ORDER, 2)
    m = d_pool.size
    clrs = []

    for c in np.linspace(255, 16711680, m):
        clrs.append('#%06x' % np.int32(c))

    print(clrs)

    line_width = np.linspace(5, 2, m)

    titles = [u'线性回归', u'Ridge回归', u'LASSO']

    for t in range(3):
        model = models[t]

        plt.subplot(2, 2, t+1)  
        plt.plot(x, y, 'ro', ms=10, zorder=ORDER)

        for i, d in enumerate(d_pool):
            model.set_params(poly__degree=d)  
            model.fit(x, y.flatten())

            lin = model.get_params('linear')['linear']

            x_hat = np.linspace(x.min(), x.max(), num=100)  
            x_hat.shape = -1, 1  
            y_hat = model.predict(x_hat)  
            s = model.score(x, y)

            z = ORDER - 1 if (d == 2) else 0  
            label = u'%d阶,$R^2$=%.3f' % (d, s)  
            if hasattr(lin, 'l1_ratio_'):  
                label += u',L1 ratio=%.2f' % lin.l1_ratio_

            plt.plot(x_hat, y_hat, color=clrs[i], lw=line_width[i], alpha=0.75, label=label, zorder=z)

        plt.legend(loc='upper left')  
        plt.grid(True)  
        plt.title(titles[t], fontsize=18)  
        plt.xlabel('X', fontsize=16)  
        plt.ylabel('Y', fontsize=16)

    plt.tight_layout(1, rect=(0, 0, 1, 0.95))  
    plt.suptitle(u'多项式曲线拟合比较', fontsize=22)  
    plt.show()

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值