一、机器学习问题
通常,学习问题考虑n个样本数据集,然后预测未知数据的属性。若各个样本多于一个,例如,对于多维的条目(又称多元数据),即说有多个属性或特性。
我们可以把学习问题划分为如下几个大类:
1. 监督式学习,又分为:
2. 非监督式学习,
涉及到的概念:
机器学习是关于从已有的数据特性集中学习,然后应用到新的数据集。这就是为什么在通常的机器学习中评估一个算法时,把数据分为两部分。一部分为训练集(Training Set)。另一部分为测试集(Testing Set)。
二、加载例子数据集
scikit-learn自带一些标准的数据集,例如iris和digits数据集用于分类,boston房价数据集用于回归
>>> from sklearn import datasets
>>> iris = datasets.load_iris()
>>> digits = datasets.load_digits()
数据集是一个类似于字典的对象,包含所有的数据以及一些关于数据的元数据。数据存储在.data成员中,它是一个n_samples, n_features数组。在监督式问题中,解释性变量存储在.target成员中,更多的关于不同数据集的细节在后续会进行介绍。
例如,在digits数据集中,digits.data访问用于分类digits样本的特征。
>>> 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数据集的目标值。即相应的各个digit图像的数字。如下:
>>> digits.target
array([0, 1, 2, ..., 8, 9, 8])
数据数组的形状
数据总是一个二维数组,n_sample, n_features,尽管原始数据具有不同的形状,对于digits数据集,各个原始样本是一个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.]])
三、学习和预测
在digits数据集中,其任务就是来预测,给定一个图像,它表示的数字是多少?我们给定各个样本十个可能的类(数字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模型来完成。作为训练集,我们使用我们数据集中所有的图像除了最后一个。
>>> clf.fit(digits.data[:-1], digits.target[:-1])
SVC(C=100.0, cache_size=200, class_weight=None, coef0=0.0, 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])
关于手写数字的识别的完整分类问题的自理,可以见:http://scikit-learn.org/stable/auto_examples/plot_digits_classification.html#example-plot-digits-classification-py
四、模型持久性
在scikit中,通过使用内置的称为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, degree=3, gamma=0.0,
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])
array([0])
>>> y[0]
0
在scikit的特殊例子中,可以更加对使用joblib来取代pickle感兴趣(joblib.dump&joblib.load),因为对于big data其更加有效,
but can only pickle to the disk and not to a string:
>>> from sklearn.externals import joblib
>>> joblib.dump(clf, 'filename.pkl')