Εισαγωγή
Μερικές φορές συγχέεται με γραμμικής παλινδρόμησης από αρχάριους – λόγω κοινής χρήσης του όρου οπισθοδρόμηση - λογική παλινδρόμηση είναι πολύ διαφορετικό από γραμμικής παλινδρόμησης. Ενώ η γραμμική παλινδρόμηση προβλέπει τιμές όπως 2, 2.45, 6.77 ή συνεχείς τιμές, καθιστώντας το οπισθοδρόμηση αλγόριθμος, λογική παλινδρόμηση προβλέπει τιμές όπως 0 ή 1, 1 ή 2 ή 3, που είναι διακριτές τιμές, καθιστώντας το ταξινόμηση αλγόριθμος. Ναι, λέγεται οπισθοδρόμηση αλλά είναι ένα ταξινόμηση αλγόριθμος. Περισσότερα για αυτό σε μια στιγμή.
Επομένως, εάν το πρόβλημα της επιστήμης δεδομένων σας περιλαμβάνει συνεχείς τιμές, μπορείτε να εφαρμόσετε α οπισθοδρόμηση αλγόριθμος (η γραμμική παλινδρόμηση είναι ένα από αυτά). Διαφορετικά, εάν περιλαμβάνει ταξινόμηση εισόδων, διακριτών τιμών ή κλάσεων, μπορείτε να εφαρμόσετε ένα ταξινόμηση αλγόριθμος (η λογιστική παλινδρόμηση είναι ένα από αυτά).
Σε αυτόν τον οδηγό, θα εκτελούμε λογιστική παλινδρόμηση στην Python με τη βιβλιοθήκη Scikit-Learn. Θα εξηγήσουμε επίσης γιατί η λέξη "οπισθοδρόμηση" υπάρχει στο όνομα και πώς λειτουργεί η λογιστική παλινδρόμηση.
Για να γίνει αυτό, θα φορτώσουμε πρώτα δεδομένα που θα ταξινομηθούν, θα οπτικοποιηθούν και θα υποβληθούν σε προεπεξεργασία. Στη συνέχεια, θα δημιουργήσουμε ένα μοντέλο λογιστικής παλινδρόμησης που θα κατανοεί αυτά τα δεδομένα. Αυτό το μοντέλο στη συνέχεια θα αξιολογηθεί και θα χρησιμοποιηθεί για την πρόβλεψη τιμών με βάση νέα δεδομένα.
Κινητοποίηση
Η εταιρεία στην οποία εργάζεστε έκανε μια συνεργασία με μια τουρκική γεωργική φάρμα. Αυτή η συνεργασία περιλαμβάνει την πώληση σπόρων κολοκύθας. Οι σπόροι κολοκύθας είναι πολύ σημαντικοί για τη διατροφή του ανθρώπου. Περιέχουν μια καλή αναλογία υδατανθράκων, λίπους, πρωτεΐνης, ασβεστίου, καλίου, φωσφόρου, μαγνησίου, σιδήρου και ψευδαργύρου.
Στην ομάδα της επιστήμης δεδομένων, το καθήκον σας είναι να πείτε τη διαφορά μεταξύ των τύπων σπόρων κολοκύθας χρησιμοποιώντας μόνο δεδομένα – ή ταξινόμηση τα δεδομένα ανάλογα με τον τύπο του σπόρου.
Η τουρκική φάρμα λειτουργεί με δύο τύπους σπόρων κολοκύθας, ο ένας ονομάζεται Çerçevelik και το άλλο Ürgüp Sivrisi.
Για να ταξινομήσετε τους σπόρους κολοκύθας, η ομάδα σας ακολούθησε το έγγραφο του 2021 «Η χρήση μεθόδων μηχανικής μάθησης στην ταξινόμηση των σπόρων κολοκύθας (Cucurbita pepo L.). Γενετικοί πόροι και εξέλιξη των καλλιεργειών» από τους Koklu, Sarigil και Ozbek – σε αυτό το άρθρο, υπάρχει μια μεθοδολογία για τη φωτογράφηση και την εξαγωγή των μετρήσεων των σπόρων από τις εικόνες.
Μετά την ολοκλήρωση της διαδικασίας που περιγράφεται στην εργασία, εξήχθησαν οι ακόλουθες μετρήσεις:
- Περιοχή – ο αριθμός των pixel εντός των ορίων ενός κολοκυθόσπορου
- Περίμετρος – η περιφέρεια σε pixel ενός κολοκυθόσπορου
- Μήκος κύριου άξονα – επίσης η περιφέρεια σε pixel ενός κολοκυθόσπορου
- Μήκος δευτερεύοντος άξονα – η μικρή απόσταση άξονα ενός κολοκυθόσπορου
- Εκκεντρικότητα – η εκκεντρικότητα ενός κολοκυθόσπορου
- Κυρτή Περιοχή – ο αριθμός των εικονοστοιχείων του μικρότερου κυρτού κελύφους στην περιοχή που σχηματίζει ο σπόρος κολοκύθας
- Εκταση – η αναλογία μιας επιφάνειας σπόρων κολοκύθας προς τα εικονοστοιχεία οριοθέτησης του κουτιού
- Ισοδύναμη διάμετρος – η τετραγωνική ρίζα του πολλαπλασιασμού του εμβαδού του κολοκυθόσπορου με το τέσσερα διαιρούμενο με το pi
- Συμπαγές – η αναλογία του εμβαδού του κολοκυθόσπορου σε σχέση με το εμβαδόν του κύκλου με την ίδια περιφέρεια
- Στερεότητα – την κυρτή και κυρτή κατάσταση των κολοκυθόσπορων
- Στρογγυλότητα – την ωοειδότητα των σπόρων κολοκύθας χωρίς να ληφθούν υπόψη οι παραμορφώσεις των άκρων τους
- Λόγος διαστάσεων – η αναλογία διαστάσεων των σπόρων κολοκύθας
Αυτές είναι οι μετρήσεις με τις οποίες πρέπει να δουλέψετε. Εκτός από τις μετρήσεις, υπάρχει και το Τάξη ετικέτα για τους δύο τύπους σπόρων κολοκύθας.
Για να ξεκινήσουμε την ταξινόμηση των σπόρων, ας εισαγάγουμε τα δεδομένα και ας αρχίσουμε να τα εξετάζουμε.
Κατανόηση του συνόλου δεδομένων
Σημείωση: Μπορείτε να κατεβάσετε το σύνολο δεδομένων κολοκύθας εδώ.
Αφού κατεβάσουμε το σύνολο δεδομένων, μπορούμε να το φορτώσουμε σε μια δομή πλαισίου δεδομένων χρησιμοποιώντας το pandas
βιβλιοθήκη. Εφόσον πρόκειται για αρχείο excel, θα χρησιμοποιήσουμε το read_excel()
μέθοδος:
import pandas as pd
fpath = 'dataset/pumpkin_seeds_dataset.xlsx'
df = pd.read_excel(fpath)
Μόλις φορτωθούν τα δεδομένα, μπορούμε να ρίξουμε μια γρήγορη ματιά στις πρώτες 5 σειρές χρησιμοποιώντας το head()
μέθοδος:
df.head()
Αυτο εχει ως αποτελεσμα:
Area Perimeter Major_Axis_Length Minor_Axis_Length Convex_Area Equiv_Diameter Eccentricity Solidity Extent Roundness Aspect_Ration Compactness Class
0 56276 888.242 326.1485 220.2388 56831 267.6805 0.7376 0.9902 0.7453 0.8963 1.4809 0.8207 Çerçevelik
1 76631 1068.146 417.1932 234.2289 77280 312.3614 0.8275 0.9916 0.7151 0.8440 1.7811 0.7487 Çerçevelik
2 71623 1082.987 435.8328 211.0457 72663 301.9822 0.8749 0.9857 0.7400 0.7674 2.0651 0.6929 Çerçevelik
3 66458 992.051 381.5638 222.5322 67118 290.8899 0.8123 0.9902 0.7396 0.8486 1.7146 0.7624 Çerçevelik
4 66107 998.146 383.8883 220.4545 67117 290.1207 0.8187 0.9850 0.6752 0.8338 1.7413 0.7557 Çerçevelik
Εδώ, έχουμε όλες τις μετρήσεις στις αντίστοιχες στήλες τους, μας χαρακτηριστικά, και επίσης το Τάξη στήλη, μας στόχος, το οποίο είναι το τελευταίο στο πλαίσιο δεδομένων. Μπορούμε να δούμε πόσες μετρήσεις έχουμε χρησιμοποιώντας το shape
Χαρακτηριστικό:
df.shape
Η έξοδος είναι:
(2500, 13)
Το αποτέλεσμα του σχήματος μας λέει ότι υπάρχουν 2500 καταχωρήσεις (ή σειρές) στο σύνολο δεδομένων και 13 στήλες. Εφόσον γνωρίζουμε ότι υπάρχει μία στήλη-στόχος – αυτό σημαίνει ότι έχουμε 12 στήλες χαρακτηριστικών.
Μπορούμε τώρα να εξερευνήσουμε τη μεταβλητή στόχο, τον κολοκυθόσπορο Class
. Εφόσον θα προβλέψουμε αυτή τη μεταβλητή, είναι ενδιαφέρον να δούμε πόσα δείγματα από κάθε σπόρο κολοκύθας έχουμε. Συνήθως, όσο μικρότερη είναι η διαφορά μεταξύ του αριθμού των περιπτώσεων στις τάξεις μας, τόσο πιο ισορροπημένο είναι το δείγμα μας και τόσο καλύτερες οι προβλέψεις μας.
Αυτή η επιθεώρηση μπορεί να γίνει μετρώντας κάθε δείγμα σπόρου με το value_counts()
μέθοδος:
df['Class'].value_counts()
Ο παραπάνω κωδικός εμφανίζει:
Çerçevelik 1300
Ürgüp Sivrisi 1200
Name: Class, dtype: int64
Μπορούμε να δούμε ότι υπάρχουν 1300 δείγματα του Çerçevelik σπόρους και 1200 δείγματα του Ürgüp Sivrisi σπόρος. Παρατηρήστε ότι η διαφορά μεταξύ τους είναι 100 δείγματα, μια πολύ μικρή διαφορά, η οποία είναι καλή για εμάς και δείχνει ότι δεν χρειάζεται να εξισορροπηθεί εκ νέου ο αριθμός των δειγμάτων.
Ας δούμε επίσης τα περιγραφικά στατιστικά των χαρακτηριστικών μας με το describe()
μέθοδο για να δείτε πόσο καλά είναι κατανεμημένα τα δεδομένα. Θα μεταφέρουμε επίσης τον πίνακα που προκύπτει με T
για να διευκολυνθεί η σύγκριση μεταξύ των στατιστικών:
df.describe().T
Ο πίνακας που προκύπτει είναι:
count mean std min 25% 50% 75% max
Area 2500.0 80658.220800 13664.510228 47939.0000 70765.000000 79076.00000 89757.500000 136574.0000
Perimeter 2500.0 1130.279015 109.256418 868.4850 1048.829750 1123.67200 1203.340500 1559.4500
Major_Axis_Length 2500.0 456.601840 56.235704 320.8446 414.957850 449.49660 492.737650 661.9113
Minor_Axis_Length 2500.0 225.794921 23.297245 152.1718 211.245925 224.70310 240.672875 305.8180
Convex_Area 2500.0 81508.084400 13764.092788 48366.0000 71512.000000 79872.00000 90797.750000 138384.0000
Equiv_Diameter 2500.0 319.334230 26.891920 247.0584 300.167975 317.30535 338.057375 417.0029
Eccentricity 2500.0 0.860879 0.045167 0.4921 0.831700 0.86370 0.897025 0.9481
Solidity 2500.0 0.989492 0.003494 0.9186 0.988300 0.99030 0.991500 0.9944
Extent 2500.0 0.693205 0.060914 0.4680 0.658900 0.71305 0.740225 0.8296
Roundness 2500.0 0.791533 0.055924 0.5546 0.751900 0.79775 0.834325 0.9396
Aspect_Ration 2500.0 2.041702 0.315997 1.1487 1.801050 1.98420 2.262075 3.1444
Compactness 2500.0 0.704121 0.053067 0.5608 0.663475 0.70770 0.743500 0.9049
Βλέποντας τον πίνακα, κατά τη σύγκριση των εννοώ και τυπική απόκλιση (std
) στήλες, μπορεί να φανεί ότι τα περισσότερα χαρακτηριστικά έχουν μέσο όρο που απέχει πολύ από την τυπική απόκλιση. Αυτό δείχνει ότι οι τιμές δεδομένων δεν συγκεντρώνονται γύρω από τη μέση τιμή, αλλά είναι πιο διάσπαρτες γύρω από αυτήν – με άλλα λόγια, έχουν υψηλή μεταβλητότητα.
Επίσης, όταν κοιτάτε το ελάχιστο (min
) Και ανώτατο όριο (max
) στήλες, ορισμένα χαρακτηριστικά, όπως π.χ Area
, να Convex_Area
, έχουν μεγάλες διαφορές μεταξύ ελάχιστων και μέγιστων τιμών. Αυτό σημαίνει ότι αυτές οι στήλες έχουν πολύ μικρά δεδομένα και επίσης πολύ μεγάλες τιμές δεδομένων, ή υψηλότερο πλάτος μεταξύ των τιμών δεδομένων.
Με υψηλή μεταβλητότητα, υψηλό πλάτος και χαρακτηριστικά με διαφορετικές μονάδες μέτρησης, τα περισσότερα από τα δεδομένα μας θα επωφεληθούν από την ύπαρξη της ίδιας κλίμακας για όλα τα χαρακτηριστικά ή λεπιδωτός. Η κλιμάκωση δεδομένων θα επικεντρώσει τα δεδομένα γύρω από τη μέση τιμή και θα μειώσει τη διακύμανσή τους.
Αυτό το σενάριο πιθανώς υποδεικνύει επίσης ότι υπάρχουν ακραίες τιμές και ακραίες τιμές στα δεδομένα. Επομένως, είναι καλύτερο να έχετε μερικά ακραία θεραπεία εκτός από την κλιμάκωση των δεδομένων.
Υπάρχουν μερικοί αλγόριθμοι μηχανικής μάθησης, για παράδειγμα, αλγόριθμοι που βασίζονται σε δέντρα όπως π.χ Τυχαία Ταξινόμηση Δασών, που δεν επηρεάζονται από υψηλή διακύμανση δεδομένων, ακραίες τιμές και ακραίες τιμές. Λογιστική παλινδρόμηση είναι διαφορετική, βασίζεται σε μια συνάρτηση που κατηγοριοποιεί τις τιμές μας και οι παράμετροι αυτής της συνάρτησης μπορούν να επηρεαστούν από τιμές που είναι εκτός της γενικής τάσης δεδομένων και έχουν υψηλή διακύμανση.
Θα καταλάβουμε περισσότερα για την υλικοτεχνική παλινδρόμηση σε λίγο όταν την εφαρμόσουμε. Προς το παρόν, μπορούμε να συνεχίσουμε να εξερευνούμε τα δεδομένα μας.
Σημείωση: Υπάρχει ένα δημοφιλές ρητό στην Επιστήμη των Υπολογιστών: «Σκουπίδια μέσα, σκουπίδια έξω» (GIGO), που είναι κατάλληλο για μηχανική μάθηση. Αυτό σημαίνει ότι όταν έχουμε δεδομένα σκουπιδιών - μετρήσεις που δεν περιγράφουν τα φαινόμενα από μόνα τους, δεδομένα που δεν έγιναν κατανοητά και δεν προετοιμάστηκαν καλά σύμφωνα με το είδος του αλγορίθμου ή του μοντέλου, πιθανότατα θα δημιουργήσουν ένα εσφαλμένο αποτέλεσμα που δεν θα λειτουργήσει καθημερινή βάση.
Αυτός είναι ένας από τους λόγους για τους οποίους η εξερεύνηση, η κατανόηση δεδομένων και ο τρόπος λειτουργίας του επιλεγμένου μοντέλου είναι τόσο σημαντική. Κάνοντας αυτό, μπορούμε να αποφύγουμε να βάλουμε σκουπίδια στο μοντέλο μας – αντ' αυτού, δίνουμε αξία σε αυτό και κερδίζουμε αξία.
Οπτικοποίηση των Δεδομένων
Μέχρι τώρα, με τα περιγραφικά στατιστικά στοιχεία, έχουμε ένα κάπως αφηρημένο στιγμιότυπο ορισμένων ποιοτήτων των δεδομένων. Ένα άλλο σημαντικό βήμα είναι να το οπτικοποιήσουμε και να επιβεβαιώσουμε την υπόθεσή μας για υψηλή διακύμανση, πλάτος και ακραίες τιμές. Για να δούμε αν αυτό που έχουμε παρατηρήσει μέχρι τώρα φαίνεται στα δεδομένα, μπορούμε να σχεδιάσουμε μερικά γραφήματα.
Είναι επίσης ενδιαφέρον να δούμε πώς σχετίζονται τα χαρακτηριστικά με τις δύο κατηγορίες που θα προβλεφθούν. Για να γίνει αυτό, ας εισάγουμε το seaborn
συσκευάστε και χρησιμοποιήστε το pairplot
γράφημα για να δείτε κάθε κατανομή χαρακτηριστικών και κάθε διαχωρισμό κλάσεων ανά χαρακτηριστικό:
import seaborn as sns
sns.pairplot(data=df, hue='Class')
Σημείωση: Ο παραπάνω κώδικας μπορεί να χρειαστεί λίγο χρόνο για να εκτελεστεί, καθώς το ζεύγος γραφήματος συνδυάζει γραφήματα διασποράς όλων των χαρακτηριστικών (μπορεί) και εμφανίζει επίσης τις κατανομές χαρακτηριστικών.
Κοιτάζοντας το pairplot, μπορούμε να δούμε ότι στις περισσότερες περιπτώσεις τα σημεία του Çerçevelik
τάξη διαχωρίζονται σαφώς από τα σημεία του Ürgüp Sivrisi
τάξη. Είτε τα σημεία μιας κατηγορίας είναι προς τα δεξιά όταν τα άλλα είναι αριστερά, είτε μερικά είναι επάνω ενώ τα άλλα είναι κάτω. Εάν χρησιμοποιούσαμε κάποιο είδος καμπύλης ή γραμμής για να διαχωρίσουμε τις κλάσεις, αυτό δείχνει ότι είναι ευκολότερο να τις διαχωρίσουμε, αν ήταν μικτές, η ταξινόμηση θα ήταν πιο δύσκολη υπόθεση.
Στο Eccentricity
, Compactness
και Aspect_Ration
στήλες, ορισμένα σημεία που είναι «απομονωμένα» ή αποκλίνουν από τη γενική τάση των δεδομένων – ακραίες τιμές – εντοπίζονται επίσης εύκολα.
Όταν κοιτάτε τη διαγώνιο από πάνω αριστερά προς τα κάτω δεξιά του γραφήματος, παρατηρήστε ότι οι κατανομές δεδομένων είναι επίσης χρωματικά κωδικοποιημένες σύμφωνα με τις τάξεις μας. Τα σχήματα κατανομής και η απόσταση μεταξύ των δύο καμπυλών είναι άλλοι δείκτες του πόσο διαχωρίσιμες είναι – όσο πιο μακριά το ένα από το άλλο, τόσο το καλύτερο. Στις περισσότερες περιπτώσεις, δεν υπερτίθενται, πράγμα που σημαίνει ότι είναι ευκολότερο να διαχωριστούν, συμβάλλοντας επίσης στο έργο μας.
Στη σειρά, μπορούμε επίσης να σχεδιάσουμε τα τετραγωνίδια όλων των μεταβλητών με το sns.boxplot()
μέθοδος. Τις περισσότερες φορές, είναι χρήσιμο να προσανατολίζονται τα τετραγωνίδια οριζόντια, έτσι ώστε τα σχήματα των τετραγωνιδίων να είναι ίδια με τα σχήματα διανομής, μπορούμε να το κάνουμε αυτό με το orient
διαφωνία:
sns.boxplot(data=df, orient='h')
Στην παραπάνω πλοκή, παρατηρήστε ότι Area
και Convex_Area
έχουν τόσο μεγάλο μέγεθος σε σύγκριση με τα μεγέθη των άλλων στηλών, που συμπιέζουν τα άλλα κουτιά. Για να μπορέσουμε να δούμε όλα τα κουτιά, μπορούμε να κλιμακώσουμε τα χαρακτηριστικά και να τα σχεδιάσουμε ξανά.
Πριν το κάνουμε αυτό, ας καταλάβουμε απλώς ότι εάν υπάρχουν τιμές χαρακτηριστικών που σχετίζονται στενά με άλλες τιμές, για παράδειγμα – εάν υπάρχουν τιμές που γίνονται επίσης μεγαλύτερες όταν οι τιμές άλλων χαρακτηριστικών γίνονται μεγαλύτερες, θετική συσχέτιση; ή αν υπάρχουν τιμές που κάνουν το αντίθετο, μικραίνουν ενώ άλλες τιμές γίνονται μικρότερες, έχοντας a Αρνητική συσχέτιση.
Αυτό είναι σημαντικό να το εξετάσουμε, επειδή η ύπαρξη ισχυρών σχέσεων στα δεδομένα μπορεί να σημαίνει ότι ορισμένες στήλες προέρχονται από άλλες στήλες ή έχουν παρόμοια σημασία με το μοντέλο μας. Όταν συμβεί αυτό, τα αποτελέσματα του μοντέλου μπορεί να υπερεκτιμηθούν και θέλουμε αποτελέσματα πιο κοντά στην πραγματικότητα. Εάν υπάρχουν ισχυροί συσχετισμοί, σημαίνει επίσης ότι μπορούμε να μειώσουμε τον αριθμό των χαρακτηριστικών και να χρησιμοποιήσουμε λιγότερες στήλες κάνοντας το μοντέλο περισσότερο φειδωλός.
Σημείωση: Η προεπιλεγμένη συσχέτιση υπολογίστηκε με το corr()
μέθοδος είναι η Συντελεστής συσχέτισης Pearson. Αυτός ο συντελεστής υποδεικνύεται όταν τα δεδομένα είναι ποσοτικά, κανονικά κατανεμημένα, δεν έχουν ακραίες τιμές και έχουν γραμμική σχέση.
Μια άλλη επιλογή θα ήταν ο υπολογισμός Συντελεστής συσχέτισης Spearman. Ο συντελεστής Spearman χρησιμοποιείται όταν τα δεδομένα είναι τακτικά, μη γραμμικά, έχουν οποιαδήποτε κατανομή και έχουν ακραίες τιμές. Παρατηρήστε ότι τα δεδομένα μας δεν ταιριάζουν απόλυτα με τις υποθέσεις του Pearson ή του Spearman (υπάρχουν επίσης περισσότερες μέθοδοι συσχέτισης, όπως η Kendall's). Δεδομένου ότι τα δεδομένα μας είναι ποσοτικά και είναι σημαντικό για εμάς να μετρήσουμε τη γραμμική τους σχέση, θα χρησιμοποιήσουμε τον συντελεστή Pearson.
Ας ρίξουμε μια ματιά στις συσχετίσεις μεταξύ των μεταβλητών και, στη συνέχεια, μπορούμε να προχωρήσουμε στην προεπεξεργασία των δεδομένων. Θα υπολογίσουμε τις συσχετίσεις με το corr()
μέθοδο και οπτικοποιήστε τα με Seaborn's heatmap()
. Το τυπικό μέγεθος του χάρτη θερμότητας τείνει να είναι μικρό, επομένως θα εισάγουμε matplotlib
(γενική μηχανή οπτικοποίησης/βιβλιοθήκη στην οποία είναι χτισμένο το Seaborn) και αλλάξτε το μέγεθος με figsize
:
import matplotlib.pyplot as plt
plt.figure(figsize=(15, 10))
correlations = df.corr()
sns.heatmap(correlations, annot=True)
Σε αυτόν τον χάρτη θερμότητας, οι τιμές που είναι πιο κοντά στο 1 ή στο -1 είναι οι τιμές που πρέπει να προσέξουμε. Η πρώτη περίπτωση, υποδηλώνει υψηλή θετική συσχέτιση και η δεύτερη, υψηλή αρνητική συσχέτιση. Και οι δύο τιμές, αν όχι πάνω από 0.8 ή -0.8 θα είναι ευεργετικές για το μοντέλο λογιστικής παλινδρόμησης.
Όταν υπάρχουν υψηλοί συσχετισμοί όπως αυτός των 0.99
μεταξύ Aspec_Ration
και Compactness
, αυτό σημαίνει ότι μπορούμε να επιλέξουμε να χρησιμοποιήσουμε μόνο Aspec_Ration
ή μόνο Compactness
, αντί και για τα δύο (αφού ήταν σχεδόν ίσα προβλέψεις ο ένας του άλλου). Το ίδιο ισχύει και για Eccentricity
και Compactness
με -0.98
συσχέτιση, για Area
και Perimeter
με 0.94
συσχέτιση και μερικές άλλες στήλες.
Προεπεξεργασία των Δεδομένων
Επειδή έχουμε ήδη εξερευνήσει τα δεδομένα για λίγο, μπορούμε να ξεκινήσουμε την προεπεξεργασία τους. Προς το παρόν, ας χρησιμοποιήσουμε όλες τις δυνατότητες για την πρόβλεψη κλάσης. Αφού λάβουμε ένα πρώτο μοντέλο, μια γραμμή βάσης, μπορούμε στη συνέχεια να αφαιρέσουμε μερικές από τις στήλες υψηλής συσχέτισης και να τις συγκρίνουμε με τη γραμμή βάσης.
Οι στήλες χαρακτηριστικών θα είναι δικές μας X
δεδομένα και η στήλη κλάσης, μας y
δεδομένα στόχου:
y = df['Class']
X = df.drop(columns=['Class'], axis=1)
Μετατροπή κατηγορικών χαρακτηριστικών σε αριθμητικά χαρακτηριστικά
Σχετικά με το δικό μας Class
στήλη – οι τιμές της δεν είναι αριθμοί, αυτό σημαίνει ότι πρέπει επίσης να τις μετατρέψουμε. Υπάρχουν πολλοί τρόποι για να γίνει αυτός ο μετασχηματισμός. εδώ, θα χρησιμοποιήσουμε το replace()
μέθοδος και αντικατάσταση Çerçevelik
προς την 0
και Ürgüp Sivrisi
προς την 1
.
y = y.replace('Çerçevelik', 0).replace('Ürgüp Sivrisi', 1)
Έχετε υπόψη σας τη χαρτογράφηση! Όταν διαβάζετε αποτελέσματα από το μοντέλο σας, θα θέλετε να τα μετατρέψετε ξανά τουλάχιστον στο μυαλό σας ή ξανά στο όνομα της τάξης για άλλους χρήστες.
Διαίρεση δεδομένων σε σύνολα τρένου και δοκιμών
Στην εξερεύνηση μας, σημειώσαμε ότι τα χαρακτηριστικά χρειάζονταν κλιμάκωση. Εάν κάναμε την κλιμάκωση τώρα, ή με αυτόματο τρόπο, θα κλιμακώναμε τις τιμές με το σύνολο του X
και y
. Σε αυτή την περίπτωση, θα εισάγαμε διαρροή δεδομένων, καθώς οι τιμές του συνόλου δοκιμής που θα είναι σύντομα θα είχαν επηρεάσει την κλιμάκωση. Η διαρροή δεδομένων είναι μια κοινή αιτία μη αναπαραγώγιμων αποτελεσμάτων και απατηλής υψηλής απόδοσης των μοντέλων ML.
Η σκέψη για την κλιμάκωση δείχνει ότι πρέπει πρώτα να χωρίσουμε X
και y
δεδομένα περαιτέρω στα σετ αμαξοστοιχίας και δοκιμών και στη συνέχεια σε ταιριάζουν ένα scaler στο σετ εκπαίδευσης, και να μετατρέψουν τόσο το σετ αμαξοστοιχίας όσο και το σετ δοκιμών (χωρίς ποτέ το σετ δοκιμής να επηρεάσει τον κλιμακωτή που το κάνει αυτό). Για αυτό, θα χρησιμοποιήσουμε το Scikit-Learn's train_test_split()
μέθοδος:
from sklearn.model_selection import train_test_split
SEED = 42
X_train, X_test, y_train, y_test = train_test_split(X, y,
test_size=.25,
random_state=SEED)
Ρύθμιση test_size=.25
διασφαλίζει ότι χρησιμοποιούμε το 25% των δεδομένων για δοκιμές και το 75% για την εκπαίδευση. Αυτό θα μπορούσε να παραλειφθεί, αφού είναι ο προεπιλεγμένος διαχωρισμός, αλλά το Pythonic Ο τρόπος για να γράψετε κώδικα συμβουλεύει ότι το να είσαι "σαφής είναι καλύτερο από το σιωπηρό".
Σημείωση: Η πρόταση "το ρητό είναι καλύτερο από το σιωπηρό" είναι μια αναφορά σε Το Ζεν της Πύθωνή PEP20. Δίνει μερικές προτάσεις για τη σύνταξη κώδικα Python. Εάν ακολουθηθούν αυτές οι προτάσεις, λαμβάνεται υπόψη ο κωδικός Pythonic. Μπορείτε να μάθετε περισσότερα για αυτό εδώ.
Αφού χωρίσετε τα δεδομένα σε σετ αμαξοστοιχίας και δοκιμών, είναι καλή πρακτική να εξετάσετε πόσες εγγραφές υπάρχουν σε κάθε σετ. Αυτό μπορεί να γίνει με το shape
Χαρακτηριστικό:
X_train.shape, X_test.shape, y_train.shape, y_test.shape
Αυτό εμφανίζει:
((1875, 12), (625, 12), (1875,), (625,))
Μπορούμε να δούμε ότι μετά τη διάσπαση, έχουμε 1875 αρχεία για εκπαίδευση και 625 για δοκιμές.
Κλιμάκωση δεδομένων
Μόλις έχουμε έτοιμα τα σετ τρένων και δοκιμών, μπορούμε να προχωρήσουμε στην κλιμάκωση των δεδομένων με το Scikit-Learn StandardScaler
αντικείμενο (ή άλλους κλιμακωτές που παρέχονται από τη βιβλιοθήκη). Για να αποφευχθεί η διαρροή, το scaler τοποθετείται στο X_train
Τα δεδομένα και οι τιμές αμαξοστοιχίας χρησιμοποιούνται στη συνέχεια για την κλίμακα – ή τον μετασχηματισμό – τόσο της αμαξοστοιχίας όσο και των δεδομένων δοκιμής:
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)
Επειδή συνήθως καλείτε:
scaler.fit(X_train)
X_train = scaler.transform(X_train)
X_test = scaler.transform(X_test)
Οι δύο πρώτες γραμμές μπορούν να συμπτυχθούν με έναν ενικό fit_transform()
κλήση, που ταιριάζει στο scaler στο σετ και το μεταμορφώνει με μία κίνηση. Μπορούμε τώρα να αναπαράγουμε τα γραφήματα του πλαισίου για να δούμε τη διαφορά μετά την κλιμάκωση των δεδομένων.
Λαμβάνοντας υπόψη ότι η κλιμάκωση αφαιρεί τα ονόματα στηλών, πριν από τη γραφική παράσταση, μπορούμε να οργανώσουμε τα δεδομένα αμαξοστοιχίας σε ένα πλαίσιο δεδομένων με ονόματα στηλών ξανά για να διευκολύνουμε την οπτικοποίηση:
column_names = df.columns[:12]
X_train = pd.DataFrame(X_train, columns=column_names)
sns.boxplot(data=X_train, orient='h')
Μπορούμε επιτέλους να δούμε όλα τα κουτιά μας! Παρατηρήστε ότι όλα έχουν ακραίες τιμές και τα χαρακτηριστικά που παρουσιάζουν μια κατανομή πιο μακριά από την κανονική (που έχουν καμπύλες λοξές είτε προς τα αριστερά είτε προς τα δεξιά), όπως π.χ. Solidity
, Extent
, Aspect_Ration
, να Compactedness
, είναι τα ίδια που είχαν υψηλότερους συσχετισμούς.
Αφαίρεση ακραίων στοιχείων με τη μέθοδο IQR
Γνωρίζουμε ήδη ότι η λογιστική παλινδρόμηση μπορεί να επηρεαστεί από ακραίες τιμές. Ένας από τους τρόπους αντιμετώπισής τους είναι να χρησιμοποιήσετε μια μέθοδο που ονομάζεται Διατεταρτημοριακό εύρος or I.Q.R.. Το αρχικό βήμα της μεθόδου IQR είναι να χωρίσουμε τα δεδομένα του τρένου μας σε τέσσερα μέρη, που ονομάζονται τεταρτημόρια. Το πρώτο τεταρτημόριο, Q1, ανέρχεται στο 25% των δεδομένων, το δεύτερο, Q2, στο 50%, το τρίτο, Q3, στο 75%, και το τελευταίο, Q4, στο 100%. Τα κουτιά στο boxplot ορίζονται με τη μέθοδο IQR και αποτελούν οπτική αναπαράστασή της.
Λαμβάνοντας υπόψη ένα οριζόντιο διάγραμμα πλαισίου, η κάθετη γραμμή στα αριστερά σημειώνει το 25% των δεδομένων, η κάθετη γραμμή στη μέση, το 50% των δεδομένων (ή η διάμεσος) και η τελευταία κάθετη γραμμή στα δεξιά, το 75% των δεδομένων . Όσο πιο ομοιόμορφα σε μέγεθος είναι και τα δύο τετράγωνα που ορίζονται από τις κατακόρυφες γραμμές – ή όσο μεγαλύτερη είναι η μέση κάθετη γραμμή στη μέση – σημαίνει ότι τα δεδομένα μας είναι πιο κοντά στην κανονική κατανομή ή λιγότερο λοξά, κάτι που είναι χρήσιμο για την ανάλυσή μας.
Εκτός από το κουτί IQR, υπάρχουν και οριζόντιες γραμμές και στις δύο πλευρές του. Αυτές οι γραμμές επισημαίνουν τις ελάχιστες και μέγιστες τιμές κατανομής που ορίζονται από
$$
Ελάχιστο = Q1 – 1.5*IQR
$$
και
$$
Μέγιστο = Q3 + 1.5*IQR
$$
Το IQR είναι ακριβώς η διαφορά μεταξύ Q3 και Q1 (ή Q3 – Q1) και είναι το πιο κεντρικό σημείο δεδομένων. Αυτός είναι ο λόγος για τον οποίο όταν βρίσκουμε το IQR, καταλήγουμε να φιλτράρουμε τα ακραία σημεία στα άκρα δεδομένων ή στα ελάχιστα και μέγιστα σημεία. Οι γραφικές παραστάσεις μας δίνουν μια κλεφτή ματιά για το αποτέλεσμα της μεθόδου IQR.
Μπορούμε να χρησιμοποιήσουμε Pandas quantile()
μέθοδος για να βρούμε τα ποσοστά μας, και iqr
από το scipy.stats
πακέτο για να λάβετε το εύρος διατεταρτημορίων δεδομένων για κάθε στήλη:
from scipy.stats import iqr
Q1 = X_train.quantile(q=.25)
Q3 = X_train.quantile(q=.75)
IQR = X_train.apply(iqr)
Τώρα έχουμε Q1, Q3 και IQR, μπορούμε να φιλτράρουμε τις τιμές πιο κοντά στη διάμεσο:
minimum = X_train < (Q1-1.5*IQR)
maximum = X_train > (Q3+1.5*IQR)
filter = ~(minimum | maximum).any(axis=1)
X_train = X_train[filter]
Αφού φιλτράρουμε τις σειρές προπόνησής μας, μπορούμε να δούμε πόσες από αυτές βρίσκονται ακόμα στα δεδομένα shape
:
X_train.shape
Αυτο εχει ως αποτελεσμα:
(1714, 12)
Μπορούμε να δούμε ότι ο αριθμός των σειρών πήγε από το 1875 στο 1714 μετά το φιλτράρισμα. Αυτό σημαίνει ότι 161 σειρές περιείχαν ακραίες τιμές ή το 8.5% των δεδομένων.
Σημείωση: Συνιστάται το φιλτράρισμα των ακραίων τιμών, η αφαίρεση των τιμών NaN και άλλες ενέργειες που περιλαμβάνουν δεδομένα φιλτραρίσματος και καθαρισμού να παραμένουν κάτω ή έως και 10% των δεδομένων. Δοκιμάστε να σκεφτείτε άλλες λύσεις εάν το φιλτράρισμα ή η αφαίρεση υπερβαίνει το 10% των δεδομένων σας.
Αφού αφαιρέσουμε τα ακραία στοιχεία, είμαστε σχεδόν έτοιμοι να συμπεριλάβουμε δεδομένα στο μοντέλο. Για την τοποθέτηση του μοντέλου, θα χρησιμοποιήσουμε δεδομένα αμαξοστοιχίας. X_train
είναι φιλτραρισμένο, αλλά τι γίνεται y_train
?
y_train.shape
Αυτό βγάζει:
(1875,)
Σημειώσε ότι y_train
έχει ακόμα 1875 σειρές. Πρέπει να ταιριάξουμε τον αριθμό των y_train
σειρές στον αριθμό των X_train
σειρές και όχι μόνο αυθαίρετα. Πρέπει να αφαιρέσουμε τις τιμές y των περιπτώσεων σπόρων κολοκύθας που αφαιρέσαμε, οι οποίοι είναι πιθανώς διάσπαρτοι στο y_train
σειρά. Το φιλτραρισμένο X_train
Το stil έχει τους αρχικούς του δείκτες και ο δείκτης έχει κενά όπου αφαιρέσαμε τις ακραίες τιμές! Στη συνέχεια μπορούμε να χρησιμοποιήσουμε το ευρετήριο του X_train
DataFrame για αναζήτηση των αντίστοιχων τιμών y_train
:
y_train = y_train.iloc[X_train.index]
Αφού το κάνουμε αυτό, μπορούμε να δούμε το y_train
σχήμα ξανά:
y_train.shape
Ποιες εξόδους:
(1714,)
Ρίξτε μια ματιά στον πρακτικό μας οδηγό για την εκμάθηση του Git, με βέλτιστες πρακτικές, πρότυπα αποδεκτά από τον κλάδο και συμπεριλαμβανόμενο φύλλο εξαπάτησης. Σταματήστε τις εντολές του Git στο Google και πραγματικά μαθαίνουν το!
Τώρα, y_train
έχει επίσης 1714 σειρές και είναι ίδιες με τις X_train
σειρές. Είμαστε επιτέλους έτοιμοι να δημιουργήσουμε το μοντέλο λογιστικής παλινδρόμησης!
Εφαρμογή του Μοντέλου Logistic Regression
Το δύσκολο κομμάτι έγινε! Η προεπεξεργασία είναι συνήθως πιο δύσκολη από την ανάπτυξη μοντέλων, όταν πρόκειται για τη χρήση βιβλιοθηκών όπως η Scikit-Learn, οι οποίες έχουν απλοποιήσει την εφαρμογή των μοντέλων ML σε μερικές μόνο γραμμές.
Αρχικά, εισάγουμε το LogisticRegression
κλάση και να το δημιουργήσετε, δημιουργώντας α LogisticRegression
αντικείμενο:
from sklearn.linear_model import LogisticRegression
logreg = LogisticRegression(random_state=SEED)
Δεύτερον, προσαρμόζουμε τα δεδομένα του τρένου μας στο logreg
μοντέλο με το fit()
μέθοδο και προβλέψτε τα δεδομένα δοκιμής μας με το predict()
μέθοδο, αποθήκευση των αποτελεσμάτων ως y_pred
:
logreg.fit(X_train.values, y_train)
y_pred = logreg.predict(X_test)
Έχουμε ήδη κάνει προβλέψεις με το μοντέλο μας! Ας δούμε τις 3 πρώτες σειρές X_train
για να δούμε ποια δεδομένα χρησιμοποιήσαμε:
X_train[:3]
Ο παραπάνω κώδικας βγάζει:
Area Perimeter Major_Axis_Length Minor_Axis_Length Convex_Area Equiv_Diameter Eccentricity Solidity Extent Roundness Aspect_Ration Compactness
0 -1.098308 -0.936518 -0.607941 -1.132551 -1.082768 -1.122359 0.458911 -1.078259 0.562847 -0.176041 0.236617 -0.360134
1 -0.501526 -0.468936 -0.387303 -0.376176 -0.507652 -0.475015 0.125764 0.258195 0.211703 0.094213 -0.122270 0.019480
2 0.012372 -0.209168 -0.354107 0.465095 0.003871 0.054384 -0.453911 0.432515 0.794735 0.647084 -0.617427 0.571137
Και στις 3 πρώτες προβλέψεις σε y_pred
για να δείτε τα αποτελέσματα:
y_pred[:3]
Αυτο εχει ως αποτελεσμα:
array([0, 0, 0])
Για αυτές τις τρεις σειρές, οι προβλέψεις μας ήταν ότι ήταν σπόροι της πρώτης κατηγορίας, Çerçevelik
.
Με λογική παλινδρόμηση, αντί να προβλέψουμε την τελική τάξη, όπως π.χ 0
, μπορούμε επίσης να προβλέψουμε την πιθανότητα που έχει η σειρά να σχετίζεται με το 0
τάξη. Αυτό συμβαίνει στην πραγματικότητα όταν η λογιστική παλινδρόμηση ταξινομεί δεδομένα και το predict()
Στη συνέχεια, η μέθοδος περνά αυτήν την πρόβλεψη από ένα όριο για να επιστρέψει μια κλάση "σκληρή". Για να προβλέψετε την πιθανότητα να αφορά μια τάξη, predict_proba()
χρησιμοποιείται:
y_pred_proba = logreg.predict_proba(X_test)
Ας ρίξουμε επίσης μια ματιά στις 3 πρώτες τιμές των προβλέψεων πιθανοτήτων y:
y_pred_proba[:3]
Ποιες εξόδους:
# class 0 class 1
array([[0.54726628, 0.45273372],
[0.56324527, 0.43675473],
[0.86233349, 0.13766651]])
Τώρα, αντί για τρία μηδενικά, έχουμε μία στήλη για κάθε τάξη. Στη στήλη στα αριστερά, ξεκινώντας από 0.54726628
, είναι οι πιθανότητες των δεδομένων που αφορούν την κλάση 0
; και στη δεξιά στήλη, ξεκινώντας από 0.45273372
, είναι η πιθανότητα να αφορά την τάξη 1
.
Σημείωση: Αυτή η διαφορά στην ταξινόμηση είναι επίσης γνωστή ως σκληρά και μαλακός προφητεία. Η σκληρή πρόβλεψη τοποθετεί την πρόβλεψη σε μια κλάση, ενώ η soft prediction εξάγει την πρόβλεψη πιθανότητα του στιγμιότυπου που ανήκει σε μια κλάση.
Υπάρχουν περισσότερες πληροφορίες για το πώς έγινε η προβλεπόμενη έξοδος. Στην πραγματικότητα δεν ήταν 0
, αλλά 55% πιθανότητα για μάθημα 0
, και 45% πιθανότητα μαθήματος 1
. Αυτό δείχνει πώς τα τρία πρώτα X_test
σημεία δεδομένων, που σχετίζονται με την τάξη 0
, είναι πραγματικά ξεκάθαρα μόνο σχετικά με το τρίτο σημείο δεδομένων, με πιθανότητα 86% – και όχι τόσο για τα δύο πρώτα σημεία δεδομένων.
Κατά την επικοινωνία ευρημάτων χρησιμοποιώντας μεθόδους ML – είναι συνήθως καλύτερο να επιστρέψετε μια soft class και τη σχετική πιθανότητα ως "αυτοπεποίθηση" αυτής της ταξινόμησης.
Θα μιλήσουμε περισσότερο για το πώς υπολογίζεται όταν εμβαθύνουμε στο μοντέλο. Αυτή τη στιγμή, μπορούμε να προχωρήσουμε στο επόμενο βήμα.
Αξιολόγηση του μοντέλου με αναφορές ταξινόμησης
Το τρίτο βήμα είναι να δείτε πώς αποδίδει το μοντέλο στα δεδομένα δοκιμής. Μπορούμε να εισάγουμε το Scikit-Learn classification_report()
και περάστε μας y_test
και y_pred
ως επιχειρήματα. Μετά από αυτό, μπορούμε να εκτυπώσουμε την απάντησή του.
Η αναφορά ταξινόμησης περιέχει τις πιο χρησιμοποιούμενες μετρήσεις ταξινόμησης, όπως π.χ ακρίβεια, ανάκληση, f1-βαθμολογία, να ακρίβεια.
- Ακρίβεια: για να κατανοήσουμε ποιες σωστές τιμές πρόβλεψης θεωρήθηκαν σωστές από τον ταξινομητή μας. Η ακρίβεια θα διαιρέσει αυτές τις αληθινές τιμές θετικών με οτιδήποτε είχε προβλεφθεί ως θετικό:
$$
ακρίβεια = frac{text{true positive}}{text{true positive} + text{false positive}}
$$
- Ανάκληση: για να καταλάβουμε πόσα από τα αληθινά θετικά εντοπίστηκαν από τον ταξινομητή μας. Η ανάκληση υπολογίζεται διαιρώντας τα αληθινά θετικά με οτιδήποτε θα έπρεπε να είχε προβλεφθεί ως θετικό:
$$
ανάκληση = frac{text{true positive}}{text{true positive} + text{false negative}}
$$
- Βαθμολογία F1: είναι η ισορροπημένη ή αρμονική μέση της ακρίβειας και της ανάκλησης. Η χαμηλότερη τιμή είναι 0 και η υψηλότερη είναι 1. Όταν
f1-score
ισούται με 1, σημαίνει ότι όλες οι κατηγορίες είχαν προβλεφθεί σωστά – αυτή είναι μια πολύ δύσκολη βαθμολογία με πραγματικά δεδομένα:
$$
text{f1-score} = 2* frac{text{precision} * text{recal}}{text{precision} + text{recall}}
$$
- Ακρίβεια: περιγράφει πόσες προβλέψεις είχε σωστές ο ταξινομητής μας. Η χαμηλότερη τιμή ακρίβειας είναι 0 και η υψηλότερη είναι 1. Αυτή η τιμή συνήθως πολλαπλασιάζεται επί 100 για να ληφθεί ένα ποσοστό:
$$
ακρίβεια = frac{κείμενο{αριθμός σωστών προβλέψεων}}{text{συνολικός αριθμός προβλέψεων}}
$$
Σημείωση: Είναι εξαιρετικά δύσκολο να αποκτήσετε 100% ακρίβεια σε οποιαδήποτε πραγματικά δεδομένα, εάν συμβεί αυτό, να γνωρίζετε ότι μπορεί να συμβαίνει κάποια διαρροή ή κάτι λάθος – δεν υπάρχει συναίνεση για μια ιδανική τιμή ακρίβειας και εξαρτάται επίσης από το περιβάλλον. Μια τιμή 70%, που σημαίνει ότι ο ταξινομητής θα κάνει λάθη στο 30% των δεδομένων ή πάνω από το 70% τείνει να είναι επαρκής για τα περισσότερα μοντέλα.
from sklearn.metrics import classification_report
cr = classification_report(y_test, y_pred)
print(cr)
Στη συνέχεια, μπορούμε να δούμε το αποτέλεσμα της αναφοράς ταξινόμησης:
precision recall f1-score support
0 0.83 0.91 0.87 316
1 0.90 0.81 0.85 309
accuracy 0.86 625
macro avg 0.86 0.86 0.86 625
weighted avg 0.86 0.86 0.86 625
Αυτό είναι το αποτέλεσμα μας. Σημειώσε ότι precision
, recall
, f1-score
, να accuracy
Οι μετρήσεις είναι όλες πολύ υψηλές, πάνω από 80%, το οποίο είναι ιδανικό – αλλά αυτά τα αποτελέσματα πιθανότατα επηρεάστηκαν από υψηλές συσχετίσεις και δεν θα διατηρηθούν μακροπρόθεσμα.
Η ακρίβεια του μοντέλου είναι 86%, που σημαίνει ότι κάνει λάθος ταξινόμηση το 14% των φορών. Έχουμε αυτές τις συνολικές πληροφορίες, αλλά θα ήταν ενδιαφέρον να μάθουμε αν τα λάθη του 14% συμβαίνουν σχετικά με την ταξινόμηση της τάξης 0
ή τάξη 1
. Για να προσδιορίσουμε ποιες κλάσεις αναγνωρίζονται εσφαλμένα ως ποιες και σε ποια συχνότητα – μπορούμε να υπολογίσουμε και να σχεδιάσουμε το a μήτρα σύγχυσης από τις προβλέψεις του μοντέλου μας.
Αξιολόγηση του μοντέλου με μια μήτρα σύγχυσης
Ας υπολογίσουμε και στη συνέχεια σχεδιάζουμε τον πίνακα σύγχυσης. Αφού το κάνουμε αυτό, μπορούμε να κατανοήσουμε κάθε μέρος του. Για να σχεδιάσουμε τον πίνακα σύγχυσης, θα χρησιμοποιήσουμε το Scikit-Learn confusion_matrix()
, το οποίο θα εισαγάγουμε από το metrics
μονάδα μέτρησης.
Η μήτρα σύγχυσης είναι ευκολότερο να απεικονιστεί χρησιμοποιώντας ένα Seaborn heatmap()
. Έτσι, αφού τον δημιουργήσουμε, θα περάσουμε τον πίνακα σύγχυσης ως όρισμα για τον χάρτη θερμότητας:
from sklearn.metrics import confusion_matrix
cm = confusion_matrix(y_test, y_pred)
sns.heatmap(cm, annot=True, fmt='d')
- Πίνακας σύγχυσης: ο πίνακας δείχνει πόσα δείγματα το μοντέλο πήρε σωστά ή λάθος για κάθε τάξη. Καλούνται οι τιμές που ήταν σωστές και σωστά προβλεπόμενες αληθινά θετικά, και λέγονται αυτά που είχαν προβλεφθεί ως θετικά αλλά δεν ήταν θετικά ψευδώς θετικά. Η ίδια ονοματολογία του αληθινά αρνητικά και ψευδώς αρνητικά χρησιμοποιείται για αρνητικές τιμές.
Εξετάζοντας την γραφική παράσταση του πίνακα σύγχυσης, μπορούμε να δούμε ότι έχουμε 287
αξίες που ήταν 0
και προβλεπόταν ως 0
- ή αληθινά θετικά για την ταξη 0
(οι σπόροι Çerçevelik). Εχουμε επισης 250
αληθινά θετικά για την τάξη 1
(Σπόροι Ürgüp Sivrisi). Τα αληθινά θετικά βρίσκονται πάντα στη διαγώνιο του πίνακα που πηγαίνει από πάνω αριστερά προς τα κάτω δεξιά.
Εχουμε επισης 29
αξίες που έπρεπε να είναι 0
, αλλά προβλεπόταν ως 1
(ψευδώς θετικά) Και 59
αξίες που ήταν 1
και προβλεπόταν ως 0
(ψευδώς αρνητικά). Με αυτούς τους αριθμούς, μπορούμε να καταλάβουμε ότι το σφάλμα που κάνει περισσότερο το μοντέλο είναι ότι προβλέπει ψευδώς αρνητικά. Έτσι, μπορεί να καταλήξει ως επί το πλείστον να ταξινομήσει έναν σπόρο Ürgüp Sivrisi ως σπόρους Çerçevelik.
Αυτό το είδος σφάλματος εξηγείται επίσης από το 81% ανάκληση της τάξης 1
. Παρατηρήστε ότι οι μετρήσεις είναι συνδεδεμένες. Και η διαφορά στην ανάκληση προέρχεται από το ότι έχουμε 100 λιγότερα δείγματα της κατηγορίας Ürgüp Sivrisi. Αυτή είναι μία από τις συνέπειες του να έχουμε λίγα δείγματα λιγότερα από την άλλη κατηγορία. Για να βελτιώσετε περαιτέρω την ανάκληση, μπορείτε είτε να πειραματιστείτε με βάρη τάξης είτε να χρησιμοποιήσετε περισσότερα δείγματα Ürgüp Sivrisi.
Μέχρι στιγμής, έχουμε εκτελέσει τα περισσότερα από τα παραδοσιακά βήματα της επιστήμης δεδομένων και χρησιμοποιήσαμε το μοντέλο λογιστικής παλινδρόμησης ως μαύρο κουτί.
Σημείωση: Εάν θέλετε να προχωρήσετε περαιτέρω, χρησιμοποιήστε Cross Validation (CV) και Grid Search να αναζητήσετε, αντίστοιχα, το μοντέλο που γενικεύει περισσότερο τα δεδομένα και τις καλύτερες παραμέτρους μοντέλου που επιλέγονται πριν από την εκπαίδευση, ή υπερπαραμέτρους.
Ιδανικά, με το βιογραφικό σημείωμα και την αναζήτηση πλέγματος, θα μπορούσατε επίσης να εφαρμόσετε έναν συνδυασμένο τρόπο για να κάνετε βήματα προεπεξεργασίας δεδομένων, διαχωρισμό δεδομένων, μοντελοποίηση και αξιολόγηση – κάτι που γίνεται εύκολο με το Scikit-Learn αγωγών.
Τώρα είναι η ώρα να ανοίξετε το μαύρο κουτί και να κοιτάξετε μέσα του, για να εμβαθύνετε στην κατανόηση του πώς λειτουργεί η λογιστική παλινδρόμηση.
Πηγαίνοντας βαθύτερα στο πώς λειτουργεί πραγματικά η Logistic Regression
Η οπισθοδρόμηση Η λέξη δεν υπάρχει τυχαία, για να καταλάβουμε τι κάνει η λογιστική παλινδρόμηση, μπορούμε να θυμηθούμε τι κάνει η αδελφική της, γραμμική παλινδρόμηση στα δεδομένα. Ο τύπος της γραμμικής παλινδρόμησης ήταν ο ακόλουθος:
$$
y = b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n
$$
Στο οποίο β0 ήταν η ανακοπή της παλινδρόμησης, β1 ο συντελεστής και το x1 τα δεδομένα.
Αυτή η εξίσωση οδήγησε σε μια ευθεία γραμμή που χρησιμοποιήθηκε για την πρόβλεψη νέων τιμών. Υπενθυμίζοντας την εισαγωγή, η διαφορά τώρα είναι ότι δεν θα προβλέψουμε νέες τιμές, αλλά μια κατηγορία. Άρα αυτή η ευθεία πρέπει να αλλάξει. Με την λογιστική παλινδρόμηση, εισάγουμε μια μη γραμμικότητα και η πρόβλεψη γίνεται τώρα χρησιμοποιώντας μια καμπύλη αντί για μια γραμμή:
Παρατηρήστε ότι ενώ η γραμμή γραμμικής παλινδρόμησης συνεχίζει και αποτελείται από συνεχείς άπειρες τιμές, η καμπύλη λογιστικής παλινδρόμησης μπορεί να διαιρεθεί στη μέση και έχει ακραίες τιμές σε τιμές 0 και 1. Αυτό το σχήμα "S" είναι ο λόγος που ταξινομεί τα δεδομένα - τα σημεία που είναι πιο κοντά ή πέφτουν στο υψηλότερο άκρο ανήκουν στην κατηγορία 1, ενώ τα σημεία που βρίσκονται στο κάτω τεταρτημόριο ή πιο κοντά στο 0, ανήκουν στην κατηγορία 0. Το μέσο το "S" είναι η μέση μεταξύ 0 και 1, 0.5 - είναι το κατώφλι για τα σημεία λογιστικής παλινδρόμησης.
Καταλαβαίνουμε ήδη την οπτική διαφορά μεταξύ λογιστικής και γραμμικής παλινδρόμησης, αλλά τι γίνεται με τον τύπο; Ο τύπος για την λογιστική παλινδρόμηση είναι ο ακόλουθος:
$$
y = b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n
$$
Μπορεί επίσης να γραφτεί ως:
$$
y_{prob} = frac{1}{1 + e^{(b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n)}}
$$
Ή ακόμα και να γραφτεί ως:
$$
y_{prob} = frac{e^{(b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n)}}{1 + e^{(b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n)}}
$$
Στην παραπάνω εξίσωση, έχουμε την πιθανότητα εισαγωγής, αντί για την τιμή της. Έχει τον αριθμητή του 1, επομένως μπορεί να οδηγήσει σε μια τιμή μεταξύ 0 και 1 και 1 συν μια τιμή στον παρονομαστή του, έτσι ώστε η τιμή του να είναι 1 και κάτι - αυτό σημαίνει ότι το αποτέλεσμα ολόκληρου του κλάσματος δεν μπορεί να είναι μεγαλύτερο από 1 .
Και ποια είναι η τιμή που είναι στον παρονομαστή; είναι e, η βάση του φυσικού λογάριθμου (περίπου 2.718282), αυξημένη στη δύναμη της γραμμικής παλινδρόμησης:
$$
e^{(b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n)}
$$
Ένας άλλος τρόπος γραφής θα ήταν:
$$
ln αριστερά( frac{p}{1-p} δεξιά) = {(b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n)}
$$
Σε αυτή την τελευταία εξίσωση, ln είναι ο φυσικός λογάριθμος (βάση ε) και p είναι η πιθανότητα, άρα ο λογάριθμος της πιθανότητας του αποτελέσματος είναι ίδιος με το αποτέλεσμα της γραμμικής παλινδρόμησης.
Με άλλα λόγια, με το αποτέλεσμα της γραμμικής παλινδρόμησης και τον φυσικό λογάριθμο, μπορούμε να καταλήξουμε στην πιθανότητα μιας εισόδου να αφορά ή όχι μια σχεδιασμένη κλάση.
Η όλη διαδικασία παραγωγής λογιστικής παλινδρόμησης είναι η εξής:
$$
p{X} = frac{e^{(b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n)}}{1 + e^{(b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n)}}
$$
$$
p(1 + e^{(b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n)}) = e^{(b_0 + b_1 * x_1 + b_2 *x_2 + b_3 * x_3 + ldots + b_n * x_n)}
$$
$$
p + p*e^{(b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n)} = e^{(b_0 + b_1 * x_1 + b_2 *x_2 + b_3 * x_3 + ldots + b_n * x_n)}
$$
p
=
e
(
b
0
+
b
1
*
x
1
+
b
2
*
x
2
+
b
3
*
x
3
+
...
+
b
n
*
x
n
)
-
p
*
e
(
b
0
+
b
1
*
x
1
+
b
2
*
x
2
+
b
3
*
x
3
+
...
+
b
n
*
x
n
)
$$
frac{p}{1-p} = e^{(b_0 + b_1 * x_1 + b_2 *x_2 + b_3 * x_3 + ldots + b_n * x_n)}
$$
$$
Αριστερά (frac{p}{1-p} δεξιά) = (b_0 + b_1 * x_1 + b_2 *x_2 + b_3 * x_3 + ldots + b_n * x_n)
$$
Αυτό σημαίνει ότι το μοντέλο λογιστικής παλινδρόμησης έχει επίσης συντελεστές και τιμή τομής. Επειδή χρησιμοποιεί μια γραμμική παλινδρόμηση και προσθέτει μια μη γραμμική συνιστώσα σε αυτήν με τον φυσικό λογάριθμο (e
).
Μπορούμε να δούμε τις τιμές των συντελεστών και της τομής του μοντέλου μας, με τον ίδιο τρόπο που κάναμε για τη γραμμική παλινδρόμηση, χρησιμοποιώντας coef_
και intercept_
ιδιότητες:
logreg.coef_
Το οποίο εμφανίζει τους συντελεστές καθενός από τα 12 χαρακτηριστικά:
array([[ 1.43726172, -1.03136968, 0.24099522, -0.61180768, 1.36538261,
-1.45321951, -1.22826034, 0.98766966, 0.0438686 , -0.78687889,
1.9601197 , -1.77226097]])
logreg.intercept_
Αυτό έχει ως αποτέλεσμα:
array([0.08735782])
Με τους συντελεστές και τις τιμές τομής, μπορούμε να υπολογίσουμε τις προβλεπόμενες πιθανότητες των δεδομένων μας. Ας πάρουμε το πρώτο X_test
τιμές ξανά, για παράδειγμα:
X_test[:1]
Αυτό επιστρέφει την πρώτη σειρά του X_test
ως πίνακας NumPy:
array([[-1.09830823, -0.93651823, -0.60794138, -1.13255059, -1.0827684 ,
-1.12235877, 0.45891056, -1.07825898, 0.56284738, -0.17604099,
0.23661678, -0.36013424]])
Ακολουθώντας την αρχική εξίσωση:
$$
p{X} = frac{e^{(b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n)}}{1 + e^{(b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n)}}
$$
Στον python έχουμε:
import math
lin_reg = logreg.intercept_[0] +
((logreg.coef_[0][0]* X_test[:1][0][0])+
(logreg.coef_[0][1]* X_test[:1][0][1])+
(logreg.coef_[0][2]* X_test[:1][0][2])+
(logreg.coef_[0][3]* X_test[:1][0][3])+
(logreg.coef_[0][4]* X_test[:1][0][4])+
(logreg.coef_[0][5]* X_test[:1][0][5])+
(logreg.coef_[0][6]* X_test[:1][0][6])+
(logreg.coef_[0][7]* X_test[:1][0][7])+
(logreg.coef_[0][8]* X_test[:1][0][8])+
(logreg.coef_[0][9]* X_test[:1][0][9])+
(logreg.coef_[0][10]* X_test[:1][0][10])+
(logreg.coef_[0][11]* X_test[:1][0][11]))
px = math.exp(lin_reg)/(1 +(math.exp(lin_reg)))
px
Αυτο εχει ως αποτελεσμα:
0.45273372469369133
Αν ξαναδούμε το predict_proba
αποτέλεσμα του πρώτου X_test
γραμμή, έχουμε:
logreg.predict_proba(X_test[:1])
Αυτό σημαίνει ότι η αρχική εξίσωση λογιστικής παλινδρόμησης μας δίνει την πιθανότητα της εισόδου σχετικά με την κλάση 1
, για να μάθετε ποια πιθανότητα είναι για την τάξη 0
, μπορούμε απλά:
1 - px
Παρατηρήστε ότι και τα δύο px
και 1-px
είναι πανομοιότυπα με predict_proba
Αποτελέσματα. Έτσι υπολογίζεται η λογιστική παλινδρόμηση και γιατί οπισθοδρόμηση είναι μέρος του ονόματός του. Τι γίνεται όμως με τον όρο logistic?
Ο όρος logistic προέρχεται από καταγραφή, η οποία είναι μια συνάρτηση που έχουμε ήδη δει:
$$
Αριστερά (frac{p}{1-p} δεξιά)
$$
Μόλις το υπολογίσαμε με px
και 1-px
. Αυτό είναι το logit, που ονομάζεται επίσης log-πιθανότητες αφού ισούται με τον λογάριθμο των πιθανοτήτων όπου p
είναι μια πιθανότητα.
Συμπέρασμα
Σε αυτόν τον οδηγό, μελετήσαμε έναν από τους πιο θεμελιώδεις αλγόριθμους ταξινόμησης μηχανικής μάθησης, π.χ λογική παλινδρόμηση.
Αρχικά, εφαρμόσαμε την logistic regression ως μαύρο κουτί με τη βιβλιοθήκη μηχανικής εκμάθησης της Scikit-Learn και αργότερα την καταλάβαμε βήμα προς βήμα για να έχουμε ξεκάθαρο γιατί και από πού προέρχονται οι όροι παλινδρόμηση και logistic.
Εξερευνήσαμε και μελετήσαμε επίσης τα δεδομένα, κατανοώντας ότι είναι ένα από τα πιο κρίσιμα μέρη μιας ανάλυσης επιστήμης δεδομένων.
Από εδώ, θα σας συμβούλευα να παίξετε πολυταξική υλικοτεχνική παλινδρόμηση, λογιστική παλινδρόμηση για περισσότερες από δύο κλάσεις – μπορείτε να εφαρμόσετε τον ίδιο αλγόριθμο λογιστικής παλινδρόμησης για άλλα σύνολα δεδομένων που έχουν πολλές κλάσεις και να ερμηνεύσετε τα αποτελέσματα.
Σημείωση: Μια καλή συλλογή συνόλων δεδομένων είναι διαθέσιμη εδώ για να παίξεις μαζί σου.
Θα σας συμβούλευα επίσης να μελετήσετε τα L1 και L2 τακτοποιήσεις, είναι ένας τρόπος να «τιμωρηθούν» τα υψηλότερα δεδομένα προκειμένου να πλησιάσουν στο κανονικό, κρατώντας την πολυπλοκότητα του μοντέλου, ώστε ο αλγόριθμος να φτάσει σε καλύτερο αποτέλεσμα. Η υλοποίηση Scikit-Learn που χρησιμοποιήσαμε έχει ήδη κανονικοποίηση L2 από προεπιλογή. Ένα άλλο πράγμα που πρέπει να δούμε είναι το διαφορετικό επιλυτές, Όπως lbgs
, που βελτιστοποιούν την απόδοση του αλγορίθμου λογιστικής παλινδρόμησης.
Είναι επίσης σημαντικό να ρίξετε μια ματιά στο στατιστικός προσέγγιση της λογιστικής παλινδρόμησης. Εχει παραδοχές σχετικά με τη συμπεριφορά των δεδομένων και σχετικά με άλλα στατιστικά στοιχεία που πρέπει να ισχύουν για να εγγυηθούν ικανοποιητικά αποτελέσματα, όπως:
- οι παρατηρήσεις είναι ανεξάρτητες.
- Δεν υπάρχει πολυσυγγραμμικότητα μεταξύ των επεξηγηματικών μεταβλητών.
- Δεν υπάρχουν ακραίες ακραίες τιμές.
- Υπάρχει μια γραμμική σχέση μεταξύ των επεξηγηματικών μεταβλητών και του λογότυπου της μεταβλητής απόκρισης.
- το μέγεθος του δείγματος είναι αρκετά μεγάλο.
Παρατηρήστε πόσες από αυτές τις υποθέσεις είχαν ήδη καλυφθεί στην ανάλυση και την επεξεργασία των δεδομένων μας.
Ελπίζω να συνεχίσετε να εξερευνάτε τι έχει να προσφέρει η λογιστική παλινδρόμηση σε όλες τις διαφορετικές προσεγγίσεις της!
- blockchain
- C + +
- κωδικός
- Coingenius
- επιστημονικά δεδομένα
- οπτικοποίηση δεδομένων
- Java
- matplotlib
- μη εύφλεκτο διακριτικό
- πολλοί
- OpenSea
- Πάντα
- PHP
- Πλάτων
- πλάτων αι
- Πληροφορία δεδομένων Plato
- Παιχνίδι Πλάτωνας
- Πλανοσάτσας
- Πλάτωνα δεδομένα
- platogaming
- Πολύγωνο
- Python
- Αντίδραση
- scikit-μάθετε
- θαλασσοπόρος
- έξυπνη σύμβαση
- σολάριουμ
- Stackabuse
- Vyper
- Web3
- zephyrnet