在机器学习领域,模型的欠拟合问题和过拟合问题一直都是我们关注的重点,正确的诊断出你的模型属于哪一类问题对改善模型至关重要。
所谓欠拟合一般是指模型没有很好的抓住数据的特征,没有对数据进行很好的拟合,使得偏差较大。这时一般要通过增加特征项或者减少正则化参数来改进模型。
而过拟合一般是由于模型使用了太多的特征引起的,使得模型将部分数据的“特性”也学习到了,导致模型的泛化能力较弱。这时一般要通过删减特征项或者增大正则化参数来改进模型。
本文通过单变量的线性回归来说明应该通过哪些操作来诊断模型是属于欠拟合还是过拟合。
对于单变量的线性回归,我们最简单的一个模型就是一次方程。我们的假设函数如下。
利用这个模型来拟合数据,绘制的拟合效果图如下。
不难看出,这个模型对数据的拟合效果不好,我们可以直观的判定这个模型存在欠拟合问题。但能不能通过什么有效的方法判断一个模型到底是存在欠拟合还是过拟合的问题呢。
答案是肯定的,我们可以绘制这个模型的学习曲线,通过学习曲线的形态来判断。所谓学习曲线就是训练集得分和验证集得分随着训练样本数的增大而变化的曲线。
当模型出现欠拟合和过拟合情况时,学习曲线一般有不同形状,如下图所示。
欠拟合情况:随着训练样本数增大,训练集得分和验证集得分收敛,并且两者的收敛值很接近。
过拟合情况:随着训练样本数增大,训练集得分和验证集得分相差还是很大。
下面利用sklearn包绘制单变量线性回归的Python代码如下。
import scipy.io as siofrom sklearn.model_selection import learning_curvefrom sklearn import linear_modelimport matplotlib.pyplot as pltimport numpy as np# 读取以MATLAB矩阵存储的数据集data = sio.loadmat('data.mat')X_train = data['X']X_cv = data['Xval']X_train = np.concatenate((X_train,X_cv),axis=0)Y_train = data['y']Y_cv = data['yval']Y_train = np.concatenate((Y_train,Y_cv),axis=0)Y_train = Y_train.reshape([1, len(Y_train)])[0]reg = linear_model.Ridge(alpha=0)train_sizes, train_scores, valid_scores = learning_curve(reg, X_train, Y_train, train_sizes=range(1,25,1), cv=4)train_std=train_scores.mean(axis=1)test_std=valid_scores.mean(axis=1)plt.plot(train_sizes,train_std,color='red')plt.plot(train_sizes,test_std,color='blue')plt.xlabel('')plt.show()
得到的学习曲线如下。
通过观察学习曲线,可以判断模型存在欠拟合问题。我们试着利用多项式回归来改进模型。此时模型的假设函数形式如下。
其中Xp=X1的p次方。
我们可以用p=1、2、...、8依次试探,但有什么策略选出最好的p值吗?答案是肯定的,我先给出如下一张图。
这幅图描绘的是训练误差和验证误差随着多项式次数的增加而变化的图。当d很小的时候,训练误差和验证误差都很大,并且很接近,此时模型存在欠拟合问题;当d较大时,训练误差很小,但验证误差还是很大,此时模型存在过拟合问题。我们要取中间较均衡的d作为多项式的次数。
利用sklearn绘制的图如下所示。
通过上图的观察,我们可以取3作为多项式模型的次数。此时模型的拟合效果如下图所示。
好了,本次的文章就写到这里了。
领取专属 10元无门槛券
私享最新 技术干货