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/uk/5-Clustering/2-K-Means/solution/R/lesson_15-R.ipynb

639 lines
37 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": 0,
"metadata": {
"anaconda-cloud": "",
"kernelspec": {
"display_name": "R",
"language": "R",
"name": "ir"
},
"language_info": {
"codemirror_mode": "r",
"file_extension": ".r",
"mimetype": "text/x-r-source",
"name": "R",
"pygments_lexer": "r",
"version": "3.4.1"
},
"colab": {
"name": "lesson_14.ipynb",
"provenance": [],
"collapsed_sections": [],
"toc_visible": true
},
"coopTranslator": {
"original_hash": "ad65fb4aad0a156b42216e4929f490fc",
"translation_date": "2025-09-04T08:16:38+00:00",
"source_file": "5-Clustering/2-K-Means/solution/R/lesson_15-R.ipynb",
"language_code": "uk"
}
},
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "GULATlQXLXyR"
},
"source": [
"## Дослідження кластеризації методом K-Means за допомогою R та принципів Tidy Data.\n",
"\n",
"### [**Тест перед лекцією**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/29/)\n",
"\n",
"У цьому уроці ви навчитеся створювати кластери за допомогою пакету Tidymodels та інших пакетів екосистеми R (назвемо їх друзями 🧑‍🤝‍🧑), а також використовуючи набір даних про нігерійську музику, який ви імпортували раніше. Ми розглянемо основи методу K-Means для кластеризації. Пам’ятайте, що, як ви дізналися в попередньому уроці, існує багато способів роботи з кластерами, і метод, який ви використовуєте, залежить від ваших даних. Ми спробуємо метод K-Means, оскільки це найпоширеніша техніка кластеризації. Почнемо!\n",
"\n",
"Терміни, які ви вивчите:\n",
"\n",
"- Оцінка силуету\n",
"\n",
"- Метод ліктя\n",
"\n",
"- Інерція\n",
"\n",
"- Дисперсія\n",
"\n",
"### **Вступ**\n",
"\n",
"[Кластеризація методом K-Means](https://wikipedia.org/wiki/K-means_clustering) — це метод, що походить із галузі обробки сигналів. Він використовується для поділу та групування даних у `k кластерів` на основі схожості їхніх характеристик.\n",
"\n",
"Кластери можна візуалізувати як [діаграми Вороного](https://wikipedia.org/wiki/Voronoi_diagram), які включають точку (або \"насіння\") та її відповідну область.\n",
"\n",
"<p >\n",
" <img src=\"../../images/voronoi.png\"\n",
" width=\"500\"/>\n",
" <figcaption>Інфографіка від Jen Looper</figcaption>\n",
"\n",
"Кластеризація методом K-Means включає наступні кроки:\n",
"\n",
"1. Дата-сайєнтист починає з визначення бажаної кількості кластерів, які потрібно створити.\n",
"\n",
"2. Далі алгоритм випадково вибирає K спостережень із набору даних, які слугуватимуть початковими центрами кластерів (тобто центроїдами).\n",
"\n",
"3. Потім кожне з решти спостережень призначається до найближчого центроїда.\n",
"\n",
"4. Далі обчислюється нове середнє кожного кластеру, і центроїд переміщується до цього середнього.\n",
"\n",
"5. Тепер, коли центри були перераховані, кожне спостереження знову перевіряється, щоб визначити, чи може воно бути ближчим до іншого кластеру. Усі об’єкти знову перепризначаються, використовуючи оновлені середні кластерів. Кроки перепризначення кластерів і оновлення центроїдів повторюються ітеративно, доки призначення кластерів перестануть змінюватися (тобто, коли досягнуто збіжності). Зазвичай алгоритм завершується, коли кожна нова ітерація призводить до незначного переміщення центроїдів, і кластери стають статичними.\n",
"\n",
"<div>\n",
"\n",
"> Зверніть увагу, що через рандомізацію початкових k спостережень, які використовуються як стартові центроїди, ми можемо отримувати трохи різні результати кожного разу, коли застосовуємо процедуру. З цієї причини більшість алгоритмів використовують кілька *випадкових стартів* і вибирають ітерацію з найменшим WCSS. Таким чином, настійно рекомендується завжди запускати K-Means із кількома значеннями *nstart*, щоб уникнути *небажаного локального оптимуму.*\n",
"\n",
"</div>\n",
"\n",
"Ця коротка анімація, створена за допомогою [ілюстрацій](https://github.com/allisonhorst/stats-illustrations) Еллісон Хорст, пояснює процес кластеризації:\n",
"\n",
"<p >\n",
" <img src=\"../../images/kmeans.gif\"\n",
" width=\"550\"/>\n",
" <figcaption>Ілюстрація від @allison_horst</figcaption>\n",
"\n",
"Фундаментальне питання, яке виникає під час кластеризації, таке: як визначити, на скільки кластерів розділити ваші дані? Одним із недоліків використання методу K-Means є те, що вам потрібно встановити `k`, тобто кількість `центроїдів`. На щастя, `метод ліктя` допомагає оцінити гарне початкове значення для `k`. Ви спробуєте це за хвилину.\n",
"\n",
"### \n",
"\n",
"**Передумови**\n",
"\n",
"Ми продовжимо з того місця, де зупинилися в [попередньому уроці](https://github.com/microsoft/ML-For-Beginners/blob/main/5-Clustering/1-Visualize/solution/R/lesson_14-R.ipynb), де ми аналізували набір даних, створювали багато візуалізацій і фільтрували набір даних до цікавих спостережень. Обов’язково перегляньте його!\n",
"\n",
"Нам знадобляться деякі пакети для виконання цього модуля. Ви можете встановити їх за допомогою: `install.packages(c('tidyverse', 'tidymodels', 'cluster', 'summarytools', 'plotly', 'paletteer', 'factoextra', 'patchwork'))`\n",
"\n",
"Альтернативно, скрипт нижче перевіряє, чи є у вас необхідні пакети для завершення цього модуля, і встановлює їх, якщо деякі відсутні.\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "ah_tBi58LXyi"
},
"source": [
"suppressWarnings(if(!require(\"pacman\")) install.packages(\"pacman\"))\n",
"\n",
"pacman::p_load('tidyverse', 'tidymodels', 'cluster', 'summarytools', 'plotly', 'paletteer', 'factoextra', 'patchwork')\n"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "7e--UCUTLXym"
},
"source": [
"Давайте розпочнемо!\n",
"\n",
"## 1. Танці з даними: Визначимо 3 найпопулярніші музичні жанри\n",
"\n",
"Це короткий огляд того, що ми робили на попередньому уроці. Давайте розберемо дані!\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "Ycamx7GGLXyn"
},
"source": [
"# Load the core tidyverse and make it available in your current R session\n",
"library(tidyverse)\n",
"\n",
"# Import the data into a tibble\n",
"df <- read_csv(file = \"https://raw.githubusercontent.com/microsoft/ML-For-Beginners/main/5-Clustering/data/nigerian-songs.csv\", show_col_types = FALSE)\n",
"\n",
"# Narrow down to top 3 popular genres\n",
"nigerian_songs <- df %>% \n",
" # Concentrate on top 3 genres\n",
" filter(artist_top_genre %in% c(\"afro dancehall\", \"afropop\",\"nigerian pop\")) %>% \n",
" # Remove unclassified observations\n",
" filter(popularity != 0)\n",
"\n",
"\n",
"\n",
"# Visualize popular genres using bar plots\n",
"theme_set(theme_light())\n",
"nigerian_songs %>%\n",
" count(artist_top_genre) %>%\n",
" ggplot(mapping = aes(x = artist_top_genre, y = n,\n",
" fill = artist_top_genre)) +\n",
" geom_col(alpha = 0.8) +\n",
" paletteer::scale_fill_paletteer_d(\"ggsci::category10_d3\") +\n",
" ggtitle(\"Top genres\") +\n",
" theme(plot.title = element_text(hjust = 0.5))\n"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "b5h5zmkPLXyp"
},
"source": [
"🤩 Це пройшло чудово!\n",
"\n",
"## 2. Більше дослідження даних.\n",
"\n",
"Наскільки чисті ці дані? Давайте перевіримо наявність викидів за допомогою коробкових діаграм. Ми зосередимося на числових стовпцях із меншою кількістю викидів (хоча ви можете видалити викиди). Коробкові діаграми можуть показати діапазон даних і допоможуть обрати, які стовпці використовувати. Зверніть увагу, що коробкові діаграми не показують дисперсію, яка є важливим елементом для якісних кластеризованих даних. Будь ласка, ознайомтеся з [цією дискусією](https://stats.stackexchange.com/questions/91536/deduce-variance-from-boxplot) для подальшого читання.\n",
"\n",
"[Коробкові діаграми](https://en.wikipedia.org/wiki/Box_plot) використовуються для графічного зображення розподілу `числових` даних, тому давайте почнемо з *вибору* всіх числових стовпців разом із популярними музичними жанрами.\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "HhNreJKLLXyq"
},
"source": [
"# Select top genre column and all other numeric columns\n",
"df_numeric <- nigerian_songs %>% \n",
" select(artist_top_genre, where(is.numeric)) \n",
"\n",
"# Display the data\n",
"df_numeric %>% \n",
" slice_head(n = 5)\n"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "uYXrwJRaLXyq"
},
"source": [
"Подивіться, як селектор `where` робить це простим 💁? Досліджуйте інші подібні функції [тут](https://tidyselect.r-lib.org/).\n",
"\n",
"Оскільки ми будемо створювати коробкові діаграми для кожної числової ознаки і хочемо уникнути використання циклів, давайте переформатуємо наші дані у *довший* формат, який дозволить нам скористатися `facets` - підграфіками, кожен з яких відображає одну підмножину даних.\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "gd5bR3f8LXys"
},
"source": [
"# Pivot data from wide to long\n",
"df_numeric_long <- df_numeric %>% \n",
" pivot_longer(!artist_top_genre, names_to = \"feature_names\", values_to = \"values\") \n",
"\n",
"# Print out data\n",
"df_numeric_long %>% \n",
" slice_head(n = 15)\n"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "-7tE1swnLXyv"
},
"source": [
"Набагато довше! Тепер час для деяких `ggplots`! То який `geom` ми будемо використовувати?\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "r88bIsyuLXyy"
},
"source": [
"# Make a box plot\n",
"df_numeric_long %>% \n",
" ggplot(mapping = aes(x = feature_names, y = values, fill = feature_names)) +\n",
" geom_boxplot() +\n",
" facet_wrap(~ feature_names, ncol = 4, scales = \"free\") +\n",
" theme(legend.position = \"none\")\n"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "EYVyKIUELXyz"
},
"source": [
"Легко-gg!\n",
"\n",
"Тепер ми можемо побачити, що ці дані трохи шумні: спостерігаючи за кожним стовпцем у вигляді діаграми-боксплоту, ви можете помітити викиди. Ви могли б пройтися по набору даних і видалити ці викиди, але це зробило б дані досить мінімальними.\n",
"\n",
"Поки що давайте оберемо, які стовпці ми будемо використовувати для нашого завдання кластеризації. Оберемо числові стовпці з подібними діапазонами. Ми могли б закодувати `artist_top_genre` як числовий, але наразі пропустимо його.\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "-wkpINyZLXy0"
},
"source": [
"# Select variables with similar ranges\n",
"df_numeric_select <- df_numeric %>% \n",
" select(popularity, danceability, acousticness, loudness, energy) \n",
"\n",
"# Normalize data\n",
"# df_numeric_select <- scale(df_numeric_select)\n"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "D7dLzgpqLXy1"
},
"source": [
"## 3. Обчислення кластеризації k-means у R\n",
"\n",
"Ми можемо обчислити k-means у R за допомогою вбудованої функції `kmeans`, див. `help(\"kmeans()\")`. Функція `kmeans()` приймає датафрейм з усіма числовими стовпцями як основний аргумент.\n",
"\n",
"Першим кроком при використанні кластеризації k-means є визначення кількості кластерів (k), які будуть створені у фінальному рішенні. Ми знаємо, що в наборі даних є 3 музичні жанри, які ми виділили, тому спробуємо 3:\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "uC4EQ5w7LXy5"
},
"source": [
"set.seed(2056)\n",
"# Kmeans clustering for 3 clusters\n",
"kclust <- kmeans(\n",
" df_numeric_select,\n",
" # Specify the number of clusters\n",
" centers = 3,\n",
" # How many random initial configurations\n",
" nstart = 25\n",
")\n",
"\n",
"# Display clustering object\n",
"kclust\n"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "hzfhscWrLXy-"
},
"source": [
"Об'єкт kmeans містить кілька частин інформації, які добре пояснені у `help(\"kmeans()\")`. Зараз зосередимося на кількох аспектах. Ми бачимо, що дані були згруповані у 3 кластери розміром 65, 110, 111. Вихідні дані також містять центри кластерів (середні значення) для 3 груп за 5 змінними.\n",
"\n",
"Вектор кластеризації — це призначення кластерів для кожного спостереження. Давайте використаємо функцію `augment`, щоб додати призначення кластерів до початкового набору даних.\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "0XwwpFGQLXy_"
},
"source": [
"# Add predicted cluster assignment to data set\n",
"augment(kclust, df_numeric_select) %>% \n",
" relocate(.cluster) %>% \n",
" slice_head(n = 10)\n"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "NXIVXXACLXzA"
},
"source": [
"Чудово, ми щойно розділили наш набір даних на 3 групи. Тож, наскільки добре виконано кластеризацію 🤷? Давайте поглянемо на `Silhouette score`.\n",
"\n",
"### **Silhouette score**\n",
"\n",
"[Аналіз силуету](https://en.wikipedia.org/wiki/Silhouette_(clustering)) можна використовувати для вивчення відстані між отриманими кластерами. Цей показник варіюється від -1 до 1, і якщо значення близьке до 1, кластер щільний і добре відокремлений від інших кластерів. Значення, близьке до 0, вказує на кластеризацію з перекриттям, де зразки дуже близькі до межі прийняття рішення сусідніх кластерів. [джерело](https://dzone.com/articles/kmeans-silhouette-score-explained-with-python-exam).\n",
"\n",
"Метод середнього силуету обчислює середній силует спостережень для різних значень *k*. Високий середній показник силуету свідчить про якісну кластеризацію.\n",
"\n",
"Функція `silhouette` у пакеті кластерів використовується для обчислення середньої ширини силуету.\n",
"\n",
"> Силует можна обчислити за допомогою будь-якої [метрики відстані](https://en.wikipedia.org/wiki/Distance \"Distance\"), наприклад, [евклідової відстані](https://en.wikipedia.org/wiki/Euclidean_distance \"Euclidean distance\") або [мангеттенської відстані](https://en.wikipedia.org/wiki/Manhattan_distance \"Manhattan distance\"), які ми обговорювали в [попередньому уроці](https://github.com/microsoft/ML-For-Beginners/blob/main/5-Clustering/1-Visualize/solution/R/lesson_14-R.ipynb).\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "Jn0McL28LXzB"
},
"source": [
"# Load cluster package\n",
"library(cluster)\n",
"\n",
"# Compute average silhouette score\n",
"ss <- silhouette(kclust$cluster,\n",
" # Compute euclidean distance\n",
" dist = dist(df_numeric_select))\n",
"mean(ss[, 3])\n"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "QyQRn97nLXzC"
},
"source": [
"Наш результат становить **.549**, тобто прямо посередині. Це свідчить про те, що наші дані не надто добре підходять для такого типу кластеризації. Давайте перевіримо цю здогадку візуально. Пакет [factoextra](https://rpkgs.datanovia.com/factoextra/index.html) надає функції (`fviz_cluster()`) для візуалізації кластеризації.\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "7a6Km1_FLXzD"
},
"source": [
"library(factoextra)\n",
"\n",
"# Visualize clustering results\n",
"fviz_cluster(kclust, df_numeric_select)\n"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "IBwCWt-0LXzD"
},
"source": [
"Перекриття кластерів свідчить про те, що наші дані не надто добре підходять для такого типу кластеризації, але давайте продовжимо.\n",
"\n",
"## 4. Визначення оптимальної кількості кластерів\n",
"\n",
"Основне питання, яке часто виникає при кластеризації методом K-Means, звучить так: без відомих міток класів, як визначити, на скільки кластерів розділити дані?\n",
"\n",
"Один із способів дізнатися це — використати вибірку даних для `створення серії моделей кластеризації` з поступовим збільшенням кількості кластерів (наприклад, від 1 до 10) і оцінити метрики кластеризації, такі як **Silhouette score.**\n",
"\n",
"Давайте визначимо оптимальну кількість кластерів, обчисливши алгоритм кластеризації для різних значень *k* і оцінюючи **Суму квадратів всередині кластерів** (WCSS). Загальна сума квадратів всередині кластерів (WCSS) вимірює компактність кластеризації, і ми прагнемо, щоб вона була якомога меншою, оскільки менші значення означають, що точки даних ближчі одна до одної.\n",
"\n",
"Давайте дослідимо вплив різних значень `k`, від 1 до 10, на цю кластеризацію.\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "hSeIiylDLXzE"
},
"source": [
"# Create a series of clustering models\n",
"kclusts <- tibble(k = 1:10) %>% \n",
" # Perform kmeans clustering for 1,2,3 ... ,10 clusters\n",
" mutate(model = map(k, ~ kmeans(df_numeric_select, centers = .x, nstart = 25)),\n",
" # Farm out clustering metrics eg WCSS\n",
" glanced = map(model, ~ glance(.x))) %>% \n",
" unnest(cols = glanced)\n",
" \n",
"\n",
"# View clustering rsulsts\n",
"kclusts\n"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "m7rS2U1eLXzE"
},
"source": [
"Тепер, коли ми маємо загальну суму квадратів всередині кластерів (tot.withinss) для кожного алгоритму кластеризації з центром *k*, ми використовуємо [метод ліктя](https://en.wikipedia.org/wiki/Elbow_method_(clustering)), щоб знайти оптимальну кількість кластерів. Цей метод полягає у побудові графіка WCSS як функції кількості кластерів і виборі [точки ліктя кривої](https://en.wikipedia.org/wiki/Elbow_of_the_curve \"Elbow of the curve\") як кількості кластерів для використання.\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "o_DjHGItLXzF"
},
"source": [
"set.seed(2056)\n",
"# Use elbow method to determine optimum number of clusters\n",
"kclusts %>% \n",
" ggplot(mapping = aes(x = k, y = tot.withinss)) +\n",
" geom_line(size = 1.2, alpha = 0.8, color = \"#FF7F0EFF\") +\n",
" geom_point(size = 2, color = \"#FF7F0EFF\")\n"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "pLYyt5XSLXzG"
},
"source": [
"Графік показує значне зменшення WCSS (тобто більшу *щільність*) при збільшенні кількості кластерів з одного до двох, а також подальше помітне зменшення з двох до трьох кластерів. Після цього зменшення стає менш вираженим, що призводить до утворення `згину` 💪 на графіку приблизно на трьох кластерах. Це є хорошим свідченням того, що існує два-три досить добре розділені кластери точок даних.\n",
"\n",
"Тепер ми можемо перейти до витягування моделі кластеризації, де `k = 3`:\n",
"\n",
"> `pull()`: використовується для витягування одного стовпця\n",
">\n",
"> `pluck()`: використовується для індексації структур даних, таких як списки\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "JP_JPKBILXzG"
},
"source": [
"# Extract k = 3 clustering\n",
"final_kmeans <- kclusts %>% \n",
" filter(k == 3) %>% \n",
" pull(model) %>% \n",
" pluck(1)\n",
"\n",
"\n",
"final_kmeans\n"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "l_PDTu8tLXzI"
},
"source": [
"Чудово! Давайте візуалізуємо отримані кластери. Хочете додати трохи інтерактивності за допомогою `plotly`?\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "dNcleFe-LXzJ"
},
"source": [
"# Add predicted cluster assignment to data set\n",
"results <- augment(final_kmeans, df_numeric_select) %>% \n",
" bind_cols(df_numeric %>% select(artist_top_genre)) \n",
"\n",
"# Plot cluster assignments\n",
"clust_plt <- results %>% \n",
" ggplot(mapping = aes(x = popularity, y = danceability, color = .cluster, shape = artist_top_genre)) +\n",
" geom_point(size = 2, alpha = 0.8) +\n",
" paletteer::scale_color_paletteer_d(\"ggthemes::Tableau_10\")\n",
"\n",
"ggplotly(clust_plt)\n"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "6JUM_51VLXzK"
},
"source": [
"Можливо, ми очікували б, що кожен кластер (позначений різними кольорами) матиме чітко визначені жанри (позначені різними формами).\n",
"\n",
"Давайте розглянемо точність моделі.\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "HdIMUGq7LXzL"
},
"source": [
"# Assign genres to predefined integers\n",
"label_count <- results %>% \n",
" group_by(artist_top_genre) %>% \n",
" mutate(id = cur_group_id()) %>% \n",
" ungroup() %>% \n",
" summarise(correct_labels = sum(.cluster == id))\n",
"\n",
"\n",
"# Print results \n",
"cat(\"Result:\", label_count$correct_labels, \"out of\", nrow(results), \"samples were correctly labeled.\")\n",
"\n",
"cat(\"\\nAccuracy score:\", label_count$correct_labels/nrow(results))\n"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "C50wvaAOLXzM"
},
"source": [
"Точність цієї моделі непогана, але не ідеальна. Можливо, дані не дуже добре підходять для кластеризації методом K-Means. Ці дані надто незбалансовані, мало корельовані, і між значеннями стовпців занадто велика варіація, щоб добре кластеризувати. Насправді, кластери, які утворюються, ймовірно, сильно впливаються або спотворюються трьома категоріями жанрів, які ми визначили вище.\n",
"\n",
"Проте, це був досить цікавий процес навчання!\n",
"\n",
"У документації Scikit-learn можна побачити, що модель, як ця, з кластерами, які не дуже чітко розмежовані, має проблему \"варіації\":\n",
"\n",
"<p >\n",
" <img src=\"../../images/problems.png\"\n",
" width=\"500\"/>\n",
" <figcaption>Інфографіка з Scikit-learn</figcaption>\n",
"\n",
"\n",
"\n",
"## **Варіація**\n",
"\n",
"Варіація визначається як \"середнє квадратів різниць від середнього значення\" [джерело](https://www.mathsisfun.com/data/standard-deviation.html). У контексті цієї проблеми кластеризації це означає, що дані нашого набору мають тенденцію занадто сильно відхилятися від середнього значення.\n",
"\n",
"✅ Це чудовий момент, щоб подумати про всі способи, якими можна виправити цю проблему. Трохи змінити дані? Використати інші стовпці? Застосувати інший алгоритм? Підказка: Спробуйте [масштабувати дані](https://www.mygreatlearning.com/blog/learning-data-science-with-k-means-clustering/), щоб нормалізувати їх і протестувати інші стовпці.\n",
"\n",
"> Спробуйте цей '[калькулятор варіації](https://www.calculatorsoup.com/calculators/statistics/variance-calculator.php)', щоб краще зрозуміти концепцію.\n",
"\n",
"------------------------------------------------------------------------\n",
"\n",
"## **🚀Виклик**\n",
"\n",
"Приділіть трохи часу цьому ноутбуку, змінюючи параметри. Чи можете ви покращити точність моделі, краще очистивши дані (наприклад, видаливши аномалії)? Ви можете використовувати ваги, щоб надати більшу вагу певним зразкам даних. Що ще можна зробити, щоб створити кращі кластери?\n",
"\n",
"Підказка: Спробуйте масштабувати дані. У ноутбуці є закоментований код, який додає стандартне масштабування, щоб зробити стовпці даних більш схожими за діапазоном. Ви побачите, що хоча оцінка силуету знижується, \"злам\" на графіку ліктя згладжується. Це тому, що залишення даних без масштабування дозволяє даним з меншою варіацією мати більшу вагу. Прочитайте більше про цю проблему [тут](https://stats.stackexchange.com/questions/21222/are-mean-normalization-and-feature-scaling-needed-for-k-means-clustering/21226#21226).\n",
"\n",
"## [**Тест після лекції**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/30/)\n",
"\n",
"## **Огляд і самостійне навчання**\n",
"\n",
"- Ознайомтеся з симулятором K-Means [наприклад, таким](https://user.ceng.metu.edu.tr/~akifakkus/courses/ceng574/k-means/). Ви можете використовувати цей інструмент для візуалізації зразків даних і визначення їхніх центроїдів. Ви можете редагувати випадковість даних, кількість кластерів і кількість центроїдів. Чи допомагає це вам зрозуміти, як дані можуть бути згруповані?\n",
"\n",
"- Також ознайомтеся з [цією пам'яткою про K-Means](https://stanford.edu/~cpiech/cs221/handouts/kmeans.html) зі Стенфорда.\n",
"\n",
"Хочете спробувати свої нові навички кластеризації на наборах даних, які добре підходять для кластеризації методом K-Means? Дивіться:\n",
"\n",
"- [Навчання і оцінка моделей кластеризації](https://rpubs.com/eR_ic/clustering) за допомогою Tidymodels та інших інструментів\n",
"\n",
"- [Аналіз кластерів методом K-Means](https://uc-r.github.io/kmeans_clustering), UC Business Analytics R Programming Guide\n",
"\n",
"- [Кластеризація методом K-Means з принципами tidy data](https://www.tidymodels.org/learn/statistics/k-means/)\n",
"\n",
"## **Завдання**\n",
"\n",
"[Спробуйте різні методи кластеризації](https://github.com/microsoft/ML-For-Beginners/blob/main/5-Clustering/2-K-Means/assignment.md)\n",
"\n",
"## ДЯКУЄМО:\n",
"\n",
"[Jen Looper](https://www.twitter.com/jenlooper) за створення оригінальної версії цього модуля на Python ♥️\n",
"\n",
"[`Allison Horst`](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",
"Щасливого навчання,\n",
"\n",
"[Eric](https://twitter.com/ericntay), Золотий студентський посол Microsoft Learn.\n",
"\n",
"<p >\n",
" <img src=\"../../images/r_learners_sm.jpeg\"\n",
" width=\"500\"/>\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"
]
}
]
}