{ "cells": [ { "cell_type": "markdown", "source": [ "## **Música Nigeriana extraída do Spotify - uma análise**\n", "\n", "Clustering é um tipo de [Aprendizagem Não Supervisionada](https://wikipedia.org/wiki/Unsupervised_learning) que parte do pressuposto de que um conjunto de dados não está rotulado ou que suas entradas não estão associadas a saídas predefinidas. Ele utiliza vários algoritmos para analisar dados não rotulados e fornecer agrupamentos com base nos padrões identificados nos dados.\n", "\n", "[**Questionário pré-aula**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/27/)\n", "\n", "### **Introdução**\n", "\n", "[Clustering](https://link.springer.com/referenceworkentry/10.1007%2F978-0-387-30164-8_124) é muito útil para explorar dados. Vamos ver se ele pode ajudar a descobrir tendências e padrões no modo como o público nigeriano consome música.\n", "\n", "> ✅ Reserve um minuto para pensar sobre os usos do clustering. Na vida real, clustering acontece sempre que você tem uma pilha de roupa suja e precisa separar as roupas dos membros da sua família 🧦👕👖🩲. Na ciência de dados, clustering ocorre ao tentar analisar as preferências de um usuário ou determinar as características de qualquer conjunto de dados não rotulado. Clustering, de certa forma, ajuda a dar sentido ao caos, como uma gaveta de meias.\n", "\n", "No ambiente profissional, clustering pode ser usado para determinar coisas como segmentação de mercado, identificando quais faixas etárias compram determinados itens, por exemplo. Outro uso seria a detecção de anomalias, talvez para identificar fraudes em um conjunto de dados de transações com cartão de crédito. Ou você pode usar clustering para identificar tumores em um lote de exames médicos.\n", "\n", "✅ Pense por um momento sobre como você pode ter encontrado clustering 'na prática', em um contexto bancário, de e-commerce ou empresarial.\n", "\n", "> 🎓 Curiosamente, a análise de clusters teve origem nos campos de Antropologia e Psicologia na década de 1930. Consegue imaginar como ela pode ter sido utilizada?\n", "\n", "Alternativamente, você poderia usá-lo para agrupar resultados de pesquisa - por links de compras, imagens ou avaliações, por exemplo. Clustering é útil quando você tem um grande conjunto de dados que deseja reduzir e sobre o qual deseja realizar uma análise mais detalhada, então a técnica pode ser usada para aprender sobre os dados antes de construir outros modelos.\n", "\n", "✅ Uma vez que seus dados estejam organizados em clusters, você atribui a eles um Id de cluster, e essa técnica pode ser útil para preservar a privacidade de um conjunto de dados; você pode, em vez disso, referir-se a um ponto de dados pelo seu Id de cluster, em vez de por dados identificáveis mais reveladores. Consegue pensar em outros motivos pelos quais você preferiria usar um Id de cluster em vez de outros elementos do cluster para identificá-lo?\n", "\n", "### Começando com clustering\n", "\n", "> 🎓 A forma como criamos clusters tem muito a ver com a maneira como agrupamos os pontos de dados. Vamos explorar alguns termos:\n", ">\n", "> 🎓 ['Transdutivo' vs. 'indutivo'](https://wikipedia.org/wiki/Transduction_(machine_learning))\n", ">\n", "> Inferência transdutiva é derivada de casos de treinamento observados que mapeiam para casos de teste específicos. Inferência indutiva é derivada de casos de treinamento que mapeiam para regras gerais que só então são aplicadas aos casos de teste.\n", ">\n", "> Um exemplo: Imagine que você tem um conjunto de dados parcialmente rotulado. Alguns itens são 'discos', outros 'CDs', e alguns estão em branco. Sua tarefa é fornecer rótulos para os itens em branco. Se você escolher uma abordagem indutiva, treinaria um modelo procurando por 'discos' e 'CDs' e aplicaria esses rótulos aos dados não rotulados. Essa abordagem teria dificuldade em classificar itens que na verdade são 'cassetes'. Uma abordagem transdutiva, por outro lado, lida com esses dados desconhecidos de forma mais eficaz, agrupando itens semelhantes e aplicando um rótulo ao grupo. Nesse caso, os clusters poderiam refletir 'coisas musicais redondas' e 'coisas musicais quadradas'.\n", ">\n", "> 🎓 ['Geometria plana' vs. 'não plana'](https://datascience.stackexchange.com/questions/52260/terminology-flat-geometry-in-the-context-of-clustering)\n", ">\n", "> Derivado da terminologia matemática, geometria plana vs. não plana refere-se à medida de distâncias entre pontos por métodos geométricos 'planos' ([Euclidianos](https://wikipedia.org/wiki/Euclidean_geometry)) ou 'não planos' (não Euclidianos).\n", ">\n", "> 'Plano' neste contexto refere-se à geometria Euclidiana (partes da qual são ensinadas como geometria 'plana'), e 'não plano' refere-se à geometria não Euclidiana. O que a geometria tem a ver com aprendizado de máquina? Bem, como dois campos que têm raízes na matemática, deve haver uma maneira comum de medir distâncias entre pontos em clusters, e isso pode ser feito de forma 'plana' ou 'não plana', dependendo da natureza dos dados. [Distâncias Euclidianas](https://wikipedia.org/wiki/Euclidean_distance) são medidas como o comprimento de um segmento de linha entre dois pontos. [Distâncias não Euclidianas](https://wikipedia.org/wiki/Non-Euclidean_geometry) são medidas ao longo de uma curva. Se seus dados, visualizados, parecem não existir em um plano, você pode precisar usar um algoritmo especializado para lidar com eles.\n", "\n", "

\n", " \n", "

Infográfico por Dasani Madipalli
\n", "\n", "\n", "\n", "> 🎓 ['Distâncias'](https://web.stanford.edu/class/cs345a/slides/12-clustering.pdf)\n", ">\n", "> Clusters são definidos por sua matriz de distâncias, ou seja, as distâncias entre pontos. Essa distância pode ser medida de algumas maneiras. Clusters Euclidianos são definidos pela média dos valores dos pontos e contêm um 'centroide' ou ponto central. As distâncias são medidas pela distância até esse centroide. Distâncias não Euclidianas referem-se a 'clustroids', o ponto mais próximo de outros pontos. Clustroids, por sua vez, podem ser definidos de várias maneiras.\n", ">\n", "> 🎓 ['Com restrições'](https://wikipedia.org/wiki/Constrained_clustering)\n", ">\n", "> [Clustering com restrições](https://web.cs.ucdavis.edu/~davidson/Publications/ICDMTutorial.pdf) introduz aprendizado 'semi-supervisionado' neste método não supervisionado. As relações entre pontos são marcadas como 'não pode vincular' ou 'deve vincular', então algumas regras são impostas ao conjunto de dados.\n", ">\n", "> Um exemplo: Se um algoritmo é liberado em um lote de dados não rotulados ou semi-rotulados, os clusters que ele produz podem ser de baixa qualidade. No exemplo acima, os clusters podem agrupar 'coisas musicais redondas', 'coisas musicais quadradas', 'coisas triangulares' e 'biscoitos'. Se forem dadas algumas restrições ou regras para seguir (\"o item deve ser feito de plástico\", \"o item precisa ser capaz de produzir música\"), isso pode ajudar a 'restringir' o algoritmo para fazer escolhas melhores.\n", ">\n", "> 🎓 'Densidade'\n", ">\n", "> Dados que são 'ruidosos' são considerados 'densos'. As distâncias entre pontos em cada um de seus clusters podem, ao serem examinadas, ser mais ou menos densas, ou 'aglomeradas', e assim esses dados precisam ser analisados com o método de clustering apropriado. [Este artigo](https://www.kdnuggets.com/2020/02/understanding-density-based-clustering.html) demonstra a diferença entre usar clustering K-Means e algoritmos HDBSCAN para explorar um conjunto de dados ruidoso com densidade de cluster desigual.\n", "\n", "Aprofunde seu entendimento sobre técnicas de clustering neste [módulo de aprendizado](https://docs.microsoft.com/learn/modules/train-evaluate-cluster-models?WT.mc_id=academic-77952-leestott)\n", "\n", "### **Algoritmos de clustering**\n", "\n", "Existem mais de 100 algoritmos de clustering, e seu uso depende da natureza dos dados em questão. Vamos discutir alguns dos principais:\n", "\n", "- **Clustering hierárquico**. Se um objeto é classificado pela sua proximidade a um objeto próximo, em vez de um mais distante, os clusters são formados com base na distância entre seus membros. O clustering hierárquico é caracterizado pela combinação repetida de dois clusters.\n", "\n", "\n", "

\n", " \n", "

Infográfico por Dasani Madipalli
\n", "\n", "\n", "\n", "- **Clustering por centroide**. Este algoritmo popular requer a escolha de 'k', ou o número de clusters a serem formados, após o qual o algoritmo determina o ponto central de um cluster e reúne dados ao redor desse ponto. [Clustering K-means](https://wikipedia.org/wiki/K-means_clustering) é uma versão popular de clustering por centroide que separa um conjunto de dados em K grupos predefinidos. O centro é determinado pela média mais próxima, daí o nome. A distância quadrada do cluster é minimizada.\n", "\n", "

\n", " \n", "

Infográfico por Dasani Madipalli
\n", "\n", "\n", "\n", "- **Clustering baseado em distribuição**. Baseado em modelagem estatística, o clustering baseado em distribuição centra-se em determinar a probabilidade de um ponto de dados pertencer a um cluster e atribuí-lo de acordo. Métodos de mistura Gaussiana pertencem a este tipo.\n", "\n", "- **Clustering baseado em densidade**. Pontos de dados são atribuídos a clusters com base na sua densidade, ou no agrupamento ao redor uns dos outros. Pontos de dados distantes do grupo são considerados outliers ou ruído. DBSCAN, Mean-shift e OPTICS pertencem a este tipo de clustering.\n", "\n", "- **Clustering baseado em grade**. Para conjuntos de dados multidimensionais, uma grade é criada e os dados são divididos entre as células da grade, criando assim clusters.\n", "\n", "A melhor maneira de aprender sobre clustering é experimentá-lo você mesmo, e é isso que você fará neste exercício.\n", "\n", "Vamos precisar de alguns pacotes para concluir este módulo. Você pode instalá-los com: `install.packages(c('tidyverse', 'tidymodels', 'DataExplorer', 'summarytools', 'plotly', 'paletteer', 'corrplot', 'patchwork'))`\n", "\n", "Alternativamente, o script abaixo verifica se você tem os pacotes necessários para completar este módulo e os instala para você caso algum esteja faltando.\n" ], "metadata": {} }, { "cell_type": "code", "execution_count": null, "source": [ "suppressWarnings(if(!require(\"pacman\")) install.packages(\"pacman\"))\r\n", "\r\n", "pacman::p_load('tidyverse', 'tidymodels', 'DataExplorer', 'summarytools', 'plotly', 'paletteer', 'corrplot', 'patchwork')\r\n" ], "outputs": [], "metadata": {} }, { "cell_type": "markdown", "source": [ "## Exercício - agrupe os seus dados\n", "\n", "O clustering como técnica é muito beneficiado por uma boa visualização, por isso vamos começar por visualizar os nossos dados de música. Este exercício vai ajudar-nos a decidir qual dos métodos de clustering devemos usar de forma mais eficaz, tendo em conta a natureza destes dados.\n", "\n", "Vamos começar rapidamente importando os dados.\n" ], "metadata": {} }, { "cell_type": "code", "execution_count": null, "source": [ "# Load the core tidyverse and make it available in your current R session\r\n", "library(tidyverse)\r\n", "\r\n", "# Import the data into a tibble\r\n", "df <- read_csv(file = \"https://raw.githubusercontent.com/microsoft/ML-For-Beginners/main/5-Clustering/data/nigerian-songs.csv\")\r\n", "\r\n", "# View the first 5 rows of the data set\r\n", "df %>% \r\n", " slice_head(n = 5)\r\n" ], "outputs": [], "metadata": {} }, { "cell_type": "markdown", "source": [ "Às vezes, podemos querer um pouco mais de informação sobre os nossos dados. Podemos observar os `dados` e a `sua estrutura` utilizando a função [*glimpse()*](https://pillar.r-lib.org/reference/glimpse.html):\n" ], "metadata": {} }, { "cell_type": "code", "execution_count": null, "source": [ "# Glimpse into the data set\r\n", "df %>% \r\n", " glimpse()\r\n" ], "outputs": [], "metadata": {} }, { "cell_type": "markdown", "source": [ "Bom trabalho!💪\n", "\n", "Podemos observar que `glimpse()` fornece o número total de linhas (observações) e colunas (variáveis), seguido pelas primeiras entradas de cada variável numa linha após o nome da variável. Além disso, o *tipo de dados* da variável é apresentado imediatamente após o nome da variável dentro de `< >`.\n", "\n", "`DataExplorer::introduce()` pode resumir esta informação de forma organizada:\n" ], "metadata": {} }, { "cell_type": "code", "execution_count": null, "source": [ "# Describe basic information for our data\r\n", "df %>% \r\n", " introduce()\r\n", "\r\n", "# A visual display of the same\r\n", "df %>% \r\n", " plot_intro()\r\n" ], "outputs": [], "metadata": {} }, { "cell_type": "markdown", "source": [ "Fantástico! Acabámos de descobrir que os nossos dados não têm valores em falta.\n", "\n", "Enquanto estamos nisto, podemos explorar estatísticas comuns de tendência central (por exemplo, [média](https://en.wikipedia.org/wiki/Arithmetic_mean) e [mediana](https://en.wikipedia.org/wiki/Median)) e medidas de dispersão (por exemplo, [desvio padrão](https://en.wikipedia.org/wiki/Standard_deviation)) utilizando `summarytools::descr()`\n" ], "metadata": {} }, { "cell_type": "code", "execution_count": null, "source": [ "# Describe common statistics\r\n", "df %>% \r\n", " descr(stats = \"common\")\r\n" ], "outputs": [], "metadata": {} }, { "cell_type": "markdown", "source": [ "Vamos analisar os valores gerais dos dados. Note que a popularidade pode ser `0`, o que indica músicas que não têm classificação. Vamos removê-las em breve.\n", "\n", "> 🤔 Se estamos a trabalhar com clustering, um método não supervisionado que não requer dados rotulados, por que estamos a mostrar estes dados com rótulos? Na fase de exploração de dados, eles são úteis, mas não são necessários para que os algoritmos de clustering funcionem.\n", "\n", "### 1. Explorar géneros populares\n", "\n", "Vamos descobrir os géneros mais populares 🎶 contando o número de vezes que aparecem.\n" ], "metadata": {} }, { "cell_type": "code", "execution_count": null, "source": [ "# Popular genres\r\n", "top_genres <- df %>% \r\n", " count(artist_top_genre, sort = TRUE) %>% \r\n", "# Encode to categorical and reorder the according to count\r\n", " mutate(artist_top_genre = factor(artist_top_genre) %>% fct_inorder())\r\n", "\r\n", "# Print the top genres\r\n", "top_genres\r\n" ], "outputs": [], "metadata": {} }, { "cell_type": "markdown", "source": [ "Isso correu bem! Dizem que uma imagem vale mais do que mil linhas de um data frame (na verdade, ninguém diz isso 😅). Mas percebes a ideia, certo?\n", "\n", "Uma forma de visualizar dados categóricos (variáveis de texto ou fatores) é utilizando gráficos de barras. Vamos criar um gráfico de barras com os 10 géneros principais:\n" ], "metadata": {} }, { "cell_type": "code", "execution_count": null, "source": [ "# Change the default gray theme\r\n", "theme_set(theme_light())\r\n", "\r\n", "# Visualize popular genres\r\n", "top_genres %>%\r\n", " slice(1:10) %>% \r\n", " ggplot(mapping = aes(x = artist_top_genre, y = n,\r\n", " fill = artist_top_genre)) +\r\n", " geom_col(alpha = 0.8) +\r\n", " paletteer::scale_fill_paletteer_d(\"rcartocolor::Vivid\") +\r\n", " ggtitle(\"Top genres\") +\r\n", " theme(plot.title = element_text(hjust = 0.5),\r\n", " # Rotates the X markers (so we can read them)\r\n", " axis.text.x = element_text(angle = 90))\r\n" ], "outputs": [], "metadata": {} }, { "cell_type": "markdown", "source": [ "Agora é muito mais fácil identificar que temos géneros `missing` 🧐!\n", "\n", "> Uma boa visualização irá mostrar-lhe coisas que não esperava ou levantar novas questões sobre os dados - Hadley Wickham e Garrett Grolemund, [R For Data Science](https://r4ds.had.co.nz/introduction.html)\n", "\n", "Nota: quando o género principal é descrito como `Missing`, isso significa que o Spotify não o classificou, por isso vamos eliminá-lo.\n" ], "metadata": {} }, { "cell_type": "code", "execution_count": null, "source": [ "# Visualize popular genres\r\n", "top_genres %>%\r\n", " filter(artist_top_genre != \"Missing\") %>% \r\n", " slice(1:10) %>% \r\n", " ggplot(mapping = aes(x = artist_top_genre, y = n,\r\n", " fill = artist_top_genre)) +\r\n", " geom_col(alpha = 0.8) +\r\n", " paletteer::scale_fill_paletteer_d(\"rcartocolor::Vivid\") +\r\n", " ggtitle(\"Top genres\") +\r\n", " theme(plot.title = element_text(hjust = 0.5),\r\n", " # Rotates the X markers (so we can read them)\r\n", " axis.text.x = element_text(angle = 90))\r\n" ], "outputs": [], "metadata": {} }, { "cell_type": "markdown", "source": [ "A partir da pequena exploração de dados, aprendemos que os três géneros principais dominam este conjunto de dados. Vamos concentrar-nos em `afro dancehall`, `afropop` e `nigerian pop`, e adicionalmente filtrar o conjunto de dados para remover qualquer entrada com um valor de popularidade igual a 0 (o que significa que não foi classificada com uma popularidade no conjunto de dados e pode ser considerada ruído para os nossos propósitos):\n" ], "metadata": {} }, { "cell_type": "code", "execution_count": null, "source": [ "nigerian_songs <- df %>% \r\n", " # Concentrate on top 3 genres\r\n", " filter(artist_top_genre %in% c(\"afro dancehall\", \"afropop\",\"nigerian pop\")) %>% \r\n", " # Remove unclassified observations\r\n", " filter(popularity != 0)\r\n", "\r\n", "\r\n", "\r\n", "# Visualize popular genres\r\n", "nigerian_songs %>%\r\n", " count(artist_top_genre) %>%\r\n", " ggplot(mapping = aes(x = artist_top_genre, y = n,\r\n", " fill = artist_top_genre)) +\r\n", " geom_col(alpha = 0.8) +\r\n", " paletteer::scale_fill_paletteer_d(\"ggsci::category10_d3\") +\r\n", " ggtitle(\"Top genres\") +\r\n", " theme(plot.title = element_text(hjust = 0.5))\r\n" ], "outputs": [], "metadata": {} }, { "cell_type": "markdown", "source": [ "Vamos verificar se existe alguma relação linear aparente entre as variáveis numéricas no nosso conjunto de dados. Esta relação é quantificada matematicamente pelo [estatístico de correlação](https://en.wikipedia.org/wiki/Correlation).\n", "\n", "O estatístico de correlação é um valor entre -1 e 1 que indica a força de uma relação. Valores acima de 0 indicam uma correlação *positiva* (valores altos de uma variável tendem a coincidir com valores altos da outra), enquanto valores abaixo de 0 indicam uma correlação *negativa* (valores altos de uma variável tendem a coincidir com valores baixos da outra).\n" ], "metadata": {} }, { "cell_type": "code", "execution_count": null, "source": [ "# Narrow down to numeric variables and fid correlation\r\n", "corr_mat <- nigerian_songs %>% \r\n", " select(where(is.numeric)) %>% \r\n", " cor()\r\n", "\r\n", "# Visualize correlation matrix\r\n", "corrplot(corr_mat, order = 'AOE', col = c('white', 'black'), bg = 'gold2') \r\n" ], "outputs": [], "metadata": {} }, { "cell_type": "markdown", "source": [ "Os dados não estão fortemente correlacionados, exceto entre `energy` e `loudness`, o que faz sentido, dado que música alta geralmente é bastante energética. `Popularity` tem uma correspondência com `release date`, o que também faz sentido, já que músicas mais recentes provavelmente são mais populares. Comprimento e energia parecem ter uma correlação também.\n", "\n", "Será interessante ver o que um algoritmo de clustering pode fazer com esses dados!\n", "\n", "> 🎓 Note que correlação não implica causalidade! Temos prova de correlação, mas nenhuma prova de causalidade. Um [site divertido](https://tylervigen.com/spurious-correlations) tem alguns visuais que enfatizam este ponto.\n", "\n", "### 2. Explorar a distribuição dos dados\n", "\n", "Vamos fazer perguntas mais subtis. Os géneros são significativamente diferentes na perceção da sua capacidade de dança, com base na sua popularidade? Vamos examinar a distribuição dos dados dos nossos três principais géneros em relação à popularidade e capacidade de dança ao longo de um eixo x e y usando [gráficos de densidade](https://www.khanacademy.org/math/ap-statistics/density-curves-normal-distribution-ap/density-curves/v/density-curves).\n" ], "metadata": {} }, { "cell_type": "code", "execution_count": null, "source": [ "# Perform 2D kernel density estimation\r\n", "density_estimate_2d <- nigerian_songs %>% \r\n", " ggplot(mapping = aes(x = popularity, y = danceability, color = artist_top_genre)) +\r\n", " geom_density_2d(bins = 5, size = 1) +\r\n", " paletteer::scale_color_paletteer_d(\"RSkittleBrewer::wildberry\") +\r\n", " xlim(-20, 80) +\r\n", " ylim(0, 1.2)\r\n", "\r\n", "# Density plot based on the popularity\r\n", "density_estimate_pop <- nigerian_songs %>% \r\n", " ggplot(mapping = aes(x = popularity, fill = artist_top_genre, color = artist_top_genre)) +\r\n", " geom_density(size = 1, alpha = 0.5) +\r\n", " paletteer::scale_fill_paletteer_d(\"RSkittleBrewer::wildberry\") +\r\n", " paletteer::scale_color_paletteer_d(\"RSkittleBrewer::wildberry\") +\r\n", " theme(legend.position = \"none\")\r\n", "\r\n", "# Density plot based on the danceability\r\n", "density_estimate_dance <- nigerian_songs %>% \r\n", " ggplot(mapping = aes(x = danceability, fill = artist_top_genre, color = artist_top_genre)) +\r\n", " geom_density(size = 1, alpha = 0.5) +\r\n", " paletteer::scale_fill_paletteer_d(\"RSkittleBrewer::wildberry\") +\r\n", " paletteer::scale_color_paletteer_d(\"RSkittleBrewer::wildberry\")\r\n", "\r\n", "\r\n", "# Patch everything together\r\n", "library(patchwork)\r\n", "density_estimate_2d / (density_estimate_pop + density_estimate_dance)\r\n" ], "outputs": [], "metadata": {} }, { "cell_type": "markdown", "source": [ "Observamos que há círculos concêntricos que se alinham, independentemente do género. Será que os gostos nigerianos convergem a um certo nível de dançabilidade para este género?\n", "\n", "De forma geral, os três géneros alinham-se em termos de popularidade e dançabilidade. Determinar agrupamentos nestes dados pouco alinhados será um desafio. Vamos ver se um gráfico de dispersão pode ajudar nisso.\n" ], "metadata": {} }, { "cell_type": "code", "execution_count": null, "source": [ "# A scatter plot of popularity and danceability\r\n", "scatter_plot <- nigerian_songs %>% \r\n", " ggplot(mapping = aes(x = popularity, y = danceability, color = artist_top_genre, shape = artist_top_genre)) +\r\n", " geom_point(size = 2, alpha = 0.8) +\r\n", " paletteer::scale_color_paletteer_d(\"futurevisions::mars\")\r\n", "\r\n", "# Add a touch of interactivity\r\n", "ggplotly(scatter_plot)\r\n" ], "outputs": [], "metadata": {} }, { "cell_type": "markdown", "source": [ "Um gráfico de dispersão dos mesmos eixos mostra um padrão semelhante de convergência.\n", "\n", "De forma geral, para clustering, pode-se usar gráficos de dispersão para mostrar agrupamentos de dados, por isso dominar este tipo de visualização é muito útil. Na próxima lição, vamos pegar estes dados filtrados e usar o clustering k-means para descobrir grupos neste conjunto de dados que parecem se sobrepor de maneiras interessantes.\n", "\n", "## **🚀 Desafio**\n", "\n", "Em preparação para a próxima lição, crie um gráfico sobre os vários algoritmos de clustering que pode descobrir e usar num ambiente de produção. Que tipos de problemas o clustering está tentando resolver?\n", "\n", "## [**Questionário pós-aula**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/28/)\n", "\n", "## **Revisão e Estudo Individual**\n", "\n", "Antes de aplicar algoritmos de clustering, como aprendemos, é uma boa ideia entender a natureza do seu conjunto de dados. Leia mais sobre este tópico [aqui](https://www.kdnuggets.com/2019/10/right-clustering-algorithm.html).\n", "\n", "Aprofunde o seu entendimento sobre técnicas de clustering:\n", "\n", "- [Treinar e Avaliar Modelos de Clustering usando Tidymodels e amigos](https://rpubs.com/eR_ic/clustering)\n", "\n", "- Bradley Boehmke & Brandon Greenwell, [*Hands-On Machine Learning with R*](https://bradleyboehmke.github.io/HOML/)*.*\n", "\n", "## **Tarefa**\n", "\n", "[Investigue outras visualizações para clustering](https://github.com/microsoft/ML-For-Beginners/blob/main/5-Clustering/1-Visualize/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", "[`Dasani Madipalli`](https://twitter.com/dasani_decoded) por criar as ilustrações incríveis que tornam os conceitos de machine learning mais interpretáveis e fáceis de entender.\n", "\n", "Boas aprendizagens,\n", "\n", "[Eric](https://twitter.com/ericntay), Gold Microsoft Learn Student Ambassador.\n" ], "metadata": {} }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n---\n\n**Aviso**: \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 pela precisão, esteja ciente de 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 uma 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" ] } ], "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" }, "coopTranslator": { "original_hash": "99c36449cad3708a435f6798cfa39972", "translation_date": "2025-09-03T20:06:44+00:00", "source_file": "5-Clustering/1-Visualize/solution/R/lesson_14-R.ipynb", "language_code": "pt" } }, "nbformat": 4, "nbformat_minor": 1 }