【机器学习】从房价预测问题看回归算法

关键词:机器学习 / 回归

文章目录

回归问题是什么

回归问题是除了分类问题以外,机器学习中另一个经典问题。本节我们以从房价预测为问题背景,逐步介绍分类问题及其相关算法。

回归的目的是想拟合一组数据的输入x \boldsymbol{x}x和输出y y y之间的映射关系f ( ⋅ ) f(\cdot)f (⋅),进而用得到的拟合模型f ( ⋅ ) f(\cdot)f (⋅)对未知的样本x t \boldsymbol{x}_t x t ​进行预测。分类和回归的最显著区别,是 输出变量y y y的类型不同:

  • 回归:y y y是 连续变量,如预测深圳市南山区住宅的明年房价,是一个回归任务;
  • 分类:y y y是 离散变量,如预测深圳市南山区住宅的明年房价是涨是跌,是一个分类任务。

房价会受很多因素的影响,如面积、所在地区便利程度、开发商品质和所在学区等等。我们希望拟合出来房价和这些因素的关系,进而对未知的房价进行预测。如果我们考虑多个影响房价的因素,那么就是一个 多元回归问题(又称多变量线性回归)。特别地,假设只考虑面积,拟合房价和面积之间的关系,那么就是一个一元回归问题:

  • 多元回归:y = f ( x ) y=f(x)y =f (x ),其中影响因素仅有一个特征,即x x x是一维;
  • 一元回归:y = f ( x ) , x = [ x 1 , x 2 , . . . , x d ] y=f(\boldsymbol{x}),\boldsymbol{x}=[x_1,x_2,…,x_d]y =f (x ),x =[x 1 ​,x 2 ​,…,x d ​],其中d d d表示元的个数,也即特征的维度。

根据房价和影响因素之间的关系的类型,又可以分为线性回归和非线性回归,前者的潜在假设是输入、输出存在线性关系,而后者则认为输入和输出存在非线性映射:

  • 线性回归:y = w T x + b = w 1 x 1 + w 2 x 2 + ⋯ + w d x d + b y=\boldsymbol{w}^{T}\boldsymbol{x}+b=w_1x_1+w_2x_2+\cdots+w_dx_d+b y =w T x +b =w 1 ​x 1 ​+w 2 ​x 2 ​+⋯+w d ​x d ​+b,其中d d d表示特征的个数;
  • 非线性回归:常见的如多项式回归y = w 0 + w 1 x 1 + w 2 x 2 2 + ⋯ + w d x d d y=w_0+w_1x_1+w_2x_2^2+\cdots+w_dx_d^d y =w 0 ​+w 1 ​x 1 ​+w 2 ​x 2 2 ​+⋯+w d ​x d d ​。

本次我们将以房价问题为例,从最简单的一元线性回归入手,了解回归问题的细节。

生成数据

我们用y y y表示房价,用X X X表示影响房价的面积、所在地区便利程度、开发商品质等因素的向量。有房价标签的训练数据集为{ ( x 1 , y 1 ) , ( x 2 , y 2 ) , ⋯ , ( x n , y n ) } {(\boldsymbol{x}_1,y_1),(\boldsymbol{x}_2,y_2),\cdots,(\boldsymbol{x}_n,y_n)}{(x 1 ​,y 1 ​),(x 2 ​,y 2 ​),⋯,(x n ​,y n ​)},我们希望可以基于这些数据训练得到拟合二者关系的函数f ( ⋅ ) f(\cdot)f (⋅),当遇到新的测试数据x t \boldsymbol{x}_t x t ​,就可以预测得到它对应的房价f ( x t ) f(\boldsymbol{x}_t)f (x t ​)。

现在假设先只考虑面积因素来预测房价,手动生成以下面积和房价数据

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 ) = w x + b f(x)=wx+b f (x )=w x +b。接下来的任务是学习这里的参数w w w和b b b使得模型拟合得到的y y y值和对应的真实训练数据的y y y值尽量接近。回归问题中常用均方误差(mean squared error)来评估训练集上预测结果相对真实结果的差异,即要求模型参数满足
w ∗ , b ∗ = arg ⁡ min ⁡ w , b 1 m ∑ i = 1 m ( f ( x i ) − y i ) 2 = arg ⁡ min ⁡ w , b 1 m ∑ i = 1 m ( w x i + b − y i ) 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 ∗​=ar g w ,b min ​m 1 ​i =1 ∑m ​(f (x i ​)−y i ​)2 =ar g w ,b min ​m 1 ​i =1 ∑m ​(w x i ​+b −y i ​)2 ​

最小二乘法是常用的用于解决上述优化问题的方法,上面的均方误差损失L = L=L =1 m ∑ i = 1 m ( w x i + b − y i ) 2 \frac{1}{m}\sum_{i=1}^m(wx_i+b-y_i)^2 m 1 ​∑i =1 m ​(w x i ​+b −y i ​)2分别对w w w和b b b求导,可以得到
∂ L ∂ w = 1 m ⋅ 2 ( w ∑ i = 1 m x 2 2 − ∑ i = 1 m ( y i − b ) x i ) ∂ L ∂ b = 1 m ⋅ 2 ∑ i = 1 m ( w x i + b − y i ) w = m ⋅ ∑ i = 1 m x i y i − ∑ i = 1 m x i ∑ i = 1 m y i m ⋅ ∑ i = 1 m x i 2 − ( ∑ i = 1 m x i ) 2 b = ∑ i = 1 m y i ∑ i = 1 m x i 2 − ∑ i = 1 m x i ∑ i = 1 m x i y i m ⋅ ∑ i = 1 m x i 2 − ( ∑ i = 1 m x i ) 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 ∂L ​w b ​=m 1 ​⋅2 (w i =1 ∑m ​x 2 2 ​−i =1 ∑m ​(y i ​−b )x i ​)=m 1 ​⋅2 i =1 ∑m ​(w x i ​+b −y i ​)=m ⋅∑i =1 m ​x i 2 ​−(∑i =1 m ​x i ​)2 m ⋅∑i =1 m ​x i ​y i ​−∑i =1 m ​x i ​∑i =1 m ​y i ​​=m ⋅∑i =1 m ​x i 2 ​−(∑i =1 m ​x i ​)2 ∑i =1 m ​y i ​∑i =1 m ​x i 2 ​−∑i =1 m ​x i ​∑i =1 m ​x i ​y i ​​​

这样我们就得到了线性回归的模型的参数,也就得到了基于训练数据的回归模型。根据以上结果,定义以下线性回归类:

class LinearRegression:
    def __init__(self, param=None):
        self.param = param

    def 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
        intercept = sum_y * sum_xsqr - sum_x * sum_mul

        self.w = coef / div
        self.b = intercept /div

    def predict(self, x):
        return self.w * x + self.b

先初始化线性回归类,然后基于训练数据进行拟合

LR = LinearRegression()
LR.fit(x_train,y_train)

用拟合出来的模型,先在训练数据上对比看看预测结果和真实y y y值的差异:

pred_y_train = LR.predict(x_train)

【机器学习】从房价预测问题看回归算法

再来看在测试数据上的表现

pred_y_test = LR.predict(x_test)

【机器学习】从房价预测问题看回归算法

图中的蓝色线,拟合了面积和房价之间的映射关系,就可以用来根据面积来预测房价啦。

最小二乘法学习多元线性回归模型

当我们关心的房价影响因素不止面积,还有所在地区便利程度、开发商品质和所在学区等时,每个样本的特征x \boldsymbol{x}x表示一个多维向量,相应的要学习的回归模型变为y = w T x + b = w 1 x 1 + w 2 x 2 + ⋯ + w d x d + b y=\boldsymbol{w}^{T}\boldsymbol{x}+b=w_1x_1+w_2x_2+\cdots+w_dx_d+b y =w T x +b =w 1 ​x 1 ​+w 2 ​x 2 ​+⋯+w d ​x d ​+b。将参数w \boldsymbol{w}w和b b b合并为一个参数a \boldsymbol{a}a,要学习的模型为y = x a y=\boldsymbol{x}\boldsymbol{a}y =x a。类似地,仍可以使用最小二乘法来对参数a \boldsymbol{a}a进行估计。

将数据写成矩阵的形式,即X ∈ R m × ( d + 1 ) \boldsymbol{X}\in\mathbb{R}^{m\times(d+1)}X ∈R m ×(d +1 )每一行为一条高维数据,参数的优化目标变为:

a ∗ = arg ⁡ min ⁡ a L = arg ⁡ min ⁡ a 1 m ( y − X a ) T ( y − X a ) \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 ∗​=ar g a min ​L =ar g a min ​m 1 ​(y −X a )T (y −X a )​

对参数a \boldsymbol{a}a进行矩阵运算的求导,得
∂ L ∂ a = 1 m ⋅ 2 X T ( X a − 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 ​=m 1 ​⋅2 X T (X a −y )​

令上式为0即可得到参数a \boldsymbol{a}a的最优解,当X T X \boldsymbol{X}^T\boldsymbol{X}X T X为满秩矩阵或正定矩阵时,可以得到
a ∗ = ( X T X ) − 1 X T y \begin{aligned} \boldsymbol{a}^* = (\boldsymbol{X}^T\boldsymbol{X})^{-1}\boldsymbol{X}^T\boldsymbol{y} \end{aligned}a ∗=(X T X )−1 X T y ​
若X T X \boldsymbol{X}^T\boldsymbol{X}X T X可逆,可用 numpy库的 linalg.inv求解;而当不可逆时,求得 伪逆,又称广义逆矩阵,是逆矩阵的推广形式,可用 linalg.pinv求解。

重新进行线性回归求解,相应的代码如下

class LinearRegression_multi:
    def __init__(self, param=None):
        self.param = param

    def 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和b b b合并为一个参数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)

用拟合出来的模型,先在训练数据上对比看看预测结果和真实y y y值的差异:

pred_y_train = LR_multi.predict(x_train)

【机器学习】从房价预测问题看回归算法

再来看在测试数据上的表现

pred_y_test = LR.predict(x_test)

【机器学习】从房价预测问题看回归算法

至此线性回归模型,拟合了面积、开发商品质和房价之间的映射关系,就可以用来根据面积来预测房价啦。

梯度下降法学习回归模型

当线性模型不再满足我们拟合数据的需求时,最小二乘法使导数为0不一定能求出最优的闭式解,这个时候可以解决非线性优化的梯度下降法就该出场啦。

梯度下降法采用逐步迭代的方式去不断逼近极值点,即均方误差最小的地方,对应的参数即为最优参数。对于前述 线性回归,损失函数和对应的梯度可以写成
L ( θ ) = 1 m ( X θ − y ) T ( X θ − y ) ▽ θ L ( θ ) = ▽ θ ( 1 m ( X θ − y ) T ( X θ − y ) ) = 2 m X T ( 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 (θ)​=m 1 ​(X θ−y )T (X θ−y )=▽θ​(m 1 ​(X θ−y )T (X θ−y ))=m 2 ​X T (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 = param

    def 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 * gradient
        cost = 2/m * (np.dot(x, self.theta) - y).T.dot(np.dot(x, self.theta) - y)
        print('cost', cost)
        return cost

    def 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)

用拟合出来的模型,先在训练数据上对比看看预测结果和真实y y y值的差异:

pred_y_train = LR_gd.predict(x_train)

【机器学习】从房价预测问题看回归算法

再来看在测试数据上的表现

pred_y_test = LR_gd.predict(x_test)

【机器学习】从房价预测问题看回归算法

结果和前面的基于最小二乘法的多元线性回归是一样的,感兴趣的同学可以自己check一下~

其他非线性回归的梯度下降法是类似的,但是需要根据不同的非线性关系进行相应的调整。

更多内容,欢迎关注我们的公众号:AI算法词典

我们的团队致力于拆解AI算法,每篇附上代码实现,构建AI学习从入门到精通的词典路径!

来找我们玩!热烈欢迎交流哦 😃

【机器学习】从房价预测问题看回归算法

Original: https://blog.csdn.net/petSym/article/details/113277157
Author: petSym
Title: 【机器学习】从房价预测问题看回归算法

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/634399/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球