多元线性回归-波士顿房价预测问题python

上一篇:一元线性回归的数学解析解

波士顿房价预测问题

波士顿房价数据集每一行代表一个样本,共有13列。数据集中的每一行数据都是对波士顿周边或城镇房价的情况描述,先说明一下具体的含义
在这里插入图片描述
CRIM: 城镇人均犯罪率
ZN: 住宅用地所占比例
INDUS: 城镇中非住宅用地所占比例
CHAS: 虚拟变量,用于回归分析
NOX: 环保指数
RM: 每栋住宅的房间数
AGE: 1940 年以前建成的自住单位的比例
DIS: 距离 5 个波士顿的就业中心的加权距离
RAD: 距离高速公路的便利指数
TAX: 每一万美元的不动产税率
PTRATIO: 城镇中的教师学生比例
B: 城镇中的黑人比例
LSTAT: 地区中有多少房东属于低收入人群
MEDV: 自住房屋房价中位数(也就是均价)

波士顿房价数据集包括506个样本,每个样本包括12个特征变量和该地区的平均房价房价(单价)显然和多个特征变量相关,不是单变量线性回归(一元线性回归)问题选择多个特征变量来建立线性方程,这就是多变量线性回归(多元线性回归)问题。
我们依旧可以建立一个线性模型,设置12个参数用来表征不同特征的影响。
在这里插入图片描述
如果用图画出来的话,其实就是一个单个计算节点的计算模型,如图:在这里插入图片描述
我们把上式用向量形式表达处来:
在这里插入图片描述
对多元线性回归的算法描述如下:
1)(随机)初始化权值
2)对每一个训练样本:
计算权值和输入特征向量之间的值作为预测值
计算实际值与预测值之间的误差
定义一种误差的度量标准,想办法使其降低
用误差指导权值的更新
3)设定算法终止标准,当达到这一标准后结束算法

度量标准的选择

显然,误差可表示成err = yi - W*X - b
所谓的度量标准,其实就是将群体的误差表述的更好一些,更能表示出全部样本的误差。看这样一个例子:
在这里插入图片描述
这其实就是三种不同的度量选择——不做处理,绝对值,平方。
显然能够看到,不做处理是肯定不行的(该例中明明有误差,但是用此度量的话误差变为了0),用误差平方和绝对值绝对值能从一定程度上度量误差的大小(绝对值的度量明显要好一点)
不论是平方还是绝对值还是其他的度量方法,我们可以为他们起一个名字——损失函数,损失函数就是用来反映当前预测值与实际值在某种意义下相差的多少。我们的训练的目标就是希望极小化损失函数,使预测值与实际值之间越接近越好。

极小化损失函数

我们希望通过误差来指导权值的更新,方法就是用梯度下降法,极小化损失函数。做法如下:
选取损失函数为平方损失函数:
在这里插入图片描述
其中,yi为第i个样本的实际值,wj为第j个位置的权重(对于波士顿房价预测问题来说的话,一共12个特征,所以w有12个),b为常数,当作偏置项。
确定权值wi对最终误差的影响,我们可以采用使损失函数对误差求偏导的方式求得。
在这里插入图片描述
在这里插入图片描述
如果你是初学者的话,可能会对梯度下降法还是有些迷糊,可以看一下下面这个简单的例子。
在这里插入图片描述
误差是由权值影响的,把权值当作自变量,损失当作因变量,梯度下降方向其实就是导数的反方向,可以指导权值改变,以此获得更小的损失值。

算法实现

算法描述如下:
参数初始化
对于每一个样本:
取前12个数组成输入特征向量,最后一个数就是实际值
特征向量与权值向量相乘得到预测值
计算误差
通过误差更新权重(更新方法是实现确定好的,就是前边梯度下降法所描述的)
达到设定的中止条件后,算法结束。

需要注意的是,由于各各输入特征相差的太多,所以需要对其归一化
将每一个特征映射为0~1上的一个小数。
参考代码如下:

import numpy as np 
import pandas as pd 
import matplotlib.pyplot as plt
from sklearn.utils import shuffle
df = pd.read_csv("boston.csv")
df = np.array(df.values,ndmin=2)
x_data = df[:,:12]
#归一化
for i in range(12):
    x_data[:,i] = (x_data[:,i]-x_data[:,i].min())/(x_data[:,i].max()-x_data[:,i].min())
y_data = df[:,12]
#将后10个作为测试集,不参加训练
test_x = x_data[-10:]
test_y = y_data[-10:]
#初始化参数
w = np.random.normal(0.0,1.0,(1,12))
b = 0.0
#设置训练轮次
train_epochs = 200
learing_rate = 0.001
loss_=[]
for count in range(train_epochs):
    loss=[]
    for i in range(len(x_data)):
        re = w.dot(x_data[i])+b
        err = y_data[i]-re
        w +=learing_rate*err*x_data[i]
        b +=learing_rate*err
        #记录误差
        loss.append(abs(err))
    loss_.append(sum(loss)/len(loss))
    #print(sum(loss)/len(loss))
    #随机打乱训练集中的样本,防止模型出现结果和输入的位置有关的情况
    x_data,y_data = shuffle(x_data,y_data)
#打印误差的变化情况
plt.plot(loss_)
#简单的评估,看看实际值和预测值之间的误差
for i in range(10):
    print("true:\t{}".format(test_y[i]),end="\t")
    pre = np.dot(w,test_x[i])+b
    print("guess:\t{}".format(pre))
plt.show()

可以看到,随着训练的进行,损失(loss)值是逐渐减小的,说明我们的模型预测的越来越准确
在这里插入图片描述
pandas库在数据处理中非常好用,甩原生的python函数n条街
数据集
数据集可通过网盘下载,提取码:15p5

  • 19
    点赞
  • 90
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值