【译】scikit-learn入门简介

scikit-learn的官方简介文档进行了简单的翻译,供初选者参考。

机器学习

通常说,一个机器学习问题是已知一组数据样本,试图预测出该数据的一些未知的性质。机器学习问题可以大体分为两类:

  • 有监督学习:分类、回归

  • 无监督学习:聚类、密度估计、降维等

加载数据

在scikit-learn中有一些标准数据集,如分类问题的iris和数字识别,回归问题的波士顿房价问题。

from sklearn import datasets
iris = datasets.load_iris()
digits = datasets.load_digits()

Dataset是一个dictionary-like 的对象,包括所有的数据和关于该数据的一些信息。数据是 .data属性,是一个(n_samples, n_features)数组。在有监督学习中,目标变量则是.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.]]
print(digits.target)
[0 1 2 ..., 8 9 8]
print(digits.data.shape)
print(digits.target.shape)
(1797, 64)
(1797,)

虽然原始数据可能有不同的数据结构,但.data总是一个 2D 数组 。在这个例子中,原始数据就是一个(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.]])

.data的每一行由对应图像矩阵的元素构成。

digits.data[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中,分类器是一个Python对象,具有fit(X, y)和predict(T)等方法。这里,我们使用支持向量机分类方法。

from sklearn import svm
clf = svm.SVC(gamma = 0.01, C = 100.)

为模型设定参数

gamma的值手动设为0.01, 但如果利用网格搜索和交叉验证集的方法,可能模型会有更好的性能。

将分类器命名为clf, 也就是classifier。通过向模型输入训练数据集,对模型进行学习(拟合)。

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.01, kernel='rbf',
  max_iter=-1, probability=False, random_state=None, shrinking=True,
  tol=0.001, verbose=False)

Note: [:-1] 代表选出数组的除最后一项的所有数据

这样,就可以利用训练好的分类器,预测最后一个数字(不包含在输入模型的训练数据中)。

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

Note: [-1:]则是选出数组的最后一个元素。

可以检查下最后一个数字是不是 8。

digits.target[-1:]
array([8])

模型保存

可以用Python的内嵌模块 pickle对scikit-learn的模型进行保存。

import pickle
s = pickle.dumps(clf)

当需用重新调用该训练好的模型时,将其从pickle中加载出来。

clf2 = pickle.loads(s)
clf2.predict(digits.data[-1:])
array([8])

在一些数据量大的情况时用joblib代替 pickle会更高效,joblib是将模型存入硬盘。

from sklearn.externals import joblib
joblib.dump(clf, 'filename.pkl')
['filename.pkl']
clf3 = joblib.load('filename.pkl')
clf3.predict(digits.data[-1:])
array([8])

一些约定

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

回归的目标变量将被转为float64,而分类的目标变量类型会沿用。

from sklearn import datasets
from sklearn.svm import SVC
iris = datasets.load_iris()
clf = SVC()
clf.fit(iris.data, iris.target)  
list(clf.predict(iris.data[:3]))
[0, 0, 0]
clf.fit(iris.data, iris.target_names[iris.target])  
list(clf.predict(iris.data[:3]))
['setosa', 'setosa', 'setosa']

这里,第一个predict()返回了一个整型数组,因为iris.target是整型数组;第二个predict()返回了字符串数组,因为iris.target_names是字符串数组。

重新拟合和参数更新

分类器的Hyper-parameters可以被更新,重新调用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) 
clf.predict(X_test)
array([1, 0, 1, 1, 0])
clf.set_params(kernel='rbf').fit(X, y)  
clf.predict(X_test)
array([0, 0, 0, 1, 0])

这里,默认的 kernel 是rbf 首先被改为 linear,在拟合之后, 又被改回了 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])

在上面的例子中,分类器是在多类的一维数组上做的拟合,其预测结果也是相应的多类一维数组。同样可以将两维数组转为标签,进行分类。

y = LabelBinarizer().fit_transform(y)
print(y)
[[1 0 0]
 [1 0 0]
 [0 1 0]
 [0 1 0]
 [0 0 1]]
classif.fit(X, y).predict(X)
array([[1, 0, 0],
       [1, 0, 0],
       [0, 1, 0],
       [0, 0, 0],
       [0, 0, 0]])

这里,分类器的拟合是基于两维二进制标签y, 基于LabelBinarizer进行转化。同样,预测值亦是相同的格式。

Note: 第4和第五预测值是全零,表明未找到符合的类。

对与对标签的输出,其结果是相似的。

from sklearn.preprocessing import MultiLabelBinarizer
y = [[0, 1], [0, 2], [1, 3], [0, 2, 3], [2, 4]]
y = MultiLabelBinarizer().fit_transform(y)
print(y)
[[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]]
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]])

猜你喜欢

转载自blog.csdn.net/u012604810/article/details/77526151
今日推荐