You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ML-For-Beginners/translations/el/6-NLP/4-Hotel-Reviews-1/README.md

50 KiB

Ανάλυση συναισθημάτων με κριτικές ξενοδοχείων - επεξεργασία δεδομένων

Σε αυτή την ενότητα θα χρησιμοποιήσετε τις τεχνικές που μάθατε στα προηγούμενα μαθήματα για να κάνετε μια διερευνητική ανάλυση δεδομένων σε ένα μεγάλο σύνολο δεδομένων. Αφού αποκτήσετε μια καλή κατανόηση της χρησιμότητας των διάφορων στηλών, θα μάθετε:

  • πώς να αφαιρέσετε τις περιττές στήλες
  • πώς να υπολογίσετε νέα δεδομένα βασισμένα στις υπάρχουσες στήλες
  • πώς να αποθηκεύσετε το προκύπτον σύνολο δεδομένων για χρήση στην τελική πρόκληση

Προ-μάθημα κουίζ

Εισαγωγή

Μέχρι τώρα έχετε μάθει πώς τα δεδομένα κειμένου διαφέρουν από τα αριθμητικά δεδομένα. Εάν πρόκειται για κείμενο που έχει γραφτεί ή ειπωθεί από έναν άνθρωπο, μπορεί να αναλυθεί για να βρεθούν μοτίβα, συχνότητες, συναισθήματα και νόημα. Αυτό το μάθημα σας εισάγει σε ένα πραγματικό σύνολο δεδομένων με μια πραγματική πρόκληση: 515K Hotel Reviews Data in Europe, το οποίο περιλαμβάνει μια CC0: Public Domain license. Τα δεδομένα έχουν συλλεχθεί από δημόσιες πηγές του Booking.com. Δημιουργός του συνόλου δεδομένων είναι ο Jiashen Liu.

Προετοιμασία

Θα χρειαστείτε:

Διερευνητική ανάλυση δεδομένων

Αυτή η πρόκληση υποθέτει ότι δημιουργείτε ένα bot σύστασης ξενοδοχείων χρησιμοποιώντας ανάλυση συναισθημάτων και βαθμολογίες επισκεπτών. Το σύνολο δεδομένων που θα χρησιμοποιήσετε περιλαμβάνει κριτικές για 1493 διαφορετικά ξενοδοχεία σε 6 πόλεις.

Χρησιμοποιώντας Python, ένα σύνολο δεδομένων κριτικών ξενοδοχείων και την ανάλυση συναισθημάτων του NLTK, μπορείτε να ανακαλύψετε:

  • Ποιες είναι οι πιο συχνά χρησιμοποιούμενες λέξεις και φράσεις στις κριτικές;
  • Συμφωνούν οι επίσημες ετικέτες που περιγράφουν ένα ξενοδοχείο με τις βαθμολογίες των κριτικών (π.χ. υπάρχουν περισσότερες αρνητικές κριτικές για ένα συγκεκριμένο ξενοδοχείο από Οικογένειες με μικρά παιδιά παρά από Μοναχικούς ταξιδιώτες, ίσως υποδεικνύοντας ότι είναι καλύτερο για Μοναχικούς ταξιδιώτες);
  • Συμφωνούν οι βαθμολογίες συναισθημάτων του NLTK με τη αριθμητική βαθμολογία του κριτικού;

Σύνολο δεδομένων

Ας εξερευνήσουμε το σύνολο δεδομένων που έχετε κατεβάσει και αποθηκεύσει τοπικά. Ανοίξτε το αρχείο σε έναν επεξεργαστή όπως το VS Code ή ακόμα και το Excel.

Οι επικεφαλίδες στο σύνολο δεδομένων είναι οι εξής:

Hotel_Address, Additional_Number_of_Scoring, Review_Date, Average_Score, Hotel_Name, Reviewer_Nationality, Negative_Review, Review_Total_Negative_Word_Counts, Total_Number_of_Reviews, Positive_Review, Review_Total_Positive_Word_Counts, Total_Number_of_Reviews_Reviewer_Has_Given, Reviewer_Score, Tags, days_since_review, lat, lng

Εδώ είναι ομαδοποιημένες με τρόπο που μπορεί να είναι πιο εύκολο να εξεταστούν:

Στήλες ξενοδοχείου
  • Hotel_Name, Hotel_Address, lat (γεωγραφικό πλάτος), lng (γεωγραφικό μήκος)
    • Χρησιμοποιώντας lat και lng μπορείτε να σχεδιάσετε έναν χάρτη με Python που δείχνει τις τοποθεσίες των ξενοδοχείων (ίσως με χρωματική κωδικοποίηση για αρνητικές και θετικές κριτικές)
    • Το Hotel_Address δεν είναι προφανώς χρήσιμο για εμάς, και πιθανότατα θα το αντικαταστήσουμε με μια χώρα για ευκολότερη ταξινόμηση και αναζήτηση

Στήλες μετα-κριτικών ξενοδοχείου

  • Average_Score

    • Σύμφωνα με τον δημιουργό του συνόλου δεδομένων, αυτή η στήλη είναι η Μέση βαθμολογία του ξενοδοχείου, υπολογισμένη βάσει του τελευταίου σχολίου του τελευταίου έτους. Αυτό φαίνεται σαν ένας ασυνήθιστος τρόπος υπολογισμού της βαθμολογίας, αλλά είναι τα δεδομένα που συλλέχθηκαν, οπότε μπορούμε να τα δεχτούμε προς το παρόν.

    Βάσει των άλλων στηλών σε αυτά τα δεδομένα, μπορείτε να σκεφτείτε έναν άλλο τρόπο υπολογισμού της μέσης βαθμολογίας;

  • Total_Number_of_Reviews

    • Ο συνολικός αριθμός κριτικών που έχει λάβει αυτό το ξενοδοχείο - δεν είναι σαφές (χωρίς να γράψουμε κάποιον κώδικα) αν αυτό αναφέρεται στις κριτικές του συνόλου δεδομένων.
  • Additional_Number_of_Scoring

    • Αυτό σημαίνει ότι δόθηκε βαθμολογία αλλά δεν γράφτηκε θετική ή αρνητική κριτική από τον κριτικό.

Στήλες κριτικών

  • Reviewer_Score
    • Αυτή είναι μια αριθμητική τιμή με το πολύ 1 δεκαδικό ψηφίο μεταξύ των ελάχιστων και μέγιστων τιμών 2.5 και 10
    • Δεν εξηγείται γιατί το 2.5 είναι η χαμηλότερη δυνατή βαθμολογία
  • Negative_Review
    • Εάν ένας κριτικός δεν έγραψε τίποτα, αυτό το πεδίο θα έχει "No Negative"
    • Σημειώστε ότι ένας κριτικός μπορεί να γράψει μια θετική κριτική στη στήλη αρνητικής κριτικής (π.χ. "δεν υπάρχει τίποτα κακό σε αυτό το ξενοδοχείο")
  • Review_Total_Negative_Word_Counts
    • Υψηλότεροι αριθμοί αρνητικών λέξεων υποδεικνύουν χαμηλότερη βαθμολογία (χωρίς να ελέγχεται η συναισθηματικότητα)
  • Positive_Review
    • Εάν ένας κριτικός δεν έγραψε τίποτα, αυτό το πεδίο θα έχει "No Positive"
    • Σημειώστε ότι ένας κριτικός μπορεί να γράψει μια αρνητική κριτική στη στήλη θετικής κριτικής (π.χ. "δεν υπάρχει τίποτα καλό σε αυτό το ξενοδοχείο")
  • Review_Total_Positive_Word_Counts
    • Υψηλότεροι αριθμοί θετικών λέξεων υποδεικνύουν υψηλότερη βαθμολογία (χωρίς να ελέγχεται η συναισθηματικότητα)
  • Review_Date και days_since_review
    • Μπορεί να εφαρμοστεί ένα μέτρο φρεσκάδας ή παλαιότητας σε μια κριτική (οι παλαιότερες κριτικές μπορεί να μην είναι τόσο ακριβείς όσο οι νεότερες λόγω αλλαγών στη διαχείριση του ξενοδοχείου, ανακαινίσεων ή προσθήκης πισίνας κ.λπ.)
  • Tags
    • Αυτές είναι σύντομες περιγραφές που μπορεί να επιλέξει ένας κριτικός για να περιγράψει τον τύπο επισκέπτη που ήταν (π.χ. μοναχικός ή οικογένεια), τον τύπο δωματίου που είχε, τη διάρκεια παραμονής και πώς υποβλήθηκε η κριτική.
    • Δυστυχώς, η χρήση αυτών των ετικετών είναι προβληματική, δείτε την ενότητα παρακάτω που συζητά τη χρησιμότητά τους.

Στήλες κριτικών επισκεπτών

  • Total_Number_of_Reviews_Reviewer_Has_Given
    • Αυτό μπορεί να είναι ένας παράγοντας σε ένα μοντέλο σύστασης, για παράδειγμα, εάν μπορούσατε να προσδιορίσετε ότι οι πιο παραγωγικοί κριτικοί με εκατοντάδες κριτικές ήταν πιο πιθανό να είναι αρνητικοί παρά θετικοί. Ωστόσο, ο κριτικός οποιασδήποτε συγκεκριμένης κριτικής δεν προσδιορίζεται με έναν μοναδικό κωδικό και επομένως δεν μπορεί να συνδεθεί με ένα σύνολο κριτικών. Υπάρχουν 30 κριτικοί με 100 ή περισσότερες κριτικές, αλλά είναι δύσκολο να δούμε πώς αυτό μπορεί να βοηθήσει το μοντέλο σύστασης.
  • Reviewer_Nationality
    • Κάποιοι μπορεί να πιστεύουν ότι ορισμένες εθνικότητες είναι πιο πιθανό να δώσουν θετική ή αρνητική κριτική λόγω εθνικής κλίσης. Να είστε προσεκτικοί όταν ενσωματώνετε τέτοιες απόψεις στο μοντέλο σας. Αυτά είναι εθνικά (και μερικές φορές φυλετικά) στερεότυπα, και κάθε κριτικός ήταν ένα άτομο που έγραψε μια κριτική βάσει της εμπειρίας του. Μπορεί να έχει φιλτραριστεί μέσα από πολλούς φακούς, όπως οι προηγούμενες διαμονές του σε ξενοδοχεία, η απόσταση που ταξίδεψε και η προσωπική του ιδιοσυγκρασία. Το να πιστεύουμε ότι η εθνικότητά τους ήταν ο λόγος για τη βαθμολογία της κριτικής είναι δύσκολο να δικαιολογηθεί.
Παραδείγματα
Average Score Total Number Reviews Reviewer Score Negative
Review
Positive Review Tags
7.8 1945 2.5 Αυτό δεν είναι αυτή τη στιγμή ξενοδοχείο αλλά εργοτάξιο. Τρομοκρατήθηκα από νωρίς το πρωί και όλη μέρα με απαράδεκτο θόρυβο από κατασκευές ενώ ξεκουραζόμουν μετά από ένα μακρύ ταξίδι και δούλευα στο δωμάτιο. Άνθρωποι δούλευαν όλη μέρα, π.χ. με κομπρεσέρ στα διπλανά δωμάτια. Ζήτησα αλλαγή δωματίου αλλά δεν υπήρχε ήσυχο δωμάτιο διαθέσιμο. Για να χειροτερέψουν τα πράγματα, χρεώθηκα υπερβολικά. Έκανα check-out το βράδυ καθώς έπρεπε να φύγω πολύ νωρίς για πτήση και έλαβα τον κατάλληλο λογαριασμό. Μια μέρα αργότερα το ξενοδοχείο έκανε άλλη χρέωση χωρίς τη συγκατάθεσή μου, υπερβαίνοντας την τιμή κράτησης. Είναι ένα τρομερό μέρος. Μην τιμωρείτε τον εαυτό σας κάνοντας κράτηση εδώ. Τίποτα. Τρομερό μέρος. Μακριά. Επαγγελματικό ταξίδι, Ζευγάρι, Standard Double Room, Διαμονή 2 νύχτες

Όπως μπορείτε να δείτε, αυτός ο επισκέπτης δεν είχε ευχάριστη διαμονή σε αυτό το ξενοδοχείο. Το ξενοδοχείο έχει μια καλή μέση βαθμολογία 7.8 και 1945 κριτικές, αλλά αυτός ο κριτικός του έδωσε 2.5 και έγραψε 115 λέξεις για το πόσο αρνητική ήταν η διαμονή του. Αν δεν έγραφε τίποτα στη στήλη Positive_Review, θα μπορούσατε να υποθέσετε ότι δεν υπήρχε τίποτα θετικό, αλλά έγραψε 7 λέξεις προειδοποίησης. Αν απλώς μετρούσαμε λέξεις αντί για το νόημα ή το συναίσθημα των λέξεων, θα μπορούσαμε να έχουμε μια παραμορφωμένη εικόνα της πρόθεσης του κριτικού. Παράξενα, η βαθμολογία του 2.5 είναι μπερδεμένη, γιατί αν η διαμονή στο ξενοδοχείο ήταν τόσο κακή, γιατί να δώσει οποιοδήποτε βαθμό; Εξετάζοντας το σύνολο δεδομένων προσεκτικά, θα δείτε ότι η χαμηλότερη δυνατή βαθμολογία είναι 2.5, όχι 0. Η υψηλότερη δυνατή βαθμολογία είναι 10.

Ετικέτες

Όπως αναφέρθηκε παραπάνω, με την πρώτη ματιά, η ιδέα να χρησιμοποιηθούν οι Tags για την κατηγοριοποίηση των δεδομένων φαίνεται λογική. Δυστυχώς, αυτές οι ετικέτες δεν είναι τυποποιημένες, πράγμα που σημαίνει ότι σε ένα δεδομένο ξενοδοχείο, οι επιλογές μπορεί να είναι Single room, Twin room και Double room, αλλά στο επόμενο ξενοδοχείο, είναι Deluxe Single Room, Classic Queen Room και Executive King Room. Αυτά μπορεί να είναι τα ίδια πράγματα, αλλά υπάρχουν τόσες πολλές παραλλαγές που η επιλογή γίνεται:

  1. Προσπάθεια αλλαγής όλων των όρων σε ένα ενιαίο πρότυπο, κάτι που είναι πολύ δύσκολο, επειδή δεν είναι σαφές ποια θα ήταν η διαδρομή μετατροπής σε κάθε περίπτωση (π.χ. Classic single room αντιστοιχεί σε Single room αλλά Superior Queen Room with Courtyard Garden or City View είναι πολύ πιο δύσκολο να αντιστοιχιστεί)

  2. Μπορούμε να πάρουμε μια προσέγγιση NLP και να μετρήσουμε τη συχνότητα ορισμένων όρων όπως Solo, Business Traveller ή Family with young kids καθώς εφαρμόζονται σε κάθε ξενοδοχείο, και να το ενσωματώσουμε στο μοντέλο σύστασης.

Οι ετικέτες είναι συνήθως (αλλά όχι πάντα) ένα μόνο πεδίο που περιέχει μια λίστα από 5 έως 6 τιμές χωρισμένες με κόμμα, που αντιστοιχούν σε Τύπο ταξιδιού, Τύπο επισκεπτών, Τύπο δωματίου, Αριθμό νυχτών και Τύπο συσκευής από την οποία υποβλήθηκε η κριτική. Ωστόσο, επειδή κάποιοι κριτικοί δεν συμπληρώνουν κάθε πεδίο (μπορεί να αφήσουν ένα κενό), οι τιμές δεν είναι πάντα με την ίδια σειρά.

Ως παράδειγμα, πάρτε τον Τύπο ομάδας. Υπάρχουν 1025 μοναδικές δυνατότητες σε αυτό το πεδίο στη στήλη Tags, και δυστυχώς μόνο μερικές από αυτές αναφέρονται σε ομάδα (κάποιες είναι ο τύπος δωματίου κ.λπ.). Εάν φιλτράρετε μόνο αυτές που αναφέρουν οικογένεια, τα αποτελέσματα περιέχουν πολλές τιμές τύπου Family room. Εάν συμπεριλάβετε τον όρο with, δηλαδή μετρήσετε τις τιμές Family with, τα αποτελέσματα είναι καλύτερα, με πάνω από 80,000 από τα 515,000 αποτελέσματα να περιέχουν τη φράση "Family with young children" ή "Family with older children".

Αυτό σημαίνει ότι η στήλη ετικετών δεν είναι εντελώς άχρηστη για εμάς, αλλά θα χρειαστεί κάποια δουλειά για να γίνει χρήσιμη.

Μέση βαθμολογία ξενοδοχείου

Υπάρχουν ορισμένες παραξενιές ή ασυμφωνίες με το σύνολο δεδομένων που δεν μπορώ να καταλάβω, αλλά παρουσιάζονται εδώ ώστε να είστε ενήμεροι όταν δημιουργείτε τα μοντέλα σας. Εάν το καταλάβετε, ενημερώστε μας στην ενότητα συζήτησης!

Το σύνολο δεδομένων έχει τις εξής στήλες που σχετίζονται με τη μέση βαθμολογία και τον αριθμό κριτικών:

  1. Hotel_Name
  2. Additional_Number_of_Scoring
  3. Average_Score
  4. Total_Number_of_Reviews
  5. Reviewer_Score

Το ξενοδοχείο με τις περισσότερες κριτικές σε αυτό το σύνολο δεδομένων είναι το Britannia International Hotel Canary Wharf με 4789 κριτικές από τις 515,000. Αλλά αν κοιτάξουμε την τιμή Total_Number_of_Reviews για αυτό το ξενοδοχείο, είναι 9086. Μπορεί να υποθέσετε ότι υπάρχουν πολλές περισσότερες βαθμολογίες χωρίς κριτικές, οπότε ίσως πρέπει να προσθέσουμε την τιμή της στήλης `Additional_Number

🚨 Μια σημείωση προσοχής

Όταν εργάζεστε με αυτό το σύνολο δεδομένων, θα γράψετε κώδικα που υπολογίζει κάτι από το κείμενο χωρίς να χρειάζεται να το διαβάσετε ή να το αναλύσετε οι ίδιοι. Αυτή είναι η ουσία της Επεξεργασίας Φυσικής Γλώσσας (NLP), η ερμηνεία νοήματος ή συναισθήματος χωρίς να χρειάζεται να το κάνει ένας άνθρωπος. Ωστόσο, είναι πιθανό να διαβάσετε κάποιες από τις αρνητικές κριτικές. Θα σας προέτρεπα να μην το κάνετε, γιατί δεν είναι απαραίτητο. Κάποιες από αυτές είναι ανόητες ή άσχετες αρνητικές κριτικές για ξενοδοχεία, όπως "Ο καιρός δεν ήταν καλός", κάτι που είναι πέρα από τον έλεγχο του ξενοδοχείου ή, πράγματι, οποιουδήποτε. Αλλά υπάρχει και μια σκοτεινή πλευρά σε κάποιες κριτικές. Μερικές φορές οι αρνητικές κριτικές είναι ρατσιστικές, σεξιστικές ή ηλικιακές. Αυτό είναι δυσάρεστο αλλά αναμενόμενο σε ένα σύνολο δεδομένων που έχει συλλεχθεί από μια δημόσια ιστοσελίδα. Κάποιοι κριτικοί αφήνουν σχόλια που μπορεί να βρείτε αποκρουστικά, άβολα ή ενοχλητικά. Καλύτερα να αφήσετε τον κώδικα να μετρήσει το συναίσθημα παρά να τα διαβάσετε οι ίδιοι και να αναστατωθείτε. Με αυτά τα δεδομένα, είναι μια μειοψηφία που γράφει τέτοια πράγματα, αλλά υπάρχουν παρ' όλα αυτά.

Άσκηση - Εξερεύνηση δεδομένων

Φόρτωση δεδομένων

Αρκετά με την οπτική εξέταση των δεδομένων, τώρα θα γράψετε κώδικα για να πάρετε απαντήσεις! Αυτή η ενότητα χρησιμοποιεί τη βιβλιοθήκη pandas. Η πρώτη σας εργασία είναι να βεβαιωθείτε ότι μπορείτε να φορτώσετε και να διαβάσετε τα δεδομένα CSV. Η βιβλιοθήκη pandas διαθέτει έναν γρήγορο φορτωτή CSV, και το αποτέλεσμα τοποθετείται σε ένα dataframe, όπως στις προηγούμενες ενότητες. Το CSV που φορτώνουμε έχει πάνω από μισό εκατομμύριο γραμμές, αλλά μόνο 17 στήλες. Η pandas σας προσφέρει πολλές ισχυρές δυνατότητες για να αλληλεπιδράσετε με ένα dataframe, συμπεριλαμβανομένης της δυνατότητας να εκτελέσετε λειτουργίες σε κάθε γραμμή.

Από εδώ και στο εξής σε αυτό το μάθημα, θα υπάρχουν αποσπάσματα κώδικα, εξηγήσεις του κώδικα και συζητήσεις για το τι σημαίνουν τα αποτελέσματα. Χρησιμοποιήστε το notebook.ipynb που περιλαμβάνεται για τον κώδικά σας.

Ας ξεκινήσουμε με τη φόρτωση του αρχείου δεδομένων που θα χρησιμοποιήσετε:

# Load the hotel reviews from CSV
import pandas as pd
import time
# importing time so the start and end time can be used to calculate file loading time
print("Loading data file now, this could take a while depending on file size")
start = time.time()
# df is 'DataFrame' - make sure you downloaded the file to the data folder
df = pd.read_csv('../../data/Hotel_Reviews.csv')
end = time.time()
print("Loading took " + str(round(end - start, 2)) + " seconds")

Τώρα που τα δεδομένα έχουν φορτωθεί, μπορούμε να εκτελέσουμε κάποιες λειτουργίες πάνω τους. Κρατήστε αυτόν τον κώδικα στην κορυφή του προγράμματός σας για το επόμενο μέρος.

Εξερεύνηση δεδομένων

Σε αυτή την περίπτωση, τα δεδομένα είναι ήδη καθαρά, που σημαίνει ότι είναι έτοιμα για επεξεργασία και δεν περιέχουν χαρακτήρες σε άλλες γλώσσες που θα μπορούσαν να προκαλέσουν προβλήματα σε αλγόριθμους που περιμένουν μόνο αγγλικούς χαρακτήρες.

Ίσως χρειαστεί να δουλέψετε με δεδομένα που απαιτούν αρχική επεξεργασία για να μορφοποιηθούν πριν εφαρμόσετε τεχνικές NLP, αλλά όχι αυτή τη φορά. Αν χρειαζόταν, πώς θα χειριζόσασταν χαρακτήρες που δεν είναι στα αγγλικά;

Πάρτε λίγο χρόνο για να βεβαιωθείτε ότι μόλις φορτωθούν τα δεδομένα, μπορείτε να τα εξερευνήσετε με κώδικα. Είναι πολύ εύκολο να θέλετε να εστιάσετε στις στήλες Negative_Review και Positive_Review. Είναι γεμάτες με φυσικό κείμενο για να επεξεργαστούν οι αλγόριθμοι NLP σας. Αλλά περιμένετε! Πριν βουτήξετε στο NLP και την ανάλυση συναισθημάτων, θα πρέπει να ακολουθήσετε τον παρακάτω κώδικα για να βεβαιωθείτε ότι οι τιμές που δίνονται στο dataset ταιριάζουν με τις τιμές που υπολογίζετε με την pandas.

Λειτουργίες στο dataframe

Η πρώτη εργασία σε αυτό το μάθημα είναι να ελέγξετε αν οι παρακάτω υποθέσεις είναι σωστές γράφοντας κώδικα που εξετάζει το dataframe (χωρίς να το αλλάξετε).

Όπως πολλές εργασίες προγραμματισμού, υπάρχουν διάφοροι τρόποι να το ολοκληρώσετε, αλλά μια καλή συμβουλή είναι να το κάνετε με τον πιο απλό και εύκολο τρόπο, ειδικά αν θα είναι πιο εύκολο να κατανοηθεί όταν επιστρέψετε σε αυτόν τον κώδικα στο μέλλον. Με τα dataframes, υπάρχει ένα ολοκληρωμένο API που συχνά θα έχει έναν τρόπο να κάνετε αυτό που θέλετε αποτελεσματικά.

Αντιμετωπίστε τις παρακάτω ερωτήσεις ως εργασίες προγραμματισμού και προσπαθήστε να τις απαντήσετε χωρίς να κοιτάξετε τη λύση.

  1. Εκτυπώστε το σχήμα του dataframe που μόλις φορτώσατε (το σχήμα είναι ο αριθμός των γραμμών και στηλών).
  2. Υπολογίστε τη συχνότητα εμφάνισης για τις εθνικότητες των κριτών:
    1. Πόσες διαφορετικές τιμές υπάρχουν για τη στήλη Reviewer_Nationality και ποιες είναι αυτές;
    2. Ποια εθνικότητα κριτών είναι η πιο συχνή στο dataset (εκτυπώστε τη χώρα και τον αριθμό των κριτικών);
    3. Ποιες είναι οι επόμενες 10 πιο συχνές εθνικότητες και η συχνότητα εμφάνισής τους;
  3. Ποιο ήταν το πιο συχνά αξιολογημένο ξενοδοχείο για κάθε μία από τις 10 πιο συχνές εθνικότητες κριτών;
  4. Πόσες κριτικές υπάρχουν ανά ξενοδοχείο (συχνότητα εμφάνισης ξενοδοχείου) στο dataset;
  5. Παρόλο που υπάρχει μια στήλη Average_Score για κάθε ξενοδοχείο στο dataset, μπορείτε επίσης να υπολογίσετε έναν μέσο όρο (λαμβάνοντας τον μέσο όρο όλων των βαθμολογιών των κριτών στο dataset για κάθε ξενοδοχείο). Προσθέστε μια νέα στήλη στο dataframe σας με την επικεφαλίδα Calc_Average_Score που περιέχει αυτόν τον υπολογισμένο μέσο όρο.
  6. Υπάρχουν ξενοδοχεία που έχουν την ίδια (στρογγυλοποιημένη στο 1 δεκαδικό ψηφίο) Average_Score και Calc_Average_Score;
    1. Δοκιμάστε να γράψετε μια συνάρτηση Python που παίρνει μια σειρά (γραμμή) ως όρισμα και συγκρίνει τις τιμές, εκτυπώνοντας ένα μήνυμα όταν οι τιμές δεν είναι ίσες. Στη συνέχεια, χρησιμοποιήστε τη μέθοδο .apply() για να επεξεργαστείτε κάθε γραμμή με τη συνάρτηση.
  7. Υπολογίστε και εκτυπώστε πόσες γραμμές έχουν τιμές "No Negative" στη στήλη Negative_Review.
  8. Υπολογίστε και εκτυπώστε πόσες γραμμές έχουν τιμές "No Positive" στη στήλη Positive_Review.
  9. Υπολογίστε και εκτυπώστε πόσες γραμμές έχουν τιμές "No Positive" στη στήλη Positive_Review και τιμές "No Negative" στη στήλη Negative_Review.

Απαντήσεις κώδικα

  1. Εκτυπώστε το σχήμα του dataframe που μόλις φορτώσατε (το σχήμα είναι ο αριθμός των γραμμών και στηλών).

    print("The shape of the data (rows, cols) is " + str(df.shape))
    > The shape of the data (rows, cols) is (515738, 17)
    
  2. Υπολογίστε τη συχνότητα εμφάνισης για τις εθνικότητες των κριτών:

    1. Πόσες διαφορετικές τιμές υπάρχουν για τη στήλη Reviewer_Nationality και ποιες είναι αυτές;
    2. Ποια εθνικότητα κριτών είναι η πιο συχνή στο dataset (εκτυπώστε τη χώρα και τον αριθμό των κριτικών);
    # value_counts() creates a Series object that has index and values in this case, the country and the frequency they occur in reviewer nationality
    nationality_freq = df["Reviewer_Nationality"].value_counts()
    print("There are " + str(nationality_freq.size) + " different nationalities")
    # print first and last rows of the Series. Change to nationality_freq.to_string() to print all of the data
    print(nationality_freq) 
    
    There are 227 different nationalities
     United Kingdom               245246
     United States of America      35437
     Australia                     21686
     Ireland                       14827
     United Arab Emirates          10235
                                   ...  
     Comoros                           1
     Palau                             1
     Northern Mariana Islands          1
     Cape Verde                        1
     Guinea                            1
    Name: Reviewer_Nationality, Length: 227, dtype: int64
    
    1. Ποιες είναι οι επόμενες 10 πιο συχνές εθνικότητες και η συχνότητα εμφάνισής τους;

      print("The highest frequency reviewer nationality is " + str(nationality_freq.index[0]).strip() + " with " + str(nationality_freq[0]) + " reviews.")
      # Notice there is a leading space on the values, strip() removes that for printing
      # What is the top 10 most common nationalities and their frequencies?
      print("The next 10 highest frequency reviewer nationalities are:")
      print(nationality_freq[1:11].to_string())
      
      The highest frequency reviewer nationality is United Kingdom with 245246 reviews.
      The next 10 highest frequency reviewer nationalities are:
       United States of America     35437
       Australia                    21686
       Ireland                      14827
       United Arab Emirates         10235
       Saudi Arabia                  8951
       Netherlands                   8772
       Switzerland                   8678
       Germany                       7941
       Canada                        7894
       France                        7296
      
  3. Ποιο ήταν το πιο συχνά αξιολογημένο ξενοδοχείο για κάθε μία από τις 10 πιο συχνές εθνικότητες κριτών;

    # What was the most frequently reviewed hotel for the top 10 nationalities
    # Normally with pandas you will avoid an explicit loop, but wanted to show creating a new dataframe using criteria (don't do this with large amounts of data because it could be very slow)
    for nat in nationality_freq[:10].index:
       # First, extract all the rows that match the criteria into a new dataframe
       nat_df = df[df["Reviewer_Nationality"] == nat]   
       # Now get the hotel freq
       freq = nat_df["Hotel_Name"].value_counts()
       print("The most reviewed hotel for " + str(nat).strip() + " was " + str(freq.index[0]) + " with " + str(freq[0]) + " reviews.") 
    
    The most reviewed hotel for United Kingdom was Britannia International Hotel Canary Wharf with 3833 reviews.
    The most reviewed hotel for United States of America was Hotel Esther a with 423 reviews.
    The most reviewed hotel for Australia was Park Plaza Westminster Bridge London with 167 reviews.
    The most reviewed hotel for Ireland was Copthorne Tara Hotel London Kensington with 239 reviews.
    The most reviewed hotel for United Arab Emirates was Millennium Hotel London Knightsbridge with 129 reviews.
    The most reviewed hotel for Saudi Arabia was The Cumberland A Guoman Hotel with 142 reviews.
    The most reviewed hotel for Netherlands was Jaz Amsterdam with 97 reviews.
    The most reviewed hotel for Switzerland was Hotel Da Vinci with 97 reviews.
    The most reviewed hotel for Germany was Hotel Da Vinci with 86 reviews.
    The most reviewed hotel for Canada was St James Court A Taj Hotel London with 61 reviews.
    
  4. Πόσες κριτικές υπάρχουν ανά ξενοδοχείο (συχνότητα εμφάνισης ξενοδοχείου) στο dataset;

    # First create a new dataframe based on the old one, removing the uneeded columns
    hotel_freq_df = df.drop(["Hotel_Address", "Additional_Number_of_Scoring", "Review_Date", "Average_Score", "Reviewer_Nationality", "Negative_Review", "Review_Total_Negative_Word_Counts", "Positive_Review", "Review_Total_Positive_Word_Counts", "Total_Number_of_Reviews_Reviewer_Has_Given", "Reviewer_Score", "Tags", "days_since_review", "lat", "lng"], axis = 1)
    
    # Group the rows by Hotel_Name, count them and put the result in a new column Total_Reviews_Found
    hotel_freq_df['Total_Reviews_Found'] = hotel_freq_df.groupby('Hotel_Name').transform('count')
    
    # Get rid of all the duplicated rows
    hotel_freq_df = hotel_freq_df.drop_duplicates(subset = ["Hotel_Name"])
    display(hotel_freq_df) 
    
    Hotel_Name Total_Number_of_Reviews Total_Reviews_Found
    Britannia International Hotel Canary Wharf 9086 4789
    Park Plaza Westminster Bridge London 12158 4169
    Copthorne Tara Hotel London Kensington 7105 3578
    ... ... ...
    Mercure Paris Porte d Orleans 110 10
    Hotel Wagner 135 10
    Hotel Gallitzinberg 173 8

    Ίσως παρατηρήσετε ότι τα αποτελέσματα που μετρήθηκαν στο dataset δεν ταιριάζουν με την τιμή στο Total_Number_of_Reviews. Δεν είναι σαφές αν αυτή η τιμή στο dataset αντιπροσώπευε τον συνολικό αριθμό κριτικών που είχε το ξενοδοχείο, αλλά δεν είχαν όλες συλλεχθεί, ή κάποια άλλη μέτρηση. Το Total_Number_of_Reviews δεν χρησιμοποιείται στο μοντέλο λόγω αυτής της ασάφειας.

  5. Παρόλο που υπάρχει μια στήλη Average_Score για κάθε ξενοδοχείο στο dataset, μπορείτε επίσης να υπολογίσετε έναν μέσο όρο (λαμβάνοντας τον μέσο όρο όλων των βαθμολογιών των κριτών στο dataset για κάθε ξενοδοχείο). Προσθέστε μια νέα στήλη στο dataframe σας με την επικεφαλίδα Calc_Average_Score που περιέχει αυτόν τον υπολογισμένο μέσο όρο. Εκτυπώστε τις στήλες Hotel_Name, Average_Score και Calc_Average_Score.

    # define a function that takes a row and performs some calculation with it
    def get_difference_review_avg(row):
      return row["Average_Score"] - row["Calc_Average_Score"]
    
    # 'mean' is mathematical word for 'average'
    df['Calc_Average_Score'] = round(df.groupby('Hotel_Name').Reviewer_Score.transform('mean'), 1)
    
    # Add a new column with the difference between the two average scores
    df["Average_Score_Difference"] = df.apply(get_difference_review_avg, axis = 1)
    
    # Create a df without all the duplicates of Hotel_Name (so only 1 row per hotel)
    review_scores_df = df.drop_duplicates(subset = ["Hotel_Name"])
    
    # Sort the dataframe to find the lowest and highest average score difference
    review_scores_df = review_scores_df.sort_values(by=["Average_Score_Difference"])
    
    display(review_scores_df[["Average_Score_Difference", "Average_Score", "Calc_Average_Score", "Hotel_Name"]])
    

    Ίσως αναρωτηθείτε για την τιμή Average_Score και γιατί μερικές φορές διαφέρει από τον υπολογισμένο μέσο όρο. Επειδή δεν μπορούμε να γνωρίζουμε γιατί μερικές από τις τιμές ταιριάζουν, αλλά άλλες έχουν διαφορά, είναι πιο ασφαλές σε αυτή την περίπτωση να χρησιμοποιήσουμε τις βαθμολογίες των κριτικών που έχουμε για να υπολογίσουμε τον μέσο όρο μόνοι μας. Παρόλα αυτά, οι διαφορές είναι συνήθως πολύ μικρές, εδώ είναι τα ξενοδοχεία με τη μεγαλύτερη απόκλιση από τον μέσο όρο του dataset και τον υπολογισμένο μέσο όρο:

    Average_Score_Difference Average_Score Calc_Average_Score Hotel_Name
    -0.8 7.7 8.5 Best Western Hotel Astoria
    -0.7 8.8 9.5 Hotel Stendhal Place Vend me Paris MGallery
    -0.7 7.5 8.2 Mercure Paris Porte d Orleans
    -0.7 7.9 8.6 Renaissance Paris Vendome Hotel
    -0.5 7.0 7.5 Hotel Royal Elys es
    ... ... ... ...
    0.7 7.5 6.8 Mercure Paris Op ra Faubourg Montmartre
    0.8 7.1 6.3 Holiday Inn Paris Montparnasse Pasteur
    0.9 6.8 5.9 Villa Eugenie
    0.9 8.6 7.7 MARQUIS Faubourg St Honor Relais Ch teaux
    1.3 7.2 5.9 Kube Hotel Ice Bar

    Με μόνο 1 ξενοδοχείο να έχει διαφορά βαθμολογίας μεγαλύτερη από 1, σημαίνει ότι μπορούμε πιθανώς να αγνοήσουμε τη διαφορά και να χρησιμοποιήσουμε τον υπολογισμένο μέσο όρο.

  6. Υπολογίστε και εκτυπώστε πόσες γραμμές έχουν τιμές "No Negative" στη στήλη Negative_Review.

  7. Υπολογίστε και εκτυπώστε πόσες γραμμές έχουν τιμές "No Positive" στη στήλη Positive_Review.

  8. Υπολογίστε και εκτυπώστε πόσες γραμμές έχουν τιμές "No Positive" στη στήλη Positive_Review και τιμές "No Negative" στη στήλη Negative_Review.

    # with lambdas:
    start = time.time()
    no_negative_reviews = df.apply(lambda x: True if x['Negative_Review'] == "No Negative" else False , axis=1)
    print("Number of No Negative reviews: " + str(len(no_negative_reviews[no_negative_reviews == True].index)))
    
    no_positive_reviews = df.apply(lambda x: True if x['Positive_Review'] == "No Positive" else False , axis=1)
    print("Number of No Positive reviews: " + str(len(no_positive_reviews[no_positive_reviews == True].index)))
    
    both_no_reviews = df.apply(lambda x: True if x['Negative_Review'] == "No Negative" and x['Positive_Review'] == "No Positive" else False , axis=1)
    print("Number of both No Negative and No Positive reviews: " + str(len(both_no_reviews[both_no_reviews == True].index)))
    end = time.time()
    print("Lambdas took " + str(round(end - start, 2)) + " seconds")
    
    Number of No Negative reviews: 127890
    Number of No Positive reviews: 35946
    Number of both No Negative and No Positive reviews: 127
    Lambdas took 9.64 seconds
    

Ένας άλλος τρόπος

Ένας άλλος τρόπος να μετρήσετε αντικείμενα χωρίς Lambdas, και να χρησιμοποιήσετε το sum για να μετρήσετε τις γραμμές:

# without lambdas (using a mixture of notations to show you can use both)
start = time.time()
no_negative_reviews = sum(df.Negative_Review == "No Negative")
print("Number of No Negative reviews: " + str(no_negative_reviews))

no_positive_reviews = sum(df["Positive_Review"] == "No Positive")
print("Number of No Positive reviews: " + str(no_positive_reviews))

both_no_reviews = sum((df.Negative_Review == "No Negative") & (df.Positive_Review == "No Positive"))
print("Number of both No Negative and No Positive reviews: " + str(both_no_reviews))

end = time.time()
print("Sum took " + str(round(end - start, 2)) + " seconds")

Number of No Negative reviews: 127890
Number of No Positive reviews: 35946
Number of both No Negative and No Positive reviews: 127
Sum took 0.19 seconds

Ίσως παρατηρήσατε ότι υπάρχουν 127 γραμμές που έχουν και "No Negative" και "No Positive" τιμές για τις στήλες Negative_Review και Positive_Review αντίστοιχα. Αυτό σημαίνει ότι ο κριτής έδωσε στο ξενοδοχείο μια αριθμητική βαθμολογία, αλλά αρνήθηκε να γράψει είτε θετική είτε αρνητική κριτική. Ευτυχώς, αυτό είναι ένα μικρό ποσοστό γραμμών (127 από 515738, ή 0.02%), οπότε πιθανώς δεν θα επηρεάσει το μοντέλο ή τα αποτελέσματα προς κάποια συγκεκριμένη κατεύθυνση, αλλά ίσως να μην περιμένατε ένα dataset κριτικών να έχει γραμμές χωρίς κριτικές, οπότε αξίζει να εξερευνήσετε τα δεδομένα για να ανακαλύψετε γραμμές σαν αυτές.

Τώρα που εξερευνήσατε το dataset, στο επόμενο μάθημα θα φιλτράρετε τα δεδομένα και θα προσθέσετε ανάλυση συναισθημάτων.


🚀Πρόκληση

Αυτό το μάθημα δείχνει, όπως είδαμε σε προηγούμενα μαθήματα, πόσο κρίσιμα σημαντικό είναι να κατανοήσετε τα δεδομένα σας και τις ιδιαιτερότητές τους πριν εκτελέσετε λειτουργίες πάνω τους. Τα δεδομένα που βασίζονται σε κείμενο, ειδικότερα, απαιτούν προσεκτική εξέταση. Ψάξτε σε διάφορα datasets με έντονο κείμενο και δείτε αν μπορείτε να ανακαλύψετε περιοχές που θα μπορούσαν να εισάγουν προκατάληψη ή παραμορφωμένο συναίσθημα σε ένα μοντέλο.

Κουίζ μετά το μάθημα

Ανασκόπηση & Αυτομελέτη

Πάρτε αυτό το Learning Path για NLP για να ανακαλύψετε εργαλεία που μπορείτε να δοκιμάσετε όταν δημιουργείτε μοντέλα με έντονο λόγο και κείμενο.

Εργασία

NLTK


Αποποίηση ευθύνης:
Αυτό το έγγραφο έχει μεταφραστεί χρησιμοποιώντας την υπηρεσία αυτόματης μετάφρασης Co-op Translator. Παρόλο που καταβάλλουμε προσπάθειες για ακρίβεια, παρακαλούμε να έχετε υπόψη ότι οι αυτοματοποιημένες μεταφράσεις ενδέχεται να περιέχουν λάθη ή ανακρίβειες. Το πρωτότυπο έγγραφο στη μητρική του γλώσσα θα πρέπει να θεωρείται η αυθεντική πηγή. Για κρίσιμες πληροφορίες, συνιστάται επαγγελματική ανθρώπινη μετάφραση. Δεν φέρουμε ευθύνη για τυχόν παρεξηγήσεις ή εσφαλμένες ερμηνείες που προκύπτουν από τη χρήση αυτής της μετάφρασης.