{ "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-08-29T23:39:22+00:00", "source_file": "5-Clustering/2-K-Means/solution/R/lesson_15-R.ipynb", "language_code": "br" } }, "cells": [ { "cell_type": "markdown", "metadata": { "id": "GULATlQXLXyR" }, "source": [ "## Explore o agrupamento K-Means usando R e os princípios de dados Tidy.\n", "\n", "### [**Questionário pré-aula**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/29/)\n", "\n", "Nesta lição, você aprenderá como criar agrupamentos usando o pacote Tidymodels e outros pacotes do ecossistema R (vamos chamá-los de amigos 🧑‍🤝‍🧑), além do conjunto de dados de música nigeriana que você importou anteriormente. Vamos abordar os fundamentos do K-Means para agrupamento. Lembre-se de que, como você aprendeu na lição anterior, existem várias maneiras de trabalhar com agrupamentos, e o método que você usa depende dos seus dados. Vamos experimentar o K-Means, pois é a técnica de agrupamento mais comum. Vamos começar!\n", "\n", "Termos que você aprenderá:\n", "\n", "- Pontuação Silhouette\n", "\n", "- Método do Cotovelo\n", "\n", "- Inércia\n", "\n", "- Variância\n", "\n", "### **Introdução**\n", "\n", "O [agrupamento K-Means](https://wikipedia.org/wiki/K-means_clustering) é um método derivado do domínio do processamento de sinais. Ele é usado para dividir e particionar grupos de dados em `k agrupamentos` com base em semelhanças em suas características.\n", "\n", "Os agrupamentos podem ser visualizados como [diagramas de Voronoi](https://wikipedia.org/wiki/Voronoi_diagram), que incluem um ponto (ou 'semente') e sua região correspondente.\n", "\n", "

\n", " \n", "

Infográfico por Jen Looper
\n", "\n", "O agrupamento K-Means segue os seguintes passos:\n", "\n", "1. O cientista de dados começa especificando o número desejado de agrupamentos a serem criados.\n", "\n", "2. Em seguida, o algoritmo seleciona aleatoriamente K observações do conjunto de dados para servir como os centros iniciais dos agrupamentos (ou seja, centróides).\n", "\n", "3. Depois, cada uma das observações restantes é atribuída ao centróide mais próximo.\n", "\n", "4. Em seguida, as novas médias de cada agrupamento são calculadas e o centróide é movido para a nova média.\n", "\n", "5. Agora que os centros foram recalculados, cada observação é verificada novamente para ver se pode estar mais próxima de um agrupamento diferente. Todos os objetos são realocados novamente usando as médias atualizadas dos agrupamentos. As etapas de atribuição de agrupamento e atualização dos centróides são repetidas iterativamente até que as atribuições de agrupamento parem de mudar (ou seja, quando a convergência é alcançada). Normalmente, o algoritmo termina quando cada nova iteração resulta em um movimento insignificante dos centróides e os agrupamentos se tornam estáticos.\n", "\n", "
\n", "\n", "> Observe que, devido à randomização das k observações iniciais usadas como centróides iniciais, podemos obter resultados ligeiramente diferentes a cada vez que aplicamos o procedimento. Por essa razão, a maioria dos algoritmos utiliza vários *inícios aleatórios* e escolhe a iteração com o menor WCSS. Assim, é altamente recomendável sempre executar o K-Means com vários valores de *nstart* para evitar um *ótimo local indesejado.*\n", "\n", "
\n", "\n", "Esta breve animação usando a [arte](https://github.com/allisonhorst/stats-illustrations) de Allison Horst explica o processo de agrupamento:\n", "\n", "

\n", " \n", "

Arte por @allison_horst
\n", "\n", "Uma questão fundamental que surge no agrupamento é: como saber em quantos agrupamentos separar seus dados? Uma desvantagem do uso do K-Means é o fato de que você precisará estabelecer `k`, ou seja, o número de `centróides`. Felizmente, o `método do cotovelo` ajuda a estimar um bom valor inicial para `k`. Você experimentará isso em breve.\n", "\n", "### \n", "\n", "**Pré-requisito**\n", "\n", "Vamos continuar de onde paramos na [lição anterior](https://github.com/microsoft/ML-For-Beginners/blob/main/5-Clustering/1-Visualize/solution/R/lesson_14-R.ipynb), onde analisamos o conjunto de dados, criamos várias visualizações e filtramos o conjunto de dados para observações de interesse. Certifique-se de conferir!\n", "\n", "Vamos precisar de alguns pacotes para concluir este módulo. Você pode instalá-los com: `install.packages(c('tidyverse', 'tidymodels', 'cluster', 'summarytools', 'plotly', 'paletteer', 'factoextra', 'patchwork'))`\n", "\n", "Alternativamente, o script abaixo verifica se você possui os pacotes necessários para completar este módulo e os instala para você caso algum esteja faltando.\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": [ "Vamos começar com tudo!\n", "\n", "## 1. Uma dança com dados: Reduza para os 3 gêneros musicais mais populares\n", "\n", "Este é um resumo do que fizemos na lição anterior. Vamos explorar e analisar alguns dados!\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": [ "🤩 Isso foi ótimo!\n", "\n", "## 2. Mais exploração de dados.\n", "\n", "Quão limpos estão esses dados? Vamos verificar a presença de outliers usando boxplots. Vamos nos concentrar em colunas numéricas com menos outliers (embora você possa limpar os outliers, se preferir). Boxplots podem mostrar o intervalo dos dados e ajudar a escolher quais colunas usar. Observe que os boxplots não mostram a variância, um elemento importante para dados bem agrupáveis. Por favor, veja [esta discussão](https://stats.stackexchange.com/questions/91536/deduce-variance-from-boxplot) para leitura adicional.\n", "\n", "[Boxplots](https://en.wikipedia.org/wiki/Box_plot) são usados para representar graficamente a distribuição de dados `numéricos`, então vamos começar *selecionando* todas as colunas numéricas junto com os gêneros musicais populares.\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": [ "Veja como o seletor `where` facilita isso 💁? Explore outras funções semelhantes [aqui](https://tidyselect.r-lib.org/).\n", "\n", "Como vamos criar um boxplot para cada característica numérica e queremos evitar o uso de loops, vamos reformular nossos dados para um formato *mais longo*, o que nos permitirá aproveitar os `facets` - subgráficos que exibem cada um um subconjunto dos dados.\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": [ "Muito mais longo! Agora é hora de alguns `ggplots`! Então, qual `geom` usaremos?\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": [ "Fácil-gg!\n", "\n", "Agora podemos ver que esses dados estão um pouco ruidosos: ao observar cada coluna como um boxplot, é possível identificar valores atípicos. Você poderia percorrer o conjunto de dados e remover esses valores atípicos, mas isso tornaria os dados bem reduzidos.\n", "\n", "Por enquanto, vamos escolher quais colunas usaremos para o nosso exercício de agrupamento. Vamos selecionar as colunas numéricas com intervalos semelhantes. Poderíamos codificar o `artist_top_genre` como numérico, mas vamos descartá-lo por enquanto.\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. Computando agrupamento k-means em R\n", "\n", "Podemos calcular k-means em R usando a função integrada `kmeans`, veja `help(\"kmeans()\")`. A função `kmeans()` aceita um data frame com todas as colunas numéricas como seu argumento principal.\n", "\n", "O primeiro passo ao usar o agrupamento k-means é especificar o número de clusters (k) que serão gerados na solução final. Sabemos que há 3 gêneros musicais que extraímos do conjunto de dados, então vamos tentar com 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": [ "O objeto kmeans contém várias informações que estão bem explicadas em `help(\"kmeans()\")`. Por enquanto, vamos nos concentrar em algumas delas. Podemos ver que os dados foram agrupados em 3 clusters com tamanhos de 65, 110 e 111. A saída também contém os centros dos clusters (médias) para os 3 grupos em relação às 5 variáveis.\n", "\n", "O vetor de agrupamento é a atribuição de cluster para cada observação. Vamos usar a função `augment` para adicionar a atribuição de cluster ao conjunto de dados original.\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": [ "Perfeito, acabamos de dividir nosso conjunto de dados em um conjunto de 3 grupos. Então, quão boa é nossa clusterização 🤷? Vamos dar uma olhada no `Silhouette score`.\n", "\n", "### **Silhouette score**\n", "\n", "[A análise de Silhouette](https://en.wikipedia.org/wiki/Silhouette_(clustering)) pode ser usada para estudar a distância de separação entre os clusters resultantes. Esse score varia de -1 a 1, e se o score estiver próximo de 1, o cluster é denso e bem separado dos outros clusters. Um valor próximo de 0 representa clusters sobrepostos com amostras muito próximas da fronteira de decisão dos clusters vizinhos. [fonte](https://dzone.com/articles/kmeans-silhouette-score-explained-with-python-exam).\n", "\n", "O método de silhouette médio calcula a média do silhouette das observações para diferentes valores de *k*. Um alto score médio de silhouette indica uma boa clusterização.\n", "\n", "A função `silhouette` no pacote de cluster é usada para calcular a largura média do silhouette.\n", "\n", "> O silhouette pode ser calculado com qualquer [métrica de distância](https://en.wikipedia.org/wiki/Distance \"Distance\"), como a [distância Euclidiana](https://en.wikipedia.org/wiki/Euclidean_distance \"Euclidean distance\") ou a [distância Manhattan](https://en.wikipedia.org/wiki/Manhattan_distance \"Manhattan distance\"), que discutimos na [lição anterior](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": [ "Nosso índice é **0,549**, bem no meio. Isso indica que nossos dados não são particularmente adequados para este tipo de agrupamento. Vamos verificar se conseguimos confirmar essa suspeita visualmente. O [pacote factoextra](https://rpkgs.datanovia.com/factoextra/index.html) fornece funções (`fviz_cluster()`) para visualizar agrupamentos.\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": [ "A sobreposição nos clusters indica que nossos dados não são particularmente adequados para esse tipo de agrupamento, mas vamos continuar.\n", "\n", "## 4. Determinando o número ideal de clusters\n", "\n", "Uma pergunta fundamental que frequentemente surge no agrupamento K-Means é esta: sem rótulos de classe conhecidos, como você sabe em quantos clusters deve separar seus dados?\n", "\n", "Uma maneira de tentar descobrir é usar uma amostra de dados para `criar uma série de modelos de agrupamento` com um número crescente de clusters (por exemplo, de 1 a 10) e avaliar métricas de agrupamento, como o **Silhouette score.**\n", "\n", "Vamos determinar o número ideal de clusters calculando o algoritmo de agrupamento para diferentes valores de *k* e avaliando o **Within Cluster Sum of Squares** (WCSS). O total de soma de quadrados dentro dos clusters (WCSS) mede a compacidade do agrupamento, e queremos que ele seja o menor possível, com valores mais baixos indicando que os pontos de dados estão mais próximos.\n", "\n", "Vamos explorar o efeito de diferentes escolhas de `k`, de 1 a 10, nesse agrupamento.\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": [ "Agora que temos o total da soma dos quadrados dentro dos clusters (tot.withinss) para cada algoritmo de agrupamento com centro *k*, usamos o [método do cotovelo](https://en.wikipedia.org/wiki/Elbow_method_(clustering)) para encontrar o número ideal de clusters. O método consiste em plotar o WCSS como uma função do número de clusters e escolher o [cotovelo da curva](https://en.wikipedia.org/wiki/Elbow_of_the_curve \"Elbow of the curve\") como o número de clusters a ser utilizado.\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": [ "O gráfico mostra uma grande redução no WCSS (ou seja, maior *coerência*) à medida que o número de clusters aumenta de um para dois, e uma redução adicional perceptível de dois para três clusters. Depois disso, a redução é menos acentuada, resultando em um `cotovelo` 💪 no gráfico em torno de três clusters. Isso é uma boa indicação de que há dois a três clusters de pontos de dados razoavelmente bem separados.\n", "\n", "Agora podemos prosseguir e extrair o modelo de clustering onde `k = 3`:\n", "\n", "> `pull()`: usado para extrair uma única coluna\n", ">\n", "> `pluck()`: usado para indexar estruturas de dados como listas\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": [ "Ótimo! Vamos visualizar os clusters obtidos. Que tal adicionar um pouco de interatividade usando `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": [ "Talvez esperássemos que cada cluster (representado por cores diferentes) tivesse gêneros distintos (representados por formas diferentes).\n", "\n", "Vamos dar uma olhada na precisão do modelo.\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": [ "A precisão deste modelo não é ruim, mas também não é excelente. Pode ser que os dados não sejam adequados para o agrupamento K-Means. Esses dados são muito desequilibrados, pouco correlacionados e há muita variância entre os valores das colunas para formar bons clusters. Na verdade, os clusters que se formam provavelmente são fortemente influenciados ou distorcidos pelas três categorias de gênero que definimos acima.\n", "\n", "Mesmo assim, foi um processo de aprendizado interessante!\n", "\n", "Na documentação do Scikit-learn, você pode ver que um modelo como este, com clusters não muito bem definidos, apresenta um problema de 'variância':\n", "\n", "

\n", " \n", "

Infográfico do Scikit-learn
\n", "\n", "\n", "\n", "## **Variância**\n", "\n", "Variância é definida como \"a média das diferenças quadradas em relação à média\" [fonte](https://www.mathsisfun.com/data/standard-deviation.html). No contexto deste problema de agrupamento, refere-se aos dados cujos números do nosso conjunto tendem a divergir um pouco demais da média.\n", "\n", "✅ Este é um ótimo momento para pensar em todas as maneiras de corrigir esse problema. Ajustar os dados um pouco mais? Usar colunas diferentes? Utilizar um algoritmo diferente? Dica: Experimente [escalar seus dados](https://www.mygreatlearning.com/blog/learning-data-science-with-k-means-clustering/) para normalizá-los e testar outras colunas.\n", "\n", "> Experimente este '[calculador de variância](https://www.calculatorsoup.com/calculators/statistics/variance-calculator.php)' para entender melhor o conceito.\n", "\n", "------------------------------------------------------------------------\n", "\n", "## **🚀Desafio**\n", "\n", "Dedique algum tempo a este notebook, ajustando os parâmetros. Você consegue melhorar a precisão do modelo limpando mais os dados (removendo outliers, por exemplo)? Você pode usar pesos para dar mais importância a determinadas amostras de dados. O que mais você pode fazer para criar clusters melhores?\n", "\n", "Dica: Experimente escalar seus dados. Há código comentado no notebook que adiciona escalonamento padrão para fazer com que as colunas de dados se assemelhem mais em termos de intervalo. Você verá que, embora a pontuação de silhueta diminua, o 'cotovelo' no gráfico suaviza. Isso ocorre porque deixar os dados sem escala permite que dados com menos variância tenham mais peso. Leia mais sobre esse problema [aqui](https://stats.stackexchange.com/questions/21222/are-mean-normalization-and-feature-scaling-needed-for-k-means-clustering/21226#21226).\n", "\n", "## [**Quiz pós-aula**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/30/)\n", "\n", "## **Revisão e Autoestudo**\n", "\n", "- Dê uma olhada em um simulador de K-Means [como este](https://user.ceng.metu.edu.tr/~akifakkus/courses/ceng574/k-means/). Você pode usar esta ferramenta para visualizar pontos de dados de amostra e determinar seus centróides. Você pode editar a aleatoriedade dos dados, o número de clusters e o número de centróides. Isso ajuda você a ter uma ideia de como os dados podem ser agrupados?\n", "\n", "- Além disso, confira [este material sobre K-Means](https://stanford.edu/~cpiech/cs221/handouts/kmeans.html) de Stanford.\n", "\n", "Quer testar suas habilidades recém-adquiridas de agrupamento em conjuntos de dados que se adaptam bem ao K-Means? Veja:\n", "\n", "- [Treine e avalie modelos de agrupamento](https://rpubs.com/eR_ic/clustering) usando Tidymodels e amigos\n", "\n", "- [Análise de Cluster K-Means](https://uc-r.github.io/kmeans_clustering), Guia de Programação R para Análise de Negócios da UC\n", "\n", "- [Agrupamento K-Means com princípios de dados organizados](https://www.tidymodels.org/learn/statistics/k-means/)\n", "\n", "## **Tarefa**\n", "\n", "[Experimente diferentes métodos de agrupamento](https://github.com/microsoft/ML-For-Beginners/blob/main/5-Clustering/2-K-Means/assignment.md)\n", "\n", "## AGRADECIMENTOS A:\n", "\n", "[Jen Looper](https://www.twitter.com/jenlooper) por criar a versão original em Python deste módulo ♥️\n", "\n", "[`Allison Horst`](https://twitter.com/allison_horst/) por criar as ilustrações incríveis que tornam o R mais acolhedor e envolvente. Encontre mais ilustrações em sua [galeria](https://www.google.com/url?q=https://github.com/allisonhorst/stats-illustrations&sa=D&source=editors&ust=1626380772530000&usg=AOvVaw3zcfyCizFQZpkSLzxiiQEM).\n", "\n", "Feliz aprendizado,\n", "\n", "[Eric](https://twitter.com/ericntay), Embaixador Estudante Gold da Microsoft Learn.\n", "\n", "

\n", " \n", "

Arte por @allison_horst
\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n---\n\n**Aviso Legal**: \nEste documento foi traduzido utilizando o serviço de tradução por IA [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos esforcemos para garantir a precisão, esteja ciente de que traduções automáticas podem conter erros ou imprecisões. O documento original em seu idioma nativo deve ser considerado a fonte oficial. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações equivocadas decorrentes do uso desta tradução.\n" ] } ] }