线性回归(模型的建立与求解)

254 阅读7分钟

0 前言

上一篇文章中笔者介绍了如何通过三个阶段来循序渐进的学习一个机器学习算法,那么下面就开讲解第一个算法:线性回归(Linear Regression)。

如图所示为整个线性回归的学习路线图,且由于是第一个算法,所以会介绍很多基本的内容,导致看起来有很多内容。因此,对于整个线性回归的学习笔者将通过五篇文章来进行介绍。但是,值得高兴的是只要完成前四步就基本完成了第一阶段的学习。下面就将正式开始介绍线性回归。

1 引例

通常来说,机器学习中的每一个算法都是为了解决某一类问题而诞生的。换句话说,也就是在实际情况中存在一些问题能够通过线性回归来解决,例如:对房价的预测。但是有人可能会问,为什么对于房价的预测就应该用线性回归,而不是其它算法呢?原因在于:常识告诉我们房价都是随着面积的增长而增长的,且总体上呈线性增长的趋势。可有没有那种当面积大到一定程度后价格反而降低了,因此不符合线性增长的呢?这当然也可能存在,但在实际处理中肯定会优先选择线性回归,当效果不佳时再尝试其它算法。因此,当我们学习过多个算法后,当拿到某个问题我们就需要考虑这个问题更适合哪种算法了。

如图所示为某房价的一个走势图,其中横坐标为面积,纵坐标为价格,且房价整体上呈线性增长的趋势。那假如现在随意告诉你一个房屋的面积,怎么才能预测(或者叫计算)出其对应的价格呢?

2 建立模型

2.1 如何建立模型

一般来说,当我们拿到一个实际问题时首先会根据问题的背景结合常识选择一个合适的模型。同时,现在常识告诉我们房价的增长更优先符合线性回归这类模型,因此可以考虑建立一个如下的线性回归模型:

\hat{y}=h(x)=wx+b\tag{1}

其中w叫权重参数(weight),b叫偏置(bias)或者截距(intercept)。当求解得到未知参数w,b之后也就意味着我们得到了预测模型,即给定一个房屋面积x,就能够预测出其对应的房价。

注:在机器学习中所谓的模型,简单理解就是一个(复合)函数。

2.2 如何求解模型

当我们建立好一个模型后,如何通过给定的数据,也叫训练集(traing data)来对模型h(x)进行求解呢?在初中的时候我们倒是学过如何通过两个坐标点来求解过这两点的直线,可在上述的场景中这种做法显然行不通,那有没有什么解决的办法呢?

此时就需要我们转换一下思路了,既然不能直接来那就换一个间接的方式。想象一下,当h(x)满足一个什么样的条件时,它才能称得上是一个好的h(x)? 回想一下我们求解h(x)的目的是什么,不就是希望输入面积x后能够输出"准确"的房价y 。既然直接求解h(x)不好入手,那么我们就从“准确”来入手。

那又怎么来定义准确呢?在这里我们可以通过计算每个样本的真实房价与预测房价之间的均方误差来进行刻画:

\begin{aligned}
J(w,b)&=\frac{1}{2m}\sum_{i=1}^m(y^{(i)}-\hat{y}^{(i)})^2\\[2ex]
\hat{y}^{(i)}&=h(x^{(i)})=wx^{(i)}+b
\end{aligned}\tag{2}

其中,m表示总的样本数,x^{(i)}表示第i个样本的,也就是第i个房屋的面积,y^{(i)}表示第i个房屋的真实价格,\hat{y}^{(i)}表示第i个房屋的预测价格。

注:由于是第一阶段的学习,我这里就直接给出,但是读者们可以提出自己的疑问。例如:换成y^{(i)}\hat{y}^{(i)}之间的绝对值可以吗?

由公式(2)可以知道,当函数J(w,b)取最小值时的参数\hat{w},\hat{b},就是我们要求的目标参数。为什么?因为当J(w,b)取最小值就意味着此时所有样本的预测值与真实值之间的误差(error)是最小的。如果极端一点,那就是所有预测值都等同于真实值,此时的J(w,b)就是0了。

因此,对于如何求解模型h(x)的问题就转换为如何最小化函数J(w,b)的问题了。其实J(w,b)有一个专门的术语叫目标函数(objective function) 或者是代价函数(cost function)亦或是损失函数。至此,我们离第一阶段的学习目标只差一步之遥了,那就是如何通过开源框架来进行建模求解,并进行预测。

至于求解过程到底怎样如何求解,那就是第二阶段的任务了,下面开始完成第一阶段的最后一部。

3 Scikit-learn建模

3.1 sklearn简介

Scikit-learn简称sklearn,官网地址为:scikit-learn.org/。 它是一个开源的机器学习框架,常用的机器学习算法都可以在里面找到。其Python化的实现风格对于Python用户来说十分友好容易上手,并且每个算法都给了示例以及API文档。

3.2 安装sklearn以及其它库

前一篇文章中我们介绍了如何配置环境,下面就开始安装所需要的包(库):

  • 首先打开cmd命令行(windows+r在=再输入cmd即可)

  • 激活之前安装的虚拟环境

    • conda activate py36,其中py36表示你创建的虚拟环境的名称

      如果环境激活成功,会变成类似提示符:(py36) C:\Users\username>

  • 安装需要的三个包numpy,sklearn,matplotlib

    • pip install numpy sklearn matplotlib

      如果之前在配置环境的时候,替换了conda的源地址为清华镜像,则下载的速度会更快。

      完成安装后关闭CMD命令行,同时Pycharm会建立新的索引可能需要几分钟,等待即可。

3.3 示例代码

  • 导入包

    import numpy as np
    from sklearn.linear_model import LinearRegression
    import matplotlib.pyplot as plt
    
  • 制作样本(数据集)

    def make_data():
        np.random.seed(20)
        x = np.random.rand(100) * 30 + 50  # square
        noise = np.random.rand(100) * 50
        y = x * 8 - 127  # price
        y = y - noise
        return x, y
    
  • 定义模型并求解

    def main(x, y):
        model = LinearRegression()# 定义模型
        x = np.reshape(x, (-1, 1))
        model.fit(np.reshape(x, (-1, 1)), y)# 求解模型
        y_pre = model.predict(x)# 预测
        plt.scatter(x, y)
    	print("参数w={},b={}".format(model.coef_,model.intercept_))
        print("面积50的房价为:",model.predict([[50]]))
        plt.plot(x, y_pre, c='r')
        plt.xlabel('Square', fontsize=15)
        plt.ylabel('Price', fontsize=15)
        plt.tight_layout()  # 调整子图间距
        plt.show()
    

    其中np.reshape(x,(-1,1))表示把x变成[n,1]的形状,至于n到底应该是多少,将通过np.reshape函数自己推导得出。距离:xshape[4,5],如果我想把a改成[2,10]形状则可以这样:a.reshape([2,10]),或者a.reshape([2,-1])

  • 运行及结果

    if __name__ == '__main__':
        x, y = make_data()
        main(x, y)
    
    # 输出结果:
    #参数w=[7.97699647],b=-154.31885006061555
    #面积50的房价为: [244.53097351]
      
    

    其中参数w=7.97,b=-154.32也就意味着h(x)=7.97x-154.32,之后便可以通过h(x)来对新的输入做预测。同时我们还能画出模型拟合出的直线:

至此我们便完成了对于线性回归第一阶段大致的学习。

4 总结

在这篇文章中,①笔者首先通过一个实际的场景介绍了什么是线性回归;②接着介绍了如何建立一个简单的线性模型;③然后引导大家如何将模型的求解问题,转化为目标函数的最小化过程;④最后通过开源框架sklearn搭建了一个简单的线性回归模型并进行了求解。虽然内容不多,但是却体现了整个线性回归算法的核心思想。同时,剩余内容也将在接下来的文章中进行介绍!本次内容就到此结束,感谢阅读!

若有任何疑问,请发邮件至moon-hotel@hotmail.com并附上文章链接,青山不改,绿水长流,月来客栈见!

引用

更多内容欢迎扫码关注公众号月来客栈!