# ---
# jupyter:
#   jupytext:
#     text_representation:
#       extension: .py
#       format_name: light
#       format_version: '1.5'
#       jupytext_version: 1.14.4
#   kernelspec:
#     display_name: Python 3
#     language: python
#     name: python3
# ---

# # Classifiers

# +
import numpy as np
import os
# %matplotlib inline
import matplotlib
import matplotlib.pyplot as plt

from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import GridSearchCV
from sklearn.metrics import accuracy_score
from sklearn.datasets import fetch_mldata
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import MinMaxScaler
# -

# ## Load the MNIST data
#
# The server that Scikit Learn pulled this data from does not seem to exist anymore. The data was found from an alternate source then placed in the directory where Scikit would usually cache data sets.

mnist = fetch_mldata('MNIST original')
X, y = mnist["data"], mnist["target"]

print(mnist["DESCR"])
print(X.shape, y.shape)

# +
i = np.random.randint(60000)

some_digit = X[i]
some_digit_image = some_digit.reshape(28, 28)
plt.imshow(some_digit_image, cmap = matplotlib.cm.binary,
           interpolation="nearest")
plt.axis("off")
plt.title(f"Labeled as {y[i]}")

plt.show()
# -

XTrain, XTest, yTrain, yTest = X[:60000], X[60000:], y[:60000], y[60000:]

shuffleIndeces = np.random.permutation(60000)
XTrain, yTrain = XTrain[shuffleIndeces], yTrain[shuffleIndeces]

pipe = Pipeline([ ('normalizer', MinMaxScaler()) ])
prepTrain = pipe.fit_transform( XTrain.astype(np.float64) )

# +
params = { "weights" : ["uniform", "distance"],
           "n_neighbors": [ 3, 4, 5, 6, 7 ] }

knn = KNeighborsClassifier()

gridKNN = GridSearchCV( knn, params, cv = 3, verbose = 3, n_jobs = 3 )
gridKNN.fit(prepTrain, yTrain)
# -

gridKNN.best_score_

gridKNN.best_params_

# +
gridKNN = KNeighborsClassifier( n_neighbors = 4, weights = 'distance' )
gridKNN.fit( prepTrain, yTrain )

pred = gridKNN.predict(pipe.transform( XTest.astype(np.float64)) )
accuracy_score(yTest, pred)


# -

# ## Shift the images by one pixel

def shiftImages( X, y ):
    """Augments the data by adding copies of each image shifted one pixel
       in each direction. Returns new shuffled arrays."""

    m, n = X.shape

    tmp = X.reshape( (m, int(np.sqrt(n)), int(np.sqrt(n)) ) )

    newX = np.zeros( shape = (5*m, n ) )
    newY = np.zeros( 5*m )

    newX[ : m] = X[:]
    newY[ : m] = y[:]
    newX[m : 2*m] = np.roll(tmp, 1, 1).reshape(m,n)[:]
    newY[m : 2*m] = y[:]
    newX[2*m : 3*m] = np.roll(tmp, 1, 1).reshape(m,n)[:]
    newY[2*m : 3*m] = y[:]
    newX[3*m : 4*m] = np.roll(tmp, -1, 2).reshape(m,n)[:]
    newY[3*m : 4*m] = y[:]
    newX[4*m : 5*m] = np.roll(tmp, -1, 2).reshape(m,n)[:]
    newY[4*m : 5*m] = y[:]

    shuffleIndeces = np.random.permutation( len(newX) )

    return newX[shuffleIndeces], newY[shuffleIndeces]



# +
prepTrain, yTrain = shiftImages( prepTrain, yTrain )

#knn = KNeighborsClassifier( **gridKNN.best_params_ )
knn = KNeighborsClassifier( n_neighbors = 4, weights = 'distance' )
knn.fit( prepTrain, yTrain )

pred = knn.predict( pipe.transform( XTest.astype(np.float64)) )
accuracy_score(yTest, pred)
# -



StarcoderdataJupyterScriptsDedupFiltered