Run Forest Run!

Hallo wereld,

Vandaag kan ik met trots aankondigen dat mijn Random Forest applicatie af is! Ik moet toegeven, ik begon te twijfelen of deze dag ooit nog zou komen. Maar, de aanhouder wint.

Het was echter niet de bedoeling om alleen een Random Forest te maken. De bedoeling was om hem te vergelijken met die van de scikit-learn library. In het bijzonder de applicatie van de EliteDataScience tutorial. Om dat te kunnen doen moest ik nog wat extra aanpassingen maken. Ten eerste moest de data verdeeld worden in een training- en testset. Vervolgens moest alle data gestandaardiseerd worden. Daarnaast moesten er ook nog wat statistische gegevens berekend worden om de prestatie van het algoritme te peilen.

Dit heb ik dan (onder andere) gedaan voor een random forest met 50 bomen met maximale diepte van 20 en een sample grootte van 100. Dat wil zeggen, er zijn 50 beslissingsbomen gemaakt met maximaal 20 lagen van vertakkingen, die gegroeid zijn op basis van 100 willekeurig geselecteerde gegevensrijen uit de trainingset. Daarnaast werden dan ook nog voor elk van die bomen slechts willekeurig 3 kwart van de kolommen geselecteerd. Dit zorgt voor extra variatie tussen de bomen. Deze bomen doen dan elk hun voorspelling en de voorspelling met de meeste stemmen wint.

Het resultaat is een model dat met succes de data van de rode wijn laadt en modelleert, met een r2-score van 0.31 (vs 0.47) en een mean-squared-error van 0.5 (vs 0.33). Ter herhaling, de r2 score geeft aan hoe goed de fit van het model is. De mean-squared-error geeft aan hoe nauwkeurig het model is. Oftewel, mijn model is een slechtere fit en minder nauwkeurig. Dit was echter te verwachten, aangezien mijn model niet automatisch getuned wordt en ik de hyperparameters willekeurig gekozen heb.

Daarnaast heb ik ook de nauwkeurigheid van het model laten uitrekenen, welke 0.67 was. Niet al te slecht dus, het raadt het 2 van de 3 keer goed. Voor het sk-learn model is dit echter niet direct uit te rekenen aangezien deze in tegenstelling tot mijn model geen categorische maar numerieke voorspellingen maakt. Hierdoor zijn alle voorspellingen automatisch niet exact juist, en moet ik dus de afgeronde waardes gebruiken. Als ik dat doe, krijg ik verrassend genoeg een nauwkeurigheid van slechts 0.69. Slechts 2 procent nauwkeuriger dan mijn eigen model!

Hoe dan ook is mijn missie geslaagd. Ik heb mijn eigen Random Forest algoritme gemaakt, en het vergeleken met het model van de EliteDataScience tutorial. Hiermee heb ik niet alleen veel geleerd over de werking van het Random Forest algoritme, ik heb ook mijn vaardigheid met Python enorm verbeterd!

De code kun je hier vinden. Ook heb ik de winesnobloader aangepast om de nauwkeurigheid uit te rekenen. In de toekomst zal ik misschien wat dieper ingaan op de werking en/of wat tutorials geven voor het maken van deze en mijn andere applicaties. Op het moment heb ik echter een probleem met mijn geluidsopname-kwaliteit, dus hoe ik dat ga doen weet ik nog niet. Maar, dat is alles voor nu.

Tot de volgende keer!

 

Worstelen met bomen

Hallo wereld,

Mijn missie om een random forest te maken met Python bleek een stuk lastiger dan ik aanvankelijk had gedacht. Maar, ik heb het nog niet op gegeven. En, hoewel ik er de afgelopen maand een beetje teveel omheen heb gedraaid ben ik er nog steeds mee bezig geweest. En vooral de afgelopen week heb ik weer wat vooruitgang gemaakt.

Na het maken van mijn eerste versie voor een beslissingsboom algoritme had ik namelijk een video met een link naar de voorbeeldcode gevonden op Youtube. In dit voorbeeld wordt ook een beslissingsboom met Python gemaakt, maar de programmeur pakt het toch allemaal net wat beter aan dan ik zelf deed. Het belangrijkste verschil is dat hij gebruikt maakte van recursie, dus ik besloot opnieuw te beginnen en ook een beslissingsboom met recursie te maken. Ik had hierbij het voornemen om alleen de informatie in de video te gebruiken en de voorbeeldcode te negeren.

En, dit was me redelijk goed gelukt, maar toen ik de beslissingsboom net zoals in mijn vorige applicatie probeerde te tekenen raakte ik in de problemen. De bomen werden succesvol gemaakt, wat ik kon zien door het resultaat in tekst te printen, maar om hem (recursief) te tekenen, dat wilde me maar niet lukken. Ondanks mijn vele pogingen.

Als je zelf ervaring hebt met het werken met grote lappen code dan weet je misschien wel hoe moeilijk het kan zijn om een groot project weer op te pakken nadat je er een tijd niet aan gewerkt hebt. Je bent vergeten wat alles ook alweer precies doet, en wat je precies nog allemaal moest doen. Als je dan niet de tijd neemt om je code weer grondig te bestuderen alsof je hem voor het eerst ziet dan kan je veel tijd verspillen. Niets wil werken, je snapt niet waarom, en je staart met frustratie en wanhoop naar je grote lap met code en vraagt je af of je niet beter opnieuw kan beginnen.

Uiteindelijk heb ik dan toch maar de moeite genomen om mijn code weer opnieuw te bestuderen. Regel voor regel. Functie voor functie. En bij al deze functies erbij gezet wat ze ook alweer precies deden. Hierdoor had ik eindelijk weer een goed begrip van hoe alles precies ook alweer werkte en was de code niet zo intimiderend meer.

En toen heb ik toch ook maar de voorbeeldcode erbij gepakt en kwam ik erachter dat daarbij niet eens de moeite werd gedaan om de boom te tekenen. In plaats daarvan werd de boom wel heel netjes met recursie geprint en gebruikt voor het maken van voorspellingen. Deze methodes heb ik dan maar aangepast en aan mijn programma toegevoegd.

Het resultaat is een efficiënte, overzichtelijke en werkende applicatie voor het maken van classificatie (maar geen regressie) bomen. Mocht je vergeten zijn wat dat betekent, het houdt in dat de boom in staat is om data in categorieën te plaatsen, maar nog niet in staat is om (exacte) numerieke voorspellingen te doen.

Aanvankelijk dacht ik regressie nodig zou hebben voor de wijndata, maar nadat ik de moeite had genomen om de data te onderzoeken kwam ik erachter dat er maar vijf verschillende cijfers voor de wijnkwaliteit waren in de gehele dataset: 3 tot en met 8. Dus, het enige wat nu nog te doen staat is het implementeren van deze beslissingsboom in een random forest algoritme. En de resultaten te vergelijken met die van de Random Forest Wijnproever zoals die op EliteDataScience geïmplementeerd was. Zou moeten lukken.

Hoe dan ook ben ik al ver gekomen tijdens het werken aan deze beslissingsboom. Mijn aanvankelijke doel voor dit project was het leren begrijpen en maken van random forests. Tot mijn eigen verbazing las ik zelf in mijn eerste bericht bij dit project terug dat ik nog niet eens van plan was om een Data Scientist te worden op dit punt. Maar, uiteindelijk verschoof het hoofddoel van dit project naar het leren programmeren met Python voor Data Science.

En, ik heb een hele hoop over Python geleerd tijdens het maken van deze beslissingsboom. Het zelf kunnen maken van een random forest is echter niet meer mijn belangrijkste leerdoel, het is slechts een project voor het oefenen met Python. Uiteindelijk is het belangrijker dat ik leer te werken met de libraries van Python voor het analyseren van data en het trainen van machine learning algoritmes. En daar zal ik dan ook na dit project mee verder gaan.

Maar, dat is alles voor nu.

Tot de volgende keer!

Door de bomen het bos zien

Hallo wereld!

Wat zijn random forests?

Hoe werken ze?

Waar worden ze voor gebruikt?

Nou, laat ik eerst een stap terug doen en wat uit leggen over machine learning en decision trees. Random forests zijn namelijk machine learning algoritmes die zijn opgebouwd uit decision trees.

Machine learning

Machine learning is het subgebied binnen kunstmatige intelligentie dat zich bezig houdt met het bedenken en trainen van algoritmes die leren van gegevens. Het zijn programma’s met een aantal variabele parameters die zich aan passen aan een dataset om een zo effectief mogelijk eindprogramma te realiseren.

Het is te vergelijken met de manier waarop wij leren. Op basis van de gebeurtenissen in ons verleden passen wij ons gedrag aan voor de gebeurtenissen in de toekomst.

Soms krijgen wij hier begeleiding bij, van ouders en leraren, die ons vertellen wat we wel of niet moeten of kunnen doen. Op andere momenten zoeken we het zelf uit, met vallen en opstaan. Zo is het ook met machine learning. Je hebt daarbij supervised (onder toezicht) en unsupervised (zonder toezicht) leren. Decision trees (beslissingsbomen) vallen onder de supervised categorie.

Wat houdt dit in?

Nou, je moet het algoritme in principe les geven. Je geeft het een gelabelde dataset, dat wil zeggen een dataset met de gewenste antwoorden bijgevoegd. Bijvoorbeeld een verzameling van plaatjes van honden en katten met de labels hond of kat. Op basis van die gelabelde data kan het algoritme dan leren wat het verschil is tussen honden en katten en nieuwe plaatjes zelf leren categoriseren.

De twee hoofdtaken binnen supervised learning zijn classificatie en regressie. Bij classificatie wordt de data gecategoriseerd, net zoals bij het voorbeeld met honden en katten. Bij regressie wordt er een continue waarde aan toegedeeld. Bijvoorbeeld een algoritme dat de leeftijd van een mens of dier op basis van een foto bepaalt.

 

Decision Trees

Decision trees zijn machine learning algoritmes die leren data te categoriseren aan de hand van een model met knooppunten en vertakkingen. Bij elk knooppunt wordt een datapunt getest op een bepaalde variabele en op basis daarvan wordt bepaald naar welk volgende knooppunt het gaat voor de volgende test. Uiteindelijk komt het dan uit bij een eindknooppunt, een blad (leaf). Hierbij wordt het datapunt dan gelabeld binnen een een bepaalde klasse (of een continue waarde in het geval van regressie).

Een voorbeeld?

Hierbij zijn de vierkanten dan dus de knooppunten, de lijntjes de takken en de rondjes de bladeren. Hoe bepaalt het algoritme wat de criteria zijn waar op getest wordt in de knooppunten?

Brute kracht in principe. Bij elk knooppunt wordt voor elke variabele voor een groot aantal waarden getest tot wat voor split het zou zorgen in de dataset. Uiteindelijk wordt dan gewoon de split gekozen die de data het beste opsplitst. Dit proces wordt herhaald tot de gekozen eindcriteria bereikt worden (bijvoorbeeld de maximale lengte voor de boom).

Decision trees hebben echter de vervelende gewoonte om data te ‘overfitten‘. Ze vormen zichzelf op een manier die heel nauwkeurig de trainingset kan modeleren, maar doen dit zo overdreven dat ze het slecht doen voor nieuwe gegevens. Ze leren de antwoorden in plaats van de patronen. Om dit te voorkomen kun je de decision trees ‘snoeien’. Dit houdt in dat je hem kleiner maakt zodat hij niet te gefocust raakt op de details. Maar er zijn ook andere oplossingen, en een daarvan is het random forest algoritme.

 

Random Forest

Een random forest is precies dat wat de naam al suggereert: een verzameling van (random) beslissingsbomen. Er wordt een verzameling van decision trees gegenereerd met random variaties in de trainingset en input variabelen. Deze decision trees krijgen dan elk een stem. In het geval van classificatie wordt het uiteindelijke antwoord bepaald door de meerderheid van die stemmen. In het geval van regressie wordt het gemiddelde genomen. Op deze manier wordt voorkomen dat het model overfit raakt, iets wat vooral een risico is voor trainingsets met veel variabelen en weinig datapunten. Random forests daarentegen kunnen daar over het algemeen uitstekend mee omgaan.

Dit en het feit dat ze over het algemeen vrij simpel te trainen zijn maakt ze erg populair. Ze doen het vooral goed voor classificatie maar zijn ook geschikt voor regressie. Ze worden gebruikt bij allerlei toepassingen op allerlei gebieden. Ze worden gebruikt door banken om kandidaten voor een lening te beoordelen. Ze worden gebruikt op de beurs om trends te voorspellen. Ze worden gebruikt in computer visie, bijvoorbeeld voor X-box connect. En nog veel meer.

En dat is het!

Simpel nietwaar? Natuurlijk komt er wat meer bij kijken als je zo’n decision tree of random forest zelf wilt implementeren en trainen. Maar daarover later meer. Ik wil er namelijk eerst voor zorgen dat je het grote plaatje duidelijk hebt. Door de bomen het bos zien aldus. Bovendien heb ik de details zelf ook nog niet allemaal op een rijtje. Een boom tegelijk planten en zo. Maar, dat is alles voor nu.

 

Tot de volgende keer!

Project update: Random Forest Wijnproever

Hallo wereld,

Inmiddels ben ik begonnen aan de Random Forest Wijnproever. Ik heb de tutorial succesvol afgerond en een werkend model met behulp van de sklearn library gegenereerd.

Laat ik beginnen met uitleggen wat ik gedaan heb in deze tutorial. Alle code werd in deze tutorial gewoon aangereikt en het was in principe een kwestie van de uitleg lezen en de code gewoon overtypen. Desalniettemin is het toch een leerzame oefening zolang je de uitleg ook echt bestudeert en je best doet om de stappen te begrijpen. Het is echter best ingewikkelde theorie en als ik de Data Science Primer niet eerst bestudeerd had dan had ik er waarschijnlijk niet veel van gevolgd. Snap je dus niet waar ik het over heb, dan is het misschien een idee om daar eerst eens naar te kijken en/of naar de voorkennis die wordt aanbevolen in de tutorial. Mijn versie van de code kun je hier vinden. In tegenstelling tot in de voorbeeldcode heb ik twee afzonderlijke scripts gemaakt, een voor het genereren van het model (winesnob.py) en een voor het laden ervan nadat het is opgeslagen (winesnobloader.py). Hieronder zal ik uitleggen hoe het model gemaakt wordt.

Stap  3 en 4

Na het importeren van alle relevante libraries begint het met het laden van de dataset van een online locatie. Daarna wordt de dataset willekeurig gesplitst in een training set en een test set. Zoals de namen al suggereren, de trainingset is de subset van de data die gebruikt wordt om het model te trainen, en de testset de subset die gebruikt wordt om het model te testen. Het is belangrijk dat deze data gescheiden blijft, want anders leert het model geen patronen te ontdekken, maar gewoon de vaste antwoorden op de gegeven dataset. Het is te vergelijken met studenten laten studeren voor een proefwerk met het antwoordmodel. We willen niet dat het model leert alleen te presteren op de gegeven dataset maar op alle data. Om te kunnen testen hoe goed onze student de theorie heeft begrepen is het van belang dat we hem met vragen presenteren die hij/zij nog niet gezien heeft. Zo ook voor ons model.

Stap 5

Vervolgens is het de zaak om de data voor te bereiden. De data is namelijk nog niet geschikt voor het algoritme. Het moet nog gestandaardiseerd worden. Wat houdt dit in? Nou, dit is een concept binnen de statistiek. De korte versie is echter dat de data voor alle eigenschappen rond 0 wordt gecentreerd door het gemiddelde van die eigenschappen er af te halen. Daarnaast wordt het ook gedeeld door iets wat de standaarddeviatie heet, en dit zorgt ervoor dat de spreiding van de gegevens voor alle eigenschappen ongeveer hetzelfde is. Het resultaat van deze bewerkingen is dat alle eigenschappen even sterk meegenomen worden in het algoritme.

Stap 6, 7 en 8

Vervolgens is het tijd om het model te genereren en het vervolgens te trainen. Maar voordat we het model loslaten op de gehele trainingset is het eerst de zaak om de hyperparameters te bepalen. Dit zijn de parameters die bepalen HOE het model leert, niet WAT het leert. Om deze te kunnen bepalen wordt gebruikt gemaakt van een techniek die cross-validatie heet. Hierbij worden meerdere subsets van de trainingset gemaakt waarop modellen met verschillende hyperparameters worden losgelaten. Bij elk van die subsets wordt een kleine portie van de totale trainingset weggelaten bij het trainen van dit model en gebruikt voor het testen van dit model. Op deze manier blijft de echte testset dus onaangetast. Vervolgens worden de hyperparameters van het model met de beste prestatie uitgekozen. Deze hyperparameters worden dan gebruikt voor het model dat wordt losgelaten op de gehele trainingset. Deze laatste stap geeft slechts een kleine verbetering in prestatie ten opzichte van het model dat al losgelaten was op een iets kleinere portie van de trainingset, maar alle beetjes helpen.

Stap 9

Nu het model getraind is kan het getest worden op de testset. Hiervoor wordt het model gebruikt om de afhankelijke variabele te berekenen uit de onafhankelijke variabelen in de testset. Dit resultaat wordt dan vergeleken met de daadwerkelijke afhankelijke variabele die al gegeven was. De nauwkeurigheid van het model wordt dan weergegeven door de r2-score en mean-squared-error (mse) uit te rekenen.  De mean-squared-error spreekt voor zich, die wil je gewoon zo klein mogelijk hebben. De r2-score, ook wel determinatiecoëfficiënt (coefficient of determination) geeft aan hoe goed de “fit” is van het model. Bij een r2 van 1 is die “perfect”, maar van wat ik begrepen heb wil je tegelijkertijd ook voorkomen dat je model “overfit” is. Voor mijn model was de r2-score 0.46 en de mse 0.35, wat ongeveer overeen kwam met de waardes uit de tutorial. Wat dat precies betekent wordt niet echt uitgelegd, en heb ik ook nog niet uit kunnen vinden.

Stap 10

Nu hoeven we het model alleen nog op te slaan zodat we het met het andere script kunnen laden.

En klaar is Kees! Snap je het allemaal? Geloof het of niet, dat was het makkelijke gedeelte. Nu komt de echte uitdaging nog: mijn eigen Random Forest Algoritme schrijven. Ik ben hier namelijk al aan begonnen en ik zie nu al dat het een flinke uitdaging gaat worden. Al is het alleen maar het uitvogelen van Python. Ook zou het wel interessant zijn om de code aan te passen zodat het scores kan geven voor individuele gevallen. In hoeverre dit alles gaat lukken durf ik niet te zeggen, maar ik zal mijn best gaan doen. Dat is alles voor nu.

Tot de volgende keer!

 

Projectaankondiging: Random Forest Wijnproever

Hallo wereld,

Een tijd geleden gaf ik al aan dat ik een nieuw idee had voor een project.  Ik had het idee om een simulatie te programmeren, data te genereren en een programma te schrijven om die data te analyseren. Echter, dit idee gaat voorlopig niet door. Waarom niet? Nou het was me nog niet echt duidelijk hoe deze programma’s er precies uit zouden komen te zien. En hoe meer ik hierover nadacht, hoe meer ik me realiseerde dat ik me eigenlijk eerst ergens anders op wilde focussen. Namelijk, het bestuderen, toepassen en zelf programmeren van machine learning algoritmes. Aldus koos ik voor het volgende project.

Ik ga een tutorial volgen voor het schrijven van een machine learning applicatie in Python die wijnkwaliteit leert beoordelen. Een tutorial op EliteDataScience, een website die mensen de leermiddelen aanreikt om een data wetenschapper te worden. Nu vindt ik dat reuze interessant, maar het is op het moment niet mijn bedoeling om een data wetenschapper te worden, maar een programmeur van datasystemen. En met deze tutorial leer ik onder andere hoe ik de data science libraries van Python kan gebruiken om data te analyseren. En ik heb al wat geleerd op deze site over wat er allemaal komt kijken bij het uitvoeren van een goede data analyse, maar ik wil een stapje verder gaan. Ik wil ZELF het algoritme programmeren dat de data analyseert, in plaats van alleen de kant en klare versie in de gebruikte Python library te leren toepassen. En dat is dan ook het echte project: mijn eigen algoritme programmeren.

Misschien dat je je afvraagt wat het nut hier van is. Immers, waarom zou ik iets programmeren waar al een library voor is? Nou, het antwoord daarop is natuurlijk dat ik wil leren hoe het het algoritme werkt. Ik wil het zo goed leren begrijpen dat ik het zelf kan programmeren.

Bovendien zal ik hiermee ook mijn programmeervaardigheden over het algemeen verbeteren. En ja, ik ga dat doen met Python. Een taal waar ik tot nu toe slechts een klein beetje ervaring mee heb opgedaan met het maken van Conway’s Game of Life. Dat is het eerste en enige programma dat ik tot nu toe met Python heb gemaakt. Dus ook dat zal leerzaam zijn.

Eerst volg ik de tutorial en voer ik de data analyse uit met de methode uit de library. In de tutorial leer je om een programma te schrijven dat leert om een cijfer voor de wijnkwaliteit te berekenen op basis van een lijst van eigenschappen. Het leert om dit te doen op basis van een set trainingsdata. Het doet dit met een random forest algoritme uit de Scikit-Learn library. Daarna schrijf ik mijn eigen random forest algoritme, voer de analyse daarmee opnieuw uit, en vergelijk de resultaten. Het random forest algoritme is een regressie algoritme: het leert om een variabele te berekenen op basis van een aantal inputvariabelen. En zegt dit je niet niets, bekijk dan eventueel ook mijn post over datamining waarin ik onder andere kort uitleg wat regressie is. En wat het random forest algoritme betreft, daarover en ook over regressie zal ik meer uitleggen in de loop dit project. Wil je nu al meer weten hierover, kijk dan misschien eens naar H5 van de Data Science Primer op EliteDataScience. Daar wordt het heel duidelijk uitgelegd. Dat is alles voor nu.

Tot de volgende keer!