Last chance! 50% off DataCamp Premium
Sale ends in
Nadat je een model voor logistische regressie hebt getraind, hoe weet je zeker dat je de coëfficiënten kunt vertrouwen?
Logistische regressie staat bekend als eenvoudig. Met scikit-learn roep je .fit() aan, lees je de oddsratio’s af, en dat is het zo’n beetje. Maar wat de meeste beginners niet weten, is dat het model eigen aannames heeft, en als je je daar niet aan houdt, misleiden de coëfficiënten je en zijn voorspellingen op manieren verkeerd die geen enkele testmetriek je zal vertellen.
Eerlijk is eerlijk: logistische regressie heeft minder aannames dan lineaire regressie, en de aannames die er zijn, zijn makkelijk te controleren. Je hoeft alleen de juiste diagnostiek te draaien vóórdat je de output gaat interpreteren, zodat je weet welke delen van het model je kunt vertrouwen.
In dit artikel neem ik je mee door elke aanname die logistische regressie maakt, hoe je ze controleert in Python en R, wat er gebeurt als ze worden geschonden en welke alternatieven je kiest als de aannames niet gevolgd kunnen worden.
Als je nieuw bent in data science en machine learning, lees dan onze blogpost over Simple Linear Regression om de aannames en diagnostiek te begrijpen.
Logistische regressie is een classificatiemodel dat de kans op een categorische uitkomst voorspelt. Je geeft voorspellers mee en het model retourneert een getal tussen 0 en 1 dat je kunt lezen als de kans om tot een bepaalde klasse te behoren.
De meeste mensen gebruiken het voor binaire classificatie zoals churn of geen churn, spam of geen spam. Varianten zoals multinomiale en ordinale logistische regressie dekken meer dan twee klassen, maar de binaire case is wat de meeste mensen bedoelen met "logistische regressie".
Onder de motorkap past het model een lineaire combinatie van je voorspellers en stuurt het resultaat door de logistische functie. De output is een kans, en de coëfficiënten vertellen je hoe elke voorspeller de log-odds verschuift.
Het is goed om te benadrukken dat logistische regressie anders is dan lineaire regressie. De laatste heeft bekende aannames zoals normaliteit van residuen, homoscedasticiteit en lineariteit tussen voorspellers en doelvariabele. Logistische regressie doet die aannames niet. Het heeft een eigen lijst, en die wijkt zodanig af dat het toepassen van aannames uit lineaire regressie je misleidende resultaten oplevert.
Voor meer details over logistische regressie, lees onze blogpost met implementatie in Python.
De aannames zijn belangrijk omdat ze direct verbonden zijn met wat je met het model doet.
Als je de aannames respecteert, betekenen de coëfficiënten wat jij denkt dat ze betekenen. De oddsratio’s die je afleest zijn geldig, en de kansen van het model sluiten goed aan op de werkelijke uitkomsten. Als de aannames niet gerespecteerd worden, wordt dat allemaal wankel op manieren die een confusion matrix of andere metriek je niet laat zien.
Het goede nieuws is dat schendingen niet binair zijn. Een milde afwijking van bijvoorbeeld de lineariteit-van-de-logit aanname maakt je model niet waardeloos. Het betekent alleen dat je oddsratio’s iets afwijken en je voorspellingen slechter kunnen zijn dan nodig. Veel productiemodellen leven met onvolmaakte aannamechecks, en dat is prima.
Wat je niet wilt, is de checks overslaan. Zonder diagnostiek kun je niet zien of je met een klein of groot probleem te maken hebt totdat voorspellingen misgaan.
Voordat we op elke aanname ingaan, volgt hier de volledige lijst die je moet controleren.
| Aanname | Wat het vereist | Gangbare diagnostiek |
|---|---|---|
| Onafhankelijke observaties | Geen enkel record beïnvloedt een ander record | Studieopzet, intraklassecorrelatie |
| Geschikte uitkomstvariabele | Binair, of gemodelleerd met de juiste variant | Inspecteer de target |
| Lineariteit van de logit | Voorspellers lineair in de log-odds | Box-Tidwell-test, splines |
| Geen ernstige multicollineariteit | Voorspellers niet sterk gecorreleerd | VIF, correlatiematrix |
| Voldoende steekproefgrootte | Genoeg events per variabele | EPV-duimregel |
| Geen invloedrijke uitschieters | Geen enkel record dat de fit scheeftrekt | Cook’s distance, leverage |
Tabel met aannames van logistische regressie
Dat is de hele checklist. In de rest van het artikel neem ik je mee door elke aanname met diagnostiek in Python en R, hoe een schending eruitziet en wat je doet als er iets misgaat.
Standaard logistische regressie is gemaakt voor een binaire uitkomst. De targetvariabele moet precies twee categorieën hebben, en het model is rond dat geval ontworpen.
De klassieke voorbeelden zijn churn of geen churn, ziekte of geen ziekte. Alles wat je als een ja/nee-vraag kunt formuleren, past goed.
Als je uitkomst meer dan twee categorieën heeft, heb je een andere variant nodig. Multinomiale logistische regressie behandelt ongeordende categorieën zoals klantsegmenten of producttypes. Ordinale logistische regressie behandelt geordende categorieën zoals tevredenheidsscores van 1 tot 5, waar de volgorde tussen niveaus betekenis heeft.
Een multi-class uitkomst forceren in een binair model betekent meestal dat je categorieën samenvoegt die je niet zou moeten samenvoegen. Als je een tevredenheidsdoel met vijf niveaus terugbrengt tot "tevreden vs niet", verlies je informatie die je model had kunnen helpen. Kies de variant die past bij de vorm van je target.
Elke rij in je dataset moet het model informatie geven die geen andere rij al biedt. Als twee records op een manier aan elkaar gelinkt zijn die dit schendt, kloppen je standaardfouten en p-waarden niet meer zoals ze zouden moeten.
De aanname faalt telkens wanneer observaties structuur delen die je niet hebt gemodelleerd. Een goed voorbeeld is herhaalde metingen bij dezelfde patiënt, want die delen de biologie van die patiënt. Een ander voorbeeld is leerlingen gegroepeerd in dezelfde klas, omdat ze dezelfde docent en ruimte delen.
Negeer je dit en pas je een gewone logistische regressie toe, dan behandelt het model elke rij als nieuwe informatie en verkleint het de standaardfouten meer dan zou moeten. Coëfficiënten kunnen er aan de oppervlakte nog prima uitzien, maar de p-waarden en betrouwbaarheidsintervallen zijn overmoedig.
De standaardalternatieven zijn mixed-effects logistische regressie en GEE. Mixed-effects modellen voegen random effects toe voor de groepen (patiënt, klas) zodat het model rekening houdt met correlatie binnen groepen. GEE, kort voor generalized estimating equations, geeft je populatiegemiddelde effecten met gecorrigeerde standaardfouten, zonder de random-effects-machinerie.
Kies mixed-effects wanneer je om variatie binnen groepen geeft. Kies GEE wanneer je marginale effecten over de hele populatie wilt.
Dit is de aanname waar de meeste mensen zich in vergissen bij logistische regressie.
Het model gaat er niet van uit dat je voorspellers een lineaire relatie met de uitkomst hebben. Het gaat ervan uit dat ze een lineaire relatie met de log-odds van de uitkomst hebben. Dat is een andere uitspraak en verandert wat je moet controleren.
De logit is de natuurlijke logaritme van de odds. Voor een kans p zijn de odds p / (1 - p), en de logit is de log van die verhouding:

De logit
Logistische regressie past vervolgens een lineaire vergelijking toe op deze schaal:

Formule voor logistische regressie
De rechterkant is lineair in de voorspellers. De linkerkant zijn de log-odds, niet de kans. De kans waar je daadwerkelijk om geeft, wordt teruggewonnen door de lineaire combinatie door de logistische functie te sturen, die niet-lineair is.
Dus de relatie tussen een voorspeller en de kans is niet-lineair. De relatie tussen een voorspeller en de log-odds hoort lineair te zijn.
Als de lineariteit van de logit niet geldt voor een voorspeller, vat de coëfficiënt bij die voorspeller een kromme samen met een rechte lijn. Het model geeft je nog steeds een getal, en dat getal kan nog steeds statistisch significant zijn, maar het beschrijft de werkelijke relatie in je data niet.
Zo kan age een U-vormig effect hebben op de log-odds van een ziekte, met hoog risico aan beide uiteinden en lager risico in het midden. Als je age als enkel lineair term opneemt, kan de coëfficiënt dicht bij nul uitkomen en concludeer je dat leeftijd niet uitmaakt. Dat doet het wel. De specificatie is fout.
Je hebt een paar opties om deze aanname te checken.
De snelste check is visuele inspectie. Verdeel elke continue voorspeller in decielen, bereken de empirische log-odds binnen elke bin en plot het resultaat tegen de voorspeller. Een min of meer rechte lijn betekent dat de aanname houdt. Een duidelijke kromme betekent van niet. De check is informeel maar werkt goed als je genoeg data per bin hebt.
De Box-Tidwell-test voegt een interactieterm toe tussen elke continue voorspeller en z’n eigen natuurlijke logaritme. Als de interactie statistisch significant is, is de lineariteit-van-de-logit aanname geschonden voor die voorspeller. De test werkt alleen op strikt positieve voorspellers (je kunt geen log van nul of een negatief getal nemen) en is, zoals elke significantietest, gevoelig voor steekproefgrootte.
Splines zijn een andere optie. In plaats van te checken of lineariteit geldt, vervang je de lineaire term door een flexibele basisfunctie zoals een restricted cubic spline, en laat je het model de vorm fitten die het nodig heeft. Als de spline veel beter past dan de lineaire term (beoordeeld met likelihood ratio of AIC), heb je bewijs dat de lineaire specificatie te beperkend was. Splines dienen ook als oplossing. Ze in het eindmodel houden is vaak het beste antwoord wanneer lineariteit faalt.
Als de aanname faalt voor een voorspeller, heb je een paar opties:
Beide houden je binnen de familie van logistische regressie, en beide zijn beter dan een voorspeller uitsluiten die eigenlijk informatief is.
Logistische regressie kan tot op zekere hoogte met gecorreleerde voorspellers overweg. Daarna begint het model zich mis te gedragen op manieren die je lastig uit een testmetriek haalt.
Multicollineariteit ontstaat wanneer twee of meer voorspellers dezelfde (of sterk vergelijkbare) informatie bevatten. Misschien heb je lengte in inches en in centimeters in hetzelfde model. Of totale omzet en omzet per klant naast klantenaantal.
Twee dingen gaan mis bij multicollineariteit:
Voorspellingen zijn meestal prima. Als je alleen om de voorspelde kans geeft, veroorzaakt milde tot matige multicollineariteit zelden problemen. De “schade” concentreert zich in de coëfficiënten en de inferentie die je erop doet.
De twee checks zijn een correlatiematrix en de variance inflation factor (VIF). Een correlatiematrix is het eerste om naar te kijken, vooral paren voorspellers met correlaties boven 0,8 of 0,9 in absolute waarde. De beperking is dat correlatiematrices alleen paarse collineariteit vastleggen, niet het meerweggeval waarbij drie of meer voorspellers collectief redundant zijn.
VIF is er voor het meerweggeval. Voor elke voorspeller meet VIF hoeveel de variantie van z’n coëfficiënt wordt opgeblazen door collineariteit met de rest van de voorspellers. Een VIF van 1 betekent geen collineariteit, waarden tot 5 zijn meestal prima, en waarden boven 10 zijn een sterk signaal dat de voorspeller redundant is met andere in het model.
Als VIF iets vlaggt, is de makkelijkste oplossing om één van de collineaire voorspellers te droppen of ze te combineren tot één feature zoals een som of een ratio. Als je liever alle voorspellers houdt, stabiliseert regularisatie (ridge of elastic net) de coëfficiënten zonder dat je hoeft te kiezen.
Logistische regressie werkt met kleine steekproeven, maar is dan wat onbetrouwbaar. Coëfficiënten schommelen meer dan zou moeten, en effecten van zeldzame klassen zijn bijna onmogelijk te schatten.
De steekproefgrootte die ertoe doet voor logistische regressie is niet het totale aantal rijen. Het is het aantal events (observaties in de minderheidsklasse). Een dataset met 100.000 rijen en 50 fraudegevallen is een klein-steekproefprobleem, omdat het model maar 50 voorbeelden heeft van hetgeen het moet leren.
Daar komt events per variabele (EPV) om de hoek kijken. EPV is het aantal observaties in de minderheidsklasse gedeeld door het aantal voorspellers in het model. Als je 50 fraudegevallen en 10 voorspellers hebt, is je EPV 5.
De oude vuistregel was een EPV van minimaal 10. Recente simulatiestudies laten zien dat het juiste getal afhangt van de effectgroottes in je data en de hoeveelheid regularisatie die je gebruikt. EPV’s zo laag als 5 kunnen in sommige settings prima zijn, en EPV’s van 20 of meer kunnen in andere nodig zijn.
De kern is om EPV te zien als waarschuwingsinformatie. Onder 10 kun je instabiele schattingen verwachten en overweeg je gestrafte methoden zoals Firth’s logistische regressie of ridge. Onder 5: verzamel meer data of vereenvoudig het model voordat je een individuele coëfficiënt vertrouwt.
Klassenonevenwicht is een gerelateerd maar anders probleem.
Een dataset waar 99% van de gevallen één klasse is, kan nog steeds in absolute zin genoeg events per variabele hebben. Wat verschuift, is het basistarief van de uitkomst, niet de EPV. Onevenwichtige data levert vaak conservatieve kansschattingen op, en accuracy houdt op een nuttige metriek te zijn. Om dat te omzeilen evalueer je met log-loss of Brier score in plaats van accuracy, en overweeg je klassegewichten of drempeltuning als je gebalanceerde beslissingen nodig hebt.
Logistische regressie gaat er niet van uit dat je voorspellers normaal verdeeld zijn. Scheve voorspellers en telvariabelen zijn op zichzelf prima. Waar het model wel om geeft, is of een enkele observatie buitensporig veel invloed heeft op de gefitte coëfficiënten.
Een invloedrijke observatie is er één die, als je hem verwijdert, het model betekenisvol zou veranderen. Dat is niet hetzelfde als een residuele uitschieter. Een punt kan een groot residu hebben (het model voorspelt het slecht) zonder invloedrijk te zijn, en een punt kan zeer invloedrijk zijn (het model leunt er zwaar op) zonder een groot residu te hebben.
Je wilt een paar diagnostieken die naar verschillende aspecten van invloed kijken:
Wanneer je een invloedrijk punt vindt, is de vraag of het punt echt of fout is. Een invoerfout wordt gecorrigeerd of verwijderd. Een echt maar ongewoon geval blijft, en je noteert dat je conclusies ervan afhangen. Sluit punten niet uit omdat ze invloedrijk zijn. Zo eindig je met een model dat je trainingsdata past en niets anders.
De meeste verwarring rond de aannames van logistische regressie komt van het gebruik van de checklist van lineaire regressie. De aannames van lineaire regressie zijn bekend en overal aangeleerd, en ze duiken op bij logistische regressie waar ze niet thuishoren. Hier zijn de vier meest voorkomende om recht te zetten.
Dit is onwaar. Logistische regressie maakt geen normaliteitsaannames voor welke variabele dan ook in het model.
De uitkomst hoort binair te zijn, niet normaal, en dat hebben we behandeld bij Aanname 1. Ook de voorspellers hoeven niet normaal te zijn en mogen elke vorm aannemen die de data heeft. Wat telt, is de relatie tussen de voorspellers en de log-odds, niet de marginale verdeling van een enkele variabele.
Ook dit is onwaar. Homoscedasticiteit (constante variantie van residuen over het bereik van voorspelde waarden) is een aanname van lineaire regressie die niet geldt voor logistische regressie.
De variantie van de uitkomst in logistische regressie hangt af van de voorspelde kans zelf. Voor een Bernoulli-uitkomst is de variantie gelijk aan p(1 - p), die het hoogst is rond p = 0,5 en het laagst rond 0 en 1. De variantie is niet constant, en het model houdt daar rekening mee via de likelihoodfunctie die het maximaliseert.
Dus als je een logistische regressie fit, schend je niets door voorspelde kansen met verschillende varianties te hebben. Dat is simpelweg hoe het model werkt.
Dit is onwaar. Logistische regressie legt geen verdelingsaanname op de voorspellers.
Je kunt continue, binaire, tel- en categorische voorspellers in hetzelfde model mixen. Scheve voorspellers zijn prima. Zwaarstaartige voorspellers ook. Het model geeft niet om marginale vormen. Het enige dat telt, is de lineariteit van de logit (behandeld in Aanname 3), wat een relatie-vorm aanname is, geen verdelings-vorm aanname.
Als de scheefheid van een voorspeller problemen veroorzaakt, komt dat meestal door de lineariteit van de logit of invloedrijke uitschieters.
Dit is onwaar. Er is geen normaliteitsaannames op de residuen van logistische regressie.
Lineaire regressie veronderstelt dat residuen normaal verdeeld zijn rond nul, omdat dat onderdeel is van hoe de inferentie werkt. Logistische regressie gebruikt maximum likelihood schatting op een binomiale likelihood, en de verdeling van de residuen wordt bepaald door de uitkomst (0 of 1) en de gefitte kans. Ze zijn niet normaal, en horen dat ook niet te zijn.
Dus wanneer je residudiagnostiek controleert voor logistische regressie (zoals in Aanname 6), kijk je naar invloedrijke observaties en punten die het model niet kan verklaren, niet naar een klokcurve.
Ik doe de diagnostiek met statsmodels. Scikit-learn fit wel logistische regressie maar geeft je niet standaard VIF, invloedsstatistieken of residudiagnostiek.
Ik genereer een synthetische churn-dataset met drie voorspellers (leeftijd, inkomen en bestedingsscore), waarbij leeftijd en inkomen opzettelijk gecorreleerd zijn zodat multicollineariteit iets kan vinden.
import numpy as np
import pandas as pd
import statsmodels.api as sm
import statsmodels.formula.api as smf
np.random.seed(42)
n = 1000
age = np.random.normal(40, 12, n).clip(18, 80)
income = 30000 + 1500 * age + np.random.normal(0, 8000, n)
spending_score = np.random.uniform(1, 100, n)
logit_p = -3 + 0.04 * age + 0.02 * spending_score
p = 1 / (1 + np.exp(-logit_p))
y = np.random.binomial(1, p)
df = pd.DataFrame({
"churned": y,
"age": age,
"income": income,
"spending_score": spending_score,
})
model = smf.glm(
"churned ~ age + income + spending_score",
data=df, family=sm.families.Binomial()
).fit()
print(model.summary())

Modeloverzicht
De samenvatting geeft coëfficiënten, standaardfouten, z-statistieken en p-waarden. age en spending_score komen eruit als de betekenisvolle voorspellers. De coëfficiënt van income is klein omdat de uitkomst niet direct afhangt van inkomen. Het schijnbare effect wordt geabsorbeerd door leeftijd.
Statsmodels maakt deze berekening ontzettend eenvoudig:
from statsmodels.stats.outliers_influence import variance_inflation_factor
X = sm.add_constant(df[["age", "income", "spending_score"]])
vif = pd.DataFrame({
"feature": X.columns,
"VIF": [variance_inflation_factor(X.values, i) for i in range(X.shape[1])]
})
print(vif[vif["feature"] != "const"])

VIF-output
De VIF’s voor age en income komen rond 5,5 uit, wat milde multicollineariteit aangeeft. spending_score komt in de buurt van 1, en dat is wat je wilt. De variantie wordt niet opgeblazen door collineariteit met de andere. VIF’s boven 5 zijn milde vlaggen; boven 10 is een serieus probleem dat je meteen moet oplossen. De zet hier is om ofwel één van age of income te droppen of ze te combineren tot één feature.
De Box-Tidwell-test voegt interactietermen toe tussen elke continue voorspeller en z’n eigen natuurlijke log. Significante interacties vlaggen een niet-lineaire log-oddsrelatie voor die voorspeller.
df_bt = df.copy()
for col in ["age", "income", "spending_score"]:
df_bt[f"{col}_logx"] = df_bt[col] * np.log(df_bt[col])
bt_formula = (
"churned ~ age + income + spending_score + "
"age_logx + income_logx + spending_score_logx"
)
bt_model = smf.glm(
bt_formula, data=df_bt, family=sm.families.Binomial()
).fit()
interactions = ["age_logx", "income_logx", "spending_score_logx"]
print(bt_model.pvalues[interactions])

Box-Tidwell-output
Als een van deze p-waarden onder 0,05 uitkomt, is de lineariteit-van-de-logit aanname verdacht voor die voorspeller. De logit is hier lineair gegenereerd, dus de interacties zouden niet significant moeten zijn. Op echte data behandel je een significant resultaat als een seintje om de empirische log-odds tegen die voorspeller te plotten en te beslissen of een transformatie of spline de juiste oplossing is.
Statsmodels geeft je toegang tot Cook’s distance en leverage via get_influence().
influence = model.get_influence()
cooks_d = influence.cooks_distance[0]
leverage = influence.hat_matrix_diag
flagged = pd.DataFrame({
"cooks_d": cooks_d,
"leverage": leverage,
}).sort_values("cooks_d", ascending=False).head(10)
print(flagged)

Uitvoer invloedsdiagnostiek
De drempel voor Cook’s distance die het onderzoeken waard is, is grofweg 4/n. Bij 1000 rijen is dat 0,004. Alles wat daar duidelijk boven zit, verdient nadere inspectie. In deze dataset zijn de grootste Cook’s distances nog klein in absolute zin, wat de saai-goede uitkomst is die je meestal wilt.
Laat me nu een visualisatie maken om de verdeling makkelijker leesbaar te maken:

Invloedsdiagnostiek gevisualiseerd
Punten die ruim boven de gestreepte drempel zitten, zijn de moeite waard om te onderzoeken. Er zijn er wat, maar niet te veel.
De deviance-residuen vertellen je bij welke observaties het model moeite heeft met fitten.
deviance_resid = model.resid_deviance
fitted = model.fittedvalues
resid_df = pd.DataFrame({
"fitted": fitted,
"deviance": deviance_resid,
}).sort_values("deviance", key=abs, ascending=False).head(10)
print(resid_df)

Uitvoer residudiagnostiek
Grote positieve deviance-residuen zijn gevallen waar het model een lage kans toekende maar die toch positief waren. Grote negatieve residuen zijn het omgekeerde. Je zou observaties met hoge residuen moeten kruisverwijzen met de invloedsdiagnostiek hierboven. Een case die zowel slecht voorspeld als invloedrijk is, is het meest de moeite waard om te onderzoeken.
R heeft strakkere ingebouwde ondersteuning voor deze diagnostiek. Het meeste wat je nodig hebt komt uit base R’s glm() plus het car-pakket.
Ik genereer dezelfde soort synthetische dataset als in het Python-voorbeeld, met leeftijd en inkomen opzettelijk gecorreleerd.
set.seed(42)
n <- 1000
age <- pmin(pmax(rnorm(n, mean = 40, sd = 12), 18), 80)
income <- 30000 + 1500 * age + rnorm(n, sd = 8000)
spending_score <- runif(n, min = 1, max = 100)
logit_p <- -3 + 0.04 * age + 0.02 * spending_score
p <- 1 / (1 + exp(-logit_p))
churned <- rbinom(n, size = 1, prob = p)
df <- data.frame(churned, age, income, spending_score)
model <- glm(churned ~ age + income + spending_score,
data = df, family = binomial)
summary(model)

Modeloverzicht-uitvoer
De output van summary(model) geeft je coëfficiënten, standaardfouten, z-statistieken en p-waarden. age en spending_score zouden betekenisvol moeten ogen, terwijl het effect van income wordt geabsorbeerd door age.
Het car-pakket geeft je vif() voor elke glm:
library(car)
vif(model)

VIF-output in R
age en income komen allebei terug met VIF’s rond 5,7, wat de ingebouwde multicollineariteit in de data laat zien. spending_score zit rond 1. Zoals in Python verdienen waarden boven 5 aandacht en zijn waarden boven 10 een duidelijk probleem.
De functie car::boxTidwell is ontworpen voor lineaire regressie, dus voor logistische regressie is het beste om de interactietermen handmatig toe te voegen en opnieuw te fitten:
df_bt <- df
df_bt$age_logx <- df_bt$age * log(df_bt$age)
df_bt$income_logx <- df_bt$income * log(df_bt$income)
df_bt$spending_score_logx <- df_bt$spending_score * log(df_bt$spending_score)
bt_model <- glm(
churned ~ age + income + spending_score +
age_logx + income_logx + spending_score_logx,
data = df_bt, family = binomial
)
interactions <- c("age_logx", "income_logx", "spending_score_logx")
summary(bt_model)$coefficients[interactions, ]

BoX-Tidwell-output in R
De output toont de coëfficiënt en p-waarde voor elke interactieterm. Significante p-waarden vlaggen een schending van de lineariteit-van-de-logit aanname voor die voorspeller. Voor de synthetische data hier zou de test lineariteit niet moeten verwerpen. Op echte data volg je op met empirische log-oddsplots of fit je een model met splines (uit het splines-pakket) voor elke voorspeller die de test vlaggt.
R biedt cooks.distance() en hatvalues() in base, dus er is geen third-party pakket nodig:
cooks_d <- cooks.distance(model)
leverage <- hatvalues(model)
influence_df <- data.frame(
index = seq_along(cooks_d),
cooks_d = cooks_d,
leverage = leverage
)
head(influence_df[order(-influence_df$cooks_d), ], 10)

Invloedsdiagnostiek in R
De drempel voor Cook’s distance is hetzelfde als in Python: 4/n, of 0,004 voor de dataset met 1000 rijen. Alles wat daar duidelijk boven zit, verdient onderzoek. Voor een snelle visuele check geeft base R’s plot(model, which = 4) met één regel een Cook’s distance-plot.

Invloedsdiagnostiek in R gevisualiseerd
R’s residuals()-functie geeft je deviance-residuen van een glm:
deviance_resid <- residuals(model, type = "deviance")
fitted_vals <- fitted(model)
resid_df <- data.frame(
fitted = fitted_vals,
deviance = deviance_resid
)
head(resid_df[order(-abs(resid_df$deviance)), ], 10)

Residudiagnostiek in R
Grote absolute deviance-residuen zijn gevallen die de voorspelling van het model miste. Je zou deze moeten kruisverwijzen met de Cook’s distance-vlaggen hierboven om observaties te vinden die zowel slecht gefit als invloedrijk zijn.
Voor een one-shot overzicht van alles retourneert influence.measures(model) een tabel die Cook’s distance, leverage, DFBETA’s en nog een paar invloedsstatistieken combineert. Het is de snelste manier om alle standaarddiagnostiek op een gefitte glm te scannen.
De meeste aannameovertredingen breken je model niet op een manier dat het niet meer werkt. Ze zorgen dat het zich subtiel misdraagt, wat je alleen merkt als je weet waar je op moet letten.
Vier gevolgen komen het vaakst voor:
Maar eerlijk: schendingen maken een model zelden waardeloos. Ze maken delen ervan onbetrouwbaar, en welke delen onbetrouwbaar zijn hangt af van welke aanname brak. Daarom is de diagnostiek belangrijk.
Als je diagnostiek wijst op problemen die je niet binnen logistische regressie kunt oplossen, is de volgende stap een model dat die aannames niet maakt.
Generalized additive models (GAM’s) zijn de volgende om naar te kijken. Een GAM behoudt de logistische linkfunctie en de interpreteerbare additieve structuur, maar vervangt de lineaire termen door vloeiende functies van elke voorspeller. Je krijgt coëfficiënten-met-vormen in plaats van enkele getallen, wat het probleem van lineariteit-van-de-logit oplost. GAM’s zijn nog parametrisch genoeg om te inspecteren en te interpreteren, wat ze een goede stap omhoog maakt vanaf logistische regressie wanneer de lineariteitsaanname niet kan houden.
Boomgebaseerde modellen zijn het flexibelere alternatief. Random forests en gradient boosting maken geen aannames over verdelingen van voorspellers of relatievormen. Ze kunnen met multicollineariteit overweg en zelfs non-lineariteit vastleggen. Ze geven je niet de gemakkelijke coëfficiëntinterpretatie van logistische regressie, maar presteren vaak beter op voorspelmetriek wanneer de data niet-lineaire structuur of interacties heeft die je niet in het model hebt gestopt.
De keuze tussen GAM’s en boommodellen komt neer op wat je van het model nodig hebt.
Het is het vermelden waard dat de aannames van logistische regressie makkelijker te checken zijn dan te negeren. Als je het issue kunt oplossen met een transformatie, een spline, regularisatie of een betere steekproef, winnen de interpreteerbaarheid en inferentiële output van logistische regressie het meestal van wat je krijgt bij een switch naar een flexibeler model.
Stap dus over op GAM’s of bomen wanneer de diagnostiek je vertelt dat de aannames echt niet houden, niet alleen omdat logistische regressie geen state-of-the-art algoritme is.
Volg tot slot deze korte lijst om altijd een model te krijgen dat je kunt vertrouwen:
Eerlijk gezegd is logistische regressie een van de vergevingsgezindere modellen die je kunt fitten.
Het tolereert scheve voorspellers en onevenwichtige uitkomsten, en het kan niet schelen hoe je residuen eruitzien. Wat het niet tolereert, is een verkeerd gespecificeerde relatie met de log-odds, of een set voorspellers die allemaal dezelfde informatie bevatten.
Daarom zijn lineariteit van de logit en multicollineariteit de twee aannamechecks die je als verplicht zou moeten zien. Het zijn degenen die het model vervormen op manieren die geen enkele testmetriek kan oppikken. De andere vier aannames zijn ook relevant, maar deze twee zijn waar je echt op moet focussen.
Speel op safe en draai de diagnostiek naast de evaluatie, niet erna. Een model dat goed voorspelt en z’n aannamechecks doorstaat, is een model waar je achter kunt staan. Alles daaronder is een model dat je hebt getraind maar niet echt hebt geverifieerd.
Klinkt dit complex? Dat is het ook. Er komt veel bij kijken om een goede machine learning engineer te zijn, dus we raden je aan je in te schrijven voor onze Machine Learning Scientist in Python-track. 85 uur aan materiaal maakt je job-ready voor 2026.
Ja. Logistische regressie maakt minder aannames dan lineaire regressie, maar is niet vrij van aannames. De belangrijkste hebben betrekking op de vorm van de uitkomstvariabele, de onafhankelijkheid van observaties, de lineariteit van de log-odds en de afwezigheid van hoge multicollineariteit of sterk invloedrijke punten.
De twee die het meest tellen zijn lineariteit van de logit en afwezigheid van hoge multicollineariteit. Lineariteit van de logit wordt het vaakst verkeerd begrepen, omdat logistische regressie geen lineaire relatie tussen voorspellers en de uitkomst aanneemt, maar wel tussen voorspellers en de log-odds. Multicollineariteit is belangrijk omdat het coëfficiënten vervormt en standaardfouten opblaast zonder accuracy te beïnvloeden, waardoor het zich kan verschuilen voor checks die alleen naar voorspelprestatie kijken.
Het hangt ervan af welke aanname breekt. Schendingen van lineariteit in de logit of sterke multicollineariteit beschadigen stilletjes de coëfficiënten terwijl accuracy intact blijft, wat ze makkelijk te missen maakt. Falen van onafhankelijkheid vergroot of verkleint standaardfouten, waardoor p-waarden onbetrouwbaar worden. De meeste schendingen maken een model niet nutteloos, maar maken delen ervan onbetrouwbaar op manieren die accuracy alleen niet laat zien.
Nee. Logistische regressie legt geen verdelingsaanname op de voorspellers. Je kunt continue, categorische, scheve en zwaarstaartige voorspellers zonder probleem in hetzelfde model gebruiken. Wat telt, is de relatie tussen elke voorspeller en de log-odds, niet de marginale vorm van de voorspeller zelf.
VIF-waarden tot 5 zijn meestal prima, waarden tussen 5 en 10 suggereren matige multicollineariteit die het onderzoeken waard is, en waarden boven 10 signaleren dat één of meer voorspellers redundant zijn. De drempels zijn geen harde regels maar conventies, omdat de interpretatie van VIF afhangt van steekproefgrootte en de precisie die je nodig hebt. Als de VIF van een voorspeller hoog is en z’n standaardfout instabiel oogt over datasubsets, heb je bewijs dat collineariteit problemen veroorzaakt.
Leren met DataCamp
Cursus
Cursus
Cursus

blog
Adel Nehme
15 min