误差模型:过拟合,交叉验证,偏差-方差权衡
作者Natasha Latysheva;Charles Ravarani
发表于cambridgecoding
介绍
在本文中也许你会掌握机器学习中最核心的概念:偏差-方差权衡.其主要想法是,你想创建尽可能预测准确并且仍能适用于新数据的模型(这是泛化).危险的是,你可以轻松的在你制定的数据中创建过度拟合本地噪音的模型,这样的模型是无用的,并且导致弱泛化能力,因为噪声是随机的,故而在每个数据集中是不同的.从本质上讲,你希望创建仅捕获数据集中有用成份的模型.另一方面,泛化能力很好但是对于产生良好预测过于僵化的模型是另一个极端(这称之为欠拟合).
我们使用k-近邻算法讨论并展示这些概念,k-近邻带有一个简单的参数k,可以用不同的参数清楚的展示欠拟合,过拟合以及泛化能力的思想.同时,平衡欠拟合和过拟合之间的相关概念称为偏差-方差权衡.这里有一个表格概括了无论是过拟合或者欠拟合模型中一些不同但相同
我们将解释这些术语的意思,以及他们如何关联的.同样也会讨论交叉验证,这是评估模型准确率和泛化能力的优秀指标.
你会在未来的所有博文中遇到这些概念,将涵盖模型优化,随机森林,朴素贝叶斯,逻辑回归以及如何将不同模型组合成为集成元模型.
产生数据
让我们从建立人工数据集开始.你可以轻松的使用sklearn.datasets中的make_classification()函数做到这一点.具体来说,你会生成相对简单的二元分类问题.为了让它更有趣一点,让我们的数据呈现月牙型并加入一些随机噪声.这应该能让其更真实并提高分类观测的难度.
“`
Creating the dataset
e.g. make_moons generates crescent-shaped data
Check out make_classification, which generates linearly-separable data
from sklearn.datasets import make_moons
X, y = make_moons(
n_samples=500, # the number of observations
random_state=1,
noise=0.3
)
Take a peek
print(X[:10,])
print(y[:10])
“`
[[ 0.50316464 0.11135559]
[ 1.06597837 -0.63035547]
[ 0.95663377 0.58199637]
[ 0.33961202 0.40713937]
[ 2.17952333 -0.08488181]
[ 2.00520942 0.7817976 ]
[ 0.12531776 -0.14925731]
[ 1.06990641 0.36447753]
[-0.76391099 -0.6136396 ]
[ 0.55678871 0.8810501 ]]
[1 1 0 0 1 1 1 0 0 0]
你刚生成的数据集如下图所示:
“`
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColorma
%matplotlib inline # for the plots to appear inline in jupyter notebooks
Plot the first feature against the other, color by class
plt.scatter(X[y == 1, 0], X[y == 1, 1], color=”#EE3D34”, marker=”x”)
plt.scatter(X[y == 0, 0], X[y == 0, 1], color=”#4458A7”, marker=”o”)
“`
![](http://i.imgur.com/f3FP1Xu.jpg)
接下来,让我们将数据且分为 训练集 和 测试集 .训练集用于开发和优化模型.测试集完全分离,直到最后在此运行完成的模型.拥有测试集允许你在之前看不到的数据之外,模型运行良好的估计.
“`
from sklearn.cross_validation import train_test_split
Split into training and test sets
XTrain, XTest, yTrain, yTest = train_test_split(X, y, random_state=1, test_size=0.5)
“`
使用K近邻(KNN)分类器预测数据集类别.Introduction to Statistical Learning第二章提供了关于KNN理论非常好介绍.我是ISLR书的脑残粉.你同样可以看看之前文章 how to implement the algorithm from scratch in Python.
介绍KNN中的超参数K
KNN算法的工作原理是,对新数据点利用K近邻信息分配类别标签.只注重于和它最相似数据点的类,并分配这个新数据点到这些近邻中最常见的类.当使用KNN,你需要设定希望算法使用的K值.
如果K很高(k=99),模型在对未知数据点类别做决策是会考虑大量近邻.这意味着模型是相当受限的,因为它分类实例时,考虑了大量信息.换句话说,一个大的k值导致相当”刚性”的模型行为.
相反,如果k很低(k=1,或k=2),在做分类决策时只考虑少量近邻,这是非常灵活并且非常复杂的模型,它能完美拟合数据的精确形式.因此模型预测更依赖于数据的局部趋势(关键的是,包含噪声).
让我们看一看k=99与k=1时KNN算法分类数据的情况.绿色的线是训练数据的决策边界(算法中的阈值决定一个数据点是否属于蓝或红类).
在本文最后你会学会如何生成这些图像,但是先让我们先深入理论.
当k=99(左),看起来模型拟合有点太平滑,对于有点接近的数据可以忍受.模型具有低灵活性 和低复杂度 .它描绘了一个笼统的决策边界.它具有比较高的偏差 ,因为对数据建模并不好,模型化数据的底层生成过程太过简单,并且偏离了事实.但是,如果你扔到另一个稍微不同的数据集,决策边界可能看起来非常相似.这是不会有非