Representación: Ingeniería de atributos

En la programación tradicional, el enfoque está en el código. En los proyectos de aprendizaje automático, el enfoque cambia a la representación. Es decir, una forma en que los desarrolladores perfeccionan un modelo es agregando y mejorando sus atributos.

Asignación de datos sin procesar a los atributos

En el lado izquierdo de la figura 1, se muestran datos sin procesar de una fuente de datos de entrada; en el lado derecho, se muestra un vector de atributos, que es el conjunto de valores de punto flotante que contiene los ejemplos del conjunto de datos. Ingeniería de atributos significa transformar datos sin procesar en un vector de atributos. Debes dedicar mucho tiempo a la ingeniería de atributos.

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 atributos de AA.

Asigna valores numéricos

Los datos de número entero y de punto flotante no necesitan una codificación especial porque se pueden multiplicar por una ponderación numérica. Como se sugiere en la figura 2, la conversión del valor entero sin procesar 6 al valor de atributo 6.0 es trivial:

Un ejemplo de una función que se puede copiar directamente desde los datos sin procesar

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

Asigna valores categóricos

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

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

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

Para lograrlo, debemos definir los valores de los atributos a números enteros, a los que nos referiremos como vocabulario. Dado 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 genérica, conocida como bucket OOV (fuera del vocabulario).

Con este enfoque, a continuación te mostramos cómo podemos asignar los nombres de las calles a los números:

  • 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 de índice directamente en nuestro modelo, se generarán algunas restricciones que podrían ser problemáticas:

  • Aprenderemos un peso único que se aplica a todas las calles. Por ejemplo, si aprendemos un peso 6 para street_name, lo multiplicaremos por 0 para Charlotte Road, por 1 para North Shoreline Boulevard, 2 para Shorebird Way y así sucesivamente. Considera un modelo que prediga el precio de las casas con street_name como atributo. Es poco probable que haya un ajuste lineal en el precio basado en el nombre de la calle y, además, esto supone que ordenaste las calles según el precio promedio de las casas. Nuestro modelo necesita la flexibilidad de aprender los diferentes pesos para cada calle, que se agregarán al precio estimado con las otras características.

  • No estamos teniendo en cuenta los casos en los que street_name puede tomar varios valores. Por ejemplo, muchas casas se encuentran en la esquina de dos calles, y no hay forma de codificar esa información en el valor street_name si contiene un solo índice.

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

  • Para los valores que se aplican al ejemplo, establece los elementos vectoriales correspondientes 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.

En la figura 3, se muestra una codificación one-hot de una calle determinada: Shorebird Way. El elemento del vector binario para Shorebird Way tiene un valor de 1, mientras que los elementos para todas las demás calles tienen valores de 0.

Asignación de un valor de string (

Figura 3: Mapear la dirección a través de la codificación one-hot

Este enfoque crea, de manera efectiva, una variable booleana para cada valor de atributo (p.ej., nombre de la calle). Aquí, si una casa está en Shorebird Way, el valor binario es 1 solo para Shorebird Way. Por lo tanto, el modelo solo usa el peso para Shorebird Way.

De manera similar, si una casa está en la esquina de dos calles, entonces dos valores binarios se establecen en 1 y el modelo usa sus pesos respectivos.

Representación dispersa

Supongamos que tenías 1,000,000 de nombres de calles diferentes en tu conjunto de datos que querías incluir como valores para street_name. Crear de manera explícita un vector binario de 1,000,000 de elementos en el que solo 1 o 2 elementos son verdaderos es una representación muy ineficiente en términos de almacenamiento y tiempo de procesamiento cuando se procesan estos vectores. En esta situación, un enfoque común es usar una representación dispersa en la que solo se almacenen valores distintos de cero. En las representaciones dispersas, se aprende un peso de modelo independiente para cada valor de atributo, como se describió antes.