给定数据集dataSet,每一行代表一组数据记录,每组数据记录中,第一个值为房屋面积(单位:平方英尺),第二个值为房屋中的房间数,第三个值为房价(单位:千美元),试用梯度下降法,构造损失函数,在函数gradientDescent中实现房价price关于房屋面积area和房间数rooms的线性回归,返回值为线性方程 price = +∗area+∗rooms 中系数 (?=0,1,2) 的列表
思路:
我们将用梯度下降法来拟合出这条直线!
首先,我们需要定义一个代价函数,在此我们选用均方误差代价函数
- m是数据集中点的个数
- 是一个常量,这样是为了在求梯度的时候,二次方乘下来就和这里的抵消了,自然就没有多余的常数系数,方便后续的计算,同时对结果不会有影响
- y 是数据集中每个点的真实y坐标的值
- h 是我们的预测函数,根据每一个输入x,根据 计算得到预测的y值,即
,
本题的函数为 price = +∗area+∗rooms
我们可以根据代价函数看到,代价函数中的变量有三个(),所以是一个多变量的梯度下降问题,求解出代价函数的梯度,也就是分别对三个变量进行微分
这个表达式 的意思就是 求的偏导 就是先将预测值 减去实际的值乘以偏移量 的总和加起来除以所有的组数。
明确了代价函数和梯度,以及预测的函数形式。我们就可以开始编写代码了。
每次迭代时,都会有 = - *lr (learning rate),经过n次迭代后,最终梯度下降到最优解附近。此时,模型就训练成功。
首先确定这是一个三元线性回归问题,我们需要人为设置的参数有学习率learning rate,还有迭代的次数epchos。
实现该线性回归主要有三步:
第一步,获得要训练的数据,也就是房子的大小,房间数以及房子的价格
第二步:设置初始的三个未知数的值,也就是线性方程的系数,刚开始,随机为1,2,1
第三步:根据设置的的值,将相应的房间大小和房价数都放入函数中,求得一个预测的房价preditc_y。用预测的房价减去实际的房价,对他们的结果求平方,并将这n组数据求得的平方结果累加起来。来算一下损失函数(就是求均方差)。
每次预测完房子的价格,都将相应的向真实的房价偏移,偏移量是(预测房价-真实房价)X 相应的参数(如果求,那就是乘1,如果是,那就乘area对应的值,如果是,那就乘rooms对应的值),该偏移量是向上偏移(即函数中的系数值变大)还是向下偏移,取决于预测值predict_y是低于还是高于真实价格。
就这样一直进行偏移量操作,一直对进行迭代。
下面就上代码吧
导入库函数和数据
%matplotlib inline
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from numpy import genfromtxt
dataPath = r"./Input/data1.csv"
dataSet = pd.read_csv(dataPath,header=None)
price = []
rooms = []
area = []
for data in range(0,len(dataSet)):
area.append(dataSet[0][data])
rooms.append(dataSet[1][data])
price.append(dataSet[2][data])
梯度下降核心代码
def gradientDescent(rooms, price, area):
"""
梯度下降法。给定起始点与目标函数的一阶导数,求在epochs次迭代中theta0,theta1,theta2的更新值
param theta0
"""
theta = [1,2,1] #预设theta初值
learn_rate = 0.0000000001 #学习率
predit_y = 0 #预测值
loss = [] #损失数组
epochs = 5000 #迭代次数
for j in range(epochs):
theta0,theta1,theta2= 0,0,0
loss_t = 0 #计算总体的方差
for i in range(5): #一共五组数据
predit_y = theta[0] + theta[1] * area[i] + theta[2]*rooms[i]
theta0 = theta0 + (predit_y - price[i])*1
theta1 = theta1 + (predit_y - price[i])*area[i]
theta2 = theta2 + (predit_y - price[i])*rooms[i]
loss_t = loss_t + ((predit_y-price[i])**2)/2
loss.append(loss/5)
theta0 = theta0 / 5
theta1 = theta1 / 5
theta2 = theta2 / 5
theta[0] = theta[0] - theta0*learn_rate
theta[1] = theta[1] - theta1*learn_rate
theta[2] = theta[2] - theta2*learn_rate
plt.plot(loss,c='b')
plt.show()
return theta
主函数调用
def demo_GD():
print("hello")
gradientDescent(rooms,price,area)
demo_GD()
参考文章:
作者:六尺帐篷
链接:https://www.jianshu.com/p/c7e642877b0e
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。