Cursus
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.
Wat is logistische regressie?
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.
Waarom aannames bij logistische regressie ertoe doen
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.
Overzicht van aannames bij logistische regressie
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.
De belangrijkste aannames van logistische regressie
Aanname 1: De uitkomstvariabele is binair (of passend gemodelleerd)
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.
Aanname 2: Observaties zijn onafhankelijk
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.
Aanname 3: Lineariteit van de logit
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.
Wat de logit is
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.
Waarom dit in de praktijk telt
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.
De lineariteit van de logit controleren
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.
Wat te doen als lineariteit faalt
Als de aanname faalt voor een voorspeller, heb je een paar opties:
- Transformeer de voorspeller (een log- of worteltransformatie doet het vaak) totdat de relatie lineair oogt in de log-odds
- Gebruik splines en accepteer een iets complexer model
Beide houden je binnen de familie van logistische regressie, en beide zijn beter dan een voorspeller uitsluiten die eigenlijk informatief is.
Aanname 4: Geen ernstige multicollineariteit
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:
- Coëfficiënten worden instabiel: Als je één rij toevoegt of verwijdert, kan de coëfficiënt bij een collineaire voorspeller sterk schommelen of van teken veranderen. Het model werkt nog wel, maar de individuele coëfficiënten betekenen weinig.
- Standaardfouten zwellen op: Met minder onafhankelijke informatie per voorspeller wordt het model onzekerder over elke coëfficiënt. P-waarden stijgen, en echte effecten kunnen onbetekenend terugkomen.
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.
Aanname 5: Adequate steekproefgrootte
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.
Aanname 6: Geen sterk invloedrijke uitschieters
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:
- Leverage meet hoe ongebruikelijk de voorspellerwaarden van een observatie zijn ten opzichte van de rest van de data. Leverage op zich betekent niet dat een observatie invloedrijk is. Het betekent dat het punt potentieel invloedrijk is als de uitkomst niet past bij wat de voorspellers zouden suggereren
- Cook’s distance combineert leverage met het residu tot één getal dat schat hoeveel de gefitte coëfficiënten zouden veranderen als je de observatie dropt. Grote Cook’s distance waarden lichten de punten uit die het onderzoeken waard zijn. Gangbare conventies zijn waarden boven 4/n (waar n je steekproefgrootte is) of simpelweg kijken naar de grootste paar Cook’s distance waarden in je dataset
- Residudiagnostiek is geweldig voor de gevallen die leverage en Cook’s distance niet oppikken. Deviance-residuen en Pearson-residuen vlaggen observaties die het model lastig kan fitten. Een punt met een groot residu is het bekijken waard, zelfs als z’n leverage gemiddeld is, omdat het model aangeeft dat het die case niet kan verklaren met de andere voorspellers
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.
Veelvoorkomende misverstanden over aannames bij logistische regressie
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.
Logistische regressie vereist normaal verdeelde variabelen
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.
Logistische regressie vereist homoscedasticiteit
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.
Voorspellers moeten normaal verdeeld zijn
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.
Residuen moeten normaal verdeeld zijn
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.
Hoe je aannames van logistische regressie controleert in Python
Ik doe de diagnostiek met statsmodels. Scikit-learn fit wel logistische regressie maar geeft je niet standaard VIF, invloedsstatistieken of residudiagnostiek.
De voorbeeldopzet
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.
Multicollineariteit met VIF
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.
Lineariteit van de logit met Box-Tidwell
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.
Invloedsdiagnostiek
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.
Residudiagnostiek
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.
Hoe je aannames van logistische regressie controleert in R
R heeft strakkere ingebouwde ondersteuning voor deze diagnostiek. Het meeste wat je nodig hebt komt uit base R’s glm() plus het car-pakket.
De voorbeeldopzet
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.
Multicollineariteit met VIF
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.
Lineariteit van de logit met Box-Tidwell
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.
Invloedsdiagnostiek
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
Residudiagnostiek
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.
Wat gebeurt er als aannames worden geschonden?
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:
- Instabiele coëfficiënten: Kleine veranderingen in de data (een paar rijen erbij of eraf, een kleine wijziging in feature engineering) kunnen de coëfficiënten drastisch veranderen of van teken laten wisselen. Dit is wat multicollineariteit doet, en ook wat gebeurt als je steekproef te klein is voor het aantal voorspellers
- Slechte calibratie: De voorspelde kansen van het model komen niet meer overeen met de werkelijke frequenties in de data. Het voorspelt 30% churn voor een groep en je observeert 15%. Accuracy kan er nog prima uitzien, maar de kansen kloppen niet. Schendingen van lineariteit in de logit en invloedrijke uitschieters dragen hier beide aan bij
- Misleidende inferentie: Dit is de lastigste om te zien, omdat het model nog steeds standaardfouten en p-waarden produceert die er goed uitzien. Gecorreleerde observaties verkleinen standaardfouten meer dan zou moeten, en verkeerde predictorspecificaties blazen ze op. Hoe dan ook betekenen de p-waarden die je krijgt niet wat jij denkt dat ze betekenen
- Gedegradeerde voorspelkwaliteit: Het meest zichtbare symptoom, hoewel het in de praktijk vaak het kleinste is. Voorspellingen houden het meestal beter dan coëfficiënten, wat de reden is dat teams die alleen naar accuracy kijken vaak de waarschuwingssignalen missen.
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.
Alternatieven wanneer aannames van logistische regressie falen
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.
- Kies GAM’s wanneer interpreteerbaarheid prioriteit heeft en je wilt zien hoe elke voorspeller de log-odds beïnvloedt
- Kies een gradient-boosted tree wanneer voorspelkwaliteit prioriteit heeft en je een minder transparant model accepteert
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.
Best practices voor modelleren met logistische regressie
Volg tot slot deze korte lijst om altijd een model te krijgen dat je kunt vertrouwen:
- Inspecteer aannames vóór interpretatie: Draai VIF, de Box-Tidwell-test en invloedsdiagnostiek vóórdat je de coëfficiënten afleest. Als je eerst interpreteert en later checkt, betrap je jezelf erop cijfers te verdedigen die je niet hebt geverifieerd. Je wilt niet die persoon zijn in een meeting
- Gebruik regularisatie bij kleine steekproef: Ridge of elastic net stabiliseert coëfficiënten wanneer EPV laag is of voorspellers gecorreleerd zijn. De trade-off is een kleine bias voor een grote variantiereductie, wat meestal een goede deal is
- Valideer op data die het model niet heeft gezien: Houd een testset achter of gebruik cross-validatie. Trainingsmetriek overschat prestaties wanneer het model ruimte heeft om te overfitten, wat logistische regressie heeft zodra je veel voorspellers of zeldzame events hebt
- Evalueer calibratie: Accuracy verbergt of je voorspelde kansen overeenkomen met werkelijke frequenties. Gebruik log-loss of Brier score voor evaluatie, en bekijk een calibratieplot wanneer kansen belangrijk zijn voor businessbeslissingen
Conclusie
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.
FAQs
Heeft logistische regressie aannames?
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.
Wat zijn de belangrijkste aannames van logistische regressie?
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.
Wat gebeurt er als aannames van logistische regressie worden geschonden?
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.
Vereist logistische regressie normaal verdeelde voorspellers?
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.
Wat is een goede VIF-drempel voor logistische regressie?
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.

