Note

本文翻译自 Sklearn 官网教程 [版本0.18.1] 翻译于2017-05-20

监督学习:根据多维观测值预测输出值

监督学习解决的问题

监督学习的用途在于学习两个数据集合之间的关系。观测值 X 和我们试图预测的值 y 。 其中,y 被我们称之为 目标 或者 标签 。通常,y 为长度为样本数目的一维数组。

所有 sklearn 中的监督学习估计量 estimators 提供一个 fit(X, y) 函数用于训练 估计量估计量 同时也提供 predict(X) 函数, 根据提供的未知的观测值 X 来预测出标签 y

分类(classification)与回归(regression)

分类与回归的区别在于:目标值是连续的还是离散的。目标值离散时,任务为分类任务。目标值连续时,任务为回归任务。

k邻近问题与维度的关系

鸢尾花(iris)分类任务

鸢尾花数据集,是一个经典的数据集。它包含了三种鸢尾花,每个鸢尾花有三个特性,花瓣、花萼长度、花萼宽度。

>>> import numpy as np
>>> from sklearn import datasets
>>> iris = datasets.load_iris()
>>> iris_X = iris.data
>>> iris_y = iris.target
>>> np.unique(iris_y)
array([0, 1, 2])

k 邻近分类器

k邻近分类器 可能是最简单的分类器:给出一个被估计量 X_test ,在训练估计量的数据集中找出距离 X_test 最近的k个点, 这k个点就代表了估计量对 X_test 的预估结果。

Note

通常我们会将数据分为两部分,一部分为训练数据,另一部分为测试数据。这是因为不应该用训练估计量 estimator 的数据去检验它的正确性。

KNN 分类示例1:

../_images/knn_classification_example.png

KNN 分类示例2:

>>> np.random.seed(0)
>>> indices = np.random.permutation(len(iris_X))
>>> iris_X_train = iris_X[indices[:-10]]
>>> iris_y_train = iris_y[indices[:-10]]
>>> iris_X_test  = iris_X[indices[-10:]]
>>> iris_y_test  = iris_y[indices[-10:]]
>>> # Create and fit a nearest-neighbor classifier
>>> from sklearn.neighbors import KNeighborsClassifier
>>> knn = KNeighborsClassifier()
>>> knn.fit(iris_X_train, iris_y_train)
KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski',
        metric_params=None, n_jobs=1, n_neighbors=5, p=2,
        weights='uniform')
>>> knn.predict(iris_X_test)
array([1, 2, 1, 0, 0, 0, 2, 1, 2, 0])
>>> iris_y_test
array([1, 1, 1, 0, 0, 0, 2, 1, 2, 0])

维度的诅咒

在这里我们可以注意到一个问题。让我们预测的结果是一维时,如果我们需要10个点来预测达到相应的精度,则对于相同的精度,如果我们预测的结果是二维的, 我们需要100个点来预测。

也就是说,随着维度的增长,我们预测的点的精度的增加是呈指数增长的。这一点在其他分类器中大多也成立,这被我们称之为维度的诅咒。

线性模型:从回归到离散

糖尿病数据集

糖尿病数据集包含了422名志愿者的10维的被估计量(年龄,性别,体重,血压等),预测量为一年后这些人的糖尿病等级。:

>>> diabetes = datasets.load_diabetes()
>>> diabetes_X_train = diabetes.data[:-20]
>>> diabetes_X_test  = diabetes.data[-20:]
>>> diabetes_y_train = diabetes.target[:-20]
>>> diabetes_y_test  = diabetes.target[-20:]

线性回归

最简单的线性回归,用于拟合一条直线,并且使得它对所有的训练值的方差最小。

线性模型:y = Xß + €

  • X: 训练数据
  • y: 目标值
  • ß: 系数(也称权值)
  • €: 观测噪声
>>> from sklearn import linear_model
>>> regr = linear_model.LinearRegression()
>>> regr.fit(diabetes_X_train, diabetes_y_train)
LinearRegression(copy_X=True, fit_intercept=True, n_jobs=1, normalize=False)
>>> print(regr.coef_)
[   0.30349955 -237.63931533  510.53060544  327.73698041 -814.13170937
  492.81458798  102.84845219  184.60648906  743.51961675   76.09517222]

>>> regr.score(diabetes_X_test, diabetes_y_test)
0.5850753022690...

regr.score 用于输出数据的线性得分, 1 代表训练数据是完全线性的,0 代表训练数据是完全非线性的。

收缩

../_images/shrinkage.png

如果只有很少的观测量,噪声将会引入巨大的误差:

>>> X = np.c_[ .5, 1].T
>>> y = [.5, 1]
>>> test = np.c_[ 0, 2].T
>>> regr = linear_model.LinearRegression()

>>> import matplotlib.pyplot as plt
>>> plt.figure()

>>> np.random.seed(0)
>>> for _ in range(6):
...    this_X = .1*np.random.normal(size=(2, 1)) + X
...    regr.fit(this_X, y)
...    plt.plot(test, regr.predict(test))
...    plt.scatter(this_X, y, s=3)
../_images/shrinkage_ridge.png

高维统计学习的一个解决方案是将回归系数缩小到零:任意两个随机选择的一组观察值可能是不相关的。 这就是所谓的岭回归:

>>> regr = linear_model.Ridge(alpha=.1)

>>> plt.figure()

>>> np.random.seed(0)
>>> for _ in range(6):
...    this_X = .1*np.random.normal(size=(2, 1)) + X
...    regr.fit(this_X, y)
...    plt.plot(test, regr.predict(test))
...    plt.scatter(this_X, y, s=3)

概念解析

估计量 estimators

根据 维基百科的定义 , 估计量(estimator)、被估量(estimand)和估计值(estimate)是不同的。

估计量是用来估计未知总体的参数,它有时也被称为估计子;一次估计是指把这个函数应用在一组已知的数据集上, 求函数的结果。对于给定的参数,可以有许多不同的估计量。我们通过一些选择标准从它们中选出较好的估计量, 但是有时候很难说选择这一个估计量比另外一个好。

K-近邻算法 KNN

k-近邻算法( Wiki 词条 ),是一种用于分类和回归的非参数统计方法。 在这两种情况下,输入包含特征空间中的k个最接近的训练样本。