Clustering per dati discreti misti numerici e nominali


10

I miei dati includono risposte al sondaggio che sono binarie (numeriche) e nominali / categoriche. Tutte le risposte sono discrete e a livello individuale.Istantanea dei dati

I dati sono di forma (n = 7219, p = 105).

Cose di coppia:

  • Sto cercando di identificare una tecnica di clustering con una misura di somiglianza che funzionerebbe con dati binari numerici e categorici. Esistono tecniche nel clustering R kmodes e kprototype progettate per questo tipo di problema, ma sto usando Python e ho bisogno di una tecnica del clustering sklearn che funzioni bene con questo tipo di problemi.

  • Voglio costruire profili di segmenti di individui. questo significa che questo gruppo di persone si preoccupa di più di questo insieme di funzionalità.


Non credo che nessun cluster restituirà risultati significativi su tali dati. Assicurati di convalidare i risultati. Considera anche di implementare un algoritmo tu stesso e di contribuire a sklearn. Ma puoi provare ad usare ad esempio DBSCAN con coefficiente di dado o un'altra funzione di distanza per dati binari / categoriali .
Ha QUIT - Anony-Mousse il

1
In questi casi è comune convertire da categorici a numerici. Vedi qui scikit-learn.org/stable/modules/generated/… . In questo modo ora avrai solo valori binari nei tuoi dati, quindi non avrai problemi di ridimensionamento con il clustering. Ora puoi provare un semplice k-medie.

Forse questo approccio sarebbe utile: zeszyty-naukowe.wwsi.edu.pl/zeszyty/zeszyt12/…

Si dovrebbe iniziare dalla soluzione più semplice, provando a convertire le rappresentazioni categoriche in una codifica a caldo come indicato sopra.
Geompalik,

Questo è l'argomento della mia tesi di dottorato preparata nel 1986 presso l'IBM France Scientific Center e l'Università Pierre et Marie Currie (Parigi 6) intitolata nuove tecniche di codifica e associazione nella classificazione automatica. In questa tesi ho proposto tecniche di codifica dei dati chiamate Triordonnance per classificare un insieme descritto da variabili numeriche, qualitative e ordinali.
Disse Chah slaoui il

Risposte:


9

Fare una pugnalata:

Sto cercando di identificare una tecnica di clustering con una misura di somiglianza che funzionerebbe con dati binari numerici e categorici.

Gower Distance è una metrica della distanza utile quando i dati contengono sia variabili continue che categoriche.

Esistono tecniche nel clustering R kmodes e kprototype progettate per questo tipo di problema, ma sto usando Python e ho bisogno di una tecnica del clustering sklearn che funzioni bene con questo tipo di problemi.

Non sono riuscito a trovare un'implementazione di Gower Distance in Python quando l'ho cercato circa 4-5 mesi fa. Quindi mi è venuta in mente la mia implementazione.

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)

Il link allo stesso codice: https://github.com/matchado/Misc/blob/master/gower_dist.py

Per quanto riguarda la tecnica del clustering, non ho usato quelli che hai citato. Ma ho usato il clustering gerarchico in R insieme a una distanza più ampia con successo in passato.

Esaminando le tecniche di clustering disponibili in scikit learn, Agglomerative Clustering sembra adattarsi al conto. http://scikit-learn.org/stable/modules/clustering.html#hierarchical-clustering

Voglio costruire profili di segmenti di individui. questo significa che questo gruppo di persone si preoccupa di più di questo insieme di funzionalità.

Dopo aver assegnato le etichette dei cluster a ciascuna riga dei dati, per ciascun cluster esaminare la distribuzione delle funzionalità (statistiche di riepilogo per variabili continue e distribuzioni di frequenza per variabili categoriali). Questo è più facile da analizzare visivamente se il tuo numero di funzioni è gestibile (<20 forse?).

Ma dal momento che hai oltre 100 funzionalità, suggerisco un approccio più organizzato. Crea una matrice con le etichette dei cluster nelle colonne e le statistiche riassuntive delle funzionalità nelle righe (suggerisco di utilizzare la mediana per la variabile continua e la percentuale di occorrenza del valore più frequente nel cluster per la variabile categoriale)

Potrebbe assomigliare a questo.

╔═══════════════════════╦═══════════╦═══════════╦════╦═══════════╗
║        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
Risposta solida, ben fatta.
Astrid

1
Eccellente! grazie per il tuo tempo
Gonzalo Garcia il

2

Ho aggiunto la mia risposta a questa domanda qui sotto: voi ragazzi essenzialmente avete fatto la stessa cosa.


Questa domanda sembra davvero sulla rappresentazione, e non tanto sul clustering.

I dati categorici sono un problema per la maggior parte degli algoritmi nell'apprendimento automatico. Supponiamo, ad esempio, di avere una variabile categorica chiamata "color" che potrebbe assumere i valori rosso, blu o giallo. Se li codifichiamo semplicemente numericamente rispettivamente come 1,2 e 3, il nostro algoritmo penserà che il rosso (1) sia effettivamente più vicino al blu (2) che al giallo (3). Dobbiamo usare una rappresentazione che permetta al computer di capire che queste cose sono effettivamente ugualmente diverse.

Un modo semplice è quello di usare quella che viene chiamata una rappresentazione one-hot, ed è esattamente quello che pensavi di dover fare. Invece di avere una variabile come "color" che può assumere tre valori, la separiamo in tre variabili. Questi sarebbero "colore rosso", "colore blu" e "colore giallo", che tutti possono assumere solo sul valore 1 o 0.

Ciò aumenta la dimensionalità dello spazio, ma ora è possibile utilizzare qualsiasi algoritmo di clustering che ti piace. A volte ha senso zscore o sbiancare i dati dopo aver eseguito questo processo, ma la tua idea è decisamente ragionevole.


1

La metrica della distanza implementata da @gregorymatchado ha un bug. Per gli attributi numerici, range fornirà NaN per gli stessi valori in tutto. Per questo abbiamo bisogno di un cambio usare max(np.ptp(feature.values),1)invece di np.ptp(feature.values). Codice completo di seguito:

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

Penso che anche tu abbia un bug. Se il vettore delle caratteristiche ha una scala molto piccola. allora la tua distanza è inutile. Quindi, vorrei convertire come segue:

epsilon = 10**(-8)
... / max(np.ptp(feature.values), epsilon)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.