# -*- coding: utf-8 -*-
"""
Created on Sun Aug 15 15:36:43 2021
@author: Yang Hongyun
"""
'''
根据下列数据建立回归方程。
x: 2.8 2.9 3.2 3.2 3.4 3.2 3.3 3.7 3.9 4.2
y: 25 27 29 32 34 36 35 39 42 45
'''
import numpy as np
import matplotlib.pyplot as plt
x=np.array([2.8,2.9,3.2,3.2,3.4,3.2,3.3,3.7,3.9,4.2])
y=np.array([25,27,29,32,34,36,35,39,42,45])
plt.scatter(x,y,c='red')
#最小二乘法,计算线性回归方程系数a,b:y=ax+b
x_=x.mean()
y_=y.mean()
n=x.size
xy=x*y
xx=x*x
a=(xy.sum()-n*x_*y_)/(xx.sum()-n*x_*x_)
b=y_-a*x_
#x1=np.arange(2.5,5)
y1=a*x+b
plt.plot(x,y1,c='black')
plt.show()
结果:
a=14.0909090909
b=-13.2272727273
import numpy as np
import matplotlib.pyplot as plt
x=np.array([2.8,2.9,3.2,3.2,3.4,3.2,3.3,3.7,3.9,4.2])
y=np.array([25,27,29,32,34,36,35,39,42,45])
plt.scatter(x,y,c='red')
#梯度下降法,计算线性回归方程系数a,b:y=ax+b
#定义损失函数 loss= 1/n ∑(y-ax-b)**2
def _loss(a,b,x,y):
total_cost=0
n=x.size
for i in range(n):
total_cost+=(y[i]-a*x[i]-b)**2
return total_cost/(2*n)
#定义模型参数初始值
learn_rate=0.01
init_a=0
init_b=0
num_iter=50000
#定义梯度下降算法函数
def gradient_desc(x,y,init_a,init_b,learn_rate,num_iter):
a=init_a
b=init_b
#定义一个损失函数数组,保存每次迭代的损失值
loss=[]
for i in range(num_iter):
loss.append(_loss(a,b,x,y))
a,b=grandient_desc_step(a,b,learn_rate,x,y)
return a,b,loss
def grandient_desc_step(cur_a,cur_b,learn_rate,x,y):
sum_grad_a=0
sum_grad_b=0
n=x.size
#对每一个(xi,yi)带入梯度方程
for i in range(n):
sum_grad_a+=(cur_a*x[i]+cur_b-y[i])*x[i]
sum_grad_b+=cur_a*x[i]+cur_b-y[i]
grad_a=1/n*sum_grad_a
grad_b=1/n*sum_grad_b
#梯度下降,更新当前的a和b
update_a=cur_a-learn_rate*grad_a
update_b=cur_b-learn_rate*grad_b
return update_a,update_b
#测试结果
a,b,loss=gradient_desc(x,y,init_a,init_b,learn_rate,num_iter)
cost=_loss(a,b,x,y)
print(loss,a,b)
plt.scatter(x,y,c='red')
y2=a*x+b
plt.plot(x,y2,c='black')
plt.show()
最后结果:
loss=1.5840931635452704
a=14.0858161167
b=-13.2098204579
plt.plot(loss[:50]) #选择loss前的前50次迭代结果显示结果,后面迭代趋近最小值的过程比较缓慢