python 用梯度下降法拟合直线 最小二乘准则

好家伙,这作业我上周就想写了

太久没更新博客了,因为这段时间实在没解决啥技术问题(或者说,遇到了技术问题懒得解决)。

生活方面嘛,我在社交上取得了重大突破。

梯度下降法

利用了:

  • python
  • spyder
  • 最优化导论p92页

所谓最优化技术,就是要搞最优化。那么,这里,我们需要想办法拟合出一条最优的直线出来,这能有多难(how hard can it be)?——很难,绝对值求导问题困了我好久,最后一看好家伙,损失函数不用绝对值呐。

大概就是这么几步,目的是找到最优的斜率k和y轴截距取值b,让损失函数最小。

具体来说,

  1. 先把损失函数(二次方形式的比绝对值好用些,绝对值形式的求导好像会出问题)给出来,用符号变量的形式;
  2. 然后再用sympy库里的求导功能把偏导表达式搞到手;
  3. 后面就是对照书本上的梯度下降公式,一层一层往前推进了,可以把这些系数放在一个扩张的list里面;
  4. 当偏导数非常小的时候,就当作收敛完成,跳出。

呃呃,
老夫聊发少年狂,欢迎指正错误!

代码:

from sympy import *#符号运算 有点像matlab
import matplotlib.pyplot as plt#画图用
import random

a=[]
b=[]
alpha= 0.001
error= 0.00000001
n= 10

for i in range(n):
    a.append(10*random.random())
    b.append(10*random.random())

plt.scatter(a,b) #绘制初步的散点图,就是两个list对应嘛

########################################
#函数
x1, x2 = symbols('x1, x2')
dist=[]
for i in range(9):
    dist.append((x1*a[i]+x2-b[i])**2)
z= sum(dist)#是的,符号变量这都顶得住,还真能求导        
d1=diff(z,x1)
d2=diff(z,x2)
########################################
#start
px=[]
py=[]
px.append(0)
py.append(0)
k=0
temp1=d1.subs({x1:px[k],x2:py[k]})
temp2=d2.subs({x1:px[k],x2:py[k]})


while(abs(d1.subs({x1:px[k],x2:py[k]})+ d2.subs({x1:px[k],x2:py[k]}))> error):#每一次都更新一对新的函数k与b(kx+b)
    px.append(px[k]-alpha*d1.subs({x1:px[k],x2:py[k]}))
    py.append(py[k]-alpha*d2.subs({x1:px[k],x2:py[k]}))
    k= k+1

########################################    
#拟合直线
print(px[k],py[k])
y=[]
for i in range(n):
    y.append(px[k]*a[i]+py[k])
plt.plot(a,y)#画线,理论上两个点就成
######################################## 
#损失函数值
cost=[]
for i in range(n):
    cost.append((px[k]*a[i]+py[k]-b[i])**2)#可以更简单一些!
print(sum(cost)/(2*n))

一些结果:


在这里插入图片描述
在这里插入图片描述

在这里插入图片描述欢迎来重庆玩!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值