{ "nbformat": 4, "nbformat_minor": 0, "metadata": { "colab": { "name": "lesson_12-R.ipynb", "provenance": [], "collapsed_sections": [] }, "kernelspec": { "name": "ir", "display_name": "R" }, "language_info": { "name": "R" }, "coopTranslator": { "original_hash": "fab50046ca413a38939d579f8432274f", "translation_date": "2025-09-06T12:31:43+00:00", "source_file": "4-Classification/3-Classifiers-2/solution/R/lesson_12-R.ipynb", "language_code": "nl" } }, "cells": [ { "cell_type": "markdown", "metadata": { "id": "jsFutf_ygqSx" }, "source": [ "# Bouw een classificatiemodel: Heerlijke Aziatische en Indiase Keukens\n" ] }, { "cell_type": "markdown", "metadata": { "id": "HD54bEefgtNO" }, "source": [ "## Categorieclassificaties 2\n", "\n", "In deze tweede les over classificatie gaan we `meer manieren` verkennen om categorische data te classificeren. We zullen ook leren over de gevolgen van het kiezen van de ene classifier boven de andere.\n", "\n", "### [**Pre-lecture quiz**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/23/)\n", "\n", "### **Vereisten**\n", "\n", "We gaan ervan uit dat je de vorige lessen hebt afgerond, aangezien we enkele eerder geleerde concepten zullen voortzetten.\n", "\n", "Voor deze les hebben we de volgende pakketten nodig:\n", "\n", "- `tidyverse`: Het [tidyverse](https://www.tidyverse.org/) is een [verzameling van R-pakketten](https://www.tidyverse.org/packages) die datawetenschap sneller, eenvoudiger en leuker maakt!\n", "\n", "- `tidymodels`: Het [tidymodels](https://www.tidymodels.org/) framework is een [verzameling van pakketten](https://www.tidymodels.org/packages/) voor modellering en machine learning.\n", "\n", "- `themis`: Het [themis-pakket](https://themis.tidymodels.org/) biedt extra stappen in recepten om om te gaan met onevenwichtige data.\n", "\n", "Je kunt ze installeren met:\n", "\n", "`install.packages(c(\"tidyverse\", \"tidymodels\", \"kernlab\", \"themis\", \"ranger\", \"xgboost\", \"kknn\"))`\n", "\n", "Als alternatief controleert het onderstaande script of je de benodigde pakketten hebt om deze module te voltooien en installeert ze voor je als ze ontbreken.\n" ] }, { "cell_type": "code", "metadata": { "id": "vZ57IuUxgyQt" }, "source": [ "suppressWarnings(if (!require(\"pacman\"))install.packages(\"pacman\"))\n", "\n", "pacman::p_load(tidyverse, tidymodels, themis, kernlab, ranger, xgboost, kknn)" ], "execution_count": null, "outputs": [] }, { "cell_type": "markdown", "metadata": { "id": "z22M-pj4g07x" }, "source": [ "## **1. Een classificatiekaart**\n", "\n", "In onze [vorige les](https://github.com/microsoft/ML-For-Beginners/tree/main/4-Classification/2-Classifiers-1) probeerden we de vraag te beantwoorden: hoe kiezen we tussen meerdere modellen? Voor een groot deel hangt dit af van de kenmerken van de data en het type probleem dat we willen oplossen (bijvoorbeeld classificatie of regressie?).\n", "\n", "Eerder hebben we geleerd over de verschillende opties die je hebt bij het classificeren van data met behulp van Microsoft's cheat sheet. Het Machine Learning-framework van Python, Scikit-learn, biedt een vergelijkbare maar meer gedetailleerde cheat sheet die verder kan helpen om je keuze van estimators (een andere term voor classifiers) te verfijnen:\n", "\n", "

\n", " \n", "

\n" ] }, { "cell_type": "markdown", "metadata": { "id": "u1i3xRIVg7vG" }, "source": [ "> Tip: [bekijk deze kaart online](https://scikit-learn.org/stable/tutorial/machine_learning_map/) en klik langs het pad om de documentatie te lezen.\n", ">\n", "> De [Tidymodels referentiesite](https://www.tidymodels.org/find/parsnip/#models) biedt ook uitstekende documentatie over verschillende soorten modellen.\n", "\n", "### **Het plan** 🗺️\n", "\n", "Deze kaart is erg handig zodra je een goed begrip hebt van je data, omdat je langs de paden kunt 'wandelen' naar een beslissing:\n", "\n", "- We hebben \\>50 samples\n", "\n", "- We willen een categorie voorspellen\n", "\n", "- We hebben gelabelde data\n", "\n", "- We hebben minder dan 100K samples\n", "\n", "- ✨ We kunnen een Linear SVC kiezen\n", "\n", "- Als dat niet werkt, aangezien we numerieke data hebben\n", "\n", " - Kunnen we een ✨ KNeighbors Classifier proberen\n", "\n", " - Als dat niet werkt, probeer ✨ SVC en ✨ Ensemble Classifiers\n", "\n", "Dit is een erg handig pad om te volgen. Laten we nu meteen aan de slag gaan met het [tidymodels](https://www.tidymodels.org/) modellering framework: een consistente en flexibele verzameling R-pakketten die is ontwikkeld om goede statistische praktijken te bevorderen 😊.\n", "\n", "## 2. Splits de data en ga om met een onevenwichtig data set.\n", "\n", "Uit onze vorige lessen hebben we geleerd dat er een set van gemeenschappelijke ingrediënten was in onze keukens. Ook was er een behoorlijk ongelijke verdeling in het aantal keukens.\n", "\n", "We gaan hiermee om door:\n", "\n", "- De meest voorkomende ingrediënten die verwarring veroorzaken tussen verschillende keukens te verwijderen, met behulp van `dplyr::select()`.\n", "\n", "- Een `recipe` te gebruiken die de data preprocessen om deze klaar te maken voor modellering door een `over-sampling` algoritme toe te passen.\n", "\n", "We hebben het bovenstaande al behandeld in de vorige les, dus dit zou een eitje moeten zijn 🥳!\n" ] }, { "cell_type": "code", "metadata": { "id": "6tj_rN00hClA" }, "source": [ "# Load the core Tidyverse and Tidymodels packages\n", "library(tidyverse)\n", "library(tidymodels)\n", "\n", "# Load the original cuisines data\n", "df <- read_csv(file = \"https://raw.githubusercontent.com/microsoft/ML-For-Beginners/main/4-Classification/data/cuisines.csv\")\n", "\n", "# Drop id column, rice, garlic and ginger from our original data set\n", "df_select <- df %>% \n", " select(-c(1, rice, garlic, ginger)) %>%\n", " # Encode cuisine column as categorical\n", " mutate(cuisine = factor(cuisine))\n", "\n", "\n", "# Create data split specification\n", "set.seed(2056)\n", "cuisines_split <- initial_split(data = df_select,\n", " strata = cuisine,\n", " prop = 0.7)\n", "\n", "# Extract the data in each split\n", "cuisines_train <- training(cuisines_split)\n", "cuisines_test <- testing(cuisines_split)\n", "\n", "# Display distribution of cuisines in the training set\n", "cuisines_train %>% \n", " count(cuisine) %>% \n", " arrange(desc(n))" ], "execution_count": null, "outputs": [] }, { "cell_type": "markdown", "metadata": { "id": "zFin5yw3hHb1" }, "source": [ "### Omgaan met onevenwichtige data\n", "\n", "Onevenwichtige data heeft vaak een negatieve invloed op de modelprestaties. Veel modellen presteren het beste wanneer het aantal observaties gelijk is en hebben daardoor moeite met onevenwichtige data.\n", "\n", "Er zijn grofweg twee manieren om met onevenwichtige datasets om te gaan:\n", "\n", "- het toevoegen van observaties aan de minderheidsklasse: `Over-sampling`, bijvoorbeeld met behulp van een SMOTE-algoritme, dat synthetisch nieuwe voorbeelden van de minderheidsklasse genereert door gebruik te maken van de dichtstbijzijnde buren van deze gevallen.\n", "\n", "- het verwijderen van observaties uit de meerderheidsklasse: `Under-sampling`\n", "\n", "In onze vorige les hebben we gedemonstreerd hoe je met onevenwichtige datasets kunt omgaan met behulp van een `recipe`. Een recipe kun je zien als een blauwdruk die beschrijft welke stappen op een dataset moeten worden toegepast om deze klaar te maken voor data-analyse. In ons geval willen we een gelijke verdeling in het aantal keukens in onze `training set`. Laten we meteen aan de slag gaan.\n" ] }, { "cell_type": "code", "metadata": { "id": "cRzTnHolhLWd" }, "source": [ "# Load themis package for dealing with imbalanced data\n", "library(themis)\n", "\n", "# Create a recipe for preprocessing training data\n", "cuisines_recipe <- recipe(cuisine ~ ., data = cuisines_train) %>%\n", " step_smote(cuisine) \n", "\n", "# Print recipe\n", "cuisines_recipe" ], "execution_count": null, "outputs": [] }, { "cell_type": "markdown", "metadata": { "id": "KxOQ2ORhhO81" }, "source": [ "Nu zijn we klaar om modellen te trainen 👩‍💻👨‍💻!\n", "\n", "## 3. Verder dan multinomiale regressiemodellen\n", "\n", "In onze vorige les hebben we gekeken naar multinomiale regressiemodellen. Laten we enkele flexibelere modellen voor classificatie verkennen.\n", "\n", "### Support Vector Machines\n", "\n", "In de context van classificatie is `Support Vector Machines` een machine learning-techniek die probeert een *hypervlak* te vinden dat de klassen op de \"beste\" manier scheidt. Laten we een eenvoudig voorbeeld bekijken:\n", "\n", "

\n", " \n", "

https://commons.wikimedia.org/w/index.php?curid=22877598
\n" ] }, { "cell_type": "markdown", "metadata": { "id": "C4Wsd0vZhXYu" }, "source": [ "H1~ scheidt de klassen niet. H2~ doet dat wel, maar slechts met een kleine marge. H3~ scheidt ze met de maximale marge.\n", "\n", "#### Lineaire Support Vector Classifier\n", "\n", "Support-Vector clustering (SVC) is een onderdeel van de Support-Vector machines familie van ML-technieken. Bij SVC wordt het hypervlak zo gekozen dat het `de meeste` trainingsobservaties correct scheidt, maar `kan enkele observaties verkeerd classificeren`. Door toe te staan dat sommige punten aan de verkeerde kant liggen, wordt de SVM robuuster tegen uitschieters en daardoor beter in het generaliseren naar nieuwe data. De parameter die deze overtreding reguleert wordt aangeduid als `cost`, welke een standaardwaarde heeft van 1 (zie `help(\"svm_poly\")`).\n", "\n", "Laten we een lineaire SVC maken door `degree = 1` in te stellen in een polynomiaal SVM-model.\n" ] }, { "cell_type": "code", "metadata": { "id": "vJpp6nuChlBz" }, "source": [ "# Make a linear SVC specification\n", "svc_linear_spec <- svm_poly(degree = 1) %>% \n", " set_engine(\"kernlab\") %>% \n", " set_mode(\"classification\")\n", "\n", "# Bundle specification and recipe into a worklow\n", "svc_linear_wf <- workflow() %>% \n", " add_recipe(cuisines_recipe) %>% \n", " add_model(svc_linear_spec)\n", "\n", "# Print out workflow\n", "svc_linear_wf" ], "execution_count": null, "outputs": [] }, { "cell_type": "markdown", "metadata": { "id": "rDs8cWNkhoqu" }, "source": [ "Nu we de stappen voor voorbewerking en modelspecificatie hebben vastgelegd in een *workflow*, kunnen we doorgaan met het trainen van de lineaire SVC en tegelijkertijd de resultaten evalueren. Voor prestatiemetrics laten we een set met metrics maken die de volgende aspecten evalueert: `accuracy`, `sensitivity`, `Positive Predicted Value` en `F Measure`.\n", "\n", "> `augment()` voegt kolom(men) toe met voorspellingen aan de gegeven data.\n" ] }, { "cell_type": "code", "metadata": { "id": "81wiqcwuhrnq" }, "source": [ "# Train a linear SVC model\n", "svc_linear_fit <- svc_linear_wf %>% \n", " fit(data = cuisines_train)\n", "\n", "# Create a metric set\n", "eval_metrics <- metric_set(ppv, sens, accuracy, f_meas)\n", "\n", "\n", "# Make predictions and Evaluate model performance\n", "svc_linear_fit %>% \n", " augment(new_data = cuisines_test) %>% \n", " eval_metrics(truth = cuisine, estimate = .pred_class)" ], "execution_count": null, "outputs": [] }, { "cell_type": "markdown", "metadata": { "id": "0UFQvHf-huo3" }, "source": [ "#### Support Vector Machine\n", "\n", "De support vector machine (SVM) is een uitbreiding van de support vector classifier om een niet-lineaire grens tussen de klassen mogelijk te maken. In essentie gebruiken SVM's de *kerneltruc* om de feature space uit te breiden en zich aan te passen aan niet-lineaire relaties tussen klassen. Een populaire en zeer flexibele kernelfunctie die door SVM's wordt gebruikt, is de *Radiale basisfunctie.* Laten we eens kijken hoe deze presteert op onze data.\n" ] }, { "cell_type": "code", "metadata": { "id": "-KX4S8mzhzmp" }, "source": [ "set.seed(2056)\n", "\n", "# Make an RBF SVM specification\n", "svm_rbf_spec <- svm_rbf() %>% \n", " set_engine(\"kernlab\") %>% \n", " set_mode(\"classification\")\n", "\n", "# Bundle specification and recipe into a worklow\n", "svm_rbf_wf <- workflow() %>% \n", " add_recipe(cuisines_recipe) %>% \n", " add_model(svm_rbf_spec)\n", "\n", "\n", "# Train an RBF model\n", "svm_rbf_fit <- svm_rbf_wf %>% \n", " fit(data = cuisines_train)\n", "\n", "\n", "# Make predictions and Evaluate model performance\n", "svm_rbf_fit %>% \n", " augment(new_data = cuisines_test) %>% \n", " eval_metrics(truth = cuisine, estimate = .pred_class)" ], "execution_count": null, "outputs": [] }, { "cell_type": "markdown", "metadata": { "id": "QBFSa7WSh4HQ" }, "source": [ "Veel beter 🤩!\n", "\n", "> ✅ Zie alstublieft:\n", ">\n", "> - [*Support Vector Machines*](https://bradleyboehmke.github.io/HOML/svm.html), Hands-on Machine Learning with R\n", ">\n", "> - [*Support Vector Machines*](https://www.statlearning.com/), An Introduction to Statistical Learning with Applications in R\n", ">\n", "> voor verdere verdieping.\n", "\n", "### Nabijste buur-classificatoren\n", "\n", "*K*-nearest neighbor (KNN) is een algoritme waarbij elke observatie wordt voorspeld op basis van de *overeenkomst* met andere observaties.\n", "\n", "Laten we er een toepassen op onze data.\n" ] }, { "cell_type": "code", "metadata": { "id": "k4BxxBcdh9Ka" }, "source": [ "# Make a KNN specification\n", "knn_spec <- nearest_neighbor() %>% \n", " set_engine(\"kknn\") %>% \n", " set_mode(\"classification\")\n", "\n", "# Bundle recipe and model specification into a workflow\n", "knn_wf <- workflow() %>% \n", " add_recipe(cuisines_recipe) %>% \n", " add_model(knn_spec)\n", "\n", "# Train a boosted tree model\n", "knn_wf_fit <- knn_wf %>% \n", " fit(data = cuisines_train)\n", "\n", "\n", "# Make predictions and Evaluate model performance\n", "knn_wf_fit %>% \n", " augment(new_data = cuisines_test) %>% \n", " eval_metrics(truth = cuisine, estimate = .pred_class)" ], "execution_count": null, "outputs": [] }, { "cell_type": "markdown", "metadata": { "id": "HaegQseriAcj" }, "source": [ "Het lijkt erop dat dit model niet zo goed presteert. Waarschijnlijk zal het aanpassen van de argumenten van het model (zie `help(\"nearest_neighbor\")`) de prestaties verbeteren. Zorg ervoor dat je dit uitprobeert.\n", "\n", "> ✅ Zie:\n", ">\n", "> - [Hands-on Machine Learning with R](https://bradleyboehmke.github.io/HOML/)\n", ">\n", "> - [An Introduction to Statistical Learning with Applications in R](https://www.statlearning.com/)\n", ">\n", "> om meer te leren over *K*-Nearest Neighbors classifiers.\n", "\n", "### Ensemble classifiers\n", "\n", "Ensemble-algoritmen werken door meerdere basismodellen te combineren om een optimaal model te creëren, op een van de volgende manieren:\n", "\n", "`bagging`: toepassen van een *gemiddelde functie* op een verzameling basismodellen\n", "\n", "`boosting`: bouwen van een reeks modellen die op elkaar voortbouwen om de voorspellende prestaties te verbeteren.\n", "\n", "Laten we beginnen met het uitproberen van een Random Forest-model, dat een grote verzameling beslissingsbomen bouwt en vervolgens een gemiddelde functie toepast voor een beter algemeen model.\n" ] }, { "cell_type": "code", "metadata": { "id": "49DPoVs6iK1M" }, "source": [ "# Make a random forest specification\n", "rf_spec <- rand_forest() %>% \n", " set_engine(\"ranger\") %>% \n", " set_mode(\"classification\")\n", "\n", "# Bundle recipe and model specification into a workflow\n", "rf_wf <- workflow() %>% \n", " add_recipe(cuisines_recipe) %>% \n", " add_model(rf_spec)\n", "\n", "# Train a random forest model\n", "rf_wf_fit <- rf_wf %>% \n", " fit(data = cuisines_train)\n", "\n", "\n", "# Make predictions and Evaluate model performance\n", "rf_wf_fit %>% \n", " augment(new_data = cuisines_test) %>% \n", " eval_metrics(truth = cuisine, estimate = .pred_class)" ], "execution_count": null, "outputs": [] }, { "cell_type": "markdown", "metadata": { "id": "RGVYwC_aiUWc" }, "source": [ "Goed gedaan 👏!\n", "\n", "Laten we ook experimenteren met een Boosted Tree-model.\n", "\n", "Boosted Tree definieert een ensemblemethode die een reeks opeenvolgende beslissingsbomen creëert, waarbij elke boom afhankelijk is van de resultaten van eerdere bomen om stapsgewijs de fout te verminderen. Het richt zich op de gewichten van verkeerd geclassificeerde items en past de fit van de volgende classifier aan om dit te corrigeren.\n", "\n", "Er zijn verschillende manieren om dit model te fitten (zie `help(\"boost_tree\")`). In dit voorbeeld passen we Boosted Trees toe via de `xgboost` engine.\n" ] }, { "cell_type": "code", "metadata": { "id": "Py1YWo-micWs" }, "source": [ "# Make a boosted tree specification\n", "boost_spec <- boost_tree(trees = 200) %>% \n", " set_engine(\"xgboost\") %>% \n", " set_mode(\"classification\")\n", "\n", "# Bundle recipe and model specification into a workflow\n", "boost_wf <- workflow() %>% \n", " add_recipe(cuisines_recipe) %>% \n", " add_model(boost_spec)\n", "\n", "# Train a boosted tree model\n", "boost_wf_fit <- boost_wf %>% \n", " fit(data = cuisines_train)\n", "\n", "\n", "# Make predictions and Evaluate model performance\n", "boost_wf_fit %>% \n", " augment(new_data = cuisines_test) %>% \n", " eval_metrics(truth = cuisine, estimate = .pred_class)" ], "execution_count": null, "outputs": [] }, { "cell_type": "markdown", "metadata": { "id": "zNQnbuejigZM" }, "source": [ "> ✅ Zie:\n", ">\n", "> - [Machine Learning for Social Scientists](https://cimentadaj.github.io/ml_socsci/tree-based-methods.html#random-forests)\n", ">\n", "> - [Hands-on Machine Learning with R](https://bradleyboehmke.github.io/HOML/)\n", ">\n", "> - [An Introduction to Statistical Learning with Applications in R](https://www.statlearning.com/)\n", ">\n", "> - - Verkent het AdaBoost-model, een goed alternatief voor xgboost.\n", ">\n", "> om meer te leren over Ensemble classifiers.\n", "\n", "## 4. Extra - meerdere modellen vergelijken\n", "\n", "We hebben in dit lab behoorlijk wat modellen gefit 🙌. Het kan tijdrovend of lastig worden om veel workflows te maken met verschillende sets preprocessors en/of modelspecificaties en vervolgens één voor één de prestatiestatistieken te berekenen.\n", "\n", "Laten we kijken of we dit kunnen aanpakken door een functie te maken die een lijst van workflows op de trainingsset fit en vervolgens de prestatiestatistieken retourneert op basis van de testset. We gaan `map()` en `map_dfr()` uit het [purrr](https://purrr.tidyverse.org/) pakket gebruiken om functies toe te passen op elk element in een lijst.\n", "\n", "> [`map()`](https://purrr.tidyverse.org/reference/map.html)-functies stellen je in staat om veel for-loops te vervangen door code die zowel beknopter als makkelijker te lezen is. De beste plek om meer te leren over de [`map()`](https://purrr.tidyverse.org/reference/map.html)-functies is het [iteratiehoofdstuk](http://r4ds.had.co.nz/iteration.html) in R for Data Science.\n" ] }, { "cell_type": "code", "metadata": { "id": "Qzb7LyZnimd2" }, "source": [ "set.seed(2056)\n", "\n", "# Create a metric set\n", "eval_metrics <- metric_set(ppv, sens, accuracy, f_meas)\n", "\n", "# Define a function that returns performance metrics\n", "compare_models <- function(workflow_list, train_set, test_set){\n", " \n", " suppressWarnings(\n", " # Fit each model to the train_set\n", " map(workflow_list, fit, data = train_set) %>% \n", " # Make predictions on the test set\n", " map_dfr(augment, new_data = test_set, .id = \"model\") %>%\n", " # Select desired columns\n", " select(model, cuisine, .pred_class) %>% \n", " # Evaluate model performance\n", " group_by(model) %>% \n", " eval_metrics(truth = cuisine, estimate = .pred_class) %>% \n", " ungroup()\n", " )\n", " \n", "} # End of function" ], "execution_count": null, "outputs": [] }, { "cell_type": "markdown", "metadata": { "id": "Fwa712sNisDA" }, "source": [] }, { "cell_type": "code", "metadata": { "id": "3i4VJOi2iu-a" }, "source": [ "# Make a list of workflows\n", "workflow_list <- list(\n", " \"svc\" = svc_linear_wf,\n", " \"svm\" = svm_rbf_wf,\n", " \"knn\" = knn_wf,\n", " \"random_forest\" = rf_wf,\n", " \"xgboost\" = boost_wf)\n", "\n", "# Call the function\n", "set.seed(2056)\n", "perf_metrics <- compare_models(workflow_list = workflow_list, train_set = cuisines_train, test_set = cuisines_test)\n", "\n", "# Print out performance metrics\n", "perf_metrics %>% \n", " group_by(.metric) %>% \n", " arrange(desc(.estimate)) %>% \n", " slice_head(n=7)\n", "\n", "# Compare accuracy\n", "perf_metrics %>% \n", " filter(.metric == \"accuracy\") %>% \n", " arrange(desc(.estimate))\n" ], "execution_count": null, "outputs": [] }, { "cell_type": "markdown", "metadata": { "id": "KuWK_lEli4nW" }, "source": [ "[**workflowset**](https://workflowsets.tidymodels.org/) stelt gebruikers in staat om een groot aantal modellen te maken en eenvoudig te trainen, maar is voornamelijk ontworpen om te werken met hersteekproeftechnieken zoals `cross-validation`, een aanpak die we nog moeten behandelen.\n", "\n", "## **🚀Uitdaging**\n", "\n", "Elk van deze technieken heeft een groot aantal parameters die je kunt aanpassen, zoals `cost` in SVMs, `neighbors` in KNN, `mtry` (willekeurig geselecteerde voorspellers) in Random Forest.\n", "\n", "Onderzoek de standaardparameters van elk model en denk na over wat het aanpassen van deze parameters zou betekenen voor de kwaliteit van het model.\n", "\n", "Om meer te weten te komen over een specifiek model en zijn parameters, gebruik: `help(\"model\")`, bijvoorbeeld `help(\"rand_forest\")`.\n", "\n", "> In de praktijk *schatten* we meestal de *beste waarden* voor deze parameters door veel modellen te trainen op een `gesimuleerd gegevensset` en te meten hoe goed al deze modellen presteren. Dit proces wordt **tuning** genoemd.\n", "\n", "### [**Quiz na de les**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/24/)\n", "\n", "### **Herziening & Zelfstudie**\n", "\n", "Er wordt veel vakjargon gebruikt in deze lessen, dus neem even de tijd om [deze lijst](https://docs.microsoft.com/dotnet/machine-learning/resources/glossary?WT.mc_id=academic-77952-leestott) met nuttige terminologie door te nemen!\n", "\n", "#### DANK AAN:\n", "\n", "[`Allison Horst`](https://twitter.com/allison_horst/) voor het maken van de geweldige illustraties die R toegankelijker en aantrekkelijker maken. Vind meer illustraties in haar [galerij](https://www.google.com/url?q=https://github.com/allisonhorst/stats-illustrations&sa=D&source=editors&ust=1626380772530000&usg=AOvVaw3zcfyCizFQZpkSLzxiiQEM).\n", "\n", "[Cassie Breviu](https://www.twitter.com/cassieview) en [Jen Looper](https://www.twitter.com/jenlooper) voor het maken van de originele Python-versie van deze module ♥️\n", "\n", "Veel leerplezier,\n", "\n", "[Eric](https://twitter.com/ericntay), Gold Microsoft Learn Student Ambassador.\n", "\n", "

\n", " \n", "

Illustratie door @allison_horst
\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n---\n\n**Disclaimer**: \nDit document is vertaald met behulp van de AI-vertalingsservice [Co-op Translator](https://github.com/Azure/co-op-translator). Hoewel we streven naar nauwkeurigheid, willen we u erop wijzen dat geautomatiseerde vertalingen fouten of onnauwkeurigheden kunnen bevatten. Het originele document in de oorspronkelijke taal moet worden beschouwd als de gezaghebbende bron. Voor kritieke informatie wordt professionele menselijke vertaling aanbevolen. Wij zijn niet aansprakelijk voor misverstanden of verkeerde interpretaties die voortvloeien uit het gebruik van deze vertaling.\n" ] } ] }