基于线性回归(Linear Regression)的房屋价格预测

一、知识预警

1.1 线性代数

( A T ) T = A (A^\mathrm{T})^\mathrm{T}=A (AT)T=A$
( A + B ) T = A T + B T (A+B)^\mathrm{T}=A^\mathrm{T}+B^\mathrm{T} (A+B)T=AT+BT
( λ A ) T = λ A T (\lambda A)^\mathrm{T}=\lambda A^\mathrm{T} (λA)T=λAT
( A B ) T = B T A T (AB)^\mathrm{T}=B^\mathrm{T}A^\mathrm{T} (AB)T=BTAT
( A − 1 ) − 1 = A (A^{-1})^{-1}=A (A1)1=A
( A B ) − 1 = B − 1 A − 1 (AB)^{-1}=B^{-1}A^{-1} (AB)1=B1A1

1.2 矩阵微积分

为了书写简便,我们通常把单个函数对多个变量或者多元函数对单个变量的偏导数写成向量和矩阵的形式,使其可以被当成一个整体处理.矩阵微积分(Matrix Calculus)是多元微积分的一种表达方式,即使用矩阵和向量来表示因变量每个成分关于自变量每个成分的偏导数。

标量关于向量的偏导数:对于M维向量 x ∈ R x \in \mathbb{R} xR和函数 y = f ( x ) ∈ R y=f(x) \in \mathbb{R} y=f(x)R,则关于 x x x的偏导数为:

∂ y ∂ x = [ ∂ y ∂ x 1 , ⋯   , ∂ y ∂ x M ] ⊤ ∈ R M × 1 , \frac{\partial y}{\partial \boldsymbol{x}}=\left[\frac{\partial y}{\partial x_{1}}, \cdots, \frac{\partial y}{\partial x_{M}}\right]^{\top} \quad \in \mathbb{R}^{M \times 1}, xy=[x1y,,xMy]RM×1,
向量关于标量的偏导数:对于标量𝑥 ∈ ℝ和函数𝒚 = 𝑓(𝑥) ∈ R N \mathbb{R}^N RN,则𝒚关于𝑥 的
偏导数为
∂ y ∂ x = [ ∂ y 1 ∂ x , ⋯   , ∂ y N ∂ x ] ∈ R 1 × N \frac{\partial \boldsymbol{y}}{\partial x}=\left[\frac{\partial y_{1}}{\partial x}, \cdots, \frac{\partial y_{N}}{\partial x}\right] \quad \in \mathbb{R}^{1 \times N} xy=[xy1,,xyN]R1×N

向量关于向量的偏导数 对于 𝑀 维向量 𝒙 ∈ ℝ𝑀 和函数 𝒚 = 𝑓(𝒙) ∈ ℝ𝑁,则
𝑓(𝒙)关于𝒙的偏导数(分母布局)为
∂ f ( x ) ∂ x = [ ∂ y 1 ∂ x 1 ⋯ ∂ y N ∂ x 1 ⋮ ⋱ ⋮ ∂ y 1 ∂ x M ⋯ ∂ y N ∂ x M ] ∈ R M × N \frac{\partial f(\boldsymbol{x})}{\partial \boldsymbol{x}}=\left[\begin{array}{ccc} \frac{\partial y_{1}}{\partial x_{1}} & \cdots & \frac{\partial y_{N}}{\partial x_{1}} \\ \vdots & \ddots & \vdots \\ \frac{\partial y_{1}}{\partial x_{M}} & \cdots & \frac{\partial y_{N}}{\partial x_{M}} \end{array}\right] \in \mathbb{R}^{M \times N} xf(x)= x1y1xMy1x1yNxMyN RM×N

向量函数及其导数
∂ x ∂ x = I \frac{\partial \pmb x}{\partial \pmb x} = I xx=I ∂ A x ∂ x = A T \frac{\partial \pmb A \pmb x}{\partial \pmb x} = \pmb A^\mathrm{T} xAx=AT ∂ x T A ∂ x = A \frac{ \partial \pmb x^\mathrm{T} A}{\partial \pmb x} = \pmb A xxTA=A

二、线性回归(Linear Regression)

2.1 什么是回归分析?

回归分析这是一个来自统计学的概念。回归分析是指一种预测性的建模技术,主要是研究自变量和因变量的关系。通常使用线/曲线来拟合数据点,然后研究如何使曲线到数据点的距离差异最小。如果使用直线进行拟合,则为线性回归(一元线性回归、多元线性回归);如果是对非线性关系进行建模,则为多项式回归。
例如,存在以下数据(左图)。然后我们拟合一条曲线 f ( x ) f(x) f(x)右图,回归分析的目标就是要拟合一条曲线,让图中红色线段加起来的和最小。

线性回归(Linear Regression)是回归分析的一种,是机器学习和统计学中最基础和最广泛应 用的模型,是一种对自变量和因变量之间关系进行建模的回归分析.自变量数量为1时称为简单回归,自变量数量大于1时称为多元回归。
  1. 假设目标值(因变量)与特征值(自变量)之间线性相关,即满足一个多元一次方程,如: f ( x ) = ( w 1 x 1 + … + w n x n + b ) f(x)=(w_1x_1+…+w_nx_n+b) f(x)=(w1x1++wnxn+b)

  2. 然后构建损失函数。

  3. 最后通过令损失函数最小来确定参数。(最关键的一步)

2.2 一元线性回归

一元线性回归(一元:只有一个未知自变量;线性:自变量 x x x的次数都为1次)。

f ( x ) = w x + b \begin{align} f(x)=wx+b \end{align} f(x)=wx+b
N N N组数据,自变量 x = ( x ( 1 ) , x ( 2 ) , … , x ( n ) ) x=(x^{(1)},x^{(2)},…,x^{(n)}) x=(x(1),x(2),,x(n)),因变量 y = ( y ( 1 ) , y ( 2 ) , … , y ( n ) ) y=(y^{(1)},y^{(2)},…,y^{(n)}) y=(y(1),y(2),,y(n)),则训练集 D = { ( x ( n ) , y ( n ) ) } n = 1 N \mathcal{D}=\{(x^{(n)} ,y^{(n)})\}_{n=1}^N D={(x(n),y(n))}n=1N,然后我们假设它们之间的关系是:
y ^ ( n ) = f ( x ) = w x ( n ) + b \begin{align}\hat y^{(n)}=f(x)=wx^{(n)}+b \end{align} y^(n)=f(x)=wx(n)+b
那么线性回归的目标就是如何让 f ( x ) f(x) f(x) y y y之间的差异最小,换句话说就是 a a a b b b取什么值的时候 f ( x ) f(x) f(x) y y y最接近。
这里我们得先解决另一个问题,就是如何衡量 f ( x ) f(x) f(x) y y y之间的差异。在回归问题中,均方误差是回归任务中最常用的性能度量。记 J ( a , b ) J(a,b) J(a,b) f ( x ) f(x) f(x) y y y之间的差异,即预测值和真实值的差异:

给定一组包含N个训练样本的数据集 D = { ( x ( n ) , y ( n ) ) } n = 1 N \mathcal{D}=\{(x^{(n)} ,y^{(n)})\}_{n=1}^N D={(x(n),y(n))}n=1N,则假设函数为:

L ( w , b ) = ∑ i = 1 N ( f ( x ( n ) ) − y ( n ) ) 2 = ( w x ( n ) + b − y ( n ) ) 2 \begin{align} \mathcal{L}(w,b) &=\sum_{i=1}^N \left(f(x^{(n)}) - y^{(n)}\right)^2 \\ &=(wx^{(n)}+b-y^{(n)})^2 \end{align} L(w,b)=i=1N(f(x(n))y(n))2=(wx(n)+by(n))2
这里称 L ( w , b ) \mathcal{L}(w,b) L(w,b)为损失函数,明显可以看出 L ( w , b ) \mathcal{L}(w,b) L(w,b)是二次函数,所以有最小值。当 L ( w , b ) \mathcal{L}(w,b) L(w,b)取最小值的时候, f ( x ) f(x) f(x) y y y的差异最小,然后我们可以通过最小化 L ( w , b ) \mathcal{L}(w,b) L(w,b)来确定 a a a b b b的值。求解该问题有很多方法,首先可以想到求偏导。

2.3 多元线性回归

现实中的数据可能是比较复杂的,自变量也可能不止一个,例如,影响房屋价格也很可能不止房屋面积一个因素,可能还有是否在地铁附近,房间数,层数,建筑年代等诸多因素,表示为 x = ( x 1 , x 2 , . . . , x D ) x=(x_1,x_2,...,x_D) x=(x1,x2,...,xD)。不过,这些因素对房价影响的权重是不同的,因此,我们可以使用多个权重 w = ( w 1 , w 2 , . . . , w D ) w=(w_1,w_2,...,w_D) w=(w1,w2,...,wD)来表示多个因素与房屋价格的关系:
y ^ = f ( x ) = ( w 1 x 1 + … + w D x D + b ) \begin{align} \hat{y}=f(x)&=(w_1x_1+…+w_Dx_D+b)\\ \end{align} y^=f(x)=(w1x1++wDxD+b)
给定一组包含 N N N个训练样本的数据集 D = { ( x ( n ) , y ( n ) ) } n = 1 N \mathcal{D}=\{(x^{(n)} ,y^{(n)})\}_{n=1}^N D={(x(n),y(n))}n=1N,则假设函数为:
y ^ ( n ) = f ( x ) = ( w 1 x 1 ( n ) + w 2 x 2 ( n ) + … + w D x D ( n ) + b ) = ∑ d = 1 D w d x d ( n ) + b \begin{align} \hat{y}^{(n)}=f(x) &=(w_1x_1^{(n)}+w_2x_2^{(n)}+…+w_Dx_D^{(n)}+b) \\ &= \sum_{d=1}^Dw_dx_d^{(n)}+b \end{align} y^(n)=f(x)=(w1x1(n)+w2x2(n)++wDxD(n)+b)=d=1Dwdxd(n)+b
写成向量形式:

y ^ ( n ) = f ( x ( n ) ) = w x ( n ) + b \begin{align} \hat{\pmb{y}}^{(n)}=f( \pmb{x}^{(n)})=\pmb{w} \pmb{x}^{(n)}+b \end{align} y^(n)=f(x(n))=wx(n)+b

为表示方便,重新定义向量 w : = w ⨁ b = [ w 1 w 2 ⋮ w D b ] \pmb w:= \pmb w \bigoplus b=\begin{bmatrix} w_{1} \\ w_{2} \\ {\vdots}\\ w_{D} \\ b \\ \end{bmatrix} w:=wb= w1w2wDb x : = x ⨁ 1 = [ x 1 x 2 ⋮ x D 1 ] \pmb x:=\pmb x \bigoplus 1=\begin{bmatrix} x_{1} \\ x_{2} \\ {\vdots}\\ x_{D} \\ 1 \\ \end{bmatrix} x:=x1= x1x2xD1 ,写成增广向量的形式:

y ^ = f ( x ) = w T x \begin{align} \hat{\pmb{y}}=f( \pmb{x})=\pmb{w ^\mathrm T} \pmb{x} \end{align} y^=f(x)=wTx

尽管公式 ( 7 ) (7) (7)可以描述变量之间的关系,但是一般机器学习领域更喜欢使用公式 ( 9 ) (9) (9)这样的向量乘法的形式。这不仅因为这样表示起来更简单,也是因为现代计算机对向量计算做了大量优化,无论是CPU还是GPU都喜欢向量计算,并行地处理数据,可以得到成百上千倍的加速比。需要注意的是,公式中不加粗的表示标量,加粗的表示向量或矩阵。

比一元线性回归更为复杂的是,多元线性回归组成的不是直线,是一个多维空间中的超平面,数据点散落在超平面的两侧。多元线性回归的损失函数仍然使用预测值-真实值的平方来计算,损失函数为所有样本点距离超平面的距离之和:

L ( w , b ) = ∑ n = 1 N ( f ( x ( n ) ) − y ( n ) ) 2 = ∑ n = 1 N ( w 1 x 1 ( n ) + w 2 x 2 ( n ) + + … + w D x D ( n ) + b − y ( n ) ) 2 = ∑ n = 1 N ( ( ∑ d = 1 D w d x d ( n ) + b ) − y ( n ) ) 2    ⟺    1 2 ∑ n = 1 N ( ( ∑ d = 1 D w d x d ( n ) + b ) − y ( n ) ) 2 \begin{align} \mathcal{L}(w,b) &=\sum_{n=1}^N \left(f(x^{(n)}) - y^{(n)}\right)^2 \\ &=\sum_{n=1}^N(w_1x_1^{(n)}+w_2x_2^{(n)}++…+w_Dx_D^{(n)}+b -y^{(n)})^2\\ &=\sum_{n=1}^N \left( \left( \sum_{d=1}^Dw_dx_d^{(n)}+b \right)-y^{(n)} \right)^2\\ &\iff \textcolor{red}{\frac{1}{2} }\sum_{n=1}^N \left( \left( \sum_{d=1}^Dw_dx_d^{(n)}+b \right)-y^{(n)} \right)^2\\ \end{align} L(w,b)=n=1N(f(x(n))y(n))2=n=1N(w1x1(n)+w2x2(n)+++wDxD(n)+by(n))2=n=1N((d=1Dwdxd(n)+b)y(n))221n=1N((d=1Dwdxd(n)+b)y(n))2

写成矩阵形式,令 X = [ x 1 ( 1 ) x 1 ( 2 ) … x 1 ( N ) x 2 ( 1 ) x 2 ( 2 ) … x 2 ( N ) ⋮ ⋮ ⋮ ⋮ x D ( 1 ) x D ( 2 ) … x D ( N ) 1 1 … 1 ] \pmb X=\begin{bmatrix} x_{1}^{(1)} & x_{1}^{(2)} & {\dots} &x_{1}^{(N)}\\ x_{2}^{(1)} & x_{2}^{(2)} & {\dots} &x_{2}^{(N)}\\ {\vdots} & {\vdots} & {\vdots} & {\vdots}\\ x_{D}^{(1)} &x_{D}^{(2)} & {\dots}&x_{D}^{(N)} \\ 1 & 1 & {\dots} & 1\\ \end{bmatrix} X= x1(1)x2(1)xD(1)1x1(2)x2(2)xD(2)1x1(N)x2(N)xD(N)1 X \pmb X X的每一列代表一个样本, y = [ y ( 1 ) y ( 2 ) ⋮ y ( N ) ] \pmb y=\begin{bmatrix} y^{(1)}\\y^{(2)}\\ \vdots \\y^{(N)}\end{bmatrix} y= y(1)y(2)y(N) 则写成矩阵形式:
L ( w ) = 1 2 ( X T w − y ) T ( X T w − y ) = 1 2 ∣ ∣ X T w − y ∣ ∣ 2 \begin{align} \mathcal{L}(w) &=\frac{1}{2} ( \pmb X^\mathrm{T} \pmb w- \pmb y)^\mathrm{T}( \pmb X^\mathrm{T} \pmb w- \pmb y)\\ &=\frac{1}{2} || \pmb X^\mathrm{T} \pmb w-\pmb y ||^2 \end{align} L(w)=21(XTwy)T(XTwy)=21∣∣XTwy2
目标是最小化损失函数式(15),这是一个无约束多元函数求极值问题,有梯度下降、牛顿法、共轭梯度法,智能优化算法(粒子群算法等、遗传算法、鲸鱼算法等),但首先想到的解法是求导令 ∂ L ( w ) ∂ w = 0 \frac{\partial \mathcal L(w)}{\partial w}=0 wL(w)=0

∂ ∂ w L ( w ) = X ( X T w − y ) = X X T w − X y = 0 X X T w = X y w = ( X X T ) − 1 X y \begin{align} \frac{\partial}{\partial w} \mathcal L(w) &=\pmb X (\pmb X^\mathrm{T} \pmb w-\pmb y)\\ &=\pmb X \pmb X^\mathrm{T}\pmb w - \pmb X\pmb y = 0 \\ \pmb X \pmb X^\mathrm{T}\pmb w&=\pmb X\pmb y\\ \pmb w&= (\pmb X \pmb X^\mathrm{T})^{-1}\pmb X \pmb y \end{align} wL(w)XXTww=X(XTwy)=XXTwXy=0=Xy=(XXT)1Xy

以上求偏导令=0的解法,就是最小二乘法,这里的二乘表示用平方来度量观测点与估计点的远近(在古汉语中“平方”称为“二乘”);“最小”指的是参数的估计值要保证各个观测点与估计点的距离的平方和达到最小,是minimize最小化。


在统计学上把单变量线性回归和多变量线性回归统称为一元线性回归、多元线性回归。

三、基于线性回归的房屋价格预测

线性回归使用梯度下降拟合参数,步骤为:

  1. 初始化最大迭代次数maxIter,学习率alpha;
  2. 导入数据:np.loadtxt(),构建假设函数(增广权重矩阵、增广特征向量) w = [ 0 0 ] \pmb w=\begin{bmatrix} 0 \\ 0 \end{bmatrix} w=[00]
  3. 由式(7)计算梯度;
  4. 由式(9)更新梯度;
  5. 由式(6)计算损失函数;
  6. 判断maxIter>当前迭代次数?,是则转step3,否则算法结束,输出增广权重矩阵 w \pmb{w} w

3.1 一元线性回归

数据集介绍:吴恩达作业(ex1data1.txt)

6.1101,17.592
5.5277,9.1302
8.5186,13.662
7.0032,11.854
5.8598,6.8233
8.3829,11.886
7.4764,4.3483
8.5781,12
6.4862,6.5987
5.0546,3.8166
5.7107,3.2522
14.164,15.505
5.734,3.1551
8.4084,7.2258
5.6407,0.71618
5.3794,3.5129
6.3654,5.3048
5.1301,0.56077
6.4296,3.6518
7.0708,5.3893
6.1891,3.1386
20.27,21.767
5.4901,4.263
6.3261,5.1875
5.5649,3.0825
18.945,22.638
12.828,13.501
10.957,7.0467
13.176,14.692
22.203,24.147
5.2524,-1.22
6.5894,5.9966
9.2482,12.134
5.8918,1.8495
8.2111,6.5426
7.9334,4.5623
8.0959,4.1164
5.6063,3.3928
12.836,10.117
6.3534,5.4974
5.4069,0.55657
6.8825,3.9115
11.708,5.3854
5.7737,2.4406
7.8247,6.7318
7.0931,1.0463
5.0702,5.1337
5.8014,1.844
11.7,8.0043
5.5416,1.0179
7.5402,6.7504
5.3077,1.8396
7.4239,4.2885
7.6031,4.9981
6.3328,1.4233
6.3589,-1.4211
6.2742,2.4756
5.6397,4.6042
9.3102,3.9624
9.4536,5.4141
8.8254,5.1694
5.1793,-0.74279
21.279,17.929
14.908,12.054
18.959,17.054
7.2182,4.8852
8.2951,5.7442
10.236,7.7754
5.4994,1.0173
20.341,20.992
10.136,6.6799
7.3345,4.0259
6.0062,1.2784
7.2259,3.3411
5.0269,-2.6807
6.5479,0.29678
7.5386,3.8845
5.0365,5.7014
10.274,6.7526
5.1077,2.0576
5.7292,0.47953
5.1884,0.20421
6.3557,0.67861
9.7687,7.5435
6.5159,5.3436
8.5172,4.2415
9.1802,6.7981
6.002,0.92695
5.5204,0.152
5.0594,2.8214
5.7077,1.8451
7.6366,4.2959
5.8707,7.2029
5.3054,1.9869
8.2934,0.14454
13.394,9.0551
5.4369,0.61705

餐馆老板想在不同城市开分店,并收集了这些城市的 人口数和当地餐馆的利润作为训练样本保存在 ex1data1.txt。该数据集为97行×2列,第一列为人口数(万),第二列为餐馆利润(万元)。请利用线性回归,根据城市的人口数据预测其利润。

3.1.1 加载数据

导入库:

import numpy as np  			# 科学计算库,处理多维数组,进行数据分析
import pandas as pd				# 基于 NumPy 的一种解决数据分析任务工具
import matplotlib.pyplot as plt # 提供一个类似 Matlab 的绘图框架

导入数据集:

data = np.loadtxt("./resources/ex1data1.txt", delimiter=',', dtype=np.float64)

数据级 D = { ( x ( i ) , y ( i ) ) } i = 1 N = 97 \mathcal{D}=\{{(x^{(i)}, y^{(i)})} \}_{i=1}^{N=97} D={(x(i),y(i))}i=1N=97 x ( i ) x^{(i)} x(i)为第 i i i个样本,即第 i i i行的人口数, N N N为样本数量。

3.1.2 假设函数

已知单变量线性回归的假设函数为 f ( x ) = w x + b f(x)=wx+b f(x)=wx+b,进一步向量乘法的形式,表示起来更简单,易于编程计算,这里构建增广权重向量 w = [ w b ] \pmb w=\begin{bmatrix}w \\ b \end{bmatrix} w=[wb],增广特征向量 x = [ x 1 ] \pmb x=\begin{bmatrix}x \\ 1 \end{bmatrix} x=[x1]
f ( x ) = w x + b = [ w b ] [ x 1 ] = w T x = x w \begin{align} f(x) &= wx+b \\ &=[w \quad b] \begin{bmatrix} x \\1\end{bmatrix}\\ &= \pmb{w}^\mathrm{T} \pmb{x}\\ &= \pmb{x}\pmb{w} \end{align} f(x)=wx+b=[wb][x1]=wTx=xw

获取数据集中的输入向量 X X X,需要在数据集加入 x 0 = 1 x_0=1 x0=1 的一列:

data = np.loadtxt("ex1data1.txt", delimiter=",", dtype=np.float64)
y = data[:, 1:2]
X = np.insert(data[:, 0:1], obj=1, values=1, axis=1)

初始化参数 w = [ 0 0 ] \pmb w=\begin{bmatrix} 0 \\ 0 \end{bmatrix} w=[00]为2行1列

w = np.zeros(X.shape[1]).reshape(2, 1)

3.1.3 损失函数(代价函数)

X = [ x ( 1 ) 1 x ( 2 ) 1 ⋮ ⋮ x ( N ) 1 ] \pmb X=\begin{bmatrix} x^{(1)} &1\\ x^{(2)} &1\\ \vdots & \vdots\\ x^{(N) } &1 \end{bmatrix} X= x(1)x(2)x(N)111 y = [ y ( 1 ) y ( 2 ) ⋮ y ( N ) ] \pmb y=\begin{bmatrix}y^{(1)} \\y^{(2)} \\ \vdots \\ y^{(N)}\end{bmatrix} y= y(1)y(2)y(N) ,则损失函数 L ( w ) \mathcal{L}(w) L(w)可以表示为:

L ( w ) = 1 2 N ∑ i = 1 N ( f ( x ( i ) ) − y ( i ) ) 2 = 1 2 N ∣ ∣ X w − y ∣ ∣ 2 \begin{align} \mathcal{L}(w)&=\frac{1}{2N} \sum_{i=1}^N \left(f(x^{(i)}) - y^{(i)} \right)^2\\ &= \frac{1}{2N} ||\pmb X \pmb w- \pmb{y}||^2 \end{align} L(w)=2N1i=1N(f(x(i))y(i))2=2N1∣∣Xwy2

def loss_func(w, X, y):
    return np.sum(np.square(X.dot(w) - y)) / 2 * X.shape[0]

3.1.4 梯度下降函数

首先对 L ( w ) \mathcal{L(w)} L(w)求导, ∇ L ( w ) = 1 N X T ( X w − y ) \begin{align} \nabla \mathcal{L(w)}=\frac{1}{N} \pmb{X}^\mathrm{T}(\pmb{Xw-y}) \end{align} L(w)=N1XT(Xwy),这里用到了向量函数及其导数公式: ∂ A x ∂ x = A T \frac{\partial \pmb{Ax}}{\partial \pmb{x}}=\pmb{A}^\mathrm{T} xAx=AT。故梯度下降更新公式:
w : = w − α ∇ L ( w ) : = w − α 1 N X T ( X w − y ) \begin{align} \pmb w&:=\pmb w-\alpha \nabla \mathcal{L(w)}\\ &:= \pmb w- \alpha \frac{1}{N} \pmb{X}^\mathrm{T}(\pmb{Xw-y}) \end{align} w:=wαL(w):=wαN1XT(Xwy)

def grad(w, X, y):
    return (X.T @ (X.dot(w) - y)) / X.shape[0]
def grad_descent(w, X, y, alpha, maxIter):
    loss = []
    for i in range(maxIter):
        w = w - alpha * grad(w, X, y)
        cost = loss_func(w, X, y)
        loss.append(cost)
    return w, loss

3.1.6 完整代码

import numpy as np
from matplotlib import pyplot as plt


def loss_func(w, X, y):
    return np.sum(np.square(X.dot(w) - y)) / 2 * X.shape[0]


def grad(w, X, y):
    return (X.T @ (X.dot(w) - y)) / X.shape[0]


def grad_descent(w, X, y, alpha, maxIter):
    loss = []
    for i in range(maxIter):
        w = w - alpha * grad(w, X, y)
        cost = loss_func(w, X, y)
        loss.append(cost)
    return w, loss


def paint(loss, data):
    fig = plt.figure(figsize=(10, 4))
    # 画第1个图:折线图
    ax1 = fig.add_subplot(121)
    ax1.plot([i for i in range(maxIter)], loss, color="#FF0000")
    ax1.set_title("loss function")
    # 画第2个图:散点图
    ax2 = fig.add_subplot(122)
    ax2.scatter(data[:, 0], data[:, 1])
    ax2.plot([5.0, 22.5], [5.0 * w[0] + w[1], 22.5 * w[0] + w[1]], color="#FF0000")
    ax2.set_title("linear regression")
    plt.show()


if __name__ == "__main__":
    maxIter = 10000
    data = np.loadtxt("ex1data1.txt", delimiter=",", dtype=np.float64)

    y = data[:, 1:2]
    X = np.insert(data[:, 0:1], obj=1, values=1, axis=1)
    w = np.zeros(X.shape[1]).reshape(2, 1)
    w, loss = grad_descent(w, X, y, alpha=0.002, maxIter=maxIter)
    print(w)
    paint(loss, data)

最后拟合得到的权重矩阵为 w = [ 1.18218457 − 3.78778781 ] \pmb w=\begin{bmatrix} 1.18218457\\ -3.78778781 \end{bmatrix} w=[1.182184573.78778781],损失函数收敛图、线性回归拟合结果如图所示:

3.2 多变量线性回归

吴恩达机器学习线性回归例题ex1data2.txt数据集,该数据集共47行×3列,第一列为房子的大小,第二列为卧室数量,第三列为房子的价格,该问题有2个变量(房子的大小,卧室的数量)。请利用线性回归,根据房子的大小和卧室的数量数据预测房子的价格。

2104,3,399900
1600,3,329900
2400,3,369000
1416,2,232000
3000,4,539900
1985,4,299900
1534,3,314900
1427,3,198999
1380,3,212000
1494,3,242500
1940,4,239999
2000,3,347000
1890,3,329999
4478,5,699900
1268,3,259900
2300,4,449900
1320,2,299900
1236,3,199900
2609,4,499998
3031,4,599000
1767,3,252900
1888,2,255000
1604,3,242900
1962,4,259900
3890,3,573900
1100,3,249900
1458,3,464500
2526,3,469000
2200,3,475000
2637,3,299900
1839,2,349900
1000,1,169900
2040,4,314900
3137,3,579900
1811,4,285900
1437,3,249900
1239,3,229900
2132,4,345000
4215,4,549000
2162,4,287000
1664,2,368500
2238,3,329900
2567,4,314000
1200,3,299000
852,2,179900
1852,4,299900
1203,3,239500

数据级 D = { ( x 1 ( i ) , x 2 ( i ) , y ( i ) ) } i = 1 N = 47 \mathcal{D}=\{{(x_1^{(i)},x_2^{(i)}, y^{(i)})} \}_{i=1}^{N=47} D={(x1(i),x2(i),y(i))}i=1N=47 x ( i ) x^{(i)} x(i)为第 i i i个样本,即第 i i i行的人口数, x 1 x_1 x1为房子大小, x 2 x_2 x2为卧室的数量, N N N为样本数量。

3.2.1 加载数据集

导入库:

import numpy as np  			# 科学计算库,处理多维数组,进行数据分析
import matplotlib.pyplot as plt # 提供一个类似 Matlab 的绘图框架

导入数据集:

data = np.loadtxt("./resources/ex1data1.txt", delimiter=',', dtype=np.float64)

3.2.2 特征缩放

在多变量线性回归中,由于变量的范围有所不同,如x1是0到5000的数,而x2则是0到5的数,这会导致在X与Y坐标轴比例尺相同的情况下,整个图像显得极为修长,且此时梯度下降会需要很多次迭代才能收敛。因此需要进行特征缩放,使x1和x2在保持原有对应关系下,能稳定在-1到1之间。
常用特征缩放方法:

  1. 线性归一化(Min-Max Normalization): X n o r m = X − X min ⁡ X max ⁡ − X min ⁡ X_{norm}=\frac{X-X_{\min}}{X_{\max}-X_{\min}} Xnorm=XmaxXminXXmin把输入数据都转换到[0,1]的范围。
  2. 0均值标准化:

3.2.3 假设函数

假设函数为 f ( x ) = w 1 x 1 + w 2 x 2 + b f(x)=w_1x_1+w_2x_2+b f(x)=w1x1+w2x2+b,进一步向量乘法的形式,表示起来更简单,易于编程计算,这里构建增广权重向量 w = [ w 1 w 2 b ] \pmb w=\begin{bmatrix}w_1 \\ w_2 \\ b \end{bmatrix} w= w1w2b ,增广特征向量 x = [ x 1 x 2 1 ] \pmb x=\begin{bmatrix}x_1 \\ x_2 \\1 \end{bmatrix} x= x1x21
f ( x ) = w 1 x 1 + w 2 x 2 + b = [ w 1 w 2 b ] [ x 1 x 2 1 ] = w T x = x w \begin{align} f(x) &= w_1x_1+w_2x_2+b \\ &=[w_1 \quad w_2 \quad b] \begin{bmatrix} x_1 \\x_2\\1\end{bmatrix}\\ &= \pmb{w}^\mathrm{T} \pmb{x}\\ &= \pmb{x}\pmb{w} \end{align} f(x)=w1x1+w2x2+b=[w1w2b] x1x21 =wTx=xw

3.2.4 损失函数

X = [ x ( 1 ) 1 x ( 2 ) 1 ⋮ ⋮ x ( N ) 1 ] \pmb X=\begin{bmatrix} x^{(1)} &1\\ x^{(2)} &1\\ \vdots & \vdots\\ x^{(N) } &1 \end{bmatrix} X= x(1)x(2)x(N)111 y = [ y ( 1 ) y ( 2 ) ⋮ y ( N ) ] \pmb y=\begin{bmatrix}y^{(1)} \\y^{(2)} \\ \vdots \\ y^{(N)}\end{bmatrix} y= y(1)y(2)y(N) ,则损失函数 L ( w ) \mathcal{L}(w) L(w)可以表示为:

L ( w ) = 1 2 N ∑ i = 1 N ( f ( x ( i ) ) − y ( i ) ) 2 = 1 2 N ∣ ∣ X w − y ∣ ∣ 2 \begin{align} \mathcal{L}(w)&=\frac{1}{2N} \sum_{i=1}^N \left(f(x^{(i)}) - y^{(i)} \right)^2\\ &= \frac{1}{2N} ||\pmb X \pmb w- \pmb{y}||^2 \end{align} L(w)=2N1i=1N(f(x(i))y(i))2=2N1∣∣Xwy2

def loss_func(w, X, y):
    return np.sum(np.square(X.dot(w) - y)) / 2 * X.shape[0]

3.2.5 梯度下降函数

首先对 L ( w ) \mathcal{L(w)} L(w)求导, ∇ L ( w ) = 1 N X T ( X w − y ) \begin{align} \nabla \mathcal{L(w)}=\frac{1}{N} \pmb{X}^\mathrm{T}(\pmb{Xw-y}) \end{align} L(w)=N1XT(Xwy),这里用到了向量函数及其导数公式: ∂ A x ∂ x = A T \frac{\partial \pmb{Ax}}{\partial \pmb{x}}=\pmb{A}^\mathrm{T} xAx=AT。故梯度下降更新公式:
w : = w − α ∇ L ( w ) : = w − α 1 N X T ( X w − y ) \begin{align} \pmb w&:=\pmb w-\alpha \nabla \mathcal{L(w)}\\ &:= \pmb w- \alpha \frac{1}{N} \pmb{X}^\mathrm{T}(\pmb{Xw-y}) \end{align} w:=wαL(w):=wαN1XT(Xwy)

def grad(w, X, y):
    return (X.T @ (X.dot(w) - y)) / X.shape[0]
def grad_descent(w, X, y, alpha, maxIter):
    loss = []
    for i in range(maxIter):
        w = w - alpha * grad(w, X, y)
        cost = loss_func(w, X, y)
        loss.append(cost)
    return w, loss

3.2.6 算法步骤

  1. 初始化最大迭代次数maxIter,学习率alpha;
  2. 导入数据:np.loadtxt(),构建假设函数(增广权重矩阵、增广特征向量) w = [ 0 0 0 ] \pmb w=\begin{bmatrix} 0 \\ 0\\ 0 \end{bmatrix} w= 000
  3. 由式(7)计算梯度;
  4. 由式(9)更新梯度;
  5. 由式(6)计算损失函数;
  6. 判断maxIter>当前迭代次数?,是则转step3,否则算法结束,输出增广权重矩阵 w \pmb{w} w

3.2.7 完整代码

import numpy as np
from matplotlib import pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

np.set_printoptions(suppress=True)


def loss_func(w, X, y):
    return np.sum(np.square(X.dot(w) - y)) / 2 * X.shape[0]


def grad(w, X, y):
    return (X.T @ (X.dot(w) - y)) / X.shape[0]


def grad_descent(w, X, y, alpha, maxIter):
    loss = []
    for i in range(maxIter):
        w = w - alpha * grad(w, X, y)
        cost = loss_func(w, X, y)
        loss.append(cost)
    return w, loss


if __name__ == "__main__":
    maxIter = 10000
    # 读取数据
    dataset = np.loadtxt("ex1data2.txt", delimiter=",", dtype=np.float64)
    # 特征缩放
    data = (dataset - np.mean(dataset, axis=0)) / np.std(dataset, axis=0)

    # 增广矩阵
    X = np.insert(data[:, 0:2], obj=2, values=1, axis=1)
    y = data[:, 2:3]

    w = np.zeros(shape=X.shape[1]).reshape(3, 1)
    w, loss = grad_descent(w, X, y, alpha=0.002, maxIter=maxIter)
    print(w)

    fig = plt.figure()
    ax = fig.add_axes(Axes3D(fig))  # 创建三维坐标
    ax.scatter(data[:, 0:1], data[:, 1:2], data[:, -1])  # 散点图
    ax.set(xlabel='size', ylabel='bedrooms', zlabel='price')  # 坐标轴

    # 绘制拟合平面
    x1, x2 = np.meshgrid(
        np.linspace(np.min(data[:, 0:1]), np.max(data[:, 0:1]), 47),
        np.linspace(np.min(data[:, 1:2]), np.max(data[:, 1:2]), 47),
    )  # 生成网格采样点,这一步很重要
    w = w.reshape(1, 3)
    f = w[0][0] * x1 + w[0][1] * x2 + w[0][2]
    ax.plot_surface(x1, x2, f, color='g', alpha=0.4)  # 绘制平面

    plt.show()

运行结果 w = [ 0.88469562 − 0.05310845 − 0. ] \pmb w=\begin{bmatrix} 0.88469562 \\ -0.05310845\\ -0. \end{bmatrix} w= 0.884695620.053108450. ,与正规方程w=np.linalg.inv(X.T@X)@X.T@y求解结果一致。

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: 线性回归是一种统计学方法,可用于预测数值型变量之间的关系,如房价和房屋尺寸之间的关系。在这个场景下,我们考虑通过线性回归来建立一种模型,在已知的房屋尺寸的基础上,预测相应的房价。 假设我们有一个包含有房价和房屋尺寸的数据集,我们可以使用数据探索的工具,如散点图,来初步探索两个变量之间的关系。然后,我们可以使用线性回归模型来拟合这些数据点,并且预测新的房屋尺寸的房价。 接下来,我们将绘制一个图形来展示我们的线性回归模型如何拟合数据点和预测房价。在这张图中,我们将在横轴上表示房屋尺寸,纵轴上表示房价,并绘制出我们的线性回归模型所拟合的直线。这张图将使我们更容易地理解房价和房屋尺寸之间的关系,并且可以用于后续的数据分析以及预测。 在绘制完这张图后,我们可以检查线性回归模型的拟合精度。如果线性回归模型在数据集中存在显著的偏差,就需要重新考虑预测模型,或者增加更多的特征变量,这样可以使预测的结果更准确。此外,在应用线性回归模型之前,我们还应该注意一些其他的影响因素,如噪声或异常值,这样可以避免模型的偏差以及其他的预测错误。 ### 回答2: 线性回归是一种常用的机器学习算法,可以用于预测房价等连续值的问题。具体地说,线性回归就是通过找到一条直线(或者超平面,在高维空间中)来尽可能地拟合已知数据,然后利用这条直线进行预测。 在房价预测的问题中,我们可以使用线性回归算法来构建一个模型。首先,我们需要收集一些房价相关的数据,例如房屋面积、地理位置、年龄等等。然后,我们可以使用这些数据来训练线性回归模型,找到一个最优的线性函数,使得它最好地拟合已有的数据。 训练模型之后,我们就可以利用这个模型来进行预测。比如,我们输入某个房屋的面积、位置等信息,就可以利用模型预测这个房屋价格了。 为了更加直观地理解线性回归算法,我们可以绘制出数据点和拟合直线的图像。在这个图像中,我们可以看到每一个数据点的位置,以及拟合直线的位置,这样可以更加方便地理解线性回归算法的表现。 总之,线性回归是一种非常实用的机器学习算法,它可以帮助我们解决很多连续值预测的问题,例如房价预测等。同时,在理解线性回归算法的时候,我们可以通过绘制图像来更好地理解模型的表现。 ### 回答3: 线性回归是一种广泛用于预测连续数值的统计学方法,常用于房价预测。我们可以通过已知的房屋面积、房龄等特征,拟合出一个数学函数,进而计算出未知房屋价格。下面我将简单介绍如何使用Python中的scikit-learn库进行线性回归分析,以及如何绘制预测结果的图像。 首先,我们需要加载数据并探索数据的基本特征。数据可以从Kaggle等网站下载得到。以Boston House Price数据集为例,我们可以通过Pandas库读入数据并查看前几行数据的情况: ``` import pandas as pd df = pd.read_csv('train.csv') print(df.head()) ``` 接下来,我们需要针对数据的特征选择适当的模型进行拟合。这里我们选取最简单的线性回归模型。通过scikit-learn库中的LinearRegression模块,可以方便地进行模型训练。 ``` from sklearn.linear_model import LinearRegression X = df[['RM', 'LSTAT', 'PTRATIO']] # 我们选择房间数量、低收入人群比例以及学生与教师之比三个特征来预测房价 y = df['MEDV'] lr = LinearRegression() lr.fit(X, y) # 模型拟合 ``` 至此,我们已经拟合出了一个模型,可以使用测试数据集进行预测并计算模型的评估指标,例如均方误差(Mean Squared Error,MSE)等。同时,我们还可以通过matplotlib库绘制出预测结果的图像: ``` import matplotlib.pyplot as plt import numpy as np import seaborn as sns sns.set(style='whitegrid', context='notebook') pred_y = lr.predict(X) plt.scatter(y, pred_y) plt.plot([0, 50], [0, 50], '--k') plt.xlabel('True value') plt.ylabel('Predicted value') ``` 在图像中,横坐标代表真实房价,纵坐标代表预测房价。可以看到,预测结果与真实情况的差异较小,说明模型的拟合效果较好。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值