{ "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-03T20:16:16+00:00", "source_file": "5-Clustering/2-K-Means/solution/R/lesson_15-R.ipynb", "language_code": "pt" } }, "cells": [ { "cell_type": "markdown", "metadata": { "id": "GULATlQXLXyR" }, "source": [ "## Explore K-Means clustering usando R e princípios de dados organizados.\n", "\n", "### [**Questionário pré-aula**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/29/)\n", "\n", "Nesta lição, vais aprender a criar clusters utilizando o pacote Tidymodels e outros pacotes do ecossistema R (vamos chamá-los de amigos 🧑‍🤝‍🧑), e o conjunto de dados de música nigeriana que importaste anteriormente. Vamos abordar os fundamentos do K-Means para Clustering. Lembra-te de que, como aprendeste na lição anterior, existem várias formas de trabalhar com clusters e o método que utilizas depende dos teus dados. Vamos experimentar o K-Means, pois é a técnica de clustering mais comum. Vamos começar!\n", "\n", "Termos que vais aprender:\n", "\n", "- Pontuação de Silhueta\n", "\n", "- Método do Cotovelo\n", "\n", "- Inércia\n", "\n", "- Variância\n", "\n", "### **Introdução**\n", "\n", "[K-Means Clustering](https://wikipedia.org/wiki/K-means_clustering) é um método derivado do domínio do processamento de sinais. É utilizado para dividir e agrupar conjuntos de dados em `k clusters` com base em semelhanças nas suas características.\n", "\n", "Os clusters podem ser visualizados como [Diagramas de Voronoi](https://wikipedia.org/wiki/Voronoi_diagram), que incluem um ponto (ou 'semente') e a sua região correspondente.\n", "\n", "

\n", " \n", "

Infográfico por Jen Looper
\n", "\n", "\n", "O clustering K-Means segue os seguintes passos:\n", "\n", "1. O cientista de dados começa por especificar o número desejado de clusters 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 clusters (ou seja, os centróides).\n", "\n", "3. Depois, cada uma das observações restantes é atribuída ao centróide mais próximo.\n", "\n", "4. A seguir, a nova média de cada cluster é calculada e o centróide é movido para essa média.\n", "\n", "5. Agora que os centros foram recalculados, cada observação é novamente verificada para ver se pode estar mais próxima de um cluster diferente. Todos os objetos são novamente reatribuídos utilizando as médias atualizadas dos clusters. Os passos de atribuição de clusters e atualização dos centróides são repetidos iterativamente até que as atribuições de clusters deixem de mudar (ou seja, quando se alcança a convergência). Normalmente, o algoritmo termina quando cada nova iteração resulta em um movimento insignificante dos centróides e os clusters tornam-se estáticos.\n", "\n", "
\n", "\n", "> Nota que, devido à randomização das observações iniciais k utilizadas como centróides iniciais, podemos obter resultados ligeiramente diferentes cada vez que aplicamos o procedimento. Por esta razão, a maioria dos algoritmos utiliza vários *inícios aleatórios* e escolhe a iteração com o menor WCSS. Assim, é fortemente recomendado executar o K-Means com vários valores de *nstart* para evitar um *ótimo local indesejável.*\n", "\n", "
\n", "\n", "Esta curta animação utilizando a [arte](https://github.com/allisonhorst/stats-illustrations) de Allison Horst explica o processo de clustering:\n", "\n", "

\n", " \n", "

Arte por @allison_horst
\n", "\n", "\n", "\n", "Uma questão fundamental que surge no clustering é esta: como sabes quantos clusters deves separar nos teus dados? Uma desvantagem do uso do K-Means é o facto de que precisas de 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`. Vais experimentá-lo em breve.\n", "\n", "### \n", "\n", "**Pré-requisito**\n", "\n", "Vamos começar exatamente de onde parámos na [lição anterior](https://github.com/microsoft/ML-For-Beginners/blob/main/5-Clustering/1-Visualize/solution/R/lesson_14-R.ipynb), onde analisámos o conjunto de dados, fizemos várias visualizações e filtrámos o conjunto de dados para observações de interesse. Certifica-te de que o revisitas!\n", "\n", "Vamos precisar de alguns pacotes para completar este módulo. Podes instalá-los com: `install.packages(c('tidyverse', 'tidymodels', 'cluster', 'summarytools', 'plotly', 'paletteer', 'factoextra', 'patchwork'))`\n", "\n", "Alternativamente, o script abaixo verifica se tens os pacotes necessários para completar este módulo e instala-os para ti caso alguns estejam em falta.\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: Reduzir aos 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 correu bem!\n", "\n", "## 2. Mais exploração de dados.\n", "\n", "Quão limpos estão estes dados? Vamos verificar a existência de valores atípicos utilizando boxplots. Vamos concentrar-nos em colunas numéricas com menos valores atípicos (embora seja possível limpar os valores atípicos). Os boxplots podem mostrar o intervalo dos dados e ajudar a escolher quais colunas usar. Note 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 por *selecionar* todas as colunas numéricas juntamente 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 auxiliar de seleção `where` torna isso fácil 💁? 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 os nossos dados para um formato *mais longo* que nos permitirá tirar proveito de `facets` - subgráficos que exibem cada 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, que `geom` vamos usar?\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": [ "Agora podemos ver que estes dados estão um pouco ruidosos: ao observar cada coluna como um boxplot, é possível identificar valores atípicos. Poderíamos percorrer o conjunto de dados e remover esses valores atípicos, mas isso tornaria os dados bastante reduzidos.\n", "\n", "Por agora, vamos escolher quais colunas utilizaremos para o nosso exercício de clustering. 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. Computação de clustering k-means em R\n", "\n", "Podemos calcular k-means em R utilizando 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 clustering k-means é especificar o número de clusters (k) que serão gerados na solução final. Sabemos que existem 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 agora, vamos concentrar-nos em algumas. Vemos que os dados foram agrupados em 3 clusters com tamanhos de 65, 110, 111. O resultado também contém os centros dos clusters (médias) para os 3 grupos ao longo das 5 variáveis.\n", "\n", "O vetor de clustering é 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, acabámos de dividir o nosso conjunto de dados em 3 grupos. Então, quão bom é o nosso agrupamento 🤷? 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. Este 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 score médio de silhouette elevado indica um bom agrupamento.\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": [ "A nossa pontuação é **0,549**, ou seja, bem no meio. Isto indica que os nossos dados não são particularmente adequados para este tipo de agrupamento. Vamos ver se conseguimos confirmar esta 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 os nossos dados não são particularmente adequados para este tipo de clustering, mas vamos continuar.\n", "\n", "## 4. Determinar o número ideal de clusters\n", "\n", "Uma questão fundamental que frequentemente surge no clustering K-Means é esta: sem etiquetas de classe conhecidas, como saber quantos clusters usar para separar os seus dados?\n", "\n", "Uma forma de tentar descobrir é usar uma amostra de dados para `criar uma série de modelos de clustering` com um número crescente de clusters (por exemplo, de 1 a 10) e avaliar métricas de clustering como o **Silhouette score.**\n", "\n", "Vamos determinar o número ideal de clusters calculando o algoritmo de clustering para diferentes valores de *k* e avaliando o **Within Cluster Sum of Squares** (WCSS). O total de soma de quadrados dentro do cluster (WCSS) mede a compacidade do clustering, e queremos que seja o menor possível, com valores mais baixos significando 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, neste clustering.\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 clustering com centro *k*, utilizamos 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 traçar 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 \"Cotovelo da curva\") 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 notável de dois para três clusters. Depois disso, a redução torna-se menos acentuada, resultando num `cotovelo` 💪 no gráfico por volta de três clusters. Isto é uma boa indicação de que existem dois a três clusters de pontos de dados razoavelmente bem separados.\n", "\n", "Podemos agora avançar 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 grupo (representado por cores diferentes) tivesse géneros distintos (representados por formas diferentes).\n", "\n", "Vamos analisar a 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 é má, mas também não é excelente. Pode ser que os dados não sejam adequados para o K-Means Clustering. Estes dados são demasiado desequilibrados, pouco correlacionados e há muita variância entre os valores das colunas para formar clusters eficazes. Na verdade, os clusters que se formam provavelmente são fortemente influenciados ou enviesados pelas três categorias de género que definimos acima.\n", "\n", "Ainda assim, foi um processo de aprendizagem interessante!\n", "\n", "Na documentação do Scikit-learn, pode-se ver que um modelo como este, com clusters pouco bem definidos, tem um problema de 'variância':\n", "\n", "

\n", " \n", "

Infográfico do Scikit-learn
\n", "\n", "\n", "\n", "## **Variância**\n", "\n", "A 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 clustering, refere-se aos dados em que os 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 formas de corrigir este problema. Ajustar os dados um pouco mais? Usar colunas diferentes? Utilizar um algoritmo diferente? Dica: Experimente [escalar os 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 compreender melhor o conceito.\n", "\n", "------------------------------------------------------------------------\n", "\n", "## **🚀Desafio**\n", "\n", "Dedique algum tempo a este notebook, ajustando os parâmetros. Consegue melhorar a precisão do modelo ao limpar mais os dados (removendo outliers, por exemplo)? Pode usar pesos para dar mais importância a determinadas amostras de dados. O que mais pode fazer para criar clusters melhores?\n", "\n", "Dica: Experimente escalar os 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. Vai perceber que, embora o score de silhueta diminua, o 'cotovelo' no gráfico suaviza-se. Isto acontece porque deixar os dados sem escala permite que dados com menos variância tenham mais peso. Leia mais sobre este problema [aqui](https://stats.stackexchange.com/questions/21222/are-mean-normalization-and-feature-scaling-needed-for-k-means-clustering/21226#21226).\n", "\n", "## [**Questionário pós-aula**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/30/)\n", "\n", "## **Revisão & Autoestudo**\n", "\n", "- Dê uma olhada num Simulador de K-Means [como este](https://user.ceng.metu.edu.tr/~akifakkus/courses/ceng574/k-means/). Pode usar esta ferramenta para visualizar pontos de dados de amostra e determinar os seus centróides. Pode editar a aleatoriedade dos dados, o número de clusters e o número de centróides. Isto ajuda-o a ter uma ideia de como os dados podem ser agrupados?\n", "\n", "- Além disso, veja [este documento sobre K-Means](https://stanford.edu/~cpiech/cs221/handouts/kmeans.html) da Stanford.\n", "\n", "Quer testar as suas novas competências de clustering em conjuntos de dados que se adaptam bem ao K-Means clustering? Veja:\n", "\n", "- [Treinar e Avaliar Modelos de Clustering](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), UC Business Analytics R Programming Guide\n", "\n", "- [Clustering 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 clustering](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 na sua [galeria](https://www.google.com/url?q=https://github.com/allisonhorst/stats-illustrations&sa=D&source=editors&ust=1626380772530000&usg=AOvVaw3zcfyCizFQZpkSLzxiiQEM).\n", "\n", "Boas aprendizagens,\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, é importante notar que traduções automáticas podem conter erros ou imprecisões. O documento original na sua língua nativa deve ser considerado a fonte autoritária. 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 incorretas decorrentes da utilização desta tradução.\n" ] } ] }