Efeito de Variação de Limiar no Auto-Treinamento

Beginner

This tutorial is from open-source community. Access the source code

Introdução

Este laboratório ilustra o efeito da variação do limiar no auto-aprendizado. O conjunto de dados breast_cancer é carregado, e as etiquetas são excluídas de forma que apenas 50 de 569 amostras tenham etiquetas. Um SelfTrainingClassifier é ajustado neste conjunto de dados, com limiares variáveis.

Dicas da Máquina Virtual

Após o arranque da máquina virtual, clique no canto superior esquerdo para mudar para a aba Notebook para aceder ao Jupyter Notebook para a prática.

Por vezes, pode ser necessário esperar alguns segundos para o Jupyter Notebook terminar o carregamento. A validação das operações não pode ser automatizada devido a limitações no Jupyter Notebook.

Se tiver problemas durante a aprendizagem, não hesite em contactar o Labby. Forneça feedback após a sessão, e resolveremos prontamente o problema para si.

Importar Bibliotecas

import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
from sklearn.svm import SVC
from sklearn.model_selection import StratifiedKFold
from sklearn.semi_supervised import SelfTrainingClassifier
from sklearn.metrics import accuracy_score
from sklearn.utils import shuffle

Primeiro, importamos as bibliotecas necessárias para este laboratório.

Carregar Dados

X, y = datasets.load_breast_cancer(return_X_y=True)
X, y = shuffle(X, y, random_state=42)
y_true = y.copy()
y[50:] = -1
total_samples = y.shape[0]

O conjunto de dados breast_cancer é carregado e embaralhado. Em seguida, as etiquetas verdadeiras são copiadas para y_true, e todas as etiquetas são removidas, exceto as primeiras 50 amostras de y. Isto será usado para simular um cenário de aprendizagem semi-supervisionada.

Definir Classificador

base_classifier = SVC(probability=True, gamma=0.001, random_state=42)

Definimos o nosso classificador base como uma Máquina de Vetores de Suporte (SVM) com um valor baixo de gama de 0,001.

Definir Valores de Limiar

x_values = np.arange(0.4, 1.05, 0.05)
x_values = np.append(x_values, 0.99999)

Definimos um array de valores de limiar que variam de 0,4 a 1, com incrementos de 0,05. Em seguida, adicionamos um valor de limiar muito alto, 0,99999, para garantir que incluímos um valor que não resultará em amostras auto-rotuladas.

Definir Arrays para Resultados

scores = np.empty((x_values.shape[0], n_splits))
amount_labeled = np.empty((x_values.shape[0], n_splits))
amount_iterations = np.empty((x_values.shape[0], n_splits))

Definimos arrays para armazenar os resultados do nosso experimento.

Auto-treinamento com Limiares Variáveis

for i, threshold in enumerate(x_values):
    self_training_clf = SelfTrainingClassifier(base_classifier, threshold=threshold)

    skfolds = StratifiedKFold(n_splits=n_splits)
    for fold, (train_index, test_index) in enumerate(skfolds.split(X, y)):
        X_train = X[train_index]
        y_train = y[train_index]
        X_test = X[test_index]
        y_test = y[test_index]
        y_test_true = y_true[test_index]

        self_training_clf.fit(X_train, y_train)

        amount_labeled[i, fold] = (
            total_samples
            - np.unique(self_training_clf.labeled_iter_, return_counts=True)[1][0]
        )

        amount_iterations[i, fold] = np.max(self_training_clf.labeled_iter_)

        y_pred = self_training_clf.predict(X_test)
        scores[i, fold] = accuracy_score(y_test_true, y_pred)

Realizamos auto-treinamento com diferentes limiares, utilizando o nosso classificador base e a classe SelfTrainingClassifier do scikit-learn. Usamos validação cruzada estratificada k-fold para dividir os nossos dados em conjuntos de treino e teste. Em seguida, ajustamos o classificador de auto-treinamento no conjunto de treino e calculamos a precisão do classificador no conjunto de teste. Também armazenamos a quantidade de amostras rotuladas e o número de iteração para cada dobra.

Visualizar Resultados

ax1 = plt.subplot(211)
ax1.errorbar(
    x_values, scores.mean(axis=1), yerr=scores.std(axis=1), capsize=2, color="b"
)
ax1.set_ylabel("Precisão", color="b")
ax1.tick_params("y", colors="b")

ax2 = ax1.twinx()
ax2.errorbar(
    x_values,
    amount_labeled.mean(axis=1),
    yerr=amount_labeled.std(axis=1),
    capsize=2,
    color="g",
)
ax2.set_ylim(bottom=0)
ax2.set_ylabel("Quantidade de amostras rotuladas", color="g")
ax2.tick_params("y", colors="g")

ax3 = plt.subplot(212, sharex=ax1)
ax3.errorbar(
    x_values,
    amount_iterations.mean(axis=1),
    yerr=amount_iterations.std(axis=1),
    capsize=2,
    color="b",
)
ax3.set_ylim(bottom=0)
ax3.set_ylabel("Quantidade de iterações")
ax3.set_xlabel("Limiar")

plt.show()

Plotamos os resultados do nosso experimento usando Matplotlib. O gráfico superior mostra a quantidade de amostras rotuladas disponíveis para o classificador no final do ajuste, bem como a precisão do classificador. O gráfico inferior mostra a última iteração em que uma amostra foi rotulada.

Resumo

Neste laboratório, aprendemos como realizar auto-treinamento com diferentes valores de limiar utilizando a biblioteca scikit-learn. Vimos que o valor de limiar ideal encontra-se entre limiares muito baixos e muito altos, e que a escolha de um valor de limiar apropriado pode resultar em melhorias significativas na precisão.