Formar una muestra de datos de entrenamiento con cambio de distribución

Descargo de responsabilidad: este artículo es un producto traducido de Max Halforda . La traducción no es limpia, sino adaptativa. De tal manera que haya comprensión en cualquier línea de conocimiento.







“Mis amigos y yo calificamos recientemente para la final de Data Science Game 2017. La primera parte de la competencia fue Kaggle con un conjunto de datos de Deezer (1). El problema consistía en solucionar el problema de clasificación binaria: era necesario predecir si el usuario iba a pasar a escuchar la composición que se le ofrecía.



Como otros equipos, hemos extraído las características relevantes y entrenado el clasificador XGBoost (2). Sin embargo, hicimos algo especial, una submuestra del conjunto de datos de entrenamiento, de modo que (el conjunto de datos de entrenamiento) se volvió más representativo del conjunto de pruebas ".




Uno de los requisitos básicos para el proceso de aprendizaje para el funcionamiento exitoso de un modelo de máquina es la misma naturaleza de las distribuciones en los conjuntos de datos de entrenamiento y prueba. Como ejemplo aproximado: el modelo se entrenó en usuarios de 20 años de edad, y en la muestra de prueba, los usuarios tienen más de 60 años.



Aquí es intuitivamente natural que con la edad en la que no se entrenó al modelo, no se las arreglará. Por supuesto, este ejemplo es puramente sintético, pero en realidad, para diferencias significativas, es suficiente entrenar el modelo para mayores de 20 e intentar que funcione para mayores de 30 años. El resultado será similar.



Esto se debe a que los modelos aprenden las distribuciones (3) de los datos. Si las distribuciones de una característica en los conjuntos de entrenamiento y prueba son las mismas, el modelo se lo agradecerá.



Insertar traductor: Cuando me senté a traducir, tenía una pregunta: ¿por qué la formación debería adaptarse a la prueba? Porque, de hecho , la prueba refleja datos invisibles que entrarán en el modelo como entrada a la producción. Luego me quedé dormido, volví a leer y todo pasó. El truco es que, bajo la influencia de factores, las retrospectivas pueden volverse irrelevantes por el momento. Más sobre esto más adelante (ejemplo ligeramente readaptado).



El sesgo en las distribuciones de una característica puede ocurrir por varias razones. El ejemplo más intuitivo se puede tomar prestado de Facebook.



Digamos que una empresa fue entrenada en un modelo que se basó en una característica (una característica es lo mismo que una característica) como pasatiempo en minutos. Deje que prediga sintéticamente el nivel de lealtad del usuario en una escala de diez puntos.



Cuando la aplicación general de Facebook se dividió en la red social principal (alimentación, etc.) y el sistema de mensajería, el tiempo en la aplicación principal disminuyó, es decir, los conjuntos de datos entrantes cambiaron y ya no correspondían a la retrospectiva pasada.

Matemáticamente, teniendo en cuenta la función de tiempo, el modelo predecirá un nivel más bajo de lealtad, aunque en realidad este no es el caso: la transferencia de tiempo simplemente se divide en dos aplicaciones. Sale tristemente.



Por lo tanto, se produce un cambio de distribución cuando la distribución de datos históricos se vuelve irrelevante para predecir nuevos datos.



En el conjunto de datos de Deezer, la inconsistencia de las distribuciones estaba en la función que mide el número de canciones escuchadas antes de resolver el problema de predicción. Esta característica tuvo una distribución exponencial (4) tanto en el público como en los conjuntos de datos de prueba. Sin embargo, en el conjunto de datos de prueba fue más pronunciado, por lo que el promedio en el conjunto de entrenamiento fue menor que en el conjunto de prueba. Después de volver a muestrear la distribución del entrenamiento, logramos aumentar la métrica ROC-AUC (5) y subir la calificación en aproximadamente 20 puntos.



A continuación se muestra un ejemplo de la diferencia de distribución:



import numpy as np
import plotly.figure_factory as ff

train = np.random.exponential(2, size=100000)
test = np.random.exponential(1, size=10000)

distplot = ff.create_distplot([train, test], ['Train', 'Test'], bin_size=0.5)
distplot.update_layout(title_text=' Test, Train')


" "



La idea de nivelar el cambio de distribución es remodelar la muestra de entrenamiento para reflejar la distribución de la prueba.



Imaginemos que queremos crear una submuestra de 50.000 observaciones de nuestro conjunto de entrenamiento para que se ajuste a la distribución del conjunto de prueba. ¿Qué quieres hacer intuitivamente?



¡Haga que los objetos que son más comunes en el conjunto de datos de prueba también sean comunes en el entrenamiento! Pero, ¿cómo se puede determinar qué objetos se necesitan más y cuáles con menor frecuencia?



¡Libra!



Los pasos serán algo como esto:



  • dividir la línea recta numérica de distribución en intervalos iguales (o cestas (contenedores)
  • contar la cantidad de objetos en cada canasta (tamaño del contenedor)
  • para cada observación en la canasta, calcule su peso igual a 1 / (tamaño del contenedor)
  • crear una submuestra de k con una distribución ponderada (los objetos con un peso más alto aparecerán en la submuestra con más frecuencia)


Transfiriendo al código, realizamos las siguientes acciones:



SAMPLE_SIZE = 50000
N_BINS = 300

#   ,       .
#        
step = 100 / N_BINS

test_percentiles = [
    np.percentile(test, q, axis=0)
    for q in np.arange(start=step, stop=100, step=step)
]

#     . 
#    ,    
train_bins = np.digitize(train, test_percentiles)

#          i   ,
#  0      , 1    1    i 
train_bin_counts = np.bincount(train_bins)

#    ,        
weights = 1 / np.array([train_bin_counts[x] for x in train_bins])

#   ,     
weights_norm = weights / np.sum(weights)

np.random.seed(0)

sample = np.random.choice(train, size=SAMPLE_SIZE, p=weights_norm, replace=False)

distplot_with_sample = ff.create_distplot([train, test, sample], ['Train', 'Test', 'New train'], bin_size=0.5)
distplot_with_sample.update_layout(title_text=' Test, Train, New train')


" " La



nueva distribución (verde) ahora coincide mejor con la distribución de la muestra de prueba (naranja). Usamos acciones similares en la competencia: el conjunto de datos original contenía 3 millones de filas, generamos el tamaño de la nueva muestra a partir de 1.3 millones de objetos. Los datos se hicieron más pequeños, pero la representatividad de la distribución mejoró la calidad de la formación.



Algunas notas de la experiencia personal del autor:



  • El número de cestas no juega un papel importante, pero cuanto menos cestas, más rápido aprende el algoritmo (intente cambiar el número de cestas (N_BINS) a 3, 30 en el ejemplo y verá que la diferencia es realmente pequeña)
  • , , , “” , , .

    ( , “” , “” . . , )



El algoritmo de remodelación está en el github del autor (carpeta xam ). En el futuro, el autor planea analizar nuevos temas y compartirlos en el blog.



Espero que la traducción y las notas hayan sido útiles y claras. Espero sus comentarios en un formato constructivo. Gracias por tu tiempo.



Notas al pie:



1. Deezer es un servicio francés de transmisión de música en línea. Como Spotify, Ya Music y ya tienes la idea



2. XGBoost- algoritmo de aumento de gradiente extremo. Me encantó llamarlo "aumento de gradiente con esteroides". La idea del impulso es capacitar a varios alumnos débiles homogéneos, cada uno de los cuales forma calificaciones en base a la experiencia de aprendizaje retrospectiva del anterior, prestando atención a aquellas clases donde más tropezó el algoritmo anterior. La idea detrás de un degradado es, en una palabra simple, minimizar los errores de aprendizaje. XGBoost, como algoritmo, es una configuración más ventajosa desde el punto de vista computacional de Gradient Boosting



3. Distribución aquí significa exactamente lo que describe la ley por la cual los números se dispersan en una variable.



4. En mi opinión personal, el acicate más comprensible para visualizar exponencialesdistribución en la cabeza es su definición como distribución, con intensidad constante.



5. ROC-AUC (Curva de característica operativa de área bajo el receptor) - el área bajo la curva de "características de procesamiento del receptor" - un nombre literal, ya que la métrica proviene de la teoría del procesamiento de señales. La curva ROC es muy empinada: demuestra la relación entre los verdaderos positivos y falsos positivos de las respuestas del modelo a medida que cambia el umbral de probabilidad para la asignación a una clase, formando un “arco”. Debido al hecho de que la relación de TP y FP es visible, es posible seleccionar el umbral de probabilidad óptimo en función de los errores del primer y segundo tipo.



En el caso de considerar la precisión del modelo, sin prestar atención al umbral de probabilidad de respuestas, se utiliza la métrica ROC-AUC, que toma valores en el rango [0,1]. Para un modelo constante con un balance de clases, el ROC-AUC será aproximadamente igual a 0.5, por lo tanto, los modelos siguientes no pasan la verificación de cordura (verificación de cordura). Cuanto más cerca de uno esté el área bajo la curva ROC, mejor, pero para indexar la utilidad de los resultados en general, es relevante comparar el AUC-ROC del modelo entrenado con el AUC-ROC del modelo constante.



All Articles