21

我的数据中有一些分类特征以及连续特征。对类别特征进行热编码以找到它与标签以及其他连续生物的相关性是一个好主意还是绝对坏主意?

4

3 回答 3

47

有一种方法可以计算相关系数,而无需对类别变量进行一次性编码。Cramers V 统计量是计算分类变量相关性的一种方法。可以如下计算。以下链接很有帮助。使用pandas,计算Cramér的系数矩阵对于具有其他连续值的变量,可以使用cutof进行分类pandas

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

print('Pandas version:', pd.__version__)
# Pandas version: 1.3.0

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"])
cramers_v(confusion_matrix.values)
# Out[2]: 0.9386619340722221

confusion_matrix = pd.crosstab(tips["total_bill_cut"], tips["time"])
cramers_v(confusion_matrix.values)
# Out[3]: 0.1649870749498837

请注意,.as_matrix()自版本 0.23.0 以来,熊猫已弃用。.values改为使用

于 2017-09-30T01:40:35.617 回答
2

我发现phik库在计算分类特征和区间特征之间的相关性方面非常有用。这对于分箱数值特征也很有用。试试这个:phik 文档

于 2020-12-24T13:50:29.867 回答
0

我希望在 BigQuery 中做同样的事情。对于数字特征,您可以使用内置的 CORR(x,y) 函数。对于分类特征,您可以将其计算为:cardinality (cat1 x cat2) / max (cardinality(cat1), cardinality(cat2)。转换为以下 SQL:

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

数字越大意味着相关性越低。

我使用以下 python 脚本生成 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)

在 numpy 中做同样的事情应该很简单。

于 2020-02-14T22:16:36.177 回答