5.3 Ingeniería de características

En aprendizaje máquina la ingeniería de características (Feature engineering) consiste en dotar al modelo de variables o características sintéticas que aporten información extra. Ya lo hemos hecho en el capítulo 4 con la variable ‘sexo’ para el enlazado probabilístico.

5.3.1 Nombre completo

En el nombre completo “JOSE CARLOS VICENTE PEREZ” ¿Cuáles son el nombre, primer apellido y segundo apellido?

Es fácil confundirse, ya que tanto CARLOS como VICENTE pueden ser tanto nombres propios como apellidos. En el caso de nombres extranjeros, la probabilidad de confusión es mayor.

En estos casos comparar con el nombre completo (nombre + primer apellido + segundo apellido) es mejor. Añadimos una variable con el nombre completo.

bdc_nombre.x bdc_apellido_1.x bdc_apellido_2.x nombre_completo.x
15 LYUDMIL VALERIEV HADZHIEV NA LYUDMIL VALERIEV HADZHIEV
28 MAGDALENA SERGEEVA ZELEVA NA MAGDALENA SERGEEVA ZELEVA
21 LORA MIRCHEVA BOSHNAKOVA NA LORA MIRCHEVA BOSHNAKOVA
11 LYUBOVKA SIMEONOVA BUYUKLIYSKA LYUBOVKA SIMEONOVA BUYUKLIYSKA

5.3.2 Distancias

La característica principal para la clasificación en enlazado de datos es la ‘similitud’ entre las variables a comparar. De hecho, en la comparativa de resultados de esta prueba de concepto no las consideramos características sintéticas.

Añadimos una variable con la distancia entre las posibles variables a comparar.

Muestra:

bdc_id_oficial.x bdc_id_oficial.y id_oficial.dis
1348 C1026361 X0102636X 3
1349 X11836Z X0011836Z 2
1350 X560673W X0560673W 1
1351 X117395A X0117395A 1
1352 A07042425 PA07042425 1
1353 Y246596G Y0246596G 1
1354 15850725E 15807025E 2
1355 X550777L X0550777L 1
1356 73601823Y 73608723Y 2
1357 15601838H 15601631H 2

5.3.3 Frecuencia de los nombres

¿Qué es más probable, que dos registros con el nombre “FRANCISCO JAVIER GARCIA” o que dos registros con el nombre “AURELIANO BUENDIA” correspondan a la misma persona?

Entre los residentes en Navarra es más probable el segundo caso, ya que el nombre AURELIANO y el apellido BUENDIA son mucho menos comunes que el nombre FRANCISCO JAVIER y el apellido GARCIA.

Añadimos una variable que indica lo comunes que son los nombres. Información proporcionada por el INE6.

ine_nombre ine_por_mil
AMAIA 6.353
JUAN ANTONIO 3.119
ANTONIO LUIS 0.135
LIBE 0.111
BERNABE 0.097
BADR 0.047
NASSIRA 0.034
LEONARDO DAVID 0.019
GERMAN JOSE 0.016
MIREN ARGIA 0.015

Cruzamos esta tabla con la muestra para añadir las variables de frecuencia:

bdc_nombre.x ine_por_mil.x bdc_nombre.y ine_por_mil.y
4506 LUIS GUILLERMO 0.028 LUIS GUILLERMO 0.028
10120 LUISA MARIA 0.231 LUISA MARIA 0.231
9245 MAIDER BARDA NA MAIDER 2.816
10218 LIZ KARINA NA LIZ KARINA NA
8430 MAITE 5.608 MAITE 5.608
11534 LUCIA 6.076 LUCIA 6.076
8972 LUIS 7.039 LUIS 7.039
3328 LUIS 7.039 LUIS 7.039
11415 LUIS MARIA 2.589 LUIS 7.039
2133 LOURDES 1.812 LOURDES 1.812

Posible mejora: frecuncia sabiendo el sexo. El INE nos proporciona la frecuencia por sexo.

5.3.4 Id. nacional o extranjero

¿En qué casos dos registros con diferente identificador oficial pueden corresponder a la misma persona?

En el caso de los extranjeros que se nacionalizan, ya que pasan de tener un NIE a tener un DNI.

Añadimos una variable que, a partir del id oficial, crea un campo que indica si parece un id de un nacional o de un extranjero.

Muestra:

bdc_id_oficial.x id_nacional_extranjero.x bdc_id_oficial.y id_nacional_extranjero.y
73121967E N M3105350M E
72708866R N X3814245V E
X6256266J E 25156637L N
X3754709M E 03754709M N
NA NA 10892581B N
X564020Z NA YB014284 NA
Y787477V NA Y0787477V E
18201469 N NA NA

5.3.5 Es menor de 14 años

Los menores de 14 años no están obligados a tener DNI. Es otro caso en el que dos registros con diferente identificador oficial pueden corresponder con la misma persona (uno vacío, el otro con un DNI)

Añadimos una variable que, a partir de la fecha de nacimiento y la fecha de la observación, crea un campo que indica si era menor de 14 años en el momento de la observación.

Muestra:

bdc_fecha_nacimiento.x bdc_fecha_valor.x es_menor_de_14.x
1979-12-15 2018-01-01 FALSE
1995-06-14 2018-01-01 FALSE
1996-02-13 2018-01-01 FALSE
1984-06-10 2018-01-01 FALSE
1991-05-14 2018-01-01 FALSE
1987-10-02 2018-01-01 FALSE
1937-02-25 2018-01-01 FALSE
1968-05-20 2018-01-01 FALSE

5.3.6 Subcadenas

En algunas variables, como el nombre y apellidos, puede ser más significativo que las distancia que la cadena más corta esté incluida en la cadena más larga:

## [1] 6
## [1] 4

Añadimos las variables nombre.incluido, apellido_1.incluido, apellido_2.incluido, municipio_domicilio.incluido, nombre_completo.incluido.

# https://www.rdocumentation.org/packages/stringr/versions/1.3.1/topics/str_detect
# Añado \\b para que compare con palabras completas, 
# de manera que "LUIS" no esté 'incluido' en "LUISA" o "LUCIA" en "LUCIANA"

muestra <- muestra %>% 
  mutate(nombre.incluido = 
    ifelse(is.na(bdc_nombre.x) | is.na(bdc_nombre.y), NA, 
      str_detect(bdc_nombre.x, paste("\\b",bdc_nombre.y,"\\b",sep="")) | 
      str_detect(bdc_nombre.y, paste("\\b",bdc_nombre.x,"\\b",sep="")))) %>%
  mutate(apellido_1.incluido = 
    ifelse(is.na(bdc_apellido_1.x) | is.na(bdc_apellido_1.y), NA, 
      str_detect(bdc_apellido_1.x, paste("\\b",bdc_apellido_1.y,"\\b",sep="")) | 
      str_detect(bdc_apellido_1.y, paste("\\b",bdc_apellido_1.x,"\\b",sep="")))) %>%
  mutate(apellido_2.incluido = 
    ifelse(is.na(bdc_apellido_2.x) | is.na(bdc_apellido_2.y), NA, 
      str_detect(bdc_apellido_2.x, paste("\\b",bdc_apellido_2.y,"\\b",sep="")) | 
      str_detect(bdc_apellido_2.y, paste("\\b",bdc_apellido_2.x,"\\b",sep="")))) %>%
  mutate(municipio_domicilio.incluido = 
    ifelse(is.na(bdc_municipio_domicilio.x) | is.na(bdc_municipio_domicilio.y), NA, 
      str_detect(bdc_municipio_domicilio.x, 
                 paste("\\b",bdc_municipio_domicilio.y,"\\b",sep="")) | 
      str_detect(bdc_municipio_domicilio.y, 
                 paste("\\b",bdc_municipio_domicilio.x,"\\b",sep="")))) %>%
  mutate(nombre_completo.incluido = 
    ifelse(is.na(nombre_completo.x) | is.na(nombre_completo.y), NA, 
      str_detect(nombre_completo.x, paste("\\b",nombre_completo.y,"\\b",sep="")) | 
      str_detect(nombre_completo.y, paste("\\b",nombre_completo.x,"\\b",sep=""))))

Muestra:

bdc_nombre.x bdc_nombre.y nombre.dis nombre.incluido
50 LUIS LUIS JUAN 5 TRUE
543 LUIS GERVASIO LUIS 9 TRUE
205 LUIS LUIS JOSE 5 TRUE
115 LUIS MIGUEL LUIS 7 TRUE
618 MAGDALENA MAGDALENA KRASIMIROV 11 TRUE
116 LUIS FRANCISCO LUIS 10 TRUE
48 LUIS PEDRO LUIS 6 TRUE
383 LUIS FERNANDO LUIS 9 TRUE
216 LUIS MARIA LUIS 6 TRUE
136 LUIS LEONCIO LUIS 8 TRUE

  1. Fuera de la POC podríamos mejorar utilizando la frecuencia del nombre en la década de nacimiento de la persona, que es información que también proporciona el INE