CodeBlanks Logo Icon CodeBlanks

Training model

Train an SVM model.

The chain and the search

The model chain: median filling → scaling → SVM. Against imbalance, class_weight="balanced" weights the minority class's errors by the inverse of the class share. Settings are searched by F1:

pipe = make_pipeline(SimpleImputer(strategy="median"), StandardScaler(),
                     SVC(class_weight="balanced"))
izgara = {"svc__C": [0.1, 1, 10], "svc__gamma": ["scale", 0.1]}
gs = GridSearchCV(pipe, izgara, cv=5, scoring="f1").fit(X_train, y_train)

The median is more robust to outliers than the mean for filling missing values.

The baseline

To interpret the search result, we first set up an untuned baseline: the same chain, without class_weight and with default settings. Every step of the project is judged by what it adds over this baseline:

temel = make_pipeline(SimpleImputer(strategy="median"), StandardScaler(), SVC())
print(cross_val_score(temel, X_train, y_train, cv=5, scoring="f1").mean())
print(gs.best_score_)

The comparison is done with CV on the training set; the test set is still untouched.

Practice Baseline and search

Compute the 5-fold F1 mean of the untuned baseline chain on the training set. Then search the class_weight="balanced" chain with the grid {"svc__C": [0.1, 1, 10], "svc__gamma": ["scale", 0.1]} using scoring="f1". Print the baseline score, best_score_ (both round(..., 3)) and best_params_ on separate lines.

Starter code

model.py
import numpy as np
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split

X, y = make_classification(n_samples=600, n_features=8, n_informative=4, weights=[0.8, 0.2], random_state=7)
rng = np.random.default_rng(7)
X[rng.random(X.shape) < 0.05] = np.nan
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=0, stratify=y)
from sklearn.pipeline import make_pipeline
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVC
from sklearn.model_selection import GridSearchCV, cross_val_score

# buraya yaz

Sample solution

model.py
import numpy as np
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split

X, y = make_classification(n_samples=600, n_features=8, n_informative=4, weights=[0.8, 0.2], random_state=7)
rng = np.random.default_rng(7)
X[rng.random(X.shape) < 0.05] = np.nan
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=0, stratify=y)
from sklearn.pipeline import make_pipeline
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVC
from sklearn.model_selection import GridSearchCV, cross_val_score

temel = make_pipeline(SimpleImputer(strategy="median"), StandardScaler(), SVC())
print(round(cross_val_score(temel, X_train, y_train, cv=5, scoring="f1").mean(), 3))
pipe = make_pipeline(SimpleImputer(strategy="median"), StandardScaler(), SVC(class_weight="balanced"))
gs = GridSearchCV(pipe, {"svc__C": [0.1, 1, 10], "svc__gamma": ["scale", 0.1]}, cv=5, scoring="f1").fit(X_train, y_train)
print(round(gs.best_score_, 3))
print(gs.best_params_)

Expected output

0.753
0.772
{'svc__C': 1, 'svc__gamma': 'scale'}

Questions and answers

Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.

1 Roughly what weight does <code>class_weight="balanced"</code> give a 20% minority class (relative to the majority)?

  • Equal
  • 0.25 times
  • 20 times
  • 4 times Correct answer

Explanation: The weight is proportional to the inverse of the class share: 0.8 / 0.2 = 4.

2 Balance the class weights automatically.

Question
SVC(class_weight=____)
Answer
SVC(class_weight="balanced")

Explanation: "balanced" computes the weights as n / (k · class_count).

3 Match the chain steps.

Term Meaning
SimpleImputer(median) Fills missing values
StandardScaler Scales
SVC(class_weight) Classifies with balance
scoring="f1" Selection criterion

All lessons in Intermediate