页面树结构

2017-11-09 ApacheCN 开源组织,第二期邀请成员活动,一起走的更远 : http://www.apachecn.org/member/209.html


MachineLearning 优酷地址 : http://i.youku.com/apachecn

转至元数据结尾
转至元数据起始

对机器学习问题的简要介绍,以及如何使用scikit-learn来解决这些问题。介绍基本概念和惯例。

章节内容

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

机器学习:问题设置

一般来说,学习问题考虑了一组n 个数据样本,然后尝试预测未知数据的属性。如果每个样本多于单个数字,并且例如多维条目(又称多变量 数据),则称其具有多个属性或特征

我们可以分开几个大类的学习问题:

  • 监督学习,其中数据带有我们想要预测的附加属性(点击此处 进入scikit-learn监督学习页面)。这个问题可以是:

    • 分类:样本属于两个或更多类,我们想从已经标记的数据中学习如何预测未标记数据的类别。分类问题的一个例子是手写数字识别示例,其目的是将每个输入向量分配给有限数目的离散类别之一。考虑分类的另一种方法是作为监督学习的离散(而不是连续的)形式,其中有一个类型有限,并且对于所提供的n个样本中的每一个,一个是尝试用正确的类别或类别来标记它们。
    • 回归:如果期望的输出由一个或多个连续变量组成,则该任务称为回归。回归问题的一个例子是预测鲑鱼的长度是其年龄和体重的函数。

  • 无监督学习,其中训练数据由没有任何相应目标值的一组输入向量x组成。这种问题的目标可能是在数据中发现类似示例的组,称为聚类,或者确定输入空间内的数据分布,称为 密度估计,或从高维数据投影数据空间缩小到两维或三维以进行可视化 (点击此处 转到scikit-learn无监督学习页面)。

训练集和测试集

机器学习是关于学习数据集的一些属性并将其应用于新数据。这就是为什么在机器的普遍做法学习评价的算法是手头上的数据分成两组,一个是我们所说的训练集上,我们了解到,我们称之为数据属性和一个测试集 上,我们测试这些属性。

 

加载示例数据集

scikit-learn提供了一些标准数据集,例如 用于分类的 虹膜数字数据集和波士顿房价回归数据集

在下文中,我们从shell中启动一个Python解释器,然后加载irisdigits数据集。我们的符号约定是 $表示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,分类的估计是实现方法的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, cache_size=200, class_weight=None, coef0=0.0,
  decision_function_shape=None, degree=3, gamma=0.001, kernel='rbf',
  max_iter=-1, probability=False, random_state=None, shrinking=True,
  tol=0.001, verbose=False) 

现在,您可以预测新值,特别是可以向分类器询问digits数据集中最后一个图像的数字是什么,我们还没有用来对分类器进行训练:

>>> clf.predict(digits.data[-1:])
array([8]) 

相应的图像如下:

正如你所看到的,这是一项具有挑战性的任务:图像分辨率差。你同意分类器吗?

这个分类问题的一个完整例子可以作为一个例子,您可以运行和学习: 识别手写数字

 

模型持久化

可以通过使用Python的内置持久化模型(即pickle)将模型保存在scikit中:

>>> from sklearn import svm
>>> from sklearn import datasets
>>> clf = svm.SVC()
>>> iris = datasets.load_iris()
>>> X, y = iris.data, iris.target
>>> clf.fit(X, y)  
SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0,
  decision_function_shape=None, degree=3, gamma='auto', kernel='rbf',
  max_iter=-1, probability=False, random_state=None, shrinking=True,
  tol=0.001, verbose=False)

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

在scikit的具体情况下,使用joblib替换pickle(joblib.dumpjoblib.load)可能会更有意思,这对大数据更有效,但只能持久化到磁盘而不是一串:

>>> from sklearn.externals import joblib
>>> joblib.dump(clf, 'filename.pkl')  

之后,您可以加载持久化模型(可能在另一个Python进程中):

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

注意:joblib.dump并且joblib.load函数也接受类似文件的对象而不是文件名。有关Joblib的数据持久性的更多信息,请点击此处

请注意,持久化有一些安全性和可维护性问题。有关使用scikit-learn的模型持久的更多详细信息,请参阅模型持久性部分。

 

约定

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

在这个例子中,Xfloat32,它被转换为float64通过 fit_transform(X)

回归目标被归结为float64,维护分类目标:

>>> from sklearn import datasets
>>> from sklearn.svm import SVC
>>> iris = datasets.load_iris()
>>> clf = SVC()
>>> clf.fit(iris.data, iris.target)  
SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0,
  decision_function_shape=None, degree=3, gamma='auto', kernel='rbf',
  max_iter=-1, probability=False, random_state=None, shrinking=True,
  tol=0.001, verbose=False)

>>> list(clf.predict(iris.data[:3]))
[0, 0, 0]

>>> clf.fit(iris.data, iris.target_names[iris.target])  
SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0,
  decision_function_shape=None, degree=3, gamma='auto', kernel='rbf',
  max_iter=-1, probability=False, random_state=None, shrinking=True,
  tol=0.001, verbose=False)

>>> list(clf.predict(iris.data[:3]))  
['setosa', 'setosa', 'setosa'] 

这里,第一个predict()返回一个整数数组,因为iris.target 使用了一个整数数组fit。第二个predict()返回一个字符串数组,因为iris.target_names是用于拟合。

修改和更新参数

估计器的超参数可以在通过该sklearn.pipeline.Pipeline.set_params方法构建之后进行更新。fit() 多次呼叫将覆盖任何以前的内容fit()

>>> import numpy as np
>>> from sklearn.svm import SVC

>>> rng = np.random.RandomState(0)
>>> X = rng.rand(100, 10)
>>> y = rng.binomial(1, 0.5, 100)
>>> X_test = rng.rand(5, 10)

>>> clf = SVC()
>>> clf.set_params(kernel='linear').fit(X, y)  
SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0,
  decision_function_shape=None, degree=3, gamma='auto', kernel='linear',
  max_iter=-1, probability=False, random_state=None, shrinking=True,
  tol=0.001, verbose=False)
>>> clf.predict(X_test)
array([1, 0, 1, 1, 0])

>>> clf.set_params(kernel='rbf').fit(X, y)  
SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0,
  decision_function_shape=None, degree=3, gamma='auto', kernel='rbf',
  max_iter=-1, probability=False, random_state=None, shrinking=True,
  tol=0.001, verbose=False)
>>> clf.predict(X_test)
array([0, 0, 0, 1, 0]) 

在这里,默认内核rbf首先被改变到linear估计器被构造之后SVC(),并且改回到rbf重新设计估计器并进行第二预测。

多类与多标签拟合

使用时,所执行的学习和预测任务取决于适合的目标数据的格式:multiclass classifiers

 

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

>>> classif = OneVsRestClassifier(estimator=SVC(random_state=0))
>>> classif.fit(X, y).predict(X)
array([0, 0, 1, 1, 2]) 

在上述情况下,分类器适合于1d类数组的多类标签,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]]) 

这里,分类器是fit() 上的2D二进制标记表示y,使用LabelBinarizer。在这种情况下,predict()返回一个表示相应多重标签预测的2d数组。

请注意,第四个和第五个实例返回所有零,表示它们不匹配三个标签之一fit。使用multilabel输出,类似地可以为一个实例分配多个标签:

>> from sklearn.preprocessing import MultiLabelBinarizer
>> y = [[0, 1], [0, 2], [1, 3], [0, 2, 3], [2, 4]]
>> y = preprocessing.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, 1, 0],
       [0, 0, 1, 0, 1]]) 

在这种情况下,分类器适合每个分配多个标签的实例。所述MultiLabelBinarizer用于multilabels的2D阵列以二进制化fit时。因此, predict()返回具有每个实例的多个预测标签的2d数组。

 

  • 无标签