在上一篇博客我们搭起了环境,这篇博客将以最简介的代码快速上手sklearn。
这节笔记摘自官网Quick-Start的教程:An introduction to machine learning with scikit-learn。比起官网教程,这篇博客首先会概述基础概念,帮助快速理解和上手。话不多说,开始吧。
scikit-learn编程概述
sklearn主要有以下几部分组成:
- 估计器,可以直接理解成分类器,主要包含两个函数:fit(x,y) 和 predict(x),分别是训练和预测算法。起接受输入格式均为numpy数组或类似格式。
- 转换器,用于数据预处理和数据转换,transform(),还有fit_transform()将fit()和transform()结合在一起。
- 流水线,sklearn.pipeline包,入门阶段不做接受
- 预处理,sklearn.prepressing包,预处理主要分为规范化和编码,规范化主要有:最大最小值规范化(MinMaxScaler)、归一化(Normalize,使特征值和为1)和白化(StandartScaler,使特征值均值为0,方差为1)。编码主要有:LabelEncoder(字符串转化为整型)、OneHotEncoder(特征有一个二进制数字来表示)、Binarizer(特征二值化)和MultiLabelBinarizer(多标签二值化)等
- 特征,主要包括特征提取和特征选择
- 降维,主要是PCA
- 组合,通过聚集多个分类器的预测来提高分类准确率
- 模型评估(度量),包含评分方法,性能度量,成对度量和距离计算。
- 交叉验证,sklearn.cross_validation
- 网格搜索,sklearn.grid_search 网格搜索最佳参数
- 多标签分类,sklearn.multiclass
通过上面的介绍,应该可以大致了解到sklearn的模块组成,也大致能了解到sklearn的强大和易用了。
这节入门教程的内容也就很清楚了,这篇博客就是简单介绍估计器的使用,后面我们可以看到仅仅需要六行代码就可以实现SVM的训练和预测。
加载数据集
sklearn包中内置了一些常用的数据集,比如下面,我们只需要导入datasets模块,就可以直接加载数据集。下面的代码中,我们导入了iris(安德森鸢尾花卉数据集)和digits(手写字符数据集)。
$ python
>>> from sklearn import datasets
>>> iris = datasets.load_iris()
>>> digits = datasets.load_digits()
关于安德森鸢尾花卉数据集,我去年caffe回归非图像数据的十堰就是在该数据集上测试的。下面我们需要用到digits,对于sklearn中数据的封装,可以通过 .data 查看用于分类的特征,可以通过 .target 来查看标签
>>> 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 array([0, 1, 2, ..., 8, 9, 8])
当然,目前我们不会用到的原始数据也可以查看。如下,可以查看原始图像,是一个8×8大小,16位深的灰度图像,看起来像是个0,虽然分辨率很低,不过对于数字来说够了。
>>> 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.]])
训练与预测
下面这段代码,建议在python命令行下一行一行输入。
>>> from sklearn import svm >>> clf = svm.SVC(gamma=0.001, C=100.) >>> 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) >>> clf.predict(digits.data[-1:]) array([8])
整个过程写成脚本就是,这样不会像上面那样显示中间结果,如果要显示中间结果,需要在predict的时候打印(print)出结果,否则是不会显示的。下面这段代码就完成了一次SVM训练手写体字符,并进行预测:
from sklearn import datasets from sklearn import svm digits = datasets.load_digits() clf = svm.SVC(gamma=0.001, C=100.) clf.fit(digits.data[:-1], digits.target[:-1]) clf.predict(digits.data[-1:])
- 1-2行,带入sklearn包
- 3行,加载手写体数字数据集
- 4行,这里,我们就创建了一个svm分类器
- 5行,我们就使用前面的fit方法进行训练,我们没有训练最后一个字符,最后一个字符留给我们做预测用
- 6行,我们预测最后一个字符,如果我们打印出来,预测结果是8,于是我们查看digits.target([:-1])发现确实是8,我们还可以通过digits.image[:-1]来查看原始图像
这样我们大致能理解sklearn的运行流程了。这里我们还要提到,输入和输出的不论是整数还是float32,最终都会被转化为float64
模型保存
如果我们训练好了一个模型,我们有什么方法可以保存下来呢?当然是用python自带的pickle就可以了
我们训练并保存一个模型clf,这里pickle.dumps(clf)就是序列化的意思,我们当然可以进一步已文件形式来保存经过序列化的s(这是python基础内容,就不介绍),然后加载(反序列化)模型clf2,然后进行预测。
>>> 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='ovr', 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
官网上高速我们,如果数据量很大的时候,可以使用joblib包来进行序列化以调高效率。下面的代码就直接序列化并保存成文件了。
>>> from sklearn.externals import joblib >>> joblib.dump(clf, 'filename.pkl') >>> clf = joblib.load('filename.pkl')
多标签预测
上面演示了单类别分类,下面这段代码演示了多类别分类。当使用多类别分类算法时,学习和预测任务将根据target的格式自动适应,比如输入可以是类别标签[0,1,2]这样,也可以是类别向量[1,0,0][0,1,0][0,0,1],而输出则是固定的类别向量形式。正如下面的代码:
>>> 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]) >>> 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]]) >> 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, 1, 0], [0, 0, 1, 0, 1]])
好了,简单介绍了sklearn的基本使用方法。
See You Next Chapter!