【scikit-learn】如何进行模型参数的选择

内容概要

这一节我们介绍以下几个内容:

  • 我们该怎样选择模型用于监督学习任务?
  • 我们该如何选择调整得到最好的模型参数?
  • 我们该如何对测试数据进行预测估计?

1. 使用整个数据集进行训练和测试

  • 这里我们使用手中的整个数据集来训练模型
  • 使用同样的数据集来测试模型,然后评估预测的结果和真实结果的差别

In [1]:

from sklearn.datasets import load_iris
iris = load_iris()

# create X(features) and y(response)
X = iris.data
y = iris.target

Logistic regression

In [2]:

from sklearn.linear_model import LogisticRegression
logreg = LogisticRegression()

logreg.fit(X, y)
y_pred = logreg.predict(X)
print "predicted response:\n",y_pred
predicted response:
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 2 1 1 1
 1 1 1 1 1 1 1 1 1 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2
 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
 2 2]

In [3]:

len(y_pred)

Out[3]:

150

分类准确率

现在我们需要使用一种度量方式来评价我们的模型的运行情况,我们使用正确预测的比例来作为评估的度量(evaluation metric)。

In [4]:

from sklearn import metrics
print metrics.accuracy_score(y, y_pred)
0.96

以上说明对于训练的数据,我们有96%的数据预测正确。这里我们使用相同的数据来训练和预测,使用的度量称其为训练准确度。

KNN(K=5)

In [5]:

from sklearn.neighbors import KNeighborsClassifier
knn5 = KNeighborsClassifier(n_neighbors=5)
knn5.fit(X, y)
y_pred = knn5.predict(X)
print metrics.accuracy_score(y, y_pred)
0.966666666667

KNN(K=1)

In [6]:

knn1 = KNeighborsClassifier(n_neighbors=1)
knn1.fit(X, y)
y_pred = knn1.predict(X)
print metrics.accuracy_score(y, y_pred)
1.0

上面我们得到了训练准确度为100%的模型,貌似得到了最好的模型和参数。但我们回想一下KNN算法的原理,KNN算法寻找训练数据中的K个最近的数据,它使用指向最多的那个类别来作为预测的输出。

这下我们就明白了为什么当K=1的时候KNN算法的训练准确度为1,KNN会查找在训练数据集中的最近的观测,训练得到的模型会在相同的数据集中找到相同的观测。换句话说,KNN算法已经记住了训练数据集,因为我们使用同样的数据作为测试的数据。

小结

我们要明确训练模型的目的是得到对于未来的观测数据的良好的预测性能,如果我们只是试图最大化训练的准确率,很有可能得到的是针对训练数据的过于复杂的模型,这种模型不具有很好的泛化能力,也就是说对于未知数据的预测得不到很好的性能。

构建没有必要的过于复杂的模型被称作过拟合。这样的模型过分地拟合噪声数据,胜过去拟合信号数据。在KNN模型中,小K值的模型会生成复杂度很高的模型,因为它跟随数据中的噪声。

下面这个是过拟合的一幅图像:这里绿色的分割线努力去学习噪声的规律,而不像黑色的分割线去学习数据信号的规律,这样对比之下,黑色的线的泛化能力应该更好。

2. 分别设置训练集和测试集

  • 将数据集分成两部分:训练集和测试集
  • 使用训练集对模型进行训练
  • 使用测试集进行模型的测试并评估性能如何

In [7]:

print X.shape
print y.shape
(150, 4)
(150,)

In [22]:

# 第一步:将X和y分割成训练和测试集
from sklearn.cross_validation import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.4, random_state=4)
# 这里的random_state参数根据给定的给定的整数,得到伪随机生成器的随机采样

上面这个图告诉我们train_test_split函数的功能,将一个数据集分成两部分。这样使用不同的数据集对模型进行分别的训练和测试,得到的测试准确率能够更好的估计模型对于未知数据的预测效果。

这里测试数据的大小没有统一的标准,一般选择数据集的20%-40%作为测试数据。

In [9]:

print X_train.shape
print X_test.shape
(90, 4)
(60, 4)

In [10]:

print y_train.shape
print y_test.shape
(90,)
(60,)

In [11]:

# 第二步:使用训练数据训练模型
logreg = LogisticRegression()
logreg.fit(X_train, y_train)

Out[11]:

LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True,
          intercept_scaling=1, max_iter=100, multi_class=‘ovr‘,
          penalty=‘l2‘, random_state=None, solver=‘liblinear‘, tol=0.0001,
          verbose=0)

In [12]:

# 第三步: 针对测试数据进行预测,并得到测试准确率
y_pred = logreg.predict(X_test)

print metrics.accuracy_score(y_test, y_pred)
# 可以尝试一下,对于上面不同数据集分割,得到的测试准确率不同
0.95

使用KNN算法

In [13]:

# K=5

knn5 = KNeighborsClassifier(n_neighbors=5)
knn5.fit(X_train, y_train)
y_pred = knn5.predict(X_test)
print metrics.accuracy_score(y_test, y_pred)
0.966666666667

In [14]:

# K=1

knn1 = KNeighborsClassifier(n_neighbors=1)
knn1.fit(X_train, y_train)
y_pred = knn1.predict(X_test)
print metrics.accuracy_score(y_test, y_pred)
0.95

我们能找到一个比较好的K值吗?

In [15]:

# 测试从K=1到K=25,记录测试准确率
k_range = range(1, 26)
test_accuracy = []

for k in k_range:
    knn = KNeighborsClassifier(n_neighbors=k)
    knn.fit(X_train, y_train)
    y_pred = knn.predict(X_test)
    test_accuracy.append(metrics.accuracy_score(y_test, y_pred))

In [16]:

%matplotlib inline
import matplotlib.pyplot as plt

plt.plot(k_range, test_accuracy)
plt.xlabel("Value of K for KNN")
plt.ylabel("Testing Accuracy")

Out[16]:

模型参数的选择

在这里,我们选择K的值为11,因为在K=11时,有较高的测试准确率。

In [17]:

# 这里我们对未知数据进行预测
knn11 = KNeighborsClassifier(n_neighbors=11)
knn11.fit(X, y)

knn11.predict([3, 5, 4, 2])

Out[17]:

array([1])

小结

  • KNN的模型复杂度主要由K的值决定,K值越小,复杂度越高
  • 训练准确度随着模型复杂度更加复杂而升高
  • 测试准确率在模型过于复杂和过于简单的时候都比较低

这种分割训练和测试数据集的模型评估流程的缺点是:这种方式会导致待预测数据(out-of-sample)估计准确率的方差过高。因为这种方式过于依赖训练数据和测试数据在数据集中的选择方式。一种克服这种的缺点的模型评估流程称为K折交叉验证,这种方法通过多次反复分割训练、测试集,对结果进行平均。

3. K折交叉检验

K折将数据集分成K个部分,其中K-1组数据作为构建预测函数的训练之用,剩余的一组数据作为测试之用。

In [18]:

from sklearn.cross_validation import KFold
import numpy as np

def cv_estimate(k, kfold=5):
    cv = KFold(n = X.shape[0], n_folds=kfold)
    clf = KNeighborsClassifier(n_neighbors=k)
    score = 0
    for train, test in cv:
        clf.fit(X[train], y[train])
        score += clf.score(X[test], y[test])
        #print clf.score(X[test], y[test])
    score /= kfold
    return score

In [19]:

# 测试从K=1到K=25,记录测试准确率
k_range = range(1, 26)
test_accuracy = []

for k in k_range:
    test_accuracy.append(cv_estimate(k, 5))

In [20]:

print test_accuracy
[0.92666666666666653, 0.90666666666666662, 0.90666666666666662, 0.90666666666666662, 0.91333333333333333, 0.90666666666666662, 0.92000000000000015, 0.91333333333333333, 0.92000000000000015, 0.92000000000000015, 0.91333333333333344, 0.89333333333333331, 0.90666666666666662, 0.90000000000000002, 0.90000000000000002, 0.88666666666666671, 0.88000000000000012, 0.86666666666666659, 0.88666666666666671, 0.86666666666666681, 0.86666666666666681, 0.86666666666666681, 0.86666666666666681, 0.84666666666666668, 0.85999999999999999]

In [21]:

plt.plot(k_range, test_accuracy)
plt.xlabel("Value of K for KNN")
plt.ylabel("Average Accuracy of Kfold CV")

Out[21]:

时间: 2024-12-25 19:27:06

【scikit-learn】如何进行模型参数的选择的相关文章

最小角回归 LARS算法包的用法以及模型参数的选择

Lasso回归模型,是常用线性回归的模型,当模型维度较高时,Lasso算法通过求解稀疏解对模型进行变量选择.Lars算法则提供了一种快速求解该模型的方法.Lars算法的基本原理有许多其他文章可以参考,这里不过多赘述, 这里主要简介如何在R中利用lars算法包求解线性回归问题以及参数的选择方法. 以下的的一些用法参照lars包的帮助文件,再加上自己的使用心得.所用的示例数据diabetes是Efron在其论文中"Least Angle Regression"中用到的,可以在加载lars包

Query意图分析:记一次完整的机器学习过程(scikit learn library学习笔记)

所谓学习问题,是指观察由n个样本组成的集合,并根据这些数据来预测未知数据的性质. 学习任务(一个二分类问题): 区分一个普通的互联网检索Query是否具有某个垂直领域的意图.假设现在有一个O2O领域的垂直搜索引擎,专门为用户提供团购.优惠券的检索:同时存在一个通用的搜索引擎,比如百度,通用搜索引擎希望能够识别出一个Query是否具有O2O检索意图,如果有则调用O2O垂直搜索引擎,获取结果作为通用搜索引擎的结果补充. 我们的目的是学习出一个分类器(classifier),分类器可以理解为一个函数,

scikit learn 模块 调参 pipeline+girdsearch 数据举例:文档分类

scikit learn 模块 调参 pipeline+girdsearch 数据举例:文档分类数据集 fetch_20newsgroups #-*- coding: UTF-8 -*- import numpy as np from sklearn.pipeline import Pipeline from sklearn.linear_model import SGDClassifier from sklearn.grid_search import GridSearchCV from sk

fluent批量处理——模型参数的设置

对于常见的工程应用来说,计算的工况很多,尤其优化工作,少则几百,多则上千,面对如此之多的case文件要写,假如按照一个一个的读写的话,相信你一定会为这么机械的工作烦躁,甚至影响今后好几天的心情,那么有什么简便一些的方法呢?答案是肯定的.那就是采用fluent的journal文件.首先打开fluent软件,在file/write/start journal,见下图: 选择保存文件名*.journal后(看你自己怎么设置文件名),我一般按照这一组的类型来命名:这样, journal文件就开始记录你以

机器学习笔记(二)模型评估与选择

2.模型评估与选择 2.1经验误差和过拟合 不同学习算法及其不同参数产生的不同模型,涉及到模型选择的问题,关系到两个指标性,就是经验误差和过拟合. 1)经验误差 错误率(errorrate):分类错误的样本数占样本总数的比例.如果在m个样本中有a个样本分类错误,则错误率E=a/m,相应的,1-a/m称为精度(accuracy),即精度=1-错误率. 误差(error):学习器的实际预测输出和样本的真实输出之间的差异.训练误差或经验误差:学习器在训练集上的误差:泛化误差:学习器在新样本上的误差.

【机器学习 第2章 学习笔记】模型评估与选择

1.训练误差:学习器在训练集上的误差,也称“经验误差” 2.泛化误差:学习器在新样本上的误差 显然,我们的目标是得到在新样本上表现更好的学习器,即泛化误差要小 3.过拟合:学习器把训练样本学的太好了,导致泛化性能下降(学过头了...让我联想到有些人死读书,读死书,僵化,不懂得变通和举一反三) 原因:学习能力过于强大,把一些不太一般的特性也学了进来 针对措施:不好解决,是机器学习面临的关键障碍 4.欠拟合:就是连训练集都没学好,更别说泛化了(有点管中窥豹,盲人摸象的意思). 原因: 学习能力低下

三.Windows I/O模型之事件选择(WSAEventSelect )模型

1.事件选择模型:和异步选择模型类似的是,它也允许应用程序在一个或多个套接字上,接收以事件为基础的网络事件通知.对于异步选择模型采用的网络事件来说,它们均可原封不动地移植到事件选择模型.事件选择模型和异步选择模型最主要的差别在于网络事件会投递至一个事件对象句柄,而非投递至一个窗口例程.2.创建事件对象:事件选择模型要求应用程序针对打算使用事件选择模型的每一个套接字,首先创建一个事件对象.创建方法是调用WSACreateEvent函数,它的定义如下:WSAEVENT WSACreateEvent(

机器学习总结之第二章模型评估与选择

机器学习总结之第二章模型评估与选择 2.1经验误差与过拟合 错误率 = a个样本分类错误/m个样本 精度 = 1 - 错误率 误差:学习器实际预测输出与样本的真是输出之间的差异. 训练误差:即经验误差.学习器在训练集上的误差. 泛化误差:学习器在新样本上的误差. 过拟合:学习器把训练样本学的"太好",把不太一般的特性学到了,泛化能力下降,对新样本的判别能力差.必然存在,无法彻底避免,只能够减小过拟合风险. 欠拟合:对训练样本的一半性质尚未学好. 2.2评估方法 (在现实任务中,还需考虑

【机器学习123】模型评估与选择 (上)

第2章 模型评估与选择 2.1 经验误差与过拟合 先引出几个基本概念: 误差(error):学习器的实际预测输出与样本的真实输出之间的差异. 训练误差(training error):学习器在训练集上的误差,也称"经验误差". 测试误差(testing error):学习器在测试集上的误差. 泛化误差(generalization error):学习器在新样本上的误差. 错误率(error rate):分类错误的样本数占样本总数的比例. 精度(accuracy) = 1 – 错误率.