亚图跨际
国际版https://viadean.notion.site

scikit-learn机器学习简介

 二维码 24

目录

机器学习:问题设置

加载示例数据集

学习和预测

模型持久性

约定

拓展知识链接

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

机器学习:问题设置

通常,学习问题会考虑一组n个数据样本,然后尝试预测未知数据的属性。 如果每个样本都大于一个数字,例如是多维条目(也称为多元数据),则称其具有多个属性或特征。

学习问题可分为以下几类:

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

训练集和测试集

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

加载示例数据集

scikit-learn附带一些标准数据集,例如用于分类的 iris和digits 数据集和用于回归的波士顿房价数据集。

接下来,我们从Shell启动Python解释器,然后加载iris和digits数据集。我们的符号约定是$表示shell提示符,而>>>表示Python解释器提示符:

$ python
>>> from sklearn import datasets
>>> iris = datasets.load_iris()
>>> digits = datasets.load_digits()

数据集是一个类似于字典的对象,其中包含所有数据和有关该数据的一些元数据。 此数据存储在.data成员中,该成员是一个n_samples,n_features数组。 在监督问题的情况下,一个或多个响应变量存储在.target成员中。

例如,对于数字数据集,使用digits.data可以访问可用于对数字样本进行分类的功能:

>>> 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])

数据阵列的形状

尽管原始数据可能具有不同的形状,但数据始终是2D形状的数组(n_samples,n_features)。对于数字,每个原始样本都是形状为(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中的数据。

学习和预测

对于数字数据集,任务是在给定图像的情况下预测其代表的数字。 我们为10种可能的类别(从零到九的数字)中的每一个提供了样本,我们在其上拟合了一个估计量,能够预测未见样本所属的类别。

在scikit-learn中,用于分类的估计量是一个实现fit(X,y)和predict(T)方法的Python对象。

估算器的一个示例是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])

相应的图像是:

如您所见,这是一项艰巨的任务:毕竟,图像的分辨率很差。您是否同意分类器?

模型持久性

通过使用Python的内置持久性模型pickle,可以在scikit-learn中保存模型:

>>> from sklearn import svm
>>> from sklearn import datasets
>>> clf = svm.SVC()
>>> X, y = datasets.load_iris(return_X_y=True)
>>> clf.fit(X, y)
SVC()

>>> import pickle
>>> s = pickle.dumps(clf)
>>> clf2 = pickle.loads(s)
>>> clf2.predict(X[0:1])
array([
0])
>>> y[0]
0

在scikit-learn的特定情况下,用joblib代替pickle(joblib.dump和joblib.load)可能会更有趣,这在大数据上效率更高,但它只能在磁盘上而不是在字符串上pickle:

>>> from joblib import dump, load
>>> dump(clf, 'filename.joblib')

稍后,您可以使用以下方法重新加载pickle的模型(可能在另一个Python进程中):

>>> clf = load('filename.joblib')

注意:joblib.dump和joblib.load函数也接受类似文件的对象而不是文件名。

请注意,pickle存在一些安全性和可维护性问题。

约定

scikit-learn估计量遵循某些规则,以使其行为更具预测性。

类型转换

除非另有说明,否则输入将强制转换为float64:

>>> import numpy as np
>>> from sklearn import random_projection

>>> rng = np.random.RandomState(0)
>>> X = rng.rand(10, 2000)
>>> X = np.array(X, dtype='float32')
>>> X.dtype
dtype(
'float32')

>>> transformer = random_projection.GaussianRandomProjection()
>>> 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()返回一个整数数组,因为fit中使用了iris.target(一个整数数组)。第二个predict()返回一个字符串数组,因为iris.target_names使用在fit中。

改写和更新参数

通过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])

此处,在构造估算器之后,默认内核rbf首先通过SVC.set_params()更改为线性,然后又更改回rbf以重新拟合估算器并进行第二次预测。

多类与多标签拟合

使用多类分类器时,执行的学习和预测任务取决于适合的目标数据的格式:

>>> from sklearn.svm import SVC
>>> 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]>>> 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]])
>>> classif = OneVsRestClassifier(estimator=SVC(random_state=
0))
>>> classif.fit(X, y).predict(X)
array([
0, 0, 1, 1, 2])

在上述情况下,分类器是一维多类标签数组上的fit,因此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的2d二进制标签表示形式。在这种情况下,predict()返回表示相应多标签预测的2d数组。

请注意,第四和第五个实例返回了全零,表明它们与三个标签都不匹配。使用多标签输出,也可以为一个实例分配多个标签:

>>> 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]])

在这种情况下,当实例分别分配了多个标签时,分类器为fit。 MultiLabelBinarizer用于将多标签的二维数组二值化为fit。 结果,predict()返回一个二维数组,每个实例带有多个预测标签。

拓展知识链接

文章分类: 编程碎语scikit-learn