Machine Learning Academy · Lektion

Fra regression til klassifikation: Beslutninger med tærskler

Forstå, hvorfor lineær regression ikke fungerer til binære udfald, og se, hvordan en tærskel omdanner en score til en klasseetiket.

Lektion 1 af 412 trin

Fra regression til klassifikation: Beslutninger med tærskler er en gratis Machine Learning Academy-lektion på CoddyKit. Dette er lektion 1 af 4. Du kan læse hele lektionen gratis nedenfor — og derefter øve dig praktisk i browseren med en indbygget kodeeditor og en AI-vejleder, der er tilgængelig døgnet rundt. Den er en del af læringsforløbet i Machine Learning Academy, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. Machine Learning Academy-kurset indeholder 4 lektioner i alt.

Hvad er klassifikation?

Klassifikation er den overvågede læringsopgave, hvor man forudsiger, hvilken kategori et input tilhører, i stedet for at forudsige et kontinuerligt tal. Eksempler omfatter:

  • At forudsige, om en e-mail er spam eller ikke-spam (binær).
  • At forudsige, hvilket ciffer (0-9) der er på et billede (flere klasser).
  • At forudsige, hvilken sygdom en patient har ud fra symptomer (flere klasser).

Den afgørende forskel fra regression er, at outputtet er en diskret etiket og ikke et reelt tal. Denne tilsyneladende lille ændring kræver andre algoritmer, andre tabsfunktioner og andre evalueringsmål.

Hvorfor lineær regression ikke fungerer til klassifikation

En nærliggende tilgang er at kode klasse 0 og klasse 1 som tal og anvende lineær regression. Du kan for eksempel kode »ikke-spam« som 0 og »spam« som 1 og derefter træne en lineær regressionsmodel. Det umiddelbare problem er, at lineær regression kan give output fra -∞ til +∞, mens sandsynligheder skal ligge mellem 0 og 1. En forudsigelse på 1,7 for klassetilhørsforhold giver ingen mening.

Et andet problem er, at lineær regression forsøger at trække den bedst tilpassede linje gennem alle eksempler. Hvis du tilføjer en tydelig afvigelse langt fra grænsen, kan linjen dreje, så den fejlklassificerer mange eksempler, der tidligere var klassificeret korrekt. Tabsfunktionen er grundlæggende forkert til binære resultater.

import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression

# Binary dataset: 1 = spam, 0 = not spam
word_count = np.array([10, 20, 25, 30, 40, 50, 200]).reshape(-1, 1)
spam = np.array([0, 0, 0, 1, 1, 1, 1])

model = LinearRegression()
model.fit(word_count, spam)

# Problematic: predictions outside [0,1]
predictions = model.predict([[5], [25], [200]])
print('Linear regression predictions (should be 0 or 1):')
print(predictions)  # might be negative or >1

Tærskelbeslutninger: Konvertering af scorer til etiketter

Den enkleste tilgang til klassifikation er at bruge outputtet fra en regressionsmodel som en score og anvende en tærskel for at konvertere den til en binær etiket. Hvis scoren er over tærsklen, forudsiges klasse 1; hvis den er under, forudsiges klasse 0.

Med output fra en lineær regression kan du for eksempel vælge en tærskel på 0,5: Alt over 0,5 er spam, og alt under er ikke-spam. Det kaldes en tærskelklassifikator. Selvom det er en grov metode, illustrerer den det centrale begreb: scorer skal konverteres til beslutninger, og valget af tærskel indebærer en afvejning mellem forskellige typer fejl.

import numpy as np
from sklearn.linear_model import LinearRegression

X = np.array([10, 20, 25, 30, 40, 50]).reshape(-1, 1)
y = np.array([0, 0, 0, 1, 1, 1])

model = LinearRegression()
model.fit(X, y)

# Apply threshold to convert scores to labels
X_new = np.array([[15], [28], [45]])
scores = model.predict(X_new)
threshold = 0.5
labels = (scores >= threshold).astype(int)

for x, score, label in zip(X_new.ravel(), scores, labels):
    print(f'x={x}: score={score:.2f} -> label={label}')

Problemerne ved en fast tærskel

Det er arbitrært at vælge en tærskel på 0,5. Den optimale tærskel afhænger af de forskellige fejltypers relative omkostninger:

  • En falsk positiv (du forudsiger spam, selvom det ikke er spam) betyder, at en legitim e-mail ender i spam-mappen.
  • En falsk negativ (du forudsiger ikke-spam, selvom det er spam) betyder, at en uønsket e-mail når indbakken.

Ved medicinsk diagnosticering er omkostningerne langt mere asymmetriske: En falsk negativ (hvor en faktisk sygdom overses) kan være katastrofal, så du sænker tærsklen for at finde flere sande positive, selvom det medfører flere falske alarmer. Tærsklen er en forretningsbeslutning, ikke en matematisk beslutning.

import numpy as np

# Same scores, different thresholds give different label distributions
scores = np.array([0.2, 0.45, 0.55, 0.7, 0.85, 0.95])
y_true = np.array([0, 0, 1, 1, 1, 1])

for threshold in [0.3, 0.5, 0.7]:
    labels = (scores >= threshold).astype(int)
    correct = (labels == y_true).sum()
    print(f'Threshold {threshold}: labels={labels.tolist()}, correct={correct}/{len(y_true)}')

Binær klassifikation kontra klassifikation med flere klasser

Binær klassifikation har præcis to mulige outputklasser (spam/ikke-spam, syg/rask, svindel/legitim). Klassifikation med flere klasser har tre eller flere klasser (hvilket ciffer fra 0-9, hvilken blomsterart, hvilken produktkategori).

De fleste binære klassifikatorer udvides til flere klasser gennem to strategier:

  • One-vs-Rest (OvR): Træn én binær klassifikator pr. klasse, og forudsig den klasse, hvis klassifikator er mest sikker.
  • One-vs-One (OvO): Træn en binær klassifikator for hvert par af klasser, og brug flertalsafgørelse.

Scikit-learn håndterer dette automatisk for de fleste algoritmer.

from sklearn.linear_model import LogisticRegression
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split

# Iris has 3 classes: sklearn handles multi-class automatically
X, y = load_iris(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42)

model = LogisticRegression(multi_class='ovr', max_iter=200)
model.fit(X_train, y_train)
print('Test accuracy:', model.score(X_test, y_test).round(3))
print('Classes:', model.classes_)

Beslutningsgrænser: Hvor modellen træffer beslutningen

En klassifikator opdeler feature-rummet i områder, ét for hver klasse. Grænsen mellem områderne kaldes beslutningsgrænsen. For en lineær klassifikator er beslutningsgrænsen en lige linje (i 2D), et plan (i 3D) eller et hyperplan (i højere dimensioner).

Det er beslutningsgrænsens placering og form, som algoritmen lærer under træningen. Visualisering af beslutningsgrænsen på et 2D-datasæt er en af de bedste måder at opbygge en intuitiv forståelse af, hvordan en klassifikator fungerer, og hvorfor dens forudsigelser er korrekte eller forkerte i bestemte områder af feature-rummet.

import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LogisticRegression
from sklearn.datasets import make_classification

X, y = make_classification(n_samples=100, n_features=2, n_redundant=0, random_state=42)
model = LogisticRegression()
model.fit(X, y)

# Plot decision boundary
xx, yy = np.meshgrid(np.linspace(-3, 3, 200), np.linspace(-3, 3, 200))
Z = model.predict(np.c_[xx.ravel(), yy.ravel()]).reshape(xx.shape)

plt.contourf(xx, yy, Z, alpha=0.3)
plt.scatter(X[:, 0], X[:, 1], c=y, edgecolors='k', alpha=0.8)
plt.title('Linear Decision Boundary')
plt.show()

Nøjagtighed: Det mest intuitive mål

Nøjagtighed er andelen af forudsigelser, der er korrekte: accuracy = correct_predictions / total_predictions. Det er det mest intuitive mål og egner sig, når klasserne er afbalancerede, og alle fejl har samme omkostning.

Nøjagtighed kan dog være en fælde ved datasæt med skæve klassefordelinger. Hvis 95 % af e-mails er legitime, og din model forudsiger »ikke-spam« for alt, opnår den 95 % nøjagtighed, selvom den fuldstændig svigter sin opgave — den fanger ikke en eneste spam-e-mail. Dette er nøjagtighedsparadokset, og det er grunden til, at man bruger mere informative mål som præcision og recall.

from sklearn.metrics import accuracy_score
import numpy as np

# Balanced dataset
y_true_balanced = np.array([0, 1, 0, 1, 0, 1, 0, 1])
y_pred_balanced = np.array([0, 1, 0, 0, 0, 1, 1, 1])
print(f'Balanced accuracy: {accuracy_score(y_true_balanced, y_pred_balanced):.2f}')  # 0.75

# Imbalanced: 95% class 0
y_true_imb = np.array([0]*95 + [1]*5)
y_pred_always0 = np.zeros(100, dtype=int)
print(f'Imbalanced accuracy (always predict 0): {accuracy_score(y_true_imb, y_pred_always0):.2f}')  # 0.95!

Forskellen på predict og predict_proba

De fleste scikit-learn-klassifikatorer har to forudsigelsesmetoder:

  • predict(X) — returnerer den endelige klasseetiket efter anvendelse af standardtærsklen (normalt 0,5 ved binær klassifikation).
  • predict_proba(X) — returnerer et sandsynlighedsarray med formen (n_samples, n_classes), som angiver modellens sikkerhed for hver klasse.

Ved at bruge predict_proba får du langt mere kontrol, fordi du kan anvende en hvilken som helst tærskel. Det er afgørende i forretningsapplikationer, hvor den optimale tærskel ikke er 0,5.

from sklearn.linear_model import LogisticRegression
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
import numpy as np

X, y = make_classification(n_samples=200, n_features=5, random_state=42)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)

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

# Hard labels
hard_labels = model.predict(X_test[:5])
print('Hard labels:', hard_labels)

# Probabilities
probas = model.predict_proba(X_test[:5])
print('Probabilities (class 0, class 1):')
for row in probas:
    print(f'  Not spam: {row[0]:.2f}  |  Spam: {row[1]:.2f}')

Brug af tilpassede tærskler i praksis

Hvis du anvender en tilpasset tærskel på sandsynlighedsoutput, kan du justere afvejningen mellem falske positive og falske negative uden at træne modellen igen. Det kaldes tærskelflytning og er et almindeligt efterbehandlingstrin i produktionssystemer.

Lavere tærskel → modellen markerer flere eksempler som positive → flere sande positive, men også flere falske positive. Højere tærskel → mere konservativ model → færre falske positive, men flere falske negative. Den rigtige tærskel bestemmes af omkostningen ved hver fejltype i din specifikke applikation.

import numpy as np
from sklearn.metrics import confusion_matrix

# Get probability scores for positive class
spam_probas = model.predict_proba(X_test)[:, 1]

print('Confusion matrices at different thresholds:')
for threshold in [0.3, 0.5, 0.7]:
    y_pred = (spam_probas >= threshold).astype(int)
    cm = confusion_matrix(y_test, y_pred)
    tp = cm[1, 1]
    fp = cm[0, 1]
    fn = cm[1, 0]
    tn = cm[0, 0]
    print(f'\nThreshold {threshold}: TP={tp} FP={fp} FN={fn} TN={tn}')

Oversigt over almindelige klassifikationsalgoritmer

Lineær regression med en tærskel er kun begyndelsen. Scikit-learn indeholder mange dedikerede klassifikationsalgoritmer, hver med sine styrker og svagheder:

  • Logistic Regression — den korrekte probabilistiske lineære klassifikator (i næste lektion).
  • K-Nearest Neighbors — klassificerer ud fra flertalsafgørelsen blandt de nærmeste træningseksempler.
  • Decision Trees — regelbaserede og fuldt fortolkelige.
  • Random Forest — en samling af træer, der er robust og effektiv.
  • SVM — finder hyperplanet med den største margin.
  • Naive Bayes — hurtig og probabilistisk samt fremragende til tekst.
from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeClassifier
from sklearn.neighbors import KNeighborsClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import cross_val_score

X, y = load_breast_cancer(return_X_y=True)

for name, clf in [('Logistic Regression', LogisticRegression(max_iter=1000)),
                  ('Decision Tree', DecisionTreeClassifier()),
                  ('KNN', KNeighborsClassifier()),
                  ('Random Forest', RandomForestClassifier())]:
    score = cross_val_score(clf, X, y, cv=5, scoring='accuracy').mean()
    print(f'{name}: {score:.3f}')

Hurtigt tjek

Test din forståelse af begreberne inden for Machine Learning med Python fra denne lektion.

Opsummering af lektionen

I denne lektion lærte du, at lineær regression ikke fungerer til binær klassifikation, fordi den giver ubegrænsede output, der ikke kan repræsentere sandsynligheder, at anvendelse af en tærskel konverterer sandsynlighedsscorer til klasseetiketter med en justerbar afvejning mellem falske positive og falske negative, og at nøjagtighed er misvisende ved datasæt med skæve klassefordelinger — recall og præcision giver et mere komplet billede. Næste gang ser vi på logistisk regression — den korrekte probabilistiske lineære klassifikator, der bruger sigmoidfunktionen til at generere kalibrerede sandsynligheder.

Gratis at komme i gang

Lær Python med en AI-underviser — gratis

Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.

Kurser
30
Lektioner
120

Ofte stillede spørgsmål

Er lektionen “Fra regression til klassifikation: Beslutninger med tærskler” gratis?

Ja — hele teksten til “Fra regression til klassifikation: Beslutninger med tærskler” kan læses gratis her på nettet. Hvis du vil øve dig interaktivt med en indbygget kodeeditor og en AI-vejleder døgnet rundt og få adgang til resten af Machine Learning Academy-kurset, skal du opgradere til CoddyKit PRO. Machine Learning Academy-kurset indeholder 4 lektioner i alt.

Hvad lærer jeg i “Fra regression til klassifikation: Beslutninger med tærskler”?

Forstå, hvorfor lineær regression ikke fungerer til binære udfald, og se, hvordan en tærskel omdanner en score til en klasseetiket. Du øver dig i Machine Learning Academy med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.

Skal jeg have erfaring for at begynde på Machine Learning Academy?

Der kræves ingen tidligere erfaring. Machine Learning Academy på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 1 af 4.

Hvor lang tid tager lektionen “Fra regression til klassifikation: Beslutninger med tærskler”?

De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.

Kan jeg skrive og køre kode i denne Machine Learning Academy-lektion?

Ja. Alle Machine Learning Academy-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.

Alle lektioner i dette kursus

  1. Fra regression til klassifikation: Beslutninger med tærskler
  2. Logistisk regression og sigmoidfunktionen
  3. Forvirringsmatricen forklaret
  4. Precision, recall og F1-score i praksis
← Tilbage til Machine Learning Academy