Învățare supervizată

2.2 Regresia logistică

În ciuda numelui, este un model de clasificare: răspunde la întrebări de tip da/nu — are diabet sau nu, e spam sau nu — cu o probabilitate între 0 și 1.

Teorie

Clasificare binară

La regresie prezicem un număr oarecare; la clasificare binară prezicem o clasă: 0 sau 1. Trucul regresiei logistice: calculează întâi un scor liniar z = w₁x₁ + … + wₙxₙ + b, apoi îl transformă în probabilitate.

Funcția sigmoid

σ(z) = 1 / (1 + e⁻ᶻ)

Sigmoidul „strivește" orice număr real în intervalul (0, 1): pentru z foarte negativ → aproape 0, pentru z = 0 → exact 0.5, pentru z foarte pozitiv → aproape 1. Rezultatul se citește ca probabilitatea clasei 1. Predicția finală: clasa 1 dacă probabilitatea ≥ 0.5 (prag implicit, care poate fi modificat — vezi lecția 4.4).

Interpretarea rezultatelor

predict_proba întoarce probabilitățile, predict doar clasa. Un pacient cu probabilitate 0.93 e o predicție sigură; unul cu 0.51 e la limită — în aplicații medicale asta contează enorm. Coeficienții pozitivi împing spre clasa 1, cei negativi spre clasa 0.

Implementarea din scikit-learn

from sklearn.linear_model import LogisticRegression

model = LogisticRegression(max_iter=1000)
model.fit(X_train, y_train)

model.predict(X_val)           # clase: [0, 1, 1, ...]
model.predict_proba(X_val)     # probabilități: [[0.9, 0.1], ...]
model.coef_, model.intercept_  # w și b
Regresia logistică merge și pe mai mult de două clase (multinomial) — sklearn se ocupă automat, ca la Iris în lecția 1.4.

Problemă rezolvată: diagnosticarea diabetului

Diagnosticarea diabetului pe baza analizelor de sânge Mediu Rezolvată — 70p

Pe baza analizelor (glucoză, tensiune, BMI, vârstă), prezicem dacă pacientul are diabet (1) sau nu (0) — clasificare binară pură.

Soluția pas cu pas

1. Analizele de sânge cu valoarea 0 sunt de fapt valori lipsă (glucoză 0 nu există) → le înlocuim cu mediana. 2. Standardizăm. 3. Regresie logistică + verificăm și F1, nu doar acuratețea (clasele pot fi dezechilibrate).

import pandas as pd
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import f1_score, accuracy_score

train = pd.read_csv("train.csv")
test = pd.read_csv("test.csv")
feats = [c for c in train.columns if c not in ("SampleID", "diabet")]

# 0 fiziologic imposibil = valoare lipsă
for col in ["glucoza", "tensiune", "bmi"]:
    med = train.loc[train[col] > 0, col].median()
    train[col] = train[col].replace(0, med)
    test[col] = test[col].replace(0, med)

X_tr, X_va, y_tr, y_va = train_test_split(train[feats], train["diabet"],
                                          test_size=0.2, random_state=42,
                                          stratify=train["diabet"])
sc = StandardScaler()
model = LogisticRegression(max_iter=1000)
model.fit(sc.fit_transform(X_tr), y_tr)
pred_va = model.predict(sc.transform(X_va))
print("Acc:", accuracy_score(y_va, pred_va), "F1:", f1_score(y_va, pred_va))

sc = StandardScaler()
model.fit(sc.fit_transform(train[feats]), train["diabet"])
pd.DataFrame({
    "SampleID": test["SampleID"],
    "diabet": model.predict(sc.transform(test[feats]))
}).to_csv("submission.csv", index=False)

Pentru mai multe puncte: încearcă praguri diferite de decizie sau un model ansamblu (lecția 2.6).

Probleme propuse

1. Sigmoid de mână Exercițiu

Calculează σ(z) pentru z ∈ {−4, −1, 0, 1, 4} și desenează funcția cu Matplotlib. La ce valoare a lui z probabilitatea trece de 0.9?

2. Prag de decizie Exercițiu

Pe problema diabetului, compară F1-scorul pentru praguri de 0.3, 0.5 și 0.7 aplicate pe predict_proba. De ce ar prefera un doctor pragul 0.3?

3. Predicția statusului pacientului Platformă

Problemă de la Simularea OJIA — același tipar, date medicale mai bogate.

4. Evaluarea împrumuturilor Platformă

Clasificare binară: banca aprobă sau nu împrumutul.