(呃,大数据的同学们交实验报告的时候,这些代码和图片也稍微改点哈!!我实验报告已经写完了,不想去改了,别等下交上去大家都是一样的┭┮﹏┭┮)
好了,上一节我们已经将数据处理的差不多了(上一节),现在让我们来建立具体的模型
要求:
- 数据建模:
- 使用LinearRegression构建线性回归模型;
- 使用Ridge构建岭回归模型。
- 模型效果评估:
- 输出两个模型的均方误差和决定系数R2;
- 绘制残差图。
不说废话,直接上代码:
import pandas as pd
import os
import matplotlib.pyplot as plt
import numpy as np
from sklearn import datasets, linear_model
from sklearn.metrics import mean_squared_error, r2_score
import warnings
warnings.filterwarnings('ignore') #忽略因为numpy版本问题引发的警告
#声明全局变量
data=pd.read_csv('data.csv')
m,n=data.shape #行列数
name=["性别","壳体最长长度","直径","高度","总重量","肉重量","内脏重量","壳体重量","环数量"]
new_data_path='data_afterproc.csv' #数据预处理后的文件名
#线性回归
def LinearRegression_model(X_train,y_train,X_test,y_test):
#需要把列表类型转化对应的x=np(m,n);y=np(m,)
diabetes_X_train = np.mat(X_train)
diabetes_y_train = np.array(y_train)
diabetes_X_test = np.mat(X_test)
diabetes_y_test = np.array(y_test)
# print('{}--{}--{}--{}'.format(diabetes_X_train.shape,diabetes_y_train.shape,diabetes_X_test.shape,diabetes_y_test.shape))
# 线性回归模型
regr = linear_model.LinearRegression(fit_intercept=True, normalize=True, n_jobs=-1)
regr.fit(diabetes_X_train, diabetes_y_train)
diabetes_y_pred = regr.predict(diabetes_X_test)
print('\n线性回归的常数项:{} 系数:{} '.format(regr.intercept_,regr.coef_))
# print('{}--{}'.format(regr.predict(diabetes_X_train)[:10],diabetes_y_test[:10]))
# 结果评估
print('线性回归的均方误差: %.2f'
% mean_squared_error(diabetes_y_test, diabetes_y_pred))
print('线性回归的确定系数(R^2): %.2f\n'
% r2_score(diabetes_y_test, diabetes_y_pred))
return diabetes_y_test, diabetes_y_pred #返回真实值和预测值,用来画图
#岭回归
def Ridge_model(X_train,y_train,X_test,y_test):
#需要把列表类型转化对应的x=np(m,n);y=np(m,)
diabetes_X_train = np.mat(X_train)
diabetes_y_train = np.array(y_train)
diabetes_X_test = np.mat(X_test)
diabetes_y_test = np.array(y_test)
# 岭回归模型
regr = linear_model.Ridge(alpha=0.001, fit_intercept=True, normalize=True, random_state=0)
regr.fit(diabetes_X_train, diabetes_y_train)
diabetes_y_pred = regr.predict(diabetes_X_test)
print('\n岭回归的常数项:{} 系数:{} '.format(regr.intercept_,regr.coef_))
# 结果评估
print('岭回归的均方误差: %.2f'
% mean_squared_error(diabetes_y_test, diabetes_y_pred))
print('岭回归的确定系数(R^2): %.2f'
% r2_score(diabetes_y_test, diabetes_y_pred))
return diabetes_y_test, diabetes_y_pred #返回真实值和预测值,用来画图
#画图
def figure_plot(L_X,L_Y,R_Y):
# 残差图绘图(标准情况只适合二维的情况,这个是10维画不出标准图的),所以就浅浅的画一个对比图
plt.rc("font",family="SimHei",size="15") #解决中文乱码问题
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
x_axis = [i for i in range(len(L_X))]
plt.subplot(1,2,1)
plt.plot(x_axis, L_X, color='green',linestyle='-',label='真实样本曲线', linewidth=1)
plt.plot(x_axis, L_Y, color='blue',linestyle=':',label='线性回归预测样本', linewidth=1)
plt.xlabel('样本编号')
plt.ylabel('环数量')
plt.title('线性回归模型')
plt.legend()
plt.subplot(1,2,2)
plt.plot(x_axis, L_X, color='green',linestyle='-',label='真实样本曲线', linewidth=1)
plt.plot(x_axis, R_Y, color='red',linestyle=':',label='岭回归预测样本', linewidth=1)
plt.xlabel('样本编号')
plt.ylabel('环数量')
plt.title('岭回归模型')
plt.legend()
plt.show()
if __name__ == '__main__':
L_X,L_Y=LinearRegression_model(X_train,y_train,X_test,y_test)
R_X,R_Y=Ridge_model(X_train,y_train,X_test,y_test)
figure_plot(L_X,L_Y,R_Y) #因为L_X和R_X都是一样的,所以随便传一个进去就行了
遇到的问题:
linear_model库的操作:
这个网上资料很多,但是我推荐这个博主的(传送门),因为比较清晰。所以在他的基础上,我讲几点,首先就是数据格式。特征x需要改为np.mat类型,标签y则要改成np.array类型
决定系数R^2为1或者均方误差为0:
大家知道我们现在可是进行的数据回归,不是分类,分类的话完全分准确实是有这个可能性,但是回归完全预测准确是几乎不存在的,(除非你是完全线性相关的)。更何况我们这可是10元线性回归问题呀。
所以一开始我们出现这个情况,就可以直接看系数,当其中大部分数据小的可怜,而有一个数据逼近一的时候,你就可以发现是你在划分数据集的时候,把标签值也划分到了特征值里面了,这样就造成了完全线性相关了。只需要去掉就行了
多元线性回归如何绘制残差图:
当然一元和二元回归还是可以画出来的,但是我们这个题是是十元线性回归,怎么画残差图呢?虽然这个问题对于数学专业的人来说确实没啥意义,但是我还是写一下:超过二元的线性回归画不出类似下面的残差图的!
因为目前还没有哪个绘图软件可以描述四维即以上的空间,所以我们这里的做法可以直接画出对比图,也就是用模型预测的和实际的去进行比较也就是类似下面的图:
numpy版本问题引发的warning如何忽略
直接两行代码解决
import warnings
warnings.filterwarnings('ignore') #忽略因为numpy版本问题引发的警告
怎么看最后的结果?
我们最终就是要得到上面的这个式子,最后我们通过调用我们模型的属性可以直接看到这些待求系数:
b0=regr.intercept_ (常数项)
bi=regr.coef_ (系数项)
(其中regr是我们建立的模型)