Preparar dados para 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á-lo e avaliá-lo. Os dados são ingeridos no Azure Databricks a partir de sua 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 mitigar problemas nos dados que afetarão sua utilidade para o aprendizado de máquina.
  • Engenharia de recursos e pré-processamento: Seleção e transformação de recursos adequados para treinamento de modelos.

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 mitigá-los ao:
    • 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.
    • Remoção total de linhas incompletas (supondo que isso deixe dados representativos adequados suficientes para modelagem)
  • Erros: Não é incomum que os dados incluam erros, causados por erros de entrada de dados ou falha no processamento de dados upstream. 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 um determinado campo.
  • Outliers: Outliers são valores que estão significativamente fora (acima ou abaixo) da distribuição estatística dos dados. Às vezes, os valores atípicos são uma indicação de um erro (por exemplo, alguém pode ter um valor com um zero extra ou omitiu um ponto decimal) e, às vezes, são valores genuínos que são excepcionalmente altos ou baixos em comparação com a maioria das observações. Em ambos os casos, valores atípicos extremos 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 valores atípicos do conjunto de dados.
  • Tipos de dados incorretos: os algoritmos de aprendizado de máquina podem ser sensíveis aos tipos de dados atribuídos aos valores de recurso. É comum que conjuntos de dados baseados em arquivos de texto contendo erros ou valores nulos convertam campos numéricos incorretamente para um tipo de dados de cadeia de caracteres e, muitas vezes, valores que representam valores inteiros discretos podem ser mal convertidos para números decimais (ou vice-versa). Você deve examinar o esquema de seus dados e atribuir os tipos de dados apropriados que refletem mais efetivamente os valores de dados.
  • Dados desequilibrados: o treinamento de aprendizado de máquina funciona melhor se os dados de treinamento tiverem representação adequada para todas as diferentes combinações de recursos e rótulos que possam ser encontradas. Em um conjunto de dados desequilibrado, os registros que incluem um determinado valor categórico ou combinação de campos são sobre-representados; que pode influenciar o algoritmo de treinamento e introduzir viés no modelo. Uma técnica comum para atenuar esse problema é a superamostragem de valores sub-representados por linhas duplicadas incluídas ou a subamostragem de linhas sobre-representadas (removendo-as do conjunto de dados).

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

Por exemplo, o código a seguir carrega dados de um arquivo de texto em 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 espaço de trabalho 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 na biblioteca SQL do Spark para explorar e transformar os dados. Por exemplo, o código a seguir usa o método dropna para remover quaisquer linhas que incluam valores nulos e atribui tipos de dados específicos a colunas no dataframe.

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

Gorjeta

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

Engenharia de recursos e pré-processamento

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

  • Derivando 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ê suspeite 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 novo recurso de day_of_week derivado da data e testar sua teoria.

  • Características numéricas discretizantes: 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 em categorias baixas, médias e altas com base nos limites apropriados.

  • Codificação de recursos categóricos: Muitos conjuntos de dados incluem dados categóricos que são representados por valores de cadeia de caracteres. No entanto, a maioria dos algoritmos de aprendizado de máquina funciona melhor com 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 um recurso para cor que pode ter um valor de "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 você cria uma nova 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
    Blue 0 0 1
    Vermelho 0 1 0
  • Dimensionamento (normalização) de valores numéricos: Os valores de dados numéricos geralmente estão em escalas ou unidades de medida diferentes uns dos outros. Os algoritmos de aprendizado de máquina processam todos eles como valores numéricos absolutos, e recursos com valores maiores muitas vezes podem dominar o treinamento do modelo. Para resolver esse problema, é comum dimensionar todas as colunas numéricas para que os valores individuais de uma única 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 forma:

    length 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 Spark MLlib inclui a classe StringIndexer , que você pode usar para executar codificação simples baseada em números 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)

Nota

Vale a pena explicar o exemplo de código StringIndexer com um pouco mais de detalhes. As classes Spark MLlib podem incluir avaliadores que ajustam um algoritmo para uma operação de transformação específica a alguns dados de exemplo. Nesse caso, o StringIndexer ajusta um algoritmo de codificação aos valores de cadeia de caracteres discretos na coluna catCol no dataframe de dados para determinar os cálculos específicos necessários para gerar uma nova coluna catColCode contendo 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.

No Spark MLLib, você pode encadear uma sequência de avaliadores e transformadores juntos em um pipeline que executa todas as etapas de engenharia de recursos e pré-processamento 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 para prever um rótulo a partir 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.