{ "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-04T08:37:25+00:00", "source_file": "4-Classification/3-Classifiers-2/solution/R/lesson_12-R.ipynb", "language_code": "el" } }, "cells": [ { "cell_type": "markdown", "metadata": { "id": "jsFutf_ygqSx" }, "source": [ "# Δημιουργήστε ένα μοντέλο ταξινόμησης: Νόστιμες Ασιατικές και Ινδικές Κουζίνες\n" ] }, { "cell_type": "markdown", "metadata": { "id": "HD54bEefgtNO" }, "source": [ "## Ταξινομητές κουζίνας 2\n", "\n", "Σε αυτό το δεύτερο μάθημα ταξινόμησης, θα εξερευνήσουμε `περισσότερους τρόπους` για να ταξινομήσουμε κατηγορικά δεδομένα. Θα μάθουμε επίσης τις συνέπειες της επιλογής ενός ταξινομητή αντί για έναν άλλο.\n", "\n", "### [**Κουίζ πριν το μάθημα**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/23/)\n", "\n", "### **Προαπαιτούμενα**\n", "\n", "Υποθέτουμε ότι έχετε ολοκληρώσει τα προηγούμενα μαθήματα, καθώς θα συνεχίσουμε με ορισμένες έννοιες που μάθαμε προηγουμένως.\n", "\n", "Για αυτό το μάθημα, θα χρειαστούμε τα εξής πακέτα:\n", "\n", "- `tidyverse`: Το [tidyverse](https://www.tidyverse.org/) είναι μια [συλλογή πακέτων R](https://www.tidyverse.org/packages) σχεδιασμένη για να κάνει την επιστήμη δεδομένων πιο γρήγορη, εύκολη και διασκεδαστική!\n", "\n", "- `tidymodels`: Το [tidymodels](https://www.tidymodels.org/) είναι ένα [πλαίσιο συλλογής πακέτων](https://www.tidymodels.org/packages/) για μοντελοποίηση και μηχανική μάθηση.\n", "\n", "- `themis`: Το [πακέτο themis](https://themis.tidymodels.org/) παρέχει επιπλέον βήματα συνταγών για την αντιμετώπιση μη ισορροπημένων δεδομένων.\n", "\n", "Μπορείτε να τα εγκαταστήσετε ως εξής:\n", "\n", "`install.packages(c(\"tidyverse\", \"tidymodels\", \"kernlab\", \"themis\", \"ranger\", \"xgboost\", \"kknn\"))`\n", "\n", "Εναλλακτικά, το παρακάτω script ελέγχει αν έχετε τα απαραίτητα πακέτα για την ολοκλήρωση αυτής της ενότητας και τα εγκαθιστά για εσάς σε περίπτωση που λείπουν.\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. Ένας χάρτης ταξινόμησης**\n", "\n", "Στο [προηγούμενο μάθημα](https://github.com/microsoft/ML-For-Beginners/tree/main/4-Classification/2-Classifiers-1), προσπαθήσαμε να απαντήσουμε στο ερώτημα: πώς επιλέγουμε ανάμεσα σε πολλαπλά μοντέλα; Σε μεγάλο βαθμό, αυτό εξαρτάται από τα χαρακτηριστικά των δεδομένων και τον τύπο του προβλήματος που θέλουμε να λύσουμε (για παράδειγμα ταξινόμηση ή παλινδρόμηση).\n", "\n", "Προηγουμένως, μάθαμε για τις διάφορες επιλογές που έχετε όταν ταξινομείτε δεδομένα χρησιμοποιώντας το cheat sheet της Microsoft. Το πλαίσιο Μηχανικής Μάθησης της Python, Scikit-learn, προσφέρει ένα παρόμοιο αλλά πιο λεπτομερές cheat sheet που μπορεί να σας βοηθήσει περαιτέρω να περιορίσετε τους εκτιμητές σας (ένας άλλος όρος για τους ταξινομητές):\n", "\n", "

\n", " \n", "

\n" ] }, { "cell_type": "markdown", "metadata": { "id": "u1i3xRIVg7vG" }, "source": [ "> Συμβουλή: [επισκεφθείτε αυτόν τον χάρτη online](https://scikit-learn.org/stable/tutorial/machine_learning_map/) και κάντε κλικ κατά μήκος της διαδρομής για να διαβάσετε την τεκμηρίωση.\n", ">\n", "> Ο [ιστότοπος αναφοράς Tidymodels](https://www.tidymodels.org/find/parsnip/#models) παρέχει επίσης εξαιρετική τεκμηρίωση για διαφορετικούς τύπους μοντέλων.\n", "\n", "### **Το σχέδιο** 🗺️\n", "\n", "Αυτός ο χάρτης είναι πολύ χρήσιμος μόλις αποκτήσετε μια ξεκάθαρη κατανόηση των δεδομένων σας, καθώς μπορείτε να \"περπατήσετε\" κατά μήκος των διαδρομών του για να φτάσετε σε μια απόφαση:\n", "\n", "- Έχουμε \\>50 δείγματα\n", "\n", "- Θέλουμε να προβλέψουμε μια κατηγορία\n", "\n", "- Έχουμε δεδομένα με ετικέτες\n", "\n", "- Έχουμε λιγότερα από 100.000 δείγματα\n", "\n", "- ✨ Μπορούμε να επιλέξουμε ένα Linear SVC\n", "\n", "- Αν αυτό δεν λειτουργήσει, δεδομένου ότι έχουμε αριθμητικά δεδομένα\n", "\n", " - Μπορούμε να δοκιμάσουμε έναν ✨ KNeighbors Classifier\n", "\n", " - Αν και αυτό δεν λειτουργήσει, δοκιμάστε ✨ SVC και ✨ Ensemble Classifiers\n", "\n", "Αυτή είναι μια πολύ χρήσιμη διαδρομή για να ακολουθήσετε. Τώρα, ας ξεκινήσουμε χρησιμοποιώντας το [tidymodels](https://www.tidymodels.org/) πλαίσιο μοντελοποίησης: μια συνεκτική και ευέλικτη συλλογή πακέτων R που αναπτύχθηκαν για να ενθαρρύνουν την καλή στατιστική πρακτική 😊.\n", "\n", "## 2. Διαχωρισμός των δεδομένων και αντιμετώπιση μη ισορροπημένων συνόλων δεδομένων.\n", "\n", "Από τα προηγούμενα μαθήματα, μάθαμε ότι υπήρχε ένα σύνολο κοινών συστατικών στις κουζίνες μας. Επίσης, υπήρχε μια αρκετά άνιση κατανομή στον αριθμό των κουζινών.\n", "\n", "Θα τα αντιμετωπίσουμε αυτά με τους εξής τρόπους:\n", "\n", "- Αφαιρώντας τα πιο κοινά συστατικά που δημιουργούν σύγχυση μεταξύ διαφορετικών κουζινών, χρησιμοποιώντας `dplyr::select()`.\n", "\n", "- Χρησιμοποιώντας μια `recipe` που προεπεξεργάζεται τα δεδομένα ώστε να είναι έτοιμα για μοντελοποίηση, εφαρμόζοντας έναν αλγόριθμο `over-sampling`.\n", "\n", "Έχουμε ήδη δει τα παραπάνω στο προηγούμενο μάθημα, οπότε αυτό θα είναι παιχνιδάκι 🥳!\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": [ "### Αντιμετώπιση μη ισορροπημένων δεδομένων\n", "\n", "Τα μη ισορροπημένα δεδομένα συχνά έχουν αρνητικές επιπτώσεις στην απόδοση του μοντέλου. Πολλά μοντέλα αποδίδουν καλύτερα όταν ο αριθμός των παρατηρήσεων είναι ίσος και, ως εκ τούτου, δυσκολεύονται με μη ισορροπημένα δεδομένα.\n", "\n", "Υπάρχουν κυρίως δύο τρόποι αντιμετώπισης μη ισορροπημένων συνόλων δεδομένων:\n", "\n", "- προσθήκη παρατηρήσεων στην κατηγορία μειοψηφίας: `Over-sampling`, π.χ. χρησιμοποιώντας έναν αλγόριθμο SMOTE, ο οποίος συνθετικά δημιουργεί νέα παραδείγματα της κατηγορίας μειοψηφίας χρησιμοποιώντας τους πλησιέστερους γείτονες αυτών των περιπτώσεων.\n", "\n", "- αφαίρεση παρατηρήσεων από την κατηγορία πλειοψηφίας: `Under-sampling`\n", "\n", "Στο προηγούμενο μάθημά μας, δείξαμε πώς να αντιμετωπίσουμε μη ισορροπημένα σύνολα δεδομένων χρησιμοποιώντας μια `recipe`. Μια recipe μπορεί να θεωρηθεί ως ένα σχέδιο που περιγράφει ποια βήματα πρέπει να εφαρμοστούν σε ένα σύνολο δεδομένων για να είναι έτοιμο για ανάλυση δεδομένων. Στην περίπτωσή μας, θέλουμε να έχουμε ίση κατανομή στον αριθμό των κουζινών μας για το `training set` μας. Ας ξεκινήσουμε!\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": [ "Τώρα είμαστε έτοιμοι να εκπαιδεύσουμε μοντέλα 👩‍💻👨‍💻!\n", "\n", "## 3. Πέρα από τα μοντέλα πολυωνυμικής παλινδρόμησης\n", "\n", "Στο προηγούμενο μάθημα, εξετάσαμε μοντέλα πολυωνυμικής παλινδρόμησης. Ας εξερευνήσουμε μερικά πιο ευέλικτα μοντέλα για ταξινόμηση.\n", "\n", "### Μηχανές Υποστήριξης Διανυσμάτων (Support Vector Machines)\n", "\n", "Στο πλαίσιο της ταξινόμησης, οι `Μηχανές Υποστήριξης Διανυσμάτων` είναι μια τεχνική μηχανικής μάθησης που προσπαθεί να βρει ένα *υπερεπίπεδο* που \"καλύτερα\" διαχωρίζει τις κατηγορίες. Ας δούμε ένα απλό παράδειγμα:\n", "\n", "

\n", " \n", "

https://commons.wikimedia.org/w/index.php?curid=22877598
\n" ] }, { "cell_type": "markdown", "metadata": { "id": "C4Wsd0vZhXYu" }, "source": [ "H1~ δεν διαχωρίζει τις κλάσεις. H2~ τις διαχωρίζει, αλλά μόνο με μικρό περιθώριο. H3~ τις διαχωρίζει με το μέγιστο περιθώριο.\n", "\n", "#### Γραμμικός Ταξινομητής Υποστηρικτικών Διανυσμάτων\n", "\n", "Η ομαδοποίηση Υποστηρικτικών Διανυσμάτων (SVC) είναι μέλος της οικογένειας τεχνικών μηχανικής μάθησης Υποστηρικτικών Διανυσμάτων. Στο SVC, το υπερεπίπεδο επιλέγεται ώστε να διαχωρίζει σωστά `την πλειοψηφία` των παρατηρήσεων εκπαίδευσης, αλλά `μπορεί να ταξινομήσει λανθασμένα` κάποιες παρατηρήσεις. Επιτρέποντας σε ορισμένα σημεία να βρίσκονται στη λάθος πλευρά, το SVM γίνεται πιο ανθεκτικό σε ακραίες τιμές και συνεπώς καλύτερο στη γενίκευση σε νέα δεδομένα. Η παράμετρος που ρυθμίζει αυτή την παραβίαση αναφέρεται ως `cost`, η οποία έχει προεπιλεγμένη τιμή 1 (δείτε `help(\"svm_poly\")`).\n", "\n", "Ας δημιουργήσουμε έναν γραμμικό SVC ορίζοντας `degree = 1` σε ένα πολυωνυμικό μοντέλο SVM.\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": [ "Τώρα που έχουμε καταγράψει τα βήματα προεπεξεργασίας και την προδιαγραφή του μοντέλου σε μια *ροή εργασίας*, μπορούμε να προχωρήσουμε στην εκπαίδευση του γραμμικού SVC και να αξιολογήσουμε τα αποτελέσματα ταυτόχρονα. Για τις μετρικές απόδοσης, ας δημιουργήσουμε ένα σύνολο μετρικών που θα αξιολογεί: `accuracy`, `sensitivity`, `Positive Predicted Value` και `F Measure`.\n", "\n", "> Το `augment()` θα προσθέσει στήλη(-ες) για προβλέψεις στα δεδομένα που δίνονται.\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": [ "#### Υποστήριξη Διανυσματικής Μηχανής\n", "\n", "Η υποστήριξη διανυσματικής μηχανής (SVM) είναι μια επέκταση του υποστηρικτικού διανυσματικού ταξινομητή, ώστε να μπορεί να διαχειριστεί ένα μη γραμμικό όριο μεταξύ των κατηγοριών. Στην ουσία, οι SVMs χρησιμοποιούν το *kernel trick* για να διευρύνουν τον χώρο χαρακτηριστικών, προσαρμοζόμενοι σε μη γραμμικές σχέσεις μεταξύ των κατηγοριών. Μία δημοφιλής και εξαιρετικά ευέλικτη συνάρτηση πυρήνα που χρησιμοποιείται από τους SVMs είναι η *Radial basis function.* Ας δούμε πώς θα αποδώσει στα δεδομένα μας.\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": [ "Πολύ καλύτερα 🤩!\n", "\n", "> ✅ Παρακαλώ δείτε:\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", "> για περαιτέρω ανάγνωση.\n", "\n", "### Ταξινομητές Πλησιέστερου Γείτονα\n", "\n", "Το *K*-nearest neighbor (KNN) είναι ένας αλγόριθμος στον οποίο κάθε παρατήρηση προβλέπεται με βάση την *ομοιότητά* της με άλλες παρατηρήσεις.\n", "\n", "Ας εφαρμόσουμε έναν στο σύνολο δεδομένων μας.\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": [ "Φαίνεται ότι αυτό το μοντέλο δεν αποδίδει τόσο καλά. Πιθανότατα η αλλαγή των παραμέτρων του μοντέλου (δείτε `help(\"nearest_neighbor\")`) θα βελτιώσει την απόδοση του μοντέλου. Φροντίστε να το δοκιμάσετε.\n", "\n", "> ✅ Παρακαλώ δείτε:\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", "> για να μάθετε περισσότερα σχετικά με τους ταξινομητές *K*-Nearest Neighbors.\n", "\n", "### Ταξινομητές Ensemble\n", "\n", "Οι αλγόριθμοι Ensemble λειτουργούν συνδυάζοντας πολλούς βασικούς εκτιμητές για να παράγουν ένα βέλτιστο μοντέλο είτε μέσω:\n", "\n", "`bagging`: εφαρμογή μιας *συνάρτησης μέσου όρου* σε μια συλλογή βασικών μοντέλων\n", "\n", "`boosting`: δημιουργία μιας ακολουθίας μοντέλων που βασίζονται το ένα στο άλλο για να βελτιώσουν την προβλεπτική απόδοση.\n", "\n", "Ας ξεκινήσουμε δοκιμάζοντας ένα μοντέλο Random Forest, το οποίο δημιουργεί μια μεγάλη συλλογή δέντρων αποφάσεων και στη συνέχεια εφαρμόζει μια συνάρτηση μέσου όρου για ένα καλύτερο συνολικό μοντέλο.\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": [ "Μπράβο 👏!\n", "\n", "Ας πειραματιστούμε επίσης με ένα μοντέλο Boosted Tree.\n", "\n", "Το Boosted Tree ορίζει μια μέθοδο συνόλου που δημιουργεί μια σειρά από διαδοχικά δέντρα αποφάσεων, όπου κάθε δέντρο εξαρτάται από τα αποτελέσματα των προηγούμενων δέντρων, σε μια προσπάθεια να μειώσει σταδιακά το σφάλμα. Εστιάζει στα βάρη των αντικειμένων που ταξινομήθηκαν λανθασμένα και προσαρμόζει την εφαρμογή για τον επόμενο ταξινομητή ώστε να διορθώσει.\n", "\n", "Υπάρχουν διαφορετικοί τρόποι για να προσαρμόσετε αυτό το μοντέλο (δείτε `help(\"boost_tree\")`). Σε αυτό το παράδειγμα, θα προσαρμόσουμε τα Boosted trees μέσω της μηχανής `xgboost`.\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": [ "> ✅ Παρακαλώ δείτε:\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", "> - - Εξετάζει το μοντέλο AdaBoost, το οποίο αποτελεί μια καλή εναλλακτική στο xgboost.\n", ">\n", "> για να μάθετε περισσότερα σχετικά με τους Ensemble classifiers.\n", "\n", "## 4. Επιπλέον - σύγκριση πολλαπλών μοντέλων\n", "\n", "Έχουμε εφαρμόσει αρκετά μοντέλα σε αυτό το εργαστήριο 🙌. Μπορεί να γίνει κουραστικό ή δύσκολο να δημιουργήσουμε πολλούς workflows από διαφορετικά σύνολα προεπεξεργαστών και/ή προδιαγραφές μοντέλων και στη συνέχεια να υπολογίσουμε τις μετρικές απόδοσης μία προς μία.\n", "\n", "Ας δούμε αν μπορούμε να αντιμετωπίσουμε αυτό το ζήτημα δημιουργώντας μια συνάρτηση που εφαρμόζει μια λίστα από workflows στο εκπαιδευτικό σύνολο και στη συνέχεια επιστρέφει τις μετρικές απόδοσης βάσει του συνόλου δοκιμών. Θα χρησιμοποιήσουμε τις `map()` και `map_dfr()` από το πακέτο [purrr](https://purrr.tidyverse.org/) για να εφαρμόσουμε συναρτήσεις σε κάθε στοιχείο της λίστας.\n", "\n", "> Οι συναρτήσεις [`map()`](https://purrr.tidyverse.org/reference/map.html) σας επιτρέπουν να αντικαταστήσετε πολλούς βρόχους for με κώδικα που είναι πιο συνοπτικός και ευκολότερος στην ανάγνωση. Το καλύτερο μέρος για να μάθετε σχετικά με τις συναρτήσεις [`map()`](https://purrr.tidyverse.org/reference/map.html) είναι το [κεφάλαιο για την επανάληψη](http://r4ds.had.co.nz/iteration.html) στο 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/) επιτρέπει στους χρήστες να δημιουργούν και να εφαρμόζουν εύκολα έναν μεγάλο αριθμό μοντέλων, αλλά έχει σχεδιαστεί κυρίως για να λειτουργεί με τεχνικές επαναδειγματοληψίας όπως η `διασταυρούμενη επικύρωση`, μια προσέγγιση που δεν έχουμε καλύψει ακόμα.\n", "\n", "## **🚀Πρόκληση**\n", "\n", "Καθεμία από αυτές τις τεχνικές έχει έναν μεγάλο αριθμό παραμέτρων που μπορείτε να προσαρμόσετε, όπως για παράδειγμα το `cost` στα SVMs, το `neighbors` στο KNN, το `mtry` (Τυχαία Επιλεγμένοι Προγνωστικοί Παράγοντες) στο Random Forest.\n", "\n", "Ερευνήστε τις προεπιλεγμένες παραμέτρους του καθενός και σκεφτείτε τι θα σήμαινε η προσαρμογή αυτών των παραμέτρων για την ποιότητα του μοντέλου.\n", "\n", "Για να μάθετε περισσότερα σχετικά με ένα συγκεκριμένο μοντέλο και τις παραμέτρους του, χρησιμοποιήστε: `help(\"model\")`, π.χ. `help(\"rand_forest\")`.\n", "\n", "> Στην πράξη, συνήθως *εκτιμούμε* τις *καλύτερες τιμές* αυτών των παραμέτρων εκπαιδεύοντας πολλά μοντέλα σε ένα `προσομοιωμένο σύνολο δεδομένων` και μετρώντας πόσο καλά αποδίδουν όλα αυτά τα μοντέλα. Αυτή η διαδικασία ονομάζεται **βελτιστοποίηση**.\n", "\n", "### [**Κουίζ μετά το μάθημα**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/24/)\n", "\n", "### **Ανασκόπηση & Αυτομελέτη**\n", "\n", "Υπάρχει αρκετή ορολογία σε αυτά τα μαθήματα, οπότε αφιερώστε λίγο χρόνο για να αναθεωρήσετε [αυτήν τη λίστα](https://docs.microsoft.com/dotnet/machine-learning/resources/glossary?WT.mc_id=academic-77952-leestott) χρήσιμων όρων!\n", "\n", "#### ΕΥΧΑΡΙΣΤΟΥΜΕ:\n", "\n", "[`Allison Horst`](https://twitter.com/allison_horst/) για τη δημιουργία των καταπληκτικών εικονογραφήσεων που κάνουν τη R πιο φιλόξενη και ενδιαφέρουσα. Βρείτε περισσότερες εικονογραφήσεις στη [συλλογή της](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) και [Jen Looper](https://www.twitter.com/jenlooper) για τη δημιουργία της αρχικής έκδοσης αυτού του module σε Python ♥️\n", "\n", "Καλή Μάθηση,\n", "\n", "[Eric](https://twitter.com/ericntay), Gold Microsoft Learn Student Ambassador.\n", "\n", "

\n", " \n", "

Artwork by @allison_horst
\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n---\n\n**Αποποίηση Ευθύνης**: \nΑυτό το έγγραφο έχει μεταφραστεί χρησιμοποιώντας την υπηρεσία αυτόματης μετάφρασης [Co-op Translator](https://github.com/Azure/co-op-translator). Παρόλο που καταβάλλουμε προσπάθειες για ακρίβεια, παρακαλούμε να έχετε υπόψη ότι οι αυτόματες μεταφράσεις ενδέχεται να περιέχουν σφάλματα ή ανακρίβειες. Το πρωτότυπο έγγραφο στη μητρική του γλώσσα θα πρέπει να θεωρείται η αυθεντική πηγή. Για κρίσιμες πληροφορίες, συνιστάται επαγγελματική ανθρώπινη μετάφραση. Δεν φέρουμε ευθύνη για τυχόν παρεξηγήσεις ή εσφαλμένες ερμηνείες που προκύπτουν από τη χρήση αυτής της μετάφρασης.\n" ] } ] }