【机器学习】从房价预测问题看回归算法
关键词:机器学习 / 回归
文章目录
- 回归问题是什么
- 生成数据
- 最小二乘法学习一元线性回归模型
- 最小二乘法学习多元线性回归模型
- 梯度下降法学习回归模型
回归问题是什么
回归问题是除了分类问题以外,机器学习中另一个经典问题。本节我们以从房价预测为问题背景,逐步介绍分类问题及其相关算法。
回归的目的是想拟合一组数据的输入x\boldsymbol{x}x和输出yyy之间的映射关系f(⋅)f(\cdot)f(⋅),进而用得到的拟合模型f(⋅)f(\cdot)f(⋅)对未知的样本xt\boldsymbol{x}_txt进行预测。分类和回归的最显著区别,是输出变量yyy的类型不同:
- 回归:yyy是连续变量,如预测深圳市南山区住宅的明年房价,是一个回归任务;
- 分类:yyy是离散变量,如预测深圳市南山区住宅的明年房价是涨是跌,是一个分类任务。
房价会受很多因素的影响,如面积、所在地区便利程度、开发商品质和所在学区等等。我们希望拟合出来房价和这些因素的关系,进而对未知的房价进行预测。如果我们考虑多个影响房价的因素,那么就是一个多元回归问题(又称多变量线性回归)。特别地,假设只考虑面积,拟合房价和面积之间的关系,那么就是一个一元回归问题:
- 多元回归:y=f(x)y=f(x)y=f(x),其中影响因素仅有一个特征,即xxx是一维;
- 一元回归:y=f(x),x=[x1,x2,...,xd]y=f(\boldsymbol{x}),\boldsymbol{x}=[x_1,x_2,...,x_d]y=f(x),x=[x1,x2,...,xd],其中ddd表示元的个数,也即特征的维度。
根据房价和影响因素之间的关系的类型,又可以分为线性回归和非线性回归,前者的潜在假设是输入、输出存在线性关系,而后者则认为输入和输出存在非线性映射:
线性回归:y=wTx+b=w1x1+w2x2+⋯+wdxd+by=\boldsymbol{w}^{T}\boldsymbol{x}+b=w_1x_1+w_2x_2+\cdots+w_dx_d+by=wTx+b=w1x1+w2x2+⋯+wdxd+b,其中ddd表示特征的个数;
非线性回归:常见的如多项式回归y=w0+w1x1+w2x22+⋯+wdxddy=w_0+w_1x_1+w_2x_2^2+\cdots+w_dx_d^dy=w0+w1x1+w2x22+⋯+wdxdd。
本次我们将以房价问题为例,从最简单的一元线性回归入手,了解回归问题的细节。
生成数据
我们用yyy表示房价,用XXX表示影响房价的面积、所在地区便利程度、开发商品质等因素的向量。有房价标签的训练数据集为{(x1,y1),(x2,y2),⋯,(xn,yn)}\{(\boldsymbol{x}_1,y_1),(\boldsymbol{x}_2,y_2),\cdots,(\boldsymbol{x}_n,y_n)\}{(x1,y1),(x2,y2),⋯,(xn,yn)},我们希望可以基于这些数据训练得到拟合二者关系的函数f(⋅)f(\cdot)f(⋅),当遇到新的测试数据xt\boldsymbol{x}_txt,就可以预测得到它对应的房价f(xt)f(\boldsymbol{x}_t)f(xt)。
现在假设先只考虑面积因素来预测房价,手动生成以下面积和房价数据
x = [100, 60, 90, 120, 150, 170, 110, 200, 250, 220, 30, 70, 80, 140, 95] # 面积
y = [405, 260, 465, 600, 750, 780, 500, 930, 999, 780, 149, 350, 404, 650, 500] # 房价
数据可视化效果如下:
我们使用前10组数据作为训练集训练的一元线性回归模型,后5组数据留作测试。即训练数据:
x_train = [100, 60, 90, 120, 150, 170, 110, 200, 250, 220] # 面积
y_train = [405, 260, 465, 600, 750, 780, 500, 930, 999, 780] # 房价
测试数据:
x_test = [30, 70, 80, 140, 95] # 面积
y_test = [149, 350, 404, 650, 500] # 房价
最小二乘法学习一元线性回归模型
我们尝试简单的线性回归模型对数据进行拟合,即假设房价和面积的因素的关系为f(x)=wx+bf(x)=wx+bf(x)=wx+b。接下来的任务是学习这里的参数www和bbb使得模型拟合得到的yyy值和对应的真实训练数据的yyy值尽量接近。回归问题中常用均方误差(mean squared error)来评估训练集上预测结果相对真实结果的差异,即要求模型参数满足
w∗,b∗=argminw,b1m∑i=1m(f(xi)−yi)2=argminw,b1m∑i=1m(wxi+b−yi)2\begin{aligned} w^*,b^* &=\arg \min_{w,b} \frac{1}{m}\sum_{i=1}^m(f(x_i)-y_i)^2 \\ &=\arg \min_{w,b} \frac{1}{m}\sum_{i=1}^m(wx_i+b-y_i)^2 \end{aligned} w∗,b∗=argw,bminm1i=1∑m(f(xi)−yi)2=argw,bminm1i=1∑m(wxi+b−yi)2
最小二乘法是常用的用于解决上述优化问题的方法,上面的均方误差损失L=L=L=1m∑i=1m(wxi+b−yi)2\frac{1}{m}\sum_{i=1}^m(wx_i+b-y_i)^2m1∑i=1m(wxi+b−yi)2分别对www和bbb求导,可以得到
∂L∂w=1m⋅2(w∑i=1mx22−∑i=1m(yi−b)xi)∂L∂b=1m⋅2∑i=1m(wxi+b−yi)w=m⋅∑i=1mxiyi−∑i=1mxi∑i=1myim⋅∑i=1mxi2−(∑i=1mxi)2b=∑i=1myi∑i=1mxi2−∑i=1mxi∑i=1mxiyim⋅∑i=1mxi2−(∑i=1mxi)2\begin{aligned} \frac{\partial \mathcal{L}}{\partial w} &= \frac{1}{m}\cdot 2\bigg(w\sum_{i=1}^m x_2^2-\sum_{i=1}^m(y_i-b)x_i\bigg) \\ \frac{\partial \mathcal{L}}{\partial b} &= \frac{1}{m}\cdot 2\sum_{i=1}^m(wx_i+b-y_i) \\ w &= \frac{m\cdot \sum_{i=1}^mx_i y_i - \sum_{i=1}^m x_i \sum_{i=1}^m y_i }{m\cdot \sum_{i=1}^m x_i ^2 - \big(\sum_{i=1}^m x_i \big)^2} \\ b &=\frac{\sum_{i=1}^m y_i \sum_{i=1}^m x_i ^2 - \sum_{i=1}^m x_i \sum_{i=1}^m x_i y_i }{m\cdot\sum_{i=1}^m x_i ^2 - \big(\sum_{i=1}^m x_i \big)^2} \end{aligned} ∂w∂L∂b∂Lwb=m1⋅2(wi=1∑mx22−i=1∑m(yi−b)xi)=m1⋅2i=1∑m(wxi+b−yi)=m⋅∑i=1mxi2−(∑i=1mxi)2m⋅∑i=1mxiyi−∑i=1mxi∑i=1myi=m⋅∑i=1mxi2−(∑i=1mxi)2∑i=1myi∑i=1mxi2−∑i=1mxi∑i=1mxiyi
这样我们就得到了线性回归的模型的参数,也就得到了基于训练数据的回归模型。根据以上结果,定义以下线性回归类:
class LinearRegression:def __init__(self, param=None):self.param = paramdef fit(self, x, y):sum_x = np.sum(x)sum_y = np.sum(y)mul_xy = np.multiply(x, y)sum_mul = np.sum(mul_xy)x_square = np.square(x)sum_xsqr = np.sum(x_square)y_square = np.square(y)sum_ysqr = np.sum(y_square)div = x.shape[0] * sum_xsqr - np.square(sum_x) # 分母coef = x.shape[0] * sum_mul - sum_x * sum_y # w的分子intercept = sum_y * sum_xsqr - sum_x * sum_mul # b的分子self.w = coef / divself.b = intercept /divdef predict(self, x):return self.w * x + self.b
先初始化线性回归类,然后基于训练数据进行拟合
LR = LinearRegression()
LR.fit(x_train,y_train)
用拟合出来的模型,先在训练数据上对比看看预测结果和真实yyy值的差异:
pred_y_train = LR.predict(x_train)
再来看在测试数据上的表现
pred_y_test = LR.predict(x_test)
图中的蓝色线,拟合了面积和房价之间的映射关系,就可以用来根据面积来预测房价啦。
最小二乘法学习多元线性回归模型
当我们关心的房价影响因素不止面积,还有所在地区便利程度、开发商品质和所在学区等时,每个样本的特征x\boldsymbol{x}x表示一个多维向量,相应的要学习的回归模型变为y=wTx+b=w1x1+w2x2+⋯+wdxd+by=\boldsymbol{w}^{T}\boldsymbol{x}+b=w_1x_1+w_2x_2+\cdots+w_dx_d+by=wTx+b=w1x1+w2x2+⋯+wdxd+b。将参数w\boldsymbol{w}w和bbb合并为一个参数a\boldsymbol{a}a,要学习的模型为y=xay=\boldsymbol{x}\boldsymbol{a}y=xa。类似地,仍可以使用最小二乘法来对参数a\boldsymbol{a}a进行估计。
将数据写成矩阵的形式,即X∈Rm×(d+1)\boldsymbol{X}\in\mathbb{R}^{m\times(d+1)}X∈Rm×(d+1)每一行为一条高维数据,参数的优化目标变为:
a∗=argminaL=argmina1m(y−Xa)T(y−Xa)\begin{aligned} \boldsymbol{a}^* &=\arg \min_{\boldsymbol{a}}\mathcal{L} \\ &=\arg \min_{\boldsymbol{a}} \frac{1}{m}(\boldsymbol{y}-\boldsymbol{X}\boldsymbol{a})^T (\boldsymbol{y}-\boldsymbol{X}\boldsymbol{a}) \end{aligned} a∗=argaminL=argaminm1(y−Xa)T(y−Xa)
对参数a\boldsymbol{a}a进行矩阵运算的求导,得
∂L∂a=1m⋅2XT(Xa−y)\begin{aligned} \frac{\partial{\mathcal{L}}}{\partial\boldsymbol{a}}=\frac{1}{m}\cdot 2\boldsymbol{X}^T(\boldsymbol{X}\boldsymbol{a}-\boldsymbol{y}) \end{aligned} ∂a∂L=m1⋅2XT(Xa−y)
令上式为0即可得到参数a\boldsymbol{a}a的最优解,当XTX\boldsymbol{X}^T\boldsymbol{X}XTX为满秩矩阵或正定矩阵时,可以得到
a∗=(XTX)−1XTy\begin{aligned} \boldsymbol{a}^* = (\boldsymbol{X}^T\boldsymbol{X})^{-1}\boldsymbol{X}^T\boldsymbol{y} \end{aligned} a∗=(XTX)−1XTy
若XTX\boldsymbol{X}^T\boldsymbol{X}XTX可逆,可用numpy
库的linalg.inv
求解;而当不可逆时,求得伪逆
,又称广义逆矩阵,是逆矩阵的推广形式,可用linalg.pinv
求解。
重新进行线性回归求解,相应的代码如下
class LinearRegression_multi:def __init__(self, param=None):self.param = paramdef fit(self, x, y):self.a = np.linalg.pinv(x.T.dot(x)).dot(x.T).dot(y) def predict(self, x):return np.dot(x, self.a)
数据上,简单地增设第二维特征开发商品质,为0到1之间的打分,一共两维特征如下
x = np.array([[100, 0.8], [ 60, 0.6],[ 90, 0.2],[120, 0.5],[150, 0.8],[170, 0.6],[110, 0.5],[200, 0.5],[250, 0.5],[220, 0.6],[ 30, 0.4],[ 70, 0.9],[ 80, 0.8],[140, 0.9],[ 95, 0.5]])
在分割训练数据和测试数据之前,注意这里还有两点需要注意
第二维特征和第一维特征的量纲差异相对大,但是不需要先进行归一化、标准化等操作
需要将特征数据和全1的向量拼接,这样才能将参数w\boldsymbol{w}w和bbb合并为一个参数a\boldsymbol{a}a进行求解
one = np.ones((len(x),1))
x = np.concatenate((x_normed, one),axis=1)
举例数据较少,我们仍然直接将数据的前10个作为训练集,后5个作为测试集进行划分。数据标签y
仍同前一个例子。
y = np.array([405, 260, 465, 600, 750, 780, 500, 930, 999, 780, 149, 350, 404, 650, 500])
x_train = x[:10]
y_train = y[:10]
x_test = x[10:]
y_test = y[10:]
先初始化多元线性回归类,然后基于训练数据进行拟合
LR_multi = LinearRegression_multi()
LR_multi.fit(x_train,y_train)
用拟合出来的模型,先在训练数据上对比看看预测结果和真实yyy值的差异:
pred_y_train = LR_multi.predict(x_train)
再来看在测试数据上的表现
pred_y_test = LR.predict(x_test)
至此线性回归模型,拟合了面积、开发商品质和房价之间的映射关系,就可以用来根据面积来预测房价啦。
梯度下降法学习回归模型
当线性模型不再满足我们拟合数据的需求时,最小二乘法使导数为0不一定能求出最优的闭式解,这个时候可以解决非线性优化的梯度下降法就该出场啦。
梯度下降法采用逐步迭代的方式去不断逼近极值点,即均方误差最小的地方,对应的参数即为最优参数。对于前述线性回归,损失函数和对应的梯度可以写成
L(θ)=1m(Xθ−y)T(Xθ−y)▽θL(θ)=▽θ(1m(Xθ−y)T(Xθ−y))=2mXT(Xθ−y)\begin{aligned} \mathcal{L}(\theta) &= \frac{1}{m} (\boldsymbol{X}\theta - \boldsymbol{y})^T(\boldsymbol{X}\theta - \boldsymbol{y}) \\ \triangledown_{\theta}\mathcal{\mathcal{L}}(\theta) &= \triangledown_{\theta} \Big(\frac{1}{m} (\boldsymbol{X}\theta - \boldsymbol{y})^T(\boldsymbol{X}\theta - \boldsymbol{y})\Big) \\ &= \frac{2}{m}\boldsymbol{X}^T(\boldsymbol{X}\theta - \boldsymbol{y}) \end{aligned} L(θ)▽θL(θ)=m1(Xθ−y)T(Xθ−y)=▽θ(m1(Xθ−y)T(Xθ−y))=m2XT(Xθ−y)
每次迭代的时候,按照学习率(步长)α\alphaα更新参数即可
θ←θ−α▽θL(θ)\begin{aligned} \theta \leftarrow \theta - \alpha \triangledown_{\theta}\mathcal{\mathcal{L}}(\theta) \end{aligned} θ←θ−α▽θL(θ)
设置初始化参数、学习率、迭代次数,依照上述公式进行迭代,我们就可以得到相应的梯度下降结果。具体代码如下:
class LinearRegression_gd:def __init__(self, param=None):self.param = paramdef gradientDescent(self, x, y, alpha, iteration): m = len(x)self.theta = np.zeros(x.shape[1])for i in range(iteration):gradient = 2/m * np.dot(x.T, (np.dot(x, self.theta) - y)) self.theta = self.theta - alpha * gradientcost = 2/m * (np.dot(x, self.theta) - y).T.dot(np.dot(x, self.theta) - y)print('cost', cost)return costdef predict(self, x):return np.dot(x, self.theta)
注意这里在进行梯度下降前,对数据进行预处理的时候,需要先进行归一化或标准化的操作,否则会不同维度的数据可能相差太大,不能用同一步长进行迭代更新。这里选择了min-max normalization
x_normed = (x - x.min(axis=0)) / (x.max(axis=0) - x.min(axis=0))
先初始化回归类,然后基于训练数据进行拟合
LR_gd = LinearRegression_gd()
LR_gd.gradientDescent(x_train, y_train, alpha = 0.5, iteration = 200)
用拟合出来的模型,先在训练数据上对比看看预测结果和真实yyy值的差异:
pred_y_train = LR_gd.predict(x_train)
再来看在测试数据上的表现
pred_y_test = LR_gd.predict(x_test)
结果和前面的基于最小二乘法的多元线性回归是一样的,感兴趣的同学可以自己check一下~
其他非线性回归的梯度下降法是类似的,但是需要根据不同的非线性关系进行相应的调整。
更多内容,欢迎关注我们的公众号:AI算法词典
我们的团队致力于拆解AI算法,每篇附上代码实现,构建AI学习从入门到精通的词典路径!
来找我们玩!热烈欢迎交流哦
AI 人工智能 Python之机器学习-波斯顿房价预测 波士顿房价预测 导入模块 import pandas as pd import numpy as np import matplotlib.py ... 写在前面: 首先感谢兄弟们的订阅,让我有创作的动力,在创作过程我会尽最大能力,保证作品的质量,如果有问题,可以私信我,让我们携手共进,共创辉煌. 本次实战的项目是:基于机器学习的房价预测研究(附完整代 ... 线性回归通常是人们为机器学习和数据科学学习的第一个算法.它简单易懂,但是由于其功能有限,在实际业务中并不是最佳选择.大多数情况下,线性回归被用作基线模型来评估和比较研究中的新方法. 在处理实际问题时, ... 爬虫能做什么 爬虫除了能够获取互联网的数据以外还能够帮我们完成很多繁琐的手动操作,这些操作不仅仅包括获取数据,还能够添加数据,比如: 投票 管理多个平台的多个账户(如各个电商平台的账号) 微信聊天机器 ... 逻辑回归(Logistic Regression,LR).在Kaggle竞赛的统计中,LR算法以63.5%的出产率,荣获各领域中"出场率最高的算法"这一殊荣.在实际场景中,逻辑回归 ... 在上一篇文章<机器学习笔记(9)--深入理解逻辑回归算法及其Python实现>中,详细学习了逻辑回归算法的分类原理和使用梯度下降法来最小化损失函数的数学推导过程,从而拟合出分类函数的参数θ ... 背景 kaggle地址:https://www.kaggle.com/c/house-prices-advanced-regression-techniques/overview 赛题给我们79个描述 ... 来源:kaggle Machine Learning Micro-Course Home Page Recap Here's the code you've written so far. Start ... 前言 前一阵学校有五一数模节校赛,和朋友一起参加做B题,波士顿房价预测,算是第一次自己动手实现一个简单的小网络吧,虽然很简单,但还是想记录一下. 题目介绍 波士顿住房数据由哈里森和 ...【机器学习】从房价预测问题看回归算法相关推荐
最新文章
热门文章