Preparar dados para o aprendizado de máquina

Concluído

Antes de criar um modelo de aprendizado de máquina, você precisa preparar os dados que usará para treiná-los e avaliá-los. Os dados são ingeridos no Azure Databricks provenientes da origem, geralmente como arquivos de dados. Opcionalmente, você pode criar tabelas delta com base nos arquivos de dados para simplificar a exploração e a análise de dados. Depois que os dados são ingeridos, um cientista de dados os prepara para o aprendizado de máquina.

Normalmente, a preparação de dados envolve duas tarefas principais:

  • Limpeza de dados: identificar e atenuar problemas nos dados que afetarão sua utilidade para o aprendizado de máquina.
  • Engenharia de recursos e pré-processamento: selecionar e transformar recursos adequados para treinamento de modelo.

Limpeza de dados

As etapas específicas necessárias para limpar dados variam de projeto para projeto, mas os problemas típicos que você precisa resolver incluem:

  • Dados incompletos: os dados geralmente incluem registros nos quais campos individuais estão ausentes (geralmente indicados pela presença de valores NULL). Você precisa identificar valores ausentes e atenuá-los da seguinte maneira:
    • Substituindo-os por uma substituição adequada – seja interpolando um valor em uma série, usando um valor médio (ou mediano) ou criando algum outro valor apropriado.
    • Removendo linhas incompletas por inteiro (supondo que isso deixe dados representativos suficientes adequados para modelagem)
  • Erros: não é incomum que os dados incluam erros, causados por falhas de entrada de dados ou processamento de dados upstream com falha. Encontrar erros pode ser difícil e geralmente envolve um escrutínio substancial dos dados usando consultas e visualizações para resumir os dados e procurar valores que não se alinham com a maioria dos outros valores em determinado campo.
  • Exceções: exceções são valores que estão significativamente fora (acima ou abaixo) da distribuição estatística dos dados. Às vezes, as exceções são uma indicação de um erro (por exemplo, alguém pode ter um valor com um zero adicional ou omitir um ponto decimal) e às vezes são valores genuínos que são extraordinariamente altos ou baixos em comparação com a maioria das observações. Em ambos os casos, exceções extremas podem afetar negativamente o treinamento de um modelo de aprendizado de máquina; portanto, geralmente é melhor lidar com eles redefinindo-os para um valor de limite superior ou inferior ou removendo registros que contêm exceções do conjunto de dados.
  • Tipos de dados incorretos: os algoritmos de aprendizado de máquina podem ser confidenciais aos tipos de dados atribuídos aos valores do recurso. É comum que conjuntos de dados baseados em arquivos de texto contendo erros ou valores nulos falhem ao converter campos numéricos em um tipo de dados de cadeia de caracteres e, muitas vezes, valores que representam valores inteiros discretos podem falhar ao converter para números decimais (ou vice-versa). Você deve examinar o esquema dos dados e atribuir a eles os tipos apropriados que reflitam com mais eficiência os valores dos dados.
  • Dados desequilibrados: o treinamento de aprendizado de máquina funcionará melhor se os dados de treinamento tiverem representação adequada para todas as diferentes combinações de recursos e rótulos que podem ser encontradas. Em um conjunto de dados desequilibrado, os registros que incluem um valor categórico específico ou uma combinação de campos são super-representados; isso pode influenciar o algoritmo de treinamento e introduzir viés no modelo. Uma técnica comum para atenuar esse problema é superar valores sub-representados por linhas duplicadas incluídas ou amostrar linhas super-representadas (removendo-as do conjunto de dados).

No Azure Databricks, a maneira mais comum de detectar e lidar com esses tipos de problema é escrever código em um notebook que explora e manipula os dados. A classe primária usada para esse tipo de manipulação de dados é o dataframe do Spark.

Por exemplo, o seguinte código carrega dados de um arquivo de texto para um dataframe:

df = spark.read.format("csv").option("header", "true").load("/myfolder/mydata.csv")

Como alternativa, se os dados tiverem sido carregados em uma tabela delta no workspace do Azure Databricks, você poderá usar uma consulta SQL para carregar seus dados em um dataframe:

df = spark.sql("SELECT * FROM mytable")

Depois que os dados são carregados em um dataframe, você pode usar seus métodos e outras funções da biblioteca SQL do Spark para explorar e transformar os dados. Por exemplo, o código a seguir usa o método dropna para remover todas as linhas que incluem valores nulos e atribuir tipos de dados específicos a colunas no dataframe.

clean_data = df.dropna().select(col("column1").astype("string"),
                                col("column2").astype("float"))

Dica

Para obter mais informações sobre a funcionalidade de dataframe do Spark, confira a documentação do Dataframe do Spark.

Engenharia e processamento de recursos

Depois de garantir que o conjunto de dados esteja completo e limpo, você poderá começar a preparar os recursos para o aprendizado de máquina. A engenharia de recursos é uma abordagem iterativa que geralmente envolve alguma avaliação e erro para determinar quais colunas de recurso têm valor preditivo e a melhor maneira de representar os recursos. As tarefas comuns de engenharia e pré-processamento de recursos incluem:

  • Derivação de novos recursos: muitas vezes, você pode derivar recursos novos e mais preditivos dos existentes. Por exemplo, suponha que um conjunto de dados inclua uma coluna de data e você suspeita que a data completa pode não ser um fator preditivo importante na identificação do rótulo, mas que o dia da semana pode ser. Você pode criar um recurso day_of_week derivado da data e testar sua teoria.

  • Como discretizar recursos numéricos: em alguns casos, um valor numérico pode ser mais preditivo quando discretizado em categorias que representam intervalos específicos de valores. Por exemplo, você pode pegar os valores numéricos em um recurso de preço e atribuí-los a categorias baixo, médio e alto com base nos limites apropriados.

  • Codificação de recursos categóricos: muitos conjuntos de dados incluem dados categóricos representados por valores de cadeia de caracteres. No entanto, a maioria dos algoritmos de aprendizado de máquina funciona melhor com os dados numéricos. Portanto, é comum atribuir códigos numéricos para representar categorias em vez de cadeias de caracteres. Por exemplo, um conjunto de dados de detalhes do produto pode incluir o recurso cor, que pode assumir os valores "Verde", "Vermelho" ou "Azul". Você pode codificar esses valores usando códigos inteiros simples, como 0 para "Verde", 1 para "Vermelho" e 2 para "Azul". Como alternativa, você pode usar uma técnica de codificação one-hot na qual se cria uma coluna para cada categoria possível e atribui o valor 1 ou 0 a cada coluna, conforme apropriado para cada linha, da seguinte forma:

    Coluna de cor original Verde Vermelho Azul
    Verde 1 0 0
    Azul 0 0 1
    Vermelho 0 1 0
  • Dimensionamento (normalização) de valores numéricos: os valores de dados numéricos geralmente estão em diferentes escalas ou unidades de medida uns dos outros. Algoritmos de aprendizado de máquina processam todos eles como valores numéricos absolutos, e os recursos de valores maiores geralmente podem dominar o treinamento do modelo. Para resolver esse problema, é comum dimensionar todas as colunas numéricas para que os valores individuais de uma só coluna mantenham a mesma relação proporcional entre si, mas todas as colunas numéricas estão em uma escala semelhante. Por exemplo, suponha que um conjunto de dados contenha valores de comprimento e peso medidos em metros e quilogramas. Você pode converter esses dois recursos em um valor dimensionado entre 0 e 1 da seguinte maneira:

    comprimento peso scaled_length scaled_weight
    250.0 2.1 0,250 0.210
    176.0 0,9 0.176 0,09

Muitas bibliotecas de aprendizado de máquina incluem classes que você pode usar para executar tarefas comuns de engenharia de recursos. Por exemplo, a biblioteca MLlib do Spark inclui a classe StringIndexer, que pode ser usada para executar codificação simples baseada em inteiros para valores de cadeia de caracteres.

from pyspark.ml.feature import StringIndexer

encoder = StringIndexer(inputCol="catCol", outputCol="catColCode")
encoded_data = encoder.fit(data).transform(data)

Observação

Vale a pena explicar o exemplo de código StringIndexer com um pouco mais de detalhes. As classes MLlib do Spark podem incluir avaliadores que se ajustam a um algoritmo para uma operação de transformação específica para alguns dados de exemplo. Nesse caso, o StringIndexer ajusta um algoritmo de codificação aos valores de cadeia de caracteres discretos na coluna catCol do dataframe de dados para determinar os cálculos específicos necessários para gerar uma nova coluna catColCode com os valores codificados. A saída de um avaliador é um transformador que encapsula a função definida pelo avaliador e que pode aplicar essa função aos dados e gerar um novo dataframe. Neste exemplo, passamos os mesmos dados usados para determinar a função de codificação para o transformador resultante para realmente aplicar a codificação.

Na MLLib do Spark, você pode encadear uma sequência de avaliadores e transformadores em um pipeline que executa todas as etapas de engenharia e pré-processamento de recursos necessárias para preparar seus dados. O pipeline pode terminar com um algoritmo de aprendizado de máquina que atua como um avaliador para determinar as operações necessárias a fim de prever um rótulo dos recursos preparados. A saída do pipeline é um modelo de aprendizado de máquina, que na verdade é um transformador que pode ser usado para aplicar a função de modelo a recursos em um dataframe e prever os valores de rótulo correspondentes.