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/bg/2-Regression/1-Tools/solution/R/lesson_1-R.ipynb

447 lines
23 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": 2,
"metadata": {
"colab": {
"name": "lesson_1-R.ipynb",
"provenance": [],
"collapsed_sections": [],
"toc_visible": true
},
"kernelspec": {
"name": "ir",
"display_name": "R"
},
"language_info": {
"name": "R"
},
"coopTranslator": {
"original_hash": "c18d3bd0bd8ae3878597e89dcd1fa5c1",
"translation_date": "2025-09-04T07:03:05+00:00",
"source_file": "2-Regression/1-Tools/solution/R/lesson_1-R.ipynb",
"language_code": "bg"
}
},
"cells": [
{
"cell_type": "markdown",
"source": [],
"metadata": {
"id": "YJUHCXqK57yz"
}
},
{
"cell_type": "markdown",
"source": [
"## Въведение в регресията - Урок 1\n",
"\n",
"#### Поставяне в перспектива\n",
"\n",
"✅ Съществуват много видове методи за регресия, и изборът на подходящия зависи от въпроса, на който искате да отговорите. Ако искате да предвидите вероятната височина на човек на определена възраст, бихте използвали `линейна регресия`, тъй като търсите **числова стойност**. Ако се интересувате дали даден тип кухня трябва да се счита за веганска или не, търсите **категорийно определение**, затова бихте използвали `логистична регресия`. Ще научите повече за логистичната регресия по-късно. Помислете за някои въпроси, които можете да зададете на данните, и кой от тези методи би бил по-подходящ.\n",
"\n",
"В тази секция ще работите с [малък набор от данни за диабет](https://www4.stat.ncsu.edu/~boos/var.select/diabetes.html). Представете си, че искате да тествате лечение за пациенти с диабет. Моделите за машинно обучение могат да ви помогнат да определите кои пациенти биха реагирали по-добре на лечението, въз основа на комбинации от променливи. Дори един много базов модел за регресия, когато е визуализиран, може да покаже информация за променливи, които биха ви помогнали да организирате теоретичните си клинични изпитания.\n",
"\n",
"И така, нека започнем с тази задача!\n",
"\n",
"<p >\n",
" <img src=\"../../images/encouRage.jpg\"\n",
" width=\"630\"/>\n",
" <figcaption>Илюстрация от @allison_horst</figcaption>\n",
"\n",
"<!--![Илюстрация от \\@allison_horst](../../../../../../2-Regression/1-Tools/images/encouRage.jpg)<br>Илюстрация от @allison_horst-->\n"
],
"metadata": {
"id": "LWNNzfqd6feZ"
}
},
{
"cell_type": "markdown",
"source": [
"## 1. Зареждане на нашия инструментариум\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",
"Можете да ги инсталирате със следната команда:\n",
"\n",
"`install.packages(c(\"tidyverse\", \"tidymodels\"))`\n",
"\n",
"Скриптът по-долу проверява дали имате необходимите пакети за завършване на този модул и ги инсталира, ако някои липсват.\n"
],
"metadata": {
"id": "FIo2YhO26wI9"
}
},
{
"cell_type": "code",
"execution_count": 2,
"source": [
"suppressWarnings(if(!require(\"pacman\")) install.packages(\"pacman\"))\n",
"pacman::p_load(tidyverse, tidymodels)"
],
"outputs": [
{
"output_type": "stream",
"name": "stderr",
"text": [
"Loading required package: pacman\n",
"\n"
]
}
],
"metadata": {
"id": "cIA9fz9v7Dss",
"colab": {
"base_uri": "https://localhost:8080/"
},
"outputId": "2df7073b-86b2-4b32-cb86-0da605a0dc11"
}
},
{
"cell_type": "markdown",
"source": [
"Сега нека заредим тези страхотни пакети и да ги направим достъпни в текущата ни R сесия. (Това е само за илюстрация, `pacman::p_load()` вече го направи за вас)\n"
],
"metadata": {
"id": "gpO_P_6f9WUG"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# load the core Tidyverse packages\r\n",
"library(tidyverse)\r\n",
"\r\n",
"# load the core Tidymodels packages\r\n",
"library(tidymodels)\r\n"
],
"outputs": [],
"metadata": {
"id": "NLMycgG-9ezO"
}
},
{
"cell_type": "markdown",
"source": [
"## 2. Диабетният набор от данни\n",
"\n",
"В това упражнение ще демонстрираме уменията си за регресия, като правим прогнози върху набор от данни за диабет. [Диабетният набор от данни](https://www4.stat.ncsu.edu/~boos/var.select/diabetes.rwrite1.txt) включва `442 проби` с данни за диабет, с 10 променливи за прогнозиране: `възраст`, `пол`, `индекс на телесна маса`, `средно кръвно налягане` и `шест измервания на кръвния серум`, както и променлива за резултат `y`: количествена мярка за прогресията на заболяването една година след началната точка.\n",
"\n",
"|Брой наблюдения|442|\n",
"|----------------------|:---|\n",
"|Брой предиктори|Първите 10 колони са числови предиктивни|\n",
"|Резултат/Цел|Колона 11 е количествена мярка за прогресията на заболяването една година след началната точка|\n",
"|Информация за предикторите|- възраст в години\n",
"||- пол\n",
"||- bmi индекс на телесна маса\n",
"||- bp средно кръвно налягане\n",
"||- s1 tc, общ серумен холестерол\n",
"||- s2 ldl, липопротеини с ниска плътност\n",
"||- s3 hdl, липопротеини с висока плътност\n",
"||- s4 tch, общ холестерол / HDL\n",
"||- s5 ltg, вероятно логаритъм на нивото на серумните триглицериди\n",
"||- s6 glu, ниво на кръвна захар|\n",
"\n",
"> 🎓 Запомнете, това е контролирано обучение и ни е необходима целева променлива 'y'.\n",
"\n",
"Преди да можете да манипулирате данни с R, трябва да импортирате данните в паметта на R или да изградите връзка към данните, която R може да използва за достъп до тях дистанционно.\n",
"\n",
"> Пакетът [readr](https://readr.tidyverse.org/), който е част от Tidyverse, предоставя бърз и удобен начин за четене на правоъгълни данни в R.\n",
"\n",
"Сега, нека заредим диабетния набор от данни, предоставен на този URL адрес: <https://www4.stat.ncsu.edu/~boos/var.select/diabetes.html>\n",
"\n",
"Също така ще направим проверка на данните с помощта на `glimpse()` и ще покажем първите 5 реда с помощта на `slice()`.\n",
"\n",
"Преди да продължим, нека въведем нещо, което често ще срещате в R код 🥁🥁: операторът pipe `%>%`\n",
"\n",
"Операторът pipe (`%>%`) изпълнява операции в логическа последователност, като предава обект напред към функция или израз за извикване. Можете да мислите за оператора pipe като \"и след това\" във вашия код.\n"
],
"metadata": {
"id": "KM6iXLH996Cl"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Import the data set\r\n",
"diabetes <- read_table2(file = \"https://www4.stat.ncsu.edu/~boos/var.select/diabetes.rwrite1.txt\")\r\n",
"\r\n",
"\r\n",
"# Get a glimpse and dimensions of the data\r\n",
"glimpse(diabetes)\r\n",
"\r\n",
"\r\n",
"# Select the first 5 rows of the data\r\n",
"diabetes %>% \r\n",
" slice(1:5)"
],
"outputs": [],
"metadata": {
"id": "Z1geAMhM-bSP"
}
},
{
"cell_type": "markdown",
"source": [
"`glimpse()` ни показва, че тези данни съдържат 442 реда и 11 колони, като всички колони са от тип данни `double`.\n",
"\n",
"<br>\n",
"\n",
"> glimpse() и slice() са функции в [`dplyr`](https://dplyr.tidyverse.org/). Dplyr, част от Tidyverse, е граматика за манипулиране на данни, която предоставя последователен набор от действия, помагащи за решаването на най-често срещаните предизвикателства при обработката на данни.\n",
"\n",
"<br>\n",
"\n",
"Сега, след като разполагаме с данните, нека се фокусираме върху една характеристика (`bmi`), която ще използваме за тази задача. Това ще изисква да изберем желаните колони. Как можем да направим това?\n",
"\n",
"[`dplyr::select()`](https://dplyr.tidyverse.org/reference/select.html) ни позволява да *изберем* (и при нужда да преименуваме) колони в дадена таблица с данни.\n"
],
"metadata": {
"id": "UwjVT1Hz-c3Z"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Select predictor feature `bmi` and outcome `y`\r\n",
"diabetes_select <- diabetes %>% \r\n",
" select(c(bmi, y))\r\n",
"\r\n",
"# Print the first 5 rows\r\n",
"diabetes_select %>% \r\n",
" slice(1:10)"
],
"outputs": [],
"metadata": {
"id": "RDY1oAKI-m80"
}
},
{
"cell_type": "markdown",
"source": [
"## 3. Данни за обучение и тестване\n",
"\n",
"Обичайна практика в контролираното обучение е *разделянето* на данните на два подмножества: (обикновено по-голям) набор за обучение на модела и по-малък \"задържан\" набор, с който да се провери как се е представил моделът.\n",
"\n",
"Сега, когато имаме готови данни, можем да видим дали машината може да помогне да се определи логично разделение между числата в този набор от данни. Можем да използваме пакета [rsample](https://tidymodels.github.io/rsample/), който е част от рамката Tidymodels, за да създадем обект, който съдържа информация за *как* да се разделят данните, а след това още две функции от rsample, за да извлечем създадените набори за обучение и тестване:\n"
],
"metadata": {
"id": "SDk668xK-tc3"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"set.seed(2056)\r\n",
"# Split 67% of the data for training and the rest for tesing\r\n",
"diabetes_split <- diabetes_select %>% \r\n",
" initial_split(prop = 0.67)\r\n",
"\r\n",
"# Extract the resulting train and test sets\r\n",
"diabetes_train <- training(diabetes_split)\r\n",
"diabetes_test <- testing(diabetes_split)\r\n",
"\r\n",
"# Print the first 3 rows of the training set\r\n",
"diabetes_train %>% \r\n",
" slice(1:10)"
],
"outputs": [],
"metadata": {
"id": "EqtHx129-1h-"
}
},
{
"cell_type": "markdown",
"source": [
"## 4. Обучение на модел за линейна регресия с Tidymodels\n",
"\n",
"Сега сме готови да обучим нашия модел!\n",
"\n",
"В Tidymodels моделите се задават с помощта на `parsnip()` чрез определяне на три концепции:\n",
"\n",
"- **Типът** на модела разграничава различни модели като линейна регресия, логистична регресия, модели с дървета за решения и други.\n",
"\n",
"- **Режимът** на модела включва често срещани опции като регресия и класификация; някои типове модели поддържат и двете, докато други имат само един режим.\n",
"\n",
"- **Енджинът** на модела е изчислителният инструмент, който ще се използва за настройка на модела. Често това са R пакети, като **`\"lm\"`** или **`\"ranger\"`**\n",
"\n",
"Тази информация за модела се съхранява в спецификация на модела, така че нека създадем такава!\n"
],
"metadata": {
"id": "sBOS-XhB-6v7"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Build a linear model specification\r\n",
"lm_spec <- \r\n",
" # Type\r\n",
" linear_reg() %>% \r\n",
" # Engine\r\n",
" set_engine(\"lm\") %>% \r\n",
" # Mode\r\n",
" set_mode(\"regression\")\r\n",
"\r\n",
"\r\n",
"# Print the model specification\r\n",
"lm_spec"
],
"outputs": [],
"metadata": {
"id": "20OwEw20--t3"
}
},
{
"cell_type": "markdown",
"source": [
"След като моделът бъде *определен*, той може да бъде `оценен` или `обучен`, като се използва функцията [`fit()`](https://parsnip.tidymodels.org/reference/fit.html), обикновено с помощта на формула и някакви данни.\n",
"\n",
"`y ~ .` означава, че ще напаснем `y` като предсказваната стойност/цел, обяснена от всички предиктори/характеристики, т.е. `.` (в този случай имаме само един предиктор: `bmi`).\n"
],
"metadata": {
"id": "_oDHs89k_CJj"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Build a linear model specification\r\n",
"lm_spec <- linear_reg() %>% \r\n",
" set_engine(\"lm\") %>%\r\n",
" set_mode(\"regression\")\r\n",
"\r\n",
"\r\n",
"# Train a linear regression model\r\n",
"lm_mod <- lm_spec %>% \r\n",
" fit(y ~ ., data = diabetes_train)\r\n",
"\r\n",
"# Print the model\r\n",
"lm_mod"
],
"outputs": [],
"metadata": {
"id": "YlsHqd-q_GJQ"
}
},
{
"cell_type": "markdown",
"source": [
"От модела можем да видим коефициентите, научени по време на обучението. Те представляват коефициентите на линията на най-добро съответствие, която ни дава най-ниската обща грешка между действителната и прогнозната променлива.\n",
"<br>\n",
"\n",
"## 5. Направете прогнози върху тестовия набор\n",
"\n",
"Сега, след като сме обучили модел, можем да го използваме, за да прогнозираме прогресията на заболяването y за тестовия набор от данни, използвайки [parsnip::predict()](https://parsnip.tidymodels.org/reference/predict.model_fit.html). Това ще се използва за начертаване на линията между групите данни.\n"
],
"metadata": {
"id": "kGZ22RQj_Olu"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Make predictions for the test set\r\n",
"predictions <- lm_mod %>% \r\n",
" predict(new_data = diabetes_test)\r\n",
"\r\n",
"# Print out some of the predictions\r\n",
"predictions %>% \r\n",
" slice(1:5)"
],
"outputs": [],
"metadata": {
"id": "nXHbY7M2_aao"
}
},
{
"cell_type": "markdown",
"source": [
"Ура! 💃🕺 Току-що обучихме модел и го използвахме за правене на прогнози!\n",
"\n",
"При правене на прогнози, конвенцията на tidymodels е винаги да се създава tibble/data frame с резултати и стандартизирани имена на колони. Това улеснява комбинирането на оригиналните данни и прогнозите в удобен формат за последващи операции като визуализация.\n",
"\n",
"`dplyr::bind_cols()` ефективно свързва множество data frame-ове по колони.\n"
],
"metadata": {
"id": "R_JstwUY_bIs"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Combine the predictions and the original test set\r\n",
"results <- diabetes_test %>% \r\n",
" bind_cols(predictions)\r\n",
"\r\n",
"\r\n",
"results %>% \r\n",
" slice(1:5)"
],
"outputs": [],
"metadata": {
"id": "RybsMJR7_iI8"
}
},
{
"cell_type": "markdown",
"source": [
"## 6. Визуализация на резултатите от модела\n",
"\n",
"Сега е време да видим това визуално 📈. Ще създадем разпръснат график на всички стойности на `y` и `bmi` от тестовия набор, след което ще използваме прогнозите, за да начертаем линия на най-подходящото място, между групите данни на модела.\n",
"\n",
"R има няколко системи за създаване на графики, но `ggplot2` е една от най-елегантните и най-гъвкавите. Това ви позволява да съставяте графики чрез **комбиниране на независими компоненти**.\n"
],
"metadata": {
"id": "XJbYbMZW_n_s"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Set a theme for the plot\r\n",
"theme_set(theme_light())\r\n",
"# Create a scatter plot\r\n",
"results %>% \r\n",
" ggplot(aes(x = bmi)) +\r\n",
" # Add a scatter plot\r\n",
" geom_point(aes(y = y), size = 1.6) +\r\n",
" # Add a line plot\r\n",
" geom_line(aes(y = .pred), color = \"blue\", size = 1.5)"
],
"outputs": [],
"metadata": {
"id": "R9tYp3VW_sTn"
}
},
{
"cell_type": "markdown",
"source": [
"✅ Помислете малко какво се случва тук. Една права линия минава през множество малки точки от данни, но какво точно прави тя? Можете ли да видите как бихте могли да използвате тази линия, за да предвидите къде нова, невиждана досега точка от данни би трябвало да се впише спрямо оста y на графиката? Опитайте се да опишете с думи практическото приложение на този модел.\n",
"\n",
"Поздравления, създадохте първия си модел за линейна регресия, направихте предсказание с него и го визуализирахте в графика!\n"
],
"metadata": {
"id": "zrPtHIxx_tNI"
}
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**Отказ от отговорност**: \nТози документ е преведен с помощта на AI услуга за превод [Co-op Translator](https://github.com/Azure/co-op-translator). Въпреки че се стремим към точност, моля, имайте предвид, че автоматичните преводи може да съдържат грешки или неточности. Оригиналният документ на неговия изходен език трябва да се счита за авторитетен източник. За критична информация се препоръчва професионален превод от човек. Ние не носим отговорност за каквито и да е недоразумения или погрешни интерпретации, произтичащи от използването на този превод.\n"
]
}
]
}