{ "nbformat": 4, "nbformat_minor": 2, "metadata": { "colab": { "name": "lesson_3-R.ipynb", "provenance": [], "collapsed_sections": [], "toc_visible": true }, "kernelspec": { "name": "ir", "display_name": "R" }, "language_info": { "name": "R" }, "coopTranslator": { "original_hash": "5015d65d61ba75a223bfc56c273aa174", "translation_date": "2025-09-04T06:30:20+00:00", "source_file": "2-Regression/3-Linear/solution/R/lesson_3-R.ipynb", "language_code": "el" } }, "cells": [ { "cell_type": "markdown", "source": [], "metadata": { "id": "EgQw8osnsUV-" } }, { "cell_type": "markdown", "source": [ "## Γραμμική και Πολυωνυμική Παλινδρόμηση για Τιμολόγηση Κολοκύθας - Μάθημα 3\n", "

\n", " \n", "

Γραφικό από τον Dasani Madipalli
\n", "\n", "\n", "#### Εισαγωγή\n", "\n", "Μέχρι στιγμής έχετε εξερευνήσει τι είναι η παλινδρόμηση με δείγματα δεδομένων που συλλέχθηκαν από το σύνολο δεδομένων τιμολόγησης κολοκύθας που θα χρησιμοποιήσουμε σε όλο το μάθημα. Έχετε επίσης οπτικοποιήσει τα δεδομένα χρησιμοποιώντας `ggplot2`.💪\n", "\n", "Τώρα είστε έτοιμοι να εμβαθύνετε περισσότερο στην παλινδρόμηση για τη Μηχανική Μάθηση. Σε αυτό το μάθημα, θα μάθετε περισσότερα για δύο τύπους παλινδρόμησης: *βασική γραμμική παλινδρόμηση* και *πολυωνυμική παλινδρόμηση*, μαζί με λίγα μαθηματικά που υποστηρίζουν αυτές τις τεχνικές.\n", "\n", "> Σε όλη αυτή την εκπαιδευτική ύλη, υποθέτουμε ελάχιστες γνώσεις μαθηματικών και προσπαθούμε να την κάνουμε προσιτή για μαθητές που προέρχονται από άλλους τομείς, γι' αυτό προσέξτε σημειώσεις, 🧮 επισημάνσεις, διαγράμματα και άλλα εργαλεία μάθησης για να βοηθήσουν στην κατανόηση.\n", "\n", "#### Προετοιμασία\n", "\n", "Ως υπενθύμιση, φορτώνετε αυτά τα δεδομένα για να θέσετε ερωτήματα σχετικά με αυτά.\n", "\n", "- Ποια είναι η καλύτερη στιγμή για να αγοράσετε κολοκύθες;\n", "\n", "- Τι τιμή μπορώ να περιμένω για μια θήκη με μίνι κολοκύθες;\n", "\n", "- Να τις αγοράσω σε καλάθια μισού μπούσελ ή σε κουτί 1 1/9 μπούσελ; Ας συνεχίσουμε να εξετάζουμε αυτά τα δεδομένα.\n", "\n", "Στο προηγούμενο μάθημα, δημιουργήσατε ένα `tibble` (μια σύγχρονη επανεξέταση του πλαισίου δεδομένων) και το γεμίσατε με μέρος του αρχικού συνόλου δεδομένων, τυποποιώντας την τιμολόγηση ανά μπούσελ. Με αυτόν τον τρόπο, ωστόσο, καταφέρατε να συλλέξετε μόνο περίπου 400 σημεία δεδομένων και μόνο για τους φθινοπωρινούς μήνες. Ίσως μπορέσουμε να πάρουμε λίγο περισσότερες λεπτομέρειες για τη φύση των δεδομένων καθαρίζοντάς τα περισσότερο; Θα δούμε... 🕵️‍♀️\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", "- `janitor`: Το [πακέτο janitor](https://github.com/sfirke/janitor) παρέχει απλά εργαλεία για την εξέταση και τον καθαρισμό \"βρώμικων\" δεδομένων.\n", "\n", "- `corrplot`: Το [πακέτο corrplot](https://cran.r-project.org/web/packages/corrplot/vignettes/corrplot-intro.html) παρέχει ένα οπτικό εργαλείο εξερεύνησης για πίνακες συσχέτισης που υποστηρίζει αυτόματη αναδιάταξη μεταβλητών για να βοηθήσει στην ανίχνευση κρυφών μοτίβων μεταξύ μεταβλητών.\n", "\n", "Μπορείτε να τα εγκαταστήσετε ως εξής:\n", "\n", "`install.packages(c(\"tidyverse\", \"tidymodels\", \"janitor\", \"corrplot\"))`\n", "\n", "Το παρακάτω σενάριο ελέγχει αν έχετε τα πακέτα που απαιτούνται για την ολοκλήρωση αυτής της ενότητας και τα εγκαθιστά για εσάς σε περίπτωση που λείπουν.\n" ], "metadata": { "id": "WqQPS1OAsg3H" } }, { "cell_type": "code", "execution_count": null, "source": [ "suppressWarnings(if (!require(\"pacman\")) install.packages(\"pacman\"))\n", "\n", "pacman::p_load(tidyverse, tidymodels, janitor, corrplot)" ], "outputs": [], "metadata": { "id": "tA4C2WN3skCf", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "c06cd805-5534-4edc-f72b-d0d1dab96ac0" } }, { "cell_type": "markdown", "source": [ "Θα φορτώσουμε αργότερα αυτά τα καταπληκτικά πακέτα και θα τα κάνουμε διαθέσιμα στην τρέχουσα συνεδρία R. (Αυτό είναι απλώς για επίδειξη, το `pacman::p_load()` το έχει ήδη κάνει για εσάς)\n", "\n", "## 1. Μια γραμμή γραμμικής παλινδρόμησης\n", "\n", "Όπως μάθατε στο Μάθημα 1, ο στόχος μιας άσκησης γραμμικής παλινδρόμησης είναι να μπορέσουμε να σχεδιάσουμε μια *γραμμή* *καλύτερης προσαρμογής* για να:\n", "\n", "- **Δείξουμε τις σχέσεις μεταβλητών**. Δείξτε τη σχέση μεταξύ των μεταβλητών.\n", "\n", "- **Κάνουμε προβλέψεις**. Κάνουμε ακριβείς προβλέψεις για το πού θα βρεθεί ένα νέο σημείο δεδομένων σε σχέση με αυτή τη γραμμή.\n", "\n", "Για να σχεδιάσουμε αυτόν τον τύπο γραμμής, χρησιμοποιούμε μια στατιστική τεχνική που ονομάζεται **Παλινδρόμηση Ελαχίστων Τετραγώνων**. Ο όρος `ελάχιστα τετράγωνα` σημαίνει ότι όλα τα σημεία δεδομένων γύρω από τη γραμμή παλινδρόμησης υψώνονται στο τετράγωνο και στη συνέχεια προστίθενται. Ιδανικά, αυτό το τελικό άθροισμα είναι όσο το δυνατόν μικρότερο, επειδή θέλουμε έναν χαμηλό αριθμό σφαλμάτων ή `ελάχιστα τετράγωνα`. Έτσι, η γραμμή καλύτερης προσαρμογής είναι η γραμμή που μας δίνει τη χαμηλότερη τιμή για το άθροισμα των τετραγωνικών σφαλμάτων - εξ ου και το όνομα *παλινδρόμηση ελαχίστων τετραγώνων*.\n", "\n", "Το κάνουμε αυτό επειδή θέλουμε να μοντελοποιήσουμε μια γραμμή που έχει τη μικρότερη σωρευτική απόσταση από όλα τα σημεία δεδομένων μας. Επίσης, υψώνουμε τους όρους στο τετράγωνο πριν τους προσθέσουμε, καθώς μας ενδιαφέρει το μέγεθός τους και όχι η κατεύθυνσή τους.\n", "\n", "> **🧮 Δείξε μου τα μαθηματικά**\n", ">\n", "> Αυτή η γραμμή, που ονομάζεται *γραμμή καλύτερης προσαρμογής*, μπορεί να εκφραστεί με [μια εξίσωση](https://en.wikipedia.org/wiki/Simple_linear_regression):\n", ">\n", "> Y = a + bX\n", ">\n", "> Το `X` είναι η '`επεξηγηματική μεταβλητή` ή `προβλεπτική`'. Το `Y` είναι η '`εξαρτημένη μεταβλητή` ή `αποτέλεσμα`'. Η κλίση της γραμμής είναι `b` και το `a` είναι η τεταγμένη στην αρχή, που αναφέρεται στην τιμή του `Y` όταν `X = 0`.\n", ">\n", "\n", "> ![](../../../../../../2-Regression/3-Linear/solution/images/slope.png \"κλίση = $y/x$\")\n", " Γραφικό από την Jen Looper\n", ">\n", "> Πρώτα, υπολογίστε την κλίση `b`.\n", ">\n", "> Με άλλα λόγια, και αναφερόμενοι στην αρχική ερώτηση για τα δεδομένα κολοκύθας: \"προβλέψτε την τιμή μιας κολοκύθας ανά μπούσελ ανά μήνα\", το `X` θα αναφέρεται στην τιμή και το `Y` θα αναφέρεται στον μήνα πώλησης.\n", ">\n", "> ![](../../../../../../2-Regression/3-Linear/solution/images/calculation.png)\n", " Γραφικό από την Jen Looper\n", "> \n", "> Υπολογίστε την τιμή του Y. Αν πληρώνετε περίπου \\$4, πρέπει να είναι Απρίλιος!\n", ">\n", "> Τα μαθηματικά που υπολογίζουν τη γραμμή πρέπει να δείξουν την κλίση της γραμμής, η οποία εξαρτάται επίσης από την τεταγμένη στην αρχή, ή πού βρίσκεται το `Y` όταν `X = 0`.\n", ">\n", "> Μπορείτε να παρατηρήσετε τη μέθοδο υπολογισμού αυτών των τιμών στον ιστότοπο [Math is Fun](https://www.mathsisfun.com/data/least-squares-regression.html). Επισκεφθείτε επίσης [αυτόν τον υπολογιστή ελαχίστων τετραγώνων](https://www.mathsisfun.com/data/least-squares-calculator.html) για να δείτε πώς οι τιμές των αριθμών επηρεάζουν τη γραμμή.\n", "\n", "Όχι και τόσο τρομακτικό, σωστά; 🤓\n", "\n", "#### Συσχέτιση\n", "\n", "Ένας ακόμη όρος που πρέπει να κατανοήσετε είναι ο **Συντελεστής Συσχέτισης** μεταξύ των δεδομένων X και Y. Χρησιμοποιώντας ένα διάγραμμα διασποράς, μπορείτε γρήγορα να οπτικοποιήσετε αυτόν τον συντελεστή. Ένα διάγραμμα με σημεία δεδομένων που είναι διασκορπισμένα σε μια τακτική γραμμή έχει υψηλή συσχέτιση, ενώ ένα διάγραμμα με σημεία δεδομένων που είναι διασκορπισμένα παντού μεταξύ X και Y έχει χαμηλή συσχέτιση.\n", "\n", "Ένα καλό μοντέλο γραμμικής παλινδρόμησης θα είναι αυτό που έχει υψηλό (πιο κοντά στο 1 παρά στο 0) Συντελεστή Συσχέτισης χρησιμοποιώντας τη μέθοδο Παλινδρόμησης Ελαχίστων Τετραγώνων με μια γραμμή παλινδρόμησης.\n" ], "metadata": { "id": "cdX5FRpvsoP5" } }, { "cell_type": "markdown", "source": [ "## **2. Ένας χορός με δεδομένα: δημιουργία ενός data frame που θα χρησιμοποιηθεί για μοντελοποίηση**\n", "\n", "

\n", " \n", "

Έργο τέχνης από @allison_horst
\n", "\n", "\n", "\n" ], "metadata": { "id": "WdUKXk7Bs8-V" } }, { "cell_type": "markdown", "source": [ "Φορτώστε τις απαραίτητες βιβλιοθήκες και το σύνολο δεδομένων. Μετατρέψτε τα δεδομένα σε ένα πλαίσιο δεδομένων που περιέχει ένα υποσύνολο των δεδομένων:\n", "\n", "- Επιλέξτε μόνο κολοκύθες που τιμολογούνται ανά καλάθι\n", "\n", "- Μετατρέψτε την ημερομηνία σε μήνα\n", "\n", "- Υπολογίστε την τιμή ως μέσο όρο των υψηλών και χαμηλών τιμών\n", "\n", "- Μετατρέψτε την τιμή ώστε να αντικατοπτρίζει την τιμολόγηση ανά ποσότητα καλαθιού\n", "\n", "> Καλύψαμε αυτά τα βήματα στο [προηγούμενο μάθημα](https://github.com/microsoft/ML-For-Beginners/blob/main/2-Regression/2-Data/solution/lesson_2-R.ipynb).\n" ], "metadata": { "id": "fMCtu2G2s-p8" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Load the core Tidyverse packages\n", "library(tidyverse)\n", "library(lubridate)\n", "\n", "# Import the pumpkins data\n", "pumpkins <- read_csv(file = \"https://raw.githubusercontent.com/microsoft/ML-For-Beginners/main/2-Regression/data/US-pumpkins.csv\")\n", "\n", "\n", "# Get a glimpse and dimensions of the data\n", "glimpse(pumpkins)\n", "\n", "\n", "# Print the first 50 rows of the data set\n", "pumpkins %>% \n", " slice_head(n = 5)" ], "outputs": [], "metadata": { "id": "ryMVZEEPtERn" } }, { "cell_type": "markdown", "source": [ "Στο πνεύμα της καθαρής περιπέτειας, ας εξερευνήσουμε το [`πακέτο janitor`](../../../../../../2-Regression/3-Linear/solution/R/github.com/sfirke/janitor) που παρέχει απλές συναρτήσεις για την εξέταση και τον καθαρισμό ακατάστατων δεδομένων. Για παράδειγμα, ας ρίξουμε μια ματιά στα ονόματα των στηλών για τα δεδομένα μας:\n" ], "metadata": { "id": "xcNxM70EtJjb" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Return column names\n", "pumpkins %>% \n", " names()" ], "outputs": [], "metadata": { "id": "5XtpaIigtPfW" } }, { "cell_type": "markdown", "source": [ "🤔 Μπορούμε να τα καταφέρουμε καλύτερα. Ας κάνουμε αυτά τα ονόματα στηλών `friendR` μετατρέποντάς τα στη σύμβαση [snake_case](https://en.wikipedia.org/wiki/Snake_case) χρησιμοποιώντας `janitor::clean_names`. Για να μάθετε περισσότερα σχετικά με αυτήν τη συνάρτηση: `?clean_names`\n" ], "metadata": { "id": "IbIqrMINtSHe" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Clean names to the snake_case convention\n", "pumpkins <- pumpkins %>% \n", " clean_names(case = \"snake\")\n", "\n", "# Return column names\n", "pumpkins %>% \n", " names()" ], "outputs": [], "metadata": { "id": "a2uYvclYtWvX" } }, { "cell_type": "markdown", "source": [ "Πολύ tidyR 🧹! Τώρα, ένας χορός με τα δεδομένα χρησιμοποιώντας το `dplyr`, όπως στο προηγούμενο μάθημα! 💃\n" ], "metadata": { "id": "HfhnuzDDtaDd" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Select desired columns\n", "pumpkins <- pumpkins %>% \n", " select(variety, city_name, package, low_price, high_price, date)\n", "\n", "\n", "\n", "# Extract the month from the dates to a new column\n", "pumpkins <- pumpkins %>%\n", " mutate(date = mdy(date),\n", " month = month(date)) %>% \n", " select(-date)\n", "\n", "\n", "\n", "# Create a new column for average Price\n", "pumpkins <- pumpkins %>% \n", " mutate(price = (low_price + high_price)/2)\n", "\n", "\n", "# Retain only pumpkins with the string \"bushel\"\n", "new_pumpkins <- pumpkins %>% \n", " filter(str_detect(string = package, pattern = \"bushel\"))\n", "\n", "\n", "# Normalize the pricing so that you show the pricing per bushel, not per 1 1/9 or 1/2 bushel\n", "new_pumpkins <- new_pumpkins %>% \n", " mutate(price = case_when(\n", " str_detect(package, \"1 1/9\") ~ price/(1.1),\n", " str_detect(package, \"1/2\") ~ price*2,\n", " TRUE ~ price))\n", "\n", "# Relocate column positions\n", "new_pumpkins <- new_pumpkins %>% \n", " relocate(month, .before = variety)\n", "\n", "\n", "# Display the first 5 rows\n", "new_pumpkins %>% \n", " slice_head(n = 5)" ], "outputs": [], "metadata": { "id": "X0wU3gQvtd9f" } }, { "cell_type": "markdown", "source": [ "Μπράβο!👌 Τώρα έχεις ένα καθαρό, τακτοποιημένο σύνολο δεδομένων πάνω στο οποίο μπορείς να χτίσεις το νέο σου μοντέλο παλινδρόμησης!\n", "\n", "Τι θα έλεγες για ένα διάγραμμα διασποράς;\n" ], "metadata": { "id": "UpaIwaxqth82" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Set theme\n", "theme_set(theme_light())\n", "\n", "# Make a scatter plot of month and price\n", "new_pumpkins %>% \n", " ggplot(mapping = aes(x = month, y = price)) +\n", " geom_point(size = 1.6)\n" ], "outputs": [], "metadata": { "id": "DXgU-j37tl5K" } }, { "cell_type": "markdown", "source": [ "Ένα διάγραμμα διασποράς μας υπενθυμίζει ότι έχουμε δεδομένα μόνο από τον Αύγουστο έως τον Δεκέμβριο. Πιθανότατα χρειαζόμαστε περισσότερα δεδομένα για να μπορέσουμε να βγάλουμε συμπεράσματα με γραμμικό τρόπο.\n", "\n", "Ας ρίξουμε μια ματιά ξανά στα δεδομένα μοντελοποίησής μας:\n" ], "metadata": { "id": "Ve64wVbwtobI" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Display first 5 rows\n", "new_pumpkins %>% \n", " slice_head(n = 5)" ], "outputs": [], "metadata": { "id": "HFQX2ng1tuSJ" } }, { "cell_type": "markdown", "source": [ "Τι θα γινόταν αν θέλαμε να προβλέψουμε την `τιμή` μιας κολοκύθας με βάση τις στήλες `πόλη` ή `πακέτο`, οι οποίες είναι τύπου χαρακτήρα; Ή ακόμα πιο απλά, πώς θα μπορούσαμε να βρούμε τη συσχέτιση (η οποία απαιτεί και οι δύο είσοδοι να είναι αριθμητικές) μεταξύ, για παράδειγμα, του `πακέτου` και της `τιμής`; 🤷🤷\n", "\n", "Τα μοντέλα μηχανικής μάθησης λειτουργούν καλύτερα με αριθμητικά χαρακτηριστικά παρά με κειμενικές τιμές, οπότε συνήθως χρειάζεται να μετατρέψετε τα κατηγορικά χαρακτηριστικά σε αριθμητικές αναπαραστάσεις.\n", "\n", "Αυτό σημαίνει ότι πρέπει να βρούμε έναν τρόπο να αναμορφώσουμε τους προβλεπτικούς μας παράγοντες ώστε να είναι πιο εύχρηστοι για ένα μοντέλο, μια διαδικασία που είναι γνωστή ως `μηχανική χαρακτηριστικών`.\n" ], "metadata": { "id": "7hsHoxsStyjJ" } }, { "cell_type": "markdown", "source": [ "## 3. Προεπεξεργασία δεδομένων για μοντελοποίηση με recipes 👩‍🍳👨‍🍳\n", "\n", "Οι δραστηριότητες που αναδιαμορφώνουν τις τιμές των προβλεπτικών μεταβλητών ώστε να γίνουν πιο εύχρηστες για ένα μοντέλο ονομάζονται `μηχανική χαρακτηριστικών` (feature engineering).\n", "\n", "Διαφορετικά μοντέλα έχουν διαφορετικές απαιτήσεις προεπεξεργασίας. Για παράδειγμα, η μέθοδος ελαχίστων τετραγώνων απαιτεί `κωδικοποίηση κατηγορικών μεταβλητών`, όπως ο μήνας, η ποικιλία και το όνομα της πόλης. Αυτό περιλαμβάνει απλώς τη `μετατροπή` μιας στήλης με `κατηγορικές τιμές` σε μία ή περισσότερες `αριθμητικές στήλες` που αντικαθιστούν την αρχική.\n", "\n", "Για παράδειγμα, ας υποθέσουμε ότι τα δεδομένα σας περιλαμβάνουν το εξής κατηγορικό χαρακτηριστικό:\n", "\n", "| πόλη |\n", "|:-------:|\n", "| Ντένβερ |\n", "| Ναϊρόμπι |\n", "| Τόκιο |\n", "\n", "Μπορείτε να εφαρμόσετε *ordinal encoding* για να αντικαταστήσετε κάθε κατηγορία με μια μοναδική ακέραια τιμή, όπως αυτό:\n", "\n", "| πόλη |\n", "|:----:|\n", "| 0 |\n", "| 1 |\n", "| 2 |\n", "\n", "Και αυτό ακριβώς θα κάνουμε στα δεδομένα μας!\n", "\n", "Σε αυτή την ενότητα, θα εξερευνήσουμε ένα ακόμη καταπληκτικό πακέτο του Tidymodels: [recipes](https://tidymodels.github.io/recipes/) - το οποίο έχει σχεδιαστεί για να σας βοηθήσει να προεπεξεργαστείτε τα δεδομένα σας **πριν** εκπαιδεύσετε το μοντέλο σας. Στον πυρήνα του, ένα recipe είναι ένα αντικείμενο που ορίζει ποια βήματα πρέπει να εφαρμοστούν σε ένα σύνολο δεδομένων ώστε να είναι έτοιμο για μοντελοποίηση.\n", "\n", "Τώρα, ας δημιουργήσουμε ένα recipe που προετοιμάζει τα δεδομένα μας για μοντελοποίηση, αντικαθιστώντας κάθε παρατήρηση στις στήλες των προβλεπτικών μεταβλητών με μια μοναδική ακέραια τιμή:\n" ], "metadata": { "id": "AD5kQbcvt3Xl" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Specify a recipe\n", "pumpkins_recipe <- recipe(price ~ ., data = new_pumpkins) %>% \n", " step_integer(all_predictors(), zero_based = TRUE)\n", "\n", "\n", "# Print out the recipe\n", "pumpkins_recipe" ], "outputs": [], "metadata": { "id": "BNaFKXfRt9TU" } }, { "cell_type": "markdown", "source": [ "Υπέροχα! 👏 Μόλις δημιουργήσαμε την πρώτη μας συνταγή που καθορίζει ένα αποτέλεσμα (τιμή) και τους αντίστοιχους προβλεπτικούς παράγοντες, και που όλες οι στήλες των προβλεπτικών παραγόντων πρέπει να κωδικοποιηθούν σε ένα σύνολο ακεραίων 🙌! Ας το αναλύσουμε γρήγορα:\n", "\n", "- Η κλήση της `recipe()` με μια φόρμουλα ενημερώνει τη συνταγή για τους *ρόλους* των μεταβλητών χρησιμοποιώντας τα δεδομένα `new_pumpkins` ως αναφορά. Για παράδειγμα, η στήλη `price` έχει ανατεθεί ως ρόλος `outcome`, ενώ οι υπόλοιπες στήλες έχουν ανατεθεί ως ρόλος `predictor`.\n", "\n", "- Η `step_integer(all_predictors(), zero_based = TRUE)` καθορίζει ότι όλοι οι προβλεπτικοί παράγοντες πρέπει να μετατραπούν σε ένα σύνολο ακεραίων, με την αρίθμηση να ξεκινά από το 0.\n", "\n", "Είμαστε σίγουροι ότι ίσως σκέφτεστε: \"Αυτό είναι τόσο φοβερό!! Αλλά τι γίνεται αν χρειαστεί να επιβεβαιώσω ότι οι συνταγές κάνουν ακριβώς αυτό που περιμένω; 🤔\"\n", "\n", "Αυτή είναι μια εξαιρετική σκέψη! Βλέπετε, μόλις ορίσετε τη συνταγή σας, μπορείτε να εκτιμήσετε τις παραμέτρους που απαιτούνται για την προεπεξεργασία των δεδομένων και στη συνέχεια να εξαγάγετε τα επεξεργασμένα δεδομένα. Συνήθως δεν χρειάζεται να το κάνετε αυτό όταν χρησιμοποιείτε το Tidymodels (θα δούμε τη συνηθισμένη πρακτική σε λίγο -> `workflows`), αλλά μπορεί να είναι χρήσιμο όταν θέλετε να κάνετε έναν έλεγχο για να επιβεβαιώσετε ότι οι συνταγές λειτουργούν όπως περιμένετε.\n", "\n", "Για αυτό, θα χρειαστείτε δύο ακόμη εντολές: `prep()` και `bake()`, και όπως πάντα, οι μικροί μας φίλοι από το R από την [`Allison Horst`](https://github.com/allisonhorst/stats-illustrations) θα σας βοηθήσουν να το κατανοήσετε καλύτερα!\n", "\n", "

\n", " \n", "

Έργο τέχνης από την @allison_horst
\n", "\n", "\n", "\n" ], "metadata": { "id": "KEiO0v7kuC9O" } }, { "cell_type": "markdown", "source": [ "[`prep()`](https://recipes.tidymodels.org/reference/prep.html): εκτιμά τις απαραίτητες παραμέτρους από ένα σύνολο εκπαίδευσης που μπορούν αργότερα να εφαρμοστούν σε άλλα σύνολα δεδομένων. Για παράδειγμα, για μια δεδομένη στήλη προβλεπτικού παράγοντα, ποια παρατήρηση θα αντιστοιχιστεί στον ακέραιο 0 ή 1 ή 2 κ.λπ.\n", "\n", "[`bake()`](https://recipes.tidymodels.org/reference/bake.html): παίρνει μια προετοιμασμένη συνταγή και εφαρμόζει τις λειτουργίες σε οποιοδήποτε σύνολο δεδομένων.\n", "\n", "Με αυτά τα δεδομένα, ας προετοιμάσουμε και εφαρμόσουμε τις συνταγές μας για να επιβεβαιώσουμε πραγματικά ότι, στο παρασκήνιο, οι στήλες προβλεπτικών παραγόντων θα κωδικοποιηθούν πρώτα πριν προσαρμοστεί ένα μοντέλο.\n" ], "metadata": { "id": "Q1xtzebuuTCP" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Prep the recipe\n", "pumpkins_prep <- prep(pumpkins_recipe)\n", "\n", "# Bake the recipe to extract a preprocessed new_pumpkins data\n", "baked_pumpkins <- bake(pumpkins_prep, new_data = NULL)\n", "\n", "# Print out the baked data set\n", "baked_pumpkins %>% \n", " slice_head(n = 10)" ], "outputs": [], "metadata": { "id": "FGBbJbP_uUUn" } }, { "cell_type": "markdown", "source": [ "Ουάου! 🥳 Τα επεξεργασμένα δεδομένα `baked_pumpkins` έχουν όλους τους προβλεπτικούς παράγοντες κωδικοποιημένους, επιβεβαιώνοντας ότι τα βήματα προεπεξεργασίας που ορίστηκαν ως η συνταγή μας λειτουργούν όπως αναμενόταν. Αυτό τα κάνει πιο δύσκολα για εσάς να τα διαβάσετε, αλλά πολύ πιο κατανοητά για τα Tidymodels! Αφιερώστε λίγο χρόνο για να ανακαλύψετε ποια παρατήρηση έχει αντιστοιχιστεί σε έναν αντίστοιχο ακέραιο αριθμό.\n", "\n", "Αξίζει επίσης να αναφερθεί ότι το `baked_pumpkins` είναι ένα πλαίσιο δεδομένων πάνω στο οποίο μπορούμε να εκτελέσουμε υπολογισμούς.\n", "\n", "Για παράδειγμα, ας προσπαθήσουμε να βρούμε μια καλή συσχέτιση μεταξύ δύο σημείων των δεδομένων σας για να δημιουργήσουμε ενδεχομένως ένα καλό προβλεπτικό μοντέλο. Θα χρησιμοποιήσουμε τη συνάρτηση `cor()` για να το κάνουμε αυτό. Πληκτρολογήστε `?cor()` για να μάθετε περισσότερα σχετικά με τη συνάρτηση.\n" ], "metadata": { "id": "1dvP0LBUueAW" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Find the correlation between the city_name and the price\n", "cor(baked_pumpkins$city_name, baked_pumpkins$price)\n", "\n", "# Find the correlation between the package and the price\n", "cor(baked_pumpkins$package, baked_pumpkins$price)\n" ], "outputs": [], "metadata": { "id": "3bQzXCjFuiSV" } }, { "cell_type": "markdown", "source": [ "Όπως αποδεικνύεται, υπάρχει μόνο μια ασθενής συσχέτιση μεταξύ της Πόλης και της Τιμής. Ωστόσο, υπάρχει μια λίγο καλύτερη συσχέτιση μεταξύ του Πακέτου και της Τιμής του. Αυτό βγάζει νόημα, σωστά; Συνήθως, όσο μεγαλύτερο είναι το κουτί προϊόντων, τόσο υψηλότερη είναι η τιμή.\n", "\n", "Αφού είμαστε σε αυτό το σημείο, ας προσπαθήσουμε επίσης να οπτικοποιήσουμε έναν πίνακα συσχέτισης όλων των στηλών χρησιμοποιώντας το πακέτο `corrplot`.\n" ], "metadata": { "id": "BToPWbgjuoZw" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Load the corrplot package\n", "library(corrplot)\n", "\n", "# Obtain correlation matrix\n", "corr_mat <- cor(baked_pumpkins %>% \n", " # Drop columns that are not really informative\n", " select(-c(low_price, high_price)))\n", "\n", "# Make a correlation plot between the variables\n", "corrplot(corr_mat, method = \"shade\", shade.col = NA, tl.col = \"black\", tl.srt = 45, addCoef.col = \"black\", cl.pos = \"n\", order = \"original\")" ], "outputs": [], "metadata": { "id": "ZwAL3ksmutVR" } }, { "cell_type": "markdown", "source": [ "🤩🤩 Πολύ καλύτερα.\n", "\n", "Μια καλή ερώτηση που μπορούμε τώρα να κάνουμε για αυτά τα δεδομένα είναι: '`Ποια τιμή μπορώ να περιμένω για ένα συγκεκριμένο πακέτο κολοκύθας;`' Ας το εξετάσουμε αμέσως!\n", "\n", "> Σημείωση: Όταν **`bake()`** τη προετοιμασμένη συνταγή **`pumpkins_prep`** με **`new_data = NULL`**, εξάγεις τα επεξεργασμένα (δηλαδή κωδικοποιημένα) δεδομένα εκπαίδευσης. Εάν είχες ένα άλλο σύνολο δεδομένων, για παράδειγμα ένα σύνολο δοκιμής, και ήθελες να δεις πώς μια συνταγή θα το προεπεξεργαζόταν, απλά θα έκανες bake **`pumpkins_prep`** με **`new_data = test_set`**.\n", "\n", "## 4. Δημιουργία ενός μοντέλου γραμμικής παλινδρόμησης\n", "\n", "

\n", " \n", "

Γραφικό από τον Dasani Madipalli
\n" ], "metadata": { "id": "YqXjLuWavNxW" } }, { "cell_type": "markdown", "source": [ "Τώρα που έχουμε δημιουργήσει μια συνταγή και επιβεβαιώσαμε ότι τα δεδομένα θα προεπεξεργαστούν κατάλληλα, ας προχωρήσουμε στη δημιουργία ενός μοντέλου παλινδρόμησης για να απαντήσουμε στην ερώτηση: `Ποια τιμή μπορώ να περιμένω για ένα δεδομένο πακέτο κολοκύθας;`\n", "\n", "#### Εκπαίδευση ενός γραμμικού μοντέλου παλινδρόμησης χρησιμοποιώντας το σύνολο εκπαίδευσης\n", "\n", "Όπως ίσως έχετε ήδη καταλάβει, η στήλη *price* είναι η μεταβλητή `αποτέλεσμα`, ενώ η στήλη *package* είναι η μεταβλητή `προβλεπτική`.\n", "\n", "Για να το κάνουμε αυτό, θα χωρίσουμε πρώτα τα δεδομένα έτσι ώστε το 80% να πάει στο σύνολο εκπαίδευσης και το 20% στο σύνολο δοκιμής, στη συνέχεια θα ορίσουμε μια συνταγή που θα κωδικοποιήσει τη στήλη προβλεπτικής μεταβλητής σε ένα σύνολο ακέραιων αριθμών και μετά θα δημιουργήσουμε μια προδιαγραφή μοντέλου. Δεν θα προετοιμάσουμε και ψήσουμε τη συνταγή μας, καθώς ήδη γνωρίζουμε ότι θα προεπεξεργαστεί τα δεδομένα όπως αναμένεται.\n" ], "metadata": { "id": "Pq0bSzCevW-h" } }, { "cell_type": "code", "execution_count": null, "source": [ "set.seed(2056)\n", "# Split the data into training and test sets\n", "pumpkins_split <- new_pumpkins %>% \n", " initial_split(prop = 0.8)\n", "\n", "\n", "# Extract training and test data\n", "pumpkins_train <- training(pumpkins_split)\n", "pumpkins_test <- testing(pumpkins_split)\n", "\n", "\n", "\n", "# Create a recipe for preprocessing the data\n", "lm_pumpkins_recipe <- recipe(price ~ package, data = pumpkins_train) %>% \n", " step_integer(all_predictors(), zero_based = TRUE)\n", "\n", "\n", "\n", "# Create a linear model specification\n", "lm_spec <- linear_reg() %>% \n", " set_engine(\"lm\") %>% \n", " set_mode(\"regression\")" ], "outputs": [], "metadata": { "id": "CyoEh_wuvcLv" } }, { "cell_type": "markdown", "source": [ "Μπράβο! Τώρα που έχουμε μια συνταγή και μια προδιαγραφή μοντέλου, πρέπει να βρούμε έναν τρόπο να τα συνδυάσουμε σε ένα αντικείμενο που θα επεξεργάζεται πρώτα τα δεδομένα (prep+bake στο παρασκήνιο), θα εκπαιδεύει το μοντέλο στα επεξεργασμένα δεδομένα και θα επιτρέπει επίσης πιθανές δραστηριότητες μετά την επεξεργασία. Πώς σου φαίνεται αυτό για την ηρεμία σου!🤩\n", "\n", "Στο Tidymodels, αυτό το πρακτικό αντικείμενο ονομάζεται [`workflow`](https://workflows.tidymodels.org/) και κρατά βολικά τα συστατικά του μοντέλου σου! Αυτό είναι που θα αποκαλούσαμε *pipelines* στη *Python*.\n", "\n", "Ας τα συνδυάσουμε όλα σε ένα workflow!📦\n" ], "metadata": { "id": "G3zF_3DqviFJ" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Hold modelling components in a workflow\n", "lm_wf <- workflow() %>% \n", " add_recipe(lm_pumpkins_recipe) %>% \n", " add_model(lm_spec)\n", "\n", "# Print out the workflow\n", "lm_wf" ], "outputs": [], "metadata": { "id": "T3olroU3v-WX" } }, { "cell_type": "markdown", "source": [ "Επιπλέον, μια ροή εργασίας μπορεί να προσαρμοστεί/εκπαιδευτεί με παρόμοιο τρόπο όπως ένα μοντέλο.\n" ], "metadata": { "id": "zd1A5tgOwEPX" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Train the model\n", "lm_wf_fit <- lm_wf %>% \n", " fit(data = pumpkins_train)\n", "\n", "# Print the model coefficients learned \n", "lm_wf_fit" ], "outputs": [], "metadata": { "id": "NhJagFumwFHf" } }, { "cell_type": "markdown", "source": [ "Από την έξοδο του μοντέλου, μπορούμε να δούμε τους συντελεστές που υπολογίστηκαν κατά τη διάρκεια της εκπαίδευσης. Αυτοί αντιπροσωπεύουν τους συντελεστές της γραμμής καλύτερης προσαρμογής που μας δίνει το χαμηλότερο συνολικό σφάλμα μεταξύ της πραγματικής και της προβλεπόμενης μεταβλητής.\n", "\n", "#### Αξιολόγηση της απόδοσης του μοντέλου χρησιμοποιώντας το σύνολο δοκιμής\n", "\n", "Ήρθε η ώρα να δούμε πώς τα πήγε το μοντέλο 📏! Πώς το κάνουμε αυτό;\n", "\n", "Τώρα που έχουμε εκπαιδεύσει το μοντέλο, μπορούμε να το χρησιμοποιήσουμε για να κάνουμε προβλέψεις για το test_set χρησιμοποιώντας `parsnip::predict()`. Στη συνέχεια, μπορούμε να συγκρίνουμε αυτές τις προβλέψεις με τις πραγματικές τιμές των ετικετών για να αξιολογήσουμε πόσο καλά (ή όχι!) λειτουργεί το μοντέλο.\n", "\n", "Ας ξεκινήσουμε κάνοντας προβλέψεις για το σύνολο δοκιμής και στη συνέχεια να συνδέσουμε τις στήλες με το σύνολο δοκιμής.\n" ], "metadata": { "id": "_4QkGtBTwItF" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Make predictions for the test set\n", "predictions <- lm_wf_fit %>% \n", " predict(new_data = pumpkins_test)\n", "\n", "\n", "# Bind predictions to the test set\n", "lm_results <- pumpkins_test %>% \n", " select(c(package, price)) %>% \n", " bind_cols(predictions)\n", "\n", "\n", "# Print the first ten rows of the tibble\n", "lm_results %>% \n", " slice_head(n = 10)" ], "outputs": [], "metadata": { "id": "UFZzTG0gwTs9" } }, { "cell_type": "markdown", "source": [ "Ναι, μόλις εκπαιδεύσατε ένα μοντέλο και το χρησιμοποιήσατε για να κάνετε προβλέψεις!🔮 Είναι καλό; Ας αξιολογήσουμε την απόδοση του μοντέλου!\n", "\n", "Στο Tidymodels, το κάνουμε αυτό χρησιμοποιώντας τη συνάρτηση `yardstick::metrics()`! Για τη γραμμική παλινδρόμηση, ας εστιάσουμε στις παρακάτω μετρικές:\n", "\n", "- `Root Mean Square Error (RMSE)`: Η τετραγωνική ρίζα του [MSE](https://en.wikipedia.org/wiki/Mean_squared_error). Παρέχει μια απόλυτη μέτρηση στην ίδια μονάδα με την ετικέτα (σε αυτή την περίπτωση, την τιμή μιας κολοκύθας). Όσο μικρότερη είναι η τιμή, τόσο καλύτερο είναι το μοντέλο (με απλοϊκή έννοια, αντιπροσωπεύει τη μέση τιμή κατά την οποία οι προβλέψεις είναι λανθασμένες!).\n", "\n", "- `Coefficient of Determination (συνήθως γνωστό ως R-squared ή R2)`: Μια σχετική μέτρηση, όπου όσο μεγαλύτερη είναι η τιμή, τόσο καλύτερη είναι η προσαρμογή του μοντέλου. Ουσιαστικά, αυτή η μέτρηση αντιπροσωπεύει το πόσο από τη διακύμανση μεταξύ των προβλεπόμενων και των πραγματικών τιμών της ετικέτας μπορεί να εξηγήσει το μοντέλο.\n" ], "metadata": { "id": "0A5MjzM7wW9M" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Evaluate performance of linear regression\n", "metrics(data = lm_results,\n", " truth = price,\n", " estimate = .pred)" ], "outputs": [], "metadata": { "id": "reJ0UIhQwcEH" } }, { "cell_type": "markdown", "source": [ "Εκεί πάει η απόδοση του μοντέλου. Ας δούμε αν μπορούμε να πάρουμε μια καλύτερη ένδειξη οπτικοποιώντας ένα διάγραμμα διασποράς του πακέτου και της τιμής και στη συνέχεια χρησιμοποιώντας τις προβλέψεις για να προσθέσουμε μια γραμμή καλύτερης προσαρμογής.\n", "\n", "Αυτό σημαίνει ότι θα πρέπει να προετοιμάσουμε και να επεξεργαστούμε το σύνολο δοκιμών, ώστε να κωδικοποιήσουμε τη στήλη του πακέτου και στη συνέχεια να τη συνδέσουμε με τις προβλέψεις που έκανε το μοντέλο μας.\n" ], "metadata": { "id": "fdgjzjkBwfWt" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Encode package column\n", "package_encode <- lm_pumpkins_recipe %>% \n", " prep() %>% \n", " bake(new_data = pumpkins_test) %>% \n", " select(package)\n", "\n", "\n", "# Bind encoded package column to the results\n", "lm_results <- lm_results %>% \n", " bind_cols(package_encode %>% \n", " rename(package_integer = package)) %>% \n", " relocate(package_integer, .after = package)\n", "\n", "\n", "# Print new results data frame\n", "lm_results %>% \n", " slice_head(n = 5)\n", "\n", "\n", "# Make a scatter plot\n", "lm_results %>% \n", " ggplot(mapping = aes(x = package_integer, y = price)) +\n", " geom_point(size = 1.6) +\n", " # Overlay a line of best fit\n", " geom_line(aes(y = .pred), color = \"orange\", size = 1.2) +\n", " xlab(\"package\")\n", " \n" ], "outputs": [], "metadata": { "id": "R0nw719lwkHE" } }, { "cell_type": "markdown", "source": [ "Όπως μπορείτε να δείτε, το μοντέλο γραμμικής παλινδρόμησης δεν γενικεύει πολύ καλά τη σχέση μεταξύ ενός πακέτου και της αντίστοιχης τιμής του.\n", "\n", "🎃 Συγχαρητήρια, μόλις δημιουργήσατε ένα μοντέλο που μπορεί να βοηθήσει στην πρόβλεψη της τιμής για μερικές ποικιλίες κολοκύθας. Το αγρόκτημα σας για τις γιορτές θα είναι πανέμορφο. Αλλά πιθανότατα μπορείτε να δημιουργήσετε ένα καλύτερο μοντέλο!\n", "\n", "## 5. Δημιουργήστε ένα μοντέλο πολυωνυμικής παλινδρόμησης\n", "\n", "

\n", " \n", "

Γραφικό από τη Dasani Madipalli
\n", "\n", "\n", "\n" ], "metadata": { "id": "HOCqJXLTwtWI" } }, { "cell_type": "markdown", "source": [ "Μερικές φορές τα δεδομένα μας μπορεί να μην έχουν γραμμική σχέση, αλλά εξακολουθούμε να θέλουμε να προβλέψουμε ένα αποτέλεσμα. Η πολυωνυμική παλινδρόμηση μπορεί να μας βοηθήσει να κάνουμε προβλέψεις για πιο σύνθετες μη γραμμικές σχέσεις.\n", "\n", "Για παράδειγμα, ας δούμε τη σχέση μεταξύ του πακέτου και της τιμής στο σύνολο δεδομένων με τις κολοκύθες μας. Ενώ μερικές φορές υπάρχει μια γραμμική σχέση μεταξύ των μεταβλητών - όσο μεγαλύτερη είναι η κολοκύθα σε όγκο, τόσο υψηλότερη είναι η τιμή - μερικές φορές αυτές οι σχέσεις δεν μπορούν να απεικονιστούν ως επίπεδο ή ευθεία γραμμή.\n", "\n", "> ✅ Εδώ είναι [μερικά ακόμη παραδείγματα](https://online.stat.psu.edu/stat501/lesson/9/9.8) δεδομένων που θα μπορούσαν να χρησιμοποιήσουν πολυωνυμική παλινδρόμηση\n", ">\n", "> Ρίξτε μια ακόμη ματιά στη σχέση μεταξύ Ποικιλίας και Τιμής στο προηγούμενο διάγραμμα. Φαίνεται αυτό το διάγραμμα διασποράς σαν να πρέπει απαραίτητα να αναλυθεί με μια ευθεία γραμμή; Ίσως όχι. Σε αυτή την περίπτωση, μπορείτε να δοκιμάσετε την πολυωνυμική παλινδρόμηση.\n", ">\n", "> ✅ Τα πολυώνυμα είναι μαθηματικές εκφράσεις που μπορεί να αποτελούνται από μία ή περισσότερες μεταβλητές και συντελεστές\n", "\n", "#### Εκπαίδευση ενός μοντέλου πολυωνυμικής παλινδρόμησης χρησιμοποιώντας το σύνολο εκπαίδευσης\n", "\n", "Η πολυωνυμική παλινδρόμηση δημιουργεί μια *καμπύλη γραμμή* για να ταιριάζει καλύτερα σε μη γραμμικά δεδομένα.\n", "\n", "Ας δούμε αν ένα πολυωνυμικό μοντέλο θα αποδώσει καλύτερα στις προβλέψεις. Θα ακολουθήσουμε μια κάπως παρόμοια διαδικασία όπως κάναμε πριν:\n", "\n", "- Δημιουργήστε μια συνταγή που καθορίζει τα βήματα προεπεξεργασίας που πρέπει να πραγματοποιηθούν στα δεδομένα μας για να είναι έτοιμα για μοντελοποίηση, δηλαδή: κωδικοποίηση προβλεπτικών μεταβλητών και υπολογισμός πολυωνύμων βαθμού *n*\n", "\n", "- Δημιουργήστε μια προδιαγραφή μοντέλου\n", "\n", "- Συνδυάστε τη συνταγή και την προδιαγραφή μοντέλου σε μια ροή εργασίας\n", "\n", "- Δημιουργήστε ένα μοντέλο προσαρμόζοντας τη ροή εργασίας\n", "\n", "- Αξιολογήστε πόσο καλά αποδίδει το μοντέλο στα δεδομένα δοκιμής\n", "\n", "Ας ξεκινήσουμε!\n" ], "metadata": { "id": "VcEIpRV9wzYr" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Specify a recipe\r\n", "poly_pumpkins_recipe <-\r\n", " recipe(price ~ package, data = pumpkins_train) %>%\r\n", " step_integer(all_predictors(), zero_based = TRUE) %>% \r\n", " step_poly(all_predictors(), degree = 4)\r\n", "\r\n", "\r\n", "# Create a model specification\r\n", "poly_spec <- linear_reg() %>% \r\n", " set_engine(\"lm\") %>% \r\n", " set_mode(\"regression\")\r\n", "\r\n", "\r\n", "# Bundle recipe and model spec into a workflow\r\n", "poly_wf <- workflow() %>% \r\n", " add_recipe(poly_pumpkins_recipe) %>% \r\n", " add_model(poly_spec)\r\n", "\r\n", "\r\n", "# Create a model\r\n", "poly_wf_fit <- poly_wf %>% \r\n", " fit(data = pumpkins_train)\r\n", "\r\n", "\r\n", "# Print learned model coefficients\r\n", "poly_wf_fit\r\n", "\r\n", " " ], "outputs": [], "metadata": { "id": "63n_YyRXw3CC" } }, { "cell_type": "markdown", "source": [ "#### Αξιολόγηση της απόδοσης του μοντέλου\n", "\n", "👏👏 Έχετε δημιουργήσει ένα πολυωνυμικό μοντέλο, ας κάνουμε προβλέψεις στο σύνολο δοκιμών!\n" ], "metadata": { "id": "-LHZtztSxDP0" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Make price predictions on test data\r\n", "poly_results <- poly_wf_fit %>% predict(new_data = pumpkins_test) %>% \r\n", " bind_cols(pumpkins_test %>% select(c(package, price))) %>% \r\n", " relocate(.pred, .after = last_col())\r\n", "\r\n", "\r\n", "# Print the results\r\n", "poly_results %>% \r\n", " slice_head(n = 10)" ], "outputs": [], "metadata": { "id": "YUFpQ_dKxJGx" } }, { "cell_type": "markdown", "source": [ "Γιούπι, ας αξιολογήσουμε πώς το μοντέλο απέδωσε στο test_set χρησιμοποιώντας `yardstick::metrics()`.\n" ], "metadata": { "id": "qxdyj86bxNGZ" } }, { "cell_type": "code", "execution_count": null, "source": [ "metrics(data = poly_results, truth = price, estimate = .pred)" ], "outputs": [], "metadata": { "id": "8AW5ltkBxXDm" } }, { "cell_type": "markdown", "source": [ "🤩🤩 Πολύ καλύτερη απόδοση.\n", "\n", "Το `rmse` μειώθηκε από περίπου 7 σε περίπου 3, ένδειξη μειωμένου σφάλματος μεταξύ της πραγματικής τιμής και της προβλεπόμενης τιμής. Μπορείτε να το *ερμηνεύσετε χαλαρά* ως ότι, κατά μέσο όρο, οι λανθασμένες προβλέψεις έχουν σφάλμα περίπου \\$3. Το `rsq` αυξήθηκε από περίπου 0.4 σε 0.8.\n", "\n", "Όλοι αυτοί οι δείκτες δείχνουν ότι το πολυωνυμικό μοντέλο αποδίδει πολύ καλύτερα από το γραμμικό μοντέλο. Μπράβο!\n", "\n", "Ας δούμε αν μπορούμε να το οπτικοποιήσουμε!\n" ], "metadata": { "id": "6gLHNZDwxYaS" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Bind encoded package column to the results\r\n", "poly_results <- poly_results %>% \r\n", " bind_cols(package_encode %>% \r\n", " rename(package_integer = package)) %>% \r\n", " relocate(package_integer, .after = package)\r\n", "\r\n", "\r\n", "# Print new results data frame\r\n", "poly_results %>% \r\n", " slice_head(n = 5)\r\n", "\r\n", "\r\n", "# Make a scatter plot\r\n", "poly_results %>% \r\n", " ggplot(mapping = aes(x = package_integer, y = price)) +\r\n", " geom_point(size = 1.6) +\r\n", " # Overlay a line of best fit\r\n", " geom_line(aes(y = .pred), color = \"midnightblue\", size = 1.2) +\r\n", " xlab(\"package\")\r\n" ], "outputs": [], "metadata": { "id": "A83U16frxdF1" } }, { "cell_type": "markdown", "source": [ "Μπορείτε να δείτε μια καμπύλη γραμμή που ταιριάζει καλύτερα στα δεδομένα σας! 🤩\n", "\n", "Μπορείτε να την κάνετε πιο ομαλή περνώντας έναν πολυωνυμικό τύπο στο `geom_smooth`, όπως αυτό:\n" ], "metadata": { "id": "4U-7aHOVxlGU" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Make a scatter plot\r\n", "poly_results %>% \r\n", " ggplot(mapping = aes(x = package_integer, y = price)) +\r\n", " geom_point(size = 1.6) +\r\n", " # Overlay a line of best fit\r\n", " geom_smooth(method = lm, formula = y ~ poly(x, degree = 4), color = \"midnightblue\", size = 1.2, se = FALSE) +\r\n", " xlab(\"package\")" ], "outputs": [], "metadata": { "id": "5vzNT0Uexm-w" } }, { "cell_type": "markdown", "source": [ "Πολύ σαν μια ομαλή καμπύλη!🤩\n", "\n", "Να πώς μπορείτε να κάνετε μια νέα πρόβλεψη:\n" ], "metadata": { "id": "v9u-wwyLxq4G" } }, { "cell_type": "code", "execution_count": null, "source": [ "# Make a hypothetical data frame\r\n", "hypo_tibble <- tibble(package = \"bushel baskets\")\r\n", "\r\n", "# Make predictions using linear model\r\n", "lm_pred <- lm_wf_fit %>% predict(new_data = hypo_tibble)\r\n", "\r\n", "# Make predictions using polynomial model\r\n", "poly_pred <- poly_wf_fit %>% predict(new_data = hypo_tibble)\r\n", "\r\n", "# Return predictions in a list\r\n", "list(\"linear model prediction\" = lm_pred, \r\n", " \"polynomial model prediction\" = poly_pred)\r\n" ], "outputs": [], "metadata": { "id": "jRPSyfQGxuQv" } }, { "cell_type": "markdown", "source": [ "Η πρόβλεψη του `πολυωνυμικού μοντέλου` έχει νόημα, δεδομένων των διαγραμμάτων διασποράς των `τιμή` και `πακέτο`! Και, αν αυτό είναι ένα καλύτερο μοντέλο από το προηγούμενο, κοιτάζοντας τα ίδια δεδομένα, θα χρειαστεί να προϋπολογίσετε για αυτές τις πιο ακριβές κολοκύθες!\n", "\n", "🏆 Μπράβο! Δημιουργήσατε δύο μοντέλα παλινδρόμησης σε ένα μάθημα. Στην τελική ενότητα για την παλινδρόμηση, θα μάθετε για τη λογιστική παλινδρόμηση για τον καθορισμό κατηγοριών.\n", "\n", "## **🚀Πρόκληση**\n", "\n", "Δοκιμάστε διάφορες μεταβλητές σε αυτό το σημειωματάριο για να δείτε πώς η συσχέτιση αντιστοιχεί στην ακρίβεια του μοντέλου.\n", "\n", "## [**Κουίζ μετά το μάθημα**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/14/)\n", "\n", "## **Ανασκόπηση & Αυτομελέτη**\n", "\n", "Σε αυτό το μάθημα μάθαμε για τη Γραμμική Παλινδρόμηση. Υπάρχουν άλλοι σημαντικοί τύποι Παλινδρόμησης. Διαβάστε για τις τεχνικές Stepwise, Ridge, Lasso και Elasticnet. Ένα καλό μάθημα για να μάθετε περισσότερα είναι το [Stanford Statistical Learning course](https://online.stanford.edu/courses/sohs-ystatslearning-statistical-learning).\n", "\n", "Αν θέλετε να μάθετε περισσότερα για το πώς να χρησιμοποιήσετε το εκπληκτικό πλαίσιο Tidymodels, παρακαλώ δείτε τους παρακάτω πόρους:\n", "\n", "- Ιστοσελίδα Tidymodels: [Ξεκινήστε με το Tidymodels](https://www.tidymodels.org/start/)\n", "\n", "- Max Kuhn και Julia Silge, [*Tidy Modeling with R*](https://www.tmwr.org/)*.*\n", "\n", "###### **ΕΥΧΑΡΙΣΤΟΥΜΕ ΤΟΥΣ:**\n", "\n", "[Allison Horst](https://twitter.com/allison_horst?lang=en) για τη δημιουργία των εκπληκτικών εικονογραφήσεων που κάνουν τη R πιο φιλόξενη και ενδιαφέρουσα. Βρείτε περισσότερες εικονογραφήσεις στη [συλλογή της](https://www.google.com/url?q=https://github.com/allisonhorst/stats-illustrations&sa=D&source=editors&ust=1626380772530000&usg=AOvVaw3zcfyCizFQZpkSLzxiiQEM).\n" ], "metadata": { "id": "8zOLOWqMxzk5" } }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n---\n\n**Αποποίηση ευθύνης**: \nΑυτό το έγγραφο έχει μεταφραστεί χρησιμοποιώντας την υπηρεσία αυτόματης μετάφρασης AI [Co-op Translator](https://github.com/Azure/co-op-translator). Παρόλο που καταβάλλουμε προσπάθειες για ακρίβεια, παρακαλούμε να έχετε υπόψη ότι οι αυτόματες μεταφράσεις ενδέχεται να περιέχουν σφάλματα ή ανακρίβειες. Το πρωτότυπο έγγραφο στη μητρική του γλώσσα θα πρέπει να θεωρείται η αυθεντική πηγή. Για κρίσιμες πληροφορίες, συνιστάται επαγγελματική ανθρώπινη μετάφραση. Δεν φέρουμε ευθύνη για τυχόν παρεξηγήσεις ή εσφαλμένες ερμηνείες που προκύπτουν από τη χρήση αυτής της μετάφρασης.\n" ] } ] }