内容概要

  • 训练集/測试集切割用于模型验证的缺点
  • K折交叉验证是怎样克服之前的不足
  • 交叉验证怎样用于选择调节參数、选择模型、选择特征
  • 改善交叉验证

1. 模型验证回想

进行模型验证的一个重要目的是要选出一个最合适的模型,对于监督学习而言,我们希望模型对于未知数据的泛化能力强,所以就须要模型验证这一过程来体现不同的模型对于未知数据的表现效果。

最先我们用训练精确度(用所有数据进行训练和測试)来衡量模型的表现,这样的方法会导致模型过拟合;为了解决这一问题,我们将所有数据分成训练集和測试集两部分,我们用训练集进行模型训练。得到的模型再用測试集来衡量模型的预測表现能力,这样的度量方式叫測试精确度,这样的方式能够有效避免过拟合。

測试精确度的一个缺点是其样本精确度是一个高方差预计(high variance estimate),所以该样本精确度会依赖不同的測试集。其表现效果不尽同样。

高方差预计的样例

以下我们使用iris数据来说明利用測试精确度来衡量模型表现的方差非常高。

In [1]:
  1. from sklearn.datasets import load_iris
  2. from sklearn.cross_validation import train_test_split
  3. from sklearn.neighbors import KNeighborsClassifier
  4. from sklearn import metrics
In [2]:
  1. # read in the iris data
  2. iris = load_iris()
  3.  
  4. X = iris.data
  5. y = iris.target
In [3]:
  1. for i in xrange(1,5):
  2. print "random_state is ", i,", and accuracy score is:"
  3. X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=i)
  4.  
  5. knn = KNeighborsClassifier(n_neighbors=5)
  6. knn.fit(X_train, y_train)
  7. y_pred = knn.predict(X_test)
  8. print metrics.accuracy_score(y_test, y_pred)
  1. random_state is 1 , and accuracy score is:
  2. 1.0
  3. random_state is 2 , and accuracy score is:
  4. 1.0
  5. random_state is 3 , and accuracy score is:
  6. 0.947368421053
  7. random_state is 4 , and accuracy score is:
  8. 0.973684210526

以上測试准确率能够看出,不同的训练集、測试集切割的方法导致其准确率不同。而交叉验证的基本思想是:将数据集进行一系列切割。生成一组不同的训练測试集,然后分别训练模型并计算測试准确率,最后对结果进行平均处理。这样来有效减少測试准确率的差异。

2. K折交叉验证

  1. 将数据集平均切割成K个等份
  2. 使用1份数据作为測试数据,其余作为训练数据
  3. 计算測试准确率
  4. 使用不同的測试集。反复2、3步骤
  5. 对測试准确率做平均。作为对未知数据预測准确率的预计
In [4]:
  1. # 以下代码演示了K-fold交叉验证是怎样进行数据切割的
  2. # simulate splitting a dataset of 25 observations into 5 folds
  3. from sklearn.cross_validation import KFold
  4. kf = KFold(25, n_folds=5, shuffle=False)
  5.  
  6. # print the contents of each training and testing set
  7. print '{} {:^61} {}'.format('Iteration', 'Training set observations', 'Testing set observations')
  8. for iteration, data in enumerate(kf, start=1):
  9. print '{:^9} {} {:^25}'.format(iteration, data[0], data[1])
  1. Iteration Training set observations Testing set observations
  2. 1 [ 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24] [0 1 2 3 4]
  3. 2 [ 0 1 2 3 4 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24] [5 6 7 8 9]
  4. 3 [ 0 1 2 3 4 5 6 7 8 9 15 16 17 18 19 20 21 22 23 24] [10 11 12 13 14]
  5. 4 [ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 20 21 22 23 24] [15 16 17 18 19]
  6. 5 [ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19] [20 21 22 23 24]

3. 使用交叉验证的建议

  1. K=10是一个一般的建议
  2. 假设对于分类问题。应该使用分层抽样(stratified sampling)来生成数据。保证正负例的比例在训练集和測试集中的比例同样

4. 交叉验证的样例

4.1 用于调节參数

交叉验证的方法能够帮助我们进行调參。终于得到一组最佳的模型參数。以下的样例我们依旧使用iris数据和KNN模型,通过调节參数,得到一组最佳的參数使得測试数据的准确率和泛化能力最佳。

In [6]:
  1. from sklearn.cross_validation import cross_val_score
In [7]:
  1. knn = KNeighborsClassifier(n_neighbors=5)
  2. # 这里的cross_val_score将交叉验证的整个过程连接起来,不用再进行手动的切割数据
  3. # cv參数用于规定将原始数据分成多少份
  4. scores = cross_val_score(knn, X, y, cv=10, scoring='accuracy')
  5. print scores
  1. [ 1. 0.93333333 1. 1. 0.86666667 0.93333333
  2. 0.93333333 1. 1. 1. ]
In [8]:
  1. # use average accuracy as an estimate of out-of-sample accuracy
  2. # 对十次迭代计算平均的測试准确率
  3. print scores.mean()
  1. 0.966666666667
In [11]:
  1. # search for an optimal value of K for KNN model
  2. k_range = range(1,31)
  3. k_scores = []
  4. for k in k_range:
  5. knn = KNeighborsClassifier(n_neighbors=k)
  6. scores = cross_val_score(knn, X, y, cv=10, scoring='accuracy')
  7. k_scores.append(scores.mean())
  8.  
  9. print k_scores
  1. [0.95999999999999996, 0.95333333333333337, 0.96666666666666656, 0.96666666666666656, 0.96666666666666679, 0.96666666666666679, 0.96666666666666679, 0.96666666666666679, 0.97333333333333338, 0.96666666666666679, 0.96666666666666679, 0.97333333333333338, 0.98000000000000009, 0.97333333333333338, 0.97333333333333338, 0.97333333333333338, 0.97333333333333338, 0.98000000000000009, 0.97333333333333338, 0.98000000000000009, 0.96666666666666656, 0.96666666666666656, 0.97333333333333338, 0.95999999999999996, 0.96666666666666656, 0.95999999999999996, 0.96666666666666656, 0.95333333333333337, 0.95333333333333337, 0.95333333333333337]
In [10]:
  1. import matplotlib.pyplot as plt
  2. %matplotlib inline
In [12]:
  1. plt.plot(k_range, k_scores)
  2. plt.xlabel("Value of K for KNN")
  3. plt.ylabel("Cross validated accuracy")
Out[12]:
  1. <matplotlib.text.Text at 0x6dd0fb0>

上面的样例显示了偏置-方差的折中,K较小的情况时偏置较低。方差较高。K较高的情况时。偏置较高,方差较低;最佳的模型參数取在中间位置,该情况下,使得偏置和方差得以平衡,模型针对于非样本数据的泛化能力是最佳的。

4.2 用于模型选择

交叉验证也能够帮助我们进行模型选择,下面是一组样例,分别使用iris数据,KNN和logistic回归模型进行模型的比較和选择。

In [13]:
  1. # 10-fold cross-validation with the best KNN model
  2. knn = KNeighborsClassifier(n_neighbors=20)
  3. print cross_val_score(knn, X, y, cv=10, scoring='accuracy').mean()
  1. 0.98
In [14]:
  1. # 10-fold cross-validation with logistic regression
  2. from sklearn.linear_model import LogisticRegression
  3. logreg = LogisticRegression()
  4. print cross_val_score(logreg, X, y, cv=10, scoring='accuracy').mean()
  1. 0.953333333333

4.3 用于特征选择

以下我们使用advertising数据,通过交叉验证来进行特征的选择,对照不同的特征组合对于模型的预測效果。

In [15]:
  1. import pandas as pd
  2. import numpy as np
  3. from sklearn.linear_model import LinearRegression
In [16]:
  1. # read in the advertising dataset
  2. data = pd.read_csv('http://www-bcf.usc.edu/~gareth/ISL/Advertising.csv', index_col=0)
In [17]:
  1. # create a Python list of three feature names
  2. feature_cols = ['TV', 'Radio', 'Newspaper']
  3.  
  4. # use the list to select a subset of the DataFrame (X)
  5. X = data[feature_cols]
  6.  
  7. # select the Sales column as the response (y)
  8. y = data.Sales
In [18]:
  1. # 10-fold cv with all features
  2. lm = LinearRegression()
  3. scores = cross_val_score(lm, X, y, cv=10, scoring='mean_squared_error')
  4. print scores
  1. [-3.56038438 -3.29767522 -2.08943356 -2.82474283 -1.3027754 -1.74163618
  2. -8.17338214 -2.11409746 -3.04273109 -2.45281793]

这里要注意的是,上面的scores都是负数,为什么均方误差会出现负数的情况呢?由于这里的mean_squared_error是一种损失函数,优化的目标的使其最小化。而分类准确率是一种奖励函数,优化的目标是使其最大化。

In [19]:
  1. # fix the sign of MSE scores
  2. mse_scores = -scores
  3. print mse_scores
  1. [ 3.56038438 3.29767522 2.08943356 2.82474283 1.3027754 1.74163618
  2. 8.17338214 2.11409746 3.04273109 2.45281793]
In [20]:
  1. # convert from MSE to RMSE
  2. rmse_scores = np.sqrt(mse_scores)
  3. print rmse_scores
  1. [ 1.88689808 1.81595022 1.44548731 1.68069713 1.14139187 1.31971064
  2. 2.85891276 1.45399362 1.7443426 1.56614748]
In [21]:
  1. # calculate the average RMSE
  2. print rmse_scores.mean()
  1. 1.69135317081
In [22]:
  1. # 10-fold cross-validation with two features (excluding Newspaper)
  2. feature_cols = ['TV', 'Radio']
  3. X = data[feature_cols]
  4. print np.sqrt(-cross_val_score(lm, X, y, cv=10, scoring='mean_squared_error')).mean()
  1. 1.67967484191

因为不增加Newspaper这一个特征得到的分数较小(1.68 < 1.69)。所以,使用全部特征得到的模型是一个更好的模型。

【scikit-learn】交叉验证及其用于參数选择、模型选择、特征选择的样例的更多相关文章

  1. [深度概念]·K-Fold 交叉验证 (Cross-Validation)的理解与应用

    K-Fold 交叉验证 (Cross-Validation)的理解与应用 我的网站 1.K-Fold 交叉验证概念 在机器学习建模过程中,通行的做法通常是将数据分为训练集和测试集.测试集是与训练独立的 ...

  2. K-Fold 交叉验证

    转载--原文地址 www.likecs.com 1.K-Fold 交叉验证概念 在机器学习建模过程中,通行的做法通常是将数据分为训练集和测试集.测试集是与训练独立的数据,完全不参与训练,用于最终模型的 ...

  3. Effective JavaScript Item 21 使用apply方法调用函数以传入可变參数列表

    本系列作为Effective JavaScript的读书笔记. 以下是一个拥有可变參数列表的方法的典型样例: average(1, 2, 3); // 2 average(1); // 1 avera ...

  4. java 可变參数列表

    Java SE5加入了可变參数列表特性 參数能够这样定义.(Object-args).可变參数用"..."来定义,args是可变參数的数组.举个样例: package sample ...

  5. 一起talk C栗子吧(第一百二十七回:C语言实例--查看main函数的參数)

    各位看官们,大家好,上一回中咱们说的是static关键字的样例,这一回咱们说的样例是:查看main函数的參数.闲话休提,言归正转.让我们一起talk C栗子吧! 看官们.我们在第五十七回中介绍过mai ...

  6. 机器学习中的train valid test以及交叉验证

    转自 https://www.cnblogs.com/rainsoul/p/6373385.html 在以前的网络训练中,有关于验证集一直比较疑惑,在一些机器学习的教程中,都会提到,将数据集分为三部分 ...

  7. 总结:Bias(偏差),Error(误差),Variance(方差)及CV(交叉验证)

    犀利的开头 在机器学习中,我们用训练数据集去训练(学习)一个model(模型),通常的做法是定义一个Loss function(误差函数),通过将这个Loss(或者叫error)的最小化过程,来提高模 ...

  8. 验证和交叉验证(Validation & Cross Validation)

    之前在<训练集,验证集,测试集(以及为什么要使用验证集?)(Training Set, Validation Set, Test Set)>一文中已经提过对模型进行验证(评估)的几种方式. ...

  9. 斯坦福大学公开课机器学习:advice for applying machine learning | model selection and training/validation/test sets(模型选择以及训练集、交叉验证集和测试集的概念)

    怎样选用正确的特征构造学习算法或者如何选择学习算法中的正则化参数lambda?这些问题我们称之为模型选择问题. 在对于这一问题的讨论中,我们不仅将数据分为:训练集和测试集,而是将数据分为三个数据组:也 ...

随机推荐

  1. hihoCoder-1633 ACM-ICPC北京赛区2017 G.Liaoning Ship’s Voyage 线段与三角形规范相交

    题面 题意:给你一个20*20的地图,起点(0,0),终点(n-1,n-1),有障碍的点为‘#’,每次可以向8个方向走一步,还给了一个三角形,除了障碍以外,到这8个方向上的点的线段如果没有与三角形相交 ...

  2. Django之缓存机制

    1.1 缓存介绍 1.缓存的简介 在动态网站中,用户所有的请求,服务器都会去数据库中进行相应的增,删,查,改,渲染模板,执行业务逻辑,最后生成用户看到的页面. 当一个网站的用户访问量很大的时候,每一次 ...

  3. 根据项目类型导入Excel文件到不同数据库

    前提:如果您要针对不同的业务做数据导入,可以参考下这个项目,这个项目的原理就是根据文件名进行区分,然后导入不同的数据表.下面我就写个Demo演示下: 学生表-- 主键,学生姓名,学生年龄,学校归属 教 ...

  4. Windows 文件自动同步共享工具

    操作地址: http://blog.sina.com.cn/s/blog_1320088ed0102uxln.html下载地址: http://www.zisync.com/download

  5. hdu 2768 Cat vs. Dog 最大独立集 巧妙的建图

    题目分析: 一个人要不是爱狗讨厌猫的人,要不就是爱猫讨厌狗的人.一个人喜欢的动物如果离开,那么他也将离开.问最多留下多少人. 思路: 爱猫和爱狗的人是两个独立的集合.若两个人喜欢和讨厌的动物是一样的, ...

  6. caffe学习笔记--跑个SampleCode

    Caffe默认情况会安装在CAFFERROOT,就是解压到那个目录,例如: home/username/caffe-master, 所以下面的工作,默认已经切换到了该工作目录.下面的工作主要是,用于测 ...

  7. Session和Cookie对比详解

    会话(Session)跟踪是Web程序中常用的技术,用来跟踪用户的整个会话.常用的会话跟踪技术是Cookie与Session.Cookie通过在客户端记录信息确定用户身份,Session通过在服务器端 ...

  8. CentOS7 使用 firewalld 打开关闭 防火墙 与 端口!!

    1.firewalld的基本使用 启动: systemctl start firewalld 关闭: systemctl stop firewalld 查看状态: systemctl status f ...

  9. Java范式1

    package Xwxx; public class Person { private String name; private int age; public Person() { } public ...

  10. java 常用API 包装 数据

    package com.oracel.demo01; public class Sjzhhm { public static void main(String[] args) { method(); ...