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/th/6-NLP/4-Hotel-Reviews-1/README.md

58 KiB

การวิเคราะห์ความรู้สึกด้วยรีวิวโรงแรม - การประมวลผลข้อมูล

ในส่วนนี้ คุณจะใช้เทคนิคที่เรียนรู้ในบทเรียนก่อนหน้าเพื่อทำการวิเคราะห์ข้อมูลเบื้องต้นในชุดข้อมูลขนาดใหญ่ เมื่อคุณเข้าใจถึงความมีประโยชน์ของคอลัมน์ต่าง ๆ แล้ว คุณจะได้เรียนรู้:

  • วิธีลบคอลัมน์ที่ไม่จำเป็น
  • วิธีคำนวณข้อมูลใหม่จากคอลัมน์ที่มีอยู่
  • วิธีบันทึกชุดข้อมูลที่ได้เพื่อใช้ในความท้าทายสุดท้าย

แบบทดสอบก่อนเรียน

บทนำ

จนถึงตอนนี้ คุณได้เรียนรู้ว่าข้อมูลข้อความนั้นแตกต่างจากข้อมูลประเภทตัวเลขอย่างมาก หากข้อความนั้นถูกเขียนหรือพูดโดยมนุษย์ ข้อมูลนั้นสามารถถูกวิเคราะห์เพื่อค้นหารูปแบบ ความถี่ ความรู้สึก และความหมาย บทเรียนนี้จะนำคุณเข้าสู่ชุดข้อมูลจริงพร้อมความท้าทายจริง: 515K Hotel Reviews Data in Europe ซึ่งมี CC0: Public Domain license ข้อมูลนี้ถูกดึงมาจาก Booking.com จากแหล่งข้อมูลสาธารณะ ผู้สร้างชุดข้อมูลคือ Jiashen Liu

การเตรียมตัว

สิ่งที่คุณต้องมี:

  • ความสามารถในการรันไฟล์ .ipynb โดยใช้ Python 3
  • pandas
  • NLTK, ซึ่งคุณควรติดตั้งในเครื่อง
  • ชุดข้อมูลที่มีอยู่ใน Kaggle 515K Hotel Reviews Data in Europe ขนาดประมาณ 230 MB เมื่อคลายซิปแล้ว ดาวน์โหลดไปยังโฟลเดอร์ /data ที่เกี่ยวข้องกับบทเรียน NLP เหล่านี้

การวิเคราะห์ข้อมูลเบื้องต้น

ความท้าทายนี้สมมติว่าคุณกำลังสร้างบอทแนะนำโรงแรมโดยใช้การวิเคราะห์ความรู้สึกและคะแนนรีวิวของผู้เข้าพัก ชุดข้อมูลที่คุณจะใช้ประกอบด้วยรีวิวของโรงแรม 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"
    • โปรดทราบว่าผู้รีวิวอาจเขียนรีวิวที่เป็นบวกในคอลัมน์ Negative review (เช่น "ไม่มีอะไรแย่เกี่ยวกับโรงแรมนี้")
  • Review_Total_Negative_Word_Counts
    • จำนวนคำที่เป็นลบสูงขึ้นบ่งชี้คะแนนที่ต่ำลง (โดยไม่ตรวจสอบความรู้สึก)
  • Positive_Review
    • หากผู้รีวิวไม่ได้เขียนอะไร คอลัมน์นี้จะมี "No Positive"
    • โปรดทราบว่าผู้รีวิวอาจเขียนรีวิวที่เป็นลบในคอลัมน์ Positive review (เช่น "ไม่มีอะไรดีเกี่ยวกับโรงแรมนี้เลย")
  • 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 ขณะนี้ไม่ใช่โรงแรมแต่เป็นไซต์ก่อสร้าง ฉันถูกรบกวนตั้งแต่เช้าตรู่และตลอดทั้งวันด้วยเสียงก่อสร้างที่ไม่สามารถยอมรับได้ขณะพักผ่อนหลังจากการเดินทางไกลและทำงานในห้อง คนงานทำงานตลอดทั้งวัน เช่น ใช้เครื่องเจาะในห้องข้างเคียง ฉันขอเปลี่ยนห้องแต่ไม่มีห้องเงียบให้ เพื่อให้แย่ลงไปอีก ฉันถูกเรียกเก็บเงินเกินราคา ฉันเช็คเอาท์ในตอนเย็นเนื่องจากต้องออกเดินทางแต่เช้าตรู่และได้รับใบเรียกเก็บเงินที่เหมาะสม วันต่อมาโรงแรมเรียกเก็บเงินอีกครั้งโดยไม่ได้รับความยินยอมในราคาที่เกินกว่าที่จองไว้ เป็นสถานที่ที่แย่มาก อย่าทำร้ายตัวเองด้วยการจองที่นี่ ไม่มีอะไร สถานที่แย่มาก หลีกเลี่ยง ทริปธุรกิจ คู่รัก ห้องมาตรฐานเตียงคู่ พัก 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_of_Scoring ค่านั้นคือ 2682 และเมื่อเพิ่มเข้าไปใน 4789 จะได้ 7471 ซึ่งยังคงขาดไป 1615 จาก Total_Number_of_Reviews

หากคุณใช้คอลัมน์ Average_Score คุณอาจสันนิษฐานว่ามันคือค่าเฉลี่ยของรีวิวในชุดข้อมูล แต่คำอธิบายจาก Kaggle คือ "คะแนนเฉลี่ยของโรงแรมที่คำนวณจากความคิดเห็นล่าสุดในปีที่ผ่านมา" ซึ่งดูเหมือนจะไม่เป็นประโยชน์นัก แต่เราสามารถคำนวณค่าเฉลี่ยของเราเองจากคะแนนรีวิวในชุดข้อมูล โดยใช้โรงแรมเดียวกันเป็นตัวอย่าง คะแนนเฉลี่ยของโรงแรมที่ให้ไว้คือ 7.1 แต่คะแนนที่คำนวณได้ (คะแนนเฉลี่ยของผู้รีวิว ใน ชุดข้อมูล) คือ 6.8 ซึ่งใกล้เคียงกัน แต่ไม่ใช่ค่าเดียวกัน และเราสามารถเดาได้ว่าคะแนนที่ให้ไว้ในรีวิว Additional_Number_of_Scoring เพิ่มค่าเฉลี่ยเป็น 7.1 น่าเสียดายที่ไม่มีวิธีทดสอบหรือพิสูจน์ข้อสันนิษฐานนี้ จึงยากที่จะใช้หรือเชื่อถือ Average_Score, Additional_Number_of_Scoring และ Total_Number_of_Reviews เมื่อพวกมันอ้างอิงถึงข้อมูลที่เราไม่มี

เพื่อทำให้เรื่องซับซ้อนขึ้น โรงแรมที่มีจำนวนรีวิวมากที่สุดอันดับสองมีคะแนนเฉลี่ยที่คำนวณได้คือ 8.12 และคะแนน Average_Score ในชุดข้อมูลคือ 8.1 นี่เป็นคะแนนที่ถูกต้องโดยบังเอิญหรือโรงแรมแรกเป็นความไม่สอดคล้องกัน?

ในความเป็นไปได้ที่โรงแรมเหล่านี้อาจเป็นค่าผิดปกติ และอาจเป็นไปได้ว่าค่าที่เหลือส่วนใหญ่สอดคล้องกัน (แต่บางค่าที่ไม่สอดคล้องกันด้วยเหตุผลบางประการ) เราจะเขียนโปรแกรมสั้น ๆ ต่อไปเพื่อสำรวจค่าต่าง ๆ ในชุดข้อมูลและกำหนดการใช้งานที่ถูกต้อง (หรือไม่ใช้งาน) ของค่าต่าง ๆ

🚨 หมายเหตุสำคัญ

เมื่อทำงานกับชุดข้อมูลนี้ คุณจะเขียนโค้ดที่คำนวณบางสิ่งจากข้อความโดยไม่จำเป็นต้องอ่านหรือวิเคราะห์ข้อความด้วยตัวเอง นี่คือแก่นแท้ของ 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 และการวิเคราะห์ความรู้สึก คุณควรทำตามโค้ดด้านล่างเพื่อยืนยันว่าค่าที่ให้มาในชุดข้อมูลตรงกับค่าที่คุณคำนวณด้วย pandas หรือไม่

การดำเนินการกับ Dataframe

งานแรกในบทเรียนนี้คือการตรวจสอบว่าข้อความต่อไปนี้ถูกต้องหรือไม่โดยการเขียนโค้ดเพื่อตรวจสอบ dataframe (โดยไม่เปลี่ยนแปลงมัน)

เช่นเดียวกับงานโปรแกรมมิ่งหลายๆ อย่าง มีหลายวิธีในการทำสิ่งนี้ให้สำเร็จ แต่คำแนะนำที่ดีคือทำในวิธีที่ง่ายที่สุดและเข้าใจง่ายที่สุด โดยเฉพาะอย่างยิ่งถ้ามันจะง่ายต่อการเข้าใจเมื่อคุณกลับมาดูโค้ดนี้ในอนาคต ด้วย dataframe มี API ที่ครอบคลุมซึ่งมักจะมีวิธีการทำสิ่งที่คุณต้องการอย่างมีประสิทธิภาพ

ปฏิบัติต่อคำถามต่อไปนี้เป็นงานเขียนโค้ดและพยายามตอบโดยไม่ดูคำตอบ

  1. พิมพ์ shape ของ dataframe ที่คุณเพิ่งโหลด (shape คือจำนวนแถวและคอลัมน์)
  2. คำนวณจำนวนครั้งที่ปรากฏของสัญชาติผู้รีวิว:
    1. มีค่าที่แตกต่างกันกี่ค่าในคอลัมน์ Reviewer_Nationality และมีค่าอะไรบ้าง?
    2. สัญชาติผู้รีวิวใดที่พบมากที่สุดในชุดข้อมูล (พิมพ์ชื่อประเทศและจำนวนรีวิว)?
    3. สัญชาติที่พบมากที่สุด 10 อันดับถัดไปและจำนวนครั้งที่พบคืออะไร?
  3. โรงแรมที่ถูกรีวิวมากที่สุดสำหรับแต่ละสัญชาติผู้รีวิว 10 อันดับแรกคืออะไร?
  4. มีรีวิวกี่รายการต่อโรงแรม (จำนวนครั้งที่โรงแรมถูกรีวิว) ในชุดข้อมูล?
  5. แม้ว่าจะมีคอลัมน์ Average_Score สำหรับแต่ละโรงแรมในชุดข้อมูล คุณยังสามารถคำนวณคะแนนเฉลี่ย (โดยการหาค่าเฉลี่ยของคะแนนผู้รีวิวทั้งหมดในชุดข้อมูลสำหรับแต่ละโรงแรม) เพิ่มคอลัมน์ใหม่ใน dataframe ของคุณโดยใช้ชื่อคอลัมน์ Calc_Average_Score ที่มีค่าเฉลี่ยที่คำนวณได้
  6. มีโรงแรมใดบ้างที่มีค่า Average_Score และ Calc_Average_Score เท่ากัน (ปัดเศษทศนิยม 1 ตำแหน่ง)?
    1. ลองเขียนฟังก์ชัน Python ที่รับ Series (แถว) เป็นอาร์กิวเมนต์และเปรียบเทียบค่า โดยพิมพ์ข้อความเมื่อค่าต่างกัน จากนั้นใช้เมธอด .apply() เพื่อประมวลผลทุกแถวด้วยฟังก์ชัน
  7. คำนวณและพิมพ์จำนวนแถวที่มีค่าคอลัมน์ Negative_Review เป็น "No Negative"
  8. คำนวณและพิมพ์จำนวนแถวที่มีค่าคอลัมน์ Positive_Review เป็น "No Positive"
  9. คำนวณและพิมพ์จำนวนแถวที่มีค่าคอลัมน์ Positive_Review เป็น "No Positive" และ Negative_Review เป็น "No Negative"

คำตอบโค้ด

  1. พิมพ์ shape ของ dataframe ที่คุณเพิ่งโหลด (shape คือจำนวนแถวและคอลัมน์)

    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. สัญชาติผู้รีวิวใดที่พบมากที่สุดในชุดข้อมูล (พิมพ์ชื่อประเทศและจำนวนรีวิว)?
    # 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. มีรีวิวกี่รายการต่อโรงแรม (จำนวนครั้งที่โรงแรมถูกรีวิว) ในชุดข้อมูล?

    # 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

    คุณอาจสังเกตเห็นว่าผลลัพธ์ ที่นับในชุดข้อมูล ไม่ตรงกับค่าที่อยู่ใน Total_Number_of_Reviews ไม่ชัดเจนว่าค่านี้ในชุดข้อมูลแสดงถึงจำนวนรีวิวทั้งหมดที่โรงแรมมี แต่ไม่ได้ถูกดึงข้อมูลทั้งหมด หรือเป็นการคำนวณอื่น Total_Number_of_Reviews ไม่ได้ถูกใช้ในโมเดลเนื่องจากความไม่ชัดเจนนี้

  5. แม้ว่าจะมีคอลัมน์ Average_Score สำหรับแต่ละโรงแรมในชุดข้อมูล คุณยังสามารถคำนวณคะแนนเฉลี่ย (โดยการหาค่าเฉลี่ยของคะแนนผู้รีวิวทั้งหมดในชุดข้อมูลสำหรับแต่ละโรงแรม) เพิ่มคอลัมน์ใหม่ใน 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 และเหตุใดจึงแตกต่างจากคะแนนเฉลี่ยที่คำนวณได้ในบางครั้ง เนื่องจากเราไม่สามารถทราบได้ว่าทำไมบางค่าจึงตรงกัน แต่บางค่ามีความแตกต่าง ในกรณีนี้ปลอดภัยที่สุดที่จะใช้คะแนนรีวิวที่เรามีเพื่อคำนวณค่าเฉลี่ยด้วยตัวเอง อย่างไรก็ตาม ความแตกต่างมักจะเล็กน้อย นี่คือโรงแรมที่มีความแตกต่างมากที่สุดระหว่างค่าเฉลี่ยในชุดข้อมูลและค่าเฉลี่ยที่คำนวณได้:

    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 หมายความว่าเราสามารถมองข้ามความแตกต่างนี้และใช้คะแนนเฉลี่ยที่คำนวณได้

  6. คำนวณและพิมพ์จำนวนแถวที่มีค่าคอลัมน์ Negative_Review เป็น "No Negative"

  7. คำนวณและพิมพ์จำนวนแถวที่มีค่าคอลัมน์ Positive_Review เป็น "No Positive"

  8. คำนวณและพิมพ์จำนวนแถวที่มีค่าคอลัมน์ Positive_Review เป็น "No Positive" และ Negative_Review เป็น "No Negative"

    # 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
    

อีกวิธีหนึ่ง

อีกวิธีหนึ่งในการนับรายการโดยไม่ใช้ Lambda และใช้ 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%) ดังนั้นจึงไม่น่าจะทำให้โมเดลหรือผลลัพธ์ของเราผิดเพี้ยนไปในทิศทางใด แต่คุณอาจไม่คาดคิดว่าชุดข้อมูลรีวิวจะมีแถวที่ไม่มีรีวิวเลย ดังนั้นจึงควรสำรวจข้อมูลเพื่อค้นหาแถวแบบนี้

ตอนนี้คุณได้สำรวจชุดข้อมูลแล้ว ในบทเรียนถัดไปคุณจะกรองข้อมูลและเพิ่มการวิเคราะห์ความรู้สึก


🚀ความท้าทาย

บทเรียนนี้แสดงให้เห็นว่า เช่นเดียวกับที่เราเห็นในบทเรียนก่อนหน้า การทำความเข้าใจข้อมูลและข้อบกพร่องของมันมีความสำคัญอย่างยิ่งก่อนที่จะดำเนินการใดๆ กับมัน ข้อมูลที่เป็นข้อความโดยเฉพาะต้องได้รับการตรวจสอบอย่างละเอียด ลองสำรวจชุดข้อมูลที่มีข้อความจำนวนมากและดูว่าคุณสามารถค้นพบพื้นที่ที่อาจแนะนำอคติหรือความรู้สึกที่ผิดเพี้ยนในโมเดลได้หรือไม่

แบบทดสอบหลังการบรรยาย

ทบทวนและศึกษาด้วยตนเอง

ลอง เส้นทางการเรียนรู้เกี่ยวกับ NLP นี้ เพื่อค้นหาเครื่องมือที่คุณสามารถลองใช้เมื่อสร้างโมเดลที่เน้นข้อความและเสียงพูด

การบ้าน

NLTK


ข้อจำกัดความรับผิดชอบ:
เอกสารนี้ได้รับการแปลโดยใช้บริการแปลภาษา AI Co-op Translator แม้ว่าเราจะพยายามให้การแปลมีความถูกต้อง แต่โปรดทราบว่าการแปลโดยอัตโนมัติอาจมีข้อผิดพลาดหรือความไม่ถูกต้อง เอกสารต้นฉบับในภาษาดั้งเดิมควรถือเป็นแหล่งข้อมูลที่เชื่อถือได้ สำหรับข้อมูลที่สำคัญ ขอแนะนำให้ใช้บริการแปลภาษามืออาชีพ เราไม่รับผิดชอบต่อความเข้าใจผิดหรือการตีความผิดที่เกิดจากการใช้การแปลนี้