对机器学习问题的简要介绍,以及如何使用scikit-learn来解决这些问题。介绍基本概念和惯例。
原文链接 : http://scikit-learn.org/stable/tutorial/basic/tutorial.html
译文链接 : http://cwiki.apachecn.org/pages/viewpage.action?pageId=10813673
在本节中,我们介绍 我们在scikit-learn学习中使用的机器学习词汇,并给出一个简单的学习示例。
一般来说,学习问题考虑了一组n 个数据样本,然后尝试预测未知数据的属性。如果每个样本多于单个数字,并且例如多维条目(又称多变量 数据),则称其具有多个属性或特征。
我们可以分开几个大类的学习问题:
训练集和测试集
机器学习是关于学习数据集的一些属性并将其应用于新数据。这就是为什么在机器的普遍做法学习评价的算法是手头上的数据分成两组,一个是我们所说的训练集上,我们了解到,我们称之为数据属性和一个测试集 上,我们测试这些属性。
scikit-learn提供了一些标准数据集,例如 用于分类的 虹膜和数字数据集和波士顿房价回归数据集。
在下文中,我们从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,分类的估计是实现方法的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.dump
&joblib.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') |
---|
在这个例子中,X
是float32
,它被转换为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数组。