前言
在前面的文章中,我们都是简单的对线性回归模型进行构建,这篇文章我们采用网上下载的数据量比较大的数据来对模型进行构造,最后讲述在线性的情况下如何对模型进行评估。
数据集介绍
下图是该数据集的前10行截图:
我们使用的数据集是一个广告和收入的关系的数据集,其特征实例一共有200条,其中每个实例有三个特征值,其含义分别如下:
-
TV:在电视上广告上的花费(单位是千元)
-
Radio:在广播媒体中的广告费用
-
Newspaper:在报纸上投资的广告费用
-
Sales:产品的销售量
数据集的下载地址:[Downlink href='/wp-content/uploads/file/20170818/1503045318704925.rar']点击下载[/Downlink]
读取数据集
这里我们使用pandas来读取数据,并使用seaborn和pyplot绘制成图,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
#coding:utf8 import numpy as np from sklearn import linear_model,metrics import pandas as pd import seaborn as sns import matplotlib.pyplot as plt from sklearn.cross_validation import train_test_split #读取数据 data = pd.read_csv('./data/AdData.csv', index_col=0) #aspect是每个子图的宽度,kind是绘制最佳拟合直线和95%的置信带 sns.pairplot(data, x_vars=["TV", "Radio", "Newspaper"], y_vars="Sales",size=5, aspect=0.7, kind="reg") sns.plt.show() |
这里我们使用pairploat来绘制图片,x_vars代表x坐标参数列,y_var代表y列,这里x_vaes给出了三列,也就是说会绘制出三个子图,结果如下
其实从这个图中我们就可以看出,TV和Sales直线的线性关系比较大,最差的是Newspaper。
使用Pandas构造X和Y并切分
1 2 3 4 5 6 7 8 |
#使用pandas来构造X和Y X = data[["TV", "Radio", "Newspaper"]] Y = data["Sales"] print X.shape #(200,3) print Y.shape #(200,) #切分训练集和测试集 X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.2, random_state=0) |
我们将数据按照8:2的比例分成了训练集和测试集。下面就可以构造线性模型了。
构造线性回归模型并进行预测
1 2 3 4 5 6 7 8 |
#构造模型 linreg = linear_model.LinearRegression() linreg.fit(X_train, Y_train) print "截距", linreg.intercept_ print "系数:", linreg.coef_ #使用测试集进行预测 y_pred = linreg.predict(X_test) |
输出的结果如下:
最终的方程便是y = 2.99 + 0.045*TV + 0.196*Radio -0.003 * Newspaper
方程的解释:TV上的广告每增加1000千元,销售量将增44.6,后面依次类推
线性模型的评估
常见线性回归情况下的模型评估主要从以下三个方面:
-
平均绝对误差:
-
均方误差:
-
均方根误差:
其方法在sklearn的metrics中都有对应,如下:
1 2 3 4 5 6 7 8 9 |
#模型评估 #平均绝对误差MAE print "MAE: ",metrics.mean_absolute_error(Y_test,y_pred) #均方误差MSE print "MSE: ",metrics.mean_squared_error(Y_test,y_pred) #均方根误差RMSE print "RMSE: ",np.sqrt(metrics.mean_squared_error(Y_test,y_pred)) |
输出结果如下:
特征值选择
从前面的点图和预测的系数值可以看出,Newspaper这一项和销售量的关系较弱,所以我们考虑将Newspaper这一项的值去掉,重新构造模型测试。
修改X的特征值个数:
1 |
X = data[["TV", "Radio"]] |
重新训练模型后输出结果如下:
把误差和之前对比可以发现,误差确实减小了,所以说,我们将Newspaper取消是对的。
全部代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
#coding:utf8 import numpy as np from sklearn import linear_model, metrics import pandas as pd import seaborn as sns import matplotlib.pyplot as plt from sklearn.cross_validation import train_test_split #读取数据 data = pd.read_csv('./data/AdData.csv', index_col=0) print "数据的前五行:\n",data.head() #分别绘制个特征值和y的点图,可以来查看线性程度 #aspect是每个子图的宽度,kind是绘制最佳拟合直线和95%的置信带 # sns.pairplot(data, x_vars=["TV", "Radio", "Newspaper"], y_vars="Sales",size=5, aspect=0.7, kind="reg") # sns.plt.show() #使用pandas来构造X和Y X = data[["TV", "Radio", "Newspaper"]] Y = data["Sales"] print X.shape #(200,3) print Y.shape #(200,) #切分训练集和测试集 X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.2, random_state=1) #构造模型 linreg = linear_model.LinearRegression() linreg.fit(X_train, Y_train) print "截距", linreg.intercept_ print "系数:", linreg.coef_ #使用测试集进行预测 y_pred = linreg.predict(X_test) #模型评估 #平均绝对误差MAE print "MAE: ",metrics.mean_absolute_error(Y_test,y_pred) #均方误差MSE print "MSE: ",metrics.mean_squared_error(Y_test,y_pred) #均方根误差RMSE print "RMSE: ",np.sqrt(metrics.mean_squared_error(Y_test,y_pred)) |