如何用学习曲线判断过拟合和欠拟合。

1. 什么是学习曲线

学习曲线是模型在训练集和验证集上的得分变化曲线,横坐标表示的是样本数量(x_train的数据量)的大小,纵坐标为训练集和验证集的得分(train_score, test_score)

2. 什么是过拟合和欠拟合

过拟合:过拟合一般是由于模型使用了太多的特征引起的,太过贴近于训练数据的特征了,在训练集上表现非常优秀,但是在新的测试集上却表现平平,不具泛化性。
欠拟合:欠拟合一般是指模型没有很好的抓住数据的特征,在训练集和测试集的准确率相差不大,但是都表现的大,使得偏差较大。

3. 怎么判断过拟合还是欠拟合

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
46
47
48
49
50
51
import numpy as np
import matplotlib.pyplot as plt
from sklearn.naive_bayes import GaussianNB
from sklearn.svm import SVC
from sklearn.datasets import load_digits
from sklearn.model_selection import learning_curve
from sklearn.model_selection import ShuffleSplit

def plot_learning_curve(estimator, title, X, y, ylim=None, cv=None,
n_jobs=1, train_sizes=np.linspace(.1, 1.0, 5)):
plt.figure()
plt.title(title)
if ylim is not None:
plt.ylim(*ylim)
plt.xlabel("Training examples")
plt.ylabel("Score")
train_sizes, train_scores, test_scores = learning_curve(
estimator, X, y, cv=cv, n_jobs=n_jobs, train_sizes=train_sizes)
train_scores_mean = np.mean(train_scores, axis=1)
train_scores_std = np.std(train_scores, axis=1)
test_scores_mean = np.mean(test_scores, axis=1)
test_scores_std = np.std(test_scores, axis=1)
plt.grid()

plt.fill_between(train_sizes, train_scores_mean - train_scores_std,
train_scores_mean + train_scores_std, alpha=0.1,
color="r")
plt.fill_between(train_sizes, test_scores_mean - test_scores_std,
test_scores_mean + test_scores_std, alpha=0.1, color="g")
plt.plot(train_sizes, train_scores_mean, 'o-', color="r",
label="Training score")
plt.plot(train_sizes, test_scores_mean, 'o-', color="g",
label="Cross-validation score")

plt.legend(loc="best")
return plt

digits = load_digits()
X, y = digits.data, digits.target

title = r"Learning Curves (Naive Bayes)"
cv = ShuffleSplit(n_splits=100, test_size=0.2, random_state=0)
estimator = GaussianNB()
plot_learning_curve(estimator, title, X, y, ylim=(0.7, 1.01), cv=cv, n_jobs=1)

title = r"Learning Curves (SVM, RBF kernel, $\gamma=0.001$)"
cv = ShuffleSplit(n_splits=10, test_size=0.2, random_state=0)
estimator = SVC(gamma=0.001)
plot_learning_curve(estimator, title, X, y, (0.7, 1.01), cv=cv, n_jobs=1)

plt.show()

image.png
图一
image.png
图二
从图一我们可以观察到,当模型欠拟合时,随着训练数据集的增加,交叉验证数据集(cross_vaildation score)的准确性逐渐增大,逐渐和训练数据集的准确性(Training score)靠近,得到一条基本不变的直线,且准确性在0.85左右,从这个关系可以看出来,当发生高偏差时,增加训练样本数量不会对算法准确性有较大的改善。
从图二可以观察到,当模型过拟合时,随着训练数据集的增加,交叉验证数据集的准确性(实线)也在增加,逐渐和训练数据集的准确性靠近,但两者之间的间隙比较大。

4. 怎么解决过拟合还是欠拟合

  • 过拟合:可以增加样本量或者降低模型的复杂度,比如减小树的深度、增大分裂节点样本数、增大样本数、减少特征数。
  • 欠拟合:可以增加模型参数,比如,构建更多的特征,减小正则项。