从简单的线性回归入门机器学习

来源:互联网 发布:java 虚拟现实 编辑:程序博客网 时间:2024/05/18 01:23

声明:

  1. 参考用Sckit-Learn和Pandas学习线性回归
  2. 入门机器学习仅仅靠这一篇文章还是有些不够,建议大家戳一戳文中的链接,看一下相关的知识。

  • 从简单的线性回归入门机器学习
    • 获取数据定义问题
    • 整理数据
    • 用pandas来读取数据
    • 准备运行算法的数据
    • 划分训练集和测试集
    • 运行scikit-learn的线性模型
    • 评价模型
    • 调优
    • 画图观察结果
    • 总结

从简单的线性回归入门机器学习

  虽然本文从一开始就限定了机器学习的方法——线性回归,但是在大多数情况下,解决问题的主要难点在于寻找合适的机器学习方法上。而这方面需要长期的积累,所以显然不是本文要讲的内容了。
  下面,本文将用面向过程的方式分解解决线性回归问题的步骤(每一个章节标题都是一个步骤),以此来帮助大家对机器学习有一个初步的了解。

获取数据,定义问题

没有数据,当然没法研究机器学习啦。:) 这里我们用UCI大学公开的机器学习数据来跑线性回归。

数据的介绍戳戳戳

数据的下载地址戳戳戳

里面是一个循环发电场的数据,共有9568个样本数据,每个数据有5列,分别是:AT(温度), V(压力), AP(湿度), RH(压强),
PE(输出电力)。我们不用纠结于每项具体的意思。

我们的问题是得到一个线性的关系,对应PE是样本输出,而AT/V/AP/RH这4个是样本特征, 机器学习的目的就是得到一个线性回归模型,即:
PE=θ0+θ1AT+θ2V+θ3AP+θ4RH而需要学习的,就是θ0θ1θ2θ3θ4这5个参数。

整理数据

下载后的数据可以发现是一个压缩文件,解压后可以看到里面有一个xlsx文件,我们先用excel把它打开,接着“另存为”csv格式(只需要保存一个sheet就可以了),保存下来,后面我们就用这个csv来运行线性回归。
ps: 本文另存为了“ccpp.csv”。转成csv格式是为了读取更方便。

打开这个csv可以发现数据已经整理好,没有非法数据,因此不需要做预处理。但是这些数据并没有归一化,也就是转化为均值0,方差1的格式。也不用我们搞,后面scikit-learn在线性回归时会先帮我们把归一化搞定。

好了,有了这个csv格式的数据,我们就可以大干一场了。

所谓非法数据,主要是指空值,一般在机器学习或者深度学习中都不接受空值,需要删除或者插值处理。

用pandas来读取数据

推荐使用的一个交互式编程工具:jupyter notebook
读取数据到变量data中

import pandas as pdimport numpy as npdata = pd.read_csv(r'./ccpp.csv', header=0)

查看data的信息

data.head()  # 前五行的信息

这里写图片描述

data.shape  # data的长和宽'''输出'''# (9568, 5)

  可以看到,data是一个pandas中的DataFrame类型,其列名是5个变量,索引是0, 1, 2…9567

准备运行算法的数据

  我们的目的是通过对前四个变量AT, V, AP, RH建立一个线性关系来预测RE,即对于函数y=f(x),机器通过输入x和输出y,找到它们之间的线性映射。

  机器学习的含义也可以在这里得到解释:通过对大量数据的学习,找出一定的规律,当再次碰到相似的数据时,可以通过之前获得的规律来作出判断。

  所以我们的输出数据X是表格data的前4列,输出真实值y是表格data的最后一列。

X = data[['AT', 'V', 'AP', 'RH']]y = data[['PE']]

划分训练集和测试集

为什么要划分训练集和测试集?
  上一个章节中,我们已经得到输入X和输出y,这足以让我们完成对机器的训练。但是,为了评估机器学习效果的好坏,还需要一些数据进行测试。
  训练集和测试集分开是机器学习界的公式,这样可以防止过拟合,增强机器学习算法的泛化能力。
如何划分训练集和测试集?
在sklearn库中提供了一个划分函数:

# 首先从sklearn库中导入划分函数from sklearn.model_selection import train_test_split# 然后执行函数获得结果x_train, x_test, y_train, y_test = train_test_split(X, y, random_state=0)print('x_train.shape: ', x_train.shape)print('y_train.shape: ', y_train.shape)print('x_test.shape: ', x_test.shape)print('y_test.shape: ', y_test.shape)'''输出'''# x_train.shape:  (7176, 4)# y_train.shape:  (7176, 1)# x_test.shape:  (2392, 4)# y_test.shape:  (2392, 1)

这个函数涉及到两个问题:

  1. random_state是什么? 它是一个随机种子,用来生成随机数。当random_state一样时,划分的数据就服从同一种随机分布。
  2. 如何确定训练集和测试集分割的比例? 默认参数test_size=0.25,即默认训练集:测试集=3:1。可以改变这个参数以获得不同的分割比例。

运行scikit-learn的线性模型

  这一步就是线性回归算法部分了,看起来最神秘,但是由于sklearn库已经将算法封装好了,所以用起来相当简单。

# 首先从sklearn库中导入线性回归函数from sklearn.linear_model import LinearRegression# 执行函数获得一个线性回归模型linreg = LinearRegression()  # 这是一个未经训练的机器学习模型# 对模型传入输入数据x_train和输出数据y_trainlinreg.fit(x_train, y_train)  # 这是一个经过训练的机器学习模型'''输出线性回归的截距和各个系数'''print('linreg.intercept_: ', linreg.intercept_)print('linreg.coef_: ', linreg.coef_)'''输出'''# linreg.intercept_:  [ 451.19095935]# linreg.coef_:  [[-1.98357941 -0.23219575  0.06559288 -0.15932893]]

  经过训练的线性回归模型可以给我们返回一组系数,将这组系数带入前面的公式就可得线性回归预测的回归函数:
PE=447.062970991.97376045AT0.23229086V+0.0693515AP0.15806957RH

评价模型

  现在,机器学习模型已经根据数据学习到了一个线性回归的规律。这一章节,我们需要评估我们的模型的好坏程度,对于线性回归来说,我们一般用均方差(Mean Squared Error, MSE)或者均方根差(Root Mean Squared Error, RMSE)在测试集上的表现来评价模型的好坏。

  同时,sklearn提供了一套用于评估模型好坏的工具库——metrics,不用我们自己敲代码了。

  前面划分的测试集在这里将排上用场:

y_pred = linreg.predict(x_test)# 引入sklearn模型评价工具库from sklearn import metricsprint("MSE: ", metrics.mean_squared_error(y_test, y_pred))print("RMSE: ", np.sqrt(metrics.mean_squared_error(y_test, y_pred)))'''输出'''# MSE:  20.5442988776# RMSE:  4.53258192178

  确实,这样看模型的好坏程度很不直观,得到一个浮点数不能让我们确定模型训练的效果。但是这个数值的意义在于,当我们使用了多种机器学习模型时,如何进行横向比较选择效果最好的模型,具有重大的参考意义。

  本文后面还会用可视化的方式直观的表示模型学习效果的好坏。

调优

  所谓调优,就是调整机器学习模型(本文中为线性回归)中的参数。很多人认为机器学习很简单,就是选个模型然和调参,实际并非如此。

  言归正传,进行调优最常用的方法是交叉验证。进行交叉验证,我们不仅需要训练集和测试集,还应该再把训练集分成子训练集和验证集。然后,通过子训练集和验证集获得最优的参数。最后用测试集进行评估作为当前模型(本位为简单线性回归)的最终评分。

画图观察结果

  这里画图真实值和预测值的变化关系,离中间的直线y=x直接越近的点代表预测损失越低。代码如下:

%matplotlib inline  # 这是为了能在交互式界面中显示图像import matplotlib.pyplot as pltfig, ax = plt.subplots()ax.scatter(y, predicted)ax.plot([y.min(), y.max()], [y.min(), y.max()], 'k--', lw=4)ax.set_xlabel('Measured')ax.set_ylabel('Predicted')plt.show()

这里写图片描述

为什么要这样画图?
  对于输出y来说,真实值和预测值都是一维的,同时,真实值和预测值一一对应,它们之间的差值越小,预测越准确。显然,如果预测值=真实值,那么它们的差值最小,即上图中的黑色虚线。横坐标是真实值,纵坐标是预测值,那么对于所有的真实值,预测值离着黑线越近,预测越准确。

总结

这是本文进行线性回归的流程图:

这里写图片描述