分类特征相关

时间:2017-09-30 00:37:40

标签: pandas machine-learning categorical-data feature-engineering

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

3 个答案:

答案 0 :(得分:6)

有一种方法可以计算相关系数而无需对类别变量进行单热编码。 Cramers V统计量是计算分类变量相关性的一种方法。它可以如下计算。以下链接很有帮助。 Using pandas, calculate Cramér's coefficient matrix对于包含其他连续值的变量,您可以使用cut 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

答案 1 :(得分:1)

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

答案 2 :(得分:0)

我一直想在BigQuery中做同样的事情。 对于数字功能,可以使用内置的CORR(x,y)函数。 对于分类特征,可以将其计算为: 基数(cat1 x cat2)/最大(基数(cat1),基数(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中执行相同的操作应该很简单。