使用 scikit-learn 介绍机器学习

小节内容

在这一节中,我们将介绍我们在整个 scikit-learn 中使用的机器学习词汇,并给出一个简单的学习示例。

机器学习:问题设置

通常,学习问题考虑一组 n 个数据样本,然后尝试预测未知数据的属性。
如果每个样本不止一个数字,例如一个多维条目entry(又名多元数据aka multivariate data),则称其具有多个属性attributes或特征features
学习问题分为以下几类:

  • 监督学习,其中数据带有我们想要预测的附加属性。这个问题可以是:
    • 分类classification:样本属于两个或多个类别,我们想从已经标记的数据中学习如何预测未标记数据的类别。分类问题的一个例子是手写数字识别handwritten digit recognition,其目的是将每个输入向量分配给有限数量的离散类别之一。将分类视为一种离散(相对于连续)形式的监督学习,其中一个类别的数量有限,对于提供的 n 个样本中的每一个,尝试用正确的类别或类别标记它们.
    • 回归regression:如果所需的输出由一个或多个连续变量组成,则该任务称为回归。回归问题的一个例子是根据年龄和体重预测鲑鱼的长度。
  • 无监督学习,其中训练数据由一组输入向量 x 组成,没有任何相应的目标值。此类问题的目标可能是在数据中发现一组相似的示例,这称为聚类 clustering,或确定determine输入空间内数据的分布,称为密度估计,或从高维投影数据空间缩小到两个或三个维度以进行可视化

训练集和测试集

机器学习是关于学习数据集的一些属性,然后针对另一个数据集测试这些属性。
机器学习中的一种常见做法是通过将数据集分成两个来评估算法。我们将其中一组称为训练集,我们从中学习一些属性;我们称另一组为测试集,我们在其上测试学习到的属性。

加载示例数据集

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 介绍机器学习_第1张图片
如您所见,此分类问题的完整示例可作为您可以运行和研究的示例:识别手写数字。这是一项具有挑战性的任务:毕竟,图像的分辨率很差。你同意分类器吗?
此分类问题的完整示例可作为您可以运行和研究的示例:识别手写数字。

惯例

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() 返回一个二维数组,每个实例都有多个预测标签。

你可能感兴趣的:(sklearn,python,机器学习)