# Δημιουργία μοντέλου παλινδρόμησης με χρήση Scikit-learn: παλινδρόμηση με τέσσερις τρόπους
## Σημείωση για αρχάριους
Η γραμμική παλινδρόμηση χρησιμοποιείται όταν θέλουμε να προβλέψουμε μια **αριθμητική τιμή** (για παράδειγμα, τιμή σπιτιού, θερμοκρασία ή πωλήσεις). Λειτουργεί βρίσκοντας μια ευθεία που αντιπροσωπεύει καλύτερα τη σχέση μεταξύ των εισαγόμενων χαρακτηριστικών και της εξόδου.
Σε αυτό το μάθημα, εστιάζουμε στην κατανόηση της έννοιας πριν εξερευνήσουμε πιο προχωρημένες τεχνικές παλινδρόμησης.

> Infographic από τον/την [Dasani Madipalli](https://twitter.com/dasani_decoded)
## [Προαιρετικό κουίζ πριν το μάθημα](https://ff-quizzes.netlify.app/en/ml/)
> ### [Αυτό το μάθημα είναι διαθέσιμο και σε R!](../../../../2-Regression/3-Linear/solution/R/lesson_3.html)
### Εισαγωγή
Μέχρι τώρα έχετε διερευνήσει τι είναι η παλινδρόμηση με δείγμα δεδομένων από το σύνολο δεδομένων τιμών κολοκύθας που θα χρησιμοποιήσουμε σε όλο αυτό το μάθημα. Επίσης, το έχετε απεικονίσει οπτικά με τη χρήση του Matplotlib.
Τώρα είστε έτοιμοι να εμβαθύνετε στην παλινδρόμηση για την Μηχανική Μάθηση. Ενώ η οπτικοποίηση σας επιτρέπει να κατανοήσετε τα δεδομένα, η πραγματική δύναμη της Μηχανικής Μάθησης προέρχεται από το _εκπαίδευση μοντέλων_. Τα μοντέλα εκπαιδεύονται με ιστορικά δεδομένα για να συλλάβουν αυτόματα τις εξαρτήσεις δεδομένων, και σας επιτρέπουν να προβλέπετε αποτελέσματα για νέα δεδομένα, τα οποία το μοντέλο δεν έχει δει προηγουμένως.
Σε αυτό το μάθημα, θα μάθετε περισσότερα για δύο τύπους παλινδρόμησης: _βασική γραμμική παλινδρόμηση_ και _πολυωνυμική παλινδρόμηση_, μαζί με κάποια από τα μαθηματικά που βασίζονται αυτές οι τεχνικές. Αυτά τα μοντέλα θα μας επιτρέψουν να προβλέψουμε τις τιμές κολοκύθας ανάλογα με διαφορετικά εισαγόμενα δεδομένα.
[](https://youtu.be/CRxFT8oTDMg "Μηχανική Μάθηση για αρχάριους - Κατανόηση της Γραμμικής Παλινδρόμησης")
> 🎥 Κάντε κλικ στην εικόνα παραπάνω για σύντομη επισκόπηση βίντεο σχετικά με τη γραμμική παλινδρόμηση.
> Σε όλη τη διάρκεια αυτού του προγράμματος σπουδών, θεωρούμε ελάχιστες γνώσεις μαθηματικών, και στοχεύουμε να το κάνουμε προσβάσιμο για φοιτητές από άλλους κλάδους, οπότε παρατηρήστε τις σημειώσεις, 🧮 επισήμανσεις, διαγράμματα και άλλα εργαλεία μάθησης για βοήθεια στην κατανόηση.
### Προαπαιτούμενα
Πρέπει να είστε εξοικειωμένοι πια με τη δομή των δεδομένων κολοκύθας που εξετάζουμε. Μπορείτε να τα βρείτε προφορτωμένα και καθαρισμένα στο αρχείο _notebook.ipynb_ αυτού του μαθήματος. Στο αρχείο, η τιμή της κολοκύθας εμφανίζεται ανά μπουσέλ σε νέο πλαίσιο δεδομένων. Βεβαιωθείτε ότι μπορείτε να εκτελέσετε αυτά τα notebooks σε kernels στο Visual Studio Code.
### Προετοιμασία
Ως υπενθύμιση, φορτώνετε αυτά τα δεδομένα για να θέσετε ερωτήματα πάνω σε αυτά.
- Ποια είναι η καλύτερη εποχή να αγοράσουμε κολοκύθες;
- Τι τιμή μπορώ να αναμένω για μια περίπτωση μικρών κολοκύθων;
- Πρέπει να τις αγοράσω σε καλάθια μισού μπουσέλ ή σε συσκευασία 1 1/9 μπουσέλ;
Ας συνεχίσουμε να ερευνούμε αυτά τα δεδομένα.
Στο προηγούμενο μάθημα, δημιουργήσατε ένα πλαίσιο δεδομένων Pandas και το γεμίσατε με μέρος του αρχικού συνόλου δεδομένων, τυποποιώντας τις τιμές ανά μπουσέλ. Με αυτόν τον τρόπο, ωστόσο, καταφέρατε να συλλέξετε μόνο περίπου 400 σημεία δεδομένων και μόνο για τους φθινοπωρινούς μήνες.
Ρίξτε μια ματιά στα δεδομένα που προφορτώσαμε στο συνοδευτικό notebook αυτού του μαθήματος. Τα δεδομένα είναι προφορτωμένα και έχει γίνει αρχικό scatterplot για να δείξει δεδομένα ανά μήνα. Ίσως μπορέσουμε να πάρουμε λίγο περισσότερες λεπτομέρειες για τη φύση των δεδομένων με περαιτέρω καθαρισμό.
## Μια γραμμική γραμμή παλινδρόμησης
Όπως μάθατε στο Μάθημα 1, ο στόχος μιας άσκησης γραμμικής παλινδρόμησης είναι να μπορέσουμε να σχεδιάσουμε μια γραμμή που:
- **Δείχνει τις σχέσεις μεταβλητών**. Δείχνει τη σχέση μεταξύ μεταβλητών
- **Κάνει προβλέψεις**. Κάνει ακριβείς προβλέψεις για το πού θα βρίσκεται ένα νέο δεδομένο σε σχέση με αυτή τη γραμμή.
Είναι τυπικό της **Παλινδρόμησης Ελαχίστων Τετραγώνων** να σχεδιάζει αυτό το είδος γραμμής. Ο όρος "Ελαχίστη Τετραγωνική" αναφέρεται στη διαδικασία ελαχιστοποίησης του συνολικού σφάλματος στο μοντέλο μας. Για κάθε σημείο δεδομένων, μετράμε την κάθετη απόσταση (που ονομάζεται υπολειπόμενο) μεταξύ του πραγματικού σημείου και της γραμμής παλινδρόμησης.
Αυτές τις αποστάσεις τις τετραγωνίζουμε για δύο κύριους λόγους:
1. **Μέγεθος αντί για κατεύθυνση:** Θέλουμε να αντιμετωπίσουμε ένα σφάλμα -5 το ίδιο με ένα σφάλμα +5. Η τετραγωνική μετατρέπει όλες τις τιμές σε θετικές.
2. **Τιμωρία για Εκτός Ορίων Σφάλματα:** Η τετραγωνική δίνει μεγαλύτερο βάρος στα μεγαλύτερα σφάλματα, αναγκάζοντας τη γραμμή να παραμείνει πιο κοντά σε σημεία που είναι μακριά.
Έπειτα προσθέτουμε όλες αυτές τις τετραγωνισμένες τιμές μαζί. Ο στόχος μας είναι να βρούμε την συγκεκριμένη γραμμή όπου αυτό το τελικό άθροισμα είναι το μικρότερο δυνατό — εξ ου και το όνομα "Ελαχίστων Τετραγώνων".
> **🧮 Δείξε μου τα μαθηματικά**
>
> Αυτή η γραμμή, που ονομάζεται _γραμμή της καλύτερης προσαρμογής_, μπορεί να εκφραστεί με [μια εξίσωση](https://en.wikipedia.org/wiki/Simple_linear_regression):
>
> ```
> Y = a + bX
> ```
>
> `X` είναι η 'εξηγηματική μεταβλητή'. `Y` είναι η 'εξαρτημένη μεταβλητή'. Η κλίση της γραμμής είναι `b` και το `a` είναι η τομή στον άξονα y, που αναφέρεται στην τιμή του `Y` όταν `X = 0`.
>
>
>
> Πρώτα, υπολογίστε την κλίση `b`. Infographic από την [Jen Looper](https://twitter.com/jenlooper)
>
> Με άλλα λόγια, και αναφερόμενοι στην αρχική ερώτηση των δεδομένων κολοκύθας μας: "προβλέψτε την τιμή μιας κολοκύθας ανά μπουσέλ ανά μήνα", το `X` θα αναφερόταν στην τιμή και το `Y` στον μήνα πώλησης.
>
>
>
> Υπολογίστε την τιμή του Y. Αν πληρώνετε γύρω στα 4 δολάρια, πρέπει να είναι Απρίλιος! Infographic από την [Jen Looper](https://twitter.com/jenlooper)
>
> Τα μαθηματικά που υπολογίζουν τη γραμμή πρέπει να δείχνουν την κλίση της γραμμής, η οποία εξαρτάται επίσης από την τομή, ή το σημείο όπου βρίσκεται το `Y` όταν `X = 0`.
>
> Μπορείτε να δείτε τη μέθοδο υπολογισμού αυτών των τιμών στην ιστοσελίδα [Math is Fun](https://www.mathsisfun.com/data/least-squares-regression.html). Επισκεφθείτε επίσης [τον υπολογιστή Ελαχίστων Τετραγώνων](https://www.mathsisfun.com/data/least-squares-calculator.html) για να δείτε πώς οι αριθμητικές τιμές επιδρούν στη γραμμή.
## Συνάφεια
Ένας ακόμη όρος προς κατανόηση είναι ο **Συντελεστής Συσχέτισης** μεταξύ των δοσμένων μεταβλητών X και Y. Χρησιμοποιώντας ένα scatterplot, μπορείτε γρήγορα να οπτικοποιήσετε αυτόν τον συντελεστή. Ένα γράφημα με σημεία δεδομένων συγκεντρωμένα σε μια καθαρή γραμμή έχει υψηλή συσχέτιση, ενώ ένα γράφημα με σημεία δεδομένων σκορπισμένα παντού μεταξύ X και Y έχει χαμηλή συσχέτιση.
Ένα καλό μοντέλο γραμμικής παλινδρόμησης θα είναι αυτό που έχει υψηλό (πιο κοντά στο 1 παρά στο 0) Συντελεστή Συσχέτισης με χρήση της μεθόδου Ελαχίστων Τετραγώνων με γραμμή παλινδρόμησης.
✅ Εκτελέστε το notebook που συνοδεύει αυτό το μάθημα και δείτε το scatterplot μήνα προς τιμή. Φαίνεται να υπάρχει υψηλή ή χαμηλή συσχέτιση στα δεδομένα που συνδέουν τον μήνα με την τιμή των πωλήσεων κολοκύθας σύμφωνα με την οπτική σας ερμηνεία του scatterplot; Αλλάζει κάτι αν χρησιμοποιήσετε πιο λεπτομερή μέτρο αντί για `Month`, π.χ. *ημέρα του έτους* (δηλαδή αριθμός ημερών από την αρχή του έτους);
Στον παρακάτω κώδικα, υποθέτουμε ότι έχουμε καθαρίσει τα δεδομένα και έχουμε αποκτήσει ένα πλαίσιο δεδομένων με το όνομα `new_pumpkins`, παρόμοιο με το εξής:
ID | Month | DayOfYear | Variety | City | Package | Low Price | High Price | Price
---|-------|-----------|---------|------|---------|-----------|------------|-------
70 | 9 | 267 | PIE TYPE | BALTIMORE | 1 1/9 bushel cartons | 15.0 | 15.0 | 13.636364
71 | 9 | 267 | PIE TYPE | BALTIMORE | 1 1/9 bushel cartons | 18.0 | 18.0 | 16.363636
72 | 10 | 274 | PIE TYPE | BALTIMORE | 1 1/9 bushel cartons | 18.0 | 18.0 | 16.363636
73 | 10 | 274 | PIE TYPE | BALTIMORE | 1 1/9 bushel cartons | 17.0 | 17.0 | 15.454545
74 | 10 | 281 | PIE TYPE | BALTIMORE | 1 1/9 bushel cartons | 15.0 | 15.0 | 13.636364
> Ο κώδικας για τον καθαρισμό των δεδομένων είναι διαθέσιμος στο [`notebook.ipynb`](notebook.ipynb). Έχουμε πραγματοποιήσει τα ίδια βήματα καθαρισμού όπως στο προηγούμενο μάθημα, και έχουμε υπολογίσει τη στήλη `DayOfYear` με την ακόλουθη έκφραση:
```python
day_of_year = pd.to_datetime(pumpkins['Date']).apply(lambda dt: (dt-datetime(dt.year,1,1)).days)
```
Τώρα που έχετε κατανοήσει τα μαθηματικά πίσω από τη γραμμική παλινδρόμηση, ας δημιουργήσουμε ένα μοντέλο παλινδρόμησης για να δούμε αν μπορούμε να προβλέψουμε ποια συσκευασία κολοκύθας θα έχει τις καλύτερες τιμές. Κάποιος που αγοράζει κολοκύθες για ένα εποχιακό παρτέρι κολοκύθας μπορεί να θέλει αυτή την πληροφορία για να βελτιστοποιήσει τις αγορές του σε συσκευασίες κολοκύθας.
## Αναζήτηση συσχέτισης
[](https://youtu.be/uoRq-lW2eQo "Μηχανική Μάθηση για αρχάριους - Αναζήτηση συσχέτισης: Το κλειδί για τη γραμμική παλινδρόμηση")
> 🎥 Κάντε κλικ στην εικόνα παραπάνω για σύντομη επισκόπηση βίντεο σχετικά με τη συσχέτιση.
Από το προηγούμενο μάθημα πιθανότατα έχετε δει ότι η μέση τιμή ανά μήνα μοιάζει κάπως έτσι:
Αυτό υποδηλώνει ότι πρέπει να υπάρχει κάποια συσχέτιση, και μπορούμε να δοκιμάσουμε να εκπαιδεύσουμε γραμμικό μοντέλο παλινδρόμησης για να προβλέψουμε τη σχέση μεταξύ `Month` και `Price`, ή μεταξύ `DayOfYear` και `Price`. Ιδού το scatter plot που δείχνει τη δεύτερη σχέση:
Ας δούμε αν υπάρχει συσχέτιση χρησιμοποιώντας τη συνάρτηση `corr`:
```python
print(new_pumpkins['Month'].corr(new_pumpkins['Price']))
print(new_pumpkins['DayOfYear'].corr(new_pumpkins['Price']))
```
Φαίνεται ότι η συσχέτιση είναι αρκετά μικρή, -0.15 με βάση τον `Month` και -0.17 με βάση τον `DayOfMonth`, αλλά μπορεί να υπάρχει μια άλλη σημαντική σχέση. Φαίνεται ότι υπάρχουν διαφορετικές ομάδες τιμών που αντιστοιχούν σε διαφορετικές ποικιλίες κολοκύθας. Για να επιβεβαιώσουμε αυτή την υπόθεση, ας σχεδιάσουμε κάθε κατηγορία κολοκύθας με διαφορετικό χρώμα. Με τη μετάδοση της παραμέτρου `ax` στη συνάρτηση σχεδίασης `scatter`, μπορούμε να σχεδιάσουμε όλα τα σημεία στο ίδιο γράφημα:
```python
ax=None
colors = ['red','blue','green','yellow']
for i,var in enumerate(new_pumpkins['Variety'].unique()):
df = new_pumpkins[new_pumpkins['Variety']==var]
ax = df.plot.scatter('DayOfYear','Price',ax=ax,c=colors[i],label=var)
```
Η έρευνά μας υποδηλώνει ότι η ποικιλία έχει μεγαλύτερη επίδραση στην συνολική τιμή από την πραγματική ημερομηνία πώλησης. Το διαπιστώνουμε και με ένα ραβδόγραμμα:
```python
new_pumpkins.groupby('Variety')['Price'].mean().plot(kind='bar')
```
Ας εστιάσουμε προς στιγμή μόνο σε μια ποικιλία κολοκύθας, την 'pie type', και ας δούμε ποια επίδραση έχει η ημερομηνία στην τιμή:
```python
pie_pumpkins = new_pumpkins[new_pumpkins['Variety']=='PIE TYPE']
pie_pumpkins.plot.scatter('DayOfYear','Price')
```
Αν τώρα υπολογίσουμε τη συσχέτιση μεταξύ `Price` και `DayOfYear` χρησιμοποιώντας τη συνάρτηση `corr`, θα πάρουμε κάτι σαν `-0.27` - που σημαίνει ότι η εκπαίδευση ενός προβλεπτικού μοντέλου έχει νόημα.
> Προτού εκπαιδεύσουμε ένα μοντέλο γραμμικής παλινδρόμησης, είναι σημαντικό να βεβαιωθούμε ότι τα δεδομένα μας είναι καθαρά. Η γραμμική παλινδρόμηση δεν λειτουργεί καλά με ελλιπείς τιμές, οπότε έχει νόημα να απαλλαγούμε από όλα τα κενά κελιά:
```python
pie_pumpkins.dropna(inplace=True)
pie_pumpkins.info()
```
Μια άλλη προσέγγιση θα ήταν να συμπληρώσουμε αυτές τις κενές τιμές με τις μέσες τιμές των αντίστοιχων στηλών.
## Απλή γραμμική παλινδρόμηση
[](https://youtu.be/e4c_UP2fSjg "Μηχανική Μάθηση για αρχάριους - Γραμμική και Πολυωνυμική Παλινδρόμηση με χρήση Scikit-learn")
> 🎥 Κάντε κλικ στην εικόνα παραπάνω για σύντομη επισκόπηση βίντεο σχετικά με γραμμική και πολυωνυμική παλινδρόμηση.
Για να εκπαιδεύσουμε το μοντέλο μας Γραμμικής Παλινδρόμησης, θα χρησιμοποιήσουμε τη βιβλιοθήκη **Scikit-learn**.
```python
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error
from sklearn.model_selection import train_test_split
```
Ξεκινάμε με τον διαχωρισμό των εισόδων (χαρακτηριστικά) και της αναμενόμενης εξόδου (ετικέτα) σε ξεχωριστά numpy arrays:
```python
X = pie_pumpkins['DayOfYear'].to_numpy().reshape(-1,1)
y = pie_pumpkins['Price']
```
> Σημειώστε ότι έπρεπε να πραγματοποιήσουμε `reshape` στα εισαγόμενα δεδομένα ώστε το πακέτο Γραμμικής Παλινδρόμησης να τα κατανοήσει σωστά. Η Γραμμική Παλινδρόμηση αναμένει ως είσοδο έναν πίνακα 2 διαστάσεων, όπου κάθε σειρά του πίνακα αντιστοιχεί σε ένα διάνυσμα χαρακτηριστικών εισόδου. Στη δική μας περίπτωση, καθώς έχουμε μόνο μία είσοδο, χρειάζεται ένας πίνακας με διάσταση N×1, όπου N είναι το μέγεθος του συνόλου δεδομένων.
Έπειτα, πρέπει να χωρίσουμε τα δεδομένα σε σύνολα εκπαίδευσης και δοκιμής, ώστε να μπορέσουμε να επαληθεύσουμε το μοντέλο μας μετά την εκπαίδευση:
```python
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)
```
Τέλος, η εκπαίδευση του πραγματικού μοντέλου Γραμμικής Παλινδρόμησης γίνεται με δύο μόνο γραμμές κώδικα. Ορίζουμε το αντικείμενο της `LinearRegression` και το εφαρμόζουμε στα δεδομένα μας χρησιμοποιώντας τη μέθοδο `fit`:
```python
lin_reg = LinearRegression()
lin_reg.fit(X_train,y_train)
```
Το αντικείμενο `LinearRegression` μετά το `fit`-άρισμα περιέχει όλους τους συντελεστές της παλινδρόμησης, τους οποίους μπορούμε να προσεγγίσουμε χρησιμοποιώντας την ιδιότητα `.coef_`. Στη δική μας περίπτωση, υπάρχει μόνο ένας συντελεστής, που θα πρέπει να είναι περίπου `-0.017`. Αυτό σημαίνει ότι οι τιμές φαίνεται να μειώνονται λίγο με το χρόνο, αλλά όχι πολύ, περίπου 2 λεπτά την ημέρα. Μπορούμε επίσης να προσεγγίσουμε το σημείο τομής της παλινδρόμησης με τον άξονα Y χρησιμοποιώντας το `lin_reg.intercept_` - θα είναι περίπου `21` στη δική μας περίπτωση, που δείχνει την τιμή στην αρχή του έτους.
Για να δούμε πόσο ακριβές είναι το μοντέλο μας, μπορούμε να προβλέψουμε τιμές σε ένα σετ δοκιμής και στη συνέχεια να μετρήσουμε πόσο κοντά είναι οι προβλέψεις μας στις αναμενόμενες τιμές. Αυτό μπορεί να γίνει χρησιμοποιώντας το μέσο τετραγωνικό σφάλμα (MSE), που είναι ο μέσος όρος όλων των τετραγωνικών διαφορών μεταξύ της αναμενόμενης και της προβλεπόμενης τιμής.
```python
pred = lin_reg.predict(X_test)
mse = np.sqrt(mean_squared_error(y_test,pred))
print(f'Mean error: {mse:3.3} ({mse/np.mean(pred)*100:3.3}%)')
```
Το σφάλμα μας φαίνεται να είναι περίπου 2 μονάδες, που είναι ~17%. Όχι και τόσο καλό. Ένας άλλος δείκτης ποιότητας μοντέλου είναι ο **συντελεστής προσδιορισμού (coefficient of determination)**, που μπορεί να προκύψει έτσι:
```python
score = lin_reg.score(X_train,y_train)
print('Model determination: ', score)
```
Αν η τιμή είναι 0, σημαίνει ότι το μοντέλο δεν λαμβάνει υπόψη τα δεδομένα εισόδου και λειτουργεί ως ο *χειρότερος γραμμικός προβλέπων*, που απλώς είναι η μέση τιμή του αποτελέσματος. Η τιμή 1 σημαίνει ότι μπορούμε να προβλέψουμε τέλεια όλες τις αναμενόμενες εξόδους. Στη δική μας περίπτωση, ο συντελεστής είναι περίπου 0.06, που είναι αρκετά χαμηλός.
Μπορούμε επίσης να σχεδιάσουμε τα δεδομένα δοκιμής μαζί με τη γραμμή παλινδρόμησης για να δούμε καλύτερα πώς λειτουργεί η παλινδρόμηση στη δική μας περίπτωση:
```python
plt.scatter(X_test,y_test)
plt.plot(X_test,pred)
```
## Πολυωνυμική Παλινδρόμηση
Ένας άλλος τύπος Γραμμικής Παλινδρόμησης είναι η Πολυωνυμική Παλινδρόμηση. Ενώ μερικές φορές υπάρχει γραμμική σχέση μεταξύ των μεταβλητών - όσο μεγαλύτερη είναι η κολοκύθα σε όγκο, τόσο υψηλότερη η τιμή - κάποιες φορές αυτές οι σχέσεις δεν μπορούν να σχεδιαστούν ως επίπεδο ή ευθεία γραμμή.
✅ Εδώ είναι [μερικά ακόμα παραδείγματα](https://online.stat.psu.edu/stat501/lesson/9/9.8) δεδομένων που θα μπορούσαν να χρησιμοποιήσουν Πολυωνυμική Παλινδρόμηση
Κοιτάξτε ξανά τη σχέση μεταξύ Ημερομηνίας και Τιμής. Φαίνεται αυτό το διάγραμμα διασποράς να πρέπει απαραίτητα να αναλυθεί από μια ευθεία γραμμή; Δεν μπορούν οι τιμές να κυμαίνονται; Σε αυτή την περίπτωση, μπορείτε να δοκιμάσετε πολυωνυμική παλινδρόμηση.
✅ Οι πολυώνυμοι είναι μαθηματικές εκφράσεις που μπορεί να αποτελούνται από μία ή περισσότερες μεταβλητές και συντελεστές
Η πολυωνυμική παλινδρόμηση δημιουργεί μια καμπύλη γραμμή για να ταιριάξει καλύτερα τα μη γραμμικά δεδομένα. Στη δική μας περίπτωση, αν συμπεριλάβουμε την τετραγωνική μεταβλητή `DayOfYear` στα δεδομένα εισόδου, θα μπορούμε να προσαρμόσουμε τα δεδομένα μας με μια παραβολική καμπύλη, που θα έχει ένα ελάχιστο σε κάποιο σημείο μέσα στο έτος.
Το Scikit-learn περιλαμβάνει ένα χρήσιμο [pipeline API](https://scikit-learn.org/stable/modules/generated/sklearn.pipeline.make_pipeline.html?highlight=pipeline#sklearn.pipeline.make_pipeline) για να συνδυάσετε διάφορα βήματα της επεξεργασίας δεδομένων μαζί. Ένα **pipeline** είναι μια αλυσίδα **εκτιμητών (estimators)**. Στη δική μας περίπτωση, θα δημιουργήσουμε ένα pipeline που πρώτα προσθέτει πολυωνυμικά χαρακτηριστικά στο μοντέλο μας, και στη συνέχεια εκπαιδεύει την παλινδρόμηση:
```python
from sklearn.preprocessing import PolynomialFeatures
from sklearn.pipeline import make_pipeline
pipeline = make_pipeline(PolynomialFeatures(2), LinearRegression())
pipeline.fit(X_train,y_train)
```
Η χρήση του `PolynomialFeatures(2)` σημαίνει ότι θα συμπεριλάβουμε όλους τους πολυώνυμους δεύτερου βαθμού από τα δεδομένα εισόδου. Στη δική μας περίπτωση αυτό θα σημαίνει μόνο `DayOfYear`2, αλλά με δύο μεταβλητές εισόδου X και Y, αυτό θα προσθέσει X2, XY και Y2. Μπορούμε επίσης να χρησιμοποιήσουμε πολυώνυμους υψηλότερου βαθμού αν θέλουμε.
Τα pipelines μπορούν να χρησιμοποιηθούν με τον ίδιο τρόπο όπως το αρχικό αντικείμενο `LinearRegression`, δηλαδή μπορούμε να `fit` το pipeline και στη συνέχεια να χρησιμοποιήσουμε `predict` για να πάρουμε τα αποτελέσματα πρόβλεψης. Εδώ είναι το γράφημα που δείχνει τα δεδομένα δοκιμής και την καμπύλη προσέγγισης:
Χρησιμοποιώντας Πολυωνυμική Παλινδρόμηση, μπορούμε να πετύχουμε λίγο μικρότερο MSE και υψηλότερο συντελεστή προσδιορισμού, αλλά όχι σημαντικά. Πρέπει να λάβουμε υπόψη και άλλα χαρακτηριστικά!
> Μπορείτε να δείτε ότι οι ελάχιστες τιμές των κολοκυθών παρατηρούνται κάπου γύρω από το Halloween. Πώς μπορεί να το εξηγήσετε;
🎃 Συγχαρητήρια, μόλις δημιουργήσατε ένα μοντέλο που μπορεί να βοηθήσει στην πρόβλεψη της τιμής των κολοκυθών για πίτες. Μπορείτε πιθανώς να επαναλάβετε την ίδια διαδικασία για όλους τους τύπους κολοκύθας, αλλά αυτό θα ήταν κουραστικό. Ας μάθουμε τώρα πώς να λάβουμε υπόψη την ποικιλία κολοκύθας στο μοντέλο μας!
## Κατηγορικά Χαρακτηριστικά
Σε έναν ιδανικό κόσμο, θέλουμε να μπορούμε να προβλέψουμε τιμές για διαφορετικές ποικιλίες κολοκύθας χρησιμοποιώντας το ίδιο μοντέλο. Ωστόσο, η στήλη `Variety` διαφέρει κάπως από στήλες όπως το `Month`, επειδή περιέχει μη αριθμητικές τιμές. Τέτοιες στήλες λέγονται **κατηγορικές**.
[](https://youtu.be/DYGliioIAE0 "ML for beginners - Categorical Feature Predictions with Linear Regression")
> 🎥 Κάντε κλικ στην εικόνα παραπάνω για μια σύντομη βιντεοπαρουσίαση για τη χρήση κατηγορικών χαρακτηριστικών.
Εδώ μπορείτε να δείτε πώς η μέση τιμή εξαρτάται από την ποικιλία:
Για να λάβουμε υπόψη την ποικιλία, πρέπει πρώτα να την μετατρέψουμε σε αριθμητική μορφή ή να την **κωδικοποιήσουμε (encode)**. Υπάρχουν αρκετοί τρόποι να το κάνουμε:
* Η απλή **αριθμητική κωδικοποίηση** θα κατασκευάσει έναν πίνακα με τις διαφορετικές ποικιλίες και στη συνέχεια θα αντικαταστήσει το όνομα της ποικιλίας με ένα δείκτη σε αυτόν τον πίνακα. Αυτό δεν είναι η καλύτερη ιδέα για γραμμική παλινδρόμηση, επειδή αυτή παίρνει την πραγματική αριθμητική τιμή του δείκτη και την προσθέτει στο αποτέλεσμα, πολλαπλασιάζοντάς την με κάποιο συντελεστή. Στη δική μας περίπτωση, η σχέση μεταξύ του αριθμού του δείκτη και της τιμής είναι σαφώς μη γραμμική, ακόμα κι αν βεβαιωθούμε ότι οι δείκτες είναι ταξινομημένοι με κάποιο συγκεκριμένο τρόπο.
* Η **one-hot κωδικοποίηση** θα αντικαταστήσει τη στήλη `Variety` με 4 διαφορετικές στήλες, μία για κάθε ποικιλία. Κάθε στήλη θα περιέχει `1` αν η αντίστοιχη σειρά ανήκει σε εκείνη την ποικιλία, και `0` διαφορετικά. Αυτό σημαίνει ότι θα υπάρχουν τέσσερις συντελεστές στη γραμμική παλινδρόμηση, ένας για κάθε ποικιλία κολοκύθας, υπεύθυνος για την "αρχική τιμή" (ή μάλλον "πρόσθετη τιμή") για εκείνη την συγκεκριμένη ποικιλία.
Ο παρακάτω κώδικας δείχνει πώς μπορούμε να κάνουμε one-hot κωδικοποίηση σε μια ποικιλία:
```python
pd.get_dummies(new_pumpkins['Variety'])
```
ID | FAIRYTALE | MINIATURE | MIXED HEIRLOOM VARIETIES | PIE TYPE
----|-----------|-----------|--------------------------|----------
70 | 0 | 0 | 0 | 1
71 | 0 | 0 | 0 | 1
... | ... | ... | ... | ...
1738 | 0 | 1 | 0 | 0
1739 | 0 | 1 | 0 | 0
1740 | 0 | 1 | 0 | 0
1741 | 0 | 1 | 0 | 0
1742 | 0 | 1 | 0 | 0
Για να εκπαιδεύσουμε τη γραμμική παλινδρόμηση χρησιμοποιώντας την one-hot κωδικοποιημένη ποικιλία ως είσοδο, απλά πρέπει να αρχικοποιήσουμε σωστά τα δεδομένα `X` και `y`:
```python
X = pd.get_dummies(new_pumpkins['Variety'])
y = new_pumpkins['Price']
```
Το υπόλοιπο του κώδικα είναι το ίδιο με αυτό που χρησιμοποιήσαμε παραπάνω για να εκπαιδεύσουμε τη Γραμμική Παλινδρόμηση. Αν το δοκιμάσετε, θα δείτε ότι το μέσο τετραγωνικό σφάλμα είναι περίπου το ίδιο, αλλά ο συντελεστής προσδιορισμού αυξάνεται πολύ (~77%). Για να πάρουμε ακόμα πιο ακριβείς προβλέψεις, μπορούμε να λάβουμε υπόψη περισσότερα κατηγορικά χαρακτηριστικά, καθώς και αριθμητικά, όπως `Month` ή `DayOfYear`. Για να πάρουμε ένα μεγάλο πίνακα χαρακτηριστικών, μπορούμε να χρησιμοποιήσουμε τη `join`:
```python
X = pd.get_dummies(new_pumpkins['Variety']) \
.join(new_pumpkins['Month']) \
.join(pd.get_dummies(new_pumpkins['City'])) \
.join(pd.get_dummies(new_pumpkins['Package']))
y = new_pumpkins['Price']
```
Εδώ λαμβάνουμε επίσης υπόψη τον τύπο `City` και `Package`, που μας δίνει MSE 2.84 (10%) και συντελεστή προσδιορισμού 0.94!
## Όλα μαζί
Για να δημιουργήσουμε το καλύτερο μοντέλο, μπορούμε να χρησιμοποιήσουμε συνδυασμένα δεδομένα (one-hot κωδικοποιημένα κατηγορικά + αριθμητικά) από το παραπάνω παράδειγμα μαζί με την Πολυωνυμική Παλινδρόμηση. Εδώ είναι ο πλήρης κώδικας για τη διευκόλυνσή σας:
```python
# ρύθμιση δεδομένων εκπαίδευσης
X = pd.get_dummies(new_pumpkins['Variety']) \
.join(new_pumpkins['Month']) \
.join(pd.get_dummies(new_pumpkins['City'])) \
.join(pd.get_dummies(new_pumpkins['Package']))
y = new_pumpkins['Price']
# δημιουργία διαχωρισμού εκπαίδευσης-δοκιμής
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)
# ρύθμιση και εκπαίδευση της αλυσίδας επεξεργασίας
pipeline = make_pipeline(PolynomialFeatures(2), LinearRegression())
pipeline.fit(X_train,y_train)
# πρόβλεψη αποτελεσμάτων για δεδομένα δοκιμής
pred = pipeline.predict(X_test)
# υπολογισμός MSE και συντελεστή προσδιορισμού
mse = np.sqrt(mean_squared_error(y_test,pred))
print(f'Mean error: {mse:3.3} ({mse/np.mean(pred)*100:3.3}%)')
score = pipeline.score(X_train,y_train)
print('Model determination: ', score)
```
Αυτό θα μας δώσει τον καλύτερο συντελεστή προσδιορισμού σχεδόν 97%, και MSE=2.23 (~8% σφάλμα πρόβλεψης).
| Μοντέλο | MSE | Συντελεστής προσδιορισμού |
|-------|-----|---------------|
| Γραμμική με `DayOfYear` | 2.77 (17.2%) | 0.07 |
| Πολυωνυμική με `DayOfYear` | 2.73 (17.0%) | 0.08 |
| Γραμμική με `Variety` | 5.24 (19.7%) | 0.77 |
| Όλα τα χαρακτηριστικά Γραμμική | 2.84 (10.5%) | 0.94 |
| Όλα τα χαρακτηριστικά Πολυωνυμική | 2.23 (8.25%) | 0.97 |
🏆 Μπράβο! Δημιουργήσατε τέσσερα μοντέλα παλινδρόμησης σε ένα μάθημα, και βελτιώσατε την ποιότητα του μοντέλου στο 97%. Στην τελική ενότητα για την Παλινδρόμηση θα μάθετε για τη Λογιστική Παλινδρόμηση για να προσδιορίσετε κατηγορίες.
---
## 🚀Πρόκληση
Δοκιμάστε διάφορες μεταβλητές σε αυτό το σημειωματάριο για να δείτε πώς η συσχέτιση αντιστοιχεί στην ακρίβεια του μοντέλου.
## [Κουίζ μετά το μάθημα](https://ff-quizzes.netlify.app/en/ml/)
## Επανάληψη & Αυτοεκπαίδευση
Σε αυτό το μάθημα μάθαμε για τη Γραμμική Παλινδρόμηση. Υπάρχουν κι άλλοι σημαντικοί τύποι Παλινδρόμησης. Διαβάστε για τις τεχνικές Stepwise, Ridge, Lasso και Elasticnet. Ένα καλό μάθημα για μελέτη είναι το [Stanford Statistical Learning course](https://online.stanford.edu/courses/sohs-ystatslearning-statistical-learning)
## Καθήκον
[Δημιουργήστε ένα Μοντέλο](assignment.md)
---
**Αποποίηση Ευθύνης**:
Αυτό το έγγραφο έχει μεταφραστεί χρησιμοποιώντας την υπηρεσία αυτόματης μετάφρασης AI [Co-op Translator](https://github.com/Azure/co-op-translator). Ενώ καταβάλλουμε προσπάθεια για ακρίβεια, παρακαλούμε να έχετε υπόψη ότι οι αυτόματες μεταφράσεις ενδέχεται να περιέχουν λάθη ή ανακρίβειες. Το πρωτότυπο έγγραφο στη γλώσσα του θεωρείται η αυθεντική πηγή. Για κρίσιμες πληροφορίες, συνιστάται επαγγελματική ανθρώπινη μετάφραση. Δεν φέρουμε ευθύνη για τυχόν παρεξηγήσεις ή λανθασμένες ερμηνείες που προκύπτουν από τη χρήση αυτής της μετάφρασης.