Capítulo 4. Datos perdidos
Este trabajo se ha traducido utilizando IA. Agradecemos tus opiniones y comentarios: translation-feedback@oreilly.com
Tenemos que tratar los datos que faltan. El capítulo anterior mostraba un ejemplo. Este capítulo profundizará un poco más en ello. La mayoría de los algoritmos no funcionan si faltan datos. Excepciones notables son las recientes bibliotecas de boosting: XGBoost, CatBoost y LightGBM.
Como ocurre con muchas cosas en el aprendizaje automático, no hay respuestas definitivas sobre cómo tratar los datos que faltan. Además, los datos que faltan pueden representar diferentes situaciones. Imagina que llegan los datos del censo y falta una característica de edad. ¿Se debe a que la muestra no quería revelar su edad? ¿No sabían su edad? ¿El que hizo las preguntas olvidó siquiera preguntar por la edad? ¿Existe algún patrón en las edades omitidas? ¿Está correlacionada con otra característica? ¿Es completamente aleatorio?
También hay varias formas de tratar los datos que faltan:
-
Elimina cualquier fila con datos que falten
-
Elimina cualquier columna con datos que falten
-
Imputar valores perdidos
-
Crea una columna indicadora para señalar que faltaban datos
Examinar los datos que faltan
Volvamos a los datos del Titanic. Como Python trata True
y False
como 1
y 0
, respectivamente, podemos utilizar este truco en pandas para obtener el porcentaje de datos que faltan:
>>>
df
.
isnull
()
.
mean
()
*
100
pclass 0.000000
survived 0.000000
name 0.000000
sex 0.000000
age 20.091673
sibsp 0.000000
parch 0.000000
ticket 0.000000
fare 0.076394
cabin 77.463713
embarked 0.152788
boat 62.872422
body 90.756303
home.dest 43.086325
dtype: float64
Para visualizar patrones en los datos omitidos, utiliza la biblioteca missingno. Esta biblioteca es útil para visualizar áreas contiguas de datos omitidos, lo que indicaría que los datos omitidos no son aleatorios (véase la Figura 4-1). La función matrix
incluye una línea de chispas en el lado derecho. Los patrones aquí también indicarían que los datos que faltan no son aleatorios. Puede que tengas que limitar el número de muestras para poder ver los patrones:
>>>
import
missingno
as
msno
>>>
ax
=
msno
.
matrix
(
orig_df
.
sample
(
500
))
>>>
ax
.
get_figure
()
.
savefig
(
"images/mlpr_0401.png"
)
Podemos crear un gráfico de barras de los recuentos de datos que faltan utilizando pandas (ver Figura 4-2):
>>>
fig
,
ax
=
plt
.
subplots
(
figsize
=
(
6
,
4
))
>>>
(
1
-
df
.
isnull
()
.
mean
())
.
abs
()
.
plot
.
bar
(
ax
=
ax
)
>>>
fig
.
savefig
(
"images/mlpr_0402.png"
,
dpi
=
300
)
O utiliza la biblioteca missingno para crear el mismo gráfico (ver Figura 4-3):
>>>
ax
=
msno
.
bar
(
orig_df
.
sample
(
500
))
>>>
ax
.
get_figure
()
.
savefig
(
"images/mlpr_0403.png"
)
Podemos crear un mapa de calor que muestre si hay correlaciones donde faltan datos (ver Figura 4-4). En este caso, no parece que los lugares donde faltan datos estén correlacionados:
>>>
ax
=
msno
.
heatmap
(
df
,
figsize
=
(
6
,
6
))
>>>
ax
.
get_figure
()
.
savefig
(
"/tmp/mlpr_0404.png"
)
Podemos crear un dendrograma que muestre las agrupaciones en las que faltan datos (véase la Figura 4-5). Las hojas que están en el mismo nivel predicen la presencia de otra (vacía o llena). Los brazos verticales sirven para indicar lo diferentes que son las agrupaciones. Los brazos cortos significan que las ramas son similares:
>>>
ax
=
msno
.
dendrogram
(
df
)
>>>
ax
.
get_figure
()
.
savefig
(
"images/mlpr_0405.png"
)
Eliminar los datos que faltan
La biblioteca pandas puede eliminar todas las filas con datos perdidos con el método .dropna
:
>>>
df1
=
df
.
dropna
()
Para eliminar columnas, podemos anotar qué columnas faltan y utilizar el método .drop
. Podemos pasar una lista de nombres de columnas o un único nombre de columna:
>>>
df1
=
df
.
drop
(
columns
=
"cabin"
)
Alternativamente, podemos utilizar el método .dropna
y establecer axis=1
(caída a lo largo del eje de columnas):
>>>
df1
=
df
.
dropna
(
axis
=
1
)
Ten cuidado con la eliminación de datos. Yo suelo considerar esto como una opción de último recurso.
Imputar datos
Una vez que dispongas de una herramienta para predecir los datos, puedes utilizarla para predecir los datos que faltan. La tarea general de definir valores para los valores que faltan se llama imputación.
Si vas a imputar datos, tendrás que crear una canalización y utilizar la misma lógica de imputación durante la creación del modelo y el tiempo de predicción. La clase SimpleImputer
de scikit-learn manejará la media, la mediana y los valores más frecuentes de las características.
El comportamiento por defecto es calcular la media:
>>>
from
sklearn.impute
import
SimpleImputer
>>>
num_cols
=
df
.
select_dtypes
(
...
include
=
"number"
...
)
.
columns
>>>
im
=
SimpleImputer
()
# mean
>>>
imputed
=
im
.
fit_transform
(
df
[
num_cols
])
Proporciona strategy='median'
o strategy='most_frequent'
para cambiar el valor sustituido a mediana o más común, respectivamente. Si deseas rellenar con un valor constante, por ejemplo -1
, utiliza strategy
='constant'
en combinación con fill_value=-1
.
Consejo
También puedes utilizar el método .fillna
de pandas para imputar valores perdidos. Sin embargo, asegúrate de no filtrar datos. Si rellenas con el valor medio, asegúrate de que utilizas el mismo valor medio durante la creación del modelo y durante la predicción del modelo.
Las estrategias más frecuente y constante pueden utilizarse con datos numéricos o de cadena. La media y la mediana requieren datos numéricos.
La biblioteca fancyimpute implementa muchos algoritmos y sigue la interfaz scikit-learn. Lamentablemente, la mayoría de los algoritmos son transductivos, lo que significa que no puedes llamar al método .transform
por sí mismo después de ajustar el algoritmo. El IterativeImputer
es inductivo (desde entonces se ha migrado de fancyimpute a scikit-learn) y admite la transformación tras el ajuste.
Añadir columnas indicadoras
La falta de datos en sí misma puede proporcionar alguna señal a un modelo. La biblioteca pandas puede añadir una nueva columna para indicar que falta un valor:
>>>
def
add_indicator
(
col
):
...
def
wrapper
(
df
):
...
return
df
[
col
]
.
isna
()
.
astype
(
int
)
...
...
return
wrapper
>>>
df1
=
df
.
assign
(
...
cabin_missing
=
add_indicator
(
"cabin"
)
...
)
Get Referencia de bolsillo sobre aprendizaje automático now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.