吴恩达机器学习作业5:Regularized Linear Regression and Bias v.s. Variance python实现

一、总结

所谓偏差和方差,可以用打靶来作为比喻。
偏差可以用来衡量打中的位置距离靶心的距离(精确度)
方差可以用来衡量打中位置的集中程度(若分散则方差比较大)

偏差大表现为拟合曲线与实际样本不符。
方差大表现为拟合曲线与实际样本过于贴合,当出现新增样本的时候,与其不符合。

二、python实现

1、代价函数和梯度下降

使用的预测模型为线性模型,在前面的练习已经写过,直接上代码:

梯度下降:(注意返回的梯度下降为一维,用flatten函数处理)

import numpy as np


def gradient(theta, x, y, mylamda):

    m = len(theta)
    theta = np.array(theta).reshape([m, 1])

    m = x.shape[0]
    one = np.ones([m, 1])
    x = np.hstack([one, x])

    hx = np.dot(x, theta)
    grad = np.dot(x.T, hx - y) / m
    grad[1:, 0] = grad[1:, 0] + (mylamda / m) * theta[1:, 0]

    return grad.flatten()

代价函数:

import numpy as np


def costfunction(theta, x, y, mylambda):

    m = np.size(theta)
    theta = np.array(theta).reshape([m, 1])

    m = x.shape[0]
    one = np.ones([m, 1])
    x = np.hstack([one, x])
    hx = np.dot(x, theta)
    cost1 = np.sum(np.power(hx - y, 2)) / (2 * m)

    if theta.shape[0] > 2:
        cost2 = mylambda / (2 * m) * np.sum(np.power(theta[1:, :], 2))
    else:
        cost2 = mylambda / (2 * m) * np.power(theta[1:, :], 2)

    return cost1 + cost2

2、学习曲线

根据训练集大小的增加来计算对应训练集的误差、交叉验证集的误差

import numpy as np

from trainLinearReg import trainLinearReg
from costFunction import costfunction


def learningcurve(x, y, xval, yval, mylambda):

    m = x.shape[0]

    cost_train = np.zeros(m)
    cost_val = np.zeros(m)
    init_theta = np.ones(x.shape[1] + 1)

    for i in range(m):

        x_temp = x[0:i+1, :]
        y_temp = y[0:i+1, :]


        theta = trainLinearReg(init_theta, x_temp, y_temp, mylambda)   # 传入0相当于不进行正则化

        cost_train[i] = costfunction(theta, x_temp, y_temp, mylambda)
        cost_val[i] = costfunction(theta, xval, yval, mylambda)

    return cost_train, cost_val

寻找最小值的函数 trainLinearReg 实现 :

import numpy as np
import scipy.optimize as opt

from costFunction import costfunction
from linearRegressionGradient import gradient


def trainLinearReg(theta, x, y, mylambda):

    result = opt.minimize(fun=costfunction, x0=theta,
                          args=(x, y, mylambda), method='TNC', jac=gradient)

    return result.x

结果:
根据
训练集的误差和交叉验证集的误差中间始终存在一条沟壑,且训练集误差不趋近于0。说明拟合的曲线出现偏差,而且增加训练集的方式并不能减少两者之间误差的大小。

3、特征增加来减少偏差

本来训练集X只有一个特征,通过X的高次方来构建新的特征。

import numpy as np


def polyfeature(x, p):

    m = x.shape[0]
    x_ploy = np.zeros([m, p])

    for i in range(p):

        x_ploy[:, i] = np.power(x[:, 0], i+1)

    return x_ploy

练习中的X最高到了八次方,多了七个特征。但是过高阶数的特征其数值比较大,最好将其缩小:处理成正态分布的类型:

import numpy as np


def featureNormalize(x):

    m, n = x.shape
    mu = np.zeros(m)
    sigma = np.zeros(m)
    x_norm = np.zeros([m, n])

    for i in range(n):

        mu[i] = np.mean(x[:, i])
        sigma[i] = np.std(x[:, i])
        x_norm[:, i] = (x[:, i] - mu[i]) / sigma[i]

    return x_norm, mu, sigma

结果,通过λ的设置来观察拟合过程(主要观察过拟合)

  1. 过拟合状态:λ= 0
    在这里插入图片描述
    拟合曲线(不光滑,不具有普遍性,高方差)
    在这里插入图片描述

  2. 过拟合状态,λ= 0.03
    在这里插入图片描述

  3. 过拟合状态, λ = 0.1
    在这里插入图片描述

  4. 最佳状态 λ = 1
    加大对Theta的惩罚之后,训练集的过拟合状态再次得到改善,但是cost也从0增加,交叉验证集的cost再次减少,两者趋于相等。
    在这里插入图片描述
    拟合曲线:(相对平滑)
    在这里插入图片描述
    至此,该练习的思路:

    1 线性模型无法很好拟合数据(偏差,学习曲线沟壑无法随着训练集的增加减少而有效交叉验证集的cost),因此想增加特征来更好的拟合预测曲线。
    2 增加特征后发现预测曲线出现过拟合的现象(训练集的cost接近0, 而交叉验证集最终不会随着训练集的增加减少,学习曲线沟壑无法随着训练集的增加而减少)。
    3 通过增加 λ 的值来减少过拟合,使预测曲线平滑。
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值