- Je herschikt één feature met expliciete indexvolgorden terwijl model en labels vastblijven.
- Je berekent verliesverschillen en beschrijvende spreiding en onderscheidt modelafhankelijk belang van causaliteit.
Een bezorgtijdmodel gebruikt afstand en ordergrootte. Welk kenmerk gebruikt het model werkelijk bij zijn voorspellingen? Een groot gewicht of een overtuigende uitleg vertelt nog niet wat er met zijn kwaliteit gebeurt wanneer informatie uit een kolom wordt verstoord.
Denk aan een spreadsheet waarin je één kolom door elkaar schudt. De labels blijven bij hun oorspronkelijke rijen; de andere kolommen ook. Als het vaste model daarna slechter voorspelt, gebruikte het kennelijk informatie uit die kolom in deze gegevens.
Je werkt met volledig verzonnen, genormaliseerde oefenscores. Negatieve waarden betekenen hier onder het gekozen midden, geen negatieve kilometers. Alle modelparameters blijven tijdens de vergelijking vast.
1. Meet eerst de oorspronkelijke fout
Permutatiebelang (permutation importance) is afhankelijk van een gekozen kwaliteitsmaat. Hier gebruik je gemiddelde kwadratische fout (mean squared error, MSE): groter is slechter. Controleer de baseline voordat je verschillen gaat interpreteren; een slecht model kan bruikbare kenmerken ongebruikt laten.
Noem de labels y_i, de voorspellingen ŷ_i en het aantal rijen n. Per rij kwadrateer je het verschil en daarna middel je. De eenheid is de gekwadrateerde oefenscore, geen percentage.
Bij labels nul en twee en voorspellingen één en nul zijn de verschillen één en min twee. Hun kwadraten zijn één en vier, dus het gemiddelde is 2,5. Dat is de berekening die je code moet bewaren.
print(squared_loss([0.,2.],[1.,0.]))
# 2.5
012. Verander precies één informatiebron
Onze drie rijen liggen op een diagonaal: beide kenmerken hebben telkens dezelfde waarde. Een indexvolgorde 2, 1, 0 verplaatst de laatste waarde naar de eerste rij. Alleen de gekozen kolom verandert; je hersorteert dus niet de volledige tabel of de labels mee.
data = [
[-1.,-1.],
[0.,0.],
[1.,1.]]
order = [2,1,0]
changed = permute_feature(data,0,order)
for row in changed:
print(row.tolist())
# [1.0, -1.0]
# [0.0, 0.0]
# [-1.0, 1.0]
De nieuwe combinaties liggen niet allemaal op de oorspronkelijke diagonaal. Dat is een belangrijke beperking bij samenhangende kenmerken: je kunt het model ongewone combinaties aanbieden. De uitkomst zegt iets over deze ingreep in dit model, niet automatisch over een oorzaak in de echte wereld.
023. Vergelijk verlies met dezelfde vaste referentie
Het gegeven tweefeaturemodel combineert een bias, twee gewichten en een mogelijke interactie. Kies hier gewicht één voor de eerste kolom en nul voor de tweede, zonder bias of interactie. Met labels min één, nul en één voorspelt dit model de oorspronkelijke drie rijen precies.
Herschik één kolom, behoud de labels en vergelijk met hetzelfde baselineverlies. Kies ook een model waarbij verstoring juist helpt.
Vast model: gewichten 1 / 0, bias 0, interactie 0.
De tweede kolom voorspelt dezelfde labels, maar dit vaste model gebruikt haar niet.
- Baselineverlies
- 0
- Gemiddeld verschil
- 1,333
- Populatiespreiding
- 1,333
Verlies na verstoring min baseline: 1,333 gemiddeld. In deze vaste vergelijking stijgt het gemiddelde verlies.
Nieuwe kolom volgt rij-indices 2, 1, 0 (vanaf nul). Labels blijven bij hun rij. Verschil voor deze volgorde: 2,667.
| Rij | x₀ | x₁ | Label | Voorsp. |
|---|---|---|---|---|
| 0 | -1↓1 | -1↓-1 | -1 | -1↓1 |
| 1 | 0↓0 | 0↓0 | 0 | 0↓0 |
| 2 | 1↓-1 | 1↓1 | 1 | 1↓-1 |
Dit zijn expliciet opgegeven volgorden, geen nieuwe willekeurige trekkingen. De populatiespreiding beschrijft deze herhalingen en is geen betrouwbaarheidsinterval. Correlatie kan ongewone combinaties maken; een afgeronde nul bewijst geen exact nul-effect of waardeloos kenmerk.
Alle modellen en rijen zijn verzonnen en blijven vast. Deze uitleg beschrijft modelgedrag bij de gekozen gegevens en ingreep; zij bewijst geen causaliteit, dataherkomst of geldigheid buiten deze oefening.
Noem het baselineverlies L_0 en het verlies na permutatie r L_r. Het verschil E_r is L_r min L_0; het gemiddelde over R opgegeven volgorden is het getoonde belang. Bij een hogere-is-beter score zou je juist een scoreafname meten, dus houd de tekenconventie expliciet.
Omkeren geeft voorspellingen één, nul en min één: de kwadratische fouten zijn vier, nul en vier. Het verlies wordt 8/3; de onveranderde volgorde geeft nul. Over die twee vaste volgorden zijn gemiddelde verschil en populatiestandaardafwijking beide 4/3.
model = {'weights':[1.,0.],
'bias':0.,'interaction':0.}
labels = [-1.,0.,1.]
orders = [order,[0,1,2]]
effect = permutation_effect(
model,data,labels,0,orders)
print(effect['baseline_loss'])
print(round(effect['mean_change'],3))
print(round(effect['spread'],3))
# 0.0
# 1.333
# 1.333
De spreiding is de wortel van de gemiddelde gekwadrateerde afwijking van dat gemiddelde. Zij beschrijft deze opgegeven volgorden; twee gekozen voorbeelden zijn geen betrouwbaarheidsinterval of bewijs van onafhankelijke randomtrekkingen. Herhaalde volgorden mogen in de invoer voorkomen.
03Wat vertelt een nul of een negatief verschil?
Draai het eerste gewicht om. Het model voorspelt dan oorspronkelijk precies de verkeerde richting; de omgekeerde kolom helpt het toevallig. Het verliesverschil is negatief en moet zichtbaar blijven.
bad = dict(model,weights=[-1.,0.])
negative = permutation_effect(
bad,data,labels,0,[order])
unused = permutation_effect(
model,data,labels,1,[order])
print(round(negative['mean_change'],3))
print(unused['mean_change'])
# -2.667
# 0.0
De tweede kolom is volledig voorspellend, maar dit vaste model gebruikt haar niet. Nul belang maakt dat kenmerk dus niet intrinsiek waardeloos. Bij vrijwel nul verschillen kan bovendien gewone float64-afronding een kleine verandering tot nul afronden.
Wat je nu kunt
- Je kiest een verliesmaat en controleert de baseline op vastgehouden gegevens.
- Je verstoort één kolom terwijl labels en model gelijk blijven.
- Je bewaart negatieve effecten en begrenst conclusies bij correlatie en afronding.
Hierna bekijk je responslijnen: wat doet hetzelfde model als je één feature langs een grid schuift?