Hyperparameter optimization

- Select the best parametrization for a specific model

In [1]:
from __future__ import print_function

from sklearn import __version__ as sklearn_version
print('Sklearn version:', sklearn_version)


Sklearn version: 0.18.1

Load data


In [2]:
from sklearn import datasets

digits = datasets.load_digits()
print(digits.DESCR)


Optical Recognition of Handwritten Digits Data Set
===================================================

Notes
-----
Data Set Characteristics:
    :Number of Instances: 5620
    :Number of Attributes: 64
    :Attribute Information: 8x8 image of integer pixels in the range 0..16.
    :Missing Attribute Values: None
    :Creator: E. Alpaydin (alpaydin '@' boun.edu.tr)
    :Date: July; 1998

This is a copy of the test set of the UCI ML hand-written digits datasets
http://archive.ics.uci.edu/ml/datasets/Optical+Recognition+of+Handwritten+Digits

The data set contains images of hand-written digits: 10 classes where
each class refers to a digit.

Preprocessing programs made available by NIST were used to extract
normalized bitmaps of handwritten digits from a preprinted form. From a
total of 43 people, 30 contributed to the training set and different 13
to the test set. 32x32 bitmaps are divided into nonoverlapping blocks of
4x4 and the number of on pixels are counted in each block. This generates
an input matrix of 8x8 where each element is an integer in the range
0..16. This reduces dimensionality and gives invariance to small
distortions.

For info on NIST preprocessing routines, see M. D. Garris, J. L. Blue, G.
T. Candela, D. L. Dimmick, J. Geist, P. J. Grother, S. A. Janet, and C.
L. Wilson, NIST Form-Based Handprint Recognition System, NISTIR 5469,
1994.

References
----------
  - C. Kaynak (1995) Methods of Combining Multiple Classifiers and Their
    Applications to Handwritten Digit Recognition, MSc Thesis, Institute of
    Graduate Studies in Science and Engineering, Bogazici University.
  - E. Alpaydin, C. Kaynak (1998) Cascading Classifiers, Kybernetika.
  - Ken Tang and Ponnuthurai N. Suganthan and Xi Yao and A. Kai Qin.
    Linear dimensionalityreduction using relevance weighted LDA. School of
    Electrical and Electronic Engineering Nanyang Technological University.
    2005.
  - Claudio Gentile. A New Approximate Maximal Margin Classification
    Algorithm. NIPS. 2000.


In [3]:
print(digits.data)
print(digits.target)


[[  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.]]
[0 1 2 ..., 8 9 8]

In [4]:
#Randomize and separate train & test
from sklearn.utils import shuffle
X, y = shuffle(digits.data, digits.target, random_state=0)

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=0)

print(X_train.shape, X_test.shape, y_train.shape, y_test.shape)


(1203, 64) (594, 64) (1203,) (594,)

RandomForestClassifier


In [5]:
from sklearn.ensemble import RandomForestClassifier
clf = RandomForestClassifier()

clf.fit(X_train, y_train)

from sklearn.metrics import accuracy_score
print('Accuracy tree: ', accuracy_score(y_test, clf.predict(X_test)))


Accuracy tree:  0.952861952862

Hiperparameter optimization


In [6]:
def acc(i):
    clf = RandomForestClassifier(max_features=i)
    clf.fit(X_train, y_train)
    return accuracy_score(y_test, clf.predict(X_test))

index = []
accuracy = []
for i in range(2,30):
    index += [i]
    accuracy += [acc(i)]

In [7]:
import matplotlib.pyplot as plt
%matplotlib inline

plt.plot(index,accuracy)


Out[7]:
[<matplotlib.lines.Line2D at 0x7f1fb9462910>]

In [8]:
import numpy as np

from time import time
from scipy.stats import randint

from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import RandomizedSearchCV


# Define estimator. No parameters
clf = RandomForestClassifier(n_estimators=20)




# specify parameters and distributions to sample from
param_dist = {"max_depth": [3, None],
              "max_features": randint(1, 11),
              "min_samples_split": randint(2, 11),
              "min_samples_leaf": randint(1, 11),
              "bootstrap": [True, False],
              "criterion": ["gini", "entropy"]}

# run randomized search
n_iter_search = 20
random_search = RandomizedSearchCV(clf, param_distributions=param_dist,
                                   n_iter=n_iter_search)

start = time()
random_search.fit(X, y)
print("RandomizedSearchCV took %.2f seconds for %d candidates"
      " parameter settings." % ((time() - start), n_iter_search))


RandomizedSearchCV took 7.75 seconds for 20 candidates parameter settings.

In [9]:
print(random_search.cv_results_)


{'rank_test_score': array([16, 15,  4,  9, 17, 18, 19, 13,  1, 11, 12, 19,  3,  6,  7, 10, 14,
        5,  7,  2], dtype=int32), 'split0_train_score': array([ 0.88368201,  0.86945607,  0.99330544,  0.97991632,  0.88117155,
        0.86527197,  0.83430962,  0.87866109,  1.        ,  0.86025105,
        0.90041841,  0.87029289,  0.99414226,  0.9832636 ,  0.97824268,
        0.89037657,  0.86276151,  0.98410042,  0.98493724,  0.9958159 ]), 'split2_test_score': array([ 0.85234899,  0.84731544,  0.95469799,  0.94463087,  0.83724832,
        0.81711409,  0.84228188,  0.83557047,  0.9614094 ,  0.87416107,
        0.8557047 ,  0.85234899,  0.95805369,  0.94295302,  0.95302013,
        0.8590604 ,  0.86744966,  0.95469799,  0.94798658,  0.96644295]), 'param_min_samples_leaf': masked_array(data = [9 4 7 7 8 2 9 6 2 10 5 5 1 6 10 10 8 6 9 5],
             mask = [False False False False False False False False False False False False
 False False False False False False False False],
       fill_value = ?)
, 'mean_fit_time': array([ 0.09195463,  0.0722816 ,  0.10614999,  0.08172727,  0.07774099,
        0.08452264,  0.07902869,  0.07496532,  0.10880129,  0.08353933,
        0.08143838,  0.07280866,  0.13238804,  0.09332204,  0.09114242,
        0.07530332,  0.06995106,  0.09928799,  0.10337869,  0.14979474]), 'param_min_samples_split': masked_array(data = [8 5 7 5 2 8 9 4 6 7 2 3 10 10 10 7 5 10 4 3],
             mask = [False False False False False False False False False False False False
 False False False False False False False False],
       fill_value = ?)
, 'std_test_score': array([ 0.01050461,  0.01239625,  0.00063142,  0.00451079,  0.00661155,
        0.02047516,  0.03274582,  0.00876228,  0.00693847,  0.01728177,
        0.00676041,  0.0155871 ,  0.00171784,  0.00216783,  0.00884629,
        0.00438265,  0.01787916,  0.00664389,  0.00330297,  0.00537061]), 'params': ({'bootstrap': False, 'min_samples_leaf': 9, 'min_samples_split': 8, 'criterion': 'entropy', 'max_features': 7, 'max_depth': 3}, {'bootstrap': True, 'min_samples_leaf': 4, 'min_samples_split': 5, 'criterion': 'gini', 'max_features': 7, 'max_depth': 3}, {'bootstrap': False, 'min_samples_leaf': 7, 'min_samples_split': 7, 'criterion': 'gini', 'max_features': 9, 'max_depth': None}, {'bootstrap': True, 'min_samples_leaf': 7, 'min_samples_split': 5, 'criterion': 'gini', 'max_features': 6, 'max_depth': None}, {'bootstrap': False, 'min_samples_leaf': 8, 'min_samples_split': 2, 'criterion': 'entropy', 'max_features': 5, 'max_depth': 3}, {'bootstrap': True, 'min_samples_leaf': 2, 'min_samples_split': 8, 'criterion': 'entropy', 'max_features': 9, 'max_depth': 3}, {'bootstrap': False, 'min_samples_leaf': 9, 'min_samples_split': 9, 'criterion': 'gini', 'max_features': 10, 'max_depth': 3}, {'bootstrap': True, 'min_samples_leaf': 6, 'min_samples_split': 4, 'criterion': 'entropy', 'max_features': 5, 'max_depth': 3}, {'bootstrap': False, 'min_samples_leaf': 2, 'min_samples_split': 6, 'criterion': 'gini', 'max_features': 8, 'max_depth': None}, {'bootstrap': True, 'min_samples_leaf': 10, 'min_samples_split': 7, 'criterion': 'entropy', 'max_features': 9, 'max_depth': 3}, {'bootstrap': True, 'min_samples_leaf': 5, 'min_samples_split': 2, 'criterion': 'entropy', 'max_features': 8, 'max_depth': 3}, {'bootstrap': True, 'min_samples_leaf': 5, 'min_samples_split': 3, 'criterion': 'entropy', 'max_features': 4, 'max_depth': 3}, {'bootstrap': True, 'min_samples_leaf': 1, 'min_samples_split': 10, 'criterion': 'entropy', 'max_features': 9, 'max_depth': None}, {'bootstrap': True, 'min_samples_leaf': 6, 'min_samples_split': 10, 'criterion': 'entropy', 'max_features': 4, 'max_depth': None}, {'bootstrap': False, 'min_samples_leaf': 10, 'min_samples_split': 10, 'criterion': 'gini', 'max_features': 6, 'max_depth': None}, {'bootstrap': False, 'min_samples_leaf': 10, 'min_samples_split': 7, 'criterion': 'entropy', 'max_features': 4, 'max_depth': 3}, {'bootstrap': True, 'min_samples_leaf': 8, 'min_samples_split': 5, 'criterion': 'gini', 'max_features': 5, 'max_depth': 3}, {'bootstrap': True, 'min_samples_leaf': 6, 'min_samples_split': 10, 'criterion': 'entropy', 'max_features': 5, 'max_depth': None}, {'bootstrap': False, 'min_samples_leaf': 9, 'min_samples_split': 4, 'criterion': 'gini', 'max_features': 9, 'max_depth': None}, {'bootstrap': False, 'min_samples_leaf': 5, 'min_samples_split': 3, 'criterion': 'entropy', 'max_features': 9, 'max_depth': None}), 'std_fit_time': array([ 0.00115622,  0.00114397,  0.00078962,  0.00013472,  0.00054667,
        0.00027547,  0.00014341,  0.00021946,  0.00024196,  0.00012383,
        0.00048064,  0.00018756,  0.00086825,  0.00091223,  0.00059366,
        0.00101429,  0.00055549,  0.00071052,  0.0004669 ,  0.00077322]), 'std_score_time': array([  1.39942973e-04,   7.69491014e-05,   2.55571669e-05,
         1.59445573e-04,   3.91385882e-05,   9.65215467e-05,
         3.65033993e-05,   1.54305639e-04,   1.86684877e-04,
         1.54541510e-05,   1.17982432e-04,   1.22242382e-04,
         1.10929025e-04,   1.35323402e-05,   9.94359517e-05,
         3.43876043e-05,   1.01843966e-04,   3.64746661e-05,
         7.72287303e-05,   1.01495461e-04]), 'std_train_score': array([ 0.01269034,  0.00656256,  0.00179163,  0.00118113,  0.01217951,
        0.01963239,  0.02217831,  0.00993328,  0.        ,  0.00842849,
        0.01764607,  0.01773605,  0.00208833,  0.00169243,  0.00278141,
        0.01236855,  0.0112465 ,  0.00297513,  0.00210166,  0.0007934 ]), 'param_criterion': masked_array(data = ['entropy' 'gini' 'gini' 'gini' 'entropy' 'entropy' 'gini' 'entropy' 'gini'
 'entropy' 'entropy' 'entropy' 'entropy' 'entropy' 'gini' 'entropy' 'gini'
 'entropy' 'gini' 'entropy'],
             mask = [False False False False False False False False False False False False
 False False False False False False False False],
       fill_value = ?)
, 'param_max_depth': masked_array(data = [3 3 None None 3 3 3 3 None 3 3 3 None None None 3 3 None None None],
             mask = [False False False False False False False False False False False False
 False False False False False False False False],
       fill_value = ?)
, 'split1_train_score': array([ 0.85893155,  0.8572621 ,  0.98914858,  0.97746244,  0.85475793,
        0.89148581,  0.87896494,  0.88647746,  1.        ,  0.85308848,
        0.8572621 ,  0.82971619,  0.99582638,  0.98497496,  0.98497496,
        0.87395659,  0.86143573,  0.99081803,  0.98998331,  0.99749583]), 'param_bootstrap': masked_array(data = [False True False True False True False True False True True True True True
 False False True True False False],
             mask = [False False False False False False False False False False False False
 False False False False False False False False],
       fill_value = ?)
, 'split2_train_score': array([ 0.88759367,  0.85428809,  0.99000833,  0.98001665,  0.85595337,
        0.84346378,  0.88343047,  0.86261449,  1.        ,  0.8734388 ,
        0.88093256,  0.86344713,  0.99916736,  0.98084929,  0.98251457,
        0.86011657,  0.88592839,  0.98501249,  0.98834305,  0.99750208]), 'mean_score_time': array([ 0.01666665,  0.01513298,  0.01587939,  0.01571735,  0.01522239,
        0.01519203,  0.0151697 ,  0.01514077,  0.01599161,  0.0150334 ,
        0.01485825,  0.01524369,  0.01589068,  0.01602467,  0.01599034,
        0.01560299,  0.01552995,  0.01626134,  0.01552129,  0.01561936]), 'mean_train_score': array([ 0.87673574,  0.86033542,  0.99082078,  0.9791318 ,  0.86396095,
        0.86674052,  0.86556835,  0.87591768,  1.        ,  0.86225944,
        0.87953769,  0.8544854 ,  0.99637867,  0.98302928,  0.98191074,
        0.87481658,  0.87004188,  0.98664365,  0.98775453,  0.99693794]), 'split0_test_score': array([ 0.82890365,  0.8255814 ,  0.95348837,  0.93521595,  0.84219269,
        0.81893688,  0.78571429,  0.85049834,  0.97840532,  0.83222591,
        0.84385382,  0.82059801,  0.96179402,  0.94518272,  0.93189369,
        0.86378738,  0.82392027,  0.93853821,  0.94352159,  0.9551495 ]), 'mean_test_score': array([ 0.83750696,  0.8425153 ,  0.95381191,  0.94156928,  0.83528102,
        0.83249861,  0.83027268,  0.84752365,  0.96994992,  0.85475793,
        0.85308848,  0.83027268,  0.96048971,  0.94546466,  0.94379521,
        0.85865331,  0.84418475,  0.94713411,  0.94379521,  0.96271564]), 'param_max_features': masked_array(data = [7 7 9 6 5 9 10 5 8 9 8 4 9 4 6 4 5 5 9 9],
             mask = [False False False False False False False False False False False False
 False False False False False False False False],
       fill_value = ?)
, 'split1_test_score': array([ 0.83138564,  0.85475793,  0.95325543,  0.94490818,  0.8263773 ,
        0.86143573,  0.86310518,  0.85642738,  0.96994992,  0.85809683,
        0.85976628,  0.81803005,  0.96160267,  0.94824708,  0.94657763,
        0.85308848,  0.84140234,  0.94824708,  0.93989983,  0.96661102])}

In [10]:
# Utility function to report best scores
def report(results, n_top=3):
    for i in range(1, n_top + 1):
        candidates = np.flatnonzero(results['rank_test_score'] == i)
        for candidate in candidates:
            print("Model with rank: {0}".format(i))
            print("Mean validation score: {0:.3f} (std: {1:.3f})".format(
                  results['mean_test_score'][candidate],
                  results['std_test_score'][candidate]))
            print("Parameters: {0}".format(results['params'][candidate]))
            print("")

            
report(random_search.cv_results_)


Model with rank: 1
Mean validation score: 0.970 (std: 0.007)
Parameters: {'bootstrap': False, 'min_samples_leaf': 2, 'min_samples_split': 6, 'criterion': 'gini', 'max_features': 8, 'max_depth': None}

Model with rank: 2
Mean validation score: 0.963 (std: 0.005)
Parameters: {'bootstrap': False, 'min_samples_leaf': 5, 'min_samples_split': 3, 'criterion': 'entropy', 'max_features': 9, 'max_depth': None}

Model with rank: 3
Mean validation score: 0.960 (std: 0.002)
Parameters: {'bootstrap': True, 'min_samples_leaf': 1, 'min_samples_split': 10, 'criterion': 'entropy', 'max_features': 9, 'max_depth': None}


In [ ]:
clf = RandomForestClassifier()

clf.fit(X_train, y_train)

from sklearn.metrics import accuracy_score
print('Accuracy tree: ', accuracy_score(y_test, clf.predict(X_test)))

In [ ]:


In [43]:
# Configure model
from sklearn import svm
clf_svc = svm.SVC(gamma=0.001, C=100.)

clf_svc.fit(X_train, y_train)
print(accuracy_score(y_test, clf_svc.predict(X_test)))


0.993265993266

In [ ]:


In [ ]: