简介
Anaconda内置scikit-learn,安装Anaconda即可
- 简单有效的数据挖掘和数据分析工具
- 每个人都可以访问,并且在不同的上下文中可重用
- 构建在NumPy、SciPy和matplotlib之上
- 开源
一般来说,一个学习问题考虑一组n个数据样本,然后试图预测未知数据的性质。如果每个样本不止一个数字,例如,一个多维条目(又名多元数据),那么它就有多个属性或特性。
学习问题主要分为两类:监督学习和无监督学习
监督学习:数据带有我们想要预测的额外属性。主要分为两类:
分类:样本属于两个或两个以上的类,我们想从已经标记的数据中学习如何预测未标记数据的类。分类问题的一个例子是手写数字识别,其目的是将每个输入向量分配给有限数量的离散类别中的一个。另一种考虑分类的方式是离散(而不是连续)形式的监督学习,其中类别的数量是有限的,对于所提供的n个样本,一种是尝试用正确的类别或类来标记它们。
回归:如果期望的输出由一个或多个连续变量组成,则该任务称为回归。回归问题的一个例子是预测鲑鱼的长度是它的年龄和体重的函数。
无监督学习:其中训练数据由一组输入向量x组成,没有任何对应的目标值。目标在这些问题可能会发现类似的例子在数据组,称为聚类,确定数据的分布在输入空间,称为密度估计,或项目的数据从高维空间到二维或三维可视化的目的。
加载数据集
scikit-learn提供了一些标准数据集,例如用于分类的iris和numbers数据集以及用于回归的boston房价数据集。
接下来,我们从shell启动Python解释器,然后加载iris和numbers数据集。我们的标注约定是$表示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.data给出了数字数据集的ground truth,即我们要学习的每个数字图像对应的数字:
>>> digits.target
array([0, 1, 2, ..., 8, 9, 8])
学习和预测
对于数字数据集,任务是预测给定的图像,它表示的是哪一位数字。我们得到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.)
先将分类器估计实例clf拟合到模型中;也就是说,它必须向模型学习。这是通过将训练集传递给fit方法来完成的。对于训练集,我们将使用来自数据集的所有图像,除了最后一个图像,我们将保留它来进行预测。我们使用Python语法[:-1]选择训练集,它将生成一个新数组,其中包含来自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='ovr', degree=3, gamma=0.001, kernel='rbf',
max_iter=-1, probability=False, random_state=None, shrinking=True,
tol=0.001, verbose=False)
在可以预测新的值了。在本例中,您将使用data. data中的最后一张图像进行预测。通过预测,您将从训练集中确定最匹配最后一张图像的图像。
>>> clf.predict(digits.data[-1:])
array([8])
应的图像为:
正如您所看到的,这是一个具有挑战性的任务:毕竟,图像的分辨率很低。你同意分类器吗?
这个分类问题的完整示例是一个您可以运行和研究的示例:手写数字识别。
模型的持久性
可以使用Python内置的持久化模型pickle将模型保存在scikit-learn中:
>>> from sklearn import svm
>>> from sklearn import datasets
>>> clf = svm.SVC(gamma='scale')
>>> 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='ovr', degree=3, gamma='scale', 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-learn的特定情况下,使用joblib替代pickle (joblib)可能更有趣。(dump & job .load),它对大数据更有效,但只能pickle到磁盘,而不能pickle到字符串:
>>> from joblib import dump, load
>>> dump(clf, 'filename.joblib')
稍后,您可以使用以下命令重新加载pickle的模型(可能在另一个Python进程中):
>>> clf = load('filename.joblib')
请注意,pickle存在一些安全性和可维护性问题。有关使用scikit-learn实现的模型持久性的详细信息,请参阅模型持久性一节。
约定
scikit-learn评估人员遵循一定的规则使他们的行为更具预测性。在公共术语和API元素的术语表中对这些进行了更详细的描述。
类型转换
除非另有说明,否则输入将转换为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(gamma='scale')
>>> clf.fit(iris.data, iris.target)
SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0,
decision_function_shape='ovr', degree=3, gamma='scale', 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='ovr', degree=3, gamma='scale', 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。fit中使用了target(一个整数数组)。第二个predict()返回一个字符串数组,因为iris。target_names用于拟合。
重新拟合和更新参数
通过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='ovr', degree=3, gamma='auto_deprecated',
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', gamma='scale').fit(X, y)
SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0,
decision_function_shape='ovr', degree=3, gamma='scale', kernel='rbf',
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])
这里,默认的内核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]
>>> classif = OneVsRestClassifier(estimator=SVC(gamma='scale',
... random_state=0))
>>> classif.fit(X, y).predict(X)
array([0, 0, 1, 1, 2])
上面的例子中,分类器适合于多类标签的一维数组,因此predict()方法提供了相应的多类预测。也可以适用于二进制标签指示符的2d数组:
>>> 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,分类器是fit()对y的二维二进制标签表示。在本例中,predict()返回一个2d数组,表示相应的多标签预测。
注意,第四个和第五个实例返回了所有的0,这表明它们与三个标签都不匹配。对于多标签输出,一个实例也可以被分配多个标签:
>>> 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用于对适合的多标签的2d数组进行二进制化。因此,predict()返回一个2d数组,每个实例具有多个预测标签。