¿Cómo automatizar la selección de modelos y optimización de parámetros?
Automatizar el proceso de selección de modelos y optimización de parámetros es clave para trabajar de manera eficiente en data science. Esto no solo ahorra tiempo, sino que además mejora la eficacia de los resultados. En esta guía usaremos el RandomizedSearchCV de Scikit-learn para demostrar cómo se realiza este proceso.
¿Qué herramientas necesitamos importar?
Para iniciar con el proceso de optimización automática, importaremos las librerías necesarias. Como siempre, pandas es fundamental para la manipulación de datos. Además, importaremos el RandomizedSearchCV del módulo model_selection y el algoritmo RandomForestRegressor del módulo ensemble.
import pandas as pd
from sklearn.model_selection import RandomizedSearchCV
from sklearn.ensemble import RandomForestRegressor
¿Cómo prepararnos para la carga de datos?
Asegúrate de que tu script se esté ejecutando dentro de un entorno activado donde las librerías estén configuradas. Luego, carga tu archivo CSV en un DataFrame utilizando pandas.
if __name__ =="__main__": df = pd.read_csv("data/felicidad.csv")print(df.shape)# Confirmar la carga de datos
¿Cómo definimos y configuramos el modelo?
Primero, definimos un regresor RandomForestRegressor sin parámetros. Luego, establecemos una grilla de parámetros en forma de diccionario, donde cada clave es un parámetro del modelo y el valor es un rango de valores posibles.
El RandomizedSearchCV es una herramienta que permite optimizar de manera automática los parámetros de un modelo. Aquí configuramos nuestro estimator, param_distributions y ajustamos la cantidad de iteraciones y el método de validación cruzada.
Para dividir nuestros datos entre características (X) y variable objetivo (y), seleccionamos las columnas correspondientes. En este caso, eliminamos cualquier columna que no aporte significativamente al modelo.
X = df.drop(columns=["RANK","SCORE"])y = df["SCORE"]
¿Cómo entrenamos el modelo con la configuración optimizada?
Entrena el modelo utilizando la configuración optimizada por RandomizedSearchCV. Es esencial imprimir el mejor estimador y los parámetros para revisar la calidad de los resultados.
Finalmente, realiza las predicciones con el modelo optimizado. Verificamos la exactitud de las predicciones comparando los resultados previstos con las variables reales.
prediction = best_estimator.predict(X.iloc[0:1])print("Predicción para el primer registro:", prediction)
¿Qué observamos sobre el resultado?
En el ejemplo, la predicción se aproximó bastante al valor real, lo que indica que la optimización funcionó adecuadamente. Este proceso puede aplicarse a diferentes modelos y datasets para optimizar configuraciones de manera sistemática y efectiva.
Incorpora esto en tu flujo de trabajo diario para obtener resultados consistentes con menos esfuerzo manual. ¡Sigue explorando y perfeccionando tus modelos!
Hice algunas actualizaciones porque las funciones en la llave "criterion" están descontinuadas, así que el código queda de esta manera:
import pandas as pd
from sklearn.model_selectionimportRandomizedSearchCVfrom sklearn.ensembleimportRandomForestRegressorif __name__ =="__main__": dataset = pd.read_csv('./data/felicidad.csv')print(dataset)X= dataset.drop(['country','rank','score'], axis=1) y = dataset[['score']].squeeze() reg =RandomForestRegressor() parametros ={'n_estimators':range(4,16),'criterion':['squared_error','absolute_error'],'max_depth':range(2,11)} rand_est =RandomizedSearchCV(reg, parametros , n_iter=10, cv=3, scoring='neg_mean_absolute_error').fit(X,y)print(rand_est.best_estimator_)print(rand_est.best_params_)print(rand_est.predict(X.loc[[0]]))
Excelente, gracias por el aporte
Gracias amigo, me estaba volviendo loco
Con respecto a la razón de eliminar el rank y el score, se hace porque generalmente lo que se quiere es que las features no tengan ninguna correlación entre ellas. Lo ideal es que exista correlación solo entre las features y la variable objetivo :)
Muy bien explicado amiga ✔🥇
Impresionante! Esto ahorra mucho tiempo y con muy buena precisión.
Y sí, el profe se equivocó de número al final. En realidad era el siguiente de la izquierda.
Así es!
Dos cosas que ha prendido al momento y que hubiera deseado aprender hace unos años.
Siempre testear, probar nuevas cosas y mas con esta forma, ya se me quitó la pereza.
Todos los modelos son malos, solo que se busca el mejor. así que con esto se quiere siempre buscar el mejor, Obvio siempre llevare este curso en mi corazón porque en verdad he aprendido tanto
Muy buen curso!!
En realidad el score del primer pais no es el señalado en el video, ya que si se presta atencion al conteo de columnas y valores, se viendo el valor de high
Para saber el score en ese punto simplemente podemos imprimir el valor de y en esa misma posicion
Algunos parámetros del código de la clase fueron actualizados posteriormente y estaban generando un error y warnings en Visual Studio Code. Ajusté los cambios con los parámetros actualizados a hoy (27 de julio de 2023). Espero que a alguien le sirva.
import pandas as pd
from sklearn.model_selectionimportRandomizedSearchCVfrom sklearn.ensembleimportRandomForestRegressorif __name__ =="__main__": dataset = pd.read_csv('./data/felicidad.csv')print(dataset)X= dataset.drop(['country','rank','score'], axis=1) y = dataset['score'].values.ravel() reg =RandomForestRegressor() parametros ={'n_estimators':range(4,16),'criterion':['squared_error','absolute_error'],'max_depth':range(2,11)} rand_est =RandomizedSearchCV(reg, parametros , n_iter=10, cv=3, scoring='neg_mean_absolute_error').fit(X,y)print(rand_est.best_estimator_)print(rand_est.best_params_)print(rand_est.predict(X.loc[[0]]))
#implmentacion_randomizedSearchCV
Cambiaron 'mse' y 'mae' respectivamente
parametros ={'n_estimators':range(4,16),'criterion':['squared_error','absolute_error'],'max_depth':range(2,11)}# definición de parámetros que vamos a revisar
Aquí tienes el código implementado con GridSearchCV:
import pandas as pd
from sklearn.model_selectionimportGridSearchCVfrom sklearn.ensembleimportRandomForestRegressorif __name__ =="__main__": # Leer el dataset
dataset = pd.read_csv('./data/felicidad.csv') # Imprimir el dataset para verificar la carga
print(dataset) # Seleccionarcaracterísticas(X) y etiquetas(y)X= dataset.drop(['country','rank','score'], axis=1) y = dataset['score'] # Inicializar el regresor RandomForestRegressor reg =RandomForestRegressor() # Definir los parámetros para la búsqueda en cuadrícula
parametros ={ # Número de árboles en el bosque
'n_estimators':[10,50,100], # Criterio utilizado para medir la calidad de una división
'criterion':['mse','mae'], # 'mse': error cuadrático medio,'mae': error absoluto medio
# Profundidad máxima de los árboles en el bosque
'max_depth':[None,10,20], # Número mínimo de muestras requeridas para dividir un nodo interno
'min_samples_split':[2,5,10], # Número mínimo de muestras requeridas para estar en un nodo hoja
'min_samples_leaf':[1,2,4], # Método para la selección de características en cada split
'max_features':['auto','sqrt','log2'], # 'auto':sqrt(num_features),'sqrt':sqrt(num_features),'log2':log2(num_features) # Bootstrap muestras al construir árboles
'bootstrap':[True,False], # True: usar bootstrap samples,False: usar el dataset completo
} # Realizar la búsqueda en cuadrícula de hiperparámetros
grid_est =GridSearchCV(reg, parametros, cv=3, scoring='neg_mean_absolute_error').fit(X, y) # Imprimir el mejor estimador encontrado
print("Mejor estimador:")print(grid_est.best_estimator_) # Imprimir los mejores parámetros encontrados
print("Mejores parámetros:")print(grid_est.best_params_) # Realizar una predicción utilizando el mejor modelo encontrado
print("Predicción para el primer ejemplo del dataset:")print(grid_est.predict(X.loc[[0]]))```import pandas as pd
from sklearn.model\_selection import GridSearchCV
from sklearn.ensemble import RandomForestRegressor
if \_\_name\_\_ == "\_\_main\_\_":
  \# Leer el dataset
  dataset = pd.read\_csv('./data/felicidad.csv')
  \# Imprimir el dataset para verificar la carga
  print(dataset)
  \# Seleccionar características (X) y etiquetas (y)
  X = dataset.drop(\['country', 'rank', 'score'], axis=1)
  y = dataset\['score']
  \# Inicializar el regresor RandomForestRegressor
  reg = RandomForestRegressor()
  \# Definir los parámetros para la búsqueda en cuadrícula
  parametros = {
  \# Número de árboles en el bosque
  'n\_estimators': \[10, 50, 100],
  \# Criterio utilizado para medir la calidad de una división
  'criterion': \['mse', 'mae'], # 'mse': error cuadrático medio, 'mae': error absoluto medio
  \# Profundidad máxima de los árboles en el bosque
  'max\_depth': \[None, 10, 20],
  \# Número mínimo de muestras requeridas para dividir un nodo interno
  'min\_samples\_split': \[2, 5, 10],
  \# Número mínimo de muestras requeridas para estar en un nodo hoja
  'min\_samples\_leaf': \[1, 2, 4],
  \# Método para la selección de características en cada split
  'max\_features': \['auto', 'sqrt', 'log2'], # 'auto': sqrt(num\_features), 'sqrt': sqrt(num\_features), 'log2': log2(num\_features)
  \# Bootstrap muestras al construir árboles
  'bootstrap': \[True, False], # True: usar bootstrap samples, False: usar el dataset completo
  }
  \# Realizar la búsqueda en cuadrícula de hiperparámetros
  grid\_est = GridSearchCV(reg, parametros, cv=3, scoring='neg\_mean\_absolute\_error').fit(X, y)
  \# Imprimir el mejor estimador encontrado
  print("Mejor estimador:")
  print(grid\_est.best\_estimator\_)
  \# Imprimir los mejores parámetros encontrados
  print("Mejores parámetros:")
  print(grid\_est.best\_params\_)
  \# Realizar una predicción utilizando el mejor modelo encontrado
  print("Predicción para el primer ejemplo del dataset:")
  print(grid\_est.predict(X.loc\[\[0]]))
Este código utiliza `GridSearchCV` en lugar de `RandomizedSearchCV`.Los parámetros y su rango son especificados manualmente para realizar una búsqueda exhaustiva sobre todas las combinaciones posibles de parámetros dentro del rango especificado.Esto puede ser útil si la cantidad de combinaciones es manejable y no demasiado grande.
Parametros de GridSearchCV
estimator: el modelo que está utilizando.
params_grid: el objeto de diccionario que contiene los hiperparámetros que desea probar.
scoring: métrica de evaluación
cv: número de validaciones cruzadas para cada conjunto de hiperparámetros
verbose: cuanto más alto, más mensajes se imprimirán.
n_jobs: número de trabajos que se ejecutarán en paralelo
pre_dispatch: controla el número de trabajos que se pueden realizar en paralelo (para evitar problemas de memoria)
iid: asume que los datos se distribuyen de forma idéntica e independiente. El valor predeterminado es falso.
refit: una vez que se encuentran los mejores parámetros, reajuste el estimador
error_score: valor para asignar al puntaje si ocurre un error al ajustar el estimador
return_train_score: incluya puntajes de tren en cv_results_
utilizando python 3.9 solo cuando cambié la forma de los datos objetivo quitando un par de corchetes pude correrlo adecuadamente (y=dataset["score"])
Tengo este error:
y no sé como solucionarlo, me ayudan ?
Mmmm el problema dice que se esperaba un arreglo 1d
Creo que se puede arreglar si cambias:
y = dataset[['score']]
por
y = dataset['score']
no es ningun error estas obteniendo la prediccion correctamente
En versiones más recientes de scikit-learn, las opciones para criterion en RandomForestRegressor han cambiado. El criterio mse (mean squared error) fue renombrado a squared_error, y el criterio mae (mean absolute error) fue renombrado a absolute_error. En:
parametros = {
'n_estimators': range(4,16),
'criterion': ['squared_error','absolute_error'],
'max_depth': range(2,11)
}
En la parte del código de los parámetros se debe reemplazar por este código, ya que los parámetros de criterion están descontinuados y sale error.
RandomizedSearchCV es una técnica de búsqueda de hiperparámetros que realiza una búsqueda aleatoria en lugar de una búsqueda exhaustiva como GridSearchCV. Esto es útil cuando tienes una gran cantidad de posibles combinaciones de hiperparámetros y deseas encontrar una configuración de hiperparámetros óptima de manera más eficiente.
La clase se centró en la implementación de la optimización paramétrica utilizando el método Randomized, específicamente aplicado a un modelo de regresión con Random Forest en scikit-learn. Se abordaron los pasos para cargar datos, definir un estimador y crear una grilla de parámetros para optimización. La técnica permite ahorrar tiempo en la selección de modelos, usando validación cruzada y métricas adecuadas para evaluar el rendimiento. Se realizó una predicción para validar el modelo optimizado, destacando su eficacia en comparación con estimaciones previas.
Yo le hice unas pequeñas variaciones para que el resultado en la terminal sea más legible:
import pandas as pd
from sklearn.ensemble import RandomForestRegressor
from sklearn.model_selection import RandomizedSearchCV
if __name__ =="__main__": data = pd.read_csv('./data/felicidad.csv') X = data.drop(['country','rank','score'], axis=1) y = data['score'] reg = RandomForestRegressor() parametros ={'n_estimators':range(4,16),'criterion':['squared_error','absolute_error'],'max_depth':range(2,11)} rand_est = RandomizedSearchCV(reg, parametros, n_iter=10, cv=3, scoring='neg_mean_absolute_error').fit(X, y)print(f"The best estimators are {rand_est.best_estimator_}")print(f"The best params are {rand_est.best_params_}")print(f"The prediction of score to the firs country is {rand_est.predict(X.loc[[0]])}")print(data.head(3))
Falto realizar el SPLIT de los datos.
X_train,X_test, y_train, y_test =train_test_split(X, y, test_size=0.25, random_state=42)
No amigo, porque recuerda que estamos haciendo cross validation con 3 particiones de los datos (cv=3), lo cual indica que ya se está trabajando con todas las combinaciones posibles con 2 partes de los datos como training y la otra parte como testing.
Es exactamente lo que NO hay que hacer.
¡Acá por fin quitó la columna 'rank'!
cross_val_score o KFold
¿Tienen una aplicación que no tenga que ver con la optimización de parámetros?
Buena pregunta.
Sugerencia de scipy.stats randint , usen randint para que no vaya por todo el range sino que aleatoriamente seleccione los parámetros así hay mas aleatoriedad