Scikit-learnのpipeleine.Pipelineが便利
分析する際に、次元圧縮→分類のような流れで行う場合には、scikit-learnのPipelineが便利。特にハイパーパラメーターを探すときには手続が煩雑になることもありますが、まとめて分類器としててGridSearchCVに突っ込むだけで良いのでめんどくさいこと考えずに済みますね。
今回はScikit-learnのサンプルデータの中から、the digits datasetのデータをロードし、PCAでの次元圧縮からSVMでの分類をPipelineでまとめて実行する手順を確認してみました。
コード
まずはデータを読み込み、訓練データとテストデータに分割。
また手書き文字のデータがどんなものかを描き出します。
import numpy as np from sklearn import svm from sklearn.decomposition import PCA from sklearn import datasets from sklearn.grid_search import GridSearchCV from sklearn.pipeline import Pipeline from sklearn.cross_validation import train_test_split from sklearn import metrics from matplotlib import pyplot as plt from matplotlib import cm %matplotlib inline digits = datasets.load_digits() X = digits.data y = digits.target print 'Number of data = {0}, Dimension = {1}'.format(X.shape[0],X.shape[1]) p = np.random.random_integers(0, len(digits.data), 25) for index, (data, label) in enumerate(np.array(zip(digits.data, digits.target))[p]): plt.subplot(5, 5, index + 1) plt.axis('off') plt.imshow(data.reshape(8, 8), cmap=plt.cm.gray_r, interpolation='nearest') plt.title('%i' % label) plt.show() #Split the data X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2) Number of data = 1797, Dimension = 64
続いて、PCAで次元削減、SVMでの分類という2つの手順を一つのPipelineで分類器としてまとめます。
今回グリッドサーチでパラメータ探索するためにリスト形式で候補を入れてます。
複数の関数にまたがってパラメーターを指定することになるため、ハイフン二つの後にパラメーター名を指定することで、コントラクタに渡すようになってます。
estimators = [('pca', PCA()), ('svm', svm.SVC())] parameters = {"pca__n_components" : range(2, 6), "svm__kernel" : ["linear", "poly", "rbf", "sigmoid"], 'svm__C': np.logspace(0, 2, 10).tolist(), "svm__gamma": np.logspace(-3, 0, 10).tolist()} pl = Pipeline(estimators)
最後にplを一つの分類器としてみなし、そのままGridSearchCVに突っ込みます。
clf = GridSearchCV(pl, parameters, n_jobs=-1) clf.fit(X_train, y_train) print 'Best_estimator = {0}'.format(clf.best_estimator_.get_params()) #予測 Predict = clf.predict(X_test) n_samples = len(digits.data) expected = digits.target[n_samples * -4 / 10:] predicted = clf.predict(digits.data[n_samples * -4 / 10:]) print("Classification report for classifier %s:\n%s\n" % (clf, metrics.classification_report(expected, predicted))) print("Confusion matrix:\n%s" % metrics.confusion_matrix(expected, predicted)) Best_estimator = {'svm__max_iter': -1, 'svm__coef0': 0.0, 'svm': SVC(C=1.6681005372, 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), 'svm__random_state': None, 'pca__copy': True, 'svm__degree': 3, 'pca__n_components': 5, 'svm__gamma': 0.01, 'svm__shrinking': True, 'pca__whiten': False, 'svm__tol': 0.001, 'svm__verbose': False, 'svm__C': 1.6681005372000588, 'steps': [('pca', PCA(copy=True, n_components=5, whiten=False)), ('svm', SVC(C=1.6681005372, 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))], 'svm__probability': False, 'svm__class_weight': None, 'pca': PCA(copy=True, n_components=5, whiten=False), 'svm__decision_function_shape': None, 'svm__kernel': 'rbf', 'svm__cache_size': 200} Classification report for classifier GridSearchCV(cv=None, error_score='raise', estimator=Pipeline(steps=[('pca', PCA(copy=True, n_components=None, whiten=False)), ('svm', 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))]), fit_params={}, iid=True, n_jobs=-1, param_grid={'pca__n_components': [2, 3, 4, 5], 'svm__C': [1.0, 1.6681005372000588, 2.7825594022071245, 4.641588833612778, 7.742636826811269, 12.91549665014884, 21.544346900318832, 35.93813663804626, 59.94842503189409, 100.0], 'svm__gamma': [0.001, 0.0021544346900318843, 0.004641588833612777, 0.01, 0.021544346900318832, 0.046415888336127774, 0.1, 0.21544346900318823, 0.46415888336127775, 1.0]}, pre_dispatch='2*n_jobs', refit=True, scoring=None, verbose=0): precision recall f1-score support 0 1.00 0.96 0.98 71 1 0.99 0.97 0.98 73 2 0.94 0.93 0.94 71 3 0.95 0.96 0.95 74 4 0.96 0.96 0.96 74 5 0.97 1.00 0.99 71 6 0.99 1.00 0.99 74 7 0.93 0.92 0.92 72 8 0.84 0.85 0.85 68 9 0.90 0.92 0.91 71 avg / total 0.95 0.95 0.95 719 Confusion matrix: [[68 0 0 0 2 0 1 0 0 0] [ 0 71 0 0 0 0 0 1 0 1] [ 0 0 66 1 0 0 0 0 2 2] [ 0 0 0 71 0 0 0 2 0 1] [ 0 0 0 0 71 0 0 0 3 0] [ 0 0 0 0 0 71 0 0 0 0] [ 0 0 0 0 0 0 74 0 0 0] [ 0 1 0 0 0 0 0 66 5 0] [ 0 0 4 0 1 0 0 2 58 3] [ 0 0 0 3 0 2 0 0 1 65]]