线性回归能做什么
获取数据, 定义问题
没有数据, 我们就没办法研究机器学习, 所以我们先找到一点可以用来做线性回归问题求解的数据, 这里我们找到了UCI大学的公开的机器学习数据来练习线性回归.
数据的介绍: http://archive.ics.uci.edu/ml/datasets/Combined+Cycle+Power+Plant
数据的下载地址在这: http://archive.ics.uci.edu/ml/machine-learning-databases/00294/
里面是一个循环发电场的数据,共有9568个样本数据,每个数据有5列,分别是:AT(温度), V(压力), AP(湿度), RH(压强), PE(输出电力)。我们不用纠结于每项具体的意思。
我们的问题是得到一个线性的关系,对应PE是样本输出,而AT/V/AP/RH这4个是样本特征, 机器学习的目的就是得到一个线性回归模型,即:
而需要学习的, 就是这5个参数
整理数据
下载后的数据可以发现是一个压缩文件,解压后可以看到里面有一个xlsx文件,我们先用excel把它打开,接着“另存为“csv”格式,保存下来,后面我们就用这个csv来运行线性回归。
打开这个csv可以发现数据已经整理好,没有非法数据,因此不需要做预处理。但是这些数据并没有归一化,也就是转化为均值0,方差1的格式。也不用我们搞,后面scikit-learn在线性回归时会先帮我们把归一化搞定。
好了,有了这个csv格式的数据,我们就可以大干一场了。
代码及运行结果展示
导入库
import os%matplotlib inlineimport matplotlib.pyplot as pltimport numpy as npimport pandas as pdfrom sklearn import datasets, linear_model
前期准备
获取数据并展示前5行
# read_csv里面的参数就是csv文件在你电脑上的路径, 此处csv文件放在本文件的相对目录的CCPP文件夹下data = pd.read_csv('.\CCPP\ccpp.csv')# 读取csv文件的前5行和最后5行试试data.head()
| AT | V | AP | RH | PE | |
|---|---|---|---|---|---|
| 0 | 8.34 | 40.77 | 1010.84 | 90.01 | 480.48 |
| 1 | 23.64 | 58.49 | 1011.40 | 74.20 | 445.75 |
| 2 | 29.74 | 56.90 | 1007.15 | 41.91 | 438.76 |
| 3 | 19.07 | 49.69 | 1007.22 | 76.79 | 453.09 |
| 4 | 11.80 | 40.66 | 1017.13 | 97.20 | 464.43 |
打印数据维度
# 打印数据维度试试data.shape
(9568, 5)
获取数据前4列
# 获取前4列的值x = data[['AT', 'V', 'AP', "RH"]]x.head()
| AT | V | AP | RH | |
|---|---|---|---|---|
| 0 | 8.34 | 40.77 | 1010.84 | 90.01 |
| 1 | 23.64 | 58.49 | 1011.40 | 74.20 |
| 2 | 29.74 | 56.90 | 1007.15 | 41.91 |
| 3 | 19.07 | 49.69 | 1007.22 | 76.79 |
| 4 | 11.80 | 40.66 | 1017.13 | 97.20 |
获取数据最后一列
# 获取最后一列试试y = data[['PE']]y.head()
| 列数 | PE |
|---|---|
| 0 | 480.48 |
| 1 | 445.75 |
| 2 | 438.76 |
| 3 | 453.09 |
| 4 | 464.43 |
划分数据集
# 把x,y的样本组合, 划成两个部分, 一部分是训练集, 一部分是测试集, 代码如下:from sklearn.model_selection import train_test_splitx_train, x_test, y_train, y_test = train_test_split(x, y, random_state=1)# 打印分好的数据print(x_train.shape)print(x_test.shape)print(y_train.shape)print(y_test.shape)
(7176, 4) (2392, 4) (7176, 1) (2392, 1)
填入数据,进行训练
# 运行scikit-learn的线性模型from sklearn.linear_model import LinearRegressionlinreg = LinearRegression()linreg.fit(x_train, y_train)
LinearRegression()
训练结束, 查看训练后的模型系数
# 拟合完毕后, 看看我们模型的系数结果print(linreg.intercept_)print(linreg.coef_)'''[447.06297099][[-1.97376045 -0.23229086 0.0693515 -0.15806957]]也就得到我们的方程为PE = 447.06297099 -1.97376045 * AT -0.23229086 * V + 0.0693515 * AP -0.15806957 *RH'''
[447.06297099] [[-1.97376045 -0.23229086 0.0693515 -0.15806957]]
模型评价
对前4列进行分析得到的模型,进行评价
# 模型评价y_pred = linreg.predict(x_test)from sklearn import metrics# 用scikit-learn计算MSEprint("MSE: ", metrics.mean_squared_error(y_test, y_pred))# 用scikir-learn计算RMSEprint("RMSE: ", np.sqrt(metrics.mean_squared_error(y_test, y_pred)))
MSE: 20.080401202073894 RMSE: 4.481116066570235
重新训练前3列,并进行分析得到的模型,进行评价
X = data[['AT', 'V', 'AP']]y = data[['PE']]X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=1)from sklearn.linear_model import LinearRegressionlinreg = LinearRegression()linreg.fit(X_train, y_train)#模型拟合测试集y_pred = linreg.predict(X_test)from sklearn import metrics# 用scikit-learn计算MSEprint("MSE:",metrics.mean_squared_error(y_test, y_pred))# 用scikit-learn计算RMSEprint("RMSE:",np.sqrt(metrics.mean_squared_error(y_test, y_pred)))
MSE: 23.208907470136236 RMSE: 4.817562399194871
交叉验证
# 交叉验证# 我们可以通过交叉验证持续优化模型, 代码如下, 我们采用10折交叉验证, 即cross_val_predict中的cv参数为10x = data[['AT', 'V', 'AP', 'RH']]y = data[['PE']]from sklearn.model_selection import cross_val_predictpredicted = cross_val_predict(linreg, x, y, cv=10)# 用scikit-learn计算MSEprint('MSE: ', metrics.mean_squared_error(y, predicted))# 用scikit-learn计算RMSEprint('RMSE', np.sqrt(metrics.mean_squared_error(y, predicted)))
MSE: 20.795597461943103 RMSE 4.560219014690315
画图展示
'''这幅图描述了线性回归模型中真实值和预测值之间的差距, 点越靠近中间的y=x代表预测效果越好'''fig, 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()
完整代码
import os%matplotlib inlineimport matplotlib.pyplot as pltimport numpy as npimport pandas as pdfrom sklearn import datasets, linear_model# read_csv里面的参数就是csv文件在你电脑上的路径, 此处csv文件放在本文件的相对目录的CCPP文件夹下data = pd.read_csv('.\CCPP\ccpp.csv')# 读取csv文件的前5行和最后5行试试data.head()# 打印数据的维度data.shapex = data[['AT', 'V', 'AP', "RH"]]x.head()y = data[['PE']]y.head()# 把x,y的样本组合, 划成两个部分, 一部分是训练集, 一部分是测试集, 代码如下:from sklearn.model_selection import train_test_splitx_train, x_test, y_train, y_test = train_test_split(x, y, random_state=1)# 打印分好的数据print(x_train.shape)print(x_test.shape)print(y_train.shape)print(y_test.shape)# 运行scikit-learn的线性模型from sklearn.linear_model import LinearRegressionlinreg = LinearRegression()linreg.fit(x_train, y_train)# 拟合完毕后, 看看我们模型的系数结果print(linreg.intercept_)print(linreg.coef_)'''[447.06297099][[-1.97376045 -0.23229086 0.0693515 -0.15806957]]也就得到我们的方程为PE = 447.06297099 -1.97376045 * AT -0.23229086 * V + 0.0693515 * AP -0.15806957 *RH'''# 模型评价y_pred = linreg.predict(x_test)from sklearn import metrics# 用scikit-learn计算MSEprint("MSE: ", metrics.mean_squared_error(y_test, y_pred))# 用scikir-learn计算RMSEprint("RMSE: ", np.sqrt(metrics.mean_squared_error(y_test, y_pred)))X = data[['AT', 'V', 'AP']]y = data[['PE']]X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=1)from sklearn.linear_model import LinearRegressionlinreg = LinearRegression()linreg.fit(X_train, y_train)#模型拟合测试集y_pred = linreg.predict(X_test)from sklearn import metrics# 用scikit-learn计算MSEprint("MSE:",metrics.mean_squared_error(y_test, y_pred))# 用scikit-learn计算RMSEprint("RMSE:",np.sqrt(metrics.mean_squared_error(y_test, y_pred)))# 交叉验证# 我们可以通过交叉验证持续优化模型, 代码如下, 我们采用10折交叉验证, 即cross_val_predict中的cv参数为10x = data[['AT', 'V', 'AP', 'RH']]y = data[['PE']]from sklearn.model_selection import cross_val_predictpredicted = cross_val_predict(linreg, x, y, cv=10)# 用scikit-learn计算MSEprint('MSE: ', metrics.mean_squared_error(y, predicted))# 用scikit-learn计算RMSEprint('RMSE', np.sqrt(metrics.mean_squared_error(y, predicted)))fig, 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()
感想
利用现成的接口,我们可以随意训练拥有n个自变量+1个因变量的n元1次方程

