Muchas tareas de clasificación binaria no tienen el mismo número de ejemplos de cada clase, por ejemplo, la distribución de la clase está sesgada o desequilibrada.
Un ejemplo popular es el conjunto de datos de ingresos de adultos que implica predecir los niveles de ingresos personales por encima o por debajo de $ 50,000 por año en función de detalles personales como la relación y el nivel de educación. Hay muchos más casos de ingresos inferiores a 50 dólares que por encima de 50 dólares, aunque el sesgo no es grave.
Esto significa que se pueden utilizar técnicas para la clasificación desequilibrada, mientras que el rendimiento del modelo todavía se puede informar utilizando la precisión de clasificación, como se utiliza con los problemas de clasificación equilibrada.
En este tutorial, descubrirá cómo desarrollar y evaluar un modelo para el conjunto de datos de clasificación de ingresos de adultos desequilibrados.
Después de completar este tutorial, sabrá:
- Cómo cargar y explorar el conjunto de datos y generar ideas para la preparación de datos y la selección del modelo.
- Cómo evaluar sistemáticamente un conjunto de modelos de aprendizaje automático con un arnés de prueba robusto.
- Cómo ajustar un modelo final y usarlo para predecir etiquetas de clase para casos específicos.
Descubra SMOTE, clasificación de una clase, aprendizaje sensible al costo, movimiento de umbral y mucho más en mi nuevo libro, con 30 tutoriales paso a paso y el código fuente completo de Python.
Empecemos.
Resumen del tutorial
Este tutorial está dividido en cinco partes; son:
- Conjunto de datos de ingresos de adultos
- Explore el conjunto de datos
- Prueba de modelo y resultado de referencia
- Evaluar modelos
- Hacer predicciones sobre nuevos datos
Conjunto de datos de ingresos de adultos
En este proyecto, utilizaremos un conjunto de datos de aprendizaje automático desequilibrado estándar denominado "Ingresos adultos"O simplemente el"adulto"Conjunto de datos.
El conjunto de datos se atribuye a Ronny Kohavi y Barry Becker y se extrajo de 1994 Oficina del Censo de los Estados Unidos datos e implica el uso de datos personales, como el nivel educativo, para predecir si una persona ganará más o menos de $ 50,000 por año.
El conjunto de datos para adultos es de la Oficina del Censo y la tarea es predecir si un adulto determinado gana más de $ 50,000 al año en función de atributos como educación, horas de trabajo por semana, etc.
- Ampliación de la precisión de los clasificadores Naive-bayes: un árbol de decisiones híbrido, 1996.
El conjunto de datos proporciona 14 variables de entrada que son una mezcla de tipos de datos categóricos, ordinales y numéricos. La lista completa de variables es la siguiente:
- Años.
- Clase de trabajo.
- Peso final.
- Educación.
- Educación Número de años.
- Estado civil.
- Ocupación.
- Relación.
- Carrera.
- Sexo.
- Ganancia capital.
- Perdida de capital.
- Horas por semana.
- Patria.
El conjunto de datos contiene valores faltantes que están marcados con un signo de interrogación (?).
Hay un total de 48,842 filas de datos y 3,620 con valores perdidos, lo que deja 45,222 filas completas.
Hay dos valores de clase '> 50K'Y'<= 50 K', lo que significa que es una tarea de clasificación binaria. Las clases están desequilibradas, con un sesgo hacia el '<= 50 K'etiqueta de clase.
- '> 50K': clase mayoritaria, aproximadamente el 25%.
- '<= 50 K': clase minoritaria, aproximadamente el 75%.
Dado que el desequilibrio de clases no es severo y que ambas etiquetas de clase son igualmente importantes, es común utilizar la precisión de clasificación o el error de clasificación para informar el rendimiento del modelo en este conjunto de datos.
Utilizando conjuntos de pruebas y trenes predefinidos, el error de clasificación correcto informado es de aproximadamente el 14 por ciento o una precisión de clasificación de aproximadamente el 86 por ciento. Esto podría proporcionar un objetivo al que apuntar cuando se trabaja en este conjunto de datos.
A continuación, echemos un vistazo más de cerca a los datos.
¿Quiere comenzar con la clasificación de desequilibrio?
Tome mi curso gratuito de 7 días por correo electrónico ahora (con código de muestra).
Haga clic para registrarse y también obtenga una versión gratuita en PDF del libro.
Explore el conjunto de datos
El conjunto de datos para adultos es un conjunto de datos de aprendizaje automático estándar ampliamente utilizado, que se utiliza para explorar y demostrar muchos algoritmos de aprendizaje automático, tanto en general como aquellos diseñados específicamente para la clasificación desequilibrada.
Primero, descargue el conjunto de datos y guárdelo en su directorio de trabajo actual con el nombre "adulto-todo.csv"
Revise el contenido del archivo.
Las primeras líneas del archivo deberían tener el siguiente aspecto:
39,State-gov,77516,Bachelors,13,Never-married,Adm-clerical,Not-in-family,White,Male,2174,0,40,United-States,<=50K 50,Self-emp-not-inc,83311,Bachelors,13,Married-civ-spouse,Exec-managerial,Husband,White,Male,0,0,13,United-States,<=50K 38,Private,215646,HS-grad,9,Divorced,Handlers-cleaners,Not-in-family,White,Male,0,0,40,United-States,<=50K 53,Private,234721,11th,7,Married-civ-spouse,Handlers-cleaners,Husband,Black,Male,0,0,40,United-States,<=50K 28,Private,338409,Bachelors,13,Married-civ-spouse,Prof-specialty,Wife,Black,Female,0,0,40,Cuba,<=50K … |
Podemos ver que las variables de entrada son una mezcla de tipos de datos numéricos y categóricos u ordinales, donde las columnas no numéricas se representan mediante cadenas. Como mínimo, las variables categóricas deberán ser ordinales o codificadas de forma única.
También podemos ver que la variable de destino se representa mediante cadenas. Esta columna deberá tener una etiqueta codificada con 0 para la clase mayoritaria y 1 para la clase minoritaria, como es costumbre para las tareas de clasificación binaria desequilibrada.
Los valores que faltan están marcados con un '?' personaje. Estos valores deberán ser imputados, o dada la pequeña cantidad de ejemplos, estas filas podrían eliminarse del conjunto de datos.
El conjunto de datos se puede cargar como Marco de datos usando el read_csv () Función de pandas, especificando el nombre del archivo, que no hay una línea de encabezado y que cadenas como ' ?'debe ser analizado como Yaya (valores faltantes.
... # define the dataset location filename = ‘adult-all.csv’ # load the csv file as a data frame dataframe = read_csv(filename, header=None, na_values=‘?’) |
Una vez cargados, podemos eliminar las filas que contienen uno o más valores perdidos.
... # drop rows with missing dataframe = dataframe.dropna() |
Podemos resumir el número de filas y columnas imprimiendo la forma del DataFrame.
... # summarize the shape of the dataset print(dataframe.shape) |
También podemos resumir el número de ejemplos en cada clase usando el Objeto contador.
... # summarize the class distribution target = dataframe.values[:,–1] counter = Counter(target) for k,v in counter.items(): per = v / len(target) * 100 print(‘Class=%s, Count=%d, Percentage=%.3f%%’ % (k, v, per)) |
Al unir esto, el ejemplo completo de carga y resumen del conjunto de datos se enumera a continuación.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
# load and summarize the dataset from pandas import read_csv from collections import Counter # define the dataset location filename = ‘adult-all.csv’ # load the csv file as a data frame dataframe = read_csv(filename, header=None, na_values=‘?’) # drop rows with missing dataframe = dataframe.dropna() # summarize the shape of the dataset print(dataframe.shape) # summarize the class distribution target = dataframe.values[:,–1] counter = Counter(target) for k,v in counter.items(): per = v / len(target) * 100 print(‘Class=%s, Count=%d, Percentage=%.3f%%’ % (k, v, per)) |
Al ejecutar el ejemplo, primero se carga el conjunto de datos y se confirma el número de filas y columnas, es decir, 45,222 14 filas sin valores perdidos y XNUMX variables de entrada y una variable de destino.
Luego se resume la distribución de clases, lo que confirma un modesto desequilibrio de clases con aproximadamente el 75 por ciento para la clase mayoritaria (<= 50K) y aproximadamente el 25 por ciento para la clase minoritaria (> 50K).
(45222, 15) Class= <=50K, Count=34014, Percentage=75.216% Class= >50K, Count=11208, Percentage=24.784% |
También podemos echar un vistazo a la distribución de las variables de entrada numéricas creando un histograma para cada una.
Primero, podemos seleccionar las columnas con variables numéricas llamando al función select_dtypes () en el DataFrame. Luego podemos seleccionar solo esas columnas del DataFrame.
... # select columns with numerical data types num_ix = df.select_dtypes(include=[‘int64’, ‘float64’]).columns # select a subset of the dataframe with the chosen columns subset = df[num_ix] |
Luego podemos crear histogramas de cada variable de entrada numérica. El ejemplo completo se enumera a continuación.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
# create histograms of numeric input variables from pandas import read_csv from matplotlib import pyplot # define the dataset location filename = ‘adult-all.csv’ # load the csv file as a data frame df = read_csv(filename, header=None, na_values=‘?’) # drop rows with missing df = df.dropna() # select columns with numerical data types num_ix = df.select_dtypes(include=[‘int64’, ‘float64’]).columns # select a subset of the dataframe with the chosen columns subset = df[num_ix] # create a histogram plot of each numeric variable subset.hist() pyplot.show() |
Al ejecutar el ejemplo, se crea la figura con una subparcela de histograma para cada una de las seis variables de entrada en el conjunto de datos. El título de cada subparcela indica el número de columna en el DataFrame (por ejemplo, compensación cero).
Podemos ver muchas distribuciones diferentes, algunas con distribuciones similares a las de Gauss, otras con distribuciones aparentemente exponenciales o discretas. También podemos ver que todos parecen tener una escala muy diferente.
Dependiendo de la elección de los algoritmos de modelado, sería de esperar que la distribución de las distribuciones al mismo rango sea útil, y tal vez el uso de algunas transformaciones de potencia.
Ahora que hemos revisado el conjunto de datos, veamos cómo desarrollar un arnés de prueba para evaluar los modelos candidatos.
Prueba de modelo y resultado de referencia
Evaluaremos los modelos candidatos mediante validación cruzada estratificada repetida de k veces.
El proyecto procedimiento de validación cruzada k-fold proporciona una buena estimación general del rendimiento del modelo que no tiene un sesgo demasiado optimista, al menos en comparación con una sola división de prueba de tren. Usaremos k = 10, lo que significa que cada pliegue contendrá aproximadamente 45,222 10/4,522, o aproximadamente XNUMX ejemplos.
Estratificado significa que cada pliegue contendrá la misma mezcla de ejemplos por clase, es decir, aproximadamente del 75 al 25 por ciento para las clases mayoritarias y minoritarias respectivamente. Repetido significa que el proceso de evaluación se realizará varias veces para ayudar a evitar resultados fortuitos y capturar mejor la varianza del modelo elegido. Usaremos tres repeticiones.
Esto significa que un solo modelo se ajustará y evaluará 10 * 3 o 30 veces y se informará la media y la desviación estándar de estas corridas.
Esto se puede lograr usando el Repetido Estratificado K Plegado clase scikit-learn.
Predeciremos una etiqueta de clase para cada ejemplo y mediremos el rendimiento del modelo utilizando la precisión de clasificación.
El proyecto evalúe_modelo () La función a continuación tomará el conjunto de datos cargado y un modelo definido y lo evaluará usando una validación cruzada estratificada repetida de k-veces, luego devolverá una lista de puntuaciones de precisión que luego se pueden resumir.
# evaluate a model def evaluate_model(X, y, model): # define evaluation procedure cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1) # evaluate model scores = cross_val_score(model, X, y, scoring=‘accuracy’, cv=cv, n_jobs=–1) return scores |
Podemos definir una función para cargar el conjunto de datos y codificar la etiqueta de la columna de destino.
También devolveremos una lista de columnas categóricas y numéricas en caso de que decidamos transformarlas más adelante al ajustar modelos.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
# load the dataset def load_dataset(full_path): # load the dataset as a numpy array dataframe = read_csv(full_path, header=None, na_values=‘?’) # drop rows with missing dataframe = dataframe.dropna() # split into inputs and outputs last_ix = len(dataframe.columns) – 1 X, y = dataframe.drop(last_ix, axis=1), dataframe[last_ix] # select categorical and numerical features cat_ix = X.select_dtypes(include=[‘object’, ‘bool’]).columns num_ix = X.select_dtypes(include=[‘int64’, ‘float64’]).columns # label encode the target variable to have the classes 0 and 1 y = LabelEncoder().fit_transform(y) return X.values, y, cat_ix, num_ix |
Finalmente, podemos evaluar un modelo de referencia en el conjunto de datos utilizando este arnés de prueba.
Cuando se usa la precisión de clasificación, un modelo ingenuo predecirá la clase mayoritaria para todos los casos. Esto proporciona una línea de base en el rendimiento del modelo sobre este problema mediante la cual se pueden comparar todos los demás modelos.
Esto se puede lograr usando el Clasificador ficticio clase de la biblioteca scikit-learn y establecer el "estrategia"Argumento a 'más frecuente'.
... # define the reference model model = DummyClassifier(strategy=‘most_frequent’) |
Una vez que se evalúa el modelo, podemos informar la desviación estándar y media de las puntuaciones de precisión directamente.
... # evaluate the model scores = evaluate_model(X, y, model) # summarize performance print(‘Mean Accuracy: %.3f (%.3f)’ % (mean(scores), std(scores))) |
Al unir esto, el ejemplo completo de cargar el conjunto de datos de adultos, evaluar un modelo de línea de base e informar el rendimiento se enumera a continuación.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
# test harness and baseline model evaluation for the adult dataset from collections import Counter from numpy import mean from numpy import std from numpy import hstack from pandas import read_csv from sklearn.preprocessing import LabelEncoder from sklearn.model_selection import cross_val_score from sklearn.model_selection import RepeatedStratifiedKFold from sklearn.dummy import DummyClassifier # load the dataset def load_dataset(full_path): # load the dataset as a numpy array dataframe = read_csv(full_path, header=None, na_values=‘?’) # drop rows with missing dataframe = dataframe.dropna() # split into inputs and outputs last_ix = len(dataframe.columns) – 1 X, y = dataframe.drop(last_ix, axis=1), dataframe[last_ix] # select categorical and numerical features cat_ix = X.select_dtypes(include=[‘object’, ‘bool’]).columns num_ix = X.select_dtypes(include=[‘int64’, ‘float64’]).columns # label encode the target variable to have the classes 0 and 1 y = LabelEncoder().fit_transform(y) return X.values, y, cat_ix, num_ix # evaluate a model def evaluate_model(X, y, model): # define evaluation procedure cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1) # evaluate model scores = cross_val_score(model, X, y, scoring=‘accuracy’, cv=cv, n_jobs=–1) return scores # define the location of the dataset full_path = ‘adult-all.csv’ # load the dataset X, y, cat_ix, num_ix = load_dataset(full_path) # summarize the loaded dataset print(X.shape, y.shape, Counter(y)) # define the reference model model = DummyClassifier(strategy=‘most_frequent’) # evaluate the model scores = evaluate_model(X, y, model) # summarize performance print(‘Mean Accuracy: %.3f (%.3f)’ % (mean(scores), std(scores))) |
La ejecución del ejemplo primero carga y resume el conjunto de datos.
Podemos ver que tenemos el número correcto de filas cargadas. Es importante destacar que podemos ver que las etiquetas de clase tienen el mapeo correcto a los números enteros, con 0 para la clase mayoritaria y 1 para la clase minoritaria, habitual para el conjunto de datos de clasificación binaria desequilibrado.
A continuación, se informa la puntuación de precisión de clasificación promedio.
En este caso, podemos ver que el algoritmo de la línea de base alcanza una precisión de alrededor del 75.2%. Esta puntuación proporciona un límite inferior en la habilidad del modelo; cualquier modelo que logre una precisión promedio superior al 75.2% tiene habilidad, mientras que los modelos que logran una puntuación por debajo de este valor no tienen habilidad en este conjunto de datos.
(45222, 14) (45222,) Counter({0: 34014, 1: 11208}) Mean Accuracy: 0.752 (0.000) |
Ahora que tenemos un arnés de prueba y una línea de base en rendimiento, podemos comenzar a evaluar algunos modelos en este conjunto de datos.
Evaluar modelos
En esta sección, evaluaremos un conjunto de técnicas diferentes en el conjunto de datos utilizando el arnés de prueba desarrollado en la sección anterior.
El objetivo es demostrar cómo resolver el problema sistemáticamente y demostrar la capacidad de algunas técnicas diseñadas para problemas de clasificación desequilibrados.
El rendimiento informado es bueno, pero no está altamente optimizado (por ejemplo, los hiperparámetros no están ajustados).
¿Puedes hacerlo mejor? Si puede lograr un mejor rendimiento de precisión de clasificación utilizando el mismo arnés de prueba, me encantaría saberlo. Déjame saber abajo en los comentarios.
Evaluar algoritmos de aprendizaje automático
Comencemos evaluando una combinación de modelos de aprendizaje automático en el conjunto de datos.
Puede ser una buena idea verificar un conjunto de algoritmos no lineales diferentes en un conjunto de datos para eliminar rápidamente lo que funciona bien y merece más atención, y lo que no.
Evaluaremos los siguientes modelos de aprendizaje automático en el conjunto de datos de adultos:
- Árbol de decisión (CARRITO)
- Máquina de vectores de soporte (SVM)
- Árboles de decisión en bolsas (BAG)
- Bosque aleatorio (RF)
- Máquina de refuerzo de gradiente (GBM)
Utilizaremos en su mayoría hiperparámetros de modelo predeterminados, con la excepción del número de árboles en los algoritmos de conjunto, que estableceremos en un valor predeterminado razonable de 100.
Definiremos cada modelo a su vez y los agregaremos a una lista para poder evaluarlos secuencialmente. los get_models () La función a continuación define la lista de modelos para evaluación, así como una lista de nombres cortos de modelos para trazar los resultados más adelante.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
# define models to test def get_models(): models, names = list(), list() # CART models.append(DecisionTreeClassifier()) names.append(‘CART’) # SVM models.append(SVC(gamma=‘scale’)) names.append(‘SVM’) # Bagging models.append(BaggingClassifier(n_estimators=100)) names.append(‘BAG’) # RF models.append(RandomForestClassifier(n_estimators=100)) names.append(‘RF’) # GBM models.append(GradientBoostingClassifier(n_estimators=100)) names.append(‘GBM’) return models, names |
Luego podemos enumerar la lista de modelos por turno y evaluar cada uno, almacenando los puntajes para una evaluación posterior.
Codificaremos one-hot las variables de entrada categóricas usando un OneHotEncoder, y normalizaremos las variables de entrada numéricas usando el Escalador MínMáx. Estas operaciones deben realizarse dentro de cada división de tren / prueba durante el proceso de validación cruzada, donde las operaciones de codificación y escalado se ajustan al conjunto de entrenamiento y se aplican al tren y a los conjuntos de prueba.
Una forma sencilla de implementar esto es utilizar un Tubería donde el primer paso es un Transformador de columna que aplica un OneHotEncoder a solo las variables categóricas, y un Escalador MínMáx a solo las variables de entrada numéricas. Para lograr esto, necesitamos una lista de los índices de columna para las variables de entrada categóricas y numéricas.
El proyecto load_dataset () La función que definimos en la sección anterior carga y devuelve tanto el conjunto de datos como las listas de columnas que tienen tipos de datos categóricos y numéricos. Esto se puede utilizar para preparar un Tubería para envolver cada modelo antes de evaluarlo. Primero el Transformador de columna está definido, que especifica qué transformación aplicar a cada tipo de columna, luego esto se usa como el primer paso en un Tubería que termina con el modelo específico que será ajustado y evaluado.
... # define steps steps = [(‘c’,OneHotEncoder(handle_unknown=‘ignore’),cat_ix), (‘n’,MinMaxScaler(),num_ix)] # one hot encode categorical, normalize numerical ct = ColumnTransformer(steps) # wrap the model i a pipeline pipeline = Pipeline(steps=[(‘t’,ct),(‘m’,models[i])]) # evaluate the model and store results scores = evaluate_model(X, y, pipeline) |
Podemos resumir la precisión media de cada algoritmo, esto ayudará a comparar directamente los algoritmos.
... # summarize performance print(‘>%s %.3f (%.3f)’ % (names[i], mean(scores), std(scores))) |
Al final de la ejecución, crearemos una gráfica de caja y bigotes separada para la muestra de resultados de cada algoritmo. Estas gráficas usarán la misma escala del eje y para que podamos comparar la distribución de resultados directamente.
... # plot the results pyplot.boxplot(results, labels=names, showmeans=True) pyplot.show() |
Uniendo todo esto, el ejemplo completo de evaluación de un conjunto de algoritmos de aprendizaje automático en el conjunto de datos desequilibrados para adultos se enumera a continuación.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
# spot check machine learning algorithms on the adult imbalanced dataset from numpy import mean from numpy import std from pandas import read_csv from matplotlib import pyplot from sklearn.preprocessing import LabelEncoder from sklearn.preprocessing import OneHotEncoder from sklearn.preprocessing import MinMaxScaler from sklearn.pipeline import Pipeline from sklearn.compose import ColumnTransformer from sklearn.model_selection import cross_val_score from sklearn.model_selection import RepeatedStratifiedKFold from sklearn.tree import DecisionTreeClassifier from sklearn.svm import SVC from sklearn.ensemble import RandomForestClassifier from sklearn.ensemble import GradientBoostingClassifier from sklearn.ensemble import BaggingClassifier # load the dataset def load_dataset(full_path): # load the dataset as a numpy array dataframe = read_csv(full_path, header=None, na_values=‘?’) # drop rows with missing dataframe = dataframe.dropna() # split into inputs and outputs last_ix = len(dataframe.columns) – 1 X, y = dataframe.drop(last_ix, axis=1), dataframe[last_ix] # select categorical and numerical features cat_ix = X.select_dtypes(include=[‘object’, ‘bool’]).columns num_ix = X.select_dtypes(include=[‘int64’, ‘float64’]).columns # label encode the target variable to have the classes 0 and 1 y = LabelEncoder().fit_transform(y) return X.values, y, cat_ix, num_ix # evaluate a model def evaluate_model(X, y, model): # define evaluation procedure cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1) # evaluate model scores = cross_val_score(model, X, y, scoring=‘accuracy’, cv=cv, n_jobs=–1) return scores # define models to test def get_models(): models, names = list(), list() # CART models.append(DecisionTreeClassifier()) names.append(‘CART’) # SVM models.append(SVC(gamma=‘scale’)) names.append(‘SVM’) # Bagging models.append(BaggingClassifier(n_estimators=100)) names.append(‘BAG’) # RF models.append(RandomForestClassifier(n_estimators=100)) names.append(‘RF’) # GBM models.append(GradientBoostingClassifier(n_estimators=100)) names.append(‘GBM’) return models, names # define the location of the dataset full_path = ‘adult-all.csv’ # load the dataset X, y, cat_ix, num_ix = load_dataset(full_path) # define models models, names = get_models() results = list() # evaluate each model for i in range(len(models)): # define steps steps = [(‘c’,OneHotEncoder(handle_unknown=‘ignore’),cat_ix), (‘n’,MinMaxScaler(),num_ix)] # one hot encode categorical, normalize numerical ct = ColumnTransformer(steps) # wrap the model i a pipeline pipeline = Pipeline(steps=[(‘t’,ct),(‘m’,models[i])]) # evaluate the model and store results scores = evaluate_model(X, y, pipeline) results.append(scores) # summarize performance print(‘>%s %.3f (%.3f)’ % (names[i], mean(scores), std(scores))) # plot the results pyplot.boxplot(results, labels=names, showmeans=True) pyplot.show() |
Ejecutar el ejemplo evalúa cada algoritmo a su vez e informa la precisión de la clasificación de desviación estándar y media.
Sus resultados específicos variarán dada la naturaleza estocástica de los algoritmos de aprendizaje; considere ejecutar el ejemplo varias veces.
¿Qué puntajes obtuviste?
Publique sus resultados en los comentarios a continuación.
En este caso, podemos ver que todos los algoritmos elegidos son hábiles, logrando una precisión de clasificación superior al 75.2%. Podemos ver que los algoritmos del árbol de decisiones por conjuntos funcionan mejor, quizás con un aumento de gradiente estocástico que rinde mejor con una precisión de clasificación de aproximadamente 86.3%.
Esto es ligeramente mejor que el resultado informado en el documento original, aunque con un procedimiento de evaluación del modelo diferente.
>CART 0.812 (0.005) >SVM 0.837 (0.005) >BAG 0.852 (0.004) >RF 0.849 (0.004) >GBM 0.863 (0.004) |
Se crea una figura que muestra un diagrama de caja y bigotes para la muestra de resultados de cada algoritmo. El cuadro muestra el 50 por ciento del medio de los datos, la línea naranja en el centro de cada cuadro muestra la mediana de la muestra y el triángulo verde en cada cuadro muestra la media de la muestra.
Podemos ver que la distribución de puntuaciones para cada algoritmo parece estar por encima de la línea de base de aproximadamente el 75%, quizás con algunos valores atípicos (círculos en la gráfica). La distribución de cada algoritmo parece compacta, con la mediana y la media alineadas, lo que sugiere que los modelos son bastante estables en este conjunto de datos y las puntuaciones no forman una distribución sesgada.
Esto resalta que no es solo la tendencia central del desempeño del modelo lo que es importante, sino también el diferencial e incluso el resultado en el peor de los casos lo que debe considerarse. Especialmente con un número limitado de ejemplos de la clase minoritaria.
Hacer predicciones sobre nuevos datos
En esta sección, podemos ajustar un modelo final y usarlo para hacer predicciones en filas individuales de datos.
Usaremos el GradientBoostingClasificador modelo como nuestro modelo final que logró una precisión de clasificación de aproximadamente el 86.3%. Ajustar el modelo final implica definir el Transformador de columna para codificar las variables categóricas y escalar las variables numéricas, luego construya una Tubería para realizar estas transformaciones en el conjunto de entrenamiento antes de ajustar el modelo.
El proyecto Tubería luego se puede usar para hacer predicciones sobre nuevos datos directamente, y automáticamente codificará y escalará nuevos datos usando las mismas operaciones que se realizaron en el conjunto de datos de entrenamiento.
Primero, podemos definir el modelo como una tubería.
... # define model to evaluate model = GradientBoostingClassifier(n_estimators=100) # one hot encode categorical, normalize numerical ct = ColumnTransformer([(‘c’,OneHotEncoder(),cat_ix), (‘n’,MinMaxScaler(),num_ix)]) # scale, then oversample, then fit model pipeline = Pipeline(steps=[(‘t’,ct), (‘m’,model)]) |
Una vez definido, podemos ajustarlo en todo el conjunto de datos de entrenamiento.
... # fit the model pipeline.fit(X, y) |
Una vez en forma, podemos usarlo para hacer predicciones para nuevos datos llamando al predecir() función. Esto devolverá la etiqueta de clase de 0 para "<= 50K", o 1 para "> 50K".
Es importante destacar que debemos utilizar el Transformador de columna en la pestaña Tubería para preparar correctamente nuevos datos utilizando las mismas transformaciones.
Por ejemplo:
... # define a row of data row = [...] # make prediction yhat = pipeline.predict([row]) |
Para demostrar esto, podemos usar el modelo de ajuste para hacer algunas predicciones de etiquetas para algunos casos en los que conocemos el resultado.
El ejemplo completo se enumera a continuación.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# fit a model and make predictions for the on the adult dataset from pandas import read_csv from sklearn.preprocessing import LabelEncoder from sklearn.preprocessing import OneHotEncoder from sklearn.preprocessing import MinMaxScaler from sklearn.compose import ColumnTransformer from sklearn.ensemble import GradientBoostingClassifier from imblearn.pipeline import Pipeline # load the dataset def load_dataset(full_path): # load the dataset as a numpy array dataframe = read_csv(full_path, header=None, na_values=‘?’) # drop rows with missing dataframe = dataframe.dropna() # split into inputs and outputs last_ix = len(dataframe.columns) – 1 X, y = dataframe.drop(last_ix, axis=1), dataframe[last_ix] # select categorical and numerical features cat_ix = X.select_dtypes(include=[‘object’, ‘bool’]).columns num_ix = X.select_dtypes(include=[‘int64’, ‘float64’]).columns # label encode the target variable to have the classes 0 and 1 y = LabelEncoder().fit_transform(y) return X.values, y, cat_ix, num_ix # define the location of the dataset full_path = ‘adult-all.csv’ # load the dataset X, y, cat_ix, num_ix = load_dataset(full_path) # define model to evaluate model = GradientBoostingClassifier(n_estimators=100) # one hot encode categorical, normalize numerical ct = ColumnTransformer([(‘c’,OneHotEncoder(),cat_ix), (‘n’,MinMaxScaler(),num_ix)]) # scale, then oversample, then fit model pipeline = Pipeline(steps=[(‘t’,ct), (‘m’,model)]) # fit the model pipeline.fit(X, y) # evaluate on some <=50K cases (known class 0) print(‘<=50K cases:’) data = [[24, ‘Private’, 161198, ‘Bachelors’, 13, ‘Never-married’, ‘Prof-specialty’, ‘Not-in-family’, ‘White’, ‘Male’, 0, 0, 25, ‘United-States’], [23, ‘Private’, 214542, ‘Some-college’, 10, ‘Never-married’, ‘Farming-fishing’, ‘Own-child’, ‘White’, ‘Male’, 0, 0, 40, ‘United-States’], [38, ‘Private’, 309122, ’10th’, 6, ‘Divorced’, ‘Machine-op-inspct’, ‘Not-in-family’, ‘White’, ‘Female’, 0, 0, 40, ‘United-States’]] for row in data: # make prediction yhat = pipeline.predict([row]) # get the label label = yhat[0] # summarize print(‘>Predicted=%d (expected 0)’ % (label)) # evaluate on some >50K cases (known class 1) print(‘>50K cases:’) data = [[55, ‘Local-gov’, 107308, ‘Masters’, 14, ‘Married-civ-spouse’, ‘Prof-specialty’, ‘Husband’, ‘White’, ‘Male’, 0, 0, 40, ‘United-States’], [53, ‘Self-emp-not-inc’, 145419, ‘1st-4th’, 2, ‘Married-civ-spouse’, ‘Exec-managerial’, ‘Husband’, ‘White’, ‘Male’, 7688, 0, 67, ‘Italy’], [44, ‘Local-gov’, 193425, ‘Masters’, 14, ‘Married-civ-spouse’, ‘Prof-specialty’, ‘Wife’, ‘White’, ‘Female’, 4386, 0, 40, ‘United-States’]] for row in data: # make prediction yhat = pipeline.predict([row]) # get the label label = yhat[0] # summarize print(‘>Predicted=%d (expected 1)’ % (label)) |
Ejecutar el ejemplo primero se ajusta al modelo en todo el conjunto de datos de entrenamiento.
Luego, el modelo de ajuste utilizado para predecir la etiqueta de <= 50K casos se elige del archivo del conjunto de datos. Podemos ver que todos los casos están correctamente predichos. Luego, se utilizan algunos casos> 50K como entrada para el modelo y se predice la etiqueta. Como podríamos haber esperado, se predicen las etiquetas correctas.
<=50K cases: >Predicted=0 (expected 0) >Predicted=0 (expected 0) >Predicted=0 (expected 0) >50K cases: >Predicted=1 (expected 1) >Predicted=1 (expected 1) >Predicted=1 (expected 1) |
OTRAS LECTURAS
Esta sección proporciona más recursos sobre el tema si está buscando profundizar.
Artículos científicos
API
Conjunto de datos
Resumen
En este tutorial, descubrió cómo desarrollar y evaluar un modelo para el conjunto de datos de clasificación de ingresos de adultos desequilibrados.
Específicamente, aprendiste:
- Cómo cargar y explorar el conjunto de datos y generar ideas para la preparación de datos y la selección del modelo.
- Cómo evaluar sistemáticamente un conjunto de modelos de aprendizaje automático con un arnés de prueba robusto.
- Cómo ajustar un modelo final y usarlo para predecir etiquetas de clase para casos específicos.
¿Tienes alguna duda?
Haga sus preguntas en los comentarios a continuación y haré todo lo posible para responder.
Fuente: https://machinelearningmastery.com/imbalanced-classification-with-the-adult-income-dataset/