Clusterização com K-means em Python utilizando Elbow Method

Detalhes do projeto

Clustering, também conhecido como agrupamento, refere-se à aplicação de técnicas de machine learning destinadas a dividir um conjunto de dados em diversos clusters ou grupos distintos, tendo como critério principal a semelhança entre os dados.

Em contraste com algoritmos de classificação e regressão, o clustering é uma técnica simples da aprendizagem não supervisionada, uma vez que os algoritmos envolvidos precisam discernir as relações intrínsecas entre os dados, sem depender de rótulos prévios que indiquem a que categoria pertencem.

Por meio de clustering, é possível extrair informações valiosas e insights que muitas vezes não seriam perceptíveis por meio de abordagens de aprendizado supervisionado.

K-means

K-Means é um algoritmo de agrupamento iterativo que busca encontrar centróides ótimos para criar clusters em um conjunto de dados. Ele itera até que os centróides não mudem substancialmente, e nesse ponto, os clusters resultantes são considerados estáveis e representam grupos distintos com base nas semelhanças entre os dados.

fonte: shabal

O algoritmo opera seguindo os seguintes passos:

Inicialização: O algoritmo escolhe aleatoriamente K pontos a partir dos dados, onde K é o número de clusters predefinido como parâmetro. Esses pontos iniciais atuam como os centros dos clusters “provisórios” antes de qualquer ajuste.

Atribuição de Clusters: Cada ponto de dado é avaliado para determinar a sua proximidade ao centróide mais próximo. Isso resulta na divisão dos dados em clusters, onde cada cluster é composto pelos pontos mais próximos ao centróide associado.

Atualização dos Centróides: Os novos valores para os centróides são calculados como a média dos dados contidos em cada cluster. Isso significa que o centro de cada cluster é recalculado com base nos pontos que o compõem.

Iteração: O processo de encontrar centróides e atualizar clusters é repetido. Os centróides são recalculados, os pontos são reatribuídos aos clusters com base na proximidade aos novos centróides e os centróides são novamente atualizados pela média dos pontos do cluster.

Convergência: O algoritmo continua a iterar até que a posição dos centróides não mude mais. Isso indica que os centróides convergiram para suas posições finais e que os clusters estão estáveis.

Este processo é repetido até que os centróides se estabilizem, e os clusters alcancem uma configuração na qual não haja mais alterações significativas.

A abordagem que o algoritmo K-Means segue para resolver o problema é chamada Expectation-Maximization (Expectativa-Maximização). A etapa E é atribuir os pontos de dados ao cluster mais próximo.

A etapa M é calcular o centróide de cada cluster. Abaixo está uma quebra de como podemos resolver isso matematicamente:

A função é:

fonte: Imad Dabbura

Onde wik=1 para o ponto de dados xi se ele pertencer ao cluster k; caso contrário, wik=0. Além disso, μk é o centróide do cluster de xi.

É um problema de minimização de duas partes. Primeiro, minimizamos J com relação a wik e tratamos μk como fixo. Em seguida, minimizamos J com relação a μk e tratamos wik como fixo. Tecnicamente falando, diferenciamos J com relação a wik primeiro e atualizamos as atribuições de cluster (etapa E).

Em seguida, diferenciamos J com relação a μk e recalculamos os centróides após as atribuições de cluster da etapa anterior (etapa M). Portanto, a etapa E é:

fonte: Imad Dabbura

Em outras palavras, atribuimos o ponto de dados xi ao cluster mais próximo, julgado pela soma das distâncias quadradas do centróide do cluster.

E a etapa M é:

fonte: Imad Dabbura

O que se traduz em recalcular o centróide de cada cluster para refletir as novas atribuições.

Elbow method

Simplesmente olhando para os dados em um scatterplot, em alguns casos é possível estimar a olho nu a quantidade de centróides ideal para ser aplicada no conjunto de dados como é possível observar na figura a seguir.

fonte: turing talks

Aqui podemos estimar que o número ideal de centróides seria igual a 5, por causa dos grandes grupos, o que resultaria no seguinte agrupamento:

fonte: turing talks

Porém como podemos saber o número ideal do ponto de vista matemático?

Um passo fundamental para qualquer algoritmo não supervisionado é determinar o número ideal de agrupamentos nos quais os dados podem ser divididos.

Como não temos um número pré-definido de agrupamentos no aprendizado não supervisionado, tendemos a utilizar algum método que nos ajude a decidir o melhor número de agrupamentos. No caso do agrupamento K-Means, usamos o Elbow-Method.

Ele leva esse nome justamente por se assemelhar a um “cotovelo” conforme é possível de se observar na figura abaixo.

O que é o Elbow-Method no Agrupamento K-Means

No algoritmo de agrupamento K-Means, inicializamos aleatoriamente k agrupamentos e ajustamos iterativamente esses k agrupamentos até que os k-centróides alcancem um estado de equilíbrio. No entanto, a coisa principal que fazemos antes de inicializar esses agrupamentos é determinar quantos agrupamentos devemos usar.

Neste método, para determinar o valor de k, iteramos continuamente de k=1 até k=n (onde n é o hiperparâmetro que escolhemos de acordo com nossos requisitos). Para cada valor de k, calculamos o valor da soma dos quadrados dentro do agrupamento (WCSS).

WCSS – É definido como a soma das distâncias quadradas entre os centróides e cada ponto.

Agora, para determinar o melhor número de agrupamentos (k), traçamos um gráfico de k versus o valor de WCSS correspondente.

Além disso, quando k=1, o WCSS tem o valor mais alto, mas, à medida que o valor de k aumenta, o valor do WCSS começa a diminuir. Escolhemos o valor de k observando no gráfico em que ponto ele começa a se assemelhar a uma linha reta.

Construindo uma visualização em Python

Começamos importando as bibliotecas que iremos utilizar. A biblioteca do KMeans do Sklearn, pandas para tratar a base, numpy para os np arrays e matplotlib para a visualização final dos gráficos.

O link do github deste projeto está disponível aqui

from sklearn.cluster import KMeans
from sklearn import metrics
from scipy.spatial.distance import cdist
import numpy as np
import matplotlib.pyplot as plt

O dataset utilizado é o mall_customers.csv disponível no kaggle. Este conjunto de dados foi criado apenas para fins de aprendizado dos conceitos de segmentação de clientes, também conhecido como “análise de cesta de mercado”.

from google.colab import files
files.upload()
df = pd.read_csv ("Mall_Customers.csv")

Usamos essa função para importar o dataset e defini-lo na variável “df”.

Ao imprimir o dataset é possível verificar que ele possui 5 dimensões, mas só preciso utilizar 2 delas que são o salário anual (Annual Income) e o score de gastos (spending score). Então eu vou tratar o dataset aqui mesmo com o pandas.

df = df.drop(columns=['Gender','CustomerID','Age'])
print('Modified DataFrame:\n', df)

Vamos montar agora o código que treina o modelo:

distortions = []
inertias = []
mapping1 = {}
mapping2 = {}
K = range(1, 10)

for k in K:
	# Construindo e treinando o modelo
	kmeanModel = KMeans(n_clusters=k).fit(X)
	kmeanModel.fit(X)

	distortions.append(sum(np.min(cdist(X, kmeanModel.cluster_centers_,
										'euclidean'), axis=1)) / X.shape[0])
	inertias.append(kmeanModel.inertia_)

	mapping1[k] = sum(np.min(cdist(X, kmeanModel.cluster_centers_,
								'euclidean'), axis=1)) / X.shape[0]
	mapping2[k] = kmeanModel.inertia_

Aqui calculamos as métricas de distorção e inércia para diferentes valores de K (número de clusters) e armazenamos essas métricas em listas e dicionários.

distortions e inertias são listas vazias que serão usadas para armazenar as métricas de distorção e inércia, respectivamente.

mapping1 e mapping2 são dicionários vazios que serão usados para mapear os valores de K para suas métricas de distorção e inércia correspondentes.

K é uma lista que contém valores de K de 1 a 9 (ou seja, de 1 a 9 clusters) que serão testados.

O loop for k in K: itera sobre os diferentes valores de K.

Dentro do loop, o modelo K-Means é construído e treinado com o número atual de clusters definido por k:

kmeanModel = KMeans(n_clusters=k).fit(X)
kmeanModel.fit(X)

Isso cria uma instância do modelo K-Means com o número atual de clusters e o ajusta aos dados X.

A distorção é calculada para o valor de K atual com a fórmula:

sum(np.min(cdist(X, kmeanModel.cluster_centers_, 'euclidean'), axis=1)) / X.shape[0]

Essa fórmula calcula a média das distâncias euclidianas mínimas entre cada ponto de dados e os centros dos clusters mais próximos.

A inércia é calculada para o valor de K atual com kmeanModel.inertia_. A inércia é a soma das distâncias quadráticas entre os pontos de dados e os centros dos clusters.

As métricas de distorção e inércia calculadas são armazenadas nas listas distortions e inertias, respectivamente.

Os valores de K e suas métricas de distorção e inércia correspondentes são armazenados nos dicionários mapping1 e mapping2, respectivamente, para análise posterior.

No final do loop, você terá listas contendo as métricas de distorção e inércia para diferentes valores de K, bem como dicionários que mapeiam os valores de K para essas métricas. Aqui queremos determinar o número ideal de clusters em uma análise de cluster K-Means.

Vamos tabular e visualizar os resultados agora utilizando os diferentes valores de distortion para o dicionário mapping1:

for key, val in mapping1.items():
	print(f'{key} : {val}')

Plotamos em um gráfico agora os dados acima:

plt.plot(K, distortions, 'bx-')
plt.xlabel('Values of K')
plt.ylabel('Distortion')
plt.title('The Elbow Method using Distortion')
plt.show()

Utilizando agora os diferentes valores de inércia para o dicionário mapping2:

for key, val in mapping2.items():
	print(f'{key} : {val}')

Para determinar o número ideal de clusters, devemos selecionar o valor de k no “cotovelo”, ou seja, o ponto após o qual a distorção/inércia começa a diminuir de maneira linear. Assim, para os dados fornecidos, concluímos que o número ideal de clusters para os dados é 5.

De forma resumida para o código a seguir, iremos plotar imagens dos pontos de dados agrupados para diferentes valores de k. Para isso, aplicaremos o algoritmo K-Means no conjunto de dados, iterando em uma faixa de valores de k.

Na range, colocamos o número que conseguimos através do Elbow-Method que foi 5

# Cria um range de valores para k
k_range = range(1, 6)

# Iniciamos uma lista vazia para armazenar os valores de inércia para cada K
inertia_values = []

# Treinamos e plotamos os dados para cada valor de k
for k in k_range:
	kmeans = KMeans(n_clusters=k, \
					init='k-means++', random_state=42)
	y_kmeans = kmeans.fit_predict(X)
	inertia_values.append(kmeans.inertia_)
 
#Gráfico Matplotlib
	plt.scatter(X[:, 0], X[:, 1], c=y_kmeans)
	plt.scatter(kmeans.cluster_centers_[:, 0],\
				kmeans.cluster_centers_[:, 1], \
				s=100, c='red')
	plt.title('K-means clustering (k={})'.format(k))
	plt.xlabel('Feature 1')
	plt.ylabel('Feature 2')
	plt.show()

# Plota os valores de inércia para cada k
plt.plot(k_range, inertia_values, 'bo-')
plt.title('Elbow Method')
plt.xlabel('Number of clusters (k)')
plt.ylabel('Inertia')
plt.show()

Resultado final:

Aqui é possível visualizar o resultado final com a plotagem iterativa de todos os gráficos para cada valor de K e os respectivos centróides.

Conclusão

Você é o proprietário de um shopping e deseja compreender os perfis dos seus clientes e quem pode ser facilmente convertido (Clientes-Alvo).

Utilizando o dataset de score de pontuação financeira, utilizamos o algoritmo do Elbow-Method para encontrar o número da referência ideal de centróides e aplicamos isso no algoritmo de aprendizado de máquina não supervisionado K-means para criar os clusters e identificar quais são os perfis de clientes de modo que isso possa ser transmitido à equipe de marketing e que a estratégia seja planejada de acordo.

Referências

  • https://www.kaggle.com/datasets/vjchoudhary7/customer-segmentation-tutorial-in-python
  • http://shabal.in/visuals/kmeans/2.html
  • https://www.geeksforgeeks.org/elbow-method-for-optimal-value-of-k-in-kmeans/
  • https://en.wikipedia.org/wiki/Cluster_analysis
  • https://towardsdatascience.com/k-means-clustering-algorithm-applications-evaluation-methods-and-drawbacks-aa03e644b48a
  • https://medium.com/turing-talks/clustering-conceitos-b%C3%A1sicos-principais-algoritmos-e-aplica%C3%A7%C3%A3o-ace572a062a9
Compartilhe nas redes sociais:
Alexandre Polselli
Alexandre Polselli

Escrevo artigos e desenvolvo projetos nas minhas áreas de maior interesse: Data Science, Data Analytics, Estatística e Probabilidade, Inteligência Artificial e Machine Learning.

Artigos: 26

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *