Praxis: SVC auf PlantVillage

Dank der scikit-learn-API ist der Tausch LogReg → SVM eine Zeile. Die eigentliche Lektion hier ist eine andere: Bei 43.000 Trainingsbildern entscheidet die Skalierbarkeit des Verfahrens, nicht nur seine Genauigkeit.

Das Problem: Kernel-SVMs trainieren zwischen O(n²) und O(n³) in der Anzahl der Beispiele. 43.000 Beispiele sind für SVC bereits Schmerzgrenze — für LinearSVC dagegen kein Thema.

Variante 1: LinearSVC — der Arbeitsgaul

PYTHONsvm_linear.py
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.svm import LinearSVC
from sklearn.metrics import classification_report

# Features + Split wie in den Grundlagen-Lektionen
pipe = make_pipeline(
    StandardScaler(),
    LinearSVC(C=1.0, max_iter=5000),
)
pipe.fit(X_train, y_train)          # Minuten, nicht Stunden

print(classification_report(y_test, pipe.predict(X_test), digits=3))

LinearSVC nutzt einen spezialisierten Solver (liblinear), der die Kernel-Maschinerie weglässt und direkt im Feature-Raum optimiert. Multiclass läuft als One-vs-Rest: 38 binäre Klassifikatoren, jeder trennt eine Klasse vom Rest.

Variante 2: SVC mit RBF — teuer, aber gekrümmt

PYTHONsvm_rbf.py
from sklearn.svm import SVC
import numpy as np

# Bei 43.000 Beispielen: erstmal auf einem Subsample testen!
rng = np.random.default_rng(42)
idx = rng.choice(len(X_train), size=10_000, replace=False)

pipe_rbf = make_pipeline(
    StandardScaler(),
    SVC(kernel="rbf", C=10, gamma="scale", cache_size=1000),
)
pipe_rbf.fit(X_train[idx], np.array(y_train)[idx])

print(classification_report(y_test, pipe_rbf.predict(X_test), digits=3))

Was man typischerweise sieht

ModellTrainingszeit (Größenordnung)Qualität
LinearSVC, 43k Beispieleeinige Minuten≈ LogReg-Baseline, oft 1–3 Punkte drüber
SVC(rbf), 10k Subsamplezweistellige Minutenkann LinearSVC schlagen — trotz weniger Daten
SVC(rbf), alle 43kStunden + viel RAMselten den Aufpreis wert

Auch die Vorhersage skaliert unterschiedlich: LinearSVC wertet pro Bild ein Skalarprodukt aus, SVC(rbf) den Kernel gegen jeden Support-Vektor — bei verrauschten Daten können das Tausende sein. Für eine Smartphone-App zur Blatt-Diagnose ist das ein Ausschlusskriterium.

Warum eigentlich?Warum probability=True doppelt kostet
SVC(probability=True) trainiert intern per 5-Fold-CV eine Platt-Kalibrierung — das Training läuft also effektiv sechsmal. Bei einem ohnehin O(n²)-Verfahren ist das der Unterschied zwischen „Kaffeepause“ und „über Nacht“. Wer nur ein Ranking der Klassen braucht, nimmt decision_function; wer echte Wahrscheinlichkeiten braucht, sollte den Bedarf hinterfragen oder gleich zur LogReg greifen.
Häufiger Denkfehlerdual und max_iter bei LinearSVC ignorieren
Zwei typische Stolperer: (1) LinearSVC warnt bei knappem Iterationsbudget genau wie LogReg — max_iter hochsetzen statt Warnung wegklicken. (2) Der Parameter dual: Bei mehr Beispielen als Features (43.000 ≫ 512) ist dual=False die schnellere Formulierung. Neuere sklearn-Versionen wählen mit dual="auto" selbst — ältere Defaults taten es nicht, und das kostete grundlos Trainingszeit.
Tiefer reinDer Mittelweg: Kernel-Approximation
Es gibt einen dritten Weg, der beide Welten verbindet: Random Fourier Features approximieren den RBF-Kernel durch eine explizite Zufalls-Transformation in z.B. 1.000 Dimensionen — danach trainiert man ein lineares Modell auf den transformierten Daten. In sklearn: RBFSampler + LinearSVC. Man bekommt gekrümmte Entscheidungsgrenzen zum Preis eines linearen Trainings — für große Datasets oft der beste SVM-Deal überhaupt.