Representación: Ingeniería de atributos

A diferencia de la programación tradicional, que se centra en el código, los proyectos de aprendizaje automático se enfocan en la representación. Es decir, una forma para perfeccionar los modelos es que los desarrolladores agreguen atributos y los mejoren.

Asignación de datos sin procesar a los atributos

A la izquierda de la Figura 1, se muestran datos sin procesar de una fuente de datos de entrada; a la derecha, se muestra un vector de atributos, que es el conjunto de valores de punto flotante que incluye los ejemplos en el conjunto de datos. La ingeniería de atributos es la transformación de datos sin procesar en un vector de atributos. Ten en cuenta que la ingeniería de atributos implica una gran cantidad de tiempo.

Muchos modelos de aprendizaje automático deben representar los atributos como vectores de números reales ya que los valores de los atributos deben multiplicarse por los pesos del modelo.

Los datos sin procesar se asignan a un vector de atributos a través de un proceso llamado ingeniería de atributos.

Figura 1: La ingeniería de atributos asigna datos sin procesar a los atributos del AA.

Asignación de valores numéricos

Los datos enteros y de punto flotante no necesitan una codificación especial porque se pueden multiplicar por un peso numérico. Como se sugiere en la Figura 2, convertir el valor entero sin procesar 6 en el valor de atributo 6.0 es sencillo:

Un ejemplo de un atributo que puede copiarse directamente de los datos sin procesar

Figura 2: Asignación de valores enteros a valores de punto flotante

Asignación de valores categóricos

Los atributos categóricos tienen un conjunto discreto de valores posibles. Por ejemplo, podría haber un atributo llamado street_name con opciones que incluyan las siguientes:

{'Charleston Road', 'North Shoreline Boulevard', 'Shorebird Way', 'Rengstorff Avenue'}

Debido a que los modelos no pueden multiplicar strings por los pesos aprendidos, usamos la ingeniería de atributos para convertir strings en valores numéricos.

Esto se puede realizar mediante la definición de una asignación a partir de los valores de los atributos a números enteros. A esta asignación la llamaremos vocabulario de valores posibles. Debido a que no todas las calles del mundo aparecerán en nuestro conjunto de datos, podemos agrupar todas las demás calles en una categoría general llamada "otras", que es lo que se conoce como un agrupamiento OOV (fuera del vocabulario).

Mediante este enfoque, podemos asignar nombres de calles a números de la siguiente manera:

  • asignar Charleston Road a 0
  • asignar North Shoreline Boulevard a 1
  • asignar Shorebird Way a 2
  • asignar Rengstorff Avenue a 3
  • asignar todo lo demás (OOV) a 4

Sin embargo, si incorporamos estos números índice directamente en nuestro modelo, se generarán restricciones que podrían ser un problema:

  • Aprenderemos un peso único que aplique a todas las calles. Por ejemplo, si aprendemos un peso 6 para street_name, luego lo multiplicaremos por 0 para Charleston Road, por 1 para North Shoreline Boulevard, por 2 para Shorebird Way y así sucesivamente. Considera un modelo que prediga el precio de las casas usando street_name como atributo. Es poco probable que haya un ajuste lineal en el precio basado en el nombre de la calle. Además, esto implicaría que ordenaste las calles según el precio promedio de las casas. Nuestro modelo necesita flexibilidad para aprender los diferentes pesos para cada calle, que se irán agregando al precio estimado usando los otros atributos.

  • No estamos contemplando los casos en los que street_name podría tener múltiples valores. Por ejemplo, muchas casas se encuentran en la intersección entre dos calles y no hay forma de codificar esa información en el valor street_name si este contiene un solo índice.

Para eliminar estas dos restricciones, podemos crear un vector binario para cada atributo categórico de nuestro modelo que represente los valores de la siguiente manera:

  • En el caso de los valores que aplican al ejemplo, establecer los elementos correspondientes al vector en 1.
  • Establecer todos los demás elementos en 0.

La longitud de este vector es igual a la cantidad de elementos del vocabulario. Esta representación se denomina codificación one-hot cuando un único valor es 1 y codificación multi-hot cuando varios valores son 1.

La figura 3 ilustra una codificación one-hot de una calle determinada: Shorebird Way. El elemento del vector ejecutable correspondiente a Shorebird Way tiene como valor 1, mientras que los elementos de todas las demás calles tienen 0 como valor.

Asignación de un valor de string ("Shorebird Way") a un vector disperso mediante la codificación one-hot.

Figura 3. Asignación de nombres de calles mediante codificación one-hot.

Este enfoque crea, de manera efectiva, una variable booleana para el valor de cada atributo (p. ej., nombre de la calle). En este caso, si una casa está en la calle Shorebird Way, el valor binario sería 1 únicamente para la calle Shorebird Way. De esta manera, el modelo usa únicamente el peso para la calle Shorebird Way.

De manera similar, si una casa está en la intersección entre dos calles, entonces los dos valores binarios se establecen en 1 y el modelo usa ambos pesos respectivos.

Representación dispersa

Imagina que tienes 1,000,000 nombres de calles diferentes en tu conjunto de datos y quieres incluir a todos como valores para street_name. Crear de manera explícita un vector binario con 1,000,000 elementos, en los que solo 1 o 2 son verdaderos, sería una representación muy ineficaz en términos de almacenamiento y tiempo a la hora de procesar estos vectores. En este caso, un enfoque común es usar una representación dispersa en la que solo se almacenen los valores que no son cero. En las representaciones dispersas, se aprende un peso modelo independiente para cada valor de atributo, tal como se describió anteriormente.