线性回归——梯度下降法

问题引入

已知南京地区的一组数据:

面积 房间数 价格
2104 3 400
1600 3 330
2400 3 369
1416 2 232

现在来了一个新的房子,知道其面积和房间数,其价格应该是多少合适呢?
我们可以将面积和房间数看成是房子的两个特征,如何根据这些特征预测价格,需要建立其价格与特征之间的联系。我们设定价格与这些特征之间呈一个近似线性的关系,那么我们就需要找出一个线性函数h:

hθ(x)=θ0+θ1x1+θ2x2

x0=1 ,那么上述公式就转化为
h(x)=i=0mθTx

现在,给出一组训练数据,如何找出最合适的 θ 呢?最合适的 θ 意味着根据 θ 计算出来的 h(x) 与y最接近。于是我们定义误差函数:
J(θ)=12i=1m(hθ(x(i))y(i))2

问题就转化为找出 θ ,使得 J(θ) 最小。

梯度下降法

首先,可以采用梯度下降法来解决这个问题。梯度下降法的步骤为:
(1)设置一个初始的 θ ,可以为任何值,包括0;
(2)改变 θ ,是的 J(θ) 按梯度下降的方向减小;
就是按照下式依次做迭代:

θj=θjαθjJ(θ)

其中, α 是学习因子,要求得 θj ,要求首先要求出上面式子中的偏倒数,我们首先考虑只有一个训练数据(m=1)的情况:
θjJ(θ)=θj12(hθ(x)y)2=(hθ(x)y)θj(hθ(x)y)=(hθ(x)y)θj(j=1nθjxjy)=xj(hθ(x)y)

因此,上面的迭代式转化为
θj=θjαxj(hθ(x)y)

这是针对只有一个训练数据的情况,如何推广到拥有多个训练数据的情况呢?有两种方法。第一种方法就是批梯度下降:
θj=θjαi=1m(hθ(x(i))y(i))x(i)j

针对每一个 θj ,按照上式做迭代,直到收敛。
批量梯度下降python代码实现:

def h(xArr, theta):
    r = 0.0
    for i in range(len(xArr)):
        r += theta[i] * xArr[i]
    return r

def batch_gradient_descent(xArr, yArr, theta, eps = 0.0001, alpha = 0.003):
    '''
    :param xArr:
    :param yArr:
    :param theta: 线性关系系数
    :param eps: 结束迭代的条件
    :param alpha: 学习因子
    :return: 学习后得到的theta
    '''
    m = shape(xArr)[0]
    n = shape(xArr)[1]
    error0 = 0.0
    cnt = 0
    while True:
        cnt += 1
        for j in range(n):
            hVal = 0
            for i in range(m):
                hVal += (yArr[i] - h(xArr[i], theta)) * xArr[i][j]
            theta[j] = theta[j] + alpha * hVal

        error1 = 0.0
        for i in range(m):
            error1 += pow((h(xArr[i], theta) - yArr[i]),2)
        if abs(error1 - error0) < eps:
            break
        else:
            error0 = error1

        print("第%d次迭代: "%(cnt))
        print("theta: ", theta)
        print("error0: %f error1: %f" %(error0, error1))

    print("Done!! theta:", theta)
    print("error0: %f error1: %f" %(error0, error1))
    print("共进行%d次迭代!!" % (cnt))
    return theta

原始数据集:
线性回归——梯度下降法_第1张图片

应用批量梯度下降法:
线性回归——梯度下降法_第2张图片

线性回归——梯度下降法_第3张图片

应用批量梯度下降法时需要注意学习因子 α 的选择, α 太小,步长就会很小,收敛会很慢,如果 α 太大,则可能会产生背离,无法收敛。

下面介绍第二种方法,就是随机梯度下降法,他每一次迭代只处理训练数据集中的一个数据。

Loop{
for i=1 to m{

θj=θjα(hθ(x(i))y(i))x(i)j

    }
}

随机梯度下降法python实现:

def gradient_descent(xArr, yArr, theta, eps = 0.0001, alpha = 0.3):

    m = shape(xArr)[0]
    n = shape(xArr)[1]
    error0 = 0.0
    cnt = 0
    while True:
        for i in range(m):
            cnt += 1
            hVal = h(xArr[i], theta)
            for j in range(n):
                theta[j] = theta[j] + alpha * xArr[i][j] * (yArr[i] - hVal)

            error1 = 0.0
            for k in range(m):
                error1 += pow((h(xArr[k], theta) - yArr[k]),2)
            if abs(error1 - error0) < eps:
                print("Done!! theta:", theta)
                print("error0: %f error1: %f" %(error0, error1))
                print("共进行%d次迭代!!" % (cnt))
                return theta
            else:
                error0 = error1

            print("第%d次迭代: "%(cnt))
            print("theta: ", theta)
            print("error0: %f error1: %f" %(error0, error1))


    return theta

采用上面的数据应用随即梯度下降法
线性回归——梯度下降法_第4张图片

两种方法的比较:
(1)批量梯度下降法能够找到全局最优解,随机梯度下降法无法保证找到全局最优解,但是能找到局部最优解;
(2)批量梯度下降法每次迭代都需要遍历整个数据集,在数据量很大时,收敛速度会很慢,随机梯度下降法每次迭代只需要遍历数据集中的一个数据,在数据量很大时,可能数据不用遍历完就找到了最优解,收敛速度较快。

你可能感兴趣的:(机器学习)