724 lines
35 KiB
Plaintext
724 lines
35 KiB
Plaintext
{
|
|
"nbformat": 4,
|
|
"nbformat_minor": 2,
|
|
"metadata": {
|
|
"colab": {
|
|
"name": "lesson_10-R.ipynb",
|
|
"provenance": [],
|
|
"collapsed_sections": []
|
|
},
|
|
"kernelspec": {
|
|
"name": "ir",
|
|
"display_name": "R"
|
|
},
|
|
"language_info": {
|
|
"name": "R"
|
|
},
|
|
"coopTranslator": {
|
|
"original_hash": "2621e24705e8100893c9bf84e0fc8aef",
|
|
"translation_date": "2025-09-04T02:50:11+00:00",
|
|
"source_file": "4-Classification/1-Introduction/solution/R/lesson_10-R.ipynb",
|
|
"language_code": "fa"
|
|
}
|
|
},
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"# ساخت یک مدل طبقهبندی: غذاهای خوشمزه آسیایی و هندی\n"
|
|
],
|
|
"metadata": {
|
|
"id": "ItETB4tSFprR"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"## مقدمهای بر طبقهبندی: پاکسازی، آمادهسازی و بصریسازی دادهها\n",
|
|
"\n",
|
|
"در این چهار درس، شما به یکی از اصول اساسی یادگیری ماشین کلاسیک یعنی *طبقهبندی* میپردازید. ما با استفاده از الگوریتمهای مختلف طبقهبندی و یک مجموعه داده درباره غذاهای شگفتانگیز آسیایی و هندی کار خواهیم کرد. امیدوارم گرسنه باشید!\n",
|
|
"\n",
|
|
"<p >\n",
|
|
" <img src=\"../../images/pinch.png\"\n",
|
|
" width=\"600\"/>\n",
|
|
" <figcaption>در این درسها غذاهای آسیایی را جشن بگیرید! تصویر از جن لوپر</figcaption>\n",
|
|
"\n",
|
|
"طبقهبندی نوعی از [یادگیری نظارتشده](https://wikipedia.org/wiki/Supervised_learning) است که شباهت زیادی به تکنیکهای رگرسیون دارد. در طبقهبندی، شما مدلی را آموزش میدهید تا پیشبینی کند که یک آیتم به کدام `دستهبندی` تعلق دارد. اگر یادگیری ماشین به پیشبینی مقادیر یا نامها با استفاده از مجموعه دادهها مربوط باشد، طبقهبندی معمولاً به دو گروه تقسیم میشود: *طبقهبندی دودویی* و *طبقهبندی چندکلاسه*.\n",
|
|
"\n",
|
|
"به یاد داشته باشید:\n",
|
|
"\n",
|
|
"- **رگرسیون خطی** به شما کمک کرد تا روابط بین متغیرها را پیشبینی کنید و پیشبینیهای دقیقی درباره مکان یک نقطه داده جدید نسبت به آن خط انجام دهید. به عنوان مثال، میتوانستید مقادیر عددی مانند *قیمت یک کدو تنبل در سپتامبر در مقابل دسامبر* را پیشبینی کنید.\n",
|
|
"\n",
|
|
"- **رگرسیون لجستیک** به شما کمک کرد تا \"دستهبندیهای دودویی\" را کشف کنید: در این نقطه قیمتی، *آیا این کدو تنبل نارنجی است یا غیرنارنجی*؟\n",
|
|
"\n",
|
|
"طبقهبندی از الگوریتمهای مختلفی برای تعیین برچسب یا کلاس یک نقطه داده استفاده میکند. بیایید با این دادههای مربوط به غذاها کار کنیم تا ببینیم آیا با مشاهده گروهی از مواد اولیه میتوانیم منشأ غذایی آن را تعیین کنیم یا خیر.\n",
|
|
"\n",
|
|
"### [**پیشاز-درس: آزمون کوتاه**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/19/)\n",
|
|
"\n",
|
|
"### **مقدمه**\n",
|
|
"\n",
|
|
"طبقهبندی یکی از فعالیتهای اساسی محققان یادگیری ماشین و دانشمندان داده است. از طبقهبندی ساده یک مقدار دودویی (\"آیا این ایمیل اسپم است یا خیر؟\") تا طبقهبندی و تقسیمبندی پیچیده تصاویر با استفاده از بینایی کامپیوتر، همیشه مفید است که بتوان دادهها را به کلاسها تقسیم کرد و از آنها سوالاتی پرسید.\n",
|
|
"\n",
|
|
"برای بیان این فرآیند به صورت علمیتر، روش طبقهبندی شما مدلی پیشبینیکننده ایجاد میکند که به شما امکان میدهد رابطه بین متغیرهای ورودی و متغیرهای خروجی را ترسیم کنید.\n",
|
|
"\n",
|
|
"<p >\n",
|
|
" <img src=\"../../images/binary-multiclass.png\"\n",
|
|
" width=\"600\"/>\n",
|
|
" <figcaption>مسائل دودویی در مقابل چندکلاسه برای الگوریتمهای طبقهبندی. اینفوگرافیک از جن لوپر</figcaption>\n",
|
|
"\n",
|
|
"پیش از شروع فرآیند پاکسازی دادهها، بصریسازی آنها و آمادهسازی برای وظایف یادگیری ماشین، بیایید کمی درباره روشهای مختلفی که یادگیری ماشین میتواند برای طبقهبندی دادهها استفاده شود، یاد بگیریم.\n",
|
|
"\n",
|
|
"طبقهبندی که از [آمار](https://wikipedia.org/wiki/Statistical_classification) مشتق شده است، در یادگیری ماشین کلاسیک از ویژگیهایی مانند `سیگاری بودن`، `وزن` و `سن` برای تعیین *احتمال ابتلا به بیماری X* استفاده میکند. به عنوان یک تکنیک یادگیری نظارتشده مشابه تمرینات رگرسیون که قبلاً انجام دادید، دادههای شما برچسبگذاری شدهاند و الگوریتمهای یادگیری ماشین از این برچسبها برای طبقهبندی و پیشبینی کلاسها (یا 'ویژگیها') در یک مجموعه داده و اختصاص آنها به یک گروه یا نتیجه استفاده میکنند.\n",
|
|
"\n",
|
|
"✅ لحظهای وقت بگذارید و یک مجموعه داده درباره غذاها را تصور کنید. یک مدل چندکلاسه چه سوالاتی میتواند پاسخ دهد؟ یک مدل دودویی چه سوالاتی میتواند پاسخ دهد؟ اگر بخواهید تعیین کنید که آیا یک غذای خاص احتمالاً از شنبلیله استفاده میکند یا خیر، چه؟ اگر بخواهید ببینید که با داشتن یک کیسه مواد غذایی شامل انیسون ستارهای، کنگر فرنگی، گلکلم و ترب کوهی، میتوانید یک غذای هندی معمولی درست کنید یا خیر، چه؟\n",
|
|
"\n",
|
|
"### **سلام به 'طبقهبند'**\n",
|
|
"\n",
|
|
"سوالی که میخواهیم از این مجموعه داده غذایی بپرسیم در واقع یک سوال **چندکلاسه** است، زیرا ما چندین غذای ملی مختلف برای کار داریم. با داشتن یک دسته مواد اولیه، این دادهها به کدام یک از این کلاسها تعلق خواهند داشت؟\n",
|
|
"\n",
|
|
"Tidymodels چندین الگوریتم مختلف برای طبقهبندی دادهها ارائه میدهد، بسته به نوع مسئلهای که میخواهید حل کنید. در دو درس بعدی، درباره چند مورد از این الگوریتمها یاد خواهید گرفت.\n",
|
|
"\n",
|
|
"#### **پیشنیاز**\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",
|
|
"- `DataExplorer`: بسته [DataExplorer](https://cran.r-project.org/web/packages/DataExplorer/vignettes/dataexplorer-intro.html) برای سادهسازی و خودکارسازی فرآیند EDA و تولید گزارش طراحی شده است.\n",
|
|
"\n",
|
|
"- `themis`: بسته [themis](https://themis.tidymodels.org/) مراحل اضافی برای مقابله با دادههای نامتعادل ارائه میدهد.\n",
|
|
"\n",
|
|
"میتوانید آنها را به این صورت نصب کنید:\n",
|
|
"\n",
|
|
"`install.packages(c(\"tidyverse\", \"tidymodels\", \"DataExplorer\", \"here\"))`\n",
|
|
"\n",
|
|
"به طور جایگزین، اسکریپت زیر بررسی میکند که آیا بستههای مورد نیاز برای تکمیل این ماژول را دارید و در صورت نبود، آنها را برای شما نصب میکند.\n"
|
|
],
|
|
"metadata": {
|
|
"id": "ri5bQxZ-Fz_0"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"suppressWarnings(if (!require(\"pacman\"))install.packages(\"pacman\"))\r\n",
|
|
"\r\n",
|
|
"pacman::p_load(tidyverse, tidymodels, DataExplorer, themis, here)"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "KIPxa4elGAPI"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"ما بعداً این بستههای عالی را بارگذاری کرده و در جلسه فعلی R خود در دسترس قرار خواهیم داد. (این فقط برای توضیح است، `pacman::p_load()` قبلاً این کار را برای شما انجام داده است)\n"
|
|
],
|
|
"metadata": {
|
|
"id": "YkKAxOJvGD4C"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"## تمرین - پاکسازی و متعادلسازی دادهها\n",
|
|
"\n",
|
|
"اولین وظیفهای که قبل از شروع این پروژه باید انجام دهید، پاکسازی و **متعادلسازی** دادهها برای دستیابی به نتایج بهتر است.\n",
|
|
"\n",
|
|
"بیایید با دادهها آشنا شویم! 🕵️\n"
|
|
],
|
|
"metadata": {
|
|
"id": "PFkQDlk0GN5O"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Import data\r\n",
|
|
"df <- read_csv(file = \"https://raw.githubusercontent.com/microsoft/ML-For-Beginners/main/4-Classification/data/cuisines.csv\")\r\n",
|
|
"\r\n",
|
|
"# View the first 5 rows\r\n",
|
|
"df %>% \r\n",
|
|
" slice_head(n = 5)\r\n"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "Qccw7okxGT0S"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"جالب است! به نظر میرسد ستون اول نوعی ستون `id` باشد. بیایید اطلاعات بیشتری درباره دادهها به دست آوریم.\n"
|
|
],
|
|
"metadata": {
|
|
"id": "XrWnlgSrGVmR"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Basic information about the data\r\n",
|
|
"df %>%\r\n",
|
|
" introduce()\r\n",
|
|
"\r\n",
|
|
"# Visualize basic information above\r\n",
|
|
"df %>% \r\n",
|
|
" plot_intro(ggtheme = theme_light())"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "4UcGmxRxGieA"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"از خروجی میتوانیم بلافاصله ببینیم که ما `2448` ردیف و `385` ستون و `0` مقدار گمشده داریم. همچنین یک ستون گسسته به نام *cuisine* داریم.\n",
|
|
"\n",
|
|
"## تمرین - آشنایی با انواع غذاها\n",
|
|
"\n",
|
|
"حالا کار شروع به جذابتر شدن میکند. بیایید توزیع دادهها را بر اساس نوع غذا کشف کنیم.\n"
|
|
],
|
|
"metadata": {
|
|
"id": "AaPubl__GmH5"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Count observations per cuisine\r\n",
|
|
"df %>% \r\n",
|
|
" count(cuisine) %>% \r\n",
|
|
" arrange(n)\r\n",
|
|
"\r\n",
|
|
"# Plot the distribution\r\n",
|
|
"theme_set(theme_light())\r\n",
|
|
"df %>% \r\n",
|
|
" count(cuisine) %>% \r\n",
|
|
" ggplot(mapping = aes(x = n, y = reorder(cuisine, -n))) +\r\n",
|
|
" geom_col(fill = \"midnightblue\", alpha = 0.7) +\r\n",
|
|
" ylab(\"cuisine\")"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "FRsBVy5eGrrv"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"تعداد محدودی از سبکهای آشپزی وجود دارد، اما توزیع دادهها یکنواخت نیست. شما میتوانید این مشکل را حل کنید! قبل از انجام این کار، کمی بیشتر بررسی کنید.\n",
|
|
"\n",
|
|
"حالا بیایید هر سبک آشپزی را به یک tibble جداگانه اختصاص دهیم و ببینیم چه مقدار داده (ردیفها، ستونها) برای هر سبک آشپزی موجود است.\n",
|
|
"\n",
|
|
"> یک [tibble](https://tibble.tidyverse.org/) یک فریم داده مدرن است.\n",
|
|
"\n",
|
|
"<p >\n",
|
|
" <img src=\"../../images/dplyr_filter.jpg\"\n",
|
|
" width=\"600\"/>\n",
|
|
" <figcaption>اثر هنری از @allison_horst</figcaption>\n"
|
|
],
|
|
"metadata": {
|
|
"id": "vVvyDb1kG2in"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Create individual tibble for the cuisines\r\n",
|
|
"thai_df <- df %>% \r\n",
|
|
" filter(cuisine == \"thai\")\r\n",
|
|
"japanese_df <- df %>% \r\n",
|
|
" filter(cuisine == \"japanese\")\r\n",
|
|
"chinese_df <- df %>% \r\n",
|
|
" filter(cuisine == \"chinese\")\r\n",
|
|
"indian_df <- df %>% \r\n",
|
|
" filter(cuisine == \"indian\")\r\n",
|
|
"korean_df <- df %>% \r\n",
|
|
" filter(cuisine == \"korean\")\r\n",
|
|
"\r\n",
|
|
"\r\n",
|
|
"# Find out how much data is available per cuisine\r\n",
|
|
"cat(\" thai df:\", dim(thai_df), \"\\n\",\r\n",
|
|
" \"japanese df:\", dim(japanese_df), \"\\n\",\r\n",
|
|
" \"chinese_df:\", dim(chinese_df), \"\\n\",\r\n",
|
|
" \"indian_df:\", dim(indian_df), \"\\n\",\r\n",
|
|
" \"korean_df:\", dim(korean_df))"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "0TvXUxD3G8Bk"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"## **تمرین - کشف مواد اولیه برتر بر اساس نوع آشپزی با استفاده از dplyr**\n",
|
|
"\n",
|
|
"حالا میتوانید عمیقتر به دادهها نگاه کنید و بفهمید که مواد اولیه معمولی برای هر نوع آشپزی چیست. باید دادههای تکراری که باعث ایجاد سردرگمی بین انواع آشپزی میشوند را پاک کنید، پس بیایید درباره این مشکل یاد بگیریم.\n",
|
|
"\n",
|
|
"یک تابع به نام `create_ingredient()` در R ایجاد کنید که یک دیتافریم مواد اولیه را برگرداند. این تابع با حذف یک ستون غیرمفید شروع میکند و مواد اولیه را بر اساس تعدادشان مرتب میکند.\n",
|
|
"\n",
|
|
"ساختار پایهای یک تابع در R به این صورت است:\n",
|
|
"\n",
|
|
"`myFunction <- function(arglist){`\n",
|
|
"\n",
|
|
"**`...`**\n",
|
|
"\n",
|
|
"**`return`**`(value)`\n",
|
|
"\n",
|
|
"`}`\n",
|
|
"\n",
|
|
"یک معرفی مرتب و ساده از توابع R را میتوانید [اینجا](https://skirmer.github.io/presentations/functions_with_r.html#1) پیدا کنید.\n",
|
|
"\n",
|
|
"بیایید مستقیم وارد کار شویم! ما از [افعال dplyr](https://dplyr.tidyverse.org/) که در درسهای قبلی یاد گرفتهایم استفاده خواهیم کرد. به عنوان یادآوری:\n",
|
|
"\n",
|
|
"- `dplyr::select()`: به شما کمک میکند که انتخاب کنید کدام **ستونها** را نگه دارید یا حذف کنید.\n",
|
|
"\n",
|
|
"- `dplyr::pivot_longer()`: به شما کمک میکند دادهها را \"طولانیتر\" کنید، تعداد ردیفها را افزایش داده و تعداد ستونها را کاهش دهید.\n",
|
|
"\n",
|
|
"- `dplyr::group_by()` و `dplyr::summarise()`: به شما کمک میکند که آمار خلاصهای برای گروههای مختلف پیدا کنید و آنها را در یک جدول مرتب قرار دهید.\n",
|
|
"\n",
|
|
"- `dplyr::filter()`: یک زیرمجموعه از دادهها ایجاد میکند که فقط شامل ردیفهایی است که شرایط شما را برآورده میکنند.\n",
|
|
"\n",
|
|
"- `dplyr::mutate()`: به شما کمک میکند ستونها را ایجاد یا اصلاح کنید.\n",
|
|
"\n",
|
|
"این [آموزش یادگیری پر از هنر](https://allisonhorst.shinyapps.io/dplyr-learnr/#section-welcome) توسط Allison Horst را بررسی کنید که برخی از توابع مفید برای پردازش دادهها در dplyr *(بخشی از Tidyverse)* را معرفی میکند.\n"
|
|
],
|
|
"metadata": {
|
|
"id": "K3RF5bSCHC76"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Creates a functions that returns the top ingredients by class\r\n",
|
|
"\r\n",
|
|
"create_ingredient <- function(df){\r\n",
|
|
" \r\n",
|
|
" # Drop the id column which is the first colum\r\n",
|
|
" ingredient_df = df %>% select(-1) %>% \r\n",
|
|
" # Transpose data to a long format\r\n",
|
|
" pivot_longer(!cuisine, names_to = \"ingredients\", values_to = \"count\") %>% \r\n",
|
|
" # Find the top most ingredients for a particular cuisine\r\n",
|
|
" group_by(ingredients) %>% \r\n",
|
|
" summarise(n_instances = sum(count)) %>% \r\n",
|
|
" filter(n_instances != 0) %>% \r\n",
|
|
" # Arrange by descending order\r\n",
|
|
" arrange(desc(n_instances)) %>% \r\n",
|
|
" mutate(ingredients = factor(ingredients) %>% fct_inorder())\r\n",
|
|
" \r\n",
|
|
" \r\n",
|
|
" return(ingredient_df)\r\n",
|
|
"} # End of function"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "uB_0JR82HTPa"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"حالا میتوانیم از این تابع استفاده کنیم تا ایدهای از ده ماده اولیه محبوب بر اساس نوع آشپزی به دست آوریم. بیایید آن را با `thai_df` امتحان کنیم.\n"
|
|
],
|
|
"metadata": {
|
|
"id": "h9794WF8HWmc"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Call create_ingredient and display popular ingredients\r\n",
|
|
"thai_ingredient_df <- create_ingredient(df = thai_df)\r\n",
|
|
"\r\n",
|
|
"thai_ingredient_df %>% \r\n",
|
|
" slice_head(n = 10)"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "agQ-1HrcHaEA"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"در بخش قبلی، از `geom_col()` استفاده کردیم، بیایید ببینیم چگونه میتوانید از `geom_bar` نیز برای ایجاد نمودارهای میلهای استفاده کنید. از `?geom_bar` برای مطالعه بیشتر استفاده کنید.\n"
|
|
],
|
|
"metadata": {
|
|
"id": "kHu9ffGjHdcX"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Make a bar chart for popular thai cuisines\r\n",
|
|
"thai_ingredient_df %>% \r\n",
|
|
" slice_head(n = 10) %>% \r\n",
|
|
" ggplot(aes(x = n_instances, y = ingredients)) +\r\n",
|
|
" geom_bar(stat = \"identity\", width = 0.5, fill = \"steelblue\") +\r\n",
|
|
" xlab(\"\") + ylab(\"\")"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "fb3Bx_3DHj6e"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"بیایید همین کار را برای دادههای ژاپنی انجام دهیم\n"
|
|
],
|
|
"metadata": {
|
|
"id": "RHP_xgdkHnvM"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Get popular ingredients for Japanese cuisines and make bar chart\r\n",
|
|
"create_ingredient(df = japanese_df) %>% \r\n",
|
|
" slice_head(n = 10) %>%\r\n",
|
|
" ggplot(aes(x = n_instances, y = ingredients)) +\r\n",
|
|
" geom_bar(stat = \"identity\", width = 0.5, fill = \"darkorange\", alpha = 0.8) +\r\n",
|
|
" xlab(\"\") + ylab(\"\")\r\n"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "019v8F0XHrRU"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"در مورد غذاهای چینی چطور؟\n"
|
|
],
|
|
"metadata": {
|
|
"id": "iIGM7vO8Hu3v"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Get popular ingredients for Chinese cuisines and make bar chart\r\n",
|
|
"create_ingredient(df = chinese_df) %>% \r\n",
|
|
" slice_head(n = 10) %>%\r\n",
|
|
" ggplot(aes(x = n_instances, y = ingredients)) +\r\n",
|
|
" geom_bar(stat = \"identity\", width = 0.5, fill = \"cyan4\", alpha = 0.8) +\r\n",
|
|
" xlab(\"\") + ylab(\"\")"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "lHd9_gd2HyzU"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"بیایید نگاهی به غذاهای هندی بیندازیم 🌶️.\n"
|
|
],
|
|
"metadata": {
|
|
"id": "ir8qyQbNH1c7"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Get popular ingredients for Indian cuisines and make bar chart\r\n",
|
|
"create_ingredient(df = indian_df) %>% \r\n",
|
|
" slice_head(n = 10) %>%\r\n",
|
|
" ggplot(aes(x = n_instances, y = ingredients)) +\r\n",
|
|
" geom_bar(stat = \"identity\", width = 0.5, fill = \"#041E42FF\", alpha = 0.8) +\r\n",
|
|
" xlab(\"\") + ylab(\"\")"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "ApukQtKjH5FO"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"در نهایت، مواد کرهای را رسم کنید.\n"
|
|
],
|
|
"metadata": {
|
|
"id": "qv30cwY1H-FM"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Get popular ingredients for Korean cuisines and make bar chart\r\n",
|
|
"create_ingredient(df = korean_df) %>% \r\n",
|
|
" slice_head(n = 10) %>%\r\n",
|
|
" ggplot(aes(x = n_instances, y = ingredients)) +\r\n",
|
|
" geom_bar(stat = \"identity\", width = 0.5, fill = \"#852419FF\", alpha = 0.8) +\r\n",
|
|
" xlab(\"\") + ylab(\"\")"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "lumgk9cHIBie"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"از دادههای تصویری، اکنون میتوانیم رایجترین مواد اولیهای که باعث ایجاد سردرگمی بین غذاهای مختلف میشوند را با استفاده از `dplyr::select()` حذف کنیم.\n",
|
|
"\n",
|
|
"همه عاشق برنج، سیر و زنجبیل هستند!\n"
|
|
],
|
|
"metadata": {
|
|
"id": "iO4veMXuIEta"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Drop id column, rice, garlic and ginger from our original data set\r\n",
|
|
"df_select <- df %>% \r\n",
|
|
" select(-c(1, rice, garlic, ginger))\r\n",
|
|
"\r\n",
|
|
"# Display new data set\r\n",
|
|
"df_select %>% \r\n",
|
|
" slice_head(n = 5)"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "iHJPiG6rIUcK"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"## پیشپردازش دادهها با استفاده از دستورالعملها 👩🍳👨🍳 - مقابله با دادههای نامتوازن ⚖️\n",
|
|
"\n",
|
|
"<p >\n",
|
|
" <img src=\"../../images/recipes.png\"\n",
|
|
" width=\"600\"/>\n",
|
|
" <figcaption>اثر هنری از @allison_horst</figcaption>\n",
|
|
"\n",
|
|
"از آنجا که این درس درباره آشپزی است، باید `دستورالعملها` را در زمینه مناسب قرار دهیم.\n",
|
|
"\n",
|
|
"Tidymodels یک بسته جذاب دیگر ارائه میدهد: `recipes` - بستهای برای پیشپردازش دادهها.\n"
|
|
],
|
|
"metadata": {
|
|
"id": "kkFd-JxdIaL6"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"بیایید دوباره نگاهی به توزیع غذاهای خود بیندازیم.\n"
|
|
],
|
|
"metadata": {
|
|
"id": "6l2ubtTPJAhY"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Distribution of cuisines\r\n",
|
|
"old_label_count <- df_select %>% \r\n",
|
|
" count(cuisine) %>% \r\n",
|
|
" arrange(desc(n))\r\n",
|
|
"\r\n",
|
|
"old_label_count"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "1e-E9cb7JDVi"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"همانطور که میبینید، توزیع تعداد غذاها بهطور قابلتوجهی نابرابر است. تعداد غذاهای کرهای تقریباً سه برابر غذاهای تایلندی است. دادههای نامتوازن اغلب تأثیرات منفی بر عملکرد مدل دارند. به یک مسئله طبقهبندی دودویی فکر کنید. اگر بیشتر دادههای شما متعلق به یک کلاس باشند، یک مدل یادگیری ماشین به احتمال زیاد همان کلاس را بیشتر پیشبینی میکند، فقط به این دلیل که دادههای بیشتری برای آن وجود دارد. متوازنسازی دادهها هرگونه انحراف در دادهها را برطرف میکند و به حذف این عدم توازن کمک میکند. بسیاری از مدلها زمانی بهترین عملکرد را دارند که تعداد مشاهدات برابر باشد و در نتیجه با دادههای نامتوازن دچار مشکل میشوند.\n",
|
|
"\n",
|
|
"دو روش اصلی برای مقابله با مجموعه دادههای نامتوازن وجود دارد:\n",
|
|
"\n",
|
|
"- افزودن مشاهدات به کلاس اقلیت: `Over-sampling` مانند استفاده از الگوریتم SMOTE\n",
|
|
"\n",
|
|
"- حذف مشاهدات از کلاس اکثریت: `Under-sampling`\n",
|
|
"\n",
|
|
"حالا بیایید نشان دهیم که چگونه میتوان با استفاده از یک `recipe` با مجموعه دادههای نامتوازن کار کرد. یک recipe را میتوان بهعنوان یک نقشه راه در نظر گرفت که توضیح میدهد چه مراحلی باید روی یک مجموعه داده اعمال شوند تا برای تحلیل داده آماده شود.\n"
|
|
],
|
|
"metadata": {
|
|
"id": "soAw6826JKx9"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Load themis package for dealing with imbalanced data\r\n",
|
|
"library(themis)\r\n",
|
|
"\r\n",
|
|
"# Create a recipe for preprocessing data\r\n",
|
|
"cuisines_recipe <- recipe(cuisine ~ ., data = df_select) %>% \r\n",
|
|
" step_smote(cuisine)\r\n",
|
|
"\r\n",
|
|
"cuisines_recipe"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "HS41brUIJVJy"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"بیایید مراحل پیشپردازش را بررسی کنیم.\n",
|
|
"\n",
|
|
"- فراخوانی `recipe()` با یک فرمول به دستورالعمل میگوید که *نقشها*ی متغیرها را با استفاده از دادههای `df_select` به عنوان مرجع تعیین کند. برای مثال، ستون `cuisine` نقش `outcome` دریافت کرده است، در حالی که بقیه ستونها نقش `predictor` دریافت کردهاند.\n",
|
|
"\n",
|
|
"- [`step_smote(cuisine)`](https://themis.tidymodels.org/reference/step_smote.html) یک *مشخصه* از یک مرحله دستورالعمل ایجاد میکند که نمونههای جدیدی از کلاس اقلیت را به صورت مصنوعی با استفاده از نزدیکترین همسایگان این موارد تولید میکند.\n",
|
|
"\n",
|
|
"حالا، اگر بخواهیم دادههای پیشپردازششده را ببینیم، باید دستورالعمل خود را [**`prep()`**](https://recipes.tidymodels.org/reference/prep.html) و [**`bake()`**](https://recipes.tidymodels.org/reference/bake.html) کنیم.\n",
|
|
"\n",
|
|
"`prep()`: پارامترهای مورد نیاز را از یک مجموعه آموزشی تخمین میزند که بعداً میتوان آنها را به مجموعه دادههای دیگر اعمال کرد.\n",
|
|
"\n",
|
|
"`bake()`: یک دستورالعمل آمادهشده را میگیرد و عملیات را روی هر مجموعه دادهای اعمال میکند.\n"
|
|
],
|
|
"metadata": {
|
|
"id": "Yb-7t7XcJaC8"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Prep and bake the recipe\r\n",
|
|
"preprocessed_df <- cuisines_recipe %>% \r\n",
|
|
" prep() %>% \r\n",
|
|
" bake(new_data = NULL) %>% \r\n",
|
|
" relocate(cuisine)\r\n",
|
|
"\r\n",
|
|
"# Display data\r\n",
|
|
"preprocessed_df %>% \r\n",
|
|
" slice_head(n = 5)\r\n",
|
|
"\r\n",
|
|
"# Quick summary stats\r\n",
|
|
"preprocessed_df %>% \r\n",
|
|
" introduce()"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "9QhSgdpxJl44"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"بیایید اکنون توزیع غذاهای خود را بررسی کنیم و آنها را با دادههای نامتعادل مقایسه کنیم.\n"
|
|
],
|
|
"metadata": {
|
|
"id": "dmidELh_LdV7"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Distribution of cuisines\r\n",
|
|
"new_label_count <- preprocessed_df %>% \r\n",
|
|
" count(cuisine) %>% \r\n",
|
|
" arrange(desc(n))\r\n",
|
|
"\r\n",
|
|
"list(new_label_count = new_label_count,\r\n",
|
|
" old_label_count = old_label_count)"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "aSh23klBLwDz"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"وای! دادهها تمیز، متعادل و بسیار خوشمزه هستند 😋!\n",
|
|
"\n",
|
|
"> معمولاً یک دستورالعمل به عنوان پیشپردازنده برای مدلسازی استفاده میشود، جایی که مشخص میکند چه مراحلی باید روی یک مجموعه داده اعمال شود تا برای مدلسازی آماده شود. در این حالت، معمولاً از یک `workflow()` استفاده میشود (همانطور که در درسهای قبلی دیدهایم) به جای اینکه دستورالعمل را به صورت دستی تخمین بزنیم.\n",
|
|
">\n",
|
|
"> بنابراین، معمولاً نیازی به استفاده از **`prep()`** و **`bake()`** در دستورالعملها هنگام استفاده از tidymodels ندارید، اما این توابع ابزارهای مفیدی هستند برای تأیید اینکه دستورالعملها همانطور که انتظار دارید عمل میکنند، مانند مورد ما.\n",
|
|
">\n",
|
|
"> وقتی یک دستورالعمل آمادهشده را با **`new_data = NULL`** بپزید، دادههایی که هنگام تعریف دستورالعمل ارائه کردهاید را دریافت میکنید، اما این دادهها مراحل پیشپردازش را پشت سر گذاشتهاند.\n",
|
|
"\n",
|
|
"حالا بیایید یک نسخه از این دادهها را برای استفاده در درسهای آینده ذخیره کنیم:\n"
|
|
],
|
|
"metadata": {
|
|
"id": "HEu80HZ8L7ae"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Save preprocessed data\r\n",
|
|
"write_csv(preprocessed_df, \"../../../data/cleaned_cuisines_R.csv\")"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "cBmCbIgrMOI6"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"این فایل CSV جدید اکنون در پوشه اصلی دادهها قرار دارد.\n",
|
|
"\n",
|
|
"**🚀چالش**\n",
|
|
"\n",
|
|
"این برنامه درسی شامل چندین مجموعه داده جالب است. پوشههای `data` را بررسی کنید و ببینید آیا مجموعه دادههایی وجود دارند که برای طبقهبندی دودویی یا چندکلاسه مناسب باشند؟ چه سوالاتی میتوانید از این مجموعه داده بپرسید؟\n",
|
|
"\n",
|
|
"## [**آزمون پس از درس**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/20/)\n",
|
|
"\n",
|
|
"## **مرور و مطالعه شخصی**\n",
|
|
"\n",
|
|
"- به [بسته themis](https://github.com/tidymodels/themis) نگاهی بیندازید. چه تکنیکهای دیگری میتوانیم برای مقابله با دادههای نامتوازن استفاده کنیم؟\n",
|
|
"\n",
|
|
"- وبسایت مرجع [مدلهای مرتب](https://www.tidymodels.org/start/).\n",
|
|
"\n",
|
|
"- H. Wickham و G. Grolemund، [*R برای علم داده: تجسم، مدلسازی، تبدیل، مرتبسازی و وارد کردن دادهها*](https://r4ds.had.co.nz/).\n",
|
|
"\n",
|
|
"#### تشکر ویژه از:\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",
|
|
"[Cassie Breviu](https://www.twitter.com/cassieview) و [Jen Looper](https://www.twitter.com/jenlooper) برای ایجاد نسخه اصلی پایتون این ماژول ♥️\n",
|
|
"\n",
|
|
"<p >\n",
|
|
" <img src=\"../../images/r_learners_sm.jpeg\"\n",
|
|
" width=\"600\"/>\n",
|
|
" <figcaption>اثر هنری از @allison_horst</figcaption>\n"
|
|
],
|
|
"metadata": {
|
|
"id": "WQs5621pMGwf"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"\n---\n\n**سلب مسئولیت**: \nاین سند با استفاده از سرویس ترجمه هوش مصنوعی [Co-op Translator](https://github.com/Azure/co-op-translator) ترجمه شده است. در حالی که ما برای دقت تلاش میکنیم، لطفاً توجه داشته باشید که ترجمههای خودکار ممکن است شامل خطاها یا نادرستیهایی باشند. سند اصلی به زبان اصلی آن باید به عنوان منبع معتبر در نظر گرفته شود. برای اطلاعات حساس، ترجمه حرفهای انسانی توصیه میشود. ما هیچ مسئولیتی در قبال سوءتفاهمها یا تفسیرهای نادرست ناشی از استفاده از این ترجمه نداریم.\n"
|
|
]
|
|
}
|
|
]
|
|
} |