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
| Modell | Trainingszeit (Größenordnung) | Qualität |
|---|---|---|
LinearSVC, 43k Beispiele | einige Minuten | ≈ LogReg-Baseline, oft 1–3 Punkte drüber |
SVC(rbf), 10k Subsample | zweistellige Minuten | kann LinearSVC schlagen — trotz weniger Daten |
SVC(rbf), alle 43k | Stunden + viel RAM | selten 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 Denkfehler — dual 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 rein — Der 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.