Conheça as transformações de conjuntos de dados

Entenda o pré-processamento, o balanceamento, a estratificação e a adequação do conjunto de dados para o aprendizado de máquina.

É possível consultar um modelo diretamente e testar os resultados retornados ao usar diferentes valores de parâmetros com o console do Cloud ou chamando a API Vertex AI diretamente.

Comando Freeform

Estou trabalhando em um projeto de aprendizado de máquina e preciso da sua ajuda para entender o processo de transformação de grandes conjuntos de dados. Confira abaixo o código que lida com valores ausentes, padroniza os valores e equilibra os dados. Você pode explicar esse código? Preciso saber se a ordem dessas etapas é importante. Se os dados de treinamento forem balanceados mais tarde, ainda preciso estratificar os dados na divisão? Além disso, os dados de teste precisam ser equilibrados antes de avaliar o desempenho do modelo? Por fim, resuma o tipo de dados apropriado para esse fluxo de trabalho.

import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import OneHotEncoder, StandardScaler
from sklearn.compose import ColumnTransformer
from sklearn.pipeline import Pipeline
from imblearn.over_sampling import SMOTENC


df = pd.read_csv('my_dataset.csv')

# Remove duplicate rows from the dataset
df.drop_duplicates(inplace=True)

# Separate the features (X) and the target variable (y)
X = df.drop('target', axis=1)
y = df['target']

# Split the data into training and test sets
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42, stratify=y)

# Check class distribution
print(f"Original training set class distribution: {np.bincount(y_train)}")

# Identify numeric and categorical features
numeric_features = [col for col in X_train.columns if 'num_feature' in col]
categorical_features = [col for col in X_train.columns if 'cat_feature' in col]

# Preprocessing pipeline for numeric missing values and feature scaling
numeric_transformer = Pipeline(steps=[
    ('imputer', SimpleImputer(strategy='mean')),
    ('scaler', StandardScaler())
])
# Preprocessing pipeline for categorical missing values and encoding
categorical_transformer = Pipeline(steps=[
    ('imputer', SimpleImputer(strategy='most_frequent')),
    ('onehot', OneHotEncoder(handle_unknown='ignore'))
])
# Preprocessing
preprocessor = ColumnTransformer(
    transformers=[
        ('num', numeric_transformer, numeric_features),
        ('cat', categorical_transformer, categorical_features)
    ])
X_train_processed = preprocessor.fit_transform(X_train)
X_test_processed = preprocessor.transform(X_test)

# Class balancing
categorical_indices = [X_train.columns.get_loc(col) for col in categorical_features]
smote_nc = SMOTENC(categorical_features=categorical_indices, random_state=42)
X_train_resampled, y_train_resampled = smote_nc.fit_resample(X_train_processed, y_train)

print(f"Resampled training set class distribution: {np.bincount(y_train_resampled)}")

Resposta

Esse código executa várias etapas de pré-processamento essenciais em um conjunto de dados antes de alimentá-lo em um modelo de aprendizado de máquina. Vamos analisar o código passo a passo e responder às suas perguntas durante o processo.

Explicação do código:

  1. Carregamento de dados e remoção de duplicações: o código começa carregando um arquivo CSV (my_dataset.csv) em um DataFrame do pandas e remove linhas duplicadas.

  2. Separação de atributos e destino: separa o conjunto de dados em atributos (X) e a variável de destino (y). A coluna "target" é considerada a variável de destino.

  3. Divisão de treinamento e teste: os dados são divididos em conjuntos de treinamento e teste usando train_test_split. Fundamentalmente, stratify=y garante que as proporções de classe na variável de destino (y) sejam mantidas nos conjuntos de treinamento e teste. Isso é importante para evitar viés, especialmente se você tiver um conjunto de dados desbalanceado.

  4. Verificação da distribuição de classes: o código mostra a distribuição de classes da variável de destino no conjunto de treinamento antes do balanceamento.

  5. Identificação de atributos: o código identifica atributos categóricos e numéricos com base em convenções de nomenclatura ("num_feature" e "cat_feature" nos nomes das colunas). Isso considera que as colunas sejam nomeadas de forma a distinguir claramente entre atributos categóricos e numéricos. Um método mais robusto pode envolver a inspeção direta dos tipos de dados.

  6. Pipelines de pré-processamento: são criados dois pipelines:

    • numeric_transformer: processa atributos numéricos. Primeiro, ele insere valores ausentes usando a média (SimpleImputer(strategy='mean')) e, em seguida, padroniza os atributos usando StandardScaler.
    • categorical_transformer: processa atributos categóricos. Ele insere valores ausentes usando o valor mais frequente (SimpleImputer(strategy='most_frequent')) e faz a codificação one-hot dos atributos usando OneHotEncoder(handle_unknown='ignore'). O parâmetro handle_unknown='ignore' é crucial. Ele processa categorias não vistas no conjunto de teste atribuindo a elas um vetor de zeros.
  7. ColumnTransformer: um ColumnTransformer combina os dois pipelines, aplicando o pipeline apropriado a cada tipo de atributo.

  8. Transformação de dados: o método fit_transform é chamado nos dados de treinamento para ajustar os transformadores e transformar os dados simultaneamente. O transform é usado nos dados de teste para aplicar as mesmas transformações aprendidas com os dados de treinamento. É crucial se ajustar apenas aos dados de treinamento para evitar o vazamento de dados.

  9. Balanceamento de classes com SMOTENC: a SMOTENC (técnica sintética de sobreamostragem de minoria para atributos nominais e de valor contínuo) é usada para sobreamostrar as classes minoritárias nos dados de treinamento. Isso resolve o desbalanceamento de classes. Sobretudo, ele usa os índices de atributos categóricos como entrada para processá-los adequadamente durante a sobreamostragem.

  10. Distribuição de classes de reamostragem: o código mostra a distribuição de classes do conjunto de treinamento após o balanceamento.

Respostas às perguntas:

  • Ordem das etapas: a ordem é muito importante. Você precisa do seguinte:

    1. Divisão: divida em conjuntos de treinamento e de teste antes de qualquer pré-processamento ou balanceamento. Isso evita a perda de dados do conjunto de teste para o conjunto de treinamento.
    2. Pré-processamento: aplique etapas de pré-processamento (inserção e escalonamento/codificação) aos conjuntos de treinamento e teste. Ajuste os transformadores apenas nos dados de treinamento e, em seguida, transforme os dados de treinamento e de teste.
    3. Balanceamento: faça o balanceamento dos dados de treinamento usando apenas técnicas como a SMOTE. Nunca faça o balanceamento do conjunto de teste.
  • Estratificar na divisão: como você fará o balanceamento dos dados de treinamento mais tarde usando SMOTE, é possível remover stratify=y do train_test_split. No entanto, mantê-lo é uma boa prática geralmente. A estratificação garante uma distribuição de classes representativa na divisão inicial, mesmo que você modifique o balanceamento do conjunto de treinamento mais tarde. A remoção da estratificação pode levar a um conjunto de testes um pouco menos representativo, mas o impacto geralmente é menor em comparação com os benefícios da amostragem estratificada.

  • Balanceamento dos dados de teste: não, nunca faça o balanceamento dos dados de teste. Os dados de teste precisam refletir a distribuição real dos seus dados. O balanceamento inflaria artificialmente as métricas de desempenho e forneceria uma avaliação enganosa da capacidade de generalização do modelo.

  • Dados adequados: esse fluxo de trabalho é adequado para conjuntos de dados com:

    • Uma combinação de atributos categóricos e numéricos.
    • Valores ausentes em atributos categóricos e numéricos.
    • Uma distribuição de classes desbalanceada na variável de destino.
    • Um número suficiente de amostras para evitar o overfitting após a sobreamostragem. A SMOTE pode criar amostras sintéticas, mas ainda é importante ter pontos de dados originais suficientes para aprender padrões significativos.

Em resumo, esse código oferece uma abordagem robusta e bem estruturada para pré-processamento de dados para aprendizado de máquina, processamento de valores ausentes, dimensionamento, codificação e desbalanceamento de classes de maneira eficaz. A ordem das operações é crucial para evitar o vazamento de dados e conseguir uma avaliação confiável do modelo.

Modelo: gemini-1.5-flash-002
Temperatura: 0,2
Máximo de tokens de saída: 8192
TopK: 40.0
TopP: 0,95