Regroupement pour des données numériques et numériques discrètes mixtes

10

Mes données incluent les réponses au sondage qui sont binaires (numériques) et nominales / catégoriques. Toutes les réponses sont discrètes et au niveau individuel.Instantané des données

Les données sont de forme (n = 7219, p = 105).

Quelques choses:

  • J'essaie d'identifier une technique de clustering avec une mesure de similitude qui fonctionnerait pour les données binaires catégorielles et numériques. Il existe des techniques de clustering et de kprototype R kmodes conçues pour ce type de problème, mais j'utilise Python et j'ai besoin d'une technique de clustering sklearn qui fonctionne bien avec ce type de problèmes.

  • Je veux construire des profils de segments d'individus. ce qui signifie que ce groupe d'individus se soucie plus de cet ensemble de fonctionnalités.

kms
la source
Je ne pense pas qu'un clustering retournera des résultats significatifs sur ces données. Assurez-vous de valider vos résultats. Pensez également à implémenter un algorithme vous-même et à le contribuer à sklearn. Mais vous pouvez essayer d'utiliser par exemple DBSCAN avec le coefficient de dés ou une autre fonction de distance pour les données binaires / catégorielles .
A QUIT - Anony-Mousse
1
Il est courant de convertir catégorique en numérique dans ces cas. Voir ici scikit-learn.org/stable/modules/generated/… . En faisant cela, vous n'aurez plus que des valeurs binaires dans vos données, vous n'aurez donc pas de problèmes de mise à l'échelle avec le clustering. Vous pouvez maintenant essayer un simple k-means.
Peut-être que cette approche serait utile: zeszyty-naukowe.wwsi.edu.pl/zeszyty/zeszyt12/…
Vous devriez partir de la solution la plus simple, en essayant de convertir les représentations catégorielles en un codage à chaud comme indiqué ci-dessus.
geompalik
C'est l'objet de ma thèse de doctorat préparée en 1986 au Centre Scientifique IBM France et à l'Université Pierre et Marie Currie (Paris 6) intitulée nouvelles techniques de codage et d'association en classification automatique. Dans cette thèse, j'ai proposé des techniques de codage de données appelées Triordonnance pour classer un ensemble décrit par des variables numériques, qualitatives et ordinales.
Dit Chah slaoui

Réponses:

9

Prendre un coup de poignard:

J'essaie d'identifier une technique de clustering avec une mesure de similitude qui fonctionnerait pour les données binaires catégorielles et numériques.

La distance Gower est une mesure de distance utile lorsque les données contiennent des variables continues et catégorielles.

Il existe des techniques de clustering et de kprototype R kmodes conçues pour ce type de problème, mais j'utilise Python et j'ai besoin d'une technique de clustering sklearn qui fonctionne bien avec ce type de problèmes.

Je n'ai pas pu trouver une implémentation de Gower Distance en Python lorsque je l'ai recherchée il y a environ 4 à 5 mois. J'ai donc créé ma propre implémentation.

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)

Le lien vers le même morceau de code: https://github.com/matchado/Misc/blob/master/gower_dist.py

En ce qui concerne la technique de clustering, je n'ai pas utilisé celles que vous avez mentionnées. Mais j'ai utilisé le clustering hiérarchique dans R avec la distance plus faible avec succès dans le passé.

En examinant les techniques de clustering disponibles dans scikit learn, le clustering agglomératif semble convenir. http://scikit-learn.org/stable/modules/clustering.html#hierarchical-clustering

Je veux construire des profils de segments d'individus. ce qui signifie que ce groupe d'individus se soucie plus de cet ensemble de fonctionnalités.

Une fois que vous avez attribué des étiquettes de cluster à chaque ligne de vos données, pour chaque cluster, examinez la distribution des fonctionnalités (statistiques récapitulatives pour les variables continues et distributions de fréquence pour les variables catégorielles). C'est plus facile à analyser visuellement si votre nombre de fonctionnalités est gérable (<20 peut-être?).

Mais puisque vous avez plus de 100 fonctionnalités, je suggère une approche plus organisée. Créez une matrice avec des étiquettes de cluster dans les colonnes et la statistique récapitulative des entités dans les lignes (je suggère d'utiliser la médiane pour la variable continue et le pourcentage d'occurrence de la valeur la plus fréquente dans le cluster pour la variable catégorielle)

Cela pourrait ressembler à ceci.

╔═══════════════════════╦═══════════╦═══════════╦════╦═══════════╗
║        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       ║
╚═══════════════════════╩═══════════╩═══════════╩════╩═══════════╝
gregorymatchado
la source
1
Réponse solide, bien faite.
Astrid
1
Excellent! merci pour votre temps
Gonzalo Garcia
2

J'ai joint ma réponse à cette question ci-dessous - vous avez essentiellement demandé la même chose.


Cette question semble vraiment concerner la représentation, et pas tant le clustering.

Les données catégorielles sont un problème pour la plupart des algorithmes d'apprentissage automatique. Supposons, par exemple, que vous ayez une variable catégorielle appelée "couleur" qui pourrait prendre les valeurs rouge, bleu ou jaune. Si nous les codons simplement numériquement en 1,2 et 3 respectivement, notre algorithme pensera que le rouge (1) est en fait plus proche du bleu (2) que du jaune (3). Nous devons utiliser une représentation qui permet à l'ordinateur de comprendre que ces choses sont toutes également différentes.

Une façon simple consiste à utiliser ce qu'on appelle une représentation unique, et c'est exactement ce que vous pensiez que vous devriez faire. Plutôt que d'avoir une variable comme "couleur" qui peut prendre trois valeurs, nous la séparons en trois variables. Il s'agit de "couleur rouge", "couleur bleu" et "couleur jaune", qui ne peuvent tous prendre que la valeur 1 ou 0.

Cela augmente la dimensionnalité de l'espace, mais vous pouvez maintenant utiliser n'importe quel algorithme de clustering que vous aimez. Il est parfois judicieux de zscore ou de blanchir les données après avoir effectué ce processus, mais votre idée est certainement raisonnable.

Jordan A
la source
1

La métrique de distance implémentée par @gregorymatchado a un bug. Pour les attributs numériques, la plage donnera NaN pour les mêmes valeurs partout. Pour cela, nous avons besoin d'un changement d'utilisation max(np.ptp(feature.values),1)au lieu de np.ptp(feature.values). Code complet ci-dessous:

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)
Rana
la source
0

Je pense que vous avez aussi un bug. Si le vecteur d'entité a une très petite échelle. alors votre distance est inutile. Donc, je convertirais comme suit:

epsilon = 10**(-8)
... / max(np.ptp(feature.values), epsilon)
Oseong Kwon
la source