{ "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-03T20:29:53+00:00", "source_file": "4-Classification/3-Classifiers-2/solution/R/lesson_12-R.ipynb", "language_code": "pl" } }, "cells": [ { "cell_type": "markdown", "metadata": { "id": "jsFutf_ygqSx" }, "source": [ "# Zbuduj model klasyfikacji: Pyszne azjatyckie i indyjskie kuchnie\n" ] }, { "cell_type": "markdown", "metadata": { "id": "HD54bEefgtNO" }, "source": [ "## Klasyfikatory kuchni 2\n", "\n", "W tej drugiej lekcji dotyczącej klasyfikacji, zbadamy `więcej sposobów` klasyfikowania danych kategorycznych. Dowiemy się również, jakie konsekwencje niesie za sobą wybór jednego klasyfikatora zamiast innego.\n", "\n", "### [**Quiz przed wykładem**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/23/)\n", "\n", "### **Wymagania wstępne**\n", "\n", "Zakładamy, że ukończyłeś poprzednie lekcje, ponieważ będziemy kontynuować niektóre wcześniej omówione pojęcia.\n", "\n", "Do tej lekcji będziemy potrzebować następujących pakietów:\n", "\n", "- `tidyverse`: [tidyverse](https://www.tidyverse.org/) to [zbiór pakietów R](https://www.tidyverse.org/packages) zaprojektowany, aby uczynić analizę danych szybszą, łatwiejszą i bardziej przyjemną!\n", "\n", "- `tidymodels`: [tidymodels](https://www.tidymodels.org/) to [framework](https://www.tidymodels.org/packages/) składający się z pakietów do modelowania i uczenia maszynowego.\n", "\n", "- `themis`: [pakiet themis](https://themis.tidymodels.org/) dostarcza dodatkowe kroki w przepisach do radzenia sobie z niezrównoważonymi danymi.\n", "\n", "Możesz je zainstalować za pomocą:\n", "\n", "`install.packages(c(\"tidyverse\", \"tidymodels\", \"kernlab\", \"themis\", \"ranger\", \"xgboost\", \"kknn\"))`\n", "\n", "Alternatywnie, poniższy skrypt sprawdza, czy masz wymagane pakiety do ukończenia tego modułu i instaluje je, jeśli ich brakuje.\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. Mapa klasyfikacji**\n", "\n", "W naszej [poprzedniej lekcji](https://github.com/microsoft/ML-For-Beginners/tree/main/4-Classification/2-Classifiers-1) próbowaliśmy odpowiedzieć na pytanie: jak wybrać pomiędzy wieloma modelami? W dużej mierze zależy to od charakterystyki danych oraz rodzaju problemu, który chcemy rozwiązać (na przykład klasyfikacja czy regresja?).\n", "\n", "Wcześniej dowiedzieliśmy się o różnych opcjach klasyfikacji danych, korzystając z arkusza pomocy Microsoftu. Framework Machine Learning w Pythonie, Scikit-learn, oferuje podobny, ale bardziej szczegółowy arkusz pomocy, który może dodatkowo pomóc w zawężeniu wyboru estymatorów (inaczej klasyfikatorów):\n", "\n", "

\n", " \n", "

\n" ] }, { "cell_type": "markdown", "metadata": { "id": "u1i3xRIVg7vG" }, "source": [ "> Wskazówka: [odwiedź tę mapę online](https://scikit-learn.org/stable/tutorial/machine_learning_map/) i klikaj po ścieżkach, aby przeczytać dokumentację.\n", ">\n", "> [Strona referencyjna Tidymodels](https://www.tidymodels.org/find/parsnip/#models) również oferuje doskonałą dokumentację dotyczącą różnych typów modeli.\n", "\n", "### **Plan** 🗺️\n", "\n", "Ta mapa jest bardzo pomocna, gdy dobrze rozumiesz swoje dane, ponieważ możesz „przejść” jej ścieżkami, aby podjąć decyzję:\n", "\n", "- Mamy \\>50 próbek\n", "\n", "- Chcemy przewidzieć kategorię\n", "\n", "- Mamy dane z etykietami\n", "\n", "- Mamy mniej niż 100 tys. próbek\n", "\n", "- ✨ Możemy wybrać Linear SVC\n", "\n", "- Jeśli to się nie sprawdzi, ponieważ mamy dane numeryczne\n", "\n", " - Możemy spróbować ✨ KNeighbors Classifier\n", "\n", " - Jeśli to się nie sprawdzi, spróbuj ✨ SVC i ✨ Ensemble Classifiers\n", "\n", "To bardzo pomocna ścieżka do podążania. Teraz przejdźmy do działania, korzystając z frameworka modelowania [tidymodels](https://www.tidymodels.org/): spójnej i elastycznej kolekcji pakietów R, opracowanej w celu promowania dobrych praktyk statystycznych 😊.\n", "\n", "## 2. Podziel dane i zajmij się niezrównoważonym zestawem danych.\n", "\n", "Z naszych poprzednich lekcji dowiedzieliśmy się, że istnieje zestaw wspólnych składników w różnych kuchniach. Ponadto zauważyliśmy nierównomierny rozkład liczby kuchni.\n", "\n", "Poradzimy sobie z tym, wykonując następujące kroki:\n", "\n", "- Usuniemy najbardziej popularne składniki, które powodują zamieszanie między różnymi kuchniami, używając `dplyr::select()`.\n", "\n", "- Użyjemy `recipe`, który wstępnie przetwarza dane, aby przygotować je do modelowania, stosując algorytm `over-sampling`.\n", "\n", "Omówiliśmy powyższe w poprzedniej lekcji, więc to powinno być proste 🥳!\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": [ "### Radzenie sobie z niezrównoważonymi danymi\n", "\n", "Niezrównoważone dane często negatywnie wpływają na wydajność modelu. Wiele modeli działa najlepiej, gdy liczba obserwacji jest równa, przez co mają trudności z przetwarzaniem niezrównoważonych danych.\n", "\n", "Istnieją dwa główne sposoby radzenia sobie z niezrównoważonymi zbiorami danych:\n", "\n", "- dodawanie obserwacji do klasy mniejszościowej: `Over-sampling`, np. za pomocą algorytmu SMOTE, który syntetycznie generuje nowe przykłady klasy mniejszościowej, wykorzystując najbliższych sąsiadów tych przypadków.\n", "\n", "- usuwanie obserwacji z klasy większościowej: `Under-sampling`\n", "\n", "W naszej poprzedniej lekcji pokazaliśmy, jak radzić sobie z niezrównoważonymi zbiorami danych, korzystając z `recipe`. Recipe można traktować jako plan działania, który opisuje, jakie kroki należy zastosować do zbioru danych, aby przygotować go do analizy. W naszym przypadku chcemy uzyskać równomierny rozkład liczby naszych kuchni w `training set`. Przejdźmy do działania.\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": [ "Teraz jesteśmy gotowi do trenowania modeli 👩‍💻👨‍💻!\n", "\n", "## 3. Poza modelami regresji wielomianowej\n", "\n", "W naszej poprzedniej lekcji przyjrzeliśmy się modelom regresji wielomianowej. Zbadajmy teraz bardziej elastyczne modele klasyfikacji.\n", "\n", "### Maszyny wektorów nośnych\n", "\n", "W kontekście klasyfikacji, `Maszyny wektorów nośnych` to technika uczenia maszynowego, która stara się znaleźć *hiperpłaszczyznę*, która \"najlepiej\" oddziela klasy. Spójrzmy na prosty przykład:\n", "\n", "

\n", " \n", "

https://commons.wikimedia.org/w/index.php?curid=22877598
\n" ] }, { "cell_type": "markdown", "metadata": { "id": "C4Wsd0vZhXYu" }, "source": [ "H1~ nie oddziela klas. H2~ oddziela je, ale tylko z małym marginesem. H3~ oddziela je z maksymalnym marginesem.\n", "\n", "#### Liniowy Klasyfikator Wektorów Nośnych\n", "\n", "Klasyfikacja za pomocą wektorów nośnych (SVC) jest częścią rodziny metod uczenia maszynowego opartych na wektorach nośnych. W SVC hiperpłaszczyzna jest wybierana tak, aby poprawnie oddzielić `większość` obserwacji treningowych, ale `może błędnie sklasyfikować` kilka obserwacji. Pozwalając niektórym punktom znaleźć się po niewłaściwej stronie, SVM staje się bardziej odporny na wartości odstające, co prowadzi do lepszej uogólnienia na nowe dane. Parametr regulujący to naruszenie nazywany jest `kosztem` i ma domyślną wartość 1 (zobacz `help(\"svm_poly\")`).\n", "\n", "Stwórzmy liniowy SVC, ustawiając `degree = 1` w modelu SVM z wielomianem.\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": [ "Teraz, gdy uchwyciliśmy kroki wstępnego przetwarzania i specyfikację modelu w *workflow*, możemy przejść do trenowania liniowego SVC i jednocześnie ocenić wyniki. Aby uzyskać metryki wydajności, stwórzmy zestaw metryk, który oceni: `accuracy`, `sensitivity`, `Positive Predicted Value` oraz `F Measure`.\n", "\n", "> `augment()` doda kolumny z przewidywaniami do podanych danych.\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": [ "#### Maszyna wektorów nośnych\n", "\n", "Maszyna wektorów nośnych (SVM) jest rozszerzeniem klasyfikatora wektorów nośnych, które pozwala na uwzględnienie nieliniowej granicy między klasami. W istocie, SVM wykorzystują *sztuczkę z jądrem*, aby powiększyć przestrzeń cech i dostosować się do nieliniowych zależności między klasami. Jedną z popularnych i niezwykle elastycznych funkcji jądra stosowanych w SVM jest *funkcja bazowa radialna*. Zobaczmy, jak poradzi sobie z naszymi danymi.\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": [ "Dużo lepiej 🤩!\n", "\n", "> ✅ Proszę zobaczyć:\n", ">\n", "> - [*Support Vector Machines*](https://bradleyboehmke.github.io/HOML/svm.html), Hands-on Machine Learning with R\n", ">\n", "> - [*Support Vector Machines*](https://www.statlearning.com/), An Introduction to Statistical Learning with Applications in R\n", ">\n", "> dla dalszej lektury.\n", "\n", "### Klasyfikatory najbliższego sąsiada\n", "\n", "Algorytm *K*-najbliższych sąsiadów (KNN) przewiduje każdą obserwację na podstawie jej *podobieństwa* do innych obserwacji.\n", "\n", "Dopasujmy go do naszych danych.\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": [ "Wydaje się, że ten model nie działa zbyt dobrze. Prawdopodobnie zmiana argumentów modelu (zobacz `help(\"nearest_neighbor\")`) poprawi jego wydajność. Koniecznie wypróbuj tę opcję.\n", "\n", "> ✅ Zobacz:\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", "> aby dowiedzieć się więcej o klasyfikatorach *K*-Nearest Neighbors.\n", "\n", "### Klasyfikatory zespołowe\n", "\n", "Algorytmy zespołowe działają poprzez łączenie wielu bazowych estymatorów w celu stworzenia optymalnego modelu, wykorzystując jedną z dwóch metod:\n", "\n", "`bagging`: zastosowanie *funkcji uśredniającej* do zbioru modeli bazowych\n", "\n", "`boosting`: budowanie sekwencji modeli, które wzajemnie się uzupełniają, aby poprawić wydajność predykcyjną.\n", "\n", "Zacznijmy od wypróbowania modelu Random Forest, który tworzy dużą liczbę drzew decyzyjnych, a następnie stosuje funkcję uśredniającą, aby uzyskać lepszy model ogólny.\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": [ "Dobra robota 👏!\n", "\n", "Spróbujmy również modelu Boosted Tree.\n", "\n", "Boosted Tree to metoda zespołowa, która tworzy serię sekwencyjnych drzew decyzyjnych, gdzie każde drzewo zależy od wyników poprzednich drzew, aby stopniowo zmniejszać błąd. Skupia się na wagach błędnie sklasyfikowanych elementów i dostosowuje dopasowanie dla kolejnego klasyfikatora, aby je poprawić.\n", "\n", "Istnieją różne sposoby dopasowania tego modelu (zobacz `help(\"boost_tree\")`). W tym przykładzie dopasujemy Boosted trees za pomocą silnika `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": [ "> ✅ Proszę zobaczyć:\n", ">\n", "> - [Machine Learning for Social Scientists](https://cimentadaj.github.io/ml_socsci/tree-based-methods.html#random-forests)\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", "> - - Omawia model AdaBoost, który jest dobrą alternatywą dla xgboost.\n", ">\n", "> aby dowiedzieć się więcej o klasyfikatorach zespołowych.\n", "\n", "## 4. Dodatkowo - porównanie wielu modeli\n", "\n", "W tym laboratorium dopasowaliśmy całkiem sporo modeli 🙌. Może to stać się żmudne lub uciążliwe, jeśli musimy tworzyć wiele przepływów pracy z różnych zestawów procesorów wstępnych i/lub specyfikacji modeli, a następnie obliczać metryki wydajności jeden po drugim.\n", "\n", "Zobaczmy, czy możemy rozwiązać ten problem, tworząc funkcję, która dopasowuje listę przepływów pracy do zestawu treningowego, a następnie zwraca metryki wydajności na podstawie zestawu testowego. Skorzystamy z `map()` i `map_dfr()` z pakietu [purrr](https://purrr.tidyverse.org/), aby zastosować funkcje do każdego elementu w liście.\n", "\n", "> Funkcje [`map()`](https://purrr.tidyverse.org/reference/map.html) pozwalają zastąpić wiele pętli for kodem, który jest zarówno bardziej zwięzły, jak i łatwiejszy do odczytania. Najlepszym miejscem do nauki o funkcjach [`map()`](https://purrr.tidyverse.org/reference/map.html) jest [rozdział o iteracji](http://r4ds.had.co.nz/iteration.html) w R for Data Science.\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/) umożliwia użytkownikom tworzenie i łatwe dopasowywanie dużej liczby modeli, ale jest głównie zaprojektowany do pracy z technikami resamplingu, takimi jak `cross-validation`, podejście, które dopiero omówimy.\n", "\n", "## **🚀Wyzwanie**\n", "\n", "Każda z tych technik ma wiele parametrów, które można dostosować, na przykład `cost` w SVM, `neighbors` w KNN, `mtry` (losowo wybrane predyktory) w Random Forest.\n", "\n", "Zbadaj domyślne wartości parametrów dla każdej z nich i zastanów się, co zmiana tych parametrów oznaczałaby dla jakości modelu.\n", "\n", "Aby dowiedzieć się więcej o konkretnym modelu i jego parametrach, użyj: `help(\"model\")`, np. `help(\"rand_forest\")`.\n", "\n", "> W praktyce zazwyczaj *szacujemy* *najlepsze wartości* tych parametrów, trenując wiele modeli na `symulowanym zestawie danych` i mierząc, jak dobrze te modele się sprawdzają. Ten proces nazywa się **strojenie**.\n", "\n", "### [**Quiz po wykładzie**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/24/)\n", "\n", "### **Przegląd i samodzielna nauka**\n", "\n", "W tych lekcjach pojawia się wiele specjalistycznych terminów, więc poświęć chwilę na przejrzenie [tej listy](https://docs.microsoft.com/dotnet/machine-learning/resources/glossary?WT.mc_id=academic-77952-leestott) przydatnej terminologii!\n", "\n", "#### PODZIĘKOWANIA DLA:\n", "\n", "[`Allison Horst`](https://twitter.com/allison_horst/) za stworzenie niesamowitych ilustracji, które sprawiają, że R jest bardziej przyjazny i angażujący. Więcej ilustracji znajdziesz w jej [galerii](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) i [Jen Looper](https://www.twitter.com/jenlooper) za stworzenie oryginalnej wersji tego modułu w Pythonie ♥️\n", "\n", "Miłej nauki,\n", "\n", "[Eric](https://twitter.com/ericntay), Złoty Ambasador Studentów Microsoft Learn.\n", "\n", "

\n", " \n", "

Ilustracja autorstwa @allison_horst
\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n---\n\n**Zastrzeżenie**: \nTen dokument został przetłumaczony za pomocą usługi tłumaczenia AI [Co-op Translator](https://github.com/Azure/co-op-translator). Chociaż dokładamy wszelkich starań, aby tłumaczenie było precyzyjne, prosimy pamiętać, że automatyczne tłumaczenia mogą zawierać błędy lub nieścisłości. Oryginalny dokument w jego rodzimym języku powinien być uznawany za źródło autorytatywne. W przypadku informacji o kluczowym znaczeniu zaleca się skorzystanie z profesjonalnego tłumaczenia wykonanego przez człowieka. Nie ponosimy odpowiedzialności za jakiekolwiek nieporozumienia lub błędne interpretacje wynikające z korzystania z tego tłumaczenia.\n" ] } ] }