Влияние переменного порога на самообучение

Beginner

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

Введение

В этом практическом занятии показано влияние изменения порога на самообучение. Загружается датасет breast_cancer, а метки удаляются так, чтобы только 50 из 569 образцов имели метки. На этом датасете настраивается SelfTrainingClassifier с различными порогами.

Советы по использованию ВМ

После запуска ВМ нажмите в левом верхнем углу, чтобы переключиться на вкладку Ноутбук и получить доступ к Jupyter Notebook для практики.

Иногда вам может потребоваться подождать несколько секунд, пока Jupyter Notebook загрузится. Валидация операций не может быть автоматизирована из-за ограничений Jupyter Notebook.

Если вы сталкиваетесь с проблемами во время обучения, не стесняйтесь обращаться к Лабби. Оставьте отзыв после занятия, и мы оперативно решим проблему для вас.

Импорт библиотек

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

Сначала мы импортируем необходимые библиотеки для этого практического занятия.

Загрузка данных

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]

Загружается и перемешивается датасет breast_cancer. Затем истинные метки копируются в y_true, а из y удаляются все метки, кроме первых 50 образцов. Это будет использоваться для имитации сценария полунагруженного обучения.

Определение классификатора

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

Мы определяем наш базовый классификатор в виде Support Vector Machine (SVM) с низким значением gamma, равным 0.001.

Определение значений порога

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

Мы определяем массив значений порога, меняющихся от 0.4 до 1 с шагом 0.05. Затем мы добавляем очень высокое значение порога 0.99999, чтобы убедиться, что в массиве есть значение порога, которое не приведет к появлению самоклассифицирующихся образцов.

Определение массивов для результатов

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))

Мы определяем массивы для хранения результатов нашего эксперимента.

Самообучающийся метод с различными порогами

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)

Мы проводим самообучение с различными порогами, используя наш базовый классификатор и класс SelfTrainingClassifier из scikit-learn. Мы используем стратифицированную k-кратную кросс-валидацию, чтобы разбить наши данные на обучающие и тестовые наборы. Затем мы обучаем самообучающий классификатор на обучающем наборе и вычисляем точность классификатора на тестовом наборе. Мы также сохраняем количество помеченных образцов и номер итерации для каждой фолда.

Визуализация результатов

ax1 = plt.subplot(211)
ax1.errorbar(
    x_values, scores.mean(axis=1), yerr=scores.std(axis=1), capsize=2, color="b"
)
ax1.set_ylabel("Accuracy", 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("Amount of labeled samples", 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("Amount of iterations")
ax3.set_xlabel("Threshold")

plt.show()

Мы строим график результатов нашего эксперимента с использованием Matplotlib. Верхний график показывает количество помеченных образцов, доступных классификатору в конце обучения, и точность классификатора. Нижний график показывает последнюю итерацию, в которой был помечен образец.

Резюме

В этом практическом занятии мы научились проводить самообучение с различными значениями порога с использованием scikit-learn. Мы увидели, что оптимальное значение порога находится между очень низким и очень высоким порогами, и что выбор подходящего значения порога может привести к значительному улучшению точности.