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

499 lines
32 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

{
"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",
"[Clustering](https://link.springer.com/referenceworkentry/10.1007%2F978-0-387-30164-8_124) הוא כלי שימושי מאוד לחקר נתונים. בואו נראה אם הוא יכול לעזור לגלות מגמות ודפוסים באופן שבו קהל ניגרי צורך מוזיקה.\n",
"\n",
"> ✅ הקדישו רגע לחשוב על השימושים של Clustering. בחיים האמיתיים, Clustering מתרחש בכל פעם שיש לכם ערימת כביסה ואתם צריכים למיין את הבגדים של בני המשפחה 🧦👕👖🩲. במדעי הנתונים, Clustering מתרחש כאשר מנסים לנתח את ההעדפות של משתמשים או לקבוע את המאפיינים של מערך נתונים לא מתויג. Clustering, במובן מסוים, עוזר לעשות סדר בכאוס, כמו מגירת גרביים.\n",
"\n",
"בסביבה מקצועית, Clustering יכול לשמש לקביעת דברים כמו פילוח שוק, למשל, לקבוע אילו קבוצות גיל קונות אילו מוצרים. שימוש נוסף יכול להיות זיהוי חריגות, אולי כדי לזהות הונאה מתוך מערך נתונים של עסקאות בכרטיסי אשראי. או שתוכלו להשתמש ב-Clustering כדי לזהות גידולים בסריקות רפואיות.\n",
"\n",
"✅ הקדישו רגע לחשוב כיצד נתקלתם ב-Clustering 'בעולם האמיתי', בסביבה בנקאית, מסחר אלקטרוני או עסקית.\n",
"\n",
"> 🎓 באופן מעניין, ניתוח Clustering מקורו בתחומי האנתרופולוגיה והפסיכולוגיה בשנות ה-30. האם אתם יכולים לדמיין כיצד הוא עשוי היה לשמש?\n",
"\n",
"לחילופין, תוכלו להשתמש בו לקיבוץ תוצאות חיפוש - לפי קישורי קניות, תמונות או ביקורות, למשל. Clustering שימושי כאשר יש לכם מערך נתונים גדול שברצונכם לצמצם ועליו לבצע ניתוח מעמיק יותר, כך שהטכניקה יכולה לשמש ללמידה על נתונים לפני בניית מודלים אחרים.\n",
"\n",
"✅ לאחר שמארגנים את הנתונים בקבוצות, ניתן להקצות להם מזהה קבוצה, וטכניקה זו יכולה להיות שימושית לשמירה על פרטיות מערך הנתונים; במקום להתייחס לנקודת נתונים לפי נתונים מזהים יותר, ניתן להתייחס אליה לפי מזהה הקבוצה שלה. האם אתם יכולים לחשוב על סיבות נוספות מדוע תעדיפו להתייחס למזהה קבוצה במקום לאלמנטים אחרים של הקבוצה כדי לזהות אותה?\n",
"\n",
"### התחלת עבודה עם Clustering\n",
"\n",
"> 🎓 האופן שבו אנו יוצרים קבוצות קשור מאוד לאופן שבו אנו אוספים את נקודות הנתונים לקבוצות. בואו נפרק כמה מושגים:\n",
">\n",
"> 🎓 ['Transductive' לעומת 'Inductive'](https://wikipedia.org/wiki/Transduction_(machine_learning))\n",
">\n",
"> הסקה Transductive נגזרת ממקרים שנצפו באימון שממופים למקרים ספציפיים בבדיקה. הסקה Inductive נגזרת ממקרים באימון שממופים לכללים כלליים שמיושמים רק לאחר מכן על מקרים בבדיקה.\n",
">\n",
"> דוגמה: דמיינו שיש לכם מערך נתונים שמתויג רק באופן חלקי. חלק מהפריטים הם 'תקליטים', חלק 'דיסקים', וחלק ריקים. המשימה שלכם היא לספק תוויות לריקים. אם תבחרו בגישה Inductive, תאמנו מודל שמחפש 'תקליטים' ו'דיסקים', ותיישמו את התוויות הללו על הנתונים הלא מתויגים. גישה זו תתקשה לסווג פריטים שהם למעשה 'קלטות'. גישה Transductive, לעומת זאת, מתמודדת עם נתונים לא ידועים בצורה יעילה יותר בכך שהיא עובדת על קיבוץ פריטים דומים יחד ואז מיישמת תווית על קבוצה. במקרה זה, הקבוצות עשויות לשקף 'דברים מוזיקליים עגולים' ו'דברים מוזיקליים מרובעים'.\n",
">\n",
"> 🎓 ['גיאומטריה שטוחה' לעומת 'לא שטוחה'](https://datascience.stackexchange.com/questions/52260/terminology-flat-geometry-in-the-context-of-clustering)\n",
">\n",
"> נגזר מהמונחים המתמטיים, גיאומטריה שטוחה לעומת לא שטוחה מתייחסת למדידת המרחקים בין נקודות על ידי שיטות גיאומטריות 'שטוחות' ([אוקלידיות](https://wikipedia.org/wiki/Euclidean_geometry)) או 'לא שטוחות' (לא אוקלידיות).\n",
">\n",
"> 'שטוחה' בהקשר זה מתייחסת לגיאומטריה אוקלידית (חלקים ממנה נלמדים כגיאומטריה 'מישורית'), ו'לא שטוחה' מתייחסת לגיאומטריה לא אוקלידית. מה לגיאומטריה וללמידת מכונה? ובכן, כשני תחומים שמבוססים על מתמטיקה, חייבת להיות דרך משותפת למדוד מרחקים בין נקודות בקבוצות, וזה יכול להיעשות בצורה 'שטוחה' או 'לא שטוחה', תלוי בטבע הנתונים. [מרחקים אוקלידיים](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>אינפוגרפיקה מאת דאסאני מדיפאלי</figcaption>\n",
"\n",
"\n",
"\n",
"> 🎓 ['מרחקים'](https://web.stanford.edu/class/cs345a/slides/12-clustering.pdf)\n",
">\n",
"> קבוצות מוגדרות על ידי מטריצת המרחקים שלהן, כלומר המרחקים בין נקודות. מרחק זה יכול להימדד בכמה דרכים. קבוצות אוקלידיות מוגדרות על ידי ממוצע ערכי הנקודות, ומכילות 'centroid' או נקודת מרכז. המרחקים נמדדים לפי המרחק לנקודת המרכז הזו. מרחקים לא אוקלידיים מתייחסים ל'clustroids', הנקודה הקרובה ביותר לנקודות אחרות. Clustroids בתורם יכולים להיות מוגדרים בדרכים שונות.\n",
">\n",
"> 🎓 ['מוגבל'](https://wikipedia.org/wiki/Constrained_clustering)\n",
">\n",
"> [Clustering מוגבל](https://web.cs.ucdavis.edu/~davidson/Publications/ICDMTutorial.pdf) מציג 'למידה חצי מונחית' לתוך שיטה בלתי מונחית זו. היחסים בין נקודות מסומנים כ'לא ניתן לקשר' או 'חייב לקשר' כך שכמה כללים נכפים על מערך הנתונים.\n",
">\n",
"> דוגמה: אם אלגוריתם משוחרר על מערך נתונים לא מתויג או מתויג חלקית, הקבוצות שהוא יוצר עשויות להיות באיכות ירודה. בדוגמה לעיל, הקבוצות עשויות לקבץ 'דברים מוזיקליים עגולים', 'דברים מוזיקליים מרובעים', 'דברים משולשים' ו'עוגיות'. אם ניתנים כמה מגבלות או כללים לעקוב אחריהם (\"הפריט חייב להיות עשוי מפלסטיק\", \"הפריט צריך להיות מסוגל להפיק מוזיקה\") זה יכול לעזור 'להגביל' את האלגוריתם לקבל החלטות טובות יותר.\n",
">\n",
"> 🎓 'צפיפות'\n",
">\n",
"> נתונים שהם 'רועשים' נחשבים ל'צפופים'. המרחקים בין נקודות בכל אחת מהקבוצות שלהם עשויים להוכיח, בבדיקה, שהם יותר או פחות צפופים, או 'צפופים' ולכן נתונים אלה צריכים להיות מנותחים עם שיטת Clustering מתאימה. [מאמר זה](https://www.kdnuggets.com/2020/02/understanding-density-based-clustering.html) מדגים את ההבדל בין שימוש ב-K-Means Clustering לעומת אלגוריתמים HDBSCAN כדי לחקור מערך נתונים רועש עם צפיפות קבוצות לא אחידה.\n",
"\n",
"העמיקו את ההבנה שלכם בטכניקות Clustering במודול [לימוד זה](https://docs.microsoft.com/learn/modules/train-evaluate-cluster-models?WT.mc_id=academic-77952-leestott)\n",
"\n",
"### **אלגוריתמי Clustering**\n",
"\n",
"ישנם מעל 100 אלגוריתמי Clustering, והשימוש בהם תלוי בטבע הנתונים שבידכם. בואו נדון בכמה מהעיקריים:\n",
"\n",
"- **Clustering היררכי**. אם אובייקט מסווג לפי קרבתו לאובייקט סמוך, ולא לאובייקט רחוק יותר, קבוצות נוצרות על בסיס המרחק של חבריהן אל ומאובייקטים אחרים. Clustering היררכי מאופיין בשילוב חוזר של שתי קבוצות.\n",
"\n",
"<p >\n",
" <img src=\"../../images/hierarchical.png\"\n",
" width=\"600\"/>\n",
" <figcaption>אינפוגרפיקה מאת דאסאני מדיפאלי</figcaption>\n",
"\n",
"\n",
"\n",
"- **Clustering מבוסס מרכז**. אלגוריתם פופולרי זה דורש בחירה של 'k', או מספר הקבוצות שיש ליצור, ולאחר מכן האלגוריתם קובע את נקודת המרכז של קבוצה ואוסף נתונים סביב אותה נקודה. [K-means Clustering](https://wikipedia.org/wiki/K-means_clustering) הוא גרסה פופולרית של Clustering מבוסס מרכז שמפריד מערך נתונים ל-K קבוצות מוגדרות מראש. המרכז נקבע לפי הממוצע הקרוב ביותר, ומכאן השם. המרחק הריבועי מהקבוצה ממוזער.\n",
"\n",
"<p >\n",
" <img src=\"../../images/centroid.png\"\n",
" width=\"600\"/>\n",
" <figcaption>אינפוגרפיקה מאת דאסאני מדיפאלי</figcaption>\n",
"\n",
"\n",
"\n",
"- **Clustering מבוסס התפלגות**. מבוסס על מודלים סטטיסטיים, Clustering מבוסס התפלגות מתמקד בקביעת ההסתברות שנקודת נתונים שייכת לקבוצה, ומקצה אותה בהתאם. שיטות Gaussian mixture שייכות לסוג זה.\n",
"\n",
"- **Clustering מבוסס צפיפות**. נקודות נתונים מוקצות לקבוצות על בסיס צפיפותן, או התאגדותן זו סביב זו. נקודות נתונים רחוקות מהקבוצה נחשבות לחריגות או רעש. DBSCAN, Mean-shift ו-OPTICS שייכים לסוג זה של Clustering.\n",
"\n",
"- **Clustering מבוסס רשת**. עבור מערכי נתונים רב-ממדיים, נוצרת רשת והנתונים מחולקים בין תאי הרשת, ובכך נוצרים קבוצות.\n",
"\n",
"הדרך הטובה ביותר ללמוד על Clustering היא לנסות זאת בעצמכם, וזה בדיוק מה שתעשו בתרגיל זה.\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",
"טכניקת האשכולות נעזרת מאוד בהדמיה נכונה, אז בואו נתחיל בהדמיה של נתוני המוזיקה שלנו. תרגיל זה יעזור לנו להחליט אילו שיטות אשכולות הכי יתאימו לאופי הנתונים הללו.\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": [
"לפעמים, אנחנו עשויים לרצות קצת יותר מידע על הנתונים שלנו. ניתן להסתכל על `הנתונים` ו-`המבנה שלהם` באמצעות הפונקציה [*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",
"> 🤔 אם אנחנו עובדים עם קלאסטרינג, שיטה לא מפוקחת שאינה דורשת נתונים מתויגים, מדוע אנחנו מציגים את הנתונים עם תוויות? בשלב חקר הנתונים, הם שימושיים, אבל הם לא הכרחיים כדי שהאלגוריתמים של הקלאסטרינג יעבדו.\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",
"אחת הדרכים להמחיש נתונים קטגוריים (משתנים מסוג תווים או גורמים) היא באמצעות תרשימי עמודות. בואו ניצור תרשים עמודות של עשרת הז'אנרים המובילים:\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": [
"עכשיו הרבה יותר קל לזהות שיש לנו ז'אנרים `חסרים` 🧐!\n",
"\n",
"> ויזואליזציה טובה תראה לך דברים שלא ציפית להם, או תעלה שאלות חדשות על הנתונים - האדלי וויקהאם וגרט גרולמונד, [R For Data Science](https://r4ds.had.co.nz/introduction.html)\n",
"\n",
"שימו לב, כאשר הז'אנר המוביל מתואר כ-`חסר`, זה אומר ש-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",
"> 🎓 שימו לב שמתאם אינו מעיד על סיבתיות! יש לנו הוכחה למתאם, אך אין לנו הוכחה לסיבתיות. באתר [משעשע](https://tylervigen.com/spurious-correlations) יש כמה חזותיות שמדגישות את הנקודה הזו.\n",
"\n",
"### 2. חקר התפלגות הנתונים\n",
"\n",
"בואו נשאל שאלות עדינות יותר. האם הז'אנרים שונים באופן משמעותי בתפיסת היכולת לרקוד שלהם, בהתבסס על הפופולריות שלהם? בואו נבחן את התפלגות הנתונים של שלושת הז'אנרים המובילים שלנו עבור פופולריות ויכולת לרקוד לאורך ציר x וציר y נתון באמצעות [גרפי צפיפות](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",
"באופן כללי, שלושת הז'אנרים מתיישרים מבחינת הפופולריות והריקודיות שלהם. זיהוי אשכולות בנתונים שמיושרים באופן רופף יהיה אתגר. בואו נראה אם תרשים פיזור יכול לתמוך בכך.\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",
"- בראדלי בוהמק וברנדון גרינוול, [*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) על יצירת הגרסה המקורית של מודול זה בפייתון ♥️\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\n**כתב ויתור**: \nמסמך זה תורגם באמצעות שירות תרגום מבוסס בינה מלאכותית [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-04T07:53:18+00:00",
"source_file": "5-Clustering/1-Visualize/solution/R/lesson_14-R.ipynb",
"language_code": "he"
}
},
"nbformat": 4,
"nbformat_minor": 1
}