Tomando uma facada:
Estou tentando identificar uma técnica de agrupamento com uma medida de similaridade que funcionaria para dados binários categóricos e numéricos.
Distância de Gower é uma métrica de distância útil quando os dados contêm variáveis contínuas e categóricas.
Existem técnicas no clustering R kmodes e no kprototype que são projetadas para esse tipo de problema, mas estou usando o Python e preciso de uma técnica do cluster sklearn que funcione bem com esse tipo de problema.
Não consegui encontrar uma implementação do Gower Distance em Python quando a procurei cerca de 4-5 meses atrás. Então, eu vim com minha própria implementação.
import pandas as pd
import numpy as np
from sklearn.neighbors import DistanceMetric
def gower_distance(X):
"""
This function expects a pandas dataframe as input
The data frame is to contain the features along the columns. Based on these features a
distance matrix will be returned which will contain the pairwise gower distance between the rows
All variables of object type will be treated as nominal variables and the others will be treated as
numeric variables.
Distance metrics used for:
Nominal variables: Dice distance (https://en.wikipedia.org/wiki/S%C3%B8rensen%E2%80%93Dice_coefficient)
Numeric variables: Manhattan distance normalized by the range of the variable (https://en.wikipedia.org/wiki/Taxicab_geometry)
"""
individual_variable_distances = []
for i in range(X.shape[1]):
feature = X.iloc[:,[i]]
if feature.dtypes[0] == np.object:
feature_dist = DistanceMetric.get_metric('dice').pairwise(pd.get_dummies(feature))
else:
feature_dist = DistanceMetric.get_metric('manhattan').pairwise(feature) / np.ptp(feature.values)
individual_variable_distances.append(feature_dist)
return np.array(individual_variable_distances).mean(0)
O link para o mesmo trecho de código: https://github.com/matchado/Misc/blob/master/gower_dist.py
Com relação à técnica de agrupamento, não usei as que você mencionou. Mas eu usei agrupamentos hierárquicos em R juntamente com distâncias maiores com sucesso no passado.
Analisando as técnicas de clustering disponíveis no scikit learn, o Clustering Aglomerativo parece ser o ideal. http://scikit-learn.org/stable/modules/clustering.html#hierarchical-clustering
Eu quero construir perfis de segmentos de indivíduos. ou seja, esse grupo de indivíduos se preocupa mais com esse conjunto de recursos.
Depois de atribuir rótulos de cluster a cada linha dos seus dados, cada grupo analisa a distribuição dos recursos (estatísticas resumidas para variáveis contínuas e distribuições de frequência para variáveis categóricas). É mais fácil analisar visualmente se o número de recursos é gerenciável (<20, talvez?).
Mas como você tem mais de 100 recursos, sugiro uma abordagem mais organizada. Crie uma matriz com rótulos de cluster nas colunas e o status resumido dos recursos nas linhas (sugiro usar mediana para variável contínua e porcentagem de ocorrência do valor mais frequente no cluster para variável categórica)
Pode parecer algo assim.
╔═══════════════════════╦═══════════╦═══════════╦════╦═══════════╗
║ Feature ║ Cluster 1 ║ Cluster 2 ║ … ║ Cluster N ║
╠═══════════════════════╬═══════════╬═══════════╬════╬═══════════╣
║ Numeric feature 1 ║ 15 ║ 37 ║ .. ║ 1 ║
║ Numeric feature 2 ║ 34 ║ 56 ║ … ║ 56 ║
║ Categorical feature 1 ║ 47% ║ 87% ║ … ║ 25% ║
║ … ║ … ║ … ║ … ║ … ║
║ Categorical feature N ║ 25% ║ 91% ║ … ║ 11% ║
║ Numeric feature N ║ 0.2 ║ 0.7 ║ … ║ 0.5 ║
╚═══════════════════════╩═══════════╩═══════════╩════╩═══════════╝