import numpy as np
import pandas as pd
#生成模拟数据集 价格关于年份的关系
def GenData(start=2001,end=2018):
a = 444 #定义一个k
dt = {'year':[],'price':[]}
for x in np.arange(start,end):
y = a*x - 886444 # 数学模型 => 一次函数
s = np.random.randint(-300,300) # 随机产生一个误差
ry = y + s # 理论数据加上偏差 得到模拟的实际数据
dt['year'].append(x)
dt['price'].append(ry)
df = pd.DataFrame(dt)
#此处把数据缩小1000倍
data = df.values*0.001
return data
def f_loss(a,b,data):#计算梯度
loss = np.sum((a * data[:, 0] + b - data[:, 1]) ** 2)
return loss
def gradient(data,a,b):#计算梯度向量
gradient_a=np.sum(2*(data[:,1]-data[:,0]*a-b)*data[:,0])
gradient_b=np.sum(2*(data[:,1]-data[:,0]*a-b))
return gradient_a , gradient_b
data=GenData()
if __name__ == '__main__':
w=400 #初始权重 w
b= -800 #初始偏置 b
old_loss=np.inf #起始误差等于无穷大
old_w=w #起始变量w
old_b=b #起始变量b
step=10 #初始移动步伐(用于计算每次loss函数的自变量的移动大小)
threshold=0.00000001 #最后要求的误差范围
while 1:
loss=f_loss(w,b,data)
if abs(old_loss-loss)<threshold:
break
if old_loss<=loss:
step=step*0.5
w,b=old_w,old_b
old_loss=loss
grad=gradient(data,w,b)
old_w,old_b=w,b
w,b=w+step*grad[0],b+step*grad[1]#此时w,b为loss函数自变量
print( step,'\t', w, '\t', b,grad[0],grad[1])