<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Exploración inicial de los datos
Step1:  Nota
Step2:  Imágenes por clase en datos de entrenamiento
Vale la pena conocer si los datos se encuentran balanceados o no (probablemente no) ya que esto puede afectar la estrategia a emplear.
Step3:  Observar algunas de las imágenes
Con esta función podemos ver algunas de las imágenes, también se puede ver que el resultado de aplicar un escalamiento sencillo no altera la imagen final. Este escalamiento puede ser muy útil para la convergencia de algunos algoritmos.
Step4:  Análisis de componentes principales (PCA)
<ASSISTANT_TASK:>
Python Code:
import os
import random
from tqdm import tqdm 
import matplotlib.pyplot as plt
from skimage import io #Para leer las imágenes
from skimage import img_as_float
%matplotlib inline
Explanation: Exploración inicial de los datos
End of explanation
ROOT_DIR = os.getcwd()
DATA_DIR = os.path.join(ROOT_DIR, 'german-traffic-signs')
TRAIN_DIR = os.path.join(DATA_DIR, 'training-set')
TEST_DIR = os.path.join(DATA_DIR, 'test-set')
os.path.split(ROOT_DIR)
assert os.path.exists(DATA_DIR)
assert os.path.exists(TRAIN_DIR)
assert os.path.exists(TEST_DIR)
Explanation: Nota: El módulo tqdm muestra una barra de progreso durante los ciclos, sólo la uso por que se ve chévere.
Definición de directorios
End of explanation
def plot_images_per_class(path): 
    lista  = [(int(folder), len(os.listdir(os.path.join(path,folder))) - 1) for folder in os.listdir(path)]
    lista = sorted(lista, key = lambda x: x[0])
    xVals = [clase for clase, val in lista]
    yVals = [val for clase, val in lista]
    fig = plt.figure(figsize=[15,5])
    ax = fig.add_subplot(111)
    plt.bar(xVals,yVals,width = 0.5)
    ax.set_title('Number of pictures per class', color = 'k', alpha = 0.6)
    ax.set_xlabel('Class', fontsize = 14)
    ax.set_ylabel('Number of pictures', fontsize = 14)
    ax.set_axisbelow(True)
plot_images_per_class(TRAIN_DIR)
plot_images_per_class(TEST_DIR)
Explanation: Imágenes por clase en datos de entrenamiento
Vale la pena conocer si los datos se encuentran balanceados o no (probablemente no) ya que esto puede afectar la estrategia a emplear.
End of explanation
def plot_random_sample(path,n_fos = 5,n_im = 3, scale = True, values = False):
    hor = n_fos
    ver = min(n_fos,n_im)
    fos = random.sample(os.listdir(path), n_fos)
    lista = []
    for fo in tqdm(fos):
        lista.append([os.path.join(fo,fi) for fi in random.sample(os.listdir(os.path.join(path,fo)),n_im) if fi.endswith('.jpg')])
    new_style = {'grid': False}
    plt.rc('axes', **new_style)
    _, ax = plt.subplots(n_fos, n_im, sharex='col', sharey='row', figsize=(2*n_im, 2*n_fos))
    for i, files in enumerate(lista):
        for j, file in enumerate(files):
            if scale:
                img = img_as_float(io.imread(os.path.join(path,file)))
            else:
                img = io.imread(os.path.join(path,file))
            if values:
                print(img)
            ax[i, j].imshow(img)
            ax[i, j].set_title(file)
    plt.show()
plot_random_sample(TRAIN_DIR)
plot_random_sample(TEST_DIR)
Explanation: Observar algunas de las imágenes
Con esta función podemos ver algunas de las imágenes, también se puede ver que el resultado de aplicar un escalamiento sencillo no altera la imagen final. Este escalamiento puede ser muy útil para la convergencia de algunos algoritmos.
End of explanation
from sklearn.decomposition import PCA, IncrementalPCA
import numpy as np
def load_data(files, scale = True):
    X, y = [], []
    for file in tqdm(files):
        if file.endswith(".jpg"):
            y.append(int(os.path.split(os.path.split(file)[0])[-1]))
            if scale:
                X.append(img_as_float(io.imread(file)))
            else:
                X.append(io.imread(file))
            
    return np.array(X), np.array(y)
def get_files_path(path, ext = ".jpg", n = np.inf):
    file_paths = []
    for folder in tqdm(os.listdir(path)):
        files = os.listdir(os.path.join(path,folder))
        if len(files) <= n:
            file_paths += [os.path.join(path,folder,file) for file in files if file.endswith(ext)]
        else:
            file_paths += [os.path.join(path,folder, file) for file in random.sample(files,n) if file.endswith(ext)]
            
    return file_paths
train_files = get_files_path(TRAIN_DIR)
X, y = load_data(train_files)
print(X.shape)
print(y.shape)
X = np.reshape(X, newshape = (-1,32*32*3))
print(X.shape)
ipca = IncrementalPCA()
ipca.fit(X)
plt.step(range(1,len(ipca.explained_variance_ratio_)+1), np.cumsum(ipca.explained_variance_ratio_), where='mid',
         label='cumulative explained variance')
plt.bar(range(1,len(ipca.explained_variance_ratio_)+1), ipca.explained_variance_ratio_, alpha=0.9, align='center',
        label='individual explained variance')
plt.ylabel('Explained variance ratio')
plt.xlabel('Principal components')
plt.legend(loc='best')
plt.show()
Explanation: Análisis de componentes principales (PCA)
End of explanation
<END_TASK>