<jupyter_start><jupyter_text>Chapter 3: Classification- Unlike Linear Regression which predict real values, Classification predicts classes (probability).<jupyter_code>!pip install wget
import wget
from os import path, mkdir

dataDir = "../datasets/mnist"
trainDir = "../datasets/mnist/train"

if not path.exists("dataDir"):
    mkdir(dataDir)
    mkdir(trainDir)

mnistTrainUrl = "http://yann.lecun.com/exdb/mnist/train-images-idx3-ubyte.gz"

if not path.exists(path.join(dataDir, "train-images-idx3-ubyte.gz")):
    wget.download(mnistTrainUrl, dataDir)

!gunzip ../datasets/mnist/train-images-idx3-ubyte.gz -d ../datasets/mnist/train
import numpy as np
import struct
from array import array

images_file = "../datasets/mnist/train-images-idx3-ubyte"
images = []

with open(images_file, 'rb') as file:
    magic, size, rows, cols = struct.unpack(">IIII", file.read(16))
    
    if magic != 2051:
        raise ValueError('Magic number mismatch, expected 2051, got {}'.format(magic))
    
    image_data = array("B", file.read()) 
    
    for i in range(size):
        images.append([0] * rows * cols)
    for i in range(size):
        img = np.array(image_data[i * rows * cols:(i + 1) * rows * cols])
        img = img.reshape(28, 28)
        images[i][:] = img 
    
def read_images(images_path):
    images = []
    with open(images_path, 'rb') as file:
        magic, size, rows, cols = struct.unpack(">IIII", file.read(16))

        if magic != 2051:
            raise ValueError('Magic number mismatch, expected 2051, got {}'.format(magic))

        image_data = array("B", file.read()) 

        for i in range(size):
            images.append([0] * rows * cols)
        for i in range(size):
            img = np.array(image_data[i * rows * cols:(i + 1) * rows * cols])
            img = img.reshape(28, 28)
            images[i][:] = img 
    return images
# Download labels
mnistTrainUrl = "http://yann.lecun.com/exdb/mnist/train-labels-idx1-ubyte.gz"

if not path.exists(path.join(dataDir, "train-labels-idx1-ubyte.gz")):
    wget.download(mnistTrainUrl, dataDir)
!gunzip ../datasets/mnist/train-labels-idx1-ubyte.gz 
def read_labels(labels_path):
    with open(labels_path, 'rb') as file:
        magic, size = struct.unpack(">II", file.read(8))
        if magic != 2049:
            raise ValueError('Magic number mismatch, expected 2049, got {}'.format(magic))
        labels = array("B", file.read())
    return labels
train_images = read_images("../datasets/mnist/train-images-idx3-ubyte")
train_labels = read_labels("../datasets/mnist/train-labels-idx1-ubyte")

assert len(train_images) == 60000
assert len(train_labels) == 60000

print("Dataset loaded...")
type(train_images)
train_images = np.array(train_images)
train_labels = np.array(train_labels)
import matplotlib.pyplot as plt
plt.imshow(train_images[0])
# Print a grid of images; just for the show and to feel cool
def show_images(images, labels):
    cols = 5
    rows = int(len(images)/cols) + 1
    plt.figure(figsize=(30,20))
    index = 1
    for image, label in zip(images, labels):
        plt.subplot(cols, rows,index)
        plt.imshow(image)
        plt.title(label)
        index += 1
show_images(train_images[0:15], train_labels[0:15])
train_images = train_images.astype(int)
train_labels = train_labels.astype(int)
show_images(train_images[-15:], train_labels[-15:])
train_images[0].shape
# Shuffle the training data
shuffle_index = np.random.permutation(60000)
X_train, y_train = train_images[shuffle_index], train_labels[shuffle_index]

assert X_train.shape == (60000, 28, 28)
assert y_train.shape == (60000,)
y_train.shape<jupyter_output><empty_output><jupyter_text>Train a binary classifier on mnist- We will simplify the problem and try for one digit- The binary classifier will be distinguishing between 5 and not 5- We will use Stochastic Gradient Descent class from `sklearn`<jupyter_code>y_train_5 = (y_train == 5) 
y_train_5.shape
y_train[0]
X_train_cp = X_train

X_train_cp = X_train_cp.reshape([60000, 784])
X_train_cp.shape
y_train_5[0]
from sklearn.linear_model import SGDClassifier

sgd_clf = SGDClassifier()
sgd_clf.fit(X_train_cp, y_train_5)

sgd_clf.predict([X_train_cp[15]])
y_train_5[15]<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.13380614657210402, 'fraction_numerical': 0.02884160756501182, 'mean_word_length': 3.8409610983981692, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 12, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 3, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '2', 'dir': 'jupyter-structured-clean-dedup', 'id': '258881', 'license': 'Apache-2.0', 'n_tokens_mistral': 1593, 'n_tokens_neox': 1485, 'n_words': 339, 'path': 'exe_solutions/Chapter_3_Classification.ipynb', 'repo_name': 'EngEryx/handson-ml', 'size': '4230'}