前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python机器学习教程—回归模型的评估与封装

Python机器学习教程—回归模型的评估与封装

作者头像
丹牛Daniel
发布2022-11-18 10:10:00
6920
发布2022-11-18 10:10:00
举报
文章被收录于专栏:python机器学习教程

在之前已介绍了线性回归的模型算法,那么有了模型之后,如何去评估这个模型的效果究竟是好还是差呢?而如果得到一个效果较好的模型又如何去将其封装,方便他人使用呢?这需要具备回归模型的评估与封装的知识。


回归模型的评估指标

如何去判断一个线性回归模型的好与坏,有个指标是看模型的拟合度,拟合度越高就代表模型的误差越小,也就代表着做预测时会越精准。因此对模型的效果评估很重要,并且模型的评估需要有同训练集分开的测试集,就好像高考是评估同学的学习效果,就必然不会拿平时做过的练习题去让同学们考,而是出新的题目给同学。

一般情况下,拿到数据集将整个数据集按照一定比例分为训练集和测试集,线性回归模型训练完毕后,可以利用测试集评估训练结果误差。sklearn.metrics提供了计算模型误差(预测结果和真实结果之间的)的几个常用算法API:

代码语言:javascript
复制
import sklearn.metrics as sm
#平均绝对值误差:1/mΣ|实际输出-预测输出|
sm.mean_absolute_error(y,pred_y)

#平均平方误差:SQRT(1/mΣ(实际输出-预测输出)A2)
sm.mean_squared_error(y,pred_y)

#中位绝对值误差:MEDIAN(|实际输出-预测输出)1
sm.median_absolute_error(y,pred_y)

#R2得分,(0,1]区间的分值。分数越高,误差越小。
sm.r2_score(y,pred_y)
  1. 平均绝对误差是相当于是看每个样本预测值和真实值的平均距离。误差对应到真实情况可理解为,假如我们根据一定的特征预测一个人的薪资水平大概15w/年,误差为0.4,也就是这个人的工资水平范围应该是14.6w-15.4w的区间内波动。
  2. 平均平方误差和平均绝对误差类似,只不过是取了一个平方再开根。
  3. 中位绝对值误差适合于最大值和最小值差距很大,中位数相较于均值更不易受影响

与上面的误差指标不同,实际上可看作一个模型的预测效果分数

代码实践

还是以薪资预测为例,这次使用一个名为数据集"Salary_Data.csv"的数据集,每行是一个样本,共有30个样本,共1个特征为工作年限,以及对应的薪资水平。将其读入python,画出散点图

代码语言:javascript
复制
# 加载数据集
data=pd.read_csv("Salary_Data.csv")
x,y=data['YearsExperience'],data['Salary']
train_x,train_y=pd.DataFrame(x),y

# 找到一组测试样本数据,输出评估指标结果
# 取测试集样本,从头至尾每4个切出1个数据
test_x,test_y=train_x.iloc[::4],train_y.iloc[::4] 
test_x

输出结果:所取出的测试集

 进行模型的建立和误差的评估

代码语言:javascript
复制
# 基于sklearn提供ApI,训练线性回归模型
model=lm.LinearRegression()
model.fit(train_x,train_y)

# 进行预测
pred_test_y=model.predict(test_x)

# 评估误差
import sklearn.metrics as sm 
print(sm.mean_absolute_error(test_y,pred_test_y))
print(sm.mean_squared_error(test_y,pred_test_y))
print(sm.median_absolute_error(test_y,pred_test_y))
print(sm.r2_score(test_y,pred_test_y))

以第一个输出结果为例,4587.366,这说明预测的薪资的误差上下波动的幅度在4000+左右,如果这个误差可以被接受,那么这个模型便可以使用。第二个由于是平方的缘故数值会明显较大。而最后一个输出是

得分,该值非常接近1,说明其预测效果较为优秀。

有了评估模型的方法,意味着在之后可以去比较模型的效果,那么模型如果要真正使用还需要对其进行保存和加载。

模型的保存和加载

模型训练是一个耗时的过程,如果数据复杂算法复杂有可能训练起来要很久的时间,一个优秀的机器学习是非常宝贵的。可以模型保存到磁盘中,也可以在需要使用的时候从磁盘中重新加载模型到内存中即可。不需要重新训练。保存和加载的工作在真正的业务中非常重要。

要存的究竟是什么呢?其实就是模型的参数,比如线性回归中的w0,w1,w2...而在python当中提供了可持久化python对象的方案,其API如下。模型训练好后,先调用下列代码前两行将训练好的模型存起来,等需要时调用后面的代码加载出来,项目真正要上线的代码就是下面那一部分模型加载出来的代码。

代码语言:javascript
复制
# 将训练好的模型对象保存到磁盘文件中
with open(../../data/linear.pkl','wb')as f:
    pickle.dump(model,f)

# 从磁盘文件中加载模型对象
with open(../../data/linear.pk1','rb')as f:
    model=pickle.load(f)
# 根据输入预测输出   
    pred_y=model.predict(x)

 代码实践

model是我们上面训练好的模型,运行如下这一段代码,如果保存成功就会输出“dump success.”

代码语言:javascript
复制
import pickle
with open('model.pickle','wb') as f:
    pickle.dump(model,f)
print('dump success.')

这样在当前的工作目录中就可以找到一个 model.pickle的文件,其保存了持久化的python对象。

 待需要使用时,直接在如下代码的predict()中加入要预测的样本数据

代码语言:javascript
复制
# 模型的加载
with open('model.pickle','rb') as f: 
    model=pickle.load(f)
model.predict([[15.6],[16.4]])

比如我设置了一组要预测的数据,当工作年限为15.6年和16.4年,对应的工资水平应该多少,输出结果如下: 

然而,在实际的业务应用中,上面的内容还是比较麻烦,因为要工作的程序员不同,要对其有很多说明才能帮助他正确的调用你写的代码,并且模型如果更新了,还需要将自己更新的文件交给要使用的程序员。

那么就需要采用封装的方法,封装到一个类,别的程序员需要的时候只需要import类,创建一个对象就可以使用模型的方法。

模型的封装

封装一个薪资预测的类,其中的构造方法意味着一旦创建对象便读取文件,拿到模型并存到属性,predict()方法是供他人使用,调用者只需要输入一维数组,在函数中会整理成二维数组,这样便可以适用model.predict()

代码语言:javascript
复制
import numpy as np
import pandas as pd
import pickle

# 声明一个薪资预测类型,封装预测逻辑
class SalaryPredictionModel():
    def _init_(self):
        with open('model.pickle','rb')as f:
            self.model=pickle.load(f)
    def predict(self,exps):
        """
        exps:工作年限数组(一维数组)
        """
        exps=np.array(exps).reshape(-1,1)#可以把(4,)一维数细变维:(4,1)
        return self.model.predict(exps)

在想要调用模型的时候只需要输入以下代码,传入一个数组即可

代码语言:javascript
复制
model=SalaryPredictionModel()
model.predict([3.4,5.5,6,8])
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-11-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 回归模型的评估指标
    • 代码实践
    • 模型的保存和加载
      •  代码实践
      • 模型的封装
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档