使用scikit-learn进行机器学习的简介
文章推薦指數: 80 %
在scikit-learn中,分类的估计量是一个实现 fit(X, y) 方法和 predict(T) 方法的Python对象。
一个估计量的例子是实现了支持向量分类 的 sklearn.svm.SVC 类。
一个估计量的 ...
上一页
scikit-learn指南
scikit-learn指南
向上
scikit-learn指南
scikit-learn指南
这个文档适用于scikit-learn版本0.17—其它版本
如果你要使用软件,请考虑引用scikit-learn和JianchengLi.
使用scikit-learn进行机器学习的简介
机器学习:问题设置
加载样例数据集
学习和预测
模型持久化
惯例约定
类型转换
重新拟合和更新参数
使用scikit-learn进行机器学习的简介¶
章节内容
在本节中,我们介绍在scikit-learn中一直用到的机器学习这个词汇,并给出一些简单的学习例子。
机器学习:问题设置¶
通常,一个学习问题考虑一组n个样本的数据,然后尝试预测未知数据的属性。
如果每个样本都不仅仅是一个单独的数字,例如,一个多维实例(也称为多变量数据),则预测它有几个属性或特征。
我们可以把学习问题分为几个大类:
监督学习,其中数据带有我们要预测的附加属性,(点击这里去scikit-learn监督学习的页面)。
这个问题可以是:
分类:样本属于两个或多个类,我们想要从已标记的数据中学习如何预测未标记的数据类别。
分类问题的一个例子是手写体数字识别,其中目标是将每个输入向量指派到一个有限数量的离散类。
另一种方式去理解分类,其实分类问题是一种离散(相对于连续)形式的监督学习,每一个都有一个有限数量的类别,对每个提供的样本,我们要尝试用正确的类别来标注他们。
回归:如果期望的输出由一个或多个连续变量组成,那么这个任务被称为*回归*。
回归问题的一个例子是,鲑鱼长度的预测——一个基于其年龄和体重的函数。
无监督学习,训练数据包含一组没有相应目标值的输入向量x。
这类问题的目标可能是在数据中发现相似的样本组,也被称为聚类;或是在输入空间中确定数据的分布,也被称为密度估计;或是把数据从高维空间投影到两个或三个维度的空间来达到*可视化*的目的(点击这里去scikit-learn无监督学习的页面)。
训练集和测试集
机器学习是学习一个数据集的一些特性,并将它们应用到新的数据。
这就是为什么在机器学习中评估算法时一个普遍做法是把数据分成两组,一组称之为**训练集**,用于学习数据的属性;另一组称之为**测试集**,用于测试这些属性。
加载样例数据集¶
scikit-learn有一些标准数据集,例如用于分类的iris和digits数据集,用于回归的bostonhousepricesdataset数据集。
接下来,我们开始从shell中开启一个Python解释器,然后加载iris和digits数据集。
我们的符号惯例是,$表示shell提示符,>>>表示Python解释器提示符:
$python
>>>fromsklearnimportdatasets
>>>iris=datasets.load_iris()
>>>digits=datasets.load_digits()
一个数据集是一个字典状的对象,拥有所有的数据和一些与数据相关的元数据。
这些数据存储在.data成员变量中,这是一个n_samples,n_features的数组。
在监督学习问题中,一个或多个响应变量被存储在.target成员变量中。
不同数据集的更多细节可以在数据集章节找到。
例如,在digits数据集,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数据集的真实值,即我们尝试学习的每个数字图像对应的数字:
>>>digits.target
array([0,1,2,...,8,9,8])
数据数组的形状
数据始终是一个二维数组,形状是(n_samples,n_features),尽管原始数据可能有不同的形状。
对digits数据集,每个原始样本都是一张形状为(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中,分类的估计量是一个实现fit(X,y)方法和predict(T)方法的Python对象。
一个估计量的例子是实现了支持向量分类的sklearn.svm.SVC类。
一个估计量的构造函数以模型的参数作为参数,但由于时间问题,我们把估计量作为一个黑盒来考虑:
>>>fromsklearnimportsvm
>>>clf=svm.SVC(gamma=0.001,C=100.)
选择模型参数
在这个例子中,我们手动设置了gamma的值。
利用网格搜索和交叉验证等工具,可以自动找到良好的参数值。
我们把我们的估计量实例称为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=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])
相应的图像如下:
正如你所看到的,这是一个具有挑战性的任务:图像分辨率很低。
你同意分类器的结果吗?
这个分类问题的一个完整例子是可以运行和学习的:Recognizinghand-writtendigits。
模型持久化¶
可以用Python内置的持久模型pickle来保存scikit中的模型:
>>>fromsklearnimportsvm
>>>fromsklearnimportdatasets
>>>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)
>>>importpickle
>>>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),因为它对大数据更有效,但只能pickle到磁盘而不是一个字符串:
>>>fromsklearn.externalsimportjoblib
>>>joblib.dump(clf,'filename.pkl')
之后你可以加载之前已经pickle的模型(可能在另一个Python程序中):
>>>clf=joblib.load('filename.pkl')
注解
joblib.dump返回一个文件名列表。
每一个被包含在clf对象中的numpy数组都被序列化为文件系统上的一个单独文件。
用joblib.load重新加载模型时,所有文件都需要在同一个文件夹中。
需要注意的是,pickle有一些安全性和可维护性的问题。
请参阅Modelpersistence以获取有关scikit-learn模型持久化更详细的信息。
惯例约定¶
scikit-learn估计量遵循一定的规则,使它们的行为更具有预测性。
类型转换¶
除非另有说明,输入将被转换为float64:
>>>importnumpyasnp
>>>fromsklearnimportrandom_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,分类目标值则维持不变:
>>>fromsklearnimportdatasets
>>>fromsklearn.svmimportSVC
>>>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()学习的内容:
>>>importnumpyasnp
>>>fromsklearn.svmimportSVC
>>>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在估计量通过SVC()构造构造后变成linear,重新拟合估计量后又变回rbf,并进行第二次预测。
Previous
延伸文章資訊
- 1Day8-Scikit-learn介紹(1) - iT 邦幫忙
... 要來介紹Scikit-learn(SKlearn),SKlearn在python中提供大量常見的機器學習演算法和許多實用的資料集合,像是Iris以及手寫辨識數字的資料(之後的程式舉例會用到)。
- 2Python機器學習-使用Scikit-Learn - 恆逸教育訓練中心
Python機器學習-使用Scikit-Learn. Introduction to Machine Learning–Using Python Scikit-Learn. 時數:21小時; 費...
- 3精通機器學習:使用Scikit-Learn, Keras與TensorFlow 第二版
這本暢銷書新版本使用具體的案例、精簡的理論,以及Python準生產框架,協助你直觀地認識智慧系統的概念與建構工具。 你將學到可快速上手的技術,只要具備程式編寫經驗,就 ...
- 4簡介Scikit-learn 機器學習
對於初學者,最建議的方式是直接下載Anaconda Python (https://www.continuum.io/downloads)。同時支援 Windows / OSX/ Linux 等...
- 5使用scikit-learn进行机器学习的简介
在scikit-learn中,分类的估计量是一个实现 fit(X, y) 方法和 predict(T) 方法的Python对象。 一个估计量的例子是实现了支持向量分类 的 sklearn.svm...