Python-SKLearn入门
本文主要来自Sklearn官网中的文档说明,详细文档请访问该网址[http://scikit-learn.org/dev/tutorial/basic/tutorial.html]
本文构成:
加载样本数据集
首先需要加载iris和digits数据集,加载代码如下。
from sklearn import datasets
iris = datasets.load_iris()
digits = datasets.load_digits()
数据集是一个类文件对象,它保存了所有的数据及其元数据。数据保存在iris或者digits的.data属性中,该属性返回值为一个数组,这个属性包括了所有的训练样本和样本的特征属性。更多的细节在dedicated section中,相关代码如下
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属性返回了样本的标签,用于监督分类。datasets包详细内容。
datasets可以加载硬盘文件。用于加载数据集的包有pandas(加载常见的csv、exvel.json、sql等数据集)、scipy、skimage等等。
学习预测
在SKlearn中集成了多种常用的机器学习方法,比如SVM、随机森林、GBDT、决策树、K近邻、K均值、神经网络和LR等等。python把学习算法封装成统一的模板,用fit函数来训练,用predict函数来预测。
比如SVM算法,在Sklearn中对应类Sklearn.svm.svc,代码如下:
from sklearn import svm
clf = svm.SVC(gamma=0.001, C=100.)
当然,我们也可以设置学习器的参数,比如在svm中我们可以设置核函数、C值、gamma值等等,例子如下:
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:])
如果是新手,可以试一试这个例子Recognizing hand-written digits.
模型持久化(模型保存)
每一次对样本数据的训练都是极大耗费时间和精力的,为了能够把已经训练好的模型保存在磁盘中或者其他存储器里面,这样就可以做到,在需要的时候进行随时调用。SKLearn提供了pickle和joblib两种方法。
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])
当然我们也可以使用joblib.dump和joblib.load方法来替代上pickle,但是两者也有区别,joblib在处理数据了大的方面有独特的优势,然而仅仅能够把数据保存到硬盘而且数据不为字符串形式。
保存到硬盘
from sklearn.externals import joblib
joblib.dump(clf, 'filename.pkl')
从硬盘读取
clf = joblib.load('filename.pkl')
两者都可以用类文件对象来代替文件名,更多的信息请看here
安全性和可维护局限
pickle有一些安全和可维护性的问题:
1.存储不可信的数据可能会导致恶意代码在加载时被执行
2.不支持和运行在加载一个版本的模型后而用于其他版本,这可能会导致意想不到的结果。
为了能够重建一个相似的新模型,需要注意一下问题:
1.训练数据一致性
2.代码一致性
3.sklearn的版本一致性
4.注意获得训练数据上面的交叉验证分数
规则
Sklearn学习器遵循以下规则来是其更具有可预测性
1.类型转换
输入数据会自动转换为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
transformer = random_projection.GaussianRandomProjection()
X_new = transformer.fit_transform(X)
X_new.dtype
上述代码中的X是float32的,通过fit_transform方法被转化为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]))
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]))
上述代码中,虽然iris.target使用了fit,然而第一个predict方法返回的是数值数组,第二个predict返回的是字符串
2.refitting和更新参数
学习器的参数能够通过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)
clf.predict(X_test)
clf.set_params(kernel='rbf').fit(X, y)
clf.predict(X_test)
如代码所示,第二次调用fit后,会覆盖上次调用的结果
3.多分类
使用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)
在上方例子中,多分类是在一维数据标签上面的,他也能在二维二分标签上进行,代码如下。
y = LabelBinarizer().fit_transform(y)
classif.fit(X, y).predict(X)
当然,其在二维多标签下也能进行
from sklearn.preprocessing import MultiLabelBinarizer
y = [[0, 1], [0, 2], [1, 3], [0, 2, 3], [2, 4]]
y = preprocessing.MultiLabelBinarizer().fit_transform(y)
classif.fit(X, y).predict(X)