线性回归预测房价

给定数据集dataSet,每一行代表一组数据记录,每组数据记录中,第一个值为房屋面积(单位:平方英尺),第二个值为房屋中的房间数,第三个值为房价(单位:千美元),试用梯度下降法,构造损失函数,在函数gradientDescent中实现房价price关于房屋面积area和房间数rooms的线性回归,返回值为线性方程 price = θ0\theta_0+θ1\theta_1∗area+θ2\theta_2∗rooms 中系数 θi\theta_i(?=0,1,2) 的列表

思路:
我们将用梯度下降法来拟合出这条直线!
首先,我们需要定义一个代价函数,在此我们选用均方误差代价函数
J(θ)=12mi=1mhθ(x(i)y(i))2J(\theta) = \frac {1}{2m}\sum_{i=1}^{m}{h_{\theta}(x^{(i)}-y^{(i)})^2}

  • m是数据集中点的个数
  • 12\frac {1}{2}是一个常量,这样是为了在求梯度的时候,二次方乘下来就和这里的12\frac {1}{2}抵消了,自然就没有多余的常数系数,方便后续的计算,同时对结果不会有影响
  • y 是数据集中每个点的真实y坐标的值
  • h 是我们的预测函数,根据每一个输入x,根据 θ\theta 计算得到预测的y值,即
    hθ(x(i))=θ0+θ1x1(i)h_{\theta}(x^{(i)})= \theta_0 + \theta_1x_1^{(i)}

本题的hθ(x(i))h_{\theta}(x^{(i)})函数为 price = θ0\theta_0+θ1\theta_1∗area+θ2\theta_2∗rooms
我们可以根据代价函数看到,代价函数中的变量有三个(θ0θ1θ2\theta_0,\theta_1,\theta_2),所以是一个多变量的梯度下降问题,求解出代价函数的梯度,也就是分别对三个变量进行微分
J(θ)=Jθ0,Jθ1,Jθ2\nabla J(\theta) = \langle \frac{\partial J}{\partial \theta_0} ,\frac{\partial J}{\partial \theta_1},\frac{\partial J}{\partial \theta_2} \rangle
Jθ0=1mi=1m(hθ(x(i))y(i))\frac{\partial J}{\partial \theta_0} = \frac{1}{m}\sum_{i=1}^m ({h_{\theta(x^{(i)})-y^{(i)}})}
Jθ1=1mi=1m(hθ(x(i))y(i))x1(i)\frac{\partial J}{\partial \theta_1} = \frac{1}{m}\sum_{i=1}^m {(h_{\theta(x^{(i)})-y^{(i)}})}x_1^{(i)}
Jθ2=1mi=1m(hθ(x(i))y(i))x2(i)\frac{\partial J}{\partial \theta_2} = \frac{1}{m}\sum_{i=1}^m {(h_{\theta(x^{(i)})-y^{(i)}})}x_2^{(i)}

这个表达式 的意思就是 求θ\theta的偏导 就是先将预测值 hθ(x(i))h_{\theta}(x^{(i)})减去实际的值y(i)y^{(i)}乘以偏移量x(i)x^{(i)} 的总和加起来除以所有的组数。
明确了代价函数和梯度,以及预测的函数形式。我们就可以开始编写代码了。
每次迭代时,都会有θ\theta = θ\theta - Jθ\frac{\partial J}{\partial \theta}*lr (learning rate),经过n次迭代后,最终梯度下降到最优解附近。此时,模型就训练成功。

首先确定这是一个三元线性回归问题,我们需要人为设置的参数有学习率learning rate,还有迭代的次数epchos。
实现该线性回归主要有三步:
第一步,获得要训练的数据,也就是房子的大小,房间数以及房子的价格
第二步:设置初始的三个未知数θ0,θ1,θ2\theta_0,\theta_1,\theta_2的值,也就是线性方程的系数,刚开始,随机为1,2,1
第三步:根据设置的θ0,θ1,θ2\theta_0,\theta_1,\theta_2的值,将相应的房间大小和房价数都放入函数中,求得一个预测的房价preditc_y。用预测的房价减去实际的房价,对他们的结果求平方,并将这n组数据求得的平方结果累加起来。来算一下损失函数(就是求均方差)。
每次预测完房子的价格,都将相应的θ0,θ1,θ2\theta_0,\theta_1,\theta_2向真实的房价偏移,偏移量是(预测房价-真实房价)X 相应的参数(如果求θ0\theta_0,那就是乘1,如果是θ1\theta_1,那就乘area对应的值,如果是θ2\theta_2,那就乘rooms对应的值),该偏移量是向上偏移(即函数中的系数θ\theta值变大)还是向下偏移,取决于预测值predict_y是低于还是高于真实价格。
就这样一直进行偏移量操作,一直对θ\theta进行迭代。

下面就上代码吧
导入库函数和数据

%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
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

posted @ 2019-10-30 15:46  Philtell  阅读(854)  评论(0编辑  收藏  举报