Algoritmo de optimizaci贸n de b煤squeda de cuadr铆cula en Python

    Introducci贸n

    En este tutorial, vamos a hablar de un algoritmo de optimizaci贸n (o automatizaci贸n) muy poderoso, es decir, el algoritmo de b煤squeda de cuadr铆cula. Se usa m谩s com煤nmente para el ajuste de hiperpar谩metros en modelos de Machine Learning. Aprenderemos c贸mo implementarlo usando Python, as铆 como aplicarlo en una aplicaci贸n real para ver c贸mo puede ayudarnos a elegir los mejores par谩metros para nuestro modelo y mejorar su precisi贸n. As铆 que empecemos.

    Prerrequisitos

    Para seguir este tutorial, debe tener un conocimiento b谩sico de Python o alg煤n otro lenguaje de programaci贸n. Es preferible, pero no esencial, que tambi茅n tenga algunos conocimientos b谩sicos de Machine Learning. Aparte de eso, este art铆culo es para principiantes y cualquier persona puede seguirlo.

    Instalaci贸n

    Para seguir el tutorial, debe tener las siguientes bibliotecas / marcos instalados en su sistema:

    Todos son bastante sencillos de instalar: puede hacer clic en cada uno para ir a sus respectivos sitios web donde se proporcionan instrucciones detalladas de instalaci贸n. Generalmente, los paquetes se pueden instalar usando pip:

    $ pip install numpy pandas tensorflow keras scikit-learn
    

    Si tiene alg煤n problema, consulte la documentaci贸n oficial de cada paquete.

    驴Qu茅 es Grid Search?

    La b煤squeda de cuadr铆cula es esencialmente un algoritmo de optimizaci贸n que le permite seleccionar los mejores par谩metros para su problema de optimizaci贸n de una lista de opciones de par谩metros que usted proporciona, automatizando as铆 el m茅todo de ‘prueba y error’. Aunque se puede aplicar a muchos problemas de optimizaci贸n, es m谩s conocido por su uso en el Machine Learning para obtener los par谩metros en los que el modelo ofrece la mejor precisi贸n.

    Supongamos que su modelo toma los siguientes tres par谩metros como entrada:

    • N煤mero de capas ocultas [2, 4]
    • N煤mero de neuronas en cada capa [5, 10]
    • N煤mero de 茅pocas [10, 50]

    Si para cada entrada de par谩metro deseamos probar dos opciones (como se menciona entre corchetes arriba), totaliza hasta 23 = 8 combinaciones diferentes (por ejemplo, una combinaci贸n posible es [2,5,10]). Hacer esto manualmente ser铆a un dolor de cabeza.

    Ahora imagine si tuvi茅ramos 10 par谩metros de entrada diferentes y quisi茅ramos probar 5 valores posibles para cada par谩metro. Requerir铆a una entrada manual de nuestra parte cada vez que deseamos cambiar el valor de un par谩metro, volver a ejecutar el c贸digo y realizar un seguimiento de los resultados de todas las combinaciones de par谩metros. Grid Search automatiza ese proceso, ya que simplemente toma los valores posibles para cada par谩metro y ejecuta el c贸digo para probar todas las combinaciones posibles, genera el resultado para cada combinaci贸n y genera la combinaci贸n que brinda la mejor precisi贸n. 脷til, 驴no?

    Implementaci贸n de b煤squeda en cuadr铆cula

    Muy bien, suficiente charla. Apliquemos Grid Search en una aplicaci贸n real. Discutir la parte de Machine Learning y preprocesamiento de datos est谩 fuera del alcance de este tutorial, por lo que simplemente ejecutaremos su c贸digo y hablaremos en profundidad sobre la parte donde entra Grid Search. 隆Comencemos!

    Usaremos el conjunto de datos Pima Indian Diabetes, que contiene informaci贸n sobre si un paciente es diab茅tico o no en funci贸n de diferentes atributos, como la concentraci贸n de glucosa en sangre, la presi贸n arterial, etc. Uso de Pandas read_csv() m茅todo puede importar directamente el conjunto de datos desde un recurso en l铆nea.

    El siguiente script importa las bibliotecas necesarias:

    from sklearn.model_selection import GridSearchCV, KFold
    from keras.models import Sequential
    from keras.layers import Dense, Dropout
    from keras.wrappers.scikit_learn import KerasClassifier
    from keras.optimizers import Adam
    import sys
    import pandas as pd
    import numpy as np
    

    La siguiente secuencia de comandos importa el conjunto de datos y establece los encabezados de columna para el conjunto de datos.

    columns = ['num_pregnant', 'glucose_concentration', 'blood_pressure', 'skin_thickness',
               'serum_insulin', 'BMI', 'pedigree_function', 'age', 'class']
    
    data_path = "https://raw.githubusercontent.com/mkhalid1/Machine-Learning-Projects-Python-/master/Grid%20Search/pima-indians-diabetes.csv"
    
    df = pd.read_csv(data_path, names=columns)
    

    Echemos un vistazo a las primeras 5 filas del conjunto de datos:

    df.head()
    

    Salida:

    Como puede ver, estas 5 filas son etiquetas para describir cada columna (en realidad hay 9 de ellas), por lo que no nos sirven de nada. Comenzaremos eliminando estas filas que no son de datos y luego reemplazaremos todas las NaN valores con 0:

    # Remove first 9 non-data rows
    df = df.iloc[9:]
    
    # Replace NaN (Not a Number) values with 0 in each column
    for col in columns:
        df[col].replace(0, np.NaN, inplace=True)
    
    df.dropna(inplace=True) # Drop all rows with missing values
    dataset = df.values # Convert dataframe to numpy array
    

    El siguiente script divide los datos en conjuntos de caracter铆sticas y etiquetas y aplica la escala est谩ndar en el conjunto de datos:

    X = dataset[:,0:8]
    Y = dataset[:, 8].astype(int)
    
    # Normalize the data using sklearn StandardScaler
    from sklearn.preprocessing import StandardScaler
    
    scaler = StandardScaler().fit(X)
    
    # Transform and display the training data
    X_standardized = scaler.transform(X)
    
    data = pd.DataFrame(X_standardized)
    

    El siguiente m茅todo crea nuestro modelo de aprendizaje profundo simple:

    def create_model(learn_rate, dropout_rate):
        # Create model
        model = Sequential()
        model.add(Dense(8, input_dim=8, kernel_initializer="normal", activation='relu'))
        model.add(Dropout(dropout_rate))
        model.add(Dense(4, input_dim=8, kernel_initializer="normal", activation='relu'))
        model.add(Dropout(dropout_rate))
        model.add(Dense(1, activation='sigmoid'))
    
        # Compile the model
        adam = Adam(lr=learn_rate)
        model.compile(loss="binary_crossentropy", optimizer=adam, metrics=['accuracy'])
        return model
    

    Este es todo el c贸digo que necesitar铆a ejecutar para cargar el conjunto de datos, preprocesarlo y crear su modelo de Machine Learning. Dado que solo nos interesa ver la funcionalidad de Grid Search, no he realizado la divisi贸n de tren / prueba, y estar铆amos ajustando el modelo en todo el conjunto de datos.

    En la siguiente secci贸n comenzaremos a ver c贸mo Grid Search nos facilita la vida optimizando nuestros par谩metros.

    Entrenamiento del modelo sin b煤squeda de cuadr铆cula

    En el c贸digo a continuaci贸n, crearemos un modelo usando valores de par谩metros que decidimos al azar, o seg煤n nuestra intuici贸n, y veremos c贸mo funciona nuestro modelo:

    # Declare parameter values
    dropout_rate = 0.1
    epochs = 1
    batch_size = 20
    learn_rate = 0.001
    
    # Create the model object by calling the create_model function we created above
    model = create_model(learn_rate, dropout_rate)
    
    # Fit the model onto the training data
    model.fit(X_standardized, Y, batch_size=batch_size, epochs=epochs, verbose=1)
    

    Salida:

    Epoch 1/1
    130/130 [==============================] - 0s 2ms/step - loss: 0.6934 - accuracy: 0.6000
    

    La precisi贸n que obtuvimos, como puede ver a continuaci贸n, es 60.00%. Esto es bastante bajo, 隆pero no hay nada de qu茅 preocuparse! Todav铆a tenemos Grid Search para intentar salvar el d铆a. Vamos a por ello.

    Optimizaci贸n de hiperpar谩metros usando Grid Search

    Si no utiliza Grid Search, puede llamar directamente al fit() m茅todo en el modelo que hemos creado anteriormente. Sin embargo, para usar Grid Search, necesitamos pasar algunos par谩metros a nuestro create_model() funci贸n. Adem谩s, necesitamos declarar nuestra cuadr铆cula con diferentes opciones que nos gustar铆a probar para cada par谩metro. Hag谩moslo en partes.

    Primero modificamos nuestro create_model() funci贸n para aceptar par谩metros de la funci贸n de llamada:

    def create_model(learn_rate, dropout_rate):
        # Create model
        model = Sequential()
        model.add(Dense(8, input_dim=8, kernel_initializer="normal", activation='relu'))
        model.add(Dropout(dropout_rate))
        model.add(Dense(4, input_dim=8, kernel_initializer="normal", activation='relu'))
        model.add(Dropout(dropout_rate))
        model.add(Dense(1, activation='sigmoid'))
    
        # Compile the model
        adam = Adam(lr=learn_rate)
        model.compile(loss="binary_crossentropy", optimizer=adam, metrics=['accuracy'])
        return model
    
    # Create the model
    model = KerasClassifier(build_fn=create_model, verbose=1)
    

    Ahora, estamos listos para implementar nuestro algoritmo Grid Search y ajustar el conjunto de datos en 茅l:

    # Define the parameters that you wish to use in your Grid Search along
    # with the list of values that you wish to try out
    learn_rate = [0.001, 0.02, 0.2]
    dropout_rate = [0.0, 0.2, 0.4]
    batch_size = [10, 20, 30]
    epochs = [1, 5, 10]
    
    seed = 42
    
    # Make a dictionary of the grid search parameters
    param_grid = dict(learn_rate=learn_rate, dropout_rate=dropout_rate, batch_size=batch_size, epochs=epochs )
    
    # Build and fit the GridSearchCV
    grid = GridSearchCV(estimator=model, param_grid=param_grid,
                        cv=KFold(random_state=seed), verbose=10)
    
    grid_results = grid.fit(X_standardized, Y)
    
    # Summarize the results in a readable format
    print("Best: {0}, using {1}".format(grid_results.best_score_, grid_results.best_params_))
    
    means = grid_results.cv_results_['mean_test_score']
    stds = grid_results.cv_results_['std_test_score']
    params = grid_results.cv_results_['params']
    
    for mean, stdev, param in zip(means, stds, params):
        print('{0} ({1}) with: {2}'.format(mean, stdev, param))
    

    Salida:

    Best: 0.7959183612648322, using {'batch_size': 10, 'dropout_rate': 0.2, 'epochs': 10, 'learn_rate': 0.02}
    

    En la salida, podemos ver que nos da la combinaci贸n de par谩metros que produce la mejor precisi贸n.

    Es seguro decir que Grid Search fue bastante f谩cil de implementar en Python y nos ahorr贸 mucho tiempo, en t茅rminos de trabajo humano. Puede simplemente enumerar todos los par谩metros que le gustar铆a ajustar, declarar los valores que se probar谩n, ejecutar su c贸digo y olvidarse de 茅l. No se requiere m谩s informaci贸n de su lado. Una vez que se haya encontrado la mejor combinaci贸n de par谩metros, simplemente puede usarla para su modelo final.

    Conclusi贸n

    En resumen, aprendimos qu茅 es Grid Search, c贸mo puede ayudarnos a optimizar nuestro modelo y los beneficios que conlleva como la automatizaci贸n. Adem谩s, aprendimos c贸mo implementarlo en unas pocas l铆neas de c贸digo usando Python Language. Para ver su efectividad, tambi茅n entrenamos un modelo de Machine Learning con y sin realizar Grid Search, y la precisi贸n fue un 19% mayor con Grid Search.

    Etiquetas:

    Deja una respuesta

    Tu direcci贸n de correo electr贸nico no ser谩 publicada. Los campos obligatorios est谩n marcados con *