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/bn/5-Clustering/2-K-Means/solution/R/lesson_15-R.ipynb

640 lines
46 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.

{
"nbformat": 4,
"nbformat_minor": 0,
"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"
},
"colab": {
"name": "lesson_14.ipynb",
"provenance": [],
"collapsed_sections": [],
"toc_visible": true
},
"coopTranslator": {
"original_hash": "ad65fb4aad0a156b42216e4929f490fc",
"translation_date": "2025-08-29T23:35:59+00:00",
"source_file": "5-Clustering/2-K-Means/solution/R/lesson_15-R.ipynb",
"language_code": "bn"
}
},
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "GULATlQXLXyR"
},
"source": [
"## R এবং Tidy ডেটা নীতিমালা ব্যবহার করে K-Means ক্লাস্টারিং অন্বেষণ করুন\n",
"\n",
"### [**পূর্ব-লেকচার কুইজ**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/29/)\n",
"\n",
"এই পাঠে, আপনি শিখবেন কীভাবে Tidymodels প্যাকেজ এবং R ইকোসিস্টেমের অন্যান্য প্যাকেজ (আমরা তাদের বন্ধু 🧑‍🤝‍🧑 বলব) ব্যবহার করে ক্লাস্টার তৈরি করতে হয় এবং আপনি আগে আমদানি করা নাইজেরিয়ান মিউজিক ডেটাসেট ব্যবহার করবেন। আমরা ক্লাস্টারিংয়ের জন্য K-Means-এর মৌলিক বিষয়গুলি কভার করব। মনে রাখবেন, যেমন আপনি আগের পাঠে শিখেছেন, ক্লাস্টারের সাথে কাজ করার অনেক পদ্ধতি রয়েছে এবং আপনি কোন পদ্ধতি ব্যবহার করবেন তা আপনার ডেটার উপর নির্ভর করে। আমরা K-Means চেষ্টা করব কারণ এটি সবচেয়ে সাধারণ ক্লাস্টারিং কৌশল। চলুন শুরু করি!\n",
"\n",
"আপনি যেসব শব্দ সম্পর্কে শিখবেন:\n",
"\n",
"- সিলুয়েট স্কোরিং\n",
"\n",
"- এলবো পদ্ধতি\n",
"\n",
"- জড়তা (Inertia)\n",
"\n",
"- ভ্যারিয়েন্স\n",
"\n",
"### **পরিচিতি**\n",
"\n",
"[K-Means Clustering](https://wikipedia.org/wiki/K-means_clustering) একটি পদ্ধতি যা সিগন্যাল প্রসেসিং ডোমেইন থেকে উদ্ভূত। এটি ডেটার বৈশিষ্ট্যের সাদৃশ্যের উপর ভিত্তি করে `k ক্লাস্টার`-এ গ্রুপ বিভক্ত এবং ভাগ করার জন্য ব্যবহৃত হয়।\n",
"\n",
"ক্লাস্টারগুলোকে [Voronoi diagrams](https://wikipedia.org/wiki/Voronoi_diagram) হিসেবে চিত্রায়িত করা যায়, যেখানে একটি পয়েন্ট (বা 'বীজ') এবং তার সংশ্লিষ্ট অঞ্চল অন্তর্ভুক্ত থাকে।\n",
"\n",
"<p >\n",
" <img src=\"../../images/voronoi.png\"\n",
" width=\"500\"/>\n",
" <figcaption>জেন লুপারের ইনফোগ্রাফিক</figcaption>\n",
"\n",
"\n",
"K-Means ক্লাস্টারিংয়ের ধাপগুলো নিম্নরূপ:\n",
"\n",
"1. ডেটা বিজ্ঞানী প্রথমে তৈরি করতে চাওয়া ক্লাস্টারের সংখ্যা নির্দিষ্ট করেন।\n",
"\n",
"2. এরপর, অ্যালগরিদম এলোমেলোভাবে ডেটাসেট থেকে Kটি পর্যবেক্ষণ নির্বাচন করে যা ক্লাস্টারের প্রাথমিক কেন্দ্র (অর্থাৎ, সেন্ট্রয়েড) হিসেবে কাজ করবে।\n",
"\n",
"3. এরপর, বাকি প্রতিটি পর্যবেক্ষণকে তার নিকটতম সেন্ট্রয়েডে বরাদ্দ করা হয়।\n",
"\n",
"4. এরপর, প্রতিটি ক্লাস্টারের নতুন গড় গণনা করা হয় এবং সেন্ট্রয়েডকে গড়ে সরানো হয়।\n",
"\n",
"5. এখন যেহেতু কেন্দ্রগুলো পুনরায় গণনা করা হয়েছে, প্রতিটি পর্যবেক্ষণ আবার পরীক্ষা করা হয় এটি অন্য কোনো ক্লাস্টারের কাছাকাছি হতে পারে কিনা। সমস্ত অবজেক্ট আবার আপডেট হওয়া ক্লাস্টার গড় ব্যবহার করে পুনরায় বরাদ্দ করা হয়। ক্লাস্টার বরাদ্দ এবং সেন্ট্রয়েড আপডেট ধাপগুলো পুনরাবৃত্তি করা হয় যতক্ষণ না ক্লাস্টার বরাদ্দ পরিবর্তন হওয়া বন্ধ হয় (অর্থাৎ, যখন কনভার্জেন্স অর্জিত হয়)। সাধারণত, অ্যালগরিদম তখন বন্ধ হয় যখন প্রতিটি নতুন পুনরাবৃত্তি সেন্ট্রয়েডের নগণ্য গতিবিধি এবং ক্লাস্টারগুলো স্থির হয়ে যায়।\n",
"\n",
"<div>\n",
"\n",
"> মনে রাখবেন যে প্রাথমিক k পর্যবেক্ষণ এলোমেলোভাবে শুরু সেন্ট্রয়েড হিসেবে ব্যবহৃত হওয়ার কারণে, আমরা প্রতিবার পদ্ধতিটি প্রয়োগ করার সময় সামান্য ভিন্ন ফলাফল পেতে পারি। এই কারণে, বেশিরভাগ অ্যালগরিদম একাধিক *random starts* ব্যবহার করে এবং সর্বনিম্ন WCSS সহ পুনরাবৃত্তি নির্বাচন করে। সুতরাং, একটি *অপ্রীতিকর স্থানীয় অপ্টিমাম* এড়াতে সর্বদা K-Means একাধিক *nstart* মান দিয়ে চালানো অত্যন্ত সুপারিশ করা হয়।\n",
"\n",
"</div>\n",
"\n",
"অ্যালিসন হর্স্টের [চিত্রকর্ম](https://github.com/allisonhorst/stats-illustrations) ব্যবহার করে এই সংক্ষিপ্ত অ্যানিমেশনটি ক্লাস্টারিং প্রক্রিয়াটি ব্যাখ্যা করে:\n",
"\n",
"<p >\n",
" <img src=\"../../images/kmeans.gif\"\n",
" width=\"550\"/>\n",
" <figcaption>@allison_horst এর চিত্রকর্ম</figcaption>\n",
"\n",
"\n",
"\n",
"ক্লাস্টারিংয়ে একটি মৌলিক প্রশ্ন হলো: আপনি কীভাবে জানবেন আপনার ডেটাকে কতগুলো ক্লাস্টারে ভাগ করবেন? K-Means ব্যবহারের একটি অসুবিধা হলো আপনাকে `k` নির্ধারণ করতে হবে, অর্থাৎ `centroids`-এর সংখ্যা। সৌভাগ্যক্রমে, `elbow method` `k`-এর জন্য একটি ভালো প্রাথমিক মান অনুমান করতে সাহায্য করে। আপনি এটি একটু পরেই চেষ্টা করবেন।\n",
"\n",
"### \n",
"\n",
"**প্রয়োজনীয়তা**\n",
"\n",
"আমরা [পূর্ববর্তী পাঠ](https://github.com/microsoft/ML-For-Beginners/blob/main/5-Clustering/1-Visualize/solution/R/lesson_14-R.ipynb) থেকে ঠিক যেখানে থেমেছিলাম সেখান থেকে শুরু করব, যেখানে আমরা ডেটাসেট বিশ্লেষণ করেছি, অনেক ভিজ্যুয়ালাইজেশন তৈরি করেছি এবং আগ্রহের পর্যবেক্ষণগুলিতে ডেটাসেট ফিল্টার করেছি। এটি অবশ্যই দেখে নিন!\n",
"\n",
"এই মডিউলটি সম্পন্ন করতে আমাদের কিছু প্যাকেজ প্রয়োজন হবে। আপনি সেগুলো ইনস্টল করতে পারেন: `install.packages(c('tidyverse', 'tidymodels', 'cluster', 'summarytools', 'plotly', 'paletteer', 'factoextra', 'patchwork'))`\n",
"\n",
"অথবা, নিচের স্ক্রিপ্টটি পরীক্ষা করে দেখবে আপনার কাছে এই মডিউল সম্পন্ন করার জন্য প্রয়োজনীয় প্যাকেজগুলো আছে কিনা এবং যদি কিছু অনুপস্থিত থাকে তবে সেগুলো ইনস্টল করবে।\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "ah_tBi58LXyi"
},
"source": [
"suppressWarnings(if(!require(\"pacman\")) install.packages(\"pacman\"))\n",
"\n",
"pacman::p_load('tidyverse', 'tidymodels', 'cluster', 'summarytools', 'plotly', 'paletteer', 'factoextra', 'patchwork')\n"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "7e--UCUTLXym"
},
"source": [
"চলুন দ্রুত শুরু করি!\n",
"\n",
"## ১. ডেটার সাথে নাচ: তিনটি সবচেয়ে জনপ্রিয় সঙ্গীত ঘরানা নির্ধারণ করুন\n",
"\n",
"এটি আগের পাঠে আমরা যা করেছি তার একটি পুনরাবৃত্তি। চলুন কিছু ডেটা বিশ্লেষণ করি!\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "Ycamx7GGLXyn"
},
"source": [
"# Load the core tidyverse and make it available in your current R session\n",
"library(tidyverse)\n",
"\n",
"# Import the data into a tibble\n",
"df <- read_csv(file = \"https://raw.githubusercontent.com/microsoft/ML-For-Beginners/main/5-Clustering/data/nigerian-songs.csv\", show_col_types = FALSE)\n",
"\n",
"# Narrow down to top 3 popular genres\n",
"nigerian_songs <- df %>% \n",
" # Concentrate on top 3 genres\n",
" filter(artist_top_genre %in% c(\"afro dancehall\", \"afropop\",\"nigerian pop\")) %>% \n",
" # Remove unclassified observations\n",
" filter(popularity != 0)\n",
"\n",
"\n",
"\n",
"# Visualize popular genres using bar plots\n",
"theme_set(theme_light())\n",
"nigerian_songs %>%\n",
" count(artist_top_genre) %>%\n",
" ggplot(mapping = aes(x = artist_top_genre, y = n,\n",
" fill = artist_top_genre)) +\n",
" geom_col(alpha = 0.8) +\n",
" paletteer::scale_fill_paletteer_d(\"ggsci::category10_d3\") +\n",
" ggtitle(\"Top genres\") +\n",
" theme(plot.title = element_text(hjust = 0.5))\n"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "b5h5zmkPLXyp"
},
"source": [
"🤩 এটি বেশ ভালো হলো!\n",
"\n",
"## ২. আরও ডেটা অনুসন্ধান।\n",
"\n",
"এই ডেটা কতটা পরিষ্কার? বক্সপ্লট ব্যবহার করে আউটলায়ার পরীক্ষা করা যাক। আমরা এমন সংখ্যাসূচক কলামগুলোর উপর মনোযোগ দেব যেখানে আউটলায়ার কম (যদিও আপনি আউটলায়ারগুলো সরিয়ে ফেলতে পারেন)। বক্সপ্লট ডেটার পরিসীমা দেখাতে পারে এবং কোন কলামগুলো ব্যবহার করা হবে তা বেছে নিতে সাহায্য করবে। তবে মনে রাখবেন, বক্সপ্লট ভ্যারিয়েন্স দেখায় না, যা ভালো ক্লাস্টারযোগ্য ডেটার একটি গুরুত্বপূর্ণ উপাদান। আরও জানতে [এই আলোচনা](https://stats.stackexchange.com/questions/91536/deduce-variance-from-boxplot) দেখুন।\n",
"\n",
"[বক্সপ্লট](https://en.wikipedia.org/wiki/Box_plot) সংখ্যাসূচক ডেটার বণ্টন গ্রাফিক্যালি উপস্থাপন করতে ব্যবহৃত হয়, তাই আসুন জনপ্রিয় সঙ্গীত ঘরানার পাশাপাশি সমস্ত সংখ্যাসূচক কলাম *নির্বাচন* করে শুরু করি।\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "HhNreJKLLXyq"
},
"source": [
"# Select top genre column and all other numeric columns\n",
"df_numeric <- nigerian_songs %>% \n",
" select(artist_top_genre, where(is.numeric)) \n",
"\n",
"# Display the data\n",
"df_numeric %>% \n",
" slice_head(n = 5)\n"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "uYXrwJRaLXyq"
},
"source": [
"দেখুন কীভাবে `where` সিলেকশন হেল্পারটি এটি সহজ করে তোলে 💁? এমন আরও ফাংশন [এখানে](https://tidyselect.r-lib.org/) অন্বেষণ করুন।\n",
"\n",
"যেহেতু আমরা প্রতিটি সংখ্যাসূচক বৈশিষ্ট্যের জন্য একটি বক্সপ্লট তৈরি করব এবং লুপ ব্যবহার এড়াতে চাই, আসুন আমাদের ডেটাকে একটি *লম্বা* ফরম্যাটে রূপান্তর করি যা আমাদের `facets` - সাবপ্লট যা প্রতিটি ডেটার একটি উপসেট প্রদর্শন করে - এর সুবিধা নিতে সাহায্য করবে।\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "gd5bR3f8LXys"
},
"source": [
"# Pivot data from wide to long\n",
"df_numeric_long <- df_numeric %>% \n",
" pivot_longer(!artist_top_genre, names_to = \"feature_names\", values_to = \"values\") \n",
"\n",
"# Print out data\n",
"df_numeric_long %>% \n",
" slice_head(n = 15)\n"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "-7tE1swnLXyv"
},
"source": [
"আরও দীর্ঘ! এখন কিছু `ggplots` এর সময়! তাহলে আমরা কোন `geom` ব্যবহার করব?\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "r88bIsyuLXyy"
},
"source": [
"# Make a box plot\n",
"df_numeric_long %>% \n",
" ggplot(mapping = aes(x = feature_names, y = values, fill = feature_names)) +\n",
" geom_boxplot() +\n",
" facet_wrap(~ feature_names, ncol = 4, scales = \"free\") +\n",
" theme(legend.position = \"none\")\n"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "EYVyKIUELXyz"
},
"source": [
"এখন আমরা দেখতে পাচ্ছি যে এই ডেটা কিছুটা বিশৃঙ্খল: প্রতিটি কলামকে একটি বক্সপ্লট হিসেবে পর্যবেক্ষণ করলে আপনি আউটলায়ার দেখতে পাবেন। আপনি ডেটাসেটটি পর্যবেক্ষণ করে এই আউটলায়ারগুলো সরিয়ে ফেলতে পারেন, তবে এতে ডেটা খুবই সীমিত হয়ে যাবে।\n",
"\n",
"এখন, চলুন ঠিক করি কোন কোন কলাম আমরা আমাদের ক্লাস্টারিং অনুশীলনের জন্য ব্যবহার করব। চলুন একই রেঞ্জের সংখ্যাসূচক কলামগুলো বেছে নিই। আমরা `artist_top_genre`-কে সংখ্যায় রূপান্তর করতে পারতাম, তবে আপাতত এটি বাদ দিচ্ছি।\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "-wkpINyZLXy0"
},
"source": [
"# Select variables with similar ranges\n",
"df_numeric_select <- df_numeric %>% \n",
" select(popularity, danceability, acousticness, loudness, energy) \n",
"\n",
"# Normalize data\n",
"# df_numeric_select <- scale(df_numeric_select)\n"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "D7dLzgpqLXy1"
},
"source": [
"## ৩. R-এ k-means ক্লাস্টারিং গণনা করা\n",
"\n",
"আমরা R-এ বিল্ট-ইন `kmeans` ফাংশন ব্যবহার করে k-means গণনা করতে পারি, দেখুন `help(\"kmeans()\")`। `kmeans()` ফাংশন একটি ডেটা ফ্রেম গ্রহণ করে যার সমস্ত কলাম সংখ্যা-ভিত্তিক, এবং এটি এর প্রধান আর্গুমেন্ট।\n",
"\n",
"k-means ক্লাস্টারিং ব্যবহার করার প্রথম ধাপ হলো ক্লাস্টারের সংখ্যা (k) নির্ধারণ করা, যা চূড়ান্ত সমাধানে তৈরি হবে। আমরা জানি যে ডেটাসেট থেকে আমরা ৩টি গানের ঘরানা বের করেছি, তাই চলুন ৩টি চেষ্টা করি:\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "uC4EQ5w7LXy5"
},
"source": [
"set.seed(2056)\n",
"# Kmeans clustering for 3 clusters\n",
"kclust <- kmeans(\n",
" df_numeric_select,\n",
" # Specify the number of clusters\n",
" centers = 3,\n",
" # How many random initial configurations\n",
" nstart = 25\n",
")\n",
"\n",
"# Display clustering object\n",
"kclust\n"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "hzfhscWrLXy-"
},
"source": [
"kmeans অবজেক্টে বেশ কিছু তথ্য থাকে যা `help(\"kmeans()\")`-এ ভালোভাবে ব্যাখ্যা করা হয়েছে। আপাতত, আমরা কয়েকটি বিষয়ে মনোযোগ দিই। আমরা দেখতে পাচ্ছি যে ডেটা ৩টি ক্লাস্টারে ভাগ করা হয়েছে, যার সাইজ যথাক্রমে ৬৫, ১১০, ১১১। আউটপুটে ৫টি ভেরিয়েবলের উপর ভিত্তি করে ৩টি গ্রুপের ক্লাস্টার সেন্টার (গড়) রয়েছে।\n",
"\n",
"ক্লাস্টারিং ভেক্টর প্রতিটি পর্যবেক্ষণের জন্য ক্লাস্টার অ্যাসাইনমেন্ট নির্দেশ করে। আসুন `augment` ফাংশন ব্যবহার করে মূল ডেটাসেটে ক্লাস্টার অ্যাসাইনমেন্ট যোগ করি।\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "0XwwpFGQLXy_"
},
"source": [
"# Add predicted cluster assignment to data set\n",
"augment(kclust, df_numeric_select) %>% \n",
" relocate(.cluster) %>% \n",
" slice_head(n = 10)\n"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "NXIVXXACLXzA"
},
"source": [
"দারুণ, আমরা আমাদের ডেটাসেটকে ৩টি গ্রুপে ভাগ করেছি। তাহলে, আমাদের ক্লাস্টারিং কতটা ভালো 🤷? চলুন `Silhouette score` দেখে নিই।\n",
"\n",
"### **Silhouette score**\n",
"\n",
"[Silhouette বিশ্লেষণ](https://en.wikipedia.org/wiki/Silhouette_(clustering)) ব্যবহার করে আমরা ক্লাস্টারগুলোর মধ্যে বিভাজন দূরত্ব বিশ্লেষণ করতে পারি। এই স্কোর -1 থেকে 1 এর মধ্যে পরিবর্তিত হয়। যদি স্কোর 1 এর কাছাকাছি হয়, তাহলে ক্লাস্টারটি ঘন এবং অন্যান্য ক্লাস্টার থেকে ভালোভাবে পৃথক। 0 এর কাছাকাছি মান নির্দেশ করে যে ক্লাস্টারগুলো একে অপরের সাথে ওভারল্যাপ করছে এবং নমুনাগুলো প্রতিবেশী ক্লাস্টারের সিদ্ধান্ত সীমানার খুব কাছাকাছি। [source](https://dzone.com/articles/kmeans-silhouette-score-explained-with-python-exam)।\n",
"\n",
"গড় silhouette পদ্ধতি বিভিন্ন *k* এর মানের জন্য পর্যবেক্ষণগুলোর গড় silhouette স্কোর গণনা করে। একটি উচ্চ গড় silhouette স্কোর একটি ভালো ক্লাস্টারিং নির্দেশ করে।\n",
"\n",
"`silhouette` ফাংশনটি ক্লাস্টার প্যাকেজে ব্যবহার করা হয় গড় silhouette প্রস্থ গণনা করার জন্য।\n",
"\n",
"> Silhouette যেকোনো [দূরত্ব](https://en.wikipedia.org/wiki/Distance \"Distance\") মেট্রিক ব্যবহার করে গণনা করা যেতে পারে, যেমন [Euclidean distance](https://en.wikipedia.org/wiki/Euclidean_distance \"Euclidean distance\") বা [Manhattan distance](https://en.wikipedia.org/wiki/Manhattan_distance \"Manhattan distance\"), যা আমরা [পূর্ববর্তী পাঠে](https://github.com/microsoft/ML-For-Beginners/blob/main/5-Clustering/1-Visualize/solution/R/lesson_14-R.ipynb) আলোচনা করেছি।\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "Jn0McL28LXzB"
},
"source": [
"# Load cluster package\n",
"library(cluster)\n",
"\n",
"# Compute average silhouette score\n",
"ss <- silhouette(kclust$cluster,\n",
" # Compute euclidean distance\n",
" dist = dist(df_numeric_select))\n",
"mean(ss[, 3])\n"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "QyQRn97nLXzC"
},
"source": [
"আমাদের স্কোর **.549**, যা মাঝামাঝি অবস্থানে রয়েছে। এটি নির্দেশ করে যে আমাদের ডেটা এই ধরনের ক্লাস্টারিংয়ের জন্য বিশেষভাবে উপযুক্ত নয়। চলুন দেখি আমরা এই ধারণাটি চাক্ষুষভাবে নিশ্চিত করতে পারি কিনা। [factoextra প্যাকেজ](https://rpkgs.datanovia.com/factoextra/index.html) ক্লাস্টারিং চিত্রায়নের জন্য ফাংশন (`fviz_cluster()`) প্রদান করে।\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "7a6Km1_FLXzD"
},
"source": [
"library(factoextra)\n",
"\n",
"# Visualize clustering results\n",
"fviz_cluster(kclust, df_numeric_select)\n"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "IBwCWt-0LXzD"
},
"source": [
"ক্লাস্টারগুলোর মধ্যে ওভারল্যাপ নির্দেশ করে যে আমাদের ডেটা এই ধরনের ক্লাস্টারিংয়ের জন্য বিশেষভাবে উপযুক্ত নয়, তবে চলুন আমরা এগিয়ে যাই।\n",
"\n",
"## . অপ্টিমাল ক্লাস্টার নির্ধারণ\n",
"\n",
"K-Means ক্লাস্টারিংয়ে একটি মৌলিক প্রশ্ন প্রায়ই উঠে আসে - যদি ক্লাস লেবেল জানা না থাকে, তাহলে কীভাবে বুঝবেন যে আপনার ডেটাকে কতগুলো ক্লাস্টারে ভাগ করতে হবে?\n",
"\n",
"আমরা এটি জানার একটি উপায় হলো একটি ডেটা স্যাম্পল ব্যবহার করে `একটি সিরিজ ক্লাস্টারিং মডেল তৈরি করা`, যেখানে ক্লাস্টারের সংখ্যা ধাপে ধাপে বাড়ানো হয় (যেমন ১ থেকে ১০ পর্যন্ত), এবং ক্লাস্টারিং মেট্রিক যেমন **Silhouette স্কোর** মূল্যায়ন করা।\n",
"\n",
"চলুন বিভিন্ন *k* এর জন্য ক্লাস্টারিং অ্যালগরিদম গণনা করে এবং **Within Cluster Sum of Squares** (WCSS) মূল্যায়ন করে অপ্টিমাল ক্লাস্টারের সংখ্যা নির্ধারণ করি। টোটাল Within Cluster Sum of Squares (WCSS) ক্লাস্টারিংয়ের কমপ্যাক্টনেস পরিমাপ করে এবং আমরা চাই এটি যতটা সম্ভব ছোট হোক, কারণ ছোট মান নির্দেশ করে যে ডেটা পয়েন্টগুলো একে অপরের কাছাকাছি।\n",
"\n",
"চলুন `k` এর বিভিন্ন মান (১ থেকে ১০ পর্যন্ত) এই ক্লাস্টারিংয়ে কী প্রভাব ফেলে তা অন্বেষণ করি।\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "hSeIiylDLXzE"
},
"source": [
"# Create a series of clustering models\n",
"kclusts <- tibble(k = 1:10) %>% \n",
" # Perform kmeans clustering for 1,2,3 ... ,10 clusters\n",
" mutate(model = map(k, ~ kmeans(df_numeric_select, centers = .x, nstart = 25)),\n",
" # Farm out clustering metrics eg WCSS\n",
" glanced = map(model, ~ glance(.x))) %>% \n",
" unnest(cols = glanced)\n",
" \n",
"\n",
"# View clustering rsulsts\n",
"kclusts\n"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "m7rS2U1eLXzE"
},
"source": [
"এখন আমাদের কাছে প্রতিটি ক্লাস্টারিং অ্যালগরিদমের জন্য কেন্দ্র *k* সহ মোট ক্লাস্টারের মধ্যে যোগফল (tot.withinss) রয়েছে, আমরা [elbow method](https://en.wikipedia.org/wiki/Elbow_method_(clustering)) ব্যবহার করে ক্লাস্টারের সর্বোত্তম সংখ্যা নির্ধারণ করি। এই পদ্ধতিতে ক্লাস্টারের সংখ্যার উপর ভিত্তি করে WCSS এর একটি গ্রাফ আঁকা হয় এবং [বক্ররেখার কনুই](https://en.wikipedia.org/wiki/Elbow_of_the_curve \"Elbow of the curve\") নির্বাচন করা হয় ক্লাস্টারের সংখ্যা হিসাবে।\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "o_DjHGItLXzF"
},
"source": [
"set.seed(2056)\n",
"# Use elbow method to determine optimum number of clusters\n",
"kclusts %>% \n",
" ggplot(mapping = aes(x = k, y = tot.withinss)) +\n",
" geom_line(size = 1.2, alpha = 0.8, color = \"#FF7F0EFF\") +\n",
" geom_point(size = 2, color = \"#FF7F0EFF\")\n"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "pLYyt5XSLXzG"
},
"source": [
"প্লটে দেখা যাচ্ছে যে WCSS-এ (অর্থাৎ, বেশি *ঘনত্ব*) একটি বড় পরিমাণ হ্রাস ঘটে যখন ক্লাস্টারের সংখ্যা এক থেকে দুইয়ে বৃদ্ধি পায়, এবং দুই থেকে তিন ক্লাস্টারে আরও একটি উল্লেখযোগ্য হ্রাস দেখা যায়। এর পর থেকে হ্রাসের মাত্রা তেমন স্পষ্ট নয়, যার ফলে চার্টে প্রায় তিনটি ক্লাস্টারের কাছাকাছি একটি `elbow` 💪 তৈরি হয়। এটি একটি ভালো ইঙ্গিত দেয় যে ডেটা পয়েন্টগুলোর মধ্যে দুই থেকে তিনটি যথেষ্ট ভালোভাবে পৃথক ক্লাস্টার রয়েছে।\n",
"\n",
"এখন আমরা `k = 3` এর জন্য ক্লাস্টারিং মডেলটি বের করতে পারি:\n",
"\n",
"> `pull()`: একটি একক কলাম বের করতে ব্যবহৃত হয় \n",
">\n",
"> `pluck()`: তালিকা বা অনুরূপ ডেটা কাঠামো থেকে ডেটা সূচক করতে ব্যবহৃত হয় \n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "JP_JPKBILXzG"
},
"source": [
"# Extract k = 3 clustering\n",
"final_kmeans <- kclusts %>% \n",
" filter(k == 3) %>% \n",
" pull(model) %>% \n",
" pluck(1)\n",
"\n",
"\n",
"final_kmeans\n"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "l_PDTu8tLXzI"
},
"source": [
"চলুন, আমরা প্রাপ্ত ক্লাস্টারগুলো ভিজুয়ালাইজ করি। `plotly` ব্যবহার করে কিছু ইন্টারঅ্যাক্টিভিটি যোগ করতে চান?\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "dNcleFe-LXzJ"
},
"source": [
"# Add predicted cluster assignment to data set\n",
"results <- augment(final_kmeans, df_numeric_select) %>% \n",
" bind_cols(df_numeric %>% select(artist_top_genre)) \n",
"\n",
"# Plot cluster assignments\n",
"clust_plt <- results %>% \n",
" ggplot(mapping = aes(x = popularity, y = danceability, color = .cluster, shape = artist_top_genre)) +\n",
" geom_point(size = 2, alpha = 0.8) +\n",
" paletteer::scale_color_paletteer_d(\"ggthemes::Tableau_10\")\n",
"\n",
"ggplotly(clust_plt)\n"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "6JUM_51VLXzK"
},
"source": [
"সম্ভবত আমরা আশা করতাম যে প্রতিটি ক্লাস্টার (বিভিন্ন রঙ দ্বারা উপস্থাপিত) আলাদা আলাদা ঘরানা (বিভিন্ন আকার দ্বারা উপস্থাপিত) থাকবে।\n",
"\n",
"চলুন মডেলের সঠিকতা দেখে নিই।\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "HdIMUGq7LXzL"
},
"source": [
"# Assign genres to predefined integers\n",
"label_count <- results %>% \n",
" group_by(artist_top_genre) %>% \n",
" mutate(id = cur_group_id()) %>% \n",
" ungroup() %>% \n",
" summarise(correct_labels = sum(.cluster == id))\n",
"\n",
"\n",
"# Print results \n",
"cat(\"Result:\", label_count$correct_labels, \"out of\", nrow(results), \"samples were correctly labeled.\")\n",
"\n",
"cat(\"\\nAccuracy score:\", label_count$correct_labels/nrow(results))\n"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "C50wvaAOLXzM"
},
"source": [
"এই মডেলের সঠিকতা খারাপ নয়, তবে খুব ভালোও নয়। হতে পারে যে ডেটা K-Means ক্লাস্টারিংয়ের জন্য খুব উপযুক্ত নয়। এই ডেটা খুবই অসম, খুব কম সম্পর্কযুক্ত এবং কলাম মানগুলির মধ্যে অনেক বেশি বৈচিত্র্য রয়েছে যা ভালোভাবে ক্লাস্টার করতে বাধা দেয়। প্রকৃতপক্ষে, গঠিত ক্লাস্টারগুলি সম্ভবত উপরে সংজ্ঞায়িত তিনটি ঘরানার দ্বারা ভারীভাবে প্রভাবিত বা বিকৃত হয়।\n",
"\n",
"তবুও, এটি একটি চমৎকার শেখার প্রক্রিয়া ছিল!\n",
"\n",
"Scikit-learn এর ডকুমেন্টেশনে, আপনি দেখতে পাবেন যে এই ধরনের একটি মডেল, যেখানে ক্লাস্টারগুলি খুব ভালোভাবে চিহ্নিত নয়, একটি 'বৈচিত্র্য' সমস্যার সম্মুখীন হয়:\n",
"\n",
"<p >\n",
" <img src=\"../../images/problems.png\"\n",
" width=\"500\"/>\n",
" <figcaption>Scikit-learn থেকে ইনফোগ্রাফিক</figcaption>\n",
"\n",
"\n",
"\n",
"## **বৈচিত্র্য**\n",
"\n",
"বৈচিত্র্যকে সংজ্ঞায়িত করা হয় \"গড় থেকে বর্গমূল পার্থক্যের গড়\" [উৎস](https://www.mathsisfun.com/data/standard-deviation.html)। এই ক্লাস্টারিং সমস্যার প্রেক্ষিতে, এটি বোঝায় যে আমাদের ডেটাসেটের সংখ্যাগুলি গড় থেকে একটু বেশিই বিচ্যুত হওয়ার প্রবণতা দেখায়।\n",
"\n",
"✅ এটি একটি দুর্দান্ত মুহূর্ত এই সমস্যাটি সমাধানের সমস্ত উপায় নিয়ে ভাবার জন্য। ডেটা আরেকটু পরিবর্তন করবেন? ভিন্ন কলাম ব্যবহার করবেন? ভিন্ন অ্যালগরিদম ব্যবহার করবেন? ইঙ্গিত: আপনার ডেটা [স্কেলিং](https://www.mygreatlearning.com/blog/learning-data-science-with-k-means-clustering/) করার চেষ্টা করুন এটি স্বাভাবিক করতে এবং অন্যান্য কলাম পরীক্ষা করুন।\n",
"\n",
"> এই '[বৈচিত্র্য ক্যালকুলেটর](https://www.calculatorsoup.com/calculators/statistics/variance-calculator.php)' ব্যবহার করে ধারণাটি আরও ভালোভাবে বোঝার চেষ্টা করুন।\n",
"\n",
"------------------------------------------------------------------------\n",
"\n",
"## **🚀চ্যালেঞ্জ**\n",
"\n",
"এই নোটবুকের সাথে কিছু সময় কাটান, প্যারামিটার পরিবর্তন করুন। ডেটা আরও পরিষ্কার করে (উদাহরণস্বরূপ, আউটলায়ার সরিয়ে) মডেলের সঠিকতা বাড়াতে পারবেন কি? আপনি নির্দিষ্ট ডেটা নমুনাগুলিকে বেশি ওজন দিতে ওজন ব্যবহার করতে পারেন। আরও কী করতে পারেন যাতে ভালো ক্লাস্টার তৈরি হয়?\n",
"\n",
"ইঙ্গিত: আপনার ডেটা স্কেল করার চেষ্টা করুন। নোটবুকে মন্তব্য করা কোড রয়েছে যা স্ট্যান্ডার্ড স্কেলিং যোগ করে যাতে ডেটা কলামগুলি রেঞ্জের দিক থেকে একে অপরের সাথে আরও ঘনিষ্ঠভাবে সাদৃশ্যপূর্ণ হয়। আপনি দেখতে পাবেন যে সিলুয়েট স্কোর কমে যায়, তবে 'কিংক' এলবো গ্রাফে মসৃণ হয়ে যায়। এর কারণ হল ডেটা স্কেল না করলে কম বৈচিত্র্যযুক্ত ডেটা বেশি ওজন বহন করতে পারে। এই সমস্যাটি সম্পর্কে আরও পড়ুন [এখানে](https://stats.stackexchange.com/questions/21222/are-mean-normalization-and-feature-scaling-needed-for-k-means-clustering/21226#21226)।\n",
"\n",
"## [**পোস্ট-লেকচার কুইজ**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/30/)\n",
"\n",
"## **পুনরালোচনা ও স্ব-অধ্যয়ন**\n",
"\n",
"- একটি K-Means সিমুলেটর [যেমন এটি](https://user.ceng.metu.edu.tr/~akifakkus/courses/ceng574/k-means/) দেখুন। আপনি এই টুলটি ব্যবহার করে নমুনা ডেটা পয়েন্টগুলি ভিজ্যুয়ালাইজ করতে এবং এর সেন্ট্রয়েড নির্ধারণ করতে পারেন। আপনি ডেটার র‍্যান্ডমনেস, ক্লাস্টারের সংখ্যা এবং সেন্ট্রয়েডের সংখ্যা সম্পাদনা করতে পারেন। এটি কি আপনাকে ডেটা কীভাবে গোষ্ঠীবদ্ধ করা যায় সে সম্পর্কে ধারণা পেতে সাহায্য করে?\n",
"\n",
"- এছাড়াও, [স্ট্যানফোর্ডের এই হ্যান্ডআউট](https://stanford.edu/~cpiech/cs221/handouts/kmeans.html) দেখুন K-Means সম্পর্কে।\n",
"\n",
"আপনার সদ্য অর্জিত ক্লাস্টারিং দক্ষতাগুলি এমন ডেটাসেটে প্রয়োগ করতে চান যা K-Means ক্লাস্টারিংয়ের জন্য উপযুক্ত? দয়া করে দেখুন:\n",
"\n",
"- [ক্লাস্টারিং মডেল প্রশিক্ষণ এবং মূল্যায়ন](https://rpubs.com/eR_ic/clustering) Tidymodels এবং বন্ধুদের ব্যবহার করে\n",
"\n",
"- [K-means ক্লাস্টার বিশ্লেষণ](https://uc-r.github.io/kmeans_clustering), UC বিজনেস অ্যানালিটিক্স R প্রোগ্রামিং গাইড\n",
"\n",
"- [টিডি ডেটা নীতির সাথে K-means ক্লাস্টারিং](https://www.tidymodels.org/learn/statistics/k-means/)\n",
"\n",
"## **অ্যাসাইনমেন্ট**\n",
"\n",
"[বিভিন্ন ক্লাস্টারিং পদ্ধতি চেষ্টা করুন](https://github.com/microsoft/ML-For-Beginners/blob/main/5-Clustering/2-K-Means/assignment.md)\n",
"\n",
"## ধন্যবাদ:\n",
"\n",
"[জেন লুপার](https://www.twitter.com/jenlooper) এই মডিউলের মূল পাইথন সংস্করণ তৈরি করার জন্য ♥️\n",
"\n",
"[`অ্যালিসন হর্স্ট`](https://twitter.com/allison_horst/) অসাধারণ ইলাস্ট্রেশন তৈরি করার জন্য যা R-কে আরও স্বাগত এবং আকর্ষণীয় করে তোলে। তার আরও ইলাস্ট্রেশন খুঁজুন তার [গ্যালারিতে](https://www.google.com/url?q=https://github.com/allisonhorst/stats-illustrations&sa=D&source=editors&ust=1626380772530000&usg=AOvVaw3zcfyCizFQZpkSLzxiiQEM)।\n",
"\n",
"শুভ শেখা,\n",
"\n",
"[এরিক](https://twitter.com/ericntay), গোল্ড মাইক্রোসফট লার্ন স্টুডেন্ট অ্যাম্বাসেডর।\n",
"\n",
"<p >\n",
" <img src=\"../../images/r_learners_sm.jpeg\"\n",
" width=\"500\"/>\n",
" <figcaption>@allison_horst এর শিল্পকর্ম</figcaption>\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**অস্বীকৃতি**: \nএই নথিটি AI অনুবাদ পরিষেবা [Co-op Translator](https://github.com/Azure/co-op-translator) ব্যবহার করে অনুবাদ করা হয়েছে। আমরা যথাসম্ভব সঠিক অনুবাদ প্রদানের চেষ্টা করি, তবে অনুগ্রহ করে মনে রাখবেন যে স্বয়ংক্রিয় অনুবাদে ত্রুটি বা অসঙ্গতি থাকতে পারে। মূল ভাষায় থাকা নথিটিকে প্রামাণিক উৎস হিসেবে বিবেচনা করা উচিত। গুরুত্বপূর্ণ তথ্যের জন্য, পেশাদার মানব অনুবাদ সুপারিশ করা হয়। এই অনুবাদ ব্যবহারের ফলে কোনো ভুল বোঝাবুঝি বা ভুল ব্যাখ্যা হলে আমরা তার জন্য দায়ী থাকব না।\n"
]
}
]
}