Clustering para dados discretos numéricos e nominais mistos


10

Meus dados incluem respostas de pesquisa binárias (numéricas) e nominais / categóricas. Todas as respostas são discretas e no nível individual.Instantâneo de dados

Os dados têm forma (n = 7219, p = 105).

Algumas coisas:

  • Estou tentando identificar uma técnica de agrupamento com uma medida de similaridade que funcionaria para dados binários categóricos e numéricos. 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.

  • Eu quero construir perfis de segmentos de indivíduos. ou seja, esse grupo de indivíduos se preocupa mais com esse conjunto de recursos.


Eu não acho que nenhum cluster retornará resultados significativos em tais dados. Certifique-se de validar suas descobertas. Considere também implementar um algoritmo e contribuí- lo para o sklearn. Mas você pode tentar usar, por exemplo, DBSCAN com coeficiente de dados ou outra função de distância para dados binários / categoriais .
Quit - Anony-Mousse

1
É comum converter categórico em numérico nesses casos. Veja aqui scikit-learn.org/stable/modules/generated/… . Fazendo isso, agora você terá apenas valores binários em seus dados, portanto, não haverá problemas de dimensionamento com o armazenamento em cluster. Agora você pode tentar um k-means simples.

Talvez essa abordagem seja útil: zeszyty-naukowe.wwsi.edu.pl/zeszyty/zeszyt12/…

Você deve começar da solução mais simples, tentando converter as representações categóricas em codificação de um hot-hot conforme observado acima.
geompalik 10/09/16

Esse é o assunto de minha tese de doutorado preparada em 1986 no IBM France Scientific Center e na Universidade Pierre et Marie Currie (Paris 6) intitulada novas técnicas de codificação e associação na classificação automática. Nesta tese, propus técnicas de codificação de dados denominadas Triordonância para classificar um conjunto descrito por variáveis ​​numéricas, qualitativas e ordinais.
Disse Chah slaoui

Respostas:


9

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       ║
╚═══════════════════════╩═══════════╩═══════════╩════╩═══════════╝

1
Resposta sólida, bem feita.
Astrid

1
Excelente! obrigado pelo seu tempo
Gonzalo Garcia

2

Anexei minha resposta a esta pergunta abaixo - vocês basicamente fizeram a mesma coisa.


Essa pergunta parece realmente sobre representação, e não tanto sobre agrupamento.

Os dados categóricos são um problema para a maioria dos algoritmos no aprendizado de máquina. Suponha, por exemplo, que você tenha alguma variável categórica chamada "cor" que possa assumir os valores vermelho, azul ou amarelo. Se simplesmente os codificarmos numericamente como 1,2 e 3, respectivamente, nosso algoritmo pensará que vermelho (1) está mais próximo do azul (2) do que amarelo (3). Precisamos usar uma representação que permita ao computador entender que essas coisas são todas igualmente diferentes.

Uma maneira simples é usar o que é chamado de representação quente, e é exatamente o que você pensou que deveria fazer. Em vez de ter uma variável como "cor" que pode assumir três valores, separamos-a em três variáveis. Eles seriam "cor vermelha", "cor azul" e "cor amarela", que todos podem assumir apenas o valor 1 ou 0.

Isso aumenta a dimensionalidade do espaço, mas agora você pode usar qualquer algoritmo de cluster que desejar. Às vezes, faz sentido zscore ou embranquecer os dados depois de executar esse processo, mas a sua ideia é definitivamente razoável.


1

A métrica de distância implementada por @gregorymatchado possui um bug. Para atributos numéricos, o intervalo fornecerá NaN para os mesmos valores. Para isso, precisamos alterar o uso em max(np.ptp(feature.values),1)vez de np.ptp(feature.values). Código completo abaixo:

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) / max(np.ptp(feature.values),1)

    individual_variable_distances.append(feature_dist)

return np.array(individual_variable_distances).mean(0)

0

Eu acho que você também tem insetos. Se o vetor de recurso tiver uma escala muito pequena. então sua distância é inútil. Então, eu converteria o seguinte:

epsilon = 10**(-8)
... / max(np.ptp(feature.values), epsilon)
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.