{ "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", "
\n",
" \n",
"
\n",
"\n",
"> glimpse() и slice() са функции в [`dplyr`](https://dplyr.tidyverse.org/). Dplyr, част от Tidyverse, е граматика за манипулиране на данни, която предоставя последователен набор от действия, помагащи за решаването на най-често срещаните предизвикателства при обработката на данни.\n",
"\n",
"
\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",
"
\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"
]
}
]
}