{ "cells": [ { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": true }, "outputs": [], "source": [ "%matplotlib inline\n", "import numpy as np" ] }, { "cell_type": "markdown", "metadata": { "collapsed": false }, "source": [ "> 作者:\tFabian Pedregosa, Gael Varoquaux\n", "\n", "**先决条件**\n", "\n", "Numpy, Scipy\n", "\n", "IPython\n", "\n", "matplotlib\n", "\n", "scikit-learn (http://scikit-learn.org)\n", "![](http://scipy-lectures.github.io/_images/scikit-learn-logo.png)\n", "\n", "**章节内容**\n", "\n", " 加载样例数据集\n", " - 学习与预测\n", " 分类\n", " - KNN分类器\n", " - 分类的支持向量机(SVMs)\n", " 聚类:将观察值聚集在一起\n", " - K-means聚类\n", " 使用主成分分析的降维\n", " 把所有都放在一起:面孔识别\n", " 线性模型:从回归到简约\n", " - 简约模型\n", " 模型选择:选择预测器和参数\n", " - 网格搜索和交叉验证预测器\n", " \n", "---\n", "**警告**:从版本0.9(在2011年9月发布)起,scikit-learn导入路径从scikits.learn 改为 sklearn\n", "\n", "---\n", "\n", "## 3.5.1 加载样例数据集\n", "\n", "![](http://scipy-lectures.github.io/_images/Virginia_Iris.png)\n", "\n", "首先,我们将加载一些数据来玩玩。我们将使用的数据是知名的非常简单的花数据鸢尾花数据集。\n", "\n", "我们有150个鸢尾花观察值指定了一些测量:花萼宽带、花萼长度、花瓣宽度和花瓣长度,以及对应的子类:Iris setosa、Iris versicolor和Iris virginica。\n", "\n", "将数据集加载为Python对象:" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": true }, "outputs": [], "source": [ "from sklearn import datasets\n", "iris = datasets.load_iris()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "这个数据存储在`.data`成员中,是一个 (n_samples, n_features) 数组。" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "(150, 4)" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "iris.data.shape" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "每个观察的类别存储在数据集的`.target`属性中。这是长度是n_samples的1D整型数组 :" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "(150,)" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "iris.target.shape" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([0, 1, 2])" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import numpy as np\n", "np.unique(iris.target)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "数据重排的例子:digits 数据集\n", "![](http://scipy-lectures.github.io/_images/digits_first_image.png)\n", "\n", "digits 数据集包含1797 图像,每一个是8X8像素的图片,代表一个手写的数字" ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "(1797, 8, 8)" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "digits = datasets.load_digits()\n", "digits.images.shape" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import pylab as pl\n", "pl.imshow(digits.images[0], cmap=pl.cm.gray_r) " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "要在scikit使用这个数据集,我们将每个8X8图片转化为一个长度为64的向量" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "collapsed": true }, "outputs": [], "source": [ "data = digits.images.reshape((digits.images.shape[0], -1))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "### 3.5.1.1 学习和预测\n", "\n", "现在我们有了一些数据,我们想要从上面学习并且在新的数据做预测。在scikit-learn中,我们通过创建一个预测器,并调用他的 fit(X, Y) 方法从现有数据上学习。" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "LinearSVC(C=1.0, class_weight=None, dual=True, fit_intercept=True,\n", " intercept_scaling=1, loss='squared_hinge', max_iter=1000,\n", " multi_class='ovr', penalty='l2', random_state=None, tol=0.0001,\n", " verbose=0)" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from sklearn import svm\n", "clf = svm.LinearSVC()\n", "clf.fit(iris.data, iris.target) # 从数据学习" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "一旦我们从数据中学习,我们可以用我们的模型来预测未见过的数据的最可能输出:" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([0])" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "clf.predict([[ 5.0, 3.6, 1.3, 0.25]])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "**注意**:我们可以通过由下滑线结尾的属性来访问模型的参数:\n", "\n", "---" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([[ 0.18424728, 0.45122657, -0.80794162, -0.45070597],\n", " [ 0.05691797, -0.89245895, 0.39682582, -0.92882381],\n", " [-0.85072494, -0.98678239, 1.38091241, 1.86550868]])" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "clf.coef_" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 3.5.2 分类\n", "### 3.5.2.1 KNN分类器\n", "![](http://scipy-lectures.github.io/_images/iris_knn.png)\n", "\n", "可能最简单的分类器是最接近的邻居: 给定一个观察,使用在N维空间中训练样例中最接近它标签,这里N是每个样例的特征数。\n", "\n", "K个最临近的邻居分类器内部使用基于ball tree的算法,用来代表训练的样例。\n", "\n", "**KNN (K个最临近邻居) 分类的例子:**" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski',\n", " metric_params=None, n_neighbors=5, p=2, weights='uniform')" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 创建并拟合一个最临近邻居分类器\n", "from sklearn import neighbors\n", "knn = neighbors.KNeighborsClassifier()\n", "knn.fit(iris.data, iris.target) " ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([0])" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "knn.predict([[0.1, 0.2, 0.3, 0.4]])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "\n", "**训练集和测试集**\n", "\n", "当用学习算法进行实验时,重要的一点是不要用拟合预测器的数据来测试预测器的预测力。实际上,我们通常会在测试集上得到准确的预测。" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski',\n", " metric_params=None, n_neighbors=5, p=2, weights='uniform')" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "perm = np.random.permutation(iris.target.size)\n", "iris.data = iris.data[perm]\n", "iris.target = iris.target[perm]\n", "knn.fit(iris.data[:100], iris.target[:100]) " ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "0.95999999999999996" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "knn.score(iris.data[100:], iris.target[100:]) " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "额外的问题: 为什么我们使用随机排列?\n", "\n", "---" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 3.5.2.2 分类的支持向量机 (SVMs)\n", "\n", "#### 3.5.2.2.1 线性支持向量机\n", "\n", "![](http://scipy-lectures.github.io/_images/svm_margin.png)\n", "\n", "SVMs试图构建一个最大化两个类的间距的超平面。它选取输入的一个子集,称为支持向量,这个子集中的观察距离分隔超平面最近。" ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0, degree=3, gamma=0.0,\n", " kernel='linear', max_iter=-1, probability=False, random_state=None,\n", " shrinking=True, tol=0.001, verbose=False)" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from sklearn import svm\n", "svc = svm.SVC(kernel='linear')\n", "svc.fit(iris.data, iris.target) " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "在scikit-learn实现了几种支持向量机。最常用的是`svm.SVC`、`svm.NuSVC` 和 `svm.LinearSVC`; “SVC” 代表支持向量分类器 (也存在用于回归的SVMs, 在scikit-learn被称为“SVR”)。\n", "\n", "---\n", "\n", "**练习**\n", "\n", "在digits数据集上训练`svm.SVC`。留下最后的10%,在这些观察上测试预测的效果。\n", "\n", "---\n", "\n", "#### 3.5.2.2.2 使用核 (kernel)\n", "\n", "类通常并不是都能用超平面分隔,因此,有一个不仅仅是线性也可能是多项式或者幂的决策函数是明智的 :\n", "\n", "**线性核 (kernel)**\n", "![](http://scipy-lectures.github.io/_images/svm_kernel_linear.png)" ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "collapsed": true }, "outputs": [], "source": [ "svc = svm.SVC(kernel='linear')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**多项式核 (kernel)**\n", "![](http://scipy-lectures.github.io/_images/svm_kernel_poly.png)" ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "collapsed": true }, "outputs": [], "source": [ "svc = svm.SVC(kernel='poly', degree=3)\n", "# degree: 多项式的阶" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**RBF核 (kernel) (径向基核函数)**\n", "![](http://scipy-lectures.github.io/_images/svm_kernel_rbf.png)" ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "collapsed": true }, "outputs": [], "source": [ "svc = svm.SVC(kernel='rbf')\n", "# gamma: 径向基核大小的倒数" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "\n", "**练习**\n", "以上列出的核哪一个在digits数据集上有较好的预测表现?\n", "\n", "---\n", "\n", "## 3.5.3 聚类 : 将观察值分组\n", "\n", "以鸢尾花 (iris) 数据集为例,如果有三类鸢尾花,但是并不能访问他们标签,我们可以尝试**非观察学习** : 通过一些标准将观察**聚类**分入一些组。\n", "\n", "### 3.5.3.1 K-means 聚类\n", "\n", "最简单的聚类算法是k-means。这个算法将集合分成k个组,将每个观察值分配给一个组,以便使观察值 (在n维空间) 到组平均值的距离最小;然后重新计算平均数。循环进行这个操作直到组收敛,比如达到最大的`max_iter`循环次数。\n", "\n", "(k-means的另一个实现在SciPy的`cluster`包中。`scikit-learn`实现的不同在于提供了一个对象API和一些额外的功能,包括智能初始化。)" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "KMeans(copy_x=True, init='k-means++', max_iter=300, n_clusters=3, n_init=10,\n", " n_jobs=1, precompute_distances='auto', random_state=None, tol=0.0001,\n", " verbose=0)" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from sklearn import cluster, datasets\n", "iris = datasets.load_iris()\n", "k_means = cluster.KMeans(n_clusters=3)\n", "k_means.fit(iris.data) " ] }, { "cell_type": "code", "execution_count": 25, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[0 0 0 0 0 1 1 1 1 1 2 2 2 2 2]\n" ] } ], "source": [ "print k_means.labels_[::10]" ] }, { "cell_type": "code", "execution_count": 26, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[0 0 0 0 0 1 1 1 1 1 2 2 2 2 2]\n" ] } ], "source": [ "print iris.target[::10]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**真实情况**\n", "\n", "![](http://scipy-lectures.github.io/_images/cluster_iris_truth.png)\n", "**K-means (3 组)**\n", "\n", "![](http://scipy-lectures.github.io/_images/k_means_iris_3.png)\n", "**K-means (8 组)**\n", "\n", "![](http://scipy-lectures.github.io/_images/k_means_iris_8.png)\n", "\n", "---\n", "**在图像压缩中的应用**\n", "\n", "聚类可以看做从信息中选取一组观察的方式。例如,这个技术可以被用来posterize一个图像 (将连续渐变色调转换为更少色调的一些区域):" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "KMeans(copy_x=True, init='k-means++', max_iter=300, n_clusters=5, n_init=10,\n", " n_jobs=1, precompute_distances='auto', random_state=None, tol=0.0001,\n", " verbose=0)" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from scipy import misc\n", "lena = misc.lena().astype(np.float32)\n", "X = lena.reshape((-1, 1)) # We need an (n_sample, n_feature) array\n", "k_means = cluster.KMeans(n_clusters=5)\n", "k_means.fit(X) " ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": true }, "outputs": [], "source": [ "values = k_means.cluster_centers_.squeeze()\n", "labels = k_means.labels_\n", "lena_compressed = np.choose(labels, values)\n", "lena_compressed.shape = lena.shape" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "源图片\n", "\n", "![](http://scipy-lectures.github.io/_images/lena1.png)\n", "\n", "K-means quantization\n", "\n", "![](http://scipy-lectures.github.io/_images/lena_compressed.png)\n", "\n", "## 3.5.4 使用主成分分析的降维\n", "\n", "![](http://scipy-lectures.github.io/_images/pca_3d_axis.jpg)\n", "\n", "![](http://scipy-lectures.github.io/_images/pca_3d_aligned.jpg)\n", "\n", "上面观察展开的云点在一个方向非常平坦,因此,一个特征几乎可以准确用另两个特征来计算。PCA找到数据并不平坦的方向,并且可以通过投影到一个子空间中来减少维度。\n", "\n", "---\n", "**警告**: 根据你的scikit-learn版本,PCA将在模块`decomposition`或`pca`中。\n", "\n", "---" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "PCA(copy=True, n_components=2, whiten=False)" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from sklearn import decomposition\n", "pca = decomposition.PCA(n_components=2)\n", "pca.fit(iris.data)" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": true }, "outputs": [], "source": [ "X = pca.transform(iris.data)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "现在我们可视化(转换的)鸢尾花数据集:" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\nG2NMmPt/TnEB4vf2nHEAAAAASUVORK5CYII=\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import pylab as pl\n", "pl.scatter(X[:, 0], X[:, 1], c=iris.target) " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "PCA并不仅仅在高纬度数据集的可视化上有用。它也可以用于帮助加速对高维不太高效的有监督方法的预处理步骤。\n", "\n", "## 3.5.5 把所有的东西放在一起: 面孔识别\n", "\n", "展示使用主成分分析来降维和用执行向量机分类的面孔识别的例子。\n", "\n", "![](http://scipy-lectures.github.io/_images/faces.png)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "\"\"\"\n", "Stripped-down version of the face recognition example by Olivier Grisel\n", "\n", "http://scikit-learn.org/dev/auto_examples/applications/face_recognition.html\n", "\n", "## original shape of images: 50, 37\n", "\"\"\"\n", "import numpy as np\n", "import pylab as pl\n", "from sklearn import cross_val, datasets, decomposition, svm\n", "\n", "# ..\n", "# .. load data ..\n", "lfw_people = datasets.fetch_lfw_people(min_faces_per_person=70, resize=0.4)\n", "perm = np.random.permutation(lfw_people.target.size)\n", "lfw_people.data = lfw_people.data[perm]\n", "lfw_people.target = lfw_people.target[perm]\n", "faces = np.reshape(lfw_people.data, (lfw_people.target.shape[0], -1))\n", "train, test = iter(cross_val.StratifiedKFold(lfw_people.target, k=4)).next()\n", "X_train, X_test = faces[train], faces[test]\n", "y_train, y_test = lfw_people.target[train], lfw_people.target[test]\n", "\n", "# ..\n", "# .. dimension reduction ..\n", "pca = decomposition.RandomizedPCA(n_components=150, whiten=True)\n", "pca.fit(X_train)\n", "X_train_pca = pca.transform(X_train)\n", "X_test_pca = pca.transform(X_test)\n", "\n", "# ..\n", "# .. classification ..\n", "clf = svm.SVC(C=5., gamma=0.001)\n", "clf.fit(X_train_pca, y_train)\n", "\n", "# ..\n", "# .. predict on new images ..\n", "for i in range(10):\n", " print lfw_people.target_names[clf.predict(X_test_pca[i])[0]]\n", " _ = pl.imshow(X_test[i].reshape(50, 37), cmap=pl.cm.gray)\n", " _ = raw_input()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "完整代码: [faces.py](http://scipy-lectures.github.io/_downloads/faces.py)\n", "\n", "## 3.5.6 线性模型: 从回归到简约\n", "\n", "**糖尿病数据集**\n", "糖尿病数据集包含442个病人测量的10个生理学变量 (年龄、性别、体重、血压),以及一个一年后病情发展的标记:" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": true }, "outputs": [], "source": [ "diabetes = datasets.load_diabetes()\n", "diabetes_X_train = diabetes.data[:-20]\n", "diabetes_X_test = diabetes.data[-20:]\n", "diabetes_y_train = diabetes.target[:-20]\n", "diabetes_y_test = diabetes.target[-20:]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "目前的任务是从生理学变量中预测疾病发生。\n", "\n", "### 3.5.6.1 简约模型\n", "\n", "要改善问题的条件 (信息量小的变量、减少高纬度的诅咒、作为一个特征预处理等等), 仅选择信息量大的特征,并且将没有信息量的特征设置为0将非常有趣。这种惩罚手段,称为**Lasso**, 可以将一些系数设置为0。这个方法称为**简约方法**,简约性可以看做是Occam剃刀的一个应用: 相比于复杂的模型更偏好简单的模型。" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "Lasso(alpha=0.3, copy_X=True, fit_intercept=True, max_iter=1000,\n", " normalize=False, positive=False, precompute=False, random_state=None,\n", " selection='cyclic', tol=0.0001, warm_start=False)" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from sklearn import linear_model\n", "regr = linear_model.Lasso(alpha=.3)\n", "regr.fit(diabetes_X_train, diabetes_y_train) " ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([ 0. , -0. , 497.34075682, 199.17441034,\n", " -0. , -0. , -118.89291545, 0. ,\n", " 430.9379595 , 0. ])" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "regr.coef_ # 非常简约的系数" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "0.55108354530029779" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "regr.score(diabetes_X_test, diabetes_y_test) " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "分数与线性回归 (最小二乘) 很相似:" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "LinearRegression(copy_X=True, fit_intercept=True, n_jobs=1, normalize=False)" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "lin = linear_model.LinearRegression()\n", "lin.fit(diabetes_X_train, diabetes_y_train) " ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "0.58507530226905713" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "lin.score(diabetes_X_test, diabetes_y_test) " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**相同问题的不同算法**\n", "不同的算法可以用于解决相同的数学问题。例如,*sklearn*中的Lasso对象用*坐标下降法*来解lasso回归,这种方法在大数据集上有效。但是,*sklearn*也提供了*LassoLARS*对象,使用*LARS*,一种在权重向量估计非常稀疏的问题上非常高效的方法,即有很少观察值的问题。\n", "\n", "## 3.5.7 模型选择: 选择预测器及其参数\n", "\n", "### 3.5.7.1 网格搜索和交叉验证预测器\n", "\n", "#### 3.5.7.1.1 网格搜索\n", "\n", "scikit-learn提供了一个对象,给定数据,计算预测器在一个参数网格的分数,并且选择可以最大化交叉验证分数的参数。这个对象用一个构建中的预测器并且暴露了一个预测器的探索集API:" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "GridSearchCV(cv=None, error_score='raise',\n", " estimator=SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0, degree=3, gamma=0.0,\n", " kernel='rbf', max_iter=-1, probability=False, random_state=None,\n", " shrinking=True, tol=0.001, verbose=False),\n", " fit_params={}, iid=True, loss_func=None, n_jobs=-1,\n", " param_grid={'gamma': array([ 1.00000e-06, 3.59381e-06, 1.29155e-05, 4.64159e-05,\n", " 1.66810e-04, 5.99484e-04, 2.15443e-03, 7.74264e-03,\n", " 2.78256e-02, 1.00000e-01])},\n", " pre_dispatch='2*n_jobs', refit=True, score_func=None, scoring=None,\n", " verbose=0)" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from sklearn import svm, grid_search\n", "gammas = np.logspace(-6, -1, 10)\n", "svc = svm.SVC()\n", "clf = grid_search.GridSearchCV(estimator=svc, param_grid=dict(gamma=gammas), n_jobs=-1)\n", "clf.fit(digits.data[:1000], digits.target[:1000]) " ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "0.93200000000000005" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "clf.best_score_" ] }, { "cell_type": "code", "execution_count": 22, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "0.00059948425031894088" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "clf.best_estimator_.gamma" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "默认,*GridSearchCV*使用三折交叉验证。但是,如果识别传递了一个分类器都不是一个回归器,它将使用一个分层三折。\n", "\n", "#### 3.5.7.1.2 交叉验证预测器\n", "\n", "一个算法一个算法为基础的设置参数来进行交叉验证更有效。这也就是为什么,对于一些预测器,scikit-learn暴露一个“CV”预测器, 这个预测器通过交叉验证自动设置他们的参数:" ] }, { "cell_type": "code", "execution_count": 23, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "LassoCV(alphas=None, copy_X=True, cv=None, eps=0.001, fit_intercept=True,\n", " max_iter=1000, n_alphas=100, n_jobs=1, normalize=False, positive=False,\n", " precompute='auto', random_state=None, selection='cyclic', tol=0.0001,\n", " verbose=False)" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from sklearn import linear_model, datasets\n", "lasso = linear_model.LassoCV()\n", "diabetes = datasets.load_diabetes()\n", "X_diabetes = diabetes.data\n", "y_diabetes = diabetes.target\n", "lasso.fit(X_diabetes, y_diabetes)" ] }, { "cell_type": "code", "execution_count": 26, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "0.012291895087486173" ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 预测器自动选择他的lambda:\n", "lasso.alpha_" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "这些预测器与他们的对等物调用方式类似,只是在名字后面增加了‘CV’。\n", "\n", "---\n", "**练习**\n", "在糖尿病数据集中,找到最优化的正则化参数alpha。\n", "\n", "---" ] } ], "metadata": { "kernelspec": { "display_name": "Python 2", "language": "python", "name": "python2" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 2 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", "version": "2.7.10" } }, "nbformat": 4, "nbformat_minor": 0 }