Representação: engenharia de atributos

Na programação tradicional, o foco está no código. Em projetos de machine learning, o foco muda para representação. Ou seja, uma maneira de os desenvolvedores aprimorarem um modelo é adicionando e melhorando os recursos dele.

Mapeamento de dados brutos para atributos

O lado esquerdo da Figura 1 ilustra os dados brutos de uma fonte de dados de entrada. O lado direito ilustra um vetor de atributo, que é o conjunto de valores de ponto flutuante que compreende os exemplos no seu conjunto de dados. Engenharia de atributos significa transformar dados brutos em um vetor de atributo. Espere passar um tempo significativo fazendo engenharia de atributos.

Muitos modelos de machine learning precisam representar os atributos como vetores de número real, já que os valores dos atributos precisam ser multiplicados pelos pesos do modelo.

Os dados brutos são mapeados para um vetor de atributo com um processo chamado engenharia de atributos.

Figura 1. A engenharia de atributos mapeia dados brutos para atributos de ML.

Mapeamento de valores numéricos

Os dados inteiros e de ponto flutuante não precisam de uma codificação especial porque podem ser multiplicados por um peso numérico. Conforme sugerido na Figura 2, é fácil converter o valor inteiro bruto 6 no valor do atributo 6.0:

Exemplo de atributo que pode ser copiado diretamente dos dados brutos

Figura 2. Mapeamento de valores inteiros para valores de ponto flutuante.

Como mapear valores categóricos

Os atributos categóricos têm um conjunto distinto de valores possíveis. Por exemplo, pode haver um recurso chamado street_name com opções que incluem:

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

Como os modelos não podem multiplicar as strings pelos pesos aprendidos, usamos a engenharia de atributos para converter strings em valores numéricos.

Para fazer isso, defina um mapeamento dos valores dos atributos, que chamamos de vocabulário dos valores possíveis, para números inteiros. Como nem todas as ruas do mundo vão aparecer no nosso conjunto de dados, podemos agrupá-las em uma categoria "outra", conhecida como bucket OOV (fora do vocabulário).

Usando esta abordagem, veja como mapear os nomes das ruas em números:

  • mapa Charleston Road para 0
  • mapear a North Shoreline Boulevard para 1
  • mapa Shorebird Way até 2
  • mapear a Rengstorff Avenue até a 3
  • mapear todo o resto (OOV) para 4

No entanto, se incorporarmos esses números de índice diretamente no modelo, algumas restrições poderão ser problemáticas:

  • Vamos aprender um único peso que se aplica a todas as ruas. Por exemplo, se observarmos um peso 6 para street_name, nós o multiplicaremos por 0 para Charleston Road, por 1 para North Shoreline Boulevard, 2 para Shorebird Way e assim por diante. Considere um modelo que prevê preços de imóveis usando street_name como atributo. É improvável que haja um ajuste linear de preço com base no nome da rua. Além disso, isso pressupõe que você pediu as ruas com base no preço médio da casa. Nosso modelo precisa da flexibilidade de aprender pesos diferentes para cada rua que será adicionado ao preço estimado usando os outros atributos.

  • Não estamos contabilizando casos em que street_name pode assumir vários valores. Por exemplo, muitas casas estão localizadas na esquina de duas ruas, e não há como codificar essa informação no valor street_name se ela contiver um único índice.

Para remover essas duas restrições, podemos criar um vetor binário para cada atributo categórico em nosso modelo que representa os valores da seguinte maneira:

  • Para valores que se aplicam ao exemplo, defina os elementos vetoriais correspondentes como 1.
  • Defina todos os outros elementos como 0.

O comprimento desse vetor é igual ao número de elementos no vocabulário. Essa representação é chamada de codificação one-hot quando um único valor é 1, e codificação multi-hot quando vários valores são 1.

A Figura 3 ilustra uma codificação one-hot de uma rua específica: Shorebird Way. O elemento no vetor binário para a Shorebird Way tem um valor de 1, enquanto os elementos de todas as outras ruas têm valores de 0.

O mapeamento de um valor de string (

Figura 3. Mapeamento de endereços com codificação one-hot.

Essa abordagem cria uma variável booleana para cada valor de recurso (por exemplo, nome da rua). Nesse caso, se uma casa estiver na Shorebird Way, o valor binário será 1 somente para a Shorebird Way. Assim, o modelo usa apenas o peso da Shorebird Way.

Da mesma forma, se uma casa estiver na esquina de duas ruas, dois valores binários serão definidos como 1, e o modelo usará os respectivos pesos.

Representação esparsa

Suponha que você tenha 1.000.000 de nomes de ruas diferentes no seu conjunto de dados e queira incluir como valores para street_name. Criar explicitamente um vetor binário de 1.000.000 de elementos em que apenas um ou dois elementos são verdadeiros é uma representação muito ineficiente em termos de tempo de armazenamento e computação ao processar esses vetores. Nessa situação, uma abordagem comum é usar uma representação esparsa em que apenas valores diferentes de zero são armazenados. Em representações esparsas, um peso de modelo independente ainda é aprendido para cada valor de atributo, conforme descrito acima.