35 KiB
Analiza sentimentului cu recenzii de hotel - procesarea datelor
În această secțiune vei folosi tehnicile din lecțiile anterioare pentru a realiza o analiză exploratorie a unui set de date mare. După ce vei avea o înțelegere bună a utilității diferitelor coloane, vei învăța:
- cum să elimini coloanele inutile
- cum să calculezi date noi bazate pe coloanele existente
- cum să salvezi setul de date rezultat pentru utilizare în provocarea finală
Chestionar înainte de lecție
Introducere
Până acum ai învățat despre cum datele text sunt destul de diferite față de datele numerice. Dacă textul a fost scris sau rostit de un om, acesta poate fi analizat pentru a găsi modele și frecvențe, sentimente și semnificații. Această lecție te introduce într-un set de date real cu o provocare reală: 515K Hotel Reviews Data in Europe, care include o licență CC0: Public Domain. Datele au fost extrase de pe Booking.com din surse publice. Creatorul setului de date este Jiashen Liu.
Pregătire
Vei avea nevoie de:
- Abilitatea de a rula notebook-uri .ipynb folosind Python 3
- pandas
- NLTK, pe care ar trebui să-l instalezi local
- Setul de date disponibil pe Kaggle 515K Hotel Reviews Data in Europe. Are aproximativ 230 MB dezarhivat. Descarcă-l în folderul rădăcină
/data
asociat acestor lecții NLP.
Analiza exploratorie a datelor
Această provocare presupune că construiești un bot de recomandare pentru hoteluri folosind analiza sentimentului și scorurile recenziilor oaspeților. Setul de date pe care îl vei folosi include recenzii pentru 1493 hoteluri diferite din 6 orașe.
Folosind Python, un set de date cu recenzii de hotel și analiza sentimentului din NLTK, ai putea afla:
- Care sunt cele mai frecvent utilizate cuvinte și expresii în recenzii?
- Corelează etichetele oficiale care descriu un hotel cu scorurile recenziilor (de exemplu, există recenzii mai negative pentru un hotel de la Familie cu copii mici decât de la Călător singur, indicând poate că este mai potrivit pentru Călători singuri?)
- Sunt scorurile sentimentului din NLTK în acord cu scorul numeric al recenziei hotelului?
Setul de date
Să explorăm setul de date pe care l-ai descărcat și salvat local. Deschide fișierul într-un editor precum VS Code sau chiar Excel.
Anteturile din setul de date sunt următoarele:
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
Iată-le grupate într-un mod care ar putea fi mai ușor de examinat:
Coloane despre hotel
Hotel_Name
,Hotel_Address
,lat
(latitudine),lng
(longitudine)- Folosind lat și lng ai putea crea o hartă cu Python care să arate locațiile hotelurilor (poate codificate pe culori pentru recenzii negative și pozitive)
- Hotel_Address nu pare să fie util pentru noi și probabil îl vom înlocui cu o țară pentru o sortare și căutare mai ușoară
Coloane meta-recenzie hotel
-
Average_Score
- Conform creatorului setului de date, această coloană reprezintă Scorul mediu al hotelului, calculat pe baza celui mai recent comentariu din ultimul an. Acesta pare un mod neobișnuit de a calcula scorul, dar este datele extrase, așa că le putem lua ca atare pentru moment.
✅ Pe baza celorlalte coloane din acest set de date, te poți gândi la un alt mod de a calcula scorul mediu?
-
Total_Number_of_Reviews
- Numărul total de recenzii pe care acest hotel le-a primit - nu este clar (fără a scrie cod) dacă se referă la recenziile din setul de date.
-
Additional_Number_of_Scoring
- Acest lucru înseamnă că a fost dat un scor de recenzie, dar nu a fost scrisă nicio recenzie pozitivă sau negativă de către recenzor
Coloane despre recenzii
Reviewer_Score
- Acesta este o valoare numerică cu cel mult 1 zecimală între valorile minime și maxime 2.5 și 10
- Nu este explicat de ce 2.5 este cel mai mic scor posibil
Negative_Review
- Dacă un recenzor nu a scris nimic, acest câmp va avea "No Negative"
- Reține că un recenzor poate scrie o recenzie pozitivă în coloana Negative review (de exemplu, "nu este nimic rău la acest hotel")
Review_Total_Negative_Word_Counts
- Numărul mai mare de cuvinte negative indică un scor mai mic (fără a verifica sentimentul)
Positive_Review
- Dacă un recenzor nu a scris nimic, acest câmp va avea "No Positive"
- Reține că un recenzor poate scrie o recenzie negativă în coloana Positive review (de exemplu, "nu este nimic bun la acest hotel")
Review_Total_Positive_Word_Counts
- Numărul mai mare de cuvinte pozitive indică un scor mai mare (fără a verifica sentimentul)
Review_Date
șidays_since_review
- Se poate aplica o măsură de prospețime sau vechime unei recenzii (recenziile mai vechi s-ar putea să nu fie la fel de precise ca cele mai noi, deoarece managementul hotelului s-a schimbat, s-au făcut renovări, s-a adăugat o piscină etc.)
Tags
- Acestea sunt descrieri scurte pe care un recenzor le poate selecta pentru a descrie tipul de oaspete care a fost (de exemplu, singur sau familie), tipul de cameră pe care a avut-o, durata șederii și modul în care recenzia a fost trimisă.
- Din păcate, utilizarea acestor etichete este problematică, verifică secțiunea de mai jos care discută utilitatea lor
Coloane despre recenzor
Total_Number_of_Reviews_Reviewer_Has_Given
- Acesta ar putea fi un factor într-un model de recomandare, de exemplu, dacă ai putea determina că recenzorii mai prolifici cu sute de recenzii sunt mai predispuși să fie negativi decât pozitivi. Totuși, recenzorul oricărei recenzii nu este identificat cu un cod unic și, prin urmare, nu poate fi legat de un set de recenzii. Există 30 de recenzori cu 100 sau mai multe recenzii, dar este greu de văzut cum acest lucru poate ajuta modelul de recomandare.
Reviewer_Nationality
- Unii oameni ar putea crede că anumite naționalități sunt mai predispuse să ofere o recenzie pozitivă sau negativă din cauza unei înclinații naționale. Fii atent când construiești astfel de opinii anecdotice în modelele tale. Acestea sunt stereotipuri naționale (și uneori rasiale), iar fiecare recenzor a fost un individ care a scris o recenzie bazată pe experiența sa. Aceasta ar fi putut fi filtrată prin multe lentile, cum ar fi șederile anterioare la hotel, distanța parcursă și temperamentul personal. Este greu de justificat ideea că naționalitatea a fost motivul unui scor de recenzie.
Exemple
Scor mediu | Număr total de recenzii | Scor recenzor | Recenzie Negativă |
Recenzie Pozitivă | Etichete |
---|---|---|---|---|---|
7.8 | 1945 | 2.5 | Acesta nu este în prezent un hotel, ci un șantier de construcții. Am fost terorizat de dimineață devreme și toată ziua cu zgomot de construcție inacceptabil în timp ce mă odihneam după o călătorie lungă și lucram în cameră. Oamenii lucrau toată ziua, adică cu ciocane pneumatice în camerele adiacente. Am cerut schimbarea camerei, dar nu era disponibilă nicio cameră liniștită. Ca să fie și mai rău, am fost suprataxat. Am plecat seara, deoarece aveam un zbor foarte devreme și am primit o factură corespunzătoare. O zi mai târziu, hotelul a făcut o altă taxare fără consimțământul meu, peste prețul rezervat. Este un loc groaznic. Nu te pedepsi rezervând aici. | Nimic. Loc groaznic. Stai departe. | Călătorie de afaceri. Cuplu. Cameră dublă standard. Ședere 2 nopți. |
După cum poți vedea, acest oaspete nu a avut o ședere fericită la acest hotel. Hotelul are un scor mediu bun de 7.8 și 1945 de recenzii, dar acest recenzor i-a dat 2.5 și a scris 115 cuvinte despre cât de negativă a fost șederea sa. Dacă nu ar fi scris nimic în coloana Positive_Review, ai putea presupune că nu a fost nimic pozitiv, dar totuși au scris 7 cuvinte de avertizare. Dacă am număra doar cuvintele în loc de semnificația sau sentimentul cuvintelor, am putea avea o viziune distorsionată asupra intenției recenzorului. Ciudat, scorul lor de 2.5 este confuz, deoarece dacă șederea la hotel a fost atât de rea, de ce să-i acorde vreun punct? Investigând setul de date mai atent, vei vedea că cel mai mic scor posibil este 2.5, nu 0. Cel mai mare scor posibil este 10.
Etichete
Așa cum s-a menționat mai sus, la prima vedere, ideea de a folosi Tags
pentru a categorisi datele are sens. Din păcate, aceste etichete nu sunt standardizate, ceea ce înseamnă că într-un hotel, opțiunile ar putea fi Single room, Twin room și Double room, dar în următorul hotel, acestea sunt Deluxe Single Room, Classic Queen Room și Executive King Room. Acestea ar putea fi aceleași lucruri, dar există atât de multe variații încât alegerea devine:
-
Încercarea de a schimba toți termenii într-un standard unic, ceea ce este foarte dificil, deoarece nu este clar care ar fi calea de conversie în fiecare caz (de exemplu, Classic single room se mapează la Single room, dar Superior Queen Room with Courtyard Garden or City View este mult mai greu de mapat)
-
Putem adopta o abordare NLP și măsura frecvența anumitor termeni precum Solo, Business Traveller sau Family with young kids pe măsură ce se aplică fiecărui hotel și să includem acest lucru în recomandare
Etichetele sunt de obicei (dar nu întotdeauna) un câmp unic care conține o listă de 5 până la 6 valori separate prin virgulă, aliniate la Tipul de călătorie, Tipul de oaspeți, Tipul de cameră, Numărul de nopți și Tipul de dispozitiv pe care a fost trimisă recenzia. Totuși, deoarece unii recenzori nu completează fiecare câmp (pot lăsa unul gol), valorile nu sunt întotdeauna în aceeași ordine.
De exemplu, ia Tipul de grup. Există 1025 de posibilități unice în acest câmp din coloana Tags
, și din păcate doar unele dintre ele se referă la un grup (unele sunt tipul de cameră etc.). Dacă filtrezi doar cele care menționează familie, rezultatele conțin multe rezultate de tip Family room. Dacă incluzi termenul with, adică numeri valorile Family with, rezultatele sunt mai bune, cu peste 80.000 din cele 515.000 de rezultate conținând expresia "Family with young children" sau "Family with older children".
Aceasta înseamnă că coloana etichete nu este complet inutilă pentru noi, dar va necesita ceva muncă pentru a o face utilă.
Scorul mediu al hotelului
Există o serie de ciudățenii sau discrepanțe în setul de date pe care nu le pot explica, dar sunt ilustrate aici pentru a fi conștient de ele atunci când construiești modelele tale. Dacă le descoperi, te rugăm să ne anunți în secțiunea de discuții!
Setul de date are următoarele coloane legate de scorul mediu și numărul de recenzii:
- Hotel_Name
- Additional_Number_of_Scoring
- Average_Score
- Total_Number_of_Reviews
- Reviewer_Score
Hotelul cu cele mai multe recenzii din acest set de date este Britannia International Hotel Canary Wharf cu 4789 de recenzii din 515.000. Dar dacă ne uităm la valoarea Total_Number_of_Reviews
pentru acest hotel, este 9086. Ai putea presupune că există mult mai multe scoruri fără recenzii, așa că poate ar trebui să adăugăm valoarea din coloana Additional_Number_of_Scoring
. Acea valoare este 2682, iar adăugând-o la 4789 obținem 7471, care este încă cu 1615 mai puțin decât Total_Number_of_Reviews
.
Dacă iei coloana Average_Score
, ai putea presupune că este media recenziilor din setul de date, dar descrierea de pe Kaggle este "Scorul mediu al hotelului, calculat pe baza celui mai recent comentariu din ultimul an". Acest lucru nu pare foarte util, dar putem calcula propria noastră medie bazată pe scorurile recenziilor din setul de date. Folosind același hotel ca exemplu, scorul mediu al hotelului este dat ca 7.1, dar scorul calculat (scorul mediu al recenzorilor din setul de date) este 6.8. Acesta este apropiat, dar nu aceeași valoare, și putem doar presupune că scorurile date în recenziile Additional_Number_of_Scoring
au crescut media la 7.1. Din păcate, fără nicio modalitate de a testa sau de a dovedi această afirmație, este dificil să folosim sau să avem încredere în Average_Score
, Additional_Number_of_Scoring
și Total_Number_of_Reviews
atunci când se bazează pe, sau se referă la, date pe care nu le avem.
Pentru a complica lucrurile și mai mult, hotelul cu al doilea cel mai mare număr de recenzii are un scor mediu calculat de 8.12, iar scorul mediu din setul de date este 8.1. Este acest scor corect o coincidență sau este primul hotel o discrepanță?
Pe posibilitatea ca acest hotel să fie un punct de excepție și că poate majoritatea valorilor se potrivesc (dar unele nu dintr-un motiv oarecare), vom scrie un program scurt în continuare pentru a explora valorile din setul de date și a determina utilizarea corectă (sau neutilizarea) valorilor.
🚨 O notă de precauție
Când lucrați cu acest set de date, veți scrie cod care calculează ceva din text fără a fi nevoie să citiți sau să analizați textul în mod direct. Aceasta este esența NLP-ului, interpretarea semnificației sau sentimentului fără a fi nevoie ca un om să o facă. Totuși, este posibil să citiți unele dintre recenziile negative. Vă îndemn să nu o faceți, deoarece nu este necesar. Unele dintre ele sunt absurde sau irelevante, cum ar fi recenzii negative despre hotel de genul „Vremea nu a fost grozavă”, ceva ce este dincolo de controlul hotelului sau, de fapt, al oricui. Dar există și o latură întunecată a unor recenzii. Uneori, recenziile negative sunt rasiste, sexiste sau discriminatorii pe criterii de vârstă. Acest lucru este regretabil, dar de așteptat într-un set de date extras de pe un site public. Unii recenzori lasă comentarii pe care le-ați putea considera dezgustătoare, inconfortabile sau deranjante. Este mai bine să lăsați codul să măsoare sentimentul decât să le citiți voi înșivă și să fiți afectați. Acestea fiind spuse, este vorba de o minoritate care scrie astfel de lucruri, dar ele există totuși.
Exercițiu - Explorarea datelor
Încarcă datele
Ajunge cu examinarea vizuală a datelor, acum vei scrie cod și vei obține răspunsuri! Această secțiune folosește biblioteca pandas. Prima ta sarcină este să te asiguri că poți încărca și citi datele CSV. Biblioteca pandas are un loader rapid pentru fișiere CSV, iar rezultatul este plasat într-un dataframe, la fel ca în lecțiile anterioare. Fișierul CSV pe care îl încărcăm are peste jumătate de milion de rânduri, dar doar 17 coloane. Pandas îți oferă multe modalități puternice de a interacționa cu un dataframe, inclusiv abilitatea de a efectua operații pe fiecare rând.
De aici înainte, în această lecție, vor fi fragmente de cod și câteva explicații ale codului, precum și discuții despre ce înseamnă rezultatele. Folosește notebook.ipynb inclus pentru codul tău.
Să începem cu încărcarea fișierului de date pe care îl vei folosi:
# 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")
Acum că datele sunt încărcate, putem efectua câteva operații asupra lor. Păstrează acest cod în partea de sus a programului pentru următoarea parte.
Explorează datele
În acest caz, datele sunt deja curate, ceea ce înseamnă că sunt gata de lucru și nu conțin caractere în alte limbi care ar putea încurca algoritmii care se așteaptă doar la caractere în limba engleză.
✅ Este posibil să trebuiască să lucrezi cu date care necesită o procesare inițială pentru a le formata înainte de a aplica tehnici NLP, dar nu de această dată. Dacă ar fi necesar, cum ai gestiona caracterele non-engleze?
Ia un moment pentru a te asigura că, odată ce datele sunt încărcate, le poți explora cu cod. Este foarte ușor să vrei să te concentrezi pe coloanele Negative_Review
și Positive_Review
. Acestea sunt pline de text natural pentru algoritmii tăi NLP. Dar stai! Înainte de a te arunca în NLP și sentiment, ar trebui să urmezi codul de mai jos pentru a verifica dacă valorile date în setul de date se potrivesc cu valorile pe care le calculezi cu pandas.
Operații pe dataframe
Prima sarcină din această lecție este să verifici dacă următoarele afirmații sunt corecte, scriind cod care examinează dataframe-ul (fără a-l modifica).
La fel ca multe sarcini de programare, există mai multe moduri de a le finaliza, dar un sfat bun este să o faci în cel mai simplu și ușor mod posibil, mai ales dacă va fi mai ușor de înțeles când te vei întoarce la acest cod în viitor. Cu dataframe-uri, există un API cuprinzător care va avea adesea o modalitate eficientă de a face ceea ce dorești.
Tratează următoarele întrebări ca sarcini de cod și încearcă să le răspunzi fără a te uita la soluție.
- Afișează forma dataframe-ului pe care tocmai l-ai încărcat (forma este numărul de rânduri și coloane).
- Calculează frecvența naționalităților recenzorilor:
- Câte valori distincte există pentru coloana
Reviewer_Nationality
și care sunt acestea? - Care este naționalitatea recenzorului cea mai comună în setul de date (afișează țara și numărul de recenzii)?
- Care sunt următoarele 10 cele mai frecvente naționalități și frecvența lor?
- Câte valori distincte există pentru coloana
- Care a fost hotelul cel mai frecvent recenzat pentru fiecare dintre cele mai frecvente 10 naționalități ale recenzorilor?
- Câte recenzii sunt per hotel (frecvența recenziilor hotelului) în setul de date?
- Deși există o coloană
Average_Score
pentru fiecare hotel în setul de date, poți calcula și un scor mediu (obținând media tuturor scorurilor recenzorilor din setul de date pentru fiecare hotel). Adaugă o nouă coloană în dataframe-ul tău cu antetulCalc_Average_Score
care conține acea medie calculată. - Există hoteluri care au același
Average_Score
șiCalc_Average_Score
(rotunjite la o zecimală)?- Încearcă să scrii o funcție Python care ia un Series (rând) ca argument și compară valorile, afișând un mesaj când valorile nu sunt egale. Apoi folosește metoda
.apply()
pentru a procesa fiecare rând cu funcția.
- Încearcă să scrii o funcție Python care ia un Series (rând) ca argument și compară valorile, afișând un mesaj când valorile nu sunt egale. Apoi folosește metoda
- Calculează și afișează câte rânduri au valori "No Negative" în coloana
Negative_Review
. - Calculează și afișează câte rânduri au valori "No Positive" în coloana
Positive_Review
. - Calculează și afișează câte rânduri au valori "No Positive" în coloana
Positive_Review
și valori "No Negative" în coloanaNegative_Review
.
Răspunsuri în cod
-
Afișează forma dataframe-ului pe care tocmai l-ai încărcat (forma este numărul de rânduri și coloane).
print("The shape of the data (rows, cols) is " + str(df.shape)) > The shape of the data (rows, cols) is (515738, 17)
-
Calculează frecvența naționalităților recenzorilor:
- Câte valori distincte există pentru coloana
Reviewer_Nationality
și care sunt acestea? - Care este naționalitatea recenzorului cea mai comună în setul de date (afișează țara și numărul de recenzii)?
# 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
-
Care sunt următoarele 10 cele mai frecvente naționalități și frecvența lor?
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
- Câte valori distincte există pentru coloana
-
Care a fost hotelul cel mai frecvent recenzat pentru fiecare dintre cele mai frecvente 10 naționalități ale recenzorilor?
# 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.
-
Câte recenzii sunt per hotel (frecvența recenziilor hotelului) în setul de date?
# 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 Poți observa că rezultatele numărate în setul de date nu se potrivesc cu valoarea din
Total_Number_of_Reviews
. Nu este clar dacă această valoare din setul de date reprezenta numărul total de recenzii pe care hotelul le avea, dar nu toate au fost extrase, sau alt calcul.Total_Number_of_Reviews
nu este utilizat în model din cauza acestei neclarități. -
Deși există o coloană
Average_Score
pentru fiecare hotel în setul de date, poți calcula și un scor mediu (obținând media tuturor scorurilor recenzorilor din setul de date pentru fiecare hotel). Adaugă o nouă coloană în dataframe-ul tău cu antetulCalc_Average_Score
care conține acea medie calculată. Afișează coloaneleHotel_Name
,Average_Score
șiCalc_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"]])
Poți să te întrebi despre valoarea
Average_Score
și de ce este uneori diferită de scorul mediu calculat. Deoarece nu putem ști de ce unele valori se potrivesc, dar altele au o diferență, este mai sigur în acest caz să folosim scorurile recenzorilor pe care le avem pentru a calcula media noi înșine. Totuși, diferențele sunt de obicei foarte mici, iată hotelurile cu cea mai mare deviație între media din setul de date și media calculată: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 Cu doar 1 hotel având o diferență de scor mai mare de 1, înseamnă că probabil putem ignora diferența și să folosim scorul mediu calculat.
-
Calculează și afișează câte rânduri au valori "No Negative" în coloana
Negative_Review
. -
Calculează și afișează câte rânduri au valori "No Positive" în coloana
Positive_Review
. -
Calculează și afișează câte rânduri au valori "No Positive" în coloana
Positive_Review
și valori "No Negative" în coloanaNegative_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
O altă metodă
O altă metodă de a număra elementele fără Lambdas și de a folosi sum pentru a număra rândurile:
# 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
Poți să fi observat că există 127 rânduri care au atât valori "No Negative", cât și "No Positive" pentru coloanele Negative_Review
și Positive_Review
respectiv. Asta înseamnă că recenzorul a dat hotelului un scor numeric, dar a refuzat să scrie fie o recenzie pozitivă, fie negativă. Din fericire, aceasta este o cantitate mică de rânduri (127 din 515738, sau 0.02%), deci probabil nu va influența modelul sau rezultatele într-o direcție particulară, dar s-ar putea să nu te fi așteptat ca un set de date de recenzii să aibă rânduri fără recenzii, așa că merită să explorezi datele pentru a descoperi astfel de rânduri.
Acum că ai explorat setul de date, în lecția următoare vei filtra datele și vei adăuga o analiză a sentimentului.
🚀Provocare
Această lecție demonstrează, așa cum am văzut în lecțiile anterioare, cât de important este să înțelegi datele și particularitățile lor înainte de a efectua operații asupra lor. Datele bazate pe text, în special, necesită o examinare atentă. Explorează diverse seturi de date bogate în text și vezi dacă poți descoperi zone care ar putea introduce bias sau sentiment distorsionat într-un model.
Quiz post-lectură
Recapitulare și studiu individual
Urmează acest parcurs de învățare despre NLP pentru a descoperi instrumente pe care să le încerci atunci când construiești modele bazate pe vorbire și text.
Temă
Declinare de responsabilitate:
Acest document a fost tradus folosind serviciul de traducere AI Co-op Translator. Deși ne străduim să asigurăm acuratețea, vă rugăm să fiți conștienți că traducerile automate pot conține erori sau inexactități. Documentul original în limba sa natală ar trebui considerat sursa autoritară. Pentru informații critice, se recomandă traducerea profesională realizată de un specialist uman. Nu ne asumăm responsabilitatea pentru eventualele neînțelegeri sau interpretări greșite care pot apărea din utilizarea acestei traduceri.