梯度下降学习算法与pthon代码实现

梯度下降学习算法的基本原理
一,梯度下降学习算法的公式推导
关于梯度学习算法的公式推导,吴恩达教授的斯坦福公开课(可以在网易公开课上获取视频资源)讲得比较清楚,借用该推导过程:
假设做一个房屋价值的评估系统,影响房屋价格的因素有很多,比如说面积、房间的数量(几室几厅)、地段、朝向等等,这些影响房屋价值的变量被称为特征(feature),特征在机器学习中是一个很重要的概念,有很多的论文专门探讨这个东西。为了简单,假设我们的房屋只受面积影响。
假设有一个房屋销售的数据如下:

面积(m^2)  销售价钱(万元)

123            250

150            320

87              160

102            220

以面积为x轴,价格为y轴作图,可以得到散点图,当然我们可以根据高中学习的方法去手动求解拟合回归直线的方程,从而获得房屋价格与面积的关系公式,但是如果用机器学习算法来自动拟合回归方程该如何实现呢?
拟合曲线

我们把上面的这四个数据称为训练集,数据集的数目为n

机器学习

首先猜测模型公式为一般公式

计算拟合回归曲线的常量参数,可以计算训练集的各个点到该拟合曲线的方差,当方差最小的时候,我们可以认为该回归曲线正是所求的曲线方程,根据方差和公式,可以有:

方差和

公式中θ表示公式常量,m表示训练集的第m个数据,1/2是为了待会计算方便加上去的。如何调整θ以使得J(θ)取得最小值有很多方法,其中有最小二乘法(min square),这里使用梯度下降法。

梯度下降法是按下面的流程进行的:

1)首先对θ赋值,这个值可以是随机的,也可以让θ是一个全零的向量。

2)改变θ的值,使得J(θ)按梯度下降的方向进行减少。

对该函数求导

求导

迭代赋值,式子中α是人为输入的参数,用来控制收敛步伐大小,可以通过判断a(h(x)-y)的值(比如当a(h(x) - y)x <0.001》来让式子收敛,从而求出θ的值。

二,python代码实现
运行环境, python3.5,windows

'''
一元一次方程函数 y =ax+b 缺陷,不能超过25个样本数据
训练样本的方程为y=x+1
'''
def gradient(list):
    result = {}
    a = 0
    b = 0
    direction = 0.2 #下降的梯度
    g = 0.01
    count = 0
    while abs(float(g*direction)) > g/100:
        for x,y in list.items():
            count += 1
            x = float(x)
            y = float(y)
            direction = (a*x+b-y)
            a = a - g * direction * x
            b = b - g * direction

    result['a'] = a
    result['b'] = b
    result['counts'] = count
    return result

'''
二元一次方程函数 z = ax+by  该代码所实现的算法有缺陷,不能超过15个样本数据
训练样本的函数为z = x + y
'''
def gradient2(list):
    result = {}
    a = 0
    b = 0
    direction = 1 #下降的梯度
    g = 0.01
    count = 0
    while abs(float(g*direction)) > g/100:
        for items in list:
            count += 1
            x = float(items[0])
            y = float(items[1])
            z = float(items[2])
            direction = (a*x+b*y-z)
            a = a - g * direction*x
            b = b - g * direction*y
    result['a'] = a
    result['b'] = b
    result['count'] = count
    return result



list1 = {1 : 2, 2 : 3, 3 : 4, 4 : 5}
list2 = [(1,3,4),(2,5,7),(3,9,12)]

a = gradient(list1)
b = gradient2(list2)
print(a)
print(b)

运行结果:

{'a': 1.008908495646052, 'b': 0.9726462684576949, 'counts': 1992}
{'a': 0.9450581576040846, 'b': 1.0184250039014437, 'counts': 7269}

在实验过程中,我发现我所写的代码训练的数据集数目有限,训练一元一次函数不能超过25个数据量,训练二元一次函数不能超过15个数据量,一旦超过限定数量,训练出来的参数不准确,当数量超过一定规模,训练出来的参数显示为无穷大或无穷小。我更改了其他同志所写的梯度下降学习代码,如http://blog.csdn.net/programmer_wei/article/details/51941358,将其数据集规模扩大,当扩大到25个数据时,该代码训练的参数也会产生很大的误差,我分析了一下,认为可能有以下原因引起:

(1)随着训练的进行,x值越来越大,为了使函数收敛,a(h(x)-y)(代码中等同于a*x+b-y)的值必须要很小,反复迭代后a的值就越来越小以至于近似无穷小,使得参数计算不准确。

针对训练集数目导致参数计算不准确的问题,有哪位同志可以给出专业的解释吗?不甚感激。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值