Validação Cruzada com Scikit-learn

scikit-learnBeginner
Pratique Agora

Introdução

Em aprendizado de máquina (machine learning), frequentemente dividimos nossos dados em um conjunto de treinamento (training set) e um conjunto de teste (testing set) para avaliar o desempenho de um modelo. No entanto, essa avaliação pode depender fortemente de quais pontos de dados acabam no conjunto de treinamento em comparação com o conjunto de teste. Um método mais robusto é a validação cruzada (cross-validation - CV).

Por que validação cruzada?

  • Reduz o risco de overfitting: Testa o modelo em múltiplas divisões de dados
  • Melhor estimativa de generalização: Desempenho mais confiável em dados não vistos
  • Maximiza o uso de dados: Cada amostra é usada tanto para treinamento quanto para teste

A validação cruzada envolve dividir o conjunto de dados em múltiplos "folds" (dobras) e, em seguida, treinar e avaliar o modelo várias vezes, usando um fold diferente para teste a cada vez. Isso nos dá uma estimativa mais confiável do desempenho do modelo em dados não vistos.

Neste laboratório, você aprenderá a usar as funções poderosas e convenientes do scikit-learn para realizar validação cruzada em um classificador usando o famoso conjunto de dados Iris. Você aprenderá a usar cross_val_score para obter pontuações de desempenho e, em seguida, calcular sua média e desvio padrão para entender melhor a estabilidade do modelo e a precisão geral.

Este é um Lab Guiado, que fornece instruções passo a passo para ajudá-lo a aprender e praticar. Siga as instruções cuidadosamente para completar cada etapa e ganhar experiência prática. Dados históricos mostram que este é um laboratório de nível iniciante com uma taxa de conclusão de 94%. Recebeu uma taxa de avaliações positivas de 100% dos estudantes.

Importar cross_val_score de sklearn.model_selection

Nesta etapa, você começará importando a função necessária para realizar a validação cruzada. A função cross_val_score é a principal ferramenta no scikit-learn para este propósito. Ela simplifica o processo de dividir dados, treinar o modelo e pontuá-lo em múltiplos folds.

Primeiro, abra o arquivo main.py localizado no diretório ~/project usando o explorador de arquivos no lado esquerdo do seu IDE.

Agora, adicione a instrução de importação para cross_val_score ao seu script main.py. Coloque-a junto com as outras importações no topo do arquivo.

from sklearn.model_selection import cross_val_score

Seu arquivo main.py agora deve se parecer com isto:

import numpy as np
from sklearn import datasets
from sklearn.svm import SVC
from sklearn.model_selection import cross_val_score

## Load the iris dataset
iris = datasets.load_iris()
X, y = iris.data, iris.target

## Initialize a Support Vector Classifier (SVC)
## Parameters explained:
## - kernel='linear': Uses a linear kernel for linearly separable data like Iris
## - C=1: Regularization parameter (higher values = less regularization)
## - random_state=42: Ensures reproducible results across runs
clf = SVC(kernel='linear', C=1, random_state=42)

## --- Your code will go below this line ---

Você pode executar o script para garantir que não haja erros de sintaxe. Abra um terminal no seu IDE e execute o seguinte comando:

python3 main.py

Você não deverá ver nenhuma saída, o que é esperado, pois ainda não adicionamos nenhum código para produzir saída.

Inicializar KFold com n_splits=5 de sklearn.model_selection

Embora cross_val_score possa lidar automaticamente com a divisão, é uma boa prática entender o mecanismo subjacente. A estratégia de validação cruzada mais comum é K-Fold, onde o conjunto de dados é dividido em 'k' folds. O modelo é treinado em k-1 folds e testado no fold restante, repetindo esse processo k vezes.

Parâmetros do KFold:

  • n_splits=5: Divide os dados em 5 partes iguais (folds)
  • shuffle=False (padrão): Mantém a ordem original dos dados
  • random_state: Controla a aleatoriedade se shuffle=True

A classe KFold no scikit-learn é um iterador de validação cruzada que fornece índices de treino/teste para dividir os dados. Embora usaremos um atalho mais simples na próxima etapa, entender KFold é fundamental.

Vamos importar KFold e ver como inicializá-lo. Adicione as seguintes linhas ao seu arquivo main.py.

Primeiro, adicione a instrução de importação no topo:

from sklearn.model_selection import KFold

Em seguida, você pode inicializá-lo. No entanto, para este laboratório, confiaremos no parâmetro cv de cross_val_score, que é uma abordagem mais direta. O objetivo desta etapa é introduzi-lo ao conceito de KFold. Por uma questão de simplicidade e para seguir o fluxo do laboratório, não adicionaremos o código de inicialização do KFold ao nosso script. Usaremos diretamente cv=5 na próxima etapa, que internamente utiliza uma estratégia K-Fold. Esta é a maneira mais comum e direta de realizar validação cruzada.

Vamos prosseguir para a próxima etapa, onde usaremos este conceito na prática. Como nenhum código foi adicionado nesta etapa, você pode clicar em "Continuar" para avançar.

Realizar validação cruzada com cross_val_score(clf, X, y, cv=5)

Agora é hora de realizar a validação cruzada. Usaremos a função cross_val_score que importamos anteriormente. Esta função aceita vários argumentos:

Parâmetros do cross_val_score:

  • estimator: O modelo a ser avaliado (nosso classificador clf)
  • X: A matriz de dados de features
  • y: O array de rótulos alvo
  • cv=5: Estratégia de validação cruzada (inteiro = k-fold, ou objeto CV splitter)
  • scoring: Métrica de avaliação (o padrão usa o método de pontuação do estimador)
  • n_jobs: Número de núcleos de CPU a serem usados (padrão=1, -1 para todos os núcleos)

Ao definir cv=5, estamos dizendo ao scikit-learn para realizar uma validação cruzada de 5 folds. Ele dividirá automaticamente os dados em 5 folds, em seguida, treinará e testará o modelo 5 vezes, retornando um array contendo a pontuação para cada execução.

Adicione o seguinte código ao final do seu arquivo main.py, abaixo da linha de comentário:

## Perform 5-fold cross-validation
scores = cross_val_score(clf, X, y, cv=5)

## Print the array of scores
print("Scores:", scores)

Seu arquivo main.py completo agora deve se parecer com isto:

import numpy as np
from sklearn import datasets
from sklearn.svm import SVC
from sklearn.model_selection import cross_val_score

## Load the iris dataset
iris = datasets.load_iris()
X, y = iris.data, iris.target

## Initialize a Support Vector Classifier (SVC)
## Parameters explained:
## - kernel='linear': Uses a linear kernel for linearly separable data like Iris
## - C=1: Regularization parameter (higher values = less regularization)
## - random_state=42: Ensures reproducible results across runs
clf = SVC(kernel='linear', C=1, random_state=42)

## --- Your code will go below this line ---

## Perform 5-fold cross-validation
scores = cross_val_score(clf, X, y, cv=5)

## Print the array of scores
print("Scores:", scores)

Agora, execute o script do seu terminal:

python3 main.py

Você verá a saída mostrando um array de 5 pontuações, uma para cada fold da validação cruzada.

Scores: [0.96666667 1.         0.96666667 0.96666667 1.        ]
Mean score: 0.9800000000000001
Standard deviation: 0.016329931618554516

Suas pontuações podem ser ligeiramente diferentes dependendo da divisão exata, mas devem ser semelhantes. Este array oferece uma visão detalhada de como o modelo se comportou em diferentes subconjuntos dos dados.

Calcular a pontuação média de CV com scores.mean()

Ter um array de pontuações é informativo, mas para um resumo rápido do desempenho do modelo, geralmente calculamos a média dessas pontuações. Este único valor nos dá uma ideia geral da precisão do modelo.

A função cross_val_score retorna um array NumPy, que vem com muitos métodos úteis, incluindo .mean(). Podemos chamar este método diretamente em nossa variável scores.

Adicione as seguintes linhas ao final do seu script main.py para calcular e imprimir a pontuação média:

## Compute and print the mean of the scores
mean_score = scores.mean()
print("Mean score:", mean_score)

Seu arquivo main.py agora deve conter o seguinte código:

import numpy as np
from sklearn import datasets
from sklearn.svm import SVC
from sklearn.model_selection import cross_val_score

## Load the iris dataset
iris = datasets.load_iris()
X, y = iris.data, iris.target

## Initialize a Support Vector Classifier (SVC)
## Parameters explained:
## - kernel='linear': Uses a linear kernel for linearly separable data like Iris
## - C=1: Regularization parameter (higher values = less regularization)
## - random_state=42: Ensures reproducible results across runs
clf = SVC(kernel='linear', C=1, random_state=42)

## --- Your code will go below this line ---

## Perform 5-fold cross-validation
scores = cross_val_score(clf, X, y, cv=5)

## Print the array of scores
print("Scores:", scores)

## Compute and print the mean of the scores
mean_score = scores.mean()
print("Mean score:", mean_score)

Execute o script novamente:

python3 main.py

A saída agora incluirá a média das 5 pontuações, fornecendo uma métrica de desempenho única e representativa.

Scores: [0.96666667 1.         0.96666667 0.96666667 1.        ]
Mean score: 0.9800000000000001

Calcular o desvio padrão das pontuações de CV com scores.std()

A pontuação média nos diz o desempenho médio, mas não nos diz o quão consistente é esse desempenho. O desvio padrão das pontuações nos dá uma medida dessa variância.

Interpretando o desvio padrão:

  • Baixo std (< 0.05): O modelo tem um desempenho consistente em todos os subconjuntos de dados
  • Médio std (0.05-0.15): Variação moderada, aceitável para a maioria dos casos
  • Alto std (> 0.15): Grande variação de desempenho, pode indicar problemas nos dados ou instabilidade do modelo

Um baixo desvio padrão indica que o desempenho do modelo é estável em diferentes subconjuntos dos dados, enquanto um alto desvio padrão sugere que o desempenho é mais variável.

Assim como .mean(), os arrays NumPy também possuem um método .std() para calcular o desvio padrão.

Adicione a última parte do código ao seu script main.py para calcular e imprimir o desvio padrão:

## Compute and print the standard deviation of the scores
std_dev = scores.std()
print("Standard deviation:", std_dev)

Seu script main.py final está agora completo e deve se parecer com isto:

import numpy as np
from sklearn import datasets
from sklearn.svm import SVC
from sklearn.model_selection import cross_val_score

## Load the iris dataset
iris = datasets.load_iris()
X, y = iris.data, iris.target

## Initialize a Support Vector Classifier (SVC)
## Parameters explained:
## - kernel='linear': Uses a linear kernel for linearly separable data like Iris
## - C=1: Regularization parameter (higher values = less regularization)
## - random_state=42: Ensures reproducible results across runs
clf = SVC(kernel='linear', C=1, random_state=42)

## --- Your code will go below this line ---

## Perform 5-fold cross-validation
scores = cross_val_score(clf, X, y, cv=5)

## Print the array of scores
print("Scores:", scores)

## Compute and print the mean of the scores
mean_score = scores.mean()
print("Mean score:", mean_score)

## Compute and print the standard deviation of the scores
std_dev = scores.std()
print("Standard deviation:", std_dev)

Execute o script mais uma vez:

python3 main.py

A saída final mostrará o array de pontuações, sua média e seu desvio padrão, fornecendo uma avaliação abrangente do desempenho do seu modelo.

Scores: [0.96666667 1.         0.96666667 0.96666667 1.        ]
Mean score: 0.9800000000000001
Standard deviation: 0.016329931618554516

Resumo

Parabéns por completar este laboratório! Você aprendeu com sucesso como realizar e interpretar uma validação cruzada k-fold usando scikit-learn.

Neste laboratório, você:

  • Compreendeu a importância da validação cruzada para uma avaliação robusta do modelo.
  • Utilizou a função cross_val_score para realizar facilmente validação cruzada de 5 dobras em um Classificador de Vetor de Suporte (Support Vector Classifier).
  • Analisou os resultados calculando e imprimindo a média e o desvio padrão das pontuações da validação cruzada.

Dicas práticas para validação cruzada:

  • Use CV de 5 ou 10 dobras para a maioria dos cenários
  • Considere CV estratificada para conjuntos de dados desbalanceados
  • Use cross_validate em vez de cross_val_score para métricas múltiplas
  • Sempre defina random_state para resultados reproduzíveis

Esta técnica é uma parte fundamental do fluxo de trabalho de aprendizado de máquina, garantindo que o desempenho do seu modelo seja confiável e não apenas o resultado de uma divisão sortuda de treino-teste. Agora você pode aplicar esse conhecimento para avaliar seus próprios modelos de aprendizado de máquina com maior confiança.