手记

线性回归 --梯度下降法与标准方程法

线性回归

简单线性回归

机器学习三要素 – 模型 策略 算法
线性回归
输入空间为XX输出空间为YY
模型:假设函数hypothesis:hθ=θ0+θ1x1hypothesishθ=θ0+θ1x1

模型参数:θ0,θ1θ0,θ1

思考:如何拟合模型参数 使得假设函数不断逼近实际值?

策略1 : 梯度下降法
设置代价函数 如果代价函数不断的减小 说明模型参数在不断的逼近实际值
已知XiXi与其对应的YiYi拟合其假设函数
代价函数 :J(θ)=12m∑i=1n(hθx(i)−y(i))2J(θ)=12mi=1n(hθx(i)y(i))2
mm为样本数

假设函数与代价函数

代价函数与代价函数轮廓图

策略1: 梯度下降法
alphaalpha:学习速率
∂∂θθ:偏导数
J(θ)J(θ):代价函数
θ=θ−α∂∂θJ(θ)θ=θαθJ(θ)
不断的迭代更新θθ

注意点:学习速率选择

        α表示迭代至稳定值的速率。当θ用公式进行迭代,两次迭代之间的Δθ的值小于某个值(一般可以用10-3),则可以认为代价函数已经最小。

   对于α,可以使用下列数据进行测试:

   0.001、0.01、0.1、1、10…,或者可以用0.001、0.003、0.01、0.03、0.1、0.3、1…,即可以用3倍或10倍的速度,将α的值慢慢调整到一个区间,再进行微调。123456

梯度下降法以及多元线性回归实现原理

分析:
梯度下降法

梯度下降法及代价函数

算法实现:
简单线性回归

import numpy as np"""梯度下降法
    ---方法实现1 比实现2精度更高?
    ---为啥子
"""def createData():
    x = [1, 2, 3, 4, 5, 6]
    y = [13, 14, 20, 21, 25, 30]    return x, y# 简单线性回归 实现def linearRegression(x, y):
    """
    cost function min
    同时更新theta0 theta1
    目标:代价函数最小化
    :param x: 特征值x
    :param y: 目标变量y 实际值y
    :return: h(x)
    """
    epsilon = 0.01
    error = 0   #
    alpha = 0.001     # 步长
    maxCycle = 20   # 最大迭代次数
    count = 0
    theta0 = 0
    theta1 = 0

    m = len(x)    while True:
        diff = [0, 0]
        count += 1
        for i in range(m):
            diff[0] += theta0 + theta1 * x[i] -y[i]
            diff[1] += (theta0 + theta1 * x[i] -y[i]) * x[i]
        print('diff---------------------', diff)
        theta0 = theta0 - alpha/m * diff[0]
        theta1 = theta1 - alpha/m * diff[1]
        print('theta0', theta0)
        print('theta1', theta1)
        error1 = 0
        for i in range(m):
            error1 += (theta0 + theta1 * x[i] - y[i]) ** 2
        if abs(error1 - error) < epsilon:            break

        if count > 200:            break

    print(theta0, theta1, error1)    return theta0, theta1, error1if __name__ == '__main__':
    x, y = createData()    # print(x) [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    # print(y) [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]

    weights = linearRegression(x, y)
    print(weights)    # print(linearRegression2(x, y))

用矩阵思维看数据集 优化算法

算法优化

def linearRegression2(x, y):
    x = np.mat(x)
    y = np.mat(y)

    m, n = np.shape(x)
    print(m, n)
    weights = np.zeros((1, m+1))
    print(np.shape(weights))

    alpha = 0.0013
    esplion = 70
    maxCycle= 2000
    count = 0
    while True:
        count += 1
        diff = [0, 0]
        diff[0] = np.sum(x.T * weights - y.T)
        print(diff[0])
        diff[1] = np.sum((x.T * weights - y.T).T * x.T)
        print(diff[1])
        print(diff)
        weights[0, 0] = weights[0, 0] - alpha/(2*n) * diff[0]
        print(weights)
        weights[0, 1] = weights[0, 1] - alpha/(2*n) * diff[1]


        error = np.sum(np.array(x.T * weights - y.T) ** 2)        if error < esplion:            break
        if count > maxCycle:            break

        print(weights, '-------------------', error)    return weights, error

策略2 : 标准方程法
      标准方程法是与梯度下降法功能相似的算法,旨在获取使代价函数值最小的参数θ。代价函数公式如下:

代价函数 :J(θ)=12m∑i=1n(hθx(i)−y(i))2J(θ)=12mi=1n(hθx(i)y(i))2
原理:在一个标准方程中求其最小值 求其偏导数 令值为0 就可以得到θθ
根据上述代价函数,令J对每个θ的倒数都为0,可以解得θ=(XTX)−1XTYθ=(XTX)1XTY

特殊情况

   由于用标准方程法时,涉及到要计算矩阵XTX的逆矩阵。但是XTX的结果有可能不可逆。

   当使用python的numpy计算时,其会返回广义的逆结果。

   主要原因:

   出现这种情况的主要原因,主要有特征值数量多于训练集个数、特征值之间线性相关(如表示面积采用平方米和平方公里同时出现在特征值中)。

   因此,首先需要考虑特征值是否冗余,并且清除不常用、区分度不大的特征值。

3、比较标准方程法和梯度下降算法

   这两个方法都是旨在获取使代价函数值最小的参数θ,两个方法各有优缺点:
   1)梯度下降算法

   优点:当训练集很大的时候(百万级),速度很快。

   缺点:需要调试出合适的学习速率α、需要多次迭代、特征值数量级不一致时需要特征缩放。

2)标准方程法

   优点:不需要α、不需要迭代、不需要特征缩放,直接解出结果。

   缺点:运算量大,当训练集很大时速度非常慢。

4、综合

   因此,当训练集百万级时,考虑使用梯度下降算法;训练集在万级别时,考虑使用标准方程法。在万到百万级区间时,看情况使用,主要还是使用梯度下降算法。

参考文献
机器学习(Machine Learning)- 吴恩达(Andrew Ng)
http://www.cnblogs.com/linhxx/p/8412687.html

原文出处

0人推荐
随时随地看视频
慕课网APP