Duplicar ejemplos de entrenamiento para manejar el desequilibrio de clase en un dataframe de pandas

Tengo un DataFrame en pandas que contiene ejemplos de entrenamiento, por ejemplo:

feature1 feature2 class 0 0.548814 0.791725 1 1 0.715189 0.528895 0 2 0.602763 0.568045 0 3 0.544883 0.925597 0 4 0.423655 0.071036 0 5 0.645894 0.087129 0 6 0.437587 0.020218 0 7 0.891773 0.832620 1 8 0.963663 0.778157 0 9 0.383442 0.870012 0 

que generé utilizando:

 import pandas as pd import numpy as np np.random.seed(0) number_of_samples = 10 frame = pd.DataFrame({ 'feature1': np.random.random(number_of_samples), 'feature2': np.random.random(number_of_samples), 'class': np.random.binomial(2, 0.1, size=number_of_samples), },columns=['feature1','feature2','class']) print(frame) 

Como puede ver, el conjunto de entrenamiento está desequilibrado (8 muestras tienen clase 0, mientras que solo 2 muestras tienen clase 1). Me gustaría sobredimensionar el conjunto formativo. Específicamente, me gustaría duplicar las muestras de entrenamiento con la clase 1 para que el conjunto de entrenamiento esté equilibrado (es decir, donde el número de muestras con clase 0 es aproximadamente el mismo que el número de muestras con clase 1). ¿Como lo puedo hacer?

Idealmente, me gustaría una solución que pueda generalizarse a una configuración multiclase (es decir, el número entero en la columna de la clase puede ser más de 1).

Puedes encontrar el tamaño máximo que un grupo tiene con

 max_size = frame['class'].value_counts().max() 

En su ejemplo, esto es igual a 8. Para cada grupo, puede muestrear con elementos de reemplazo max_size - len(group_size) . De esta manera, si los ajusta al DataFrame original, sus tamaños serán los mismos y mantendrá las filas originales.

 lst = [frame] for class_index, group in frame.groupby('class'): lst.append(group.sample(max_size-len(group), replace=True)) frame_new = pd.concat(lst) 

Puedes jugar con max_size-len(group) y quizás agregarle algo de ruido porque esto hará que todos los tamaños de grupo sean iguales.