Från regression till klassificering: beslut med tröskelvärden
Ni kommer att förstå varför linjär regression inte fungerar för binära utfall och se hur ett tröskelvärde omvandlar ett poängvärde till en klassetikett.
Från regression till klassificering: beslut med tröskelvärden är en gratis lektion i Machine Learning Academy på CoddyKit. Detta är lektion 1 av 4. Ni kan läsa hela lektionen gratis nedan och sedan öva praktiskt i webbläsaren med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt. Den ingår i lärvägen för Machine Learning Academy, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Machine Learning Academy innehåller totalt 4 lektioner.
Vad är klassificering?
Klassificering är den övervakade inlärningsuppgiften att förutsäga vilken kategori ett indata tillhör, i stället för att förutsäga ett kontinuerligt tal. Exempel:
- Att förutsäga om ett e-postmeddelande är skräppost eller inte skräppost (binär klassificering).
- Att förutsäga vilken siffra (0–9) som finns i en bild (klassificering med flera klasser).
- Att förutsäga vilken sjukdom en patient har utifrån symtom (klassificering med flera klasser).
Den viktiga skillnaden mot regression är att resultatet är en diskret etikett, inte ett reellt tal. Den till synes lilla förändringen kräver andra algoritmer, andra förlustfunktioner och andra utvärderingsmått.
Varför linjär regression misslyckas vid klassificering
Ett frestande tillvägagångssätt är att koda klass 0 och klass 1 som tal och tillämpa linjär regression. Du kan till exempel koda ”inte skräppost” som 0 och ”skräppost” som 1 och sedan träna en linjär regressionsmodell. Det omedelbara problemet är att linjär regression kan ge resultat från -∞ till +∞, medan sannolikheter måste ligga mellan 0 och 1. En förutsägelse på 1,7 för klasstillhörighet saknar betydelse.
Ett annat problem är att linjär regression försöker dra den linje som passar bäst genom alla exempel. Om du lägger till ett tydligt extremvärde långt från gränsen kan linjen vridas så att många tidigare korrekta exempel klassificeras fel. Förlustfunktionen är i grunden fel för binära utfall.
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 >1Tröskelbeslut: omvandla poäng till etiketter
Det enklaste sättet att klassificera är att använda resultatet från en regressionsmodell som en poäng och tillämpa en tröskel för att omvandla den till en binär etikett. Om poängen ligger över tröskeln förutsäger modellen klass 1; om den ligger under tröskeln förutsäger den klass 0.
Med resultatet från en linjär regression kan du till exempel välja tröskeln 0,5: allt över 0,5 är skräppost och allt under är inte skräppost. Detta kallas en tröskelklassificerare. Även om metoden är grov illustrerar den grundkonceptet: poäng måste omvandlas till beslut, och valet av tröskel innebär en avvägning mellan olika typer av fel.
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}')Problemen med en fast tröskel
Att välja tröskeln 0,5 är godtyckligt. Den optimala tröskeln beror på den relativa kostnaden för olika typer av fel:
- Ett falskt positivt resultat (att förutsäga skräppost när meddelandet inte är det) innebär att ett legitimt e-postmeddelande hamnar i skräppostmappen.
- Ett falskt negativt resultat (att förutsäga inte skräppost när meddelandet är skräppost) innebär att skräppost når inkorgen.
Vid medicinsk diagnostik är kostnaderna mycket mer asymmetriska: ett falskt negativt resultat (att missa en verklig sjukdom) kan få katastrofala följder. Därför sänker du tröskeln för att upptäcka fler verkligt positiva fall, även om det leder till fler falsklarm. Tröskeln är ett affärsbeslut, inte ett matematiskt beslut.
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 klassificering jämfört med klassificering med flera klasser
Binär klassificering har exakt två möjliga resultatklasser (skräppost/inte skräppost, sjuk/frisk, bedrägeri/legitimt). Klassificering med flera klasser har tre eller fler klasser (vilken siffra från 0 till 9, vilken blomart, vilken produktkategori).
De flesta binära klassificerare utökas till flera klasser med hjälp av två strategier:
- One-vs-Rest (OvR): träna en binär klassificerare per klass och förutsäg den klass vars klassificerare är mest säker.
- One-vs-One (OvO): träna en binär klassificerare för varje klasspar och använd majoritetsröstning.
Scikit-learn hanterar detta automatiskt för de flesta 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_)Beslutsgränser: där modellen fattar beslut
En klassificerare delar upp egenskapsrummet i regioner, en för varje klass. Gränsen mellan regionerna kallas beslutsgräns. För en linjär klassificerare är beslutsgränsen en rät linje (i 2D), ett plan (i 3D) eller ett hyperplan (i högre dimensioner).
Det är beslutsgränsens placering och form som algoritmen lär sig under träningen. Att visualisera beslutsgränsen för en 2D-datauppsättning är ett av de bästa sätten att bygga en intuitiv förståelse för hur en klassificerare fungerar och varför dess förutsägelser är korrekta eller felaktiga i specifika regioner av egenskapsrummet.
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()Noggrannhet: det mest intuitiva måttet
Noggrannhet är andelen korrekta förutsägelser: accuracy = correct_predictions / total_predictions. Det är det mest intuitiva måttet och passar när klasserna är balanserade och alla fel kostar lika mycket.
Noggrannhet är dock en fälla för obalanserade datauppsättningar. Om 95 % av alla e-postmeddelanden är legitima och modellen förutsäger ”inte skräppost” för allt, uppnår den 95 % noggrannhet samtidigt som den helt misslyckas med sin uppgift – den upptäcker inte ett enda skräppostmeddelande. Detta är noggrannhetsparadoxen och motiverar mer informativa mått som precision och 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!Skillnaden mellan Predict och Predict_proba
De flesta klassificerare i scikit-learn tillhandahåller två prediktionsmetoder:
predict(X)– returnerar den hårda klassetiketten efter att standardtröskeln har tillämpats (vanligtvis 0,5 vid binär klassificering).predict_proba(X)– returnerar en sannolikhetsarray med formen(n_samples, n_classes), som anger modellens säkerhet för varje klass.
Med predict_proba får du mycket större kontroll eftersom du kan tillämpa valfri tröskel. Detta är avgörande i affärstillämpningar där den optimala tröskeln inte är 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}')Anpassade trösklar i praktiken
Genom att tillämpa en anpassad tröskel på sannolikhetsresultat kan du finjustera avvägningen mellan falskt positiva och falskt negativa resultat utan att träna om modellen. Detta kallas threshold moving och är ett vanligt efterbearbetningssteg i produktionssystem.
Lägre tröskel → modellen flaggar fler exempel som positiva → fler verkligt positiva resultat men också fler falskt positiva resultat. Högre tröskel → mer försiktig modell → färre falskt positiva resultat men fler falskt negativa resultat. Den rätta tröskeln avgörs av kostnaden för varje typ av fel i den specifika tillämpningen.
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}')Översikt över vanliga klassificeringsalgoritmer
Linjär regression med en tröskel är bara början. Scikit-learn tillhandahåller många särskilda klassificeringsalgoritmer, var och en med styrkor och svagheter:
- Logistic Regression – den korrekta probabilistiska linjära klassificeraren (nästa lektion).
- K-Nearest Neighbors – klassificerar genom majoritetsröstning bland de närmaste träningsexemplen.
- Decision Trees – regelbaserade och helt tolkningsbara.
- Random Forest – en ensemble av träd, robust och kraftfull.
- SVM – hittar hyperplanet med maximal marginal.
- Naive Bayes – snabb, probabilistisk och utmärkt för text.
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}')Snabbtest
Testa dina kunskaper om begreppen inom Machine Learning med Python från den här lektionen.
Sammanfattning av lektionen
I den här lektionen lärde du dig att linjär regression misslyckas vid binär klassificering eftersom den ger obegränsade resultat som inte kan representera sannolikheter, att en tröskel omvandlar sannolikhetspoäng till klassetiketter med en justerbar avvägning mellan falskt positiva och falskt negativa resultat och att noggrannhet är missvisande för obalanserade datauppsättningar – recall och precision ger en mer fullständig bild. Nästa steg är att studera logistisk regression – den korrekta probabilistiska linjära klassificeraren som använder sigmoidfunktionen för att producera kalibrerade sannolikheter.
Lär dig Python med en AI-lärare – gratis
Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.
- Kurser
- 30
- Lektioner
- 120
Vanliga frågor
Är lektionen ”Från regression till klassificering: beslut med tröskelvärden” gratis?
Ja – hela texten till ”Från regression till klassificering: beslut med tröskelvärden” kan läsas gratis här på webben. Om Ni vill öva interaktivt med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt och låsa upp resten av kursen i Machine Learning Academy, kan Ni uppgradera till CoddyKit PRO. Kursen i Machine Learning Academy innehåller totalt 4 lektioner.
Vad lär jag mig i ”Från regression till klassificering: beslut med tröskelvärden”?
Ni kommer att förstå varför linjär regression inte fungerar för binära utfall och se hur ett tröskelvärde omvandlar ett poängvärde till en klassetikett. Ni övar på Machine Learning Academy med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.
Behöver jag någon erfarenhet för att börja lära mig Machine Learning Academy?
Du behöver inga förkunskaper. Utbildningen i Machine Learning Academy på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 1 av 4.
Hur lång tid tar lektionen ”Från regression till klassificering: beslut med tröskelvärden”?
De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.
Kan jag skriva och köra kod i den här Machine Learning Academy-lektionen?
Ja. Varje Machine Learning Academy-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.
Alla lektioner i den här kursen
- Från regression till klassificering: beslut med tröskelvärden
- Logistisk regression och sigmoidfunktionen
- Förklarat: förväxlingsmatrisen
- Precision, recall och F1-score i praktiken