Foto de Harry Grout en Unsplash El preprocesamiento de datos es un paso fundamental en una canalización de aprendizaje automático. Depende del algoritmo que se utilice pero, en general, no podemos o no debemos esperar que los algoritmos funcionen bien con los datos sin procesar. Incluso los modelos bien estructurados pueden no producir resultados aceptables si los datos sin procesar no se procesan correctamente. Algunos podrían considerar utilizando el término preparación de datos para cubrir las operaciones de limpieza y preprocesamiento de datos. El enfoque de este artículo es la parte de preprocesamiento de datos. Por ejemplo, algunos algoritmos requieren que las características numéricas se escalen a niveles similares. De lo contrario, tienden a dar más importancia a las características que tienen un rango de valor más alto. Considere una tarea de predicción del precio de la vivienda. El área de las casas por lo general varía entre 1000 y 2000 pies cuadrados mientras que la edad es menor de 50 en la mayoría de los casos. Lo que haríamos para evitar que un modelo de aprendizaje automático le dé más importancia al área de la casa es escalar estas características para que se encuentren entre un valor mínimo y máximo dado, como entre 0 y 1. Este proceso se llama MinMaxScaling. Repasaremos 4 operaciones de preprocesamiento de datos de uso común, incluidos fragmentos de código que explican cómo hacerlo con Scikit-learn. Usaremos un conjunto de datos de rotación bancaria, que está disponible en Kaggle con una licencia creative commons. Siéntase libre de descargarlo y seguirlo. Importe pandas como pd# Lea el conjunto de datos (solo 5 columnas) en un Pandas DataFrame
abandono = pd.read_csv(
“BankChurners.csv”,
usecols=[“Attrition_Flag”, “Marital_Status”, “Card_Category”, “Customer_Age”, “Total_Trans_Amt”]
)churn.cabeza()Las primeras 5 filas del DataFrame (imagen del autor) Una cosa muy importante a mencionar aquí es la división entre pruebas, que es de crucial importancia para evaluar el rendimiento del modelo. Al igual que entrenamos modelos con datos, medimos sus precisiones con datos. Pero no podemos usar los mismos datos para el entrenamiento y la prueba. Antes de entrenar el modelo, debemos reservar algunos datos para la prueba. Esto se conoce como división de prueba de tren y debe realizarse antes de cualquier operación de preprocesamiento de datos. De lo contrario, estaríamos provocando una fuga de datos, lo que básicamente significa que el modelo aprende sobre las propiedades de los datos de prueba. Por lo tanto, todas las operaciones siguientes deben realizarse después de la división de prueba de tren. Considere que el DataFrame que tenemos (abandono) solo incluye los datos de entrenamiento. Es muy probable que los conjuntos de datos de la vida real incluyan algunos valores faltantes. Hay dos enfoques para manejarlos, que consisten en descartar los valores faltantes y reemplazarlos con valores adecuados. En general, este último es mejor porque los datos son el activo más valioso en el producto basado en datos y no queremos desperdiciarlos. El valor adecuado para reemplazar un valor faltante depende de las características y la estructura del conjunto de datos. El conjunto de datos que estamos usando no tiene ningún valor faltante, así que agreguemos algunos a propósito para demostrar cómo manejarlos. Importar numpy como npchurn.iloc[np.random.randint(0, 1000, size=25), 1] = np.nan
churn.iloc[np.random.randint(0, 1000, size=25), 4] = np.nanchurn.isna().sum()# salida
Desgaste_Flag 0
Cliente_Edad 24
Estado civil 0
Tarjeta_Categoría 0
Importe_trans_total 24
dtype: int64 En el fragmento de código anterior, se usa una matriz NumPy con 25 enteros aleatorios para seleccionar el índice de las filas cuyo valor en la segunda y quinta columna se reemplaza con un valor faltante (np.nan). En la salida, vemos que hay 24 valores faltantes en estas columnas porque las matrices NumPy se generan aleatoriamente y pueden incluir valores duplicados. Para manejar estos valores faltantes, podemos usar la clase SimpleImputer, que es un ejemplo de imputación de características univariadas. El imputador simple proporciona estrategias básicas para imputar valores faltantes, que se pueden imputar con un valor constante proporcionado, o usando las estadísticas (media, mediana o más frecuente) de cada columna en la que se encuentran los valores faltantes. Usemos el valor medio de la columna para reemplazar los valores faltantes.de sklearn.imputar importar SimpleImputer# Crear un imputer
imputer = SimpleImputer(missing_values=np.nan, estrategia=’media’)# Aplicarlo a las columnas numéricas
numeric_features = [“Customer_Age”, “Total_Trans_Amt”]
batir[numeric_features] = imputer.fit_transform(abandono[numeric_features])churn.isna().sum()# salida
Desgaste_Flag 0
Cliente_Edad 0
Estado civil 0
Tarjeta_Categoría 0
Importe_trans_total 0
dtype: int64 En el fragmento de código anterior, se crea un objeto de imputación simple con estrategia media, lo que significa que imputa los valores faltantes utilizando el valor medio de la columna. Luego, lo usamos para reemplazar los valores faltantes en las columnas de edad del cliente y monto total de la transacción. Scikit-learn también proporciona métodos más sofisticados para imputar valores faltantes. Por ejemplo, la clase IterativeImputer es un ejemplo de imputación de características multivariante y modela cada característica con valores faltantes en función de otras características, y usa esa estimación para la imputación. Mencionamos que una característica que tiene un rango de valores más alto en comparación con otras características se le podría dar más importancia, lo que podría inducir a error. Además, los modelos tienden a funcionar mejor y convergen más rápido cuando las características están en una escala relativamente similar. Una opción para manejar características con rangos de valores muy diferentes es la estandarización, que básicamente significa transformar los datos para centrarlos eliminando el valor medio de cada característica. , luego escálelo dividiendo las características no constantes por su desviación estándar. Las características resultantes tienen una desviación estándar de 1 y una media muy cercana a cero. Por lo tanto, terminamos teniendo características (es decir, variables o columnas en un conjunto de datos) que tienen una distribución casi normal. Apliquemos la clase StandardScaler de Scikit-learn a las columnas de edad del cliente y monto total de la transacción. Como vemos en el resultado a continuación, estas dos columnas tienen rangos de valores muy diferentes. Churn[[“Customer_Age”, “Total_Trans_Amt”]].cabeza()(imagen del autor) Apliquemos la estandarización en estas características y verifiquemos los valores después. from sklearn.preprocessing import StandardScaler# Crear un objeto escalador
scaler = StandardScaler()# Ajustar datos de entrenamiento
scaler.fit(abandono[[“Customer_Age”, “Total_Trans_Amt”]])# Transformar los valores de las características
batir[[“Customer_Age”, “Total_Trans_Amt”]]= scaler.transform(abandono[[“Customer_Age”, “Total_Trans_Amt”]])# Mostrar las características transformadas
batir[[“Customer_Age”, “Total_Trans_Amt”]].cabeza()(imagen del autor) También verifiquemos la desviación estándar y el valor medio de una función transformada. Churn[“Customer_Age”].aplicar([“mean”, “std”])# producción
media -7.942474e-16
estándar 1.000049e+00
Nombre: Customer_Age, dtype: float64La desviación estándar es 1 y la media está muy cerca de 0 como se esperaba. Otra forma de llevar los rangos de valores a un nivel similar es escalarlos a un rango específico. Por ejemplo, podemos comprimir cada columna entre 0 y 1 de manera que los valores mínimo y máximo antes de escalar se conviertan en 0 y 1 después de escalar. Este tipo de escalado se puede lograr con MinMaxScaler de Scikit-learn.from sklearn.preprocessing import MinMaxScaler# Crear un objeto escalador
mm_scaler = MinMaxScaler()# Ajustar datos de entrenamiento
mm_scaler.fit(abandono[[“Customer_Age”, “Total_Trans_Amt”]])# Transformar los valores de las características
batir[[“Customer_Age”, “Total_Trans_Amt”]]= mm_scaler.transform(abandono[[“Customer_Age”, “Total_Trans_Amt”]])# comprobar el rango de valores de la característica después de la transformación
batir[“Customer_Age”].aplicar([“min”, “max”])# producción
mínimo 0.0
máx. 1,0
Nombre: Customer_Age, dtype: float64Como vemos en el resultado anterior, los valores mínimo y máximo de estas características son 0 y 1, respectivamente. El rango predeterminado para MinMaxScaler es [0,1] pero podemos cambiarlo usando el parámetro feature_range. StandardScaler y MinMaxScaler no son resistentes a los valores atípicos. Considere que tenemos una función cuyos valores están entre 100 y 500 con un valor excepcional de 25000. Si escalamos esta función con MinMaxScaler(feature_range=(0,1)), 25000 se escala como 1 y todos los demás valores se acercan mucho al límite inferior que es cero. Así, terminamos teniendo una escala desproporcionada que afecta negativamente el rendimiento de un modelo. Una solución es eliminar los valores atípicos y luego aplicar la escala. Sin embargo, puede que no siempre sea una buena práctica eliminar los valores atípicos. En tales casos, podemos usar la clase RobustScaler de Scikit-learn. RobustScaler, como sugiere el nombre, es resistente a los valores atípicos. Elimina la mediana y escala los datos de acuerdo con el rango del cuantil (predeterminado en IQR: rango intercuartílico). El IQR es el rango entre el primer cuartil (cuartil 25) y el tercer cuartil (cuartil 75). RobustScaler no limita el rango escalado por un intervalo predeterminado. Por lo tanto, no necesitamos especificar un rango como lo hacemos para MinMaxScaler. A menudo trabajamos con conjuntos de datos que tienen características categóricas, que también requieren un procesamiento previo al igual que las características numéricas. Algunos algoritmos esperan las variables categóricas en formato numérico o codificado en caliente. . La codificación de etiquetas simplemente significa convertir categorías en números. Por ejemplo, una característica de tamaño que tiene los valores S, M y L se convertirá en una característica con valores 1, 2 y 3. Si una variable categórica no es ordinal (es decir, no hay un orden jerárquico en ellas) , la codificación de etiquetas no es suficiente. Necesitamos codificar las variables categóricas nominales utilizando la codificación one-hot. Considere el ejemplo anterior donde hicimos la codificación de etiquetas en la función de estado civil. El estado desconocido se codifica en 3, mientras que el estado casado es 1. Un modelo de aprendizaje automático podría evaluar esto como que el estado desconocido es superior o superior al estado casado, lo cual no es cierto. No existe una relación jerárquica entre estos valores. En tales casos, es mejor realizar una codificación one-hot, que crea una columna binaria para cada categoría. Apliquémoslo a la columna de estado civil. from sklearn.preprocessing import OneHotEncoder# Crear un codificador one-hot
onehot = OneHotEncoder()# Crear una función codificada
encoded_features = onehot.fit_transform(churn[[“Marital_Status”]]).toarray()# Crear DataFrame con las características codificadas
encoded_df = pd.DataFrame(encoded_features, column=onehot.categories_)# Mostrar las primeras 5 filas
codificado_df.head()(imagen del autor) Como hay 4 valores diferentes en la columna de estado civil (Divorciado, Casado, Soltero, Desconocido), se crean 4 columnas binarias. El primer valor de la columna de estado civil es “Casado”, por lo que la columna Casado toma el valor 1 en la primera fila. Todos los demás valores en la primera fila son 0. Una cosa importante a mencionar es el parámetro de caída. Si hay n valores distintos en una columna categórica, podemos hacer una codificación one-hot con n-1 columnas porque una de las columnas es realmente redundante. Por ejemplo, en el resultado anterior, cuando el valor de 3 columnas es 0, entonces esa fila pertenece a la cuarta columna. En realidad, no necesitamos la cuarta columna para saber esto. Podemos usar el parámetro drop de OneHotEncoder para soltar una de las columnas. Hemos aprendido algunas de las operaciones de preprocesamiento de datos más frecuentes en el aprendizaje automático y cómo realizarlas usando la biblioteca Scikit-learn. Puede convertirse en miembro de Medium para desbloquear acceso total a mis escritos, además del resto de Medium. Si ya lo eres, no olvides suscribirte si deseas recibir un correo electrónico cada vez que publique un nuevo artículo. Gracias por leer. Por favor, hágamelo saber si tiene algún comentario.
Los días felices de la PDA y Blackberry han quedado definitivamente atrás, pero el factor…
Tutorial sobre cómo pronosticar usando un modelo autorregresivo en PythonFoto de Aron Visuals en UnsplashForecasting…
Si tienes un iPhone, los AirPods Pro son la opción obvia para escuchar música, ¡aunque…
Ilustración de Alex Castro / The Verge Plus nuevos rumores sobre el quinto Galaxy Fold.…
Se rumorea que los auriculares premium de próxima generación de Apple, los AirPods Max 2,…
El desarrollador Motive Studio y el editor EA han lanzado un nuevo tráiler de la…