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/5-Clustering/1-Visualize/solution/R/lesson_14-R.ipynb

493 lines
46 KiB

{
"cells": [
{
"cell_type": "markdown",
"source": [
"## **การวิเคราะห์เพลงไนจีเรียที่ดึงข้อมูลจาก Spotify**\n",
"\n",
"การจัดกลุ่ม (Clustering) เป็นรูปแบบหนึ่งของ [การเรียนรู้แบบไม่มีผู้สอน](https://wikipedia.org/wiki/Unsupervised_learning) ซึ่งสมมติว่าชุดข้อมูลไม่มีการติดป้ายกำกับ หรือข้อมูลนำเข้าไม่ได้จับคู่กับผลลัพธ์ที่กำหนดไว้ล่วงหน้า โดยใช้หลากหลายอัลกอริทึมเพื่อจัดเรียงข้อมูลที่ไม่มีป้ายกำกับและสร้างกลุ่มตามรูปแบบที่พบในข้อมูล\n",
"\n",
"[**แบบทดสอบก่อนการบรรยาย**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/27/)\n",
"\n",
"### **บทนำ**\n",
"\n",
"[การจัดกลุ่ม](https://link.springer.com/referenceworkentry/10.1007%2F978-0-387-30164-8_124) มีประโยชน์มากสำหรับการสำรวจข้อมูล ลองมาดูกันว่ามันสามารถช่วยค้นหาแนวโน้มและรูปแบบในวิธีที่ผู้ฟังชาวไนจีเรียบริโภคเพลงได้หรือไม่\n",
"\n",
"> ✅ ลองใช้เวลาสักครู่คิดถึงการใช้งานของการจัดกลุ่ม ในชีวิตจริง การจัดกลุ่มเกิดขึ้นเมื่อคุณมีกองผ้าซักและต้องแยกเสื้อผ้าของสมาชิกในครอบครัวออกจากกัน 🧦👕👖🩲 ในด้านวิทยาศาสตร์ข้อมูล การจัดกลุ่มเกิดขึ้นเมื่อพยายามวิเคราะห์ความชอบของผู้ใช้ หรือกำหนดลักษณะของชุดข้อมูลที่ไม่มีป้ายกำกับ การจัดกลุ่มช่วยให้เข้าใจความยุ่งเหยิง เช่น ลิ้นชักถุงเท้า\n",
"\n",
"ในสภาพแวดล้อมการทำงาน การจัดกลุ่มสามารถใช้เพื่อกำหนดสิ่งต่าง ๆ เช่น การแบ่งส่วนตลาด หรือการระบุว่ากลุ่มอายุใดซื้อสินค้าอะไร ตัวอย่างเช่น อีกการใช้งานหนึ่งคือการตรวจจับความผิดปกติ เช่น การตรวจจับการฉ้อโกงจากชุดข้อมูลธุรกรรมบัตรเครดิต หรือคุณอาจใช้การจัดกลุ่มเพื่อระบุเนื้องอกจากชุดภาพสแกนทางการแพทย์\n",
"\n",
"✅ ลองคิดสักครู่เกี่ยวกับวิธีที่คุณอาจเคยพบการจัดกลุ่มในชีวิตจริง เช่น ในธนาคาร อีคอมเมิร์ซ หรือการตั้งค่าทางธุรกิจ\n",
"\n",
"> 🎓 น่าสนใจที่การวิเคราะห์การจัดกลุ่มมีต้นกำเนิดในสาขามานุษยวิทยาและจิตวิทยาในช่วงปี 1930 คุณจินตนาการได้ไหมว่ามันอาจถูกใช้อย่างไร?\n",
"\n",
"อีกทางหนึ่ง คุณสามารถใช้มันเพื่อจัดกลุ่มผลการค้นหา เช่น ลิงก์การช็อปปิ้ง รูปภาพ หรือรีวิว การจัดกลุ่มมีประโยชน์เมื่อคุณมีชุดข้อมูลขนาดใหญ่ที่ต้องการลดขนาดลงและต้องการวิเคราะห์ในเชิงลึกมากขึ้น ดังนั้นเทคนิคนี้สามารถใช้เพื่อเรียนรู้เกี่ยวกับข้อมูลก่อนที่จะสร้างโมเดลอื่น ๆ\n",
"\n",
"✅ เมื่อข้อมูลของคุณถูกจัดระเบียบในกลุ่ม คุณสามารถกำหนดรหัสกลุ่มให้กับมัน เทคนิคนี้มีประโยชน์เมื่อคุณต้องการรักษาความเป็นส่วนตัวของชุดข้อมูล คุณสามารถอ้างถึงจุดข้อมูลโดยใช้รหัสกลุ่มแทนที่จะใช้ข้อมูลที่สามารถระบุตัวตนได้ คุณคิดเหตุผลอื่น ๆ ได้ไหมว่าทำไมคุณถึงเลือกใช้รหัสกลุ่มแทนองค์ประกอบอื่น ๆ ของกลุ่มเพื่อระบุข้อมูล?\n",
"\n",
"### เริ่มต้นกับการจัดกลุ่ม\n",
"\n",
"> 🎓 วิธีที่เราสร้างกลุ่มมีความเกี่ยวข้องอย่างมากกับวิธีที่เรารวบรวมจุดข้อมูลเข้าด้วยกัน ลองมาทำความเข้าใจคำศัพท์บางคำ:\n",
">\n",
"> 🎓 ['Transductive' vs. 'Inductive'](https://wikipedia.org/wiki/Transduction_(machine_learning))\n",
">\n",
"> การอนุมานแบบ Transductive มาจากกรณีการฝึกอบรมที่สังเกตได้ซึ่งจับคู่กับกรณีทดสอบเฉพาะ การอนุมานแบบ Inductive มาจากกรณีการฝึกอบรมที่จับคู่กับกฎทั่วไปซึ่งจะถูกนำไปใช้กับกรณีทดสอบในภายหลัง\n",
">\n",
"> ตัวอย่าง: ลองจินตนาการว่าคุณมีชุดข้อมูลที่มีการติดป้ายกำกับบางส่วน บางรายการเป็น 'แผ่นเสียง' บางรายการเป็น 'ซีดี' และบางรายการไม่มีป้ายกำกับ งานของคุณคือการให้ป้ายกำกับกับข้อมูลที่ไม่มีป้ายกำกับ หากคุณเลือกวิธี Inductive คุณจะฝึกโมเดลเพื่อค้นหา 'แผ่นเสียง' และ 'ซีดี' และนำป้ายกำกับเหล่านั้นไปใช้กับข้อมูลที่ไม่มีป้ายกำกับ วิธีนี้จะมีปัญหาในการจัดประเภทสิ่งที่จริง ๆ แล้วเป็น 'เทปคาสเซ็ต' ในทางกลับกัน วิธี Transductive จะจัดการกับข้อมูลที่ไม่รู้จักได้อย่างมีประสิทธิภาพมากกว่า โดยทำงานเพื่อจัดกลุ่มรายการที่คล้ายกันเข้าด้วยกันและนำป้ายกำกับไปใช้กับกลุ่ม ในกรณีนี้ กลุ่มอาจสะท้อนถึง 'สิ่งดนตรีทรงกลม' และ 'สิ่งดนตรีทรงสี่เหลี่ยม'\n",
">\n",
"> 🎓 ['Non-flat' vs. 'Flat' Geometry](https://datascience.stackexchange.com/questions/52260/terminology-flat-geometry-in-the-context-of-clustering)\n",
">\n",
"> มาจากคำศัพท์ทางคณิตศาสตร์ 'Non-flat' vs. 'Flat' Geometry หมายถึงการวัดระยะทางระหว่างจุดโดยใช้วิธีการทางเรขาคณิตแบบ 'Flat' ([Euclidean](https://wikipedia.org/wiki/Euclidean_geometry)) หรือ 'Non-flat' (Non-Euclidean)\n",
">\n",
"> 'Flat' ในบริบทนี้หมายถึงเรขาคณิตแบบยูคลิด (บางส่วนของมันถูกสอนเป็นเรขาคณิต 'Plane') และ 'Non-flat' หมายถึงเรขาคณิตแบบไม่ใช่ยูคลิด เรขาคณิตเกี่ยวข้องอะไรกับการเรียนรู้ของเครื่อง? เนื่องจากทั้งสองสาขามีรากฐานมาจากคณิตศาสตร์ จึงต้องมีวิธีการทั่วไปในการวัดระยะทางระหว่างจุดในกลุ่ม ซึ่งสามารถทำได้ในแบบ 'Flat' หรือ 'Non-flat' ขึ้นอยู่กับลักษณะของข้อมูล [ระยะทางแบบยูคลิด](https://wikipedia.org/wiki/Euclidean_distance) ถูกวัดเป็นความยาวของเส้นตรงระหว่างสองจุด [ระยะทางแบบไม่ใช่ยูคลิด](https://wikipedia.org/wiki/Non-Euclidean_geometry) ถูกวัดตามเส้นโค้ง หากข้อมูลของคุณเมื่อแสดงภาพดูเหมือนจะไม่อยู่บนระนาบ คุณอาจต้องใช้อัลกอริทึมเฉพาะเพื่อจัดการกับมัน\n",
"\n",
"<p >\n",
" <img src=\"../../images/flat-nonflat.png\"\n",
" width=\"600\"/>\n",
" <figcaption>อินโฟกราฟิกโดย Dasani Madipalli</figcaption>\n",
"\n",
"> 🎓 ['Distances'](https://web.stanford.edu/class/cs345a/slides/12-clustering.pdf)\n",
">\n",
"> กลุ่มถูกกำหนดโดยเมทริกซ์ระยะทาง เช่น ระยะทางระหว่างจุด ระยะทางนี้สามารถวัดได้หลายวิธี กลุ่มแบบยูคลิดถูกกำหนดโดยค่าเฉลี่ยของค่าจุด และมี 'Centroid' หรือจุดศูนย์กลาง ระยะทางจึงถูกวัดโดยระยะทางไปยัง Centroid นั้น ระยะทางแบบไม่ใช่ยูคลิดหมายถึง 'Clustroids' ซึ่งเป็นจุดที่ใกล้ที่สุดกับจุดอื่น ๆ Clustroids สามารถกำหนดได้หลายวิธี\n",
">\n",
"> 🎓 ['Constrained'](https://wikipedia.org/wiki/Constrained_clustering)\n",
">\n",
"> [การจัดกลุ่มแบบมีข้อจำกัด](https://web.cs.ucdavis.edu/~davidson/Publications/ICDMTutorial.pdf) แนะนำการเรียนรู้แบบกึ่งมีผู้สอนเข้าสู่วิธีการแบบไม่มีผู้สอน ความสัมพันธ์ระหว่างจุดถูกกำหนดเป็น 'ไม่สามารถเชื่อมโยง' หรือ 'ต้องเชื่อมโยง' ดังนั้นจึงมีการบังคับกฎบางอย่างในชุดข้อมูล\n",
">\n",
"> ตัวอย่าง: หากอัลกอริทึมถูกปล่อยให้ทำงานกับชุดข้อมูลที่ไม่มีป้ายกำกับหรือมีป้ายกำกับบางส่วน กลุ่มที่มันสร้างขึ้นอาจมีคุณภาพต่ำ ในตัวอย่างข้างต้น กลุ่มอาจจัดกลุ่ม 'สิ่งดนตรีทรงกลม' 'สิ่งดนตรีทรงสี่เหลี่ยม' 'สิ่งทรงสามเหลี่ยม' และ 'คุกกี้' หากมีการให้ข้อจำกัดหรือกฎบางอย่าง (\"รายการต้องทำจากพลาสติก\", \"รายการต้องสามารถผลิตเสียงดนตรีได้\") สิ่งนี้สามารถช่วย 'จำกัด' อัลกอริทึมให้เลือกได้ดีขึ้น\n",
">\n",
"> 🎓 'Density'\n",
">\n",
"> ข้อมูลที่มี 'เสียงรบกวน' ถือว่าเป็น 'หนาแน่น' ระยะทางระหว่างจุดในแต่ละกลุ่มอาจพิสูจน์ได้ว่ามีความหนาแน่นมากหรือน้อยเมื่อวิเคราะห์ และข้อมูลนี้จำเป็นต้องได้รับการวิเคราะห์ด้วยวิธีการจัดกลุ่มที่เหมาะสม [บทความนี้](https://www.kdnuggets.com/2020/02/understanding-density-based-clustering.html) แสดงให้เห็นความแตกต่างระหว่างการใช้ K-Means clustering กับ HDBSCAN เพื่อสำรวจชุดข้อมูลที่มีความหนาแน่นของกลุ่มไม่เท่ากัน\n",
"\n",
"เพิ่มความเข้าใจของคุณเกี่ยวกับเทคนิคการจัดกลุ่มใน [โมดูลการเรียนรู้](https://docs.microsoft.com/learn/modules/train-evaluate-cluster-models?WT.mc_id=academic-77952-leestott)\n",
"\n",
"### **อัลกอริทึมการจัดกลุ่ม**\n",
"\n",
"มีอัลกอริทึมการจัดกลุ่มมากกว่า 100 แบบ และการใช้งานขึ้นอยู่กับลักษณะของข้อมูลที่มีอยู่ ลองมาพูดถึงบางส่วนที่สำคัญ:\n",
"\n",
"- **การจัดกลุ่มแบบลำดับชั้น** หากวัตถุถูกจัดประเภทตามความใกล้ชิดกับวัตถุใกล้เคียงมากกว่ากับวัตถุที่อยู่ไกลออกไป กลุ่มจะถูกสร้างขึ้นตามระยะทางของสมาชิกไปยังและจากวัตถุอื่น ๆ การจัดกลุ่มแบบลำดับชั้นมีลักษณะโดยการรวมสองกลุ่มซ้ำ ๆ\n",
"\n",
"<p >\n",
" <img src=\"../../images/hierarchical.png\"\n",
" width=\"600\"/>\n",
" <figcaption>อินโฟกราฟิกโดย Dasani Madipalli</figcaption>\n",
"\n",
"- **การจัดกลุ่มแบบ Centroid** อัลกอริทึมยอดนิยมนี้ต้องการการเลือก 'k' หรือจำนวนกลุ่มที่จะสร้าง หลังจากนั้นอัลกอริทึมจะกำหนดจุดศูนย์กลางของกลุ่มและรวบรวมข้อมูลรอบจุดนั้น [K-means clustering](https://wikipedia.org/wiki/K-means_clustering) เป็นเวอร์ชันยอดนิยมของการจัดกลุ่มแบบ Centroid ซึ่งแยกชุดข้อมูลออกเป็น K กลุ่มที่กำหนดไว้ล่วงหน้า จุดศูนย์กลางถูกกำหนดโดยค่าเฉลี่ยที่ใกล้ที่สุด จึงเป็นที่มาของชื่อ ระยะทางยกกำลังสองจากกลุ่มจะถูกลดลง\n",
"\n",
"<p >\n",
" <img src=\"../../images/centroid.png\"\n",
" width=\"600\"/>\n",
" <figcaption>อินโฟกราฟิกโดย Dasani Madipalli</figcaption>\n",
"\n",
"- **การจัดกลุ่มแบบอิงการกระจาย** อิงตามการสร้างแบบจำลองทางสถิติ การจัดกลุ่มแบบอิงการกระจายมุ่งเน้นไปที่การกำหนดความน่าจะเป็นที่จุดข้อมูลจะอยู่ในกลุ่ม และกำหนดให้ตามนั้น วิธี Gaussian mixture เป็นส่วนหนึ่งของประเภทนี้\n",
"\n",
"- **การจัดกลุ่มแบบอิงความหนาแน่น** จุดข้อมูลจะถูกกำหนดให้กับกลุ่มตามความหนาแน่น หรือการรวมกลุ่มรอบ ๆ กัน จุดข้อมูลที่อยู่ไกลจากกลุ่มจะถือว่าเป็นข้อมูลรบกวนหรือเสียงรบกวน DBSCAN, Mean-shift และ OPTICS เป็นส่วนหนึ่งของประเภทนี้\n",
"\n",
"- **การจัดกลุ่มแบบอิงกริด** สำหรับชุดข้อมูลหลายมิติ จะมีการสร้างกริดและข้อมูลจะถูกแบ่งออกเป็นเซลล์ของกริดนั้น ซึ่งจะสร้างกลุ่มขึ้นมา\n",
"\n",
"วิธีที่ดีที่สุดในการเรียนรู้เกี่ยวกับการจัดกลุ่มคือการลองทำด้วยตัวเอง และนั่นคือสิ่งที่คุณจะทำในแบบฝึกหัดนี้\n",
"\n",
"เราจะต้องใช้แพ็กเกจบางอย่างเพื่อเริ่มต้นโมดูลนี้ คุณสามารถติดตั้งได้โดยใช้: `install.packages(c('tidyverse', 'tidymodels', 'DataExplorer', 'summarytools', 'plotly', 'paletteer', 'corrplot', 'patchwork'))`\n",
"\n",
"หรือใช้สคริปต์ด้านล่างเพื่อตรวจสอบว่าคุณมีแพ็กเกจที่จำเป็นสำหรับการทำโมดูลนี้หรือไม่ และติดตั้งให้คุณในกรณีที่บางแพ็กเกจขาดหายไป\n"
],
"metadata": {}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"suppressWarnings(if(!require(\"pacman\")) install.packages(\"pacman\"))\r\n",
"\r\n",
"pacman::p_load('tidyverse', 'tidymodels', 'DataExplorer', 'summarytools', 'plotly', 'paletteer', 'corrplot', 'patchwork')\r\n"
],
"outputs": [],
"metadata": {}
},
{
"cell_type": "markdown",
"source": [
"## แบบฝึกหัด - จัดกลุ่มข้อมูลของคุณ\n",
"\n",
"การจัดกลุ่มข้อมูล (Clustering) เป็นเทคนิคที่ได้รับประโยชน์อย่างมากจากการแสดงผลข้อมูลที่เหมาะสม ดังนั้นเรามาเริ่มต้นด้วยการแสดงผลข้อมูลเพลงของเรากัน การฝึกหัดนี้จะช่วยให้เราตัดสินใจได้ว่าวิธีการจัดกลุ่มข้อมูลแบบใดที่เหมาะสมที่สุดสำหรับลักษณะของข้อมูลนี้\n",
"\n",
"มาเริ่มต้นกันเลยด้วยการนำเข้าข้อมูล!\n"
],
"metadata": {}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Load the core tidyverse and make it available in your current R session\r\n",
"library(tidyverse)\r\n",
"\r\n",
"# Import the data into a tibble\r\n",
"df <- read_csv(file = \"https://raw.githubusercontent.com/microsoft/ML-For-Beginners/main/5-Clustering/data/nigerian-songs.csv\")\r\n",
"\r\n",
"# View the first 5 rows of the data set\r\n",
"df %>% \r\n",
" slice_head(n = 5)\r\n"
],
"outputs": [],
"metadata": {}
},
{
"cell_type": "markdown",
"source": [
"บางครั้งเราอาจต้องการข้อมูลเพิ่มเติมเล็กน้อยเกี่ยวกับข้อมูลของเรา เราสามารถดู `data` และ `โครงสร้างของมัน` ได้โดยใช้ฟังก์ชัน [*glimpse()*](https://pillar.r-lib.org/reference/glimpse.html):\n"
],
"metadata": {}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Glimpse into the data set\r\n",
"df %>% \r\n",
" glimpse()\r\n"
],
"outputs": [],
"metadata": {}
},
{
"cell_type": "markdown",
"source": [
"เยี่ยมมาก!💪\n",
"\n",
"เราสามารถสังเกตได้ว่า `glimpse()` จะแสดงจำนวนแถวทั้งหมด (observations) และจำนวนคอลัมน์ทั้งหมด (variables) จากนั้นจะแสดงข้อมูลบางส่วนของแต่ละตัวแปรในแถวถัดจากชื่อของตัวแปร นอกจากนี้ *ประเภทข้อมูล* ของตัวแปรจะถูกแสดงอยู่ถัดจากชื่อของตัวแปรภายใน `< >`\n",
"\n",
"`DataExplorer::introduce()` สามารถสรุปข้อมูลเหล่านี้ได้อย่างเป็นระเบียบ:\n"
],
"metadata": {}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Describe basic information for our data\r\n",
"df %>% \r\n",
" introduce()\r\n",
"\r\n",
"# A visual display of the same\r\n",
"df %>% \r\n",
" plot_intro()\r\n"
],
"outputs": [],
"metadata": {}
},
{
"cell_type": "markdown",
"source": [
"เยี่ยมไปเลย! เราเพิ่งทราบว่าข้อมูลของเราไม่มีค่าที่หายไป\n",
"\n",
"ในขณะที่เรากำลังทำสิ่งนี้ เราสามารถสำรวจสถิติที่แสดงถึงแนวโน้มศูนย์กลางทั่วไป (เช่น [ค่าเฉลี่ย](https://en.wikipedia.org/wiki/Arithmetic_mean) และ [ค่ามัธยฐาน](https://en.wikipedia.org/wiki/Median)) และการวัดการกระจายตัว (เช่น [ส่วนเบี่ยงเบนมาตรฐาน](https://en.wikipedia.org/wiki/Standard_deviation)) โดยใช้ `summarytools::descr()`\n"
],
"metadata": {}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Describe common statistics\r\n",
"df %>% \r\n",
" descr(stats = \"common\")\r\n"
],
"outputs": [],
"metadata": {}
},
{
"cell_type": "markdown",
"source": [
"มาดูค่าทั่วไปของข้อมูลกันก่อน โปรดทราบว่าความนิยม (popularity) อาจมีค่าเป็น `0` ซึ่งแสดงถึงเพลงที่ไม่มีการจัดอันดับ เราจะลบข้อมูลเหล่านั้นในภายหลัง\n",
"\n",
"> 🤔 ถ้าเรากำลังทำงานกับการจัดกลุ่ม (clustering) ซึ่งเป็นวิธีการแบบไม่มีผู้สอนที่ไม่ต้องการข้อมูลที่มีป้ายกำกับ ทำไมเราถึงแสดงข้อมูลนี้พร้อมป้ายกำกับ? ในขั้นตอนการสำรวจข้อมูล ป้ายกำกับเหล่านี้มีประโยชน์ แต่ไม่ได้จำเป็นสำหรับการทำงานของอัลกอริทึมการจัดกลุ่ม\n",
"\n",
"### 1. สำรวจแนวเพลงยอดนิยม\n",
"\n",
"มาลองค้นหาแนวเพลงที่ได้รับความนิยมมากที่สุด 🎶 โดยการนับจำนวนครั้งที่ปรากฏกันเถอะ\n"
],
"metadata": {}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Popular genres\r\n",
"top_genres <- df %>% \r\n",
" count(artist_top_genre, sort = TRUE) %>% \r\n",
"# Encode to categorical and reorder the according to count\r\n",
" mutate(artist_top_genre = factor(artist_top_genre) %>% fct_inorder())\r\n",
"\r\n",
"# Print the top genres\r\n",
"top_genres\r\n"
],
"outputs": [],
"metadata": {}
},
{
"cell_type": "markdown",
"source": [
"นั่นไปได้ดี! เขาว่าภาพหนึ่งภาพมีค่ามากกว่าพันแถวของข้อมูล (จริงๆ แล้วไม่มีใครพูดแบบนั้นเลย 😅) แต่คุณเข้าใจความหมายใช่ไหม?\n",
"\n",
"วิธีหนึ่งในการแสดงข้อมูลประเภทหมวดหมู่ (ตัวแปรประเภทตัวอักษรหรือแฟคเตอร์) คือการใช้กราฟแท่ง ลองมาสร้างกราฟแท่งของ 10 อันดับแรกของประเภทแนวเพลงกัน:\n"
],
"metadata": {}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Change the default gray theme\r\n",
"theme_set(theme_light())\r\n",
"\r\n",
"# Visualize popular genres\r\n",
"top_genres %>%\r\n",
" slice(1:10) %>% \r\n",
" ggplot(mapping = aes(x = artist_top_genre, y = n,\r\n",
" fill = artist_top_genre)) +\r\n",
" geom_col(alpha = 0.8) +\r\n",
" paletteer::scale_fill_paletteer_d(\"rcartocolor::Vivid\") +\r\n",
" ggtitle(\"Top genres\") +\r\n",
" theme(plot.title = element_text(hjust = 0.5),\r\n",
" # Rotates the X markers (so we can read them)\r\n",
" axis.text.x = element_text(angle = 90))\r\n"
],
"outputs": [],
"metadata": {}
},
{
"cell_type": "markdown",
"source": [
"ตอนนี้มันง่ายขึ้นมากที่จะระบุว่าเรามี `missing` ประเภทเพลง 🧐!\n",
"\n",
"> การแสดงผลข้อมูลที่ดีจะช่วยให้คุณเห็นสิ่งที่คุณไม่คาดคิด หรือทำให้เกิดคำถามใหม่เกี่ยวกับข้อมูล - Hadley Wickham และ Garrett Grolemund, [R For Data Science](https://r4ds.had.co.nz/introduction.html)\n",
"\n",
"โปรดทราบว่า เมื่อประเภทเพลงที่อยู่ด้านบนถูกระบุว่า `Missing` นั่นหมายความว่า Spotify ไม่ได้จัดประเภทให้ ดังนั้นเรามาลบมันออกไปกันเถอะ\n"
],
"metadata": {}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Visualize popular genres\r\n",
"top_genres %>%\r\n",
" filter(artist_top_genre != \"Missing\") %>% \r\n",
" slice(1:10) %>% \r\n",
" ggplot(mapping = aes(x = artist_top_genre, y = n,\r\n",
" fill = artist_top_genre)) +\r\n",
" geom_col(alpha = 0.8) +\r\n",
" paletteer::scale_fill_paletteer_d(\"rcartocolor::Vivid\") +\r\n",
" ggtitle(\"Top genres\") +\r\n",
" theme(plot.title = element_text(hjust = 0.5),\r\n",
" # Rotates the X markers (so we can read them)\r\n",
" axis.text.x = element_text(angle = 90))\r\n"
],
"outputs": [],
"metadata": {}
},
{
"cell_type": "markdown",
"source": [
"จากการสำรวจข้อมูลเบื้องต้น เราได้เรียนรู้ว่าแนวเพลงสามอันดับแรกมีอิทธิพลอย่างมากในชุดข้อมูลนี้ ดังนั้นเรามาเน้นที่ `afro dancehall`, `afropop` และ `nigerian pop` และกรองชุดข้อมูลเพิ่มเติมเพื่อเอาข้อมูลที่มีค่า popularity เท่ากับ 0 ออก (ซึ่งหมายความว่าไม่ได้ถูกจัดประเภทด้วยค่าความนิยมในชุดข้อมูล และสามารถพิจารณาได้ว่าเป็นสัญญาณรบกวนสำหรับวัตถุประสงค์ของเรา):\n"
],
"metadata": {}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"nigerian_songs <- df %>% \r\n",
" # Concentrate on top 3 genres\r\n",
" filter(artist_top_genre %in% c(\"afro dancehall\", \"afropop\",\"nigerian pop\")) %>% \r\n",
" # Remove unclassified observations\r\n",
" filter(popularity != 0)\r\n",
"\r\n",
"\r\n",
"\r\n",
"# Visualize popular genres\r\n",
"nigerian_songs %>%\r\n",
" count(artist_top_genre) %>%\r\n",
" ggplot(mapping = aes(x = artist_top_genre, y = n,\r\n",
" fill = artist_top_genre)) +\r\n",
" geom_col(alpha = 0.8) +\r\n",
" paletteer::scale_fill_paletteer_d(\"ggsci::category10_d3\") +\r\n",
" ggtitle(\"Top genres\") +\r\n",
" theme(plot.title = element_text(hjust = 0.5))\r\n"
],
"outputs": [],
"metadata": {}
},
{
"cell_type": "markdown",
"source": [
"มาดูกันว่ามีความสัมพันธ์เชิงเส้นที่ชัดเจนระหว่างตัวแปรเชิงปริมาณในชุดข้อมูลของเราหรือไม่ ความสัมพันธ์นี้ถูกวัดในเชิงคณิตศาสตร์โดย [สถิติความสัมพันธ์](https://en.wikipedia.org/wiki/Correlation)\n",
"\n",
"สถิติความสัมพันธ์เป็นค่าที่อยู่ระหว่าง -1 ถึง 1 ซึ่งบ่งบอกถึงความแข็งแกร่งของความสัมพันธ์ ค่าเหนือ 0 แสดงถึงความสัมพันธ์แบบ *บวก* (ค่าที่สูงของตัวแปรหนึ่งมักจะสอดคล้องกับค่าที่สูงของอีกตัวแปรหนึ่ง) ในขณะที่ค่าต่ำกว่า 0 แสดงถึงความสัมพันธ์แบบ *ลบ* (ค่าที่สูงของตัวแปรหนึ่งมักจะสอดคล้องกับค่าที่ต่ำของอีกตัวแปรหนึ่ง)\n"
],
"metadata": {}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Narrow down to numeric variables and fid correlation\r\n",
"corr_mat <- nigerian_songs %>% \r\n",
" select(where(is.numeric)) %>% \r\n",
" cor()\r\n",
"\r\n",
"# Visualize correlation matrix\r\n",
"corrplot(corr_mat, order = 'AOE', col = c('white', 'black'), bg = 'gold2') \r\n"
],
"outputs": [],
"metadata": {}
},
{
"cell_type": "markdown",
"source": [
"ข้อมูลไม่ได้มีความสัมพันธ์ที่ชัดเจน ยกเว้นระหว่าง `energy` และ `loudness` ซึ่งสมเหตุสมผล เพราะเพลงที่เสียงดังมักจะมีพลังงานสูง `Popularity` มีความสัมพันธ์กับ `release date` ซึ่งก็สมเหตุสมผลเช่นกัน เนื่องจากเพลงที่ออกใหม่มักจะได้รับความนิยมมากกว่า นอกจากนี้ ความยาวและพลังงานดูเหมือนจะมีความสัมพันธ์กันด้วย\n",
"\n",
"น่าสนใจที่จะดูว่าอัลกอริทึมการจัดกลุ่มจะสามารถวิเคราะห์ข้อมูลนี้ได้อย่างไร!\n",
"\n",
"> 🎓 โปรดทราบว่าความสัมพันธ์ไม่ได้หมายถึงเหตุและผล! เรามีหลักฐานของความสัมพันธ์ แต่ไม่มีหลักฐานของเหตุและผล เว็บไซต์ [ที่น่าสนุก](https://tylervigen.com/spurious-correlations) มีภาพประกอบที่เน้นประเด็นนี้\n",
"\n",
"### 2. สำรวจการกระจายตัวของข้อมูล\n",
"\n",
"ลองถามคำถามที่ลึกซึ้งขึ้นอีกหน่อย แนวเพลงต่าง ๆ มีความแตกต่างกันอย่างมีนัยสำคัญในแง่ของการเต้นได้หรือไม่ โดยพิจารณาจากความนิยม? ลองตรวจสอบการกระจายตัวของข้อมูลในสามแนวเพลงยอดนิยมของเราสำหรับความนิยมและการเต้นได้ตามแกน x และ y ที่กำหนด โดยใช้ [density plots](https://www.khanacademy.org/math/ap-statistics/density-curves-normal-distribution-ap/density-curves/v/density-curves)\n"
],
"metadata": {}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Perform 2D kernel density estimation\r\n",
"density_estimate_2d <- nigerian_songs %>% \r\n",
" ggplot(mapping = aes(x = popularity, y = danceability, color = artist_top_genre)) +\r\n",
" geom_density_2d(bins = 5, size = 1) +\r\n",
" paletteer::scale_color_paletteer_d(\"RSkittleBrewer::wildberry\") +\r\n",
" xlim(-20, 80) +\r\n",
" ylim(0, 1.2)\r\n",
"\r\n",
"# Density plot based on the popularity\r\n",
"density_estimate_pop <- nigerian_songs %>% \r\n",
" ggplot(mapping = aes(x = popularity, fill = artist_top_genre, color = artist_top_genre)) +\r\n",
" geom_density(size = 1, alpha = 0.5) +\r\n",
" paletteer::scale_fill_paletteer_d(\"RSkittleBrewer::wildberry\") +\r\n",
" paletteer::scale_color_paletteer_d(\"RSkittleBrewer::wildberry\") +\r\n",
" theme(legend.position = \"none\")\r\n",
"\r\n",
"# Density plot based on the danceability\r\n",
"density_estimate_dance <- nigerian_songs %>% \r\n",
" ggplot(mapping = aes(x = danceability, fill = artist_top_genre, color = artist_top_genre)) +\r\n",
" geom_density(size = 1, alpha = 0.5) +\r\n",
" paletteer::scale_fill_paletteer_d(\"RSkittleBrewer::wildberry\") +\r\n",
" paletteer::scale_color_paletteer_d(\"RSkittleBrewer::wildberry\")\r\n",
"\r\n",
"\r\n",
"# Patch everything together\r\n",
"library(patchwork)\r\n",
"density_estimate_2d / (density_estimate_pop + density_estimate_dance)\r\n"
],
"outputs": [],
"metadata": {}
},
{
"cell_type": "markdown",
"source": [
"เราสังเกตเห็นว่ามีวงกลมที่เรียงตัวกันเป็นชั้นๆ ไม่ว่าจะเป็นแนวเพลงใดก็ตาม อาจเป็นไปได้ว่ารสนิยมของชาวไนจีเรียมาบรรจบกันที่ระดับความสามารถในการเต้นสำหรับแนวเพลงนี้?\n",
"\n",
"โดยทั่วไปแล้ว แนวเพลงทั้งสามมีความสอดคล้องกันในแง่ของความนิยมและความสามารถในการเต้น การกำหนดกลุ่มในข้อมูลที่เรียงตัวกันอย่างหลวมๆ นี้จะเป็นความท้าทาย ลองมาดูกันว่าการใช้ scatter plot จะช่วยสนับสนุนเรื่องนี้ได้หรือไม่\n"
],
"metadata": {}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# A scatter plot of popularity and danceability\r\n",
"scatter_plot <- nigerian_songs %>% \r\n",
" ggplot(mapping = aes(x = popularity, y = danceability, color = artist_top_genre, shape = artist_top_genre)) +\r\n",
" geom_point(size = 2, alpha = 0.8) +\r\n",
" paletteer::scale_color_paletteer_d(\"futurevisions::mars\")\r\n",
"\r\n",
"# Add a touch of interactivity\r\n",
"ggplotly(scatter_plot)\r\n"
],
"outputs": [],
"metadata": {}
},
{
"cell_type": "markdown",
"source": [
"แผนภาพกระจายของแกนเดียวกันแสดงรูปแบบการบรรจบกันที่คล้ายกัน\n",
"\n",
"โดยทั่วไป สำหรับการจัดกลุ่มข้อมูล คุณสามารถใช้แผนภาพกระจายเพื่อแสดงกลุ่มของข้อมูล ดังนั้นการเชี่ยวชาญการสร้างภาพประเภทนี้จึงมีประโยชน์มาก ในบทเรียนถัดไป เราจะนำข้อมูลที่กรองแล้วนี้มาใช้กับการจัดกลุ่มแบบ k-means เพื่อค้นหากลุ่มในข้อมูลที่มีการทับซ้อนกันในรูปแบบที่น่าสนใจ\n",
"\n",
"## **🚀 ความท้าทาย**\n",
"\n",
"เพื่อเตรียมตัวสำหรับบทเรียนถัดไป สร้างแผนภูมิที่เกี่ยวกับอัลกอริทึมการจัดกลุ่มต่าง ๆ ที่คุณอาจค้นพบและใช้ในสภาพแวดล้อมการผลิต อัลกอริทึมการจัดกลุ่มเหล่านี้พยายามแก้ไขปัญหาแบบใด?\n",
"\n",
"## [**แบบทดสอบหลังบทเรียน**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/28/)\n",
"\n",
"## **ทบทวนและศึกษาด้วยตัวเอง**\n",
"\n",
"ก่อนที่คุณจะใช้การจัดกลุ่มข้อมูลตามที่เราได้เรียนรู้มา การทำความเข้าใจลักษณะของชุดข้อมูลของคุณเป็นความคิดที่ดี อ่านเพิ่มเติมเกี่ยวกับหัวข้อนี้ [ที่นี่](https://www.kdnuggets.com/2019/10/right-clustering-algorithm.html)\n",
"\n",
"เพิ่มพูนความเข้าใจเกี่ยวกับเทคนิคการจัดกลุ่มข้อมูล:\n",
"\n",
"- [ฝึกฝนและประเมินโมเดลการจัดกลุ่มด้วย Tidymodels และเครื่องมืออื่น ๆ](https://rpubs.com/eR_ic/clustering)\n",
"\n",
"- Bradley Boehmke & Brandon Greenwell, [*Hands-On Machine Learning with R*](https://bradleyboehmke.github.io/HOML/)*.*\n",
"\n",
"## **งานที่ได้รับมอบหมาย**\n",
"\n",
"[ค้นคว้าการสร้างภาพอื่น ๆ สำหรับการจัดกลุ่มข้อมูล](https://github.com/microsoft/ML-For-Beginners/blob/main/5-Clustering/1-Visualize/assignment.md)\n",
"\n",
"## ขอขอบคุณ:\n",
"\n",
"[Jen Looper](https://www.twitter.com/jenlooper) สำหรับการสร้างเวอร์ชัน Python ดั้งเดิมของโมดูลนี้ ♥️\n",
"\n",
"[`Dasani Madipalli`](https://twitter.com/dasani_decoded) สำหรับการสร้างภาพประกอบที่ยอดเยี่ยมซึ่งช่วยให้แนวคิดเกี่ยวกับการเรียนรู้ของเครื่องเข้าใจง่ายและเข้าถึงได้มากขึ้น\n",
"\n",
"เรียนรู้อย่างมีความสุข,\n",
"\n",
"[Eric](https://twitter.com/ericntay), Gold Microsoft Learn Student Ambassador\n"
],
"metadata": {}
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**ข้อจำกัดความรับผิดชอบ**: \nเอกสารนี้ได้รับการแปลโดยใช้บริการแปลภาษา AI [Co-op Translator](https://github.com/Azure/co-op-translator) แม้ว่าเราจะพยายามให้การแปลมีความถูกต้องมากที่สุด แต่โปรดทราบว่าการแปลโดยอัตโนมัติอาจมีข้อผิดพลาดหรือความไม่ถูกต้อง เอกสารต้นฉบับในภาษาต้นทางควรถือเป็นแหล่งข้อมูลที่เชื่อถือได้ สำหรับข้อมูลที่สำคัญ ขอแนะนำให้ใช้บริการแปลภาษาจากผู้เชี่ยวชาญ เราไม่รับผิดชอบต่อความเข้าใจผิดหรือการตีความผิดที่เกิดจากการใช้การแปลนี้\n"
]
}
],
"metadata": {
"anaconda-cloud": "",
"kernelspec": {
"display_name": "R",
"language": "R",
"name": "ir"
},
"language_info": {
"codemirror_mode": "r",
"file_extension": ".r",
"mimetype": "text/x-r-source",
"name": "R",
"pygments_lexer": "r",
"version": "3.4.1"
},
"coopTranslator": {
"original_hash": "99c36449cad3708a435f6798cfa39972",
"translation_date": "2025-09-06T14:16:59+00:00",
"source_file": "5-Clustering/1-Visualize/solution/R/lesson_14-R.ipynb",
"language_code": "th"
}
},
"nbformat": 4,
"nbformat_minor": 1
}