OpenCV-Python教程:60.scikit-learn

机器学习:问题设置

一般的,一个学习问题考虑一个n个样本集合的数据,然后尝试预测未知数据的属性。如果每个样本都超过一个数,比如是多维度条目。被叫做有多个特征或者属性。

我们可以把学习问题分成几个大类:

·监督学习,数据有我们要预测的额外的属性。问题可以是:

·分类:样本属于两个或更多的类别,我们要从已经标记过的数据学习如果预测未分类数据的类别。一个分类的例子是手写数字识别,目标是给每个输入向量分配一个分类的数字。

·回归:如果期望的输出包含一个或多个连续变量,任务就被叫做回归,一个回归的例子是根据鲑鱼的年龄和重量预测它的长度。

·无监督学习,训练数据不包括任何对应目标值得输入向量x 的集合组成。这种问题的目标是发现数据里的相似数据的分组,这被叫做聚类。或者是在输入空间里决定数据的分布,被叫做密度估计。或者从一个高纬度空间投射数据到2维或者3维空以显示

训练集合和测试集合

机器学习是关于学习数据集的一些属性,并应用到其他数据上。这就是为什么机器学习里通常评估算法的方式是把手里的数据拆分成两个集合,一个我们叫做训练集,用来学习数据的属性,另一个叫做测试集,我们用来测试这些属性。

加载一个数据集

scikit-learn自带一些标准数据集,比如iris和digits数据集用来做分类,boston house prices dataset用来做回归。

下面我们启动一个python解释器,并加载iris和digits数据集。

$ python

>>> from sklearn import datasets

>>> iris = datasets.load_iris()

>>> digits = datasets.load_digits()

一个数据集是一个字典类的对象,里面有所有的数据还有关于数据的元数据。这些数据存在.data成员里,是n_samples,k 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.target
array([0, 1, 2, ..., 8, 9, 8])

数据数字的形状

数据都是2D数组,虽然原始数据可能有不同的形状,在这个数字的例子里,每个原始样本都是一个8x8的图像,可以通过下面方式访问:

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

学习和预测

在数字数据集的例子里,任务是预测,给定一个图像,它表示的数字是啥,我们给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.)

选择模型参数

我们手动设置gamma的值,如果用类似于grid search或者cross validation这样的工具可以自动找到好的值。

我们把估计量实例叫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)

现在你可以预测新值了,我们可以问分类器最后一张图像里的数字是什么

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

array([8])

模型持久化

可以用Python内置的持久化模块pickle来保存模型:

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

之后你可以把pickle了的模型加载回来。

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

注意:joblib.dump返回一个文件列表。clf对象里包含的每个单独的numpy数组被串行化到文件系统的单独文件里。当joblib.load加载模型的时候所有文件都需要在同一个目录里。

惯例

scikit-learn 估计量遵循下属原则以使其行为更可预测。

type casting

除非另外指明,否则输入会被转换到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()

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

这里,由于iris.target(整数数组)被fit使用,第一个predict()返回了整数数组,第二个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在通过SVC()构造后被改变为linear,然后变回rbf来重新适应估计量。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,607评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,047评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,496评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,405评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,400评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,479评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,883评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,535评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,743评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,544评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,612评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,309评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,881评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,891评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,136评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,783评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,316评论 2 342

推荐阅读更多精彩内容