In de programmeertaal R wordt de functie round() vaak gebruikt om getallen naar het dichtstbijzijnde gehele getal af te ronden. Dit kan een waarde vereenvoudigen en beter geschikt maken voor verdere berekeningen of presentaties. Wanneer we een aangepaste functie maken, kunnen we de round() functie gebruiken om het resultaat van een berekening af te ronden, zoals bijvoorbeeld bij de wortel van een getal. Een voorbeeld hiervan is een functie die de vierkantswortel van een getal berekent en het resultaat afrondt:
Wanneer deze functie wordt aangeroepen met bijvoorbeeld square_root_and_round(50), zal de functie de vierkantswortel van 50 berekenen (wat ongeveer 7.071 is) en het resultaat afronden naar het dichtstbijzijnde gehele getal, 7.
Wat opvalt, is dat de functie return() in R vaak expliciet niet nodig is om een waarde terug te geven. R retourneert automatisch de waarde van de laatste berekening binnen een functie. Dit maakt de code eenvoudiger en vermindert de noodzaak van overbodige regels. Echter, in sommige gevallen kan het handig zijn om de return() functie expliciet te gebruiken, bijvoorbeeld wanneer je de uitvoer van een functie duidelijk wilt definiëren of de stroom van de functie beter wilt beheersen. Het volgende is dus een vereenvoudigde versie van dezelfde functie, zonder het gebruik van return():
Zelfs zonder de return() functie zal het resultaat van de laatste bewerking, namelijk de afgeronde waarde, automatisch worden geretourneerd wanneer de functie wordt aangeroepen. Dit vereenvoudigt de code zonder verlies van functionaliteit, zeker bij eenvoudige berekeningen.
Naast eenvoudige functies zoals de bovenstaande, kan het nodig zijn om functies te schrijven die meerdere argumenten vereisen. Het werken met meerdere argumenten biedt veel flexibiliteit, vooral bij complexere berekeningen. Zo kunnen we een functie schrijven die twee getallen accepteert, de eerste verheft tot de macht van de tweede, en het resultaat afrondt. Dit zou er als volgt uitzien:
Wanneer we deze functie aanroepen met verschillende argumenten, zoals power_and_round(2.1, 3.2) of power_and_round(5.1, 2.2), zullen we telkens het resultaat van de macht en de afgeronde waarde terugkrijgen. Bij dergelijke functies is het belangrijk om te weten dat de volgorde van de argumenten bepalend is voor de uitkomst. Om dit te beheren, kun je expliciet de argumenten benoemen tijdens het aanroepen van de functie:
Op deze manier kun je de volgorde van de argumenten aanpassen zonder verwarring te veroorzaken. Daarnaast kunnen argumenten standaardwaarden krijgen, wat handig is voor het schrijven van flexibele en gebruiksvriendelijke functies. Als we bijvoorbeeld een standaardwaarde willen voor y, kunnen we de functie als volgt aanpassen:
Nu kan de functie zowel met één argument als met twee argumenten worden aangeroepen. Wanneer slechts één argument wordt opgegeven, wordt de standaardwaarde voor y gebruikt, wat de functie nog flexibeler maakt:
Dit resulteert in het afgeronde resultaat van 12.5 tot de macht 2.
Bij het werken met variabelen binnen functies is het belangrijk om de concepten van variabelen en hun bereik te begrijpen. In R, zoals in de meeste programmeertalen, hebben variabelen die binnen een functie worden gedefinieerd een lokaal bereik. Dit betekent dat een variabele binnen een functie alleen toegankelijk is binnen die functie en geen invloed heeft op variabelen buiten de functie. Dit wordt geïllustreerd door het volgende voorbeeld:
In dit geval heeft de variabele x binnen de functie test_scope() geen invloed op de globale variabele x, omdat ze in verschillende omgevingen bestaan. Het begrijpen van deze scope is essentieel om onverwachte resultaten te vermijden bij het werken met complexe functies.
Een andere belangrijke techniek in R is het gebruik van geneste functies en de zogenaamde "pipe" operator (|>). Wanneer we functies combineren, kunnen we intermediate resultaten direct doorgeven aan de volgende functie, wat de leesbaarheid van de code kan verbeteren en de geheugengebruik kan verminderen. In plaats van eerst een variabele op te slaan voor het resultaat van de vierkantswortel en daarna te ronden, kunnen we de berekeningen in één stap combineren met de pipe operator:
Dit maakt de code eenvoudiger en beknopter, maar kan soms moeilijker te begrijpen zijn wanneer de berekeningen complexer worden. Het is belangrijk om de leesbaarheid van de code niet op te offeren voor kortere schrijfwijze.
R biedt ook alternatieve manieren om functies te nestelen, zoals de "magrittr" pipe operator (%>%), die veel wordt gebruikt in de R-gemeenschap. Deze pipe werkt in wezen hetzelfde als de basis R-pipe, maar biedt enkele extra functionaliteiten. Het gebruik van de juiste operator hangt af van persoonlijke voorkeur en de specifieke vereisten van de taak.
Hoe een verwarringsmatrix kan worden gebruikt voor modelvalidatie en voorspellingen in regressieanalyse
Het evalueren van een model is cruciaal voor het begrijpen van de prestaties en het verbeteren van de nauwkeurigheid. Eén van de meest gebruikte hulpmiddelen hiervoor is de verwarringsmatrix, die een overzicht biedt van de voorspellende kracht van een model. Hoewel er verschillende methoden zijn om modelprestaties te beoordelen, is de verwarringsmatrix vaak de eerste stap om een beter inzicht te krijgen in hoe goed ons model functioneert.
Het proces om een verwarringsmatrix te creëren kan in drie eenvoudige stappen worden onderverdeeld. Eerst verzamelen we de werkelijke uitkomsten van de gevechten, de zogenaamde "grondwaarheid". Dit kan eenvoudig worden gedaan door de kolom met de werkelijke uitkomst van de aanvaller, "attacker_winner", uit de originele gegevens te extraheren. In R kan de pull() functie van de dplyr bibliotheek dit eenvoudig realiseren, waarbij de gegevens worden opgeslagen in een vector.
De tweede stap is het verzamelen van de voorspellingen die het model heeft gemaakt. Dit kan worden gedaan door de fitted() functie van het model te gebruiken, die de voorspelde waarden van de aanvaller’s winst tussen 0 en 1 retourneert. Omdat we met een classificatietaak werken, moeten deze waarden worden afgerond: waarden boven de 0.5 worden gecategoriseerd als een overwinning voor de aanvallende Pokémon. Dit kan eenvoudig worden omgezet in een vector.
In de derde en laatste stap wordt de verwarringsmatrix gecreëerd door de functie table() te gebruiken, die de werkelijke en voorspelde uitkomsten vergelijkt.
De verwarringsmatrix wordt weergegeven als een 2x2 matrix, waarin de prestaties van het model kunnen worden afgelezen. De lezing van de matrix kan in de klokrichting als volgt worden geïnterpreteerd:
-
Bovenlinks (Voorspeld 0, Werkelijk 0): Aantal keren dat het model correct voorspelde dat de aanvallende Pokémon zou verliezen.
-
Bovenrechts (Voorspeld 1, Werkelijk 0): Aantal keren dat het model voorspelde dat de aanvallende Pokémon zou winnen, terwijl deze in werkelijkheid verloor.
-
Onderrechts (Voorspeld 1, Werkelijk 1): Aantal keren dat het model correct voorspelde dat de aanvallende Pokémon zou winnen.
-
Onderlinks (Voorspeld 0, Werkelijk 1): Aantal keren dat het model voorspelde dat de aanvallende Pokémon zou verliezen, terwijl deze in werkelijkheid won.
De verwarringsmatrix geeft ons direct inzicht in de nauwkeurigheid van ons model. In het voorbeeld uit de tekst blijkt dat het model ongeveer 90% van de gevechten correct voorspelt, wat wijst op een redelijk goede prestatie. Echter, het is belangrijk om te benadrukken dat een goed presterend model op de trainingsdata niet altijd goed presteert op nieuwe, onbekende data. De prestaties op de testdata zullen waarschijnlijk variëren, en daarom is het essentieel om te leren hoe we ons model kunnen evalueren met verschillende technieken, zoals het splitsen van de gegevens in trainings- en testsets.
Wanneer we ons model eenmaal hebben gevalideerd, kunnen we beginnen met het maken van voorspellingen voor nieuwe gegevens. In dit geval, om de uitkomsten van toekomstige gevechten te voorspellen, moeten we de gegevens die we willen voorspellen samenvoegen met de benodigde kenmerken. Dit kan door de Pokémon-statistieken te combineren met het nieuwe gevechtsdataset.
Bij het voorspellen van nieuwe gegevens is het belangrijk dat alle variabelen die het model gebruikt ook in de nieuwe gegevens aanwezig zijn. Wanneer we de juiste variabelen hebben voorbereid, kunnen we de voorspellingen genereren met behulp van de predict() functie. Deze functie neemt het model als eerste argument en de gegevens die voorspeld moeten worden als tweede argument. Door het argument type = "response" in te stellen, krijgen we de voorspellingen op de schaal van de responsvariabele, wat in dit geval de log-odds is.
Het resultaat van deze stap is een dataset waarin we de voorspelde uitkomsten voor de nieuwe gevechten kunnen zien. Dit stelt ons in staat om met behulp van het model gevechtsresultaten te voorspellen op basis van de kenmerken van de betrokken Pokémon.
Het begrijpen van het proces van modelvalidatie en voorspelling met regressie is essentieel voor het verbeteren van de betrouwbaarheid van onze modellen. Dit proces is echter niet zonder uitdagingen. Hoewel we met een goed begrip van de statistische technieken zoals lineaire en logistische regressie waardevolle inzichten kunnen verkrijgen, blijft het belangrijk om verder te gaan dan alleen de prestatie van het model op de trainingsdata. Een model dat goed presteert op de trainingsset kan alsnog overfitting vertonen, wat betekent dat het zich te veel heeft aangepast aan specifieke kenmerken van de trainingsdata en daardoor minder goed presteert op nieuwe gegevens.
Het is cruciaal om naast het gebruik van een verwarringsmatrix ook andere evaluatiemethoden toe te passen, zoals cross-validatie en het onderzoeken van de AUC (Area Under the Curve) van de ROC (Receiver Operating Characteristic) curve. Dit biedt een meer holistisch inzicht in de werkelijke prestaties van het model en kan ons helpen bij het verbeteren van de voorspellingskracht op onbekende data.

Deutsch
Francais
Nederlands
Svenska
Norsk
Dansk
Suomi
Espanol
Italiano
Portugues
Magyar
Polski
Cestina
Русский