650 lines
32 KiB
Plaintext
650 lines
32 KiB
Plaintext
{
|
|
"nbformat": 4,
|
|
"nbformat_minor": 0,
|
|
"metadata": {
|
|
"colab": {
|
|
"name": "lesson_12-R.ipynb",
|
|
"provenance": [],
|
|
"collapsed_sections": []
|
|
},
|
|
"kernelspec": {
|
|
"name": "ir",
|
|
"display_name": "R"
|
|
},
|
|
"language_info": {
|
|
"name": "R"
|
|
},
|
|
"coopTranslator": {
|
|
"original_hash": "fab50046ca413a38939d579f8432274f",
|
|
"translation_date": "2025-09-04T02:38:47+00:00",
|
|
"source_file": "4-Classification/3-Classifiers-2/solution/R/lesson_12-R.ipynb",
|
|
"language_code": "fa"
|
|
}
|
|
},
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"id": "jsFutf_ygqSx"
|
|
},
|
|
"source": [
|
|
"# ساخت یک مدل طبقهبندی: غذاهای خوشمزه آسیایی و هندی\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"id": "HD54bEefgtNO"
|
|
},
|
|
"source": [
|
|
"## طبقهبندیکنندههای آشپزی ۲\n",
|
|
"\n",
|
|
"در این درس دوم از طبقهبندی، ما به بررسی `روشهای بیشتری` برای طبقهبندی دادههای دستهبندیشده خواهیم پرداخت. همچنین درباره پیامدهای انتخاب یک طبقهبندیکننده نسبت به دیگری یاد خواهیم گرفت.\n",
|
|
"\n",
|
|
"### [**آزمون پیش از درس**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/23/)\n",
|
|
"\n",
|
|
"### **پیشنیاز**\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",
|
|
"- `themis`: بسته [themis](https://themis.tidymodels.org/) مراحل اضافی برای مقابله با دادههای نامتعادل را فراهم میکند.\n",
|
|
"\n",
|
|
"میتوانید این بستهها را با دستور زیر نصب کنید:\n",
|
|
"\n",
|
|
"`install.packages(c(\"tidyverse\", \"tidymodels\", \"kernlab\", \"themis\", \"ranger\", \"xgboost\", \"kknn\"))`\n",
|
|
"\n",
|
|
"همچنین، اسکریپت زیر بررسی میکند که آیا بستههای مورد نیاز برای تکمیل این ماژول را دارید یا خیر و در صورت نبود، آنها را برای شما نصب میکند.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"metadata": {
|
|
"id": "vZ57IuUxgyQt"
|
|
},
|
|
"source": [
|
|
"suppressWarnings(if (!require(\"pacman\"))install.packages(\"pacman\"))\n",
|
|
"\n",
|
|
"pacman::p_load(tidyverse, tidymodels, themis, kernlab, ranger, xgboost, kknn)"
|
|
],
|
|
"execution_count": null,
|
|
"outputs": []
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"id": "z22M-pj4g07x"
|
|
},
|
|
"source": [
|
|
"## **1. یک نقشه طبقهبندی**\n",
|
|
"\n",
|
|
"در [درس قبلی](https://github.com/microsoft/ML-For-Beginners/tree/main/4-Classification/2-Classifiers-1)، سعی کردیم به این پرسش پاسخ دهیم: چگونه بین مدلهای مختلف انتخاب کنیم؟ تا حد زیادی این انتخاب به ویژگیهای داده و نوع مسئلهای که میخواهیم حل کنیم بستگی دارد (برای مثال طبقهبندی یا رگرسیون؟)\n",
|
|
"\n",
|
|
"قبلاً درباره گزینههای مختلفی که هنگام طبقهبندی دادهها در اختیار دارید، با استفاده از برگه تقلب مایکروسافت یاد گرفتیم. چارچوب یادگیری ماشین پایتون، Scikit-learn، یک برگه تقلب مشابه اما با جزئیات بیشتر ارائه میدهد که میتواند به شما در محدود کردن انتخاب تخمینگرها (اصطلاح دیگری برای طبقهبندها) کمک کند:\n",
|
|
"\n",
|
|
"<p >\n",
|
|
" <img src=\"../../images/map.png\"\n",
|
|
" width=\"700\"/>\n",
|
|
" <figcaption></figcaption>\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"id": "u1i3xRIVg7vG"
|
|
},
|
|
"source": [
|
|
"> نکته: [این نقشه را به صورت آنلاین مشاهده کنید](https://scikit-learn.org/stable/tutorial/machine_learning_map/) و با کلیک روی مسیرها مستندات را بخوانید.\n",
|
|
">\n",
|
|
"> سایت [مرجع Tidymodels](https://www.tidymodels.org/find/parsnip/#models) نیز مستندات بسیار خوبی درباره انواع مختلف مدلها ارائه میدهد.\n",
|
|
"\n",
|
|
"### **برنامه** 🗺️\n",
|
|
"\n",
|
|
"این نقشه زمانی که درک واضحی از دادههای خود داشته باشید بسیار مفید است، زیرا میتوانید با دنبال کردن مسیرهای آن به یک تصمیم برسید:\n",
|
|
"\n",
|
|
"- ما بیش از ۵۰ نمونه داریم\n",
|
|
"\n",
|
|
"- میخواهیم یک دستهبندی را پیشبینی کنیم\n",
|
|
"\n",
|
|
"- دادههای برچسبدار داریم\n",
|
|
"\n",
|
|
"- کمتر از ۱۰۰ هزار نمونه داریم\n",
|
|
"\n",
|
|
"- ✨ میتوانیم یک Linear SVC انتخاب کنیم\n",
|
|
"\n",
|
|
"- اگر این کار نکرد، چون دادههای ما عددی هستند\n",
|
|
"\n",
|
|
" - میتوانیم یک ✨ KNeighbors Classifier امتحان کنیم\n",
|
|
"\n",
|
|
" - اگر این هم جواب نداد، ✨ SVC و ✨ Ensemble Classifiers را امتحان کنید\n",
|
|
"\n",
|
|
"این یک مسیر بسیار مفید برای دنبال کردن است. حالا، بیایید با استفاده از چارچوب مدلسازی [tidymodels](https://www.tidymodels.org/) شروع کنیم: مجموعهای منسجم و انعطافپذیر از بستههای R که برای تشویق به شیوههای آماری خوب توسعه داده شدهاند 😊.\n",
|
|
"\n",
|
|
"## ۲. تقسیم دادهها و مدیریت مجموعه دادههای نامتوازن\n",
|
|
"\n",
|
|
"از درسهای قبلی یاد گرفتیم که مجموعهای از مواد اولیه مشترک در میان غذاهای مختلف وجود داشت. همچنین، توزیع تعداد غذاها بسیار نابرابر بود.\n",
|
|
"\n",
|
|
"ما این موارد را به این صورت مدیریت میکنیم:\n",
|
|
"\n",
|
|
"- حذف مواد اولیهای که بیشترین اشتباه را بین غذاهای مختلف ایجاد میکنند، با استفاده از `dplyr::select()`.\n",
|
|
"\n",
|
|
"- استفاده از یک `recipe` که دادهها را پیشپردازش میکند تا با اعمال یک الگوریتم `over-sampling` برای مدلسازی آماده شوند.\n",
|
|
"\n",
|
|
"ما قبلاً این موارد را در درس قبلی بررسی کردیم، بنابراین این کار باید آسان باشد 🥳!\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"metadata": {
|
|
"id": "6tj_rN00hClA"
|
|
},
|
|
"source": [
|
|
"# Load the core Tidyverse and Tidymodels packages\n",
|
|
"library(tidyverse)\n",
|
|
"library(tidymodels)\n",
|
|
"\n",
|
|
"# Load the original cuisines data\n",
|
|
"df <- read_csv(file = \"https://raw.githubusercontent.com/microsoft/ML-For-Beginners/main/4-Classification/data/cuisines.csv\")\n",
|
|
"\n",
|
|
"# Drop id column, rice, garlic and ginger from our original data set\n",
|
|
"df_select <- df %>% \n",
|
|
" select(-c(1, rice, garlic, ginger)) %>%\n",
|
|
" # Encode cuisine column as categorical\n",
|
|
" mutate(cuisine = factor(cuisine))\n",
|
|
"\n",
|
|
"\n",
|
|
"# Create data split specification\n",
|
|
"set.seed(2056)\n",
|
|
"cuisines_split <- initial_split(data = df_select,\n",
|
|
" strata = cuisine,\n",
|
|
" prop = 0.7)\n",
|
|
"\n",
|
|
"# Extract the data in each split\n",
|
|
"cuisines_train <- training(cuisines_split)\n",
|
|
"cuisines_test <- testing(cuisines_split)\n",
|
|
"\n",
|
|
"# Display distribution of cuisines in the training set\n",
|
|
"cuisines_train %>% \n",
|
|
" count(cuisine) %>% \n",
|
|
" arrange(desc(n))"
|
|
],
|
|
"execution_count": null,
|
|
"outputs": []
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"id": "zFin5yw3hHb1"
|
|
},
|
|
"source": [
|
|
"### مقابله با دادههای نامتوازن\n",
|
|
"\n",
|
|
"دادههای نامتوازن اغلب تأثیرات منفی بر عملکرد مدل دارند. بسیاری از مدلها زمانی بهترین عملکرد را دارند که تعداد مشاهدات برابر باشد و به همین دلیل با دادههای نامتوازن دچار مشکل میشوند.\n",
|
|
"\n",
|
|
"دو روش اصلی برای مقابله با مجموعه دادههای نامتوازن وجود دارد:\n",
|
|
"\n",
|
|
"- اضافه کردن مشاهدات به کلاس اقلیت: `Over-sampling`، به عنوان مثال استفاده از الگوریتم SMOTE که به صورت مصنوعی نمونههای جدیدی از کلاس اقلیت را با استفاده از نزدیکترین همسایگان این موارد تولید میکند.\n",
|
|
"\n",
|
|
"- حذف مشاهدات از کلاس اکثریت: `Under-sampling`\n",
|
|
"\n",
|
|
"در درس قبلی، نشان دادیم که چگونه میتوان با استفاده از یک `recipe` با مجموعه دادههای نامتوازن برخورد کرد. یک recipe را میتوان به عنوان یک نقشه راه در نظر گرفت که توضیح میدهد چه مراحلی باید روی یک مجموعه داده اعمال شود تا برای تحلیل داده آماده شود. در مورد ما، میخواهیم توزیع برابری در تعداد غذاهای مختلف برای `training set` خود داشته باشیم. بیایید مستقیماً وارد موضوع شویم.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"metadata": {
|
|
"id": "cRzTnHolhLWd"
|
|
},
|
|
"source": [
|
|
"# Load themis package for dealing with imbalanced data\n",
|
|
"library(themis)\n",
|
|
"\n",
|
|
"# Create a recipe for preprocessing training data\n",
|
|
"cuisines_recipe <- recipe(cuisine ~ ., data = cuisines_train) %>%\n",
|
|
" step_smote(cuisine) \n",
|
|
"\n",
|
|
"# Print recipe\n",
|
|
"cuisines_recipe"
|
|
],
|
|
"execution_count": null,
|
|
"outputs": []
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"id": "KxOQ2ORhhO81"
|
|
},
|
|
"source": [
|
|
"حالا آمادهایم تا مدلها را آموزش دهیم! 👩💻👨💻\n",
|
|
"\n",
|
|
"## ۳. فراتر از مدلهای رگرسیون چندجملهای\n",
|
|
"\n",
|
|
"در درس قبلی، به مدلهای رگرسیون چندجملهای پرداختیم. بیایید مدلهای انعطافپذیرتری برای طبقهبندی بررسی کنیم.\n",
|
|
"\n",
|
|
"### ماشینهای بردار پشتیبان\n",
|
|
"\n",
|
|
"در زمینه طبقهبندی، `ماشینهای بردار پشتیبان` یک تکنیک یادگیری ماشین است که تلاش میکند یک *ابرصفحه* پیدا کند که به بهترین شکل ممکن کلاسها را از هم جدا کند. بیایید یک مثال ساده را بررسی کنیم:\n",
|
|
"\n",
|
|
"<p >\n",
|
|
" <img src=\"../../images/svm.png\"\n",
|
|
" width=\"300\"/>\n",
|
|
" <figcaption>https://commons.wikimedia.org/w/index.php?curid=22877598</figcaption>\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"id": "C4Wsd0vZhXYu"
|
|
},
|
|
"source": [
|
|
"H1~ کلاسها را جدا نمیکند. H2~ کلاسها را جدا میکند، اما فقط با یک فاصله کوچک. H3~ کلاسها را با بیشترین فاصله جدا میکند.\n",
|
|
"\n",
|
|
"#### طبقهبند خطی بردار پشتیبان\n",
|
|
"\n",
|
|
"خوشهبندی بردار پشتیبان (SVC) یکی از اعضای خانواده تکنیکهای یادگیری ماشین بردار پشتیبان است. در SVC، ابرصفحهای انتخاب میشود که بتواند `بیشتر` مشاهدات آموزشی را به درستی جدا کند، اما ممکن است `چند مشاهده` را اشتباه طبقهبندی کند. با اجازه دادن به برخی نقاط برای قرار گرفتن در سمت اشتباه، SVM نسبت به دادههای پرت مقاومتر میشود و در نتیجه تعمیم بهتری به دادههای جدید دارد. پارامتری که این تخطی را تنظیم میکند، به نام `cost` شناخته میشود که مقدار پیشفرض آن 1 است (به `help(\"svm_poly\")` مراجعه کنید).\n",
|
|
"\n",
|
|
"بیایید یک SVC خطی ایجاد کنیم با تنظیم `degree = 1` در یک مدل SVM چندجملهای.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"metadata": {
|
|
"id": "vJpp6nuChlBz"
|
|
},
|
|
"source": [
|
|
"# Make a linear SVC specification\n",
|
|
"svc_linear_spec <- svm_poly(degree = 1) %>% \n",
|
|
" set_engine(\"kernlab\") %>% \n",
|
|
" set_mode(\"classification\")\n",
|
|
"\n",
|
|
"# Bundle specification and recipe into a worklow\n",
|
|
"svc_linear_wf <- workflow() %>% \n",
|
|
" add_recipe(cuisines_recipe) %>% \n",
|
|
" add_model(svc_linear_spec)\n",
|
|
"\n",
|
|
"# Print out workflow\n",
|
|
"svc_linear_wf"
|
|
],
|
|
"execution_count": null,
|
|
"outputs": []
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"id": "rDs8cWNkhoqu"
|
|
},
|
|
"source": [
|
|
"حالا که مراحل پیشپردازش و مشخصات مدل را در قالب یک *جریان کاری* ثبت کردهایم، میتوانیم به آموزش مدل SVC خطی بپردازیم و در همین حین نتایج را ارزیابی کنیم. برای معیارهای عملکرد، بیایید یک مجموعه معیار ایجاد کنیم که موارد زیر را ارزیابی کند: `دقت`، `حساسیت`، `ارزش پیشبینی مثبت` و `F Measure`.\n",
|
|
"\n",
|
|
"> تابع `augment()` ستون(هایی) برای پیشبینیها به دادههای دادهشده اضافه میکند.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"metadata": {
|
|
"id": "81wiqcwuhrnq"
|
|
},
|
|
"source": [
|
|
"# Train a linear SVC model\n",
|
|
"svc_linear_fit <- svc_linear_wf %>% \n",
|
|
" fit(data = cuisines_train)\n",
|
|
"\n",
|
|
"# Create a metric set\n",
|
|
"eval_metrics <- metric_set(ppv, sens, accuracy, f_meas)\n",
|
|
"\n",
|
|
"\n",
|
|
"# Make predictions and Evaluate model performance\n",
|
|
"svc_linear_fit %>% \n",
|
|
" augment(new_data = cuisines_test) %>% \n",
|
|
" eval_metrics(truth = cuisine, estimate = .pred_class)"
|
|
],
|
|
"execution_count": null,
|
|
"outputs": []
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"id": "0UFQvHf-huo3"
|
|
},
|
|
"source": [
|
|
"#### ماشین بردار پشتیبان\n",
|
|
"\n",
|
|
"ماشین بردار پشتیبان (SVM) نسخهای توسعهیافته از طبقهبند بردار پشتیبان است که برای ایجاد مرز غیرخطی بین کلاسها طراحی شده است. به طور کلی، SVMها از *ترفند کرنل* برای گسترش فضای ویژگی استفاده میکنند تا بتوانند روابط غیرخطی بین کلاسها را تطبیق دهند. یکی از توابع کرنل محبوب و بسیار انعطافپذیری که توسط SVMها استفاده میشود، *تابع پایه شعاعی* است. بیایید ببینیم این روش چگونه روی دادههای ما عمل میکند.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"metadata": {
|
|
"id": "-KX4S8mzhzmp"
|
|
},
|
|
"source": [
|
|
"set.seed(2056)\n",
|
|
"\n",
|
|
"# Make an RBF SVM specification\n",
|
|
"svm_rbf_spec <- svm_rbf() %>% \n",
|
|
" set_engine(\"kernlab\") %>% \n",
|
|
" set_mode(\"classification\")\n",
|
|
"\n",
|
|
"# Bundle specification and recipe into a worklow\n",
|
|
"svm_rbf_wf <- workflow() %>% \n",
|
|
" add_recipe(cuisines_recipe) %>% \n",
|
|
" add_model(svm_rbf_spec)\n",
|
|
"\n",
|
|
"\n",
|
|
"# Train an RBF model\n",
|
|
"svm_rbf_fit <- svm_rbf_wf %>% \n",
|
|
" fit(data = cuisines_train)\n",
|
|
"\n",
|
|
"\n",
|
|
"# Make predictions and Evaluate model performance\n",
|
|
"svm_rbf_fit %>% \n",
|
|
" augment(new_data = cuisines_test) %>% \n",
|
|
" eval_metrics(truth = cuisine, estimate = .pred_class)"
|
|
],
|
|
"execution_count": null,
|
|
"outputs": []
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"id": "QBFSa7WSh4HQ"
|
|
},
|
|
"source": [
|
|
"خیلی بهتر 🤩!\n",
|
|
"\n",
|
|
"> ✅ لطفاً ببینید:\n",
|
|
">\n",
|
|
"> - [*ماشینهای بردار پشتیبان*](https://bradleyboehmke.github.io/HOML/svm.html)، یادگیری ماشین عملی با R\n",
|
|
">\n",
|
|
"> - [*ماشینهای بردار پشتیبان*](https://www.statlearning.com/)، مقدمهای بر یادگیری آماری با کاربردهایی در R\n",
|
|
">\n",
|
|
"> برای مطالعه بیشتر.\n",
|
|
"\n",
|
|
"### طبقهبندهای نزدیکترین همسایه\n",
|
|
"\n",
|
|
"الگوریتم *K*-نزدیکترین همسایه (KNN) الگوریتمی است که در آن هر مشاهده بر اساس *شباهت* آن به سایر مشاهدات پیشبینی میشود.\n",
|
|
"\n",
|
|
"بیایید یکی از این الگوریتمها را روی دادههای خود اعمال کنیم.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"metadata": {
|
|
"id": "k4BxxBcdh9Ka"
|
|
},
|
|
"source": [
|
|
"# Make a KNN specification\n",
|
|
"knn_spec <- nearest_neighbor() %>% \n",
|
|
" set_engine(\"kknn\") %>% \n",
|
|
" set_mode(\"classification\")\n",
|
|
"\n",
|
|
"# Bundle recipe and model specification into a workflow\n",
|
|
"knn_wf <- workflow() %>% \n",
|
|
" add_recipe(cuisines_recipe) %>% \n",
|
|
" add_model(knn_spec)\n",
|
|
"\n",
|
|
"# Train a boosted tree model\n",
|
|
"knn_wf_fit <- knn_wf %>% \n",
|
|
" fit(data = cuisines_train)\n",
|
|
"\n",
|
|
"\n",
|
|
"# Make predictions and Evaluate model performance\n",
|
|
"knn_wf_fit %>% \n",
|
|
" augment(new_data = cuisines_test) %>% \n",
|
|
" eval_metrics(truth = cuisine, estimate = .pred_class)"
|
|
],
|
|
"execution_count": null,
|
|
"outputs": []
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"id": "HaegQseriAcj"
|
|
},
|
|
"source": [
|
|
"به نظر میرسد که این مدل عملکرد خوبی ندارد. احتمالاً تغییر پارامترهای مدل (به کمک `help(\"nearest_neighbor\")`) میتواند عملکرد مدل را بهبود بخشد. حتماً آن را امتحان کنید.\n",
|
|
"\n",
|
|
"> ✅ لطفاً ببینید:\n",
|
|
">\n",
|
|
"> - [Hands-on Machine Learning with R](https://bradleyboehmke.github.io/HOML/)\n",
|
|
">\n",
|
|
"> - [An Introduction to Statistical Learning with Applications in R](https://www.statlearning.com/)\n",
|
|
">\n",
|
|
"> برای یادگیری بیشتر درباره طبقهبندهای *K*-نزدیکترین همسایهها.\n",
|
|
"\n",
|
|
"### طبقهبندهای ترکیبی\n",
|
|
"\n",
|
|
"الگوریتمهای ترکیبی با ترکیب چندین مدل پایه برای ایجاد یک مدل بهینه عمل میکنند، به یکی از روشهای زیر:\n",
|
|
"\n",
|
|
"`bagging`: اعمال یک *تابع میانگینگیری* بر مجموعهای از مدلهای پایه\n",
|
|
"\n",
|
|
"`boosting`: ساخت یک دنباله از مدلها که بر اساس یکدیگر ساخته میشوند تا عملکرد پیشبینی بهبود یابد.\n",
|
|
"\n",
|
|
"بیایید با امتحان کردن یک مدل جنگل تصادفی شروع کنیم، که مجموعه بزرگی از درختهای تصمیمگیری میسازد و سپس یک تابع میانگینگیری را اعمال میکند تا یک مدل کلی بهتر ایجاد شود.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"metadata": {
|
|
"id": "49DPoVs6iK1M"
|
|
},
|
|
"source": [
|
|
"# Make a random forest specification\n",
|
|
"rf_spec <- rand_forest() %>% \n",
|
|
" set_engine(\"ranger\") %>% \n",
|
|
" set_mode(\"classification\")\n",
|
|
"\n",
|
|
"# Bundle recipe and model specification into a workflow\n",
|
|
"rf_wf <- workflow() %>% \n",
|
|
" add_recipe(cuisines_recipe) %>% \n",
|
|
" add_model(rf_spec)\n",
|
|
"\n",
|
|
"# Train a random forest model\n",
|
|
"rf_wf_fit <- rf_wf %>% \n",
|
|
" fit(data = cuisines_train)\n",
|
|
"\n",
|
|
"\n",
|
|
"# Make predictions and Evaluate model performance\n",
|
|
"rf_wf_fit %>% \n",
|
|
" augment(new_data = cuisines_test) %>% \n",
|
|
" eval_metrics(truth = cuisine, estimate = .pred_class)"
|
|
],
|
|
"execution_count": null,
|
|
"outputs": []
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"id": "RGVYwC_aiUWc"
|
|
},
|
|
"source": [
|
|
"کار عالی 👏!\n",
|
|
"\n",
|
|
"بیایید همچنین با مدل Boosted Tree آزمایش کنیم.\n",
|
|
"\n",
|
|
"Boosted Tree یک روش ترکیبی را تعریف میکند که مجموعهای از درختهای تصمیمگیری متوالی ایجاد میکند، بهطوریکه هر درخت به نتایج درختهای قبلی وابسته است و تلاش میکند بهصورت تدریجی خطا را کاهش دهد. این روش بر وزن مواردی که بهاشتباه طبقهبندی شدهاند تمرکز میکند و برازش مدل بعدی را تنظیم میکند تا این اشتباهات را اصلاح کند.\n",
|
|
"\n",
|
|
"روشهای مختلفی برای برازش این مدل وجود دارد (به `help(\"boost_tree\")` مراجعه کنید). در این مثال، ما درختهای Boosted را از طریق موتور `xgboost` برازش خواهیم داد.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"metadata": {
|
|
"id": "Py1YWo-micWs"
|
|
},
|
|
"source": [
|
|
"# Make a boosted tree specification\n",
|
|
"boost_spec <- boost_tree(trees = 200) %>% \n",
|
|
" set_engine(\"xgboost\") %>% \n",
|
|
" set_mode(\"classification\")\n",
|
|
"\n",
|
|
"# Bundle recipe and model specification into a workflow\n",
|
|
"boost_wf <- workflow() %>% \n",
|
|
" add_recipe(cuisines_recipe) %>% \n",
|
|
" add_model(boost_spec)\n",
|
|
"\n",
|
|
"# Train a boosted tree model\n",
|
|
"boost_wf_fit <- boost_wf %>% \n",
|
|
" fit(data = cuisines_train)\n",
|
|
"\n",
|
|
"\n",
|
|
"# Make predictions and Evaluate model performance\n",
|
|
"boost_wf_fit %>% \n",
|
|
" augment(new_data = cuisines_test) %>% \n",
|
|
" eval_metrics(truth = cuisine, estimate = .pred_class)"
|
|
],
|
|
"execution_count": null,
|
|
"outputs": []
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"id": "zNQnbuejigZM"
|
|
},
|
|
"source": [
|
|
"> ✅ لطفاً ببینید:\n",
|
|
">\n",
|
|
"> - [یادگیری ماشین برای دانشمندان اجتماعی](https://cimentadaj.github.io/ml_socsci/tree-based-methods.html#random-forests)\n",
|
|
">\n",
|
|
"> - [یادگیری ماشین عملی با R](https://bradleyboehmke.github.io/HOML/)\n",
|
|
">\n",
|
|
"> - [مقدمهای بر یادگیری آماری با کاربردهایی در R](https://www.statlearning.com/)\n",
|
|
">\n",
|
|
"> - <https://algotech.netlify.app/blog/xgboost/> - مدل AdaBoost را بررسی میکند که جایگزین خوبی برای xgboost است.\n",
|
|
">\n",
|
|
"> برای یادگیری بیشتر درباره طبقهبندهای Ensemble.\n",
|
|
"\n",
|
|
"## ۴. اضافی - مقایسه چندین مدل\n",
|
|
"\n",
|
|
"ما در این آزمایشگاه تعداد زیادی مدل را برازش کردهایم 🙌. ایجاد تعداد زیادی جریان کاری از مجموعههای مختلف پیشپردازندهها و/یا مشخصات مدل و سپس محاسبه معیارهای عملکرد بهصورت تکتک میتواند خستهکننده یا دشوار باشد.\n",
|
|
"\n",
|
|
"بیایید ببینیم آیا میتوانیم این مشکل را با ایجاد یک تابع که لیستی از جریانهای کاری را روی مجموعه آموزشی برازش میکند و سپس معیارهای عملکرد را بر اساس مجموعه آزمایشی بازمیگرداند، حل کنیم. ما از `map()` و `map_dfr()` از بسته [purrr](https://purrr.tidyverse.org/) استفاده خواهیم کرد تا توابع را روی هر عنصر در لیست اعمال کنیم.\n",
|
|
"\n",
|
|
"> توابع [`map()`](https://purrr.tidyverse.org/reference/map.html) به شما این امکان را میدهند که بسیاری از حلقههای for را با کدی جایگزین کنید که هم مختصرتر و هم خواناتر است. بهترین مکان برای یادگیری درباره توابع [`map()`](https://purrr.tidyverse.org/reference/map.html) فصل [تکرار](http://r4ds.had.co.nz/iteration.html) در کتاب R برای علم داده است.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"metadata": {
|
|
"id": "Qzb7LyZnimd2"
|
|
},
|
|
"source": [
|
|
"set.seed(2056)\n",
|
|
"\n",
|
|
"# Create a metric set\n",
|
|
"eval_metrics <- metric_set(ppv, sens, accuracy, f_meas)\n",
|
|
"\n",
|
|
"# Define a function that returns performance metrics\n",
|
|
"compare_models <- function(workflow_list, train_set, test_set){\n",
|
|
" \n",
|
|
" suppressWarnings(\n",
|
|
" # Fit each model to the train_set\n",
|
|
" map(workflow_list, fit, data = train_set) %>% \n",
|
|
" # Make predictions on the test set\n",
|
|
" map_dfr(augment, new_data = test_set, .id = \"model\") %>%\n",
|
|
" # Select desired columns\n",
|
|
" select(model, cuisine, .pred_class) %>% \n",
|
|
" # Evaluate model performance\n",
|
|
" group_by(model) %>% \n",
|
|
" eval_metrics(truth = cuisine, estimate = .pred_class) %>% \n",
|
|
" ungroup()\n",
|
|
" )\n",
|
|
" \n",
|
|
"} # End of function"
|
|
],
|
|
"execution_count": null,
|
|
"outputs": []
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"id": "Fwa712sNisDA"
|
|
},
|
|
"source": []
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"metadata": {
|
|
"id": "3i4VJOi2iu-a"
|
|
},
|
|
"source": [
|
|
"# Make a list of workflows\n",
|
|
"workflow_list <- list(\n",
|
|
" \"svc\" = svc_linear_wf,\n",
|
|
" \"svm\" = svm_rbf_wf,\n",
|
|
" \"knn\" = knn_wf,\n",
|
|
" \"random_forest\" = rf_wf,\n",
|
|
" \"xgboost\" = boost_wf)\n",
|
|
"\n",
|
|
"# Call the function\n",
|
|
"set.seed(2056)\n",
|
|
"perf_metrics <- compare_models(workflow_list = workflow_list, train_set = cuisines_train, test_set = cuisines_test)\n",
|
|
"\n",
|
|
"# Print out performance metrics\n",
|
|
"perf_metrics %>% \n",
|
|
" group_by(.metric) %>% \n",
|
|
" arrange(desc(.estimate)) %>% \n",
|
|
" slice_head(n=7)\n",
|
|
"\n",
|
|
"# Compare accuracy\n",
|
|
"perf_metrics %>% \n",
|
|
" filter(.metric == \"accuracy\") %>% \n",
|
|
" arrange(desc(.estimate))\n"
|
|
],
|
|
"execution_count": null,
|
|
"outputs": []
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"id": "KuWK_lEli4nW"
|
|
},
|
|
"source": [
|
|
"بسته [**workflowset**](https://workflowsets.tidymodels.org/) به کاربران این امکان را میدهد که تعداد زیادی مدل ایجاد کرده و بهراحتی آنها را برازش کنند، اما بیشتر برای کار با تکنیکهای بازنمونهگیری مانند `cross-validation` طراحی شده است، رویکردی که هنوز به آن نپرداختهایم.\n",
|
|
"\n",
|
|
"## **🚀چالش**\n",
|
|
"\n",
|
|
"هر یک از این تکنیکها تعداد زیادی پارامتر دارند که میتوانید آنها را تنظیم کنید، برای مثال `cost` در SVMها، `neighbors` در KNN، و `mtry` (پیشبینیکنندههای انتخابی تصادفی) در جنگل تصادفی.\n",
|
|
"\n",
|
|
"پارامترهای پیشفرض هر کدام را بررسی کنید و به این فکر کنید که تنظیم این پارامترها چه تأثیری بر کیفیت مدل خواهد داشت.\n",
|
|
"\n",
|
|
"برای اطلاعات بیشتر درباره یک مدل خاص و پارامترهای آن، از دستور زیر استفاده کنید: `help(\"model\")` مثلاً `help(\"rand_forest\")`\n",
|
|
"\n",
|
|
"> در عمل، ما معمولاً *بهترین مقادیر* را با آموزش تعداد زیادی مدل روی یک `مجموعه داده شبیهسازیشده` و اندازهگیری عملکرد این مدلها *تخمین میزنیم*. این فرآیند **تنظیم** نامیده میشود.\n",
|
|
"\n",
|
|
"### [**آزمون پس از درس**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/24/)\n",
|
|
"\n",
|
|
"### **مرور و مطالعه شخصی**\n",
|
|
"\n",
|
|
"در این درسها اصطلاحات زیادی وجود دارد، بنابراین چند دقیقه وقت بگذارید و [این فهرست](https://docs.microsoft.com/dotnet/machine-learning/resources/glossary?WT.mc_id=academic-77952-leestott) از اصطلاحات مفید را مرور کنید!\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",
|
|
"با آرزوی یادگیری شاد،\n",
|
|
"\n",
|
|
"[اریک](https://twitter.com/ericntay)، سفیر طلایی دانشجویی Microsoft Learn.\n",
|
|
"\n",
|
|
"<p >\n",
|
|
" <img src=\"../../images/r_learners_sm.jpeg\"\n",
|
|
" width=\"569\"/>\n",
|
|
" <figcaption>اثر هنری از @allison_horst</figcaption>\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"\n---\n\n**سلب مسئولیت**: \nاین سند با استفاده از سرویس ترجمه هوش مصنوعی [Co-op Translator](https://github.com/Azure/co-op-translator) ترجمه شده است. در حالی که ما برای دقت تلاش میکنیم، لطفاً توجه داشته باشید که ترجمههای خودکار ممکن است شامل خطاها یا نادقتیها باشند. سند اصلی به زبان اصلی آن باید به عنوان منبع معتبر در نظر گرفته شود. برای اطلاعات حساس، ترجمه حرفهای انسانی توصیه میشود. ما هیچ مسئولیتی در قبال سوءتفاهمها یا تفسیرهای نادرست ناشی از استفاده از این ترجمه نداریم.\n"
|
|
]
|
|
}
|
|
]
|
|
} |