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?
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
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.