{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "## লজিস্টিক রিগ্রেশন মডেল তৈরি করুন - পাঠ ৪\n", "\n", "![লজিস্টিক বনাম লিনিয়ার রিগ্রেশন ইনফোগ্রাফিক](../../../../../../translated_images/linear-vs-logistic.ba180bf95e7ee66721ba10ebf2dac2666acbd64a88b003c83928712433a13c7d.bn.png)\n", "\n", "#### **[পাঠের পূর্ববর্তী কুইজ](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/15/)**\n", "\n", "#### ভূমিকা\n", "\n", "রিগ্রেশনের উপর এই চূড়ান্ত পাঠে, যা একটি মৌলিক *ক্লাসিক* মেশিন লার্নিং কৌশল, আমরা লজিস্টিক রিগ্রেশন নিয়ে আলোচনা করব। এই কৌশলটি ব্যবহার করে আপনি প্যাটার্ন খুঁজে বের করতে পারেন যা বাইনারি ক্যাটাগরি পূর্বাভাস দিতে সাহায্য করে। এই ক্যান্ডি চকলেট কিনা? এই রোগ সংক্রামক কিনা? এই গ্রাহক এই পণ্যটি কিনবে কিনা?\n", "\n", "এই পাঠে আপনি শিখবেন:\n", "\n", "- লজিস্টিক রিগ্রেশনের কৌশলসমূহ\n", "\n", "✅ এই [Learn module](https://learn.microsoft.com/training/modules/introduction-classification-models/?WT.mc_id=academic-77952-leestott) এ এই ধরনের রিগ্রেশনের সাথে কাজ করার দক্ষতা আরও গভীর করুন।\n", "\n", "## পূর্বশর্ত\n", "\n", "কুমড়ার ডেটা নিয়ে কাজ করার পর, আমরা এখন এটি সম্পর্কে যথেষ্ট পরিচিত হয়েছি যাতে বুঝতে পারি যে একটি বাইনারি ক্যাটাগরি রয়েছে যার সাথে আমরা কাজ করতে পারি: `Color`।\n", "\n", "চলুন একটি লজিস্টিক রিগ্রেশন মডেল তৈরি করি যা পূর্বাভাস দিতে পারে, কিছু ভেরিয়েবল দেওয়া হলে, *একটি নির্দিষ্ট কুমড়ার রঙ কী হতে পারে* (কমলা 🎃 বা সাদা 👻)।\n", "\n", "> আমরা কেন রিগ্রেশনের পাঠে বাইনারি ক্লাসিফিকেশন নিয়ে আলোচনা করছি? শুধুমাত্র ভাষাগত সুবিধার জন্য, কারণ লজিস্টিক রিগ্রেশন [আসলে একটি ক্লাসিফিকেশন পদ্ধতি](https://scikit-learn.org/stable/modules/linear_model.html#logistic-regression), যদিও এটি লিনিয়ার-ভিত্তিক। ডেটা ক্লাসিফাই করার অন্যান্য পদ্ধতি সম্পর্কে পরবর্তী পাঠে জানুন।\n", "\n", "এই পাঠের জন্য, আমাদের নিম্নলিখিত প্যাকেজগুলোর প্রয়োজন হবে:\n", "\n", "- `tidyverse`: [tidyverse](https://www.tidyverse.org/) হলো একটি [R প্যাকেজের সংগ্রহ](https://www.tidyverse.org/packages) যা ডেটা সায়েন্সকে দ্রুত, সহজ এবং আরও মজাদার করে তোলে!\n", "\n", "- `tidymodels`: [tidymodels](https://www.tidymodels.org/) ফ্রেমওয়ার্ক হলো মডেলিং এবং মেশিন লার্নিংয়ের জন্য একটি [প্যাকেজের সংগ্রহ](https://www.tidymodels.org/packages/)।\n", "\n", "- `janitor`: [janitor প্যাকেজ](https://github.com/sfirke/janitor) ডেটা পরীক্ষা এবং পরিষ্কার করার জন্য সহজ সরঞ্জাম সরবরাহ করে।\n", "\n", "- `ggbeeswarm`: [ggbeeswarm প্যাকেজ](https://github.com/eclarke/ggbeeswarm) ggplot2 ব্যবহার করে beeswarm-স্টাইল প্লট তৈরি করার পদ্ধতি সরবরাহ করে।\n", "\n", "আপনি এগুলো ইনস্টল করতে পারেন:\n", "\n", "`install.packages(c(\"tidyverse\", \"tidymodels\", \"janitor\", \"ggbeeswarm\"))`\n", "\n", "অথবা, নিচের স্ক্রিপ্টটি পরীক্ষা করে দেখবে যে আপনার এই মডিউল সম্পন্ন করার জন্য প্রয়োজনীয় প্যাকেজগুলো আছে কিনা এবং যদি না থাকে তবে সেগুলো ইনস্টল করবে।\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "vscode": { "languageId": "r" } }, "outputs": [], "source": [ "suppressWarnings(if (!require(\"pacman\"))install.packages(\"pacman\"))\n", "\n", "pacman::p_load(tidyverse, tidymodels, janitor, ggbeeswarm)\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## **প্রশ্নটি সংজ্ঞায়িত করুন**\n", "\n", "আমাদের উদ্দেশ্যে, আমরা এটিকে একটি বাইনারি আকারে প্রকাশ করব: 'সাদা' বা 'সাদা নয়'। আমাদের ডেটাসেটে একটি 'ডোরা কাটা' বিভাগও রয়েছে, তবে এর উদাহরণ খুব কম, তাই আমরা এটি ব্যবহার করব না। যাই হোক, এটি ডেটাসেট থেকে null মান সরানোর পর অদৃশ্য হয়ে যায়।\n", "\n", "> 🎃 মজার তথ্য, আমরা কখনও কখনও সাদা কুমড়াকে 'ভূত' কুমড়া বলে থাকি। এগুলো খোদাই করা খুব সহজ নয়, তাই এগুলো কম জনপ্রিয়, তবে দেখতে বেশ আকর্ষণীয়! সুতরাং আমরা আমাদের প্রশ্নটি এভাবে পুনর্গঠন করতে পারি: 'ভূত' বা 'ভূত নয়'। 👻\n", "\n", "## **লজিস্টিক রিগ্রেশন সম্পর্কে**\n", "\n", "লজিস্টিক রিগ্রেশন কিছু গুরুত্বপূর্ণ উপায়ে পূর্বে শেখা লিনিয়ার রিগ্রেশন থেকে আলাদা।\n", "\n", "#### **বাইনারি শ্রেণীবিভাগ**\n", "\n", "লজিস্টিক রিগ্রেশন লিনিয়ার রিগ্রেশনের মতো একই বৈশিষ্ট্য প্রদান করে না। প্রথমটি একটি `বাইনারি বিভাগ` (\"কমলা বা কমলা নয়\") সম্পর্কে পূর্বাভাস দেয়, যেখানে দ্বিতীয়টি `ধারাবাহিক মান` পূর্বাভাস দিতে সক্ষম, যেমন কুমড়ার উৎপত্তি এবং ফসল তোলার সময় দেওয়া হলে, *এর দাম কতটা বাড়বে*।\n", "\n", "![দাসানি মাদিপালির ইনফোগ্রাফিক](../../../../../../translated_images/pumpkin-classifier.562771f104ad5436b87d1c67bca02a42a17841133556559325c0a0e348e5b774.bn.png)\n", "\n", "### অন্যান্য শ্রেণীবিভাগ\n", "\n", "লজিস্টিক রিগ্রেশনের অন্যান্য ধরন রয়েছে, যেমন মাল্টিনোমিয়াল এবং অর্ডিনাল:\n", "\n", "- **মাল্টিনোমিয়াল**, যেখানে একাধিক বিভাগ থাকে - \"কমলা, সাদা এবং ডোরা কাটা\"।\n", "\n", "- **অর্ডিনাল**, যেখানে ক্রমানুসারে বিভাগ থাকে, যা আমাদের ফলাফলগুলোকে যৌক্তিকভাবে সাজাতে সাহায্য করে, যেমন আমাদের কুমড়াগুলো যা একটি নির্দিষ্ট সংখ্যক আকারে সাজানো থাকে (মিনি, ছোট, মাঝারি, বড়, এক্সএল, ডাবল এক্সএল)।\n", "\n", "![মাল্টিনোমিয়াল বনাম অর্ডিনাল রিগ্রেশন](../../../../../../translated_images/multinomial-vs-ordinal.36701b4850e37d86c9dd49f7bef93a2f94dbdb8fe03443eb68f0542f97f28f29.bn.png)\n", "\n", "#### **ভেরিয়েবলগুলোর মধ্যে সম্পর্ক থাকা জরুরি নয়**\n", "\n", "আপনি কি মনে করেন লিনিয়ার রিগ্রেশন আরও ভালো কাজ করত যদি ভেরিয়েবলগুলো আরও বেশি সম্পর্কিত হতো? লজিস্টিক রিগ্রেশন ঠিক উল্টো - ভেরিয়েবলগুলোকে একে অপরের সাথে সামঞ্জস্যপূর্ণ হতে হবে না। এটি এই ডেটার জন্য কার্যকর, যেখানে সম্পর্কগুলো তুলনামূলকভাবে দুর্বল।\n", "\n", "#### **আপনার অনেক পরিষ্কার ডেটা দরকার**\n", "\n", "লজিস্টিক রিগ্রেশন আরও সঠিক ফলাফল দেবে যদি আপনি বেশি ডেটা ব্যবহার করেন; আমাদের ছোট ডেটাসেট এই কাজের জন্য আদর্শ নয়, তাই এটি মনে রাখুন।\n", "\n", "✅ এমন ডেটার ধরন সম্পর্কে চিন্তা করুন যা লজিস্টিক রিগ্রেশনের জন্য উপযুক্ত হতে পারে।\n", "\n", "## অনুশীলন - ডেটা পরিষ্কার করুন\n", "\n", "প্রথমে, ডেটা একটু পরিষ্কার করুন, null মানগুলো বাদ দিন এবং শুধুমাত্র কিছু কলাম নির্বাচন করুন:\n", "\n", "1. নিম্নলিখিত কোড যোগ করুন:\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "vscode": { "languageId": "r" } }, "outputs": [], "source": [ "# Load the core tidyverse packages\n", "library(tidyverse)\n", "\n", "# Import the data and clean column names\n", "pumpkins <- read_csv(file = \"https://raw.githubusercontent.com/microsoft/ML-For-Beginners/main/2-Regression/data/US-pumpkins.csv\") %>% \n", " clean_names()\n", "\n", "# Select desired columns\n", "pumpkins_select <- pumpkins %>% \n", " select(c(city_name, package, variety, origin, item_size, color)) \n", "\n", "# Drop rows containing missing values and encode color as factor (category)\n", "pumpkins_select <- pumpkins_select %>% \n", " drop_na() %>% \n", " mutate(color = factor(color))\n", "\n", "# View the first few rows\n", "pumpkins_select %>% \n", " slice_head(n = 5)\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "আপনি সবসময় আপনার নতুন ডেটাফ্রেমটি একবার দেখে নিতে পারেন, নিচের মতো [*glimpse()*](https://pillar.r-lib.org/reference/glimpse.html) ফাংশন ব্যবহার করে:\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "vscode": { "languageId": "r" } }, "outputs": [], "source": [ "pumpkins_select %>% \n", " glimpse()\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "চলুন নিশ্চিত করি যে আমরা আসলে একটি বাইনারি শ্রেণীবিন্যাস সমস্যা করতে যাচ্ছি:\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "vscode": { "languageId": "r" } }, "outputs": [], "source": [ "# Subset distinct observations in outcome column\n", "pumpkins_select %>% \n", " distinct(color)\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### ভিজুয়ালাইজেশন - শ্রেণীবদ্ধ প্লট\n", "এখন পর্যন্ত আপনি আবারও কুমড়ার ডেটা লোড করেছেন এবং এটি পরিষ্কার করেছেন যাতে কিছু ভেরিয়েবলসহ একটি ডেটাসেট সংরক্ষণ করা যায়, যার মধ্যে রঙ অন্তর্ভুক্ত রয়েছে। চলুন নোটবুকে ggplot লাইব্রেরি ব্যবহার করে ডেটাফ্রেমটি ভিজুয়ালাইজ করি।\n", "\n", "ggplot লাইব্রেরি আপনার ডেটা ভিজুয়ালাইজ করার জন্য কিছু চমৎকার উপায় প্রদান করে। উদাহরণস্বরূপ, আপনি একটি শ্রেণীবদ্ধ প্লটে প্রতিটি Variety এবং Color এর জন্য ডেটার বিতরণ তুলনা করতে পারেন।\n", "\n", "1. geombar ফাংশন ব্যবহার করে এমন একটি প্লট তৈরি করুন, আমাদের কুমড়ার ডেটা ব্যবহার করে, এবং প্রতিটি কুমড়ার ক্যাটাগরির (কমলা বা সাদা) জন্য একটি রঙের ম্যাপিং নির্দিষ্ট করুন:\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "vscode": { "languageId": "python" } }, "outputs": [], "source": [ "# Specify colors for each value of the hue variable\n", "palette <- c(ORANGE = \"orange\", WHITE = \"wheat\")\n", "\n", "# Create the bar plot\n", "ggplot(pumpkins_select, aes(y = variety, fill = color)) +\n", " geom_bar(position = \"dodge\") +\n", " scale_fill_manual(values = palette) +\n", " labs(y = \"Variety\", fill = \"Color\") +\n", " theme_minimal()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "ডেটা পর্যবেক্ষণ করে, আপনি দেখতে পারেন কীভাবে রঙের ডেটা বৈচিত্র্যের সাথে সম্পর্কিত।\n", "\n", "✅ এই শ্রেণীবদ্ধ প্লটটি দেখে, আপনি কী কী আকর্ষণীয় অনুসন্ধান কল্পনা করতে পারেন?\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### ডেটা প্রি-প্রসেসিং: ফিচার এনকোডিং\n", "\n", "আমাদের পাম্পকিনস ডেটাসেটে সমস্ত কলামের জন্য স্ট্রিং মান রয়েছে। মানুষের জন্য ক্যাটেগরিকাল ডেটা নিয়ে কাজ করা সহজ হলেও মেশিনের জন্য তা নয়। মেশিন লার্নিং অ্যালগরিদমগুলো সংখ্যার সাথে ভালো কাজ করে। এজন্য এনকোডিং ডেটা প্রি-প্রসেসিং ধাপের একটি অত্যন্ত গুরুত্বপূর্ণ অংশ, কারণ এটি আমাদের ক্যাটেগরিকাল ডেটাকে সংখ্যায় রূপান্তর করতে সাহায্য করে, কোনো তথ্য হারানো ছাড়াই। ভালো এনকোডিং একটি ভালো মডেল তৈরিতে সহায়ক হয়।\n", "\n", "ফিচার এনকোডিংয়ের জন্য দুটি প্রধান ধরনের এনকোডার রয়েছে:\n", "\n", "1. **অর্ডিনাল এনকোডার**: এটি অর্ডিনাল ভ্যারিয়েবলগুলোর জন্য উপযুক্ত, যা ক্যাটেগরিকাল ভ্যারিয়েবল যেখানে ডেটা একটি যৌক্তিক ক্রম অনুসরণ করে, যেমন আমাদের ডেটাসেটের `item_size` কলাম। এটি একটি ম্যাপিং তৈরি করে যেখানে প্রতিটি ক্যাটেগরি একটি সংখ্যার মাধ্যমে উপস্থাপিত হয়, যা কলামে ক্যাটেগরির ক্রম নির্দেশ করে।\n", "\n", "2. **ক্যাটেগরিকাল এনকোডার**: এটি নোমিনাল ভ্যারিয়েবলগুলোর জন্য উপযুক্ত, যা ক্যাটেগরিকাল ভ্যারিয়েবল যেখানে ডেটা কোনো যৌক্তিক ক্রম অনুসরণ করে না, যেমন আমাদের ডেটাসেটে `item_size` ব্যতীত অন্যান্য ফিচার। এটি একটি ওয়ান-হট এনকোডিং, যার অর্থ প্রতিটি ক্যাটেগরি একটি বাইনারি কলামের মাধ্যমে উপস্থাপিত হয়: এনকোড করা ভ্যারিয়েবলটি 1 হয় যদি পাম্পকিন সেই ভ্যারাইটির অন্তর্ভুক্ত হয় এবং অন্যথায় 0 হয়।\n", "\n", "**Tidymodels** আরেকটি চমৎকার প্যাকেজ সরবরাহ করে: [recipes](https://recipes.tidymodels.org/) - ডেটা প্রি-প্রসেসিংয়ের জন্য একটি প্যাকেজ। আমরা একটি `recipe` সংজ্ঞায়িত করব যা নির্ধারণ করবে যে সমস্ত প্রেডিক্টর কলামগুলোকে একটি সেট ইন্টিজারে এনকোড করা উচিত, `prep` ব্যবহার করে প্রয়োজনীয় পরিমাণ এবং পরিসংখ্যান অনুমান করব যা কোনো অপারেশনের জন্য প্রয়োজন এবং শেষে `bake` ব্যবহার করে নতুন ডেটায় সেই গণনাগুলো প্রয়োগ করব।\n", "\n", "> সাধারণত, **recipes** সাধারণত মডেলিংয়ের জন্য একটি প্রি-প্রসেসর হিসেবে ব্যবহৃত হয় যেখানে এটি নির্ধারণ করে যে একটি ডেটাসেটের উপর মডেলিংয়ের জন্য প্রস্তুত করতে কী ধাপগুলো প্রয়োগ করা উচিত। এই ক্ষেত্রে, এটি **অত্যন্ত সুপারিশ করা হয়** যে আপনি `workflow()` ব্যবহার করুন, `prep` এবং `bake` ব্যবহার করে ম্যানুয়ালি একটি রেসিপি অনুমান করার পরিবর্তে। আমরা এটি কিছুক্ষণের মধ্যেই দেখব।\n", ">\n", "> তবে আপাতত, আমরা **recipes + prep + bake** ব্যবহার করছি একটি ডেটাসেটের উপর কী ধাপগুলো প্রয়োগ করা উচিত তা নির্ধারণ করতে যাতে এটি ডেটা বিশ্লেষণের জন্য প্রস্তুত হয় এবং প্রয়োগ করা ধাপগুলো সহ প্রি-প্রসেসড ডেটা বের করতে।\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "vscode": { "languageId": "r" } }, "outputs": [], "source": [ "# Preprocess and extract data to allow some data analysis\n", "baked_pumpkins <- recipe(color ~ ., data = pumpkins_select) %>%\n", " # Define ordering for item_size column\n", " step_mutate(item_size = ordered(item_size, levels = c('sml', 'med', 'med-lge', 'lge', 'xlge', 'jbo', 'exjbo'))) %>%\n", " # Convert factors to numbers using the order defined above (Ordinal encoding)\n", " step_integer(item_size, zero_based = F) %>%\n", " # Encode all other predictors using one hot encoding\n", " step_dummy(all_nominal(), -all_outcomes(), one_hot = TRUE) %>%\n", " prep(data = pumpkin_select) %>%\n", " bake(new_data = NULL)\n", "\n", "# Display the first few rows of preprocessed data\n", "baked_pumpkins %>% \n", " slice_head(n = 5)\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "✅ আইটেম সাইজ কলামের জন্য অর্ডিনাল এনকোডার ব্যবহারের সুবিধাগুলো কী?\n", "\n", "### ভেরিয়েবলগুলোর মধ্যে সম্পর্ক বিশ্লেষণ\n", "\n", "এখন যেহেতু আমরা আমাদের ডেটা প্রি-প্রসেস করেছি, আমরা ফিচার এবং লেবেলের মধ্যে সম্পর্ক বিশ্লেষণ করতে পারি, যাতে বোঝা যায় মডেলটি ফিচারগুলো থেকে লেবেল কতটা ভালোভাবে পূর্বানুমান করতে পারবে। এই ধরনের বিশ্লেষণ করার সবচেয়ে ভালো উপায় হলো ডেটা প্লট করা। \n", "আমরা আবারও ggplot-এর geom_boxplot_ ফাংশন ব্যবহার করব, যাতে একটি ক্যাটেগরিক্যাল প্লটে আইটেম সাইজ, ভ্যারাইটি এবং কালারের মধ্যে সম্পর্কগুলো ভিজুয়ালাইজ করা যায়। ডেটা আরও ভালোভাবে প্লট করার জন্য আমরা এনকোড করা আইটেম সাইজ কলাম এবং আনএনকোড করা ভ্যারাইটি কলাম ব্যবহার করব।\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "vscode": { "languageId": "r" } }, "outputs": [], "source": [ "# Define the color palette\n", "palette <- c(ORANGE = \"orange\", WHITE = \"wheat\")\n", "\n", "# We need the encoded Item Size column to use it as the x-axis values in the plot\n", "pumpkins_select_plot<-pumpkins_select\n", "pumpkins_select_plot$item_size <- baked_pumpkins$item_size\n", "\n", "# Create the grouped box plot\n", "ggplot(pumpkins_select_plot, aes(x = `item_size`, y = color, fill = color)) +\n", " geom_boxplot() +\n", " facet_grid(variety ~ ., scales = \"free_x\") +\n", " scale_fill_manual(values = palette) +\n", " labs(x = \"Item Size\", y = \"\") +\n", " theme_minimal() +\n", " theme(strip.text = element_text(size = 12)) +\n", " theme(axis.text.x = element_text(size = 10)) +\n", " theme(axis.title.x = element_text(size = 12)) +\n", " theme(axis.title.y = element_blank()) +\n", " theme(legend.position = \"bottom\") +\n", " guides(fill = guide_legend(title = \"Color\")) +\n", " theme(panel.spacing = unit(0.5, \"lines\"))+\n", " theme(strip.text.y = element_text(size = 4, hjust = 0)) \n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### একটি স্বার্ম প্লট ব্যবহার করুন\n", "\n", "যেহেতু Color একটি দ্বৈত ক্যাটাগরি (সাদা বা নয়), এটি ভিজুয়ালাইজেশনের জন্য 'একটি [বিশেষ পদ্ধতির](https://github.com/rstudio/cheatsheets/blob/main/data-visualization.pdf) প্রয়োজন'।\n", "\n", "Color-এর বণ্টন item_size-এর সাথে সম্পর্কিতভাবে দেখানোর জন্য একটি `swarm plot` চেষ্টা করুন।\n", "\n", "আমরা [ggbeeswarm প্যাকেজ](https://github.com/eclarke/ggbeeswarm) ব্যবহার করব, যা ggplot2 ব্যবহার করে beeswarm-স্টাইলের প্লট তৈরি করার পদ্ধতি প্রদান করে। Beeswarm প্লট এমন একটি পদ্ধতি যেখানে সাধারণত পয়েন্টগুলো একটির উপর আরেকটি পড়ে যেত, সেগুলোকে পাশাপাশি ফেলার জন্য ব্যবহার করা হয়।\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "vscode": { "languageId": "r" } }, "outputs": [], "source": [ "# Create beeswarm plots of color and item_size\n", "baked_pumpkins %>% \n", " mutate(color = factor(color)) %>% \n", " ggplot(mapping = aes(x = color, y = item_size, color = color)) +\n", " geom_quasirandom() +\n", " scale_color_brewer(palette = \"Dark2\", direction = -1) +\n", " theme(legend.position = \"none\")\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "এখন যেহেতু আমরা রঙের দ্বৈত শ্রেণীবিভাগ এবং আকারের বৃহত্তর গোষ্ঠীর মধ্যে সম্পর্ক সম্পর্কে ধারণা পেয়েছি, চলুন একটি কুমড়ার সম্ভাব্য রঙ নির্ধারণের জন্য লজিস্টিক রিগ্রেশন অন্বেষণ করি।\n", "\n", "## আপনার মডেল তৈরি করুন\n", "\n", "আপনার শ্রেণীবিভাজন মডেলে ব্যবহারের জন্য ভেরিয়েবল নির্বাচন করুন এবং ডেটাকে প্রশিক্ষণ ও পরীক্ষার সেটে ভাগ করুন। [rsample](https://rsample.tidymodels.org/), Tidymodels-এর একটি প্যাকেজ, দক্ষ ডেটা বিভাজন এবং পুনঃনমুনার জন্য অবকাঠামো প্রদান করে:\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "vscode": { "languageId": "r" } }, "outputs": [], "source": [ "# Split data into 80% for training and 20% for testing\n", "set.seed(2056)\n", "pumpkins_split <- pumpkins_select %>% \n", " initial_split(prop = 0.8)\n", "\n", "# Extract the data in each split\n", "pumpkins_train <- training(pumpkins_split)\n", "pumpkins_test <- testing(pumpkins_split)\n", "\n", "# Print out the first 5 rows of the training set\n", "pumpkins_train %>% \n", " slice_head(n = 5)\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "🙌 আমরা এখন একটি মডেল প্রশিক্ষণ করার জন্য প্রস্তুত, যেখানে প্রশিক্ষণের বৈশিষ্ট্যগুলো প্রশিক্ষণের লেবেল (রঙ) এর সাথে মানানসই করা হবে।\n", "\n", "আমরা একটি রেসিপি তৈরি করার মাধ্যমে শুরু করব, যা আমাদের ডেটার উপর প্রি-প্রসেসিং ধাপগুলো নির্ধারণ করবে, যাতে এটি মডেলিংয়ের জন্য প্রস্তুত হয়। উদাহরণস্বরূপ: ক্যাটেগরিকাল ভেরিয়েবলগুলোকে একটি পূর্ণসংখ্যার সেটে এনকোড করা। ঠিক যেমন `baked_pumpkins`, আমরা একটি `pumpkins_recipe` তৈরি করব, কিন্তু এটিকে `prep` এবং `bake` করব না, কারণ এটি একটি ওয়ার্কফ্লোতে অন্তর্ভুক্ত করা হবে, যা আপনি কয়েকটি ধাপ পরে দেখতে পাবেন।\n", "\n", "Tidymodels-এ লজিস্টিক রিগ্রেশন মডেল নির্ধারণ করার বেশ কিছু উপায় রয়েছে। দেখুন `?logistic_reg()`। আপাতত, আমরা ডিফল্ট `stats::glm()` ইঞ্জিন ব্যবহার করে একটি লজিস্টিক রিগ্রেশন মডেল নির্ধারণ করব।\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "vscode": { "languageId": "r" } }, "outputs": [], "source": [ "# Create a recipe that specifies preprocessing steps for modelling\n", "pumpkins_recipe <- recipe(color ~ ., data = pumpkins_train) %>% \n", " step_mutate(item_size = ordered(item_size, levels = c('sml', 'med', 'med-lge', 'lge', 'xlge', 'jbo', 'exjbo'))) %>%\n", " step_integer(item_size, zero_based = F) %>% \n", " step_dummy(all_nominal(), -all_outcomes(), one_hot = TRUE)\n", "\n", "# Create a logistic model specification\n", "log_reg <- logistic_reg() %>% \n", " set_engine(\"glm\") %>% \n", " set_mode(\"classification\")\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "এখন যেহেতু আমাদের কাছে একটি রেসিপি এবং একটি মডেল স্পেসিফিকেশন রয়েছে, আমাদের সেগুলোকে একত্রিত করার একটি উপায় খুঁজে বের করতে হবে এমন একটি অবজেক্টে যা প্রথমে ডেটা প্রিপ্রসেস করবে (পর্দার আড়ালে prep+bake), প্রিপ্রসেসড ডেটার উপর মডেল ফিট করবে এবং সম্ভাব্য পোস্ট-প্রসেসিং কার্যক্রমের জন্যও সুযোগ দেবে।\n", "\n", "Tidymodels-এ, এই সুবিধাজনক অবজেক্টটিকে [`workflow`](https://workflows.tidymodels.org/) বলা হয় এবং এটি আপনার মডেলিং উপাদানগুলোকে সহজেই ধরে রাখে।\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "vscode": { "languageId": "r" } }, "outputs": [], "source": [ "# Bundle modelling components in a workflow\n", "log_reg_wf <- workflow() %>% \n", " add_recipe(pumpkins_recipe) %>% \n", " add_model(log_reg)\n", "\n", "# Print out the workflow\n", "log_reg_wf\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "একটি ওয়ার্কফ্লো *নির্ধারণ* করার পর, একটি মডেল [`fit()`](https://tidymodels.github.io/parsnip/reference/fit.html) ফাংশন ব্যবহার করে `প্রশিক্ষণ` দেওয়া যেতে পারে। ওয়ার্কফ্লোটি একটি রেসিপি অনুমান করবে এবং প্রশিক্ষণের আগে ডেটা প্রিপ্রসেস করবে, তাই আমাদের ম্যানুয়ালি prep এবং bake ব্যবহার করে এটি করতে হবে না।\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "vscode": { "languageId": "r" } }, "outputs": [], "source": [ "# Train the model\n", "wf_fit <- log_reg_wf %>% \n", " fit(data = pumpkins_train)\n", "\n", "# Print the trained workflow\n", "wf_fit\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "মডেল প্রশিক্ষণের সময় শেখা গুণাঙ্কগুলো প্রদর্শন করে।\n", "\n", "এখন আমরা প্রশিক্ষণ ডেটা ব্যবহার করে মডেলটি প্রশিক্ষণ দিয়েছি, আমরা [parsnip::predict()](https://parsnip.tidymodels.org/reference/predict.model_fit.html) ব্যবহার করে পরীক্ষার ডেটার উপর পূর্বাভাস করতে পারি। চলুন শুরু করি মডেলটি ব্যবহার করে আমাদের পরীক্ষার সেটের জন্য লেবেল এবং প্রতিটি লেবেলের সম্ভাবনা পূর্বাভাস করা। যখন সম্ভাবনা ০.৫ এর বেশি হয়, পূর্বাভাসকৃত শ্রেণি হবে `WHITE`, অন্যথায় `ORANGE`।\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "vscode": { "languageId": "r" } }, "outputs": [], "source": [ "# Make predictions for color and corresponding probabilities\n", "results <- pumpkins_test %>% select(color) %>% \n", " bind_cols(wf_fit %>% \n", " predict(new_data = pumpkins_test)) %>%\n", " bind_cols(wf_fit %>%\n", " predict(new_data = pumpkins_test, type = \"prob\"))\n", "\n", "# Compare predictions\n", "results %>% \n", " slice_head(n = 10)\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "খুব ভালো! এটি লজিস্টিক রিগ্রেশন কীভাবে কাজ করে তার সম্পর্কে আরও কিছু ধারণা প্রদান করে।\n", "\n", "### বিভ্রান্তি ম্যাট্রিক্সের মাধ্যমে আরও ভালো বোঝাপড়া\n", "\n", "প্রত্যেকটি পূর্বাভাসকে তার সংশ্লিষ্ট \"গ্রাউন্ড ট্রুথ\" প্রকৃত মানের সাথে তুলনা করা মডেলের পূর্বাভাসের কার্যকারিতা নির্ধারণ করার জন্য খুব কার্যকর পদ্ধতি নয়। সৌভাগ্যক্রমে, Tidymodels-এর কাছে আরও কিছু কৌশল রয়েছে: [`yardstick`](https://yardstick.tidymodels.org/) - একটি প্যাকেজ যা পারফরম্যান্স মেট্রিক ব্যবহার করে মডেলের কার্যকারিতা পরিমাপ করতে ব্যবহৃত হয়।\n", "\n", "শ্রেণীবিন্যাস সমস্যার সাথে সম্পর্কিত একটি পারফরম্যান্স মেট্রিক হলো [`confusion matrix`](https://wikipedia.org/wiki/Confusion_matrix)। একটি বিভ্রান্তি ম্যাট্রিক্স বর্ণনা করে একটি শ্রেণীবিন্যাস মডেল কতটা ভালো কাজ করছে। বিভ্রান্তি ম্যাট্রিক্স দেখায় প্রতিটি শ্রেণীর কতগুলো উদাহরণ সঠিকভাবে মডেল দ্বারা শ্রেণীবিন্যাস করা হয়েছে। আমাদের ক্ষেত্রে, এটি দেখাবে কতগুলো কমলা রঙের কুমড়া কমলা হিসেবে শ্রেণীবিন্যাস করা হয়েছে এবং কতগুলো সাদা কুমড়া সাদা হিসেবে শ্রেণীবিন্যাস করা হয়েছে; বিভ্রান্তি ম্যাট্রিক্স এটিও দেখাবে কতগুলো **ভুল** শ্রেণীতে শ্রেণীবিন্যাস করা হয়েছে।\n", "\n", "[**`conf_mat()`**](https://tidymodels.github.io/yardstick/reference/conf_mat.html) ফাংশনটি yardstick থেকে পর্যবেক্ষণ এবং পূর্বাভাসিত শ্রেণীগুলোর এই ক্রস-ট্যাবুলেশন গণনা করে।\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "vscode": { "languageId": "r" } }, "outputs": [], "source": [ "# Confusion matrix for prediction results\n", "conf_mat(data = results, truth = color, estimate = .pred_class)\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "আসুন কনফিউশন ম্যাট্রিক্সটি বিশ্লেষণ করি। আমাদের মডেলকে কুমড়োগুলোকে দুটি বাইনারি ক্যাটাগরিতে শ্রেণীবদ্ধ করতে বলা হয়েছে: ক্যাটাগরি `সাদা` এবং ক্যাটাগরি `সাদা নয়`।\n", "\n", "- যদি আপনার মডেল একটি কুমড়োকে সাদা হিসেবে পূর্বানুমান করে এবং বাস্তবে সেটি 'সাদা' ক্যাটাগরির অন্তর্ভুক্ত হয়, আমরা এটিকে বলি `সত্য পজিটিভ`, যা উপরের বাম দিকের সংখ্যায় দেখানো হয়।\n", "\n", "- যদি আপনার মডেল একটি কুমড়োকে সাদা নয় হিসেবে পূর্বানুমান করে এবং বাস্তবে সেটি 'সাদা' ক্যাটাগরির অন্তর্ভুক্ত হয়, আমরা এটিকে বলি `মিথ্যা নেগেটিভ`, যা নিচের বাম দিকের সংখ্যায় দেখানো হয়।\n", "\n", "- যদি আপনার মডেল একটি কুমড়োকে সাদা হিসেবে পূর্বানুমান করে এবং বাস্তবে সেটি 'সাদা নয়' ক্যাটাগরির অন্তর্ভুক্ত হয়, আমরা এটিকে বলি `মিথ্যা পজিটিভ`, যা উপরের ডান দিকের সংখ্যায় দেখানো হয়।\n", "\n", "- যদি আপনার মডেল একটি কুমড়োকে সাদা নয় হিসেবে পূর্বানুমান করে এবং বাস্তবে সেটি 'সাদা নয়' ক্যাটাগরির অন্তর্ভুক্ত হয়, আমরা এটিকে বলি `সত্য নেগেটিভ`, যা নিচের ডান দিকের সংখ্যায় দেখানো হয়।\n", "\n", "| সত্য |\n", "|:-----:|\n", "\n", "| | | |\n", "|---------------|--------|-------|\n", "| **পূর্বানুমান** | সাদা | কমলা |\n", "| সাদা | TP | FP |\n", "| কমলা | FN | TN |\n", "\n", "আপনি হয়তো অনুমান করতে পেরেছেন যে, সত্য পজিটিভ এবং সত্য নেগেটিভের সংখ্যা যত বেশি হবে এবং মিথ্যা পজিটিভ ও মিথ্যা নেগেটিভের সংখ্যা যত কম হবে, মডেলের কার্যকারিতা তত ভালো হবে।\n", "\n", "কনফিউশন ম্যাট্রিক্সটি গুরুত্বপূর্ণ কারণ এটি অন্যান্য মেট্রিক্সের জন্ম দেয় যা আমাদের একটি শ্রেণীবিভাজন মডেলের কার্যকারিতা আরও ভালোভাবে মূল্যায়ন করতে সাহায্য করে। আসুন সেগুলো নিয়ে আলোচনা করি:\n", "\n", "🎓 প্রিসিশন: `TP/(TP + FP)` যা পূর্বানুমান করা পজিটিভগুলোর মধ্যে আসল পজিটিভের অনুপাত হিসেবে সংজ্ঞায়িত। এটিকে [পজিটিভ প্রেডিক্টিভ ভ্যালু](https://en.wikipedia.org/wiki/Positive_predictive_value \"Positive predictive value\")-ও বলা হয়।\n", "\n", "🎓 রিকল: `TP/(TP + FN)` যা আসল পজিটিভ নমুনাগুলোর মধ্যে পজিটিভ ফলাফলের অনুপাত হিসেবে সংজ্ঞায়িত। এটিকে `সংবেদনশীলতা` নামেও পরিচিত।\n", "\n", "🎓 স্পেসিফিসিটি: `TN/(TN + FP)` যা আসল নেগেটিভ নমুনাগুলোর মধ্যে নেগেটিভ ফলাফলের অনুপাত হিসেবে সংজ্ঞায়িত।\n", "\n", "🎓 একিউরেসি: `TP + TN/(TP + TN + FP + FN)` একটি নমুনার জন্য সঠিকভাবে পূর্বানুমান করা লেবেলের শতাংশ।\n", "\n", "🎓 এফ মেজার: প্রিসিশন এবং রিকলের একটি ভারসাম্যপূর্ণ গড়, যেখানে সর্বোচ্চ মান ১ এবং সর্বনিম্ন মান ০।\n", "\n", "আসুন এই মেট্রিক্সগুলো গণনা করি!\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "vscode": { "languageId": "r" } }, "outputs": [], "source": [ "# Combine metric functions and calculate them all at once\n", "eval_metrics <- metric_set(ppv, recall, spec, f_meas, accuracy)\n", "eval_metrics(data = results, truth = color, estimate = .pred_class)\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## এই মডেলের ROC কার্ভ দেখুন\n", "\n", "চলুন আরেকটি ভিজুয়ালাইজেশন করি যাতে তথাকথিত [`ROC কার্ভ`](https://en.wikipedia.org/wiki/Receiver_operating_characteristic) দেখা যায়:\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "vscode": { "languageId": "r" } }, "outputs": [], "source": [ "# Make a roc_curve\n", "results %>% \n", " roc_curve(color, .pred_ORANGE) %>% \n", " autoplot()\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "ROC কার্ভ সাধারণত একটি শ্রেণীবিন্যাসকারীর আউটপুট বিশ্লেষণ করতে ব্যবহৃত হয়, যেখানে সত্য পজিটিভ বনাম মিথ্যা পজিটিভের তুলনা করা হয়। ROC কার্ভে সাধারণত Y অক্ষে `True Positive Rate`/সংবেদনশীলতা এবং X অক্ষে `False Positive Rate`/1-নির্দিষ্টতা দেখানো হয়। সুতরাং, কার্ভের খাড়া হওয়া এবং মধ্যরেখা ও কার্ভের মধ্যবর্তী ফাঁক গুরুত্বপূর্ণ: আপনি এমন একটি কার্ভ চান যা দ্রুত উপরের দিকে উঠে এবং রেখার ওপরে চলে যায়। আমাদের ক্ষেত্রে, শুরুতে কিছু মিথ্যা পজিটিভ থাকে, তারপর রেখাটি সঠিকভাবে উপরের দিকে উঠে যায়।\n", "\n", "শেষে, চলুন `yardstick::roc_auc()` ব্যবহার করে প্রকৃত Area Under the Curve (AUC) গণনা করি। AUC-এর একটি ব্যাখ্যা হতে পারে এটি: মডেলটি একটি এলোমেলো পজিটিভ উদাহরণকে একটি এলোমেলো নেগেটিভ উদাহরণের চেয়ে বেশি র‍্যাঙ্ক করার সম্ভাবনা।\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "vscode": { "languageId": "r" } }, "outputs": [], "source": [ "# Calculate area under curve\n", "results %>% \n", " roc_auc(color, .pred_ORANGE)\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "ফলাফল প্রায় `0.975`। যেহেতু AUC-এর মান 0 থেকে 1 এর মধ্যে থাকে, আপনি একটি বড় স্কোর পেতে চান, কারণ একটি মডেল যা তার পূর্বাভাসে 100% সঠিক, তার AUC হবে 1; এই ক্ষেত্রে, মডেলটি *খুব ভালো*।\n", "\n", "ভবিষ্যতের শ্রেণীবিভাগের পাঠে, আপনি শিখবেন কীভাবে আপনার মডেলের স্কোর উন্নত করা যায় (যেমন, এই ক্ষেত্রে ভারসাম্যহীন ডেটার সাথে কাজ করা)।\n", "\n", "## 🚀চ্যালেঞ্জ\n", "\n", "লজিস্টিক রিগ্রেশন সম্পর্কে আরও অনেক কিছু জানার আছে! তবে শেখার সেরা উপায় হল পরীক্ষা-নিরীক্ষা করা। এমন একটি ডেটাসেট খুঁজুন যা এই ধরনের বিশ্লেষণের জন্য উপযুক্ত এবং এর সাথে একটি মডেল তৈরি করুন। আপনি কী শিখলেন? টিপ: [Kaggle](https://www.kaggle.com/search?q=logistic+regression+datasets)-এ আকর্ষণীয় ডেটাসেট খুঁজে দেখুন।\n", "\n", "## পর্যালোচনা ও স্ব-অধ্যয়ন\n", "\n", "[স্ট্যানফোর্ডের এই পেপারের](https://web.stanford.edu/~jurafsky/slp3/5.pdf) প্রথম কয়েকটি পৃষ্ঠা পড়ুন, যেখানে লজিস্টিক রিগ্রেশনের কিছু ব্যবহারিক প্রয়োগ নিয়ে আলোচনা করা হয়েছে। এমন কাজ নিয়ে ভাবুন যেগুলো আমরা এখন পর্যন্ত অধ্যয়ন করা বিভিন্ন রিগ্রেশন পদ্ধতির জন্য উপযুক্ত। কোনটি সবচেয়ে ভালো কাজ করবে?\n" ] }, { "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", "langauge": "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": "feaf125f481a89c468fa115bf2aed580", "translation_date": "2025-08-29T23:00:17+00:00", "source_file": "2-Regression/4-Logistic/solution/R/lesson_4-R.ipynb", "language_code": "bn" } }, "nbformat": 4, "nbformat_minor": 1 }