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

492 lines
47 KiB

{
"cells": [
{
"cell_type": "markdown",
"source": [
"## **តន្ត្រីនីជេរីយ៉ាន់ដែលបានច្រកចេញពី Spotify - ការវិភាគ**\r\n",
"\r\n",
"ការជំរុញជាគ្រឿងម៉ាស៊ីនមួយប្រភេទ [កំណត់អត្រា​គ្មានអ្នកគ្រប់គ្រង](https://wikipedia.org/wiki/Unsupervised_learning) ដែលសន្មត់ថាតំណើរការទិន្នន័យមិនមានស្លាកឬថា ការបញ្ចូលទិន្នន័យរបស់វាមិនត្រូវបានផ្គូផ្គងជាមួយលទ្ធផលដែលបានកំណត់ជាមុនទេ។ វាប្រើប្រាស់អាល់ហ្គរីធម៍ជាច្រើនដើម្បីតម្រៀបតាមទិន្នន័យគ្មានស្លាក ហើយផ្តល់ជាក្រុមតាមលំនាំដែលវាបង្កប់ក្នុងទិន្នន័យ។\r\n",
"\r\n",
"[**សំណួរត្រួតពិនិត្យមុនថ្នាក់**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/27/)\r\n",
"\r\n",
"### **ការបើកបង្ហាញ**\r\n",
"\r\n",
"[ការជំរុញ](https://link.springer.com/referenceworkentry/10.1007%2F978-0-387-30164-8_124) មានប្រយោជន៍ខ្លាំងសម្រាប់ការស្វែងយល់ទិន្នន័យ។ យើងមកមើលថាតើវាអាចជួយរកឃើញនិន្នាការ និងលំនាំក្នុងវិធីដែលអ្នកស្តាប់តន្ត្រីនីជេរីយ៉ាន់ប្រើប្រាស់តន្ត្រីបានទេ។\r\n",
"\r\n",
"> ✅ ចំណាយពេលមួយនាទីគិតអំពីការប្រើប្រាស់នៃការជំរុញ។ នៅក្នុងជីវិតពិត ការជំរុញកើតឡើងនៅពេលដែលអ្នកមានវេចខ្ទប់សម្លៀកបំពាក់ហើយត្រូវតម្រៀបសម្លៀកបំពាក់របស់សមាជិកគ្រួសាររបស់អ្នក 🧦👕👖🩲។ ក្នុងវិទ្យាសាស្ត្រទិន្នន័យ ការជំរុញកើតឡើងនៅពេលព្យាយាមវិភាគចំណង់ចំណូលចិត្តរបស់អ្នកប្រើប្រាស់ ឬកំណត់លក្ខណៈនៃ datasets គ្មានស្លាកណាមួយ។ ការជំរុញ ជាជំនួយចំពោះការស្វែងយល់ពីរំខាន ដូចជាឃូបនៃស្រោមជើងជើង។\r\n",
"\r\n",
"នៅក្នុងបរិបទវិជ្ជាជីវៈ ការជំរុញអាចប្រើប្រាស់ដើម្បីកំណត់អ្វីៗដូចជា ការបែងចែកទីផ្សារ កំណត់អាយុដែលទិញផលិតផលជាក់លាក់ៗ ។ ការប្រើប្រាស់មួយផ្សេងទៀតគឺការរកឃើញអសកម្មភាព ប្រហែលជាសម្រាប់រកឃើញការបោកប្រាស់ពីរៃយកាតឥណទាន។ ឬអ្នកអាចប្រើការជំរុញដើម្បីកំណត់មហារីកក្នុងប្រមាណផ្នែកវេជ្ជសាស្ត្រ។\r\n",
"\r\n",
"✅ គិតមួយនាទីអំពីរបៀបដែលអ្នកប្រហែលជាបានជួបប្រទៈការជំរុញ 'ក្នុងធម្មជាតិ' នៅក្នុងបរិបទធនាគារ, អ៊ី-ចម្រុះ ឬជំនួញ។\r\n",
"\r\n",
"> 🎓 គួរឱ្យចាប់អារម្មណ៍ ជំរុញត្រូវបានបង្កើតឡើងក្នុងវិស័យមនុស្សបច្ចេកទេស និងចិត្តវិទ្យា នៅឆ្នាំ 1930។ អ្នកអាចលើកទឹកចិត្តថាវាត្រូវបានប្រើប្រាស់យ៉ាងដូចម្តេចទេ?\r\n",
"\r\n",
"ដោយជម្រើសផ្សេង អ្នកអាចប្រើវាសម្រាប់បំបែកលទ្ធផលស្វែងរក - ដោយតំណភ្ជាប់ទិញ, រូបភាព ឬការពិនិត្យលើ។ ការជំរុញមានប្រយោជន៍នៅពេលដែលអ្នកមានdatasetធំដែលអ្នកចង់បង្រួម និងអនុវត្តវិភាគលំអិតជាងនេះ ដូច្នេះវិធីសាស្ត្រនេះអាចប្រើសម្រាប់រៀនពីទិន្នន័យ មុនពេលមានការបង្កើតម៉ូដែលផ្សេងទៀត។\r\n",
"\r\n",
"✅ ពេលទិន្នន័យរបស់អ្នកតម្រៀបក្នុងក្រុមអ្នកផ្ដល់លេខសម្គាល់ក្រុមមួយ ហើយវិធីសាស្ត្រនេះអាចមានប្រយោជន៍នៅពេលរក្សាព័ត៌មានឯកជនរបស់datasets អ្នកអាចយោងទៅលើចំណុចទិន្នន័យដោយលេខសម្គាល់ក្រុម ជំនួសឲ្យលេខសម្គាល់បង្ហាញពីព័ត៌មានឯកជន។ អ្នកអាចគិតឃើញហេតុផលផ្សេងទៀតដែលអ្នកយោងទៅលេខសម្គាល់ក្រុមប៉ុន្មានជំនួសធាតុផ្សេងទៀតក្នុងក្រុមដើម្បីសម្គាល់វា?\r\n",
"\r\n",
"### ចាប់ផ្តើមជាមួយការជំរុញ\r\n",
"\r\n",
"> 🎓 របៀបយើងបង្កើតក្រុមនៅទំនាក់ទំនងទៅនឹងរបៀបយើងប្រមូលចំណុចទិន្នន័យជាក្រុម។ បង្ហាញវាក្នុងពាក្យសំខាន់៖\r\n",
">\r\n",
"> 🎓 ['Transductive' ប្រឆាំងនឹង 'inductive'](https://wikipedia.org/wiki/Transduction_(machine_learning))\r\n",
">\r\n",
"> ការជានិស្ស័យ transductive មានប្រភពចេញពីករណីបណ្តុះបណ្តាលដែលបានមើលឃើញដែលផ្គូផ្គងទៅនឹងករណីសាកល្បងជាក់លាក់។ ការជានិស្ស័យ inductive មានប្រភពចេញពីករណីបណ្តុះបណ្តាលដែលផ្គូផ្គងទៅនឹងច្បាប់ទូទៅ ដែលត្រូវបានអនុវត្តត្រឹមតែទៅក្ដៅករណីសាកល្បងប៉ុណ្ណោះ។\r\n",
">\r\n",
"> ឧទាហរណ៍៖ ស្រមៃថាអ្នកមានdatasetមួយ ដែលមានប៉ុន្មានស្លាកតិចតួច។ មានអ្វីខ្លះនៅជារបៀប 'កំណត់ត្រា' (records) ខ្លះ 'ស៊ីឌី' (cds) ហើយខ្លះទៀតគ្មានស្លាក។ ការងាររបស់អ្នកគឺផ្ដល់ស្លាកសម្រាប់ការខ្វះ។ បើអ្នកជ្រើសរើសវិធី inductive អ្នកនឹងបណ្តុះបណ្តាលម៉ូដែលស្វែងរក 'កំណត់ត្រា' និង 'ស៊ីឌី' ហើយផ្ដល់ស្លាកទ្រង់ទ្រាយទៅលើទិន្នន័យគ្មានស្លាករបស់អ្នក។ វិធីនេះនឹងមានបញ្ហាក្នុងការបែងចែកវាលើអ្វីដែលពិតជា 'កាសែត'។ ផ្ទុយទៅវិញ អ្នកប្រើវិធី transductive អាចដោះស្រាយទិន្នន័យមិនស្គាល់នេះបានប្រសើរជាង ដោយវាកម្មវិធីដើម្បីបំបែកវត្ថុស្រដៀងគ្នាជាក្រុម ហើយបន្ទាប់មកផ្ដល់ស្លាកក្នុងក្រុម។ ក្នុងករណីនេះ ក្រុមអាចបង្ហាញ 'រឿងតន្ត្រីរង្វង់' និង 'រឿងតន្ត្រីការ៉េ'។\r\n",
">\r\n",
"> 🎓 ['Geometry មិនស្មើ' ប្រឆាំងនឹង 'geometry ស្មើ'](https://datascience.stackexchange.com/questions/52260/terminology-flat-geometry-in-the-context-of-clustering)\r\n",
">\r\n",
"> ទាមទារពីវេយ្យាករណ៍គណិតវិទ្យា geometry មិនស្មើ ប្រឆាំងនឹង geometry ស្មើ មានន័យពីការវាស់ចម្ងាយរវាងចំណុច ដោយប្រើវិធីគណិតវិទ្យា 'ស្មើ' ([Euclidean](https://wikipedia.org/wiki/Euclidean_geometry)) ឬ 'មិនស្មើ' (non-Euclidean)។\r\n",
">\r\n",
"> 'ស្មើ' នៅក្នុងបរិបទនេះយោងឲ្យ geometry Euclidean (ផ្នែកមួយដែលបានបង្រៀនក្នុងនាមជា 'geometry លើផ្ទៃ'), ហើយមិនស្មើយោងទៅ geometry មិន Euclidean។ អ្វីទៅជាgeometry ទាក់ទងទៅ machine learning? ដូចជាវិស័យទាំងពីរដែលដាំដុះពីគណិតវិទ្យា ត្រូវមានវិធីសាមញ្ញមួយសម្រាប់វាស់ចម្ងាយរវាងចំណុចក្នុងក្រុម ហើយវាអាចធ្វើបានជា 'ស្មើ' ឬ 'មិនស្មើ'ព្រមទាំងតម្រូវទៅលើធម្មជាតិទិន្នន័យ។ [ចម្ងាយ Euclidean](https://wikipedia.org/wiki/Euclidean_distance) ត្រូវបានវាស់យើម្បីជាបញ្ចេញប្រវែងបន្ទាត់រវាងចំណុចពីរផ្ទាល់។ [ចម្ងាយមិន-Euclidean](https://wikipedia.org/wiki/Non-Euclidean_geometry) ត្រូវបានវាស់តាមបន្ទាត់ឈរ។ ប្រសិនបើទិន្នន័យរបស់អ្នក មានការបង្ហាញមិនស្ថិតលើផ្ទៃ អ្នកប្រហែលជាត្រូវប្រើអាល់ហ្គរីធម៍ពិសេសមួយដើម្បីដោះស្រាយវា។\r\n",
"\r\n",
"<p >\r\n",
" <img src=\"../../../../../../translated_images/km/flat-nonflat.d1c8c6e2a96110c1.webp\"\r\n",
" width=\"600\"/>\r\n",
" <figcaption>តារាងព័ត៌មានដោយ Dasani Madipalli</figcaption>\r\n",
"\r\n",
"\r\n",
"\r\n",
"> 🎓 ['ចម្ងាយ'](https://web.stanford.edu/class/cs345a/slides/12-clustering.pdf)\r\n",
">\r\n",
"> ក្រុមត្រូវបានកំណត់ដោយម៉ាទ្រីសចម្ងាយ រួមមានចម្ងាយរវាងចំណុច។ ចម្ងាយនេះអាចវាស់បានច្រើនវិធី។ ក្រុម Euclidean ត្រូវបានកំណត់ដោយមធ្យមភាគរយនៃតម្លៃចំណុច ហើយមាន 'centroid' ឬចំណុចកណ្តាល។ ចម្ងាយដូច្នេះត្រូវបានវាស់ដោយចម្ងាយទៅកាន់ centroid នោះ។ ចម្ងាយមិន-Euclidean ធ្វើចំណងទៅ 'clustroids', ចំណុចដែលជិតចំណុចផ្សេងៗជាងគេ។ Clustroids ត្រូវបានកំណត់បានជា​វិធីផ្សេងគ្នា។\r\n",
">\r\n",
"> 🎓 ['មានភាពកំណត់'](https://wikipedia.org/wiki/Constrained_clustering)\r\n",
">\r\n",
"> [Constrained Clustering](https://web.cs.ucdavis.edu/~davidson/Publications/ICDMTutorial.pdf) បញ្ចូលការរៀន 'ពាក់កណ្តាលគ្រប់គ្រង' ទៅវិធីមិនគ្រប់គ្រងនេះ។ សម្រួលភាពទំនាក់ទំនងរវាងចំណុចត្រូវបានគេដាក់សញ្ញា 'មិនអាចភ្ជាប់' ឬ 'ត្រូវភ្ជាប់' ដូច្នេះមានច្បាប់ខ្លះត្រូវអនុវត្តទៅលើ dataset។\r\n",
">\r\n",
"> ឧទាហរណ៍៖ ប្រសិនបើអាល់ហ្គរីធម៍ត្រូវបានដោះស្រាយលើទិន្នន័យគ្មានស្លាកឬពាក់កណ្តាល មានន័យថាក្រុមដែលវាបង្កើតអាចមានគុណភាពទាប។ ក្នុងឧទាហរណ៍ខាងលើ ក្រុមអាចចែក 'រឿងតន្ត្រីរង្វង់' នឹង 'រឿងតន្ត្រីការ៉េ' និង 'រឿងត្រីកោណ' និង 'គូគី'។ ប្រសិនបើមានកំណត់ ឬច្បាប់មួយ (\"វត្ថុត្រូវផលិតពីប្លាស្ទិច\", \"វត្ថុត្រូវអាចផលិតតន្ត្រី\") នេះអាចជួយ 'ដាក់កំណត់' អាល់ហ្គរីធម៍ក្នុងការជ្រើសរើសល្អប្រសើរ។\r\n",
">\r\n",
"> 🎓 'Density'\r\n",
">\r\n",
"> ទិន្នន័យដែល 'មានសំឡេងរំខាន' ត្រូវបានគេចាត់ទុកថា 'សម្បូរបែប'។ ចម្ងាយរវាងចំណុចក្នុងក្រុមអាចបង្ហាញថា មានភាពសម្បូរឬអត់ ស្ថិតក្នុងស្ថានភាព 'រុំគ្នា' ដូច្នេះទិន្នន័យនេះត្រូវបានវិភាគដោយវិធីត្រឹមត្រូវនៃការជំរុញ។ [អត្ថបទនេះ](https://www.kdnuggets.com/2020/02/understanding-density-based-clustering.html) បង្ហាញពីភាពខុសគ្នារវាងការប្រើប្រាស់ K-Means clustering ប្រឆាំងនឹង HDBSCAN algorithms ដើម្បីស្វែងយល់ dataset រញ្ជួយមានភាពនៅចម្ងាយបែកឡែកគ្នា។\r\n",
"\r\n",
"បង្កើនការយល់ដឹងរបស់អ្នកអំពីវិធីសាស្ត្រជំរុញនៅក្នុង [ផ្នែករៀន](https://docs.microsoft.com/learn/modules/train-evaluate-cluster-models?WT.mc_id=academic-77952-leestott)\r\n",
"\r\n",
"### **អាល់ហ្គរីធម៍ជំរុញ**\r\n",
"\r\n",
"មានអាល់ហ្គរីធម៍ជំរុញលើស ១០០ ប្រភេទ ហើយការប្រើប្រាស់របស់ពួកវាអាស្រ័យលើធម្មជាតិទិន្នន័យនៅដើម។ យើងមកពិភាក្សាអំពីចំនុចសំខាន់ៗខ្លះ៖\r\n",
"\r\n",
"- **ការជំរុញលំដាប់ដាច់ខាត (Hierarchical clustering)**។ ប្រសិនបើវត្ថុណាមួយត្រូវបានចាត់ថ្នាក់ដោយភាពជិតស្និទ្ធទៅវត្ថុជិតខាងមួយ មិនមែនទៅវត្ថុឆ្ងាយជាងទេ ក្រុមនឹងត្រូវបានបង្កើតឡើងដោយអាស្រ័យលើចម្ងាយរវាងសមាជិក។ ការជំរុញលំដាប់ដាច់ខាតត្រូវបានលក្ខណៈដោយការបន្សំក្រុមពីរក្រុមជាបន្តបន្ទាប់។\r\n",
"\r\n",
"\r\n",
"<p >\r\n",
" <img src=\"../../../../../../translated_images/km/hierarchical.bf59403aa43c8c47.webp\"\r\n",
" width=\"600\"/>\r\n",
" <figcaption>តារាងព័ត៌មានដោយ Dasani Madipalli</figcaption>\r\n",
"\r\n",
"\r\n",
"\r\n",
"- **ការជំរុញតាមភាគរយ (Centroid clustering)**។ អាល់ហ្គរីធម៍ពេញនិយមនេះតម្រូវឲ្យជ្រើសរើស 'k' ឬចំនួនក្រុមដែលត្រូវបង្កើត បន្ទាប់មកអាល់ហ្គរីធម៍កំណត់ចំណុចកណ្តាលរបស់ក្រុម ហើយប្រមូលទិន្នន័យជុំវិញចំណុចនោះ។ [K-means clustering](https://wikipedia.org/wiki/K-means_clustering) គឺជាប្រភេទដែលពេញនិយមនៃការជំរុញតាមភាគរយ ដែលបំបែក dataset ទៅជា K ក្រុមដែលបានកំណត់ជាមុន។ ចំណុចកណ្តាលត្រូវបានកំណត់ដោយមធ្យមភាគនៅជិតបំផុត ដូច្នេះមានឈ្មោះ។ ចម្ងាយការេពីក្រុមត្រូវបានកាត់បន្ថយ។\r\n",
"\r\n",
"<p >\r\n",
" <img src=\"../../../../../../translated_images/km/centroid.097fde836cf6c918.webp\"\r\n",
" width=\"600\"/>\r\n",
" <figcaption>តារាងព័ត៌មានដោយ Dasani Madipalli</figcaption>\r\n",
"\r\n",
"\r\n",
"\r\n",
"- **ការជំរុញដោយផ្អែកលើចែកចាយ (Distribution-based clustering)**។ មានមូលដ្ឋាននៅលើម៉ូដែលស្ថិតិ ការជំរុញដោយផ្អែកលើចែកចាយផ្ដោតលើការកំណត់ប្រតិបត្តិអាចធ្វើបានថាចំណុចទិន្នន័យជាប់នឹងក្រុមណាមួយ ហើយផ្ដល់ចំណាត់ថ្នាក់តាមបែបនេះ។ វិធីផ្សំ Gaussian ជាផ្នែកមួយនៃប្រភេទនេះ។\r\n",
"\r\n",
"- **ការជំរុញដោយផ្អែកលើដង់សុីតេ (Density-based clustering)**។ ចំណុចទិន្នន័យត្រូវបានផ្ដល់សេចក្តីថ្លែងអំពីក្រុមដោយផ្អែកលើដង់សុីតេ រឺការជុំវិញគ្នា។ ចំណុចដែលឆ្ងាយពីក្រុមគេចាត់ទុកថាជាអ្វីៗមិនរួមបញ្ចូល ឬសម្លេងរំខាន។ DBSCAN, Mean-shift និង OPTICS ជាផ្នែកនៃប្រភេទនេះ។\r\n",
"\r\n",
"- **ការជំរុញដោយផ្អែកលើក្រឡា (Grid-based clustering)**។ សម្រាប់ dataset ច្រើនវិមាត្រ ក្រឡាត្រូវបានបង្កើត ហើយទិន្នន័យត្រូវបានបែងចែកទៅចូលក្នុងក្រឡាពណ៍។ ដោយហេតុនេះ បង្កើតក្រុមឡើង។\r\n",
"\r\n",
"វិធីល្អបំផុតសម្រាប់រៀនអំពីការជំរុញគឺសាកល្បងវាផ្ទាល់ ដូច្នេះនេះជាការធ្វើក្នុងលំហាត់នេះ។\r\n",
"\r\n",
"យើងត្រូវការ package ខ្លះសម្រាប់បញ្ចប់មេរៀននេះ។ អ្នកអាចដំឡើងបានដោយ: `install.packages(c('tidyverse', 'tidymodels', 'DataExplorer', 'summarytools', 'plotly', 'paletteer', 'corrplot', 'patchwork'))`\r\n",
"\r\n",
"ជាជម្រើសផ្សេងទៀត ស្គ្រីបខាងក្រោមពិនិត្យមើលថាអ្នកមាន package ដែលត្រូវការសម្រាប់បញ្ចប់មេរៀននេះ ហើយដំឡើងវាសម្រាប់អ្នក ប្រសិនបើមាន package ខ្វះចាំបាច់។\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",
"ការប្រមូលក្រុមជាយុទ្ធសាស្ត្រមួយត្រូវបានជួយយ៉ាងខ្លាំងដោយការបង្ហាញតម្លៃដ៏ត្រឹមត្រូវ ដូច្នេះយើងចាប់ផ្តើមដោយបង្ហាញតម្លៃទិន្នន័យតន្រ្តីរបស់យើង។ ដំណើរការនេះនឹងជួយយើងសម្រេចចិត្តថាវិធីណាដែលយើងគួរតែប្រើច្រើនបំផុតសម្រាប់ធម្មជាតិនៃទិន្នន័យនេះ។\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` និង `its structure` ដោយប្រើមុខងារ [*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()` នឹងផ្តល់ឲ្យអ្នកនូវចំនួនជួរដេកសរុប (ការសង្កេត) និងជួរឈរ (អថេរ) បន្ទាប់មកជួរដេកដំបូងៗនៃអថេរនីមួយៗបន្ទាប់ពីឈ្មោះអថេរ។ លើសពីនេះទៀត *ប្រភេទទិន្នន័យ* នៃអថេរនោះត្រូវបានផ្តល់ភ្លាមៗបន្ទាប់ពីឈ្មោះអថេរនីមួយៗនៅក្នុង `< >`។\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": [
"មកសូមមើលតម្លៃទូទៅនៃទិន្នន័យ។ ចង់បញ្ជាក់ថាបាតុភូតពេញនិយមអាចមានតម្លៃជា `0` ដែលបង្ហាញពីចម្រៀងដែលមិនមានចំណាត់ថ្នាក់ទេ។ យើងនឹងដកចេញវាឆាប់ៗនេះ។\n",
"\n",
"> 🤔 បើយើងកំពុងធ្វើការជាមួយ clustering វិធីសាស្រ្តមិនត្រូវការយោងលើទិន្នន័យមានស្លាកហើយ គួរឲ្យផ្ញើយកទិន្នន័យនេះជាមួយស្លាកហើយមានហេតុអ្វី? ក្នុងដំណាក់កាលស្វែងរកទិន្នន័យ វាពាក់ព័ន្ធផងដែរ ប៉ុន្តែមិនចាំបាច់សម្រាប់អាល់គុណម clustering ឲ្យដំណើរការទេ។\n",
"\n",
"### 1. ស្វែងរកប្រភេទតន្ត្រីពេញនិយម\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",
"វិធីមួយ​ដើម្បី​មើល​ទិន្នន័យ​ដែលើ​ប្រភេទ​តួអក្សរ (អក្សរ ឬអថេរ factor) គឺ​ការ​ប្រើ​ប្រាស់ប្លុតបារ។ អ្នកមក​ធ្វើ​ប្លុតបារ​នៃ​ប្រភេទ ១០​លើស​ពីគេដូចតទៅ៖\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` បន្ថែមទៀតធ្វើការត្រងឃ្លោងទិន្នន័យដើម្បីខ្វក់អ្វីដែលមានតម្លៃពេញនិយម 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",
"> 🎓 សូមចំណាំថា ទំនាក់ទំនងមិនមានន័យថា មានមូលហេតុ! យើងមានភស្តុតាងពីទំនាក់ទំនងប៉ុន្តែមិនមានភស្តុតាងពីមូលហេតុឡើយ។ គេហទំព័រមួយ [amusing web site](https://tylervigen.com/spurious-correlations) មានរូបភាពមួយចំនួនដែលលើកឡើងចំណុចនេះ។\n",
"\n",
"### 2. ស្វែងយល់ការចែកចាយទិន្នន័យ\n",
"\n",
"អោយយើងសួរបញ្ហាបន្តិចទៀត។ តើរចនាប័ទ្មតន្ត្រីមានភាពខុសគ្នាដោយសារ ចំពោះការយល់ឃើញនៃការរាំរបស់ពួកវាដោយផ្អែកលើប្រជាប្រិយភាពរបស់ពួកវាទេ? អោយយើងពិនិត្យការចែកចាយទិន្នន័យរចនាប័ទ្មច្រីនបួនលើប្រជាប្រិយភាព និងការរាំ ដោយប្រើ [density plots](https://www.khanacademy.org/math/ap-statistics/density-curves-normal-distribution-ap/density-curves/v/density-curves) ជាមួយអ័ក្ស x និង y មួយដែលបានផ្តល់។\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": [
"យើងមើលឃើញថាមានរង្វង់រំលឹកគ្នាមួយចំនួនដែលស្របគ្នា មិនគិតពីប្រភេទតន្ត្រីឡើយ។ តើអាចជាការស្របគ្នារវាងរសជាតិអ្នកនិយមតន្ត្រី Nigerien នៅកម្រិតចាក់រាំដូចគ្នាមួយសម្រាប់ប្រភេទតន្ត្រីនេះ?\n",
"\n",
"ជាទូទៅ ប្រភេទតន្ត្រីទាំងបីត្រូវគ្នាតាមកម្រិតនៃការពេញនិយម និងចាក់រាំ។ ការកំណត់រ៉ូមក្រុមក្នុងទិន្នន័យដែលមិនបានស្របគ្នារបស់ក្រុមនេះនឹងជាឧបសគ្គមួយ។ យើងមកមើលថាតើតារាងបញ្ចាំងចំណុចអាចគាំទ្រ និយមន័យនេះឬអត់។\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), តំណាងសិស្ស Microsoft Learn ជាពេជ្រមាស។\n"
],
"metadata": {}
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n\n<!-- CO-OP TRANSLATOR DISCLAIMER START -->\n**ការព្រមាន**៖ \nឯកសារនេះត្រូវបានបកប្រែដោយប្រើសេវាបកប្រែ AI [Co-op Translator](https://github.com/Azure/co-op-translator)។ ខណៈពេលយើងខិតខំប្រឹងប្រែងដើម្បីឲ្យបានភាពត្រឹមត្រូវ សូមយល់ជ្រាបថាការបកប្រែដោយស្វ័យប្រវត្តិអាចមានកំហុស ឬភាពមិនត្រឹមត្រូវខ្លះ។ ឯកសារដើមជាភាសាមូលដ្ឋានគួរត្រូវបានយកទៅជាលទ្ធផលផ្លូវការនិងត្រឹមត្រូវបំផុត។ សម្រាប់ព័ត៌មានសំខាន់ៗ យើងណែនាំឲ្យប្រើការបកប្រែដោយមនុស្សជាជំនាញវិជ្ជាជីវៈ។ យើងមិនទទួលខុសត្រូវចំពោះការយល់ច្រឡំ ឬការបកអត្ថន័យខុសដែលកើតមានពីការប្រើប្រាស់ការបកប្រែនេះឡើយ។\n<!-- CO-OP TRANSLATOR DISCLAIMER END -->\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"
}
},
"nbformat": 4,
"nbformat_minor": 1
}