web-dev-qa-db-fra.com

Corrélation des caractéristiques catégorielles

J'ai des caractéristiques catégoriques dans mes données ainsi que des caractéristiques continues. Est-ce une bonne ou une mauvaise idée d'encoder à chaud des fonctionnalités de catégorie pour en trouver la corrélation avec des étiquettes avec d'autres créatures continues?

10
user8653080

Il existe un moyen de calculer le coefficient de corrélation sans coder à chaud la variable de catégorie. La statistique Cramers V est une méthode de calcul de la corrélation des variables catégorielles. Il peut être calculé comme suit. Le lien suivant est utile. À l'aide de pandas, calculez la matrice des coefficients de Cramér Pour les variables avec d'autres valeurs continues, vous pouvez les classer en utilisant cut of pandas.

import pandas as pd
import numpy as np
import scipy.stats as ss
import seaborn as sns

tips = sns.load_dataset("tips")

tips["total_bill_cut"] = pd.cut(tips["total_bill"],
                                np.arange(0, 55, 5),
                                include_lowest=True,
                                right=False)

def cramers_v(confusion_matrix):
    """ calculate Cramers V statistic for categorial-categorial association.
        uses correction from Bergsma and Wicher,
        Journal of the Korean Statistical Society 42 (2013): 323-328
    """
    chi2 = ss.chi2_contingency(confusion_matrix)[0]
    n = confusion_matrix.sum()
    phi2 = chi2 / n
    r, k = confusion_matrix.shape
    phi2corr = max(0, phi2 - ((k-1)*(r-1))/(n-1))
    rcorr = r - ((r-1)**2)/(n-1)
    kcorr = k - ((k-1)**2)/(n-1)
    return np.sqrt(phi2corr / min((kcorr-1), (rcorr-1)))

confusion_matrix = pd.crosstab(tips["day"], tips["time"]).as_matrix()
cramers_v(confusion_matrix)
# Out[10]: 0.93866193407222209

confusion_matrix = pd.crosstab(tips["total_bill_cut"], tips["time"]).as_matrix()
cramers_v(confusion_matrix)
# Out[24]: 0.16498707494988371
20
Keiku

Je cherchais à faire la même chose dans BigQuery. Pour les fonctionnalités numériques, vous pouvez utiliser la fonction CORR (x, y) intégrée. Pour les fonctionnalités catégorielles, vous pouvez le calculer comme suit: cardinalité (cat1 x cat2)/max (cardinalité (cat1), cardinalité (cat2). Cela se traduit par le SQL suivant:

SELECT 
COUNT(DISTINCT(CONCAT(cat1, cat2))) / GREATEST (COUNT(DISTINCT(cat1)), COUNT(DISTINCT(cat2))) as cat1_2,
COUNT(DISTINCT(CONCAT(cat1, cat3))) / GREATEST (COUNT(DISTINCT(cat1)), COUNT(DISTINCT(cat3))) as cat1_3,
....
FROM ...

Un nombre plus élevé signifie une corrélation plus faible.

J'ai utilisé le script python pour générer SQL:

import itertools

arr = range(1,10)

query = ',\n'.join(list('COUNT(DISTINCT(CONCAT({a}, {b}))) / GREATEST (COUNT(DISTINCT({a})), COUNT(DISTINCT({b}))) as cat{a}_{b}'.format(a=a,b=b) 
  for (a,b) in itertools.combinations(arr,2)))
query = 'SELECT \n ' + query + '\n FROM  `...`;'
print (query)

Il devrait être simple de faire la même chose en numpy.

0
Aleksey Vlasenko