from __future__ import print_function

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

"""
Explanation: Hyperparameter optimization
- Select the best parametrization for a specific model
End of explanation
"""


from sklearn import datasets

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

print(digits.data)
print(digits.target)

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

"""
Explanation: Load data
End of explanation
"""


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

"""
Explanation: RandomForestClassifier
End of explanation
"""


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

import matplotlib.pyplot as plt
%matplotlib inline

plt.plot(index,accuracy)


"""
Explanation: Hiperparameter optimization
End of explanation
"""


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


print(random_search.cv_results_)

# 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_)       

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

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

"""
Explanation: Use of RandomizedSearchCV
http://scikit-learn.org/stable/modules/generated/sklearn.model_selection.RandomizedSearchCV.html#sklearn.model_selection.RandomizedSearchCV
End of explanation
"""


