Einführung
In diesem Lab wird der Effekt unterschiedlicher Schwellwerte auf das Selbsttraining illustriert. Der Datensatz breast_cancer wird geladen und die Labels entfernt, sodass nur 50 von 569 Proben Labels haben. Ein SelfTrainingClassifier wird auf diesem Datensatz mit unterschiedlichen Schwellwerten trainiert.
Tipps für die VM
Nachdem der Start der VM abgeschlossen ist, klicken Sie in der oberen linken Ecke, um zur Registerkarte Notebook zu wechseln und Jupyter Notebook für die Übung zu nutzen.
Manchmal müssen Sie einige Sekunden warten, bis Jupyter Notebook vollständig geladen ist. Die Validierung von Vorgängen kann aufgrund der Einschränkungen von Jupyter Notebook nicht automatisiert werden.
Wenn Sie bei der Lernphase Probleme haben, können Sie Labby gerne fragen. Geben Sie nach der Sitzung Feedback, und wir werden das Problem für Sie prompt beheben.
Bibliotheken importieren
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
Zunächst importieren wir die erforderlichen Bibliotheken für dieses Lab.
Daten laden
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]
Der Datensatz breast_cancer wird geladen und gemischt. Anschließend kopieren wir die wahren Labels in y_true und entfernen alle Labels aus y, außer den ersten 50 Proben. Dies wird verwendet, um einen halbüberwachten Lernscenariobereich zu simulieren.
Klassifizierer definieren
base_classifier = SVC(probability=True, gamma=0.001, random_state=42)
Wir definieren unseren Basisklassifizierer als einen Support Vector Machine (SVM) mit einem niedrigen Gamma-Wert von 0,001.
Schwellwerte definieren
x_values = np.arange(0.4, 1.05, 0.05)
x_values = np.append(x_values, 0.99999)
Wir definieren einen Array von Schwellwerten, der von 0,4 bis 1 reicht, mit Schritten von 0,05. Anschließend fügen wir einen sehr hohen Schwellwert von 0,99999 hinzu, um sicherzustellen, dass wir einen Schwellwert enthalten, der keine selbst zugewiesenen Proben hervorruft.
Arrays für die Ergebnisse definieren
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))
Wir definieren Arrays, um die Ergebnisse unseres Experiments zu speichern.
Selbsttraining mit variierendem Schwellwert
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)
Wir durchführen Selbsttraining mit variierenden Schwellwerten, indem wir unseren Basisklassifizierer und die Klasse SelfTrainingClassifier aus scikit-learn verwenden. Wir verwenden stratifizierte Kreuzvalidierung, um unsere Daten in Trainings- und Testsets aufzuteilen. Anschließend trainieren wir den Selbsttrainingsklassifizierer auf dem Trainingsset und berechnen die Genauigkeit des Klassifizierers auf dem Testset. Wir speichern auch die Anzahl der markierten Proben und die Iterationsnummer für jede Fold.
Ergebnisse visualisieren
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()
Wir visualisieren die Ergebnisse unseres Experiments mit Matplotlib. Das obere Diagramm zeigt die Anzahl der markierten Proben, die der Klassifizierer am Ende des Fits zur Verfügung hat, sowie die Genauigkeit des Klassifizierers. Das untere Diagramm zeigt die letzte Iteration, in der eine Probe markiert wurde.
Zusammenfassung
In diesem Lab haben wir gelernt, wie man mit scikit-learn Selbsttraining mit variierenden Schwellwerten durchführt. Wir haben festgestellt, dass der optimale Schwellwert zwischen sehr niedrigen und sehr hohen Schwellwerten liegt und dass die Wahl eines geeigneten Schwellwerts zu signifikanten Verbesserungen der Genauigkeit führen kann.