小节内容
在这一节中,我们将介绍我们在整个 scikit-learn 中使用的机器学习词汇,并给出一个简单的学习示例。
通常,学习问题考虑一组 n 个数据样本,然后尝试预测未知数据的属性。
如果每个样本不止一个数字,例如一个多维条目entry(又名多元数据aka multivariate data),则称其具有多个属性attributes或特征features。
学习问题分为以下几类:
训练集和测试集
机器学习是关于学习数据集的一些属性,然后针对另一个数据集测试这些属性。
机器学习中的一种常见做法是通过将数据集分成两个来评估算法。我们将其中一组称为训练集,我们从中学习一些属性;我们称另一组为测试集,我们在其上测试学习到的属性。
scikit-learn 带有一些标准数据集,例如用于分类的 iris 和digits以及用于回归的糖尿病数据集。
在下面,我们从我们的 shell 启动一个 Python 解释器,然后加载 iris 和数字数据集。
我们的符号约定是 $ 表示 shell 提示,而 >>> 表示 Python 解释器提示:
$ python
# sklearn库中导入数据集包
>>> from sklearn import datasets
# datasets中导入iris数据集
>>>> iris = datasets.load_iris()
># 导入digits数据集
>>>>digits = datasets.load_digits()
数据集是一个类似字典的对象,其中包含所有数据和有关数据的一些元数据。该数据存储在 .data 成员中,它是一个 n_samples, n_features 数组。在监督问题的情况下,一个或多个响应变量存储在 .target 成员中。有关不同数据集的更多详细信息,请参见专用部分。
例如,在数字数据集的情况下,digits.data 可以访问可用于对数字样本进行分类的特征:
>>>digits.data
array([[ 0., 0., 5., …, 0., 0., 0.],
[ 0., 0., 0., …, 10., 0., 0.],
[ 0., 0., 0., …, 16., 9., 0.],
…,
[ 0., 0., 1., …, 6., 0., 0.],
[ 0., 0., 2., …, 12., 0., 0.],
[ 0., 0., 10., …, 12., 1., 0.]])
>>> print(digits.data)
[[ 0. 0. 5. … 0. 0. 0.]
[ 0. 0. 0. … 10. 0. 0.]
[ 0. 0. 0. … 16. 9. 0.]
…
[ 0. 0. 1. … 6. 0. 0.]
[ 0. 0. 2. … 12. 0. 0.]
[ 0. 0. 10. … 12. 1. 0.]]
而digits.target 给出了数字数据集的基本事实,即与我们试图学习的每个数字图像对应的数字:
>>> digits.target
array([0, 1, 2, …, 8, 9, 8])
数据数组的形状
数据始终是一个二维数组,形状为 (n_samples, n_features),尽管原始数据可能具有不同的形状。
在数字的情况下,每个原始样本都是形状为 (8, 8) 的图像,(像素点为8*8)可以使用以下方法访问:
>>> digits.images[0]
array([[ 0., 0., 5., 13., 9., 1., 0., 0.],
[ 0., 0., 13., 15., 10., 15., 5., 0.],
[ 0., 3., 15., 2., 0., 11., 8., 0.],
[ 0., 4., 12., 0., 0., 8., 8., 0.],
[ 0., 5., 8., 0., 0., 9., 8., 0.],
[ 0., 4., 11., 0., 1., 12., 7., 0.],
[ 0., 2., 14., 5., 10., 12., 0., 0.],
[ 0., 0., 6., 13., 10., 0., 0., 0.]])
此数据集上的简单示例说明了如何从原始问题开始,在 scikit-learn 中塑造用于消费的数据。
从外部数据集加载
要从外部数据集加载,请参阅加载外部数据集。
在digits(手写笔记识别)数据集的情况下,任务是在给定图像的情况下预测它代表哪个数字。
我们获得了 10 个可能的类别(数字 0 到 9)中的每一个的样本,我们在这些样本上拟合了一个估计器,以便能够预测未见过的样本所属的类别。
在 scikit-learn 中,分类估计器是一个 Python 对象,它实现了 fit(X, y) 和 predict(T) 方法。
估计器的一个例子是 sklearn.svm.SVC 类,它实现了支持向量分类。估计器的构造函数将模型的参数作为参数。
现在,我们将估计器视为一个黑匣子:
# 导入支持向量机
>>> from sklearn import svm
>>> clf = svm.SVC(gamma=0.001, C=100.)
选择模型的参数 在这个例子中,我们手动设置了 gamma 的值。
为了找到这些参数的好值,我们可以使用网格搜索和交叉验证等工具。
clf(用于分类器)估计器实例首先拟合模型;也就是说,它必须从模型中学习。这是通过将我们的训练集传递给 fit 方法来完成的。对于训练集,我们将使用数据集中的所有图像,除了最后一张图像,我们将保留用于预测。我们使用 [:-1] Python 语法选择训练集,这会生成一个新数组,其中包含除digits.data 中的最后一项之外的所有项:
>>> clf.fit(digits.data[:-1], digits.target[:-1])
SVC(C=100.0, gamma=0.001)
现在您可以预测新值。在这种情况下,您将使用digits.data 中的最后一张图像进行预测。通过预测,您将从训练集中确定与最后一张图像最匹配的图像。
clf.predict(digits.data[-1:])
array([8])
对应的图片是:
如您所见,此分类问题的完整示例可作为您可以运行和研究的示例:识别手写数字。这是一项具有挑战性的任务:毕竟,图像的分辨率很差。你同意分类器吗?
此分类问题的完整示例可作为您可以运行和研究的示例:识别手写数字。
scikit-learn 估计器遵循某些规则,使他们的行为更具预测性。这些在通用术语和 API 元素词汇表中有更详细的描述。
除非另有说明,否则输入将被强制转换为 float64
>>> import numpy as np
>>> from sklearn import random_projection
>>> rng = np.random.RandomState(0)
# 生成10*2000的矩阵,类型为float64
>>> X = rng.rand(10, 2000)
# 改变数组的类型
>>> X = np.array(X, dtype='float32')
>>> X.dtype
dtype(‘float32’)
# 高斯随机投影
>>> transformer = random_projection.GaussianRandomProjection()
# 拟合X矩阵
>>> X_new = transformer.fit_transform(X)
>>> X_new.dtype
dtype(‘float64’)
在这个例子中,X 是 float32,它被 fit_transform(X) 转换为 float64。
回归目标被转换为 float64 并保持分类目标:
>>> from sklearn import datasets
# 导入支持向量机
>>> from sklearn.svm import SVC
# 导入鸢尾花数据集
>>> iris = datasets.load_iris()
>>> clf = SVC()
# 监督学习:把数据与目标同时用来拟合
>>> clf.fit(iris.data, iris.target)
SVC()
# 预测最后三个样本的目标值
# 此处存在数据泄露,类型为训练-测试污染
>>> list(clf.predict(iris.data[:3]))
[0, 0, 0]
# 将目标值换成花种类的名字而非数字
>>> clf.fit(iris.data, iris.target_names[iris.target])
SVC()
>>> list(clf.predict(iris.data[:3]))
[‘setosa’, ‘setosa’, ‘setosa’]
这里,第一个 predict() 返回一个整数数组,因为 iris.target(一个整数数组)用于 fit。第二个 predict() 返回一个字符串数组,因为 iris.target_names 用于拟合。
估计器的超参数可以在通过 set_params() 方法构造后更新。多次调用 fit() 将覆盖之前任何 fit() 学到的知识:
>>> import numpy as np
>>> from sklearn.datasets import load_iris
>>> from sklearn.svm import SVC
>>> X, y = load_iris(return_X_y=True)
>>> clf = SVC()
# 使用线性核函数
>>> clf.set_params(kernel='linear').fit(X, y)
SVC(kernel=‘linear’)
# 数据泄露
>>> clf.predict(X[:5])
array([0, 0, 0, 0, 0])
# 换高斯核函数
>>> clf.set_params(kernel='rbf').fit(X, y)
SVC()
>>> clf.predict(X[:5])
array([0, 0, 0, 0, 0])
使用多类分类器时,执行的学习和预测任务取决于适合的目标数据格式:
>>> from sklearn.svm import SVC
# 一对 (OvR) 多类策略。
>>> from sklearn.multiclass import OneVsRestClassifier
# 以一对多的方式对标签进行二值化
>>> from sklearn.preprocessing import LabelBinarizer
>>> X = [[1, 2], [2, 4], [4, 5], [3, 2], [3, 1]]
>>> y = [0, 0, 1, 1, 2]
>>> classif = OneVsRestClassifier(estimator=SVC(random_state=0))
>>> classif.fit(X, y).predict(X)
array([0, 0, 1, 1, 2])
在上述情况下,分类器适合多类标签的一维数组,因此 predict() 方法提供相应的多类预测。也可以适应二进制标签指示符的二维数组:
>>> y = LabelBinarizer().fit_transform(y)
>>> classif.fit(X, y).predict(X)
array([[1, 0, 0],
[1, 0, 0],
[0, 1, 0],
[0, 0, 0],
[0, 0, 0]])
这里,分类器使用 LabelBinarizer 在 y 的二维二进制标签表示上进行 fit()。在这种情况下, predict() 返回一个表示相应多标签预测的二维数组。
请注意,第四个和第五个实例返回全零,表明它们不匹配适合的三个标签。对于多标签输出,同样可以为一个实例分配多个标签:
>>> from sklearn.preprocessing import MultiLabelBinarizer
>>> y = [[0, 1], [0, 2], [1, 3], [0, 2, 3], [2, 4]]
>>> y = MultiLabelBinarizer().fit_transform(y)
>>> classif.fit(X, y).predict(X)
array([[1, 1, 0, 0, 0],
[1, 0, 1, 0, 0],
[0, 1, 0, 1, 0],
[1, 0, 1, 0, 0],
[1, 0, 1, 0, 0]])
在这种情况下,分类器适合每个分配了多个标签的实例。 MultiLabelBinarizer 用于二值化多标签的二维数组以适应。因此, predict() 返回一个二维数组,每个实例都有多个预测标签。