【问题标题】:Numerical vs. categorical vars: Why 100% correlation for categorical variable with high cardinality?数值与分类变量:为什么具有高基数的分类变量具有 100% 相关性?
【发布时间】:2022-09-28 18:07:37
【问题描述】:

我是数据科学的新手,并试图掌握探索性数据分析。我的目标是获得所有变量之间的相关矩阵。对于数值变量,我使用 Pearson\'s R,对于分类变量,我使用修正后的 Cramer\'s V。现在的问题是在分类变量和数值变量之间获得有意义的相关性。为此,我使用相关比率,如here 所述。问题在于,具有高基数的分类变量无论如何都显示出高相关性:

correlation matrix cat vs. num

这似乎很荒谬,因为这实际上会显示分类变量的基数,而不是与数值变量的相关性。问题是:如何处理问题以获得有意义的相关性。

下面的 Python 代码显示了我是如何实现相关比率的:

import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

train = pd.DataFrame({
    \'id\': [0,1,2,3,4,5,6,7,8,9,10,11], \'num3\': [6,3,3,9,6,9,9,3,6,3,6,9],
    \'cat2\': [0,1,0,1,0,1,0,1,0,1,0,1], \'cat3\': [0,1,2,0,1,2,0,1,2,0,1,2],
    \'cat6\': [0,4,8,2,6,10,0,4,8,2,6,10], \'cat12\': [0,7,2,9,4,11,6,1,8,3,10,5],
})
cat_cols, num_cols = [\'cat2\',\'cat3\',\'cat6\',\'cat12\'], [\'id\',\'num3\']

def corr_ratio(cats, nums):
    avgtotal = nums.mean()
    elements_avg, elements_count = np.zeros(len(cats.index)), np.zeros(len(cats.index))
    cu = cats.unique()
    for i in range(cu.size):
        cn = cu[i]
        filt = cats == cn
        elements_count[i] = filt.sum()
        elements_avg[i] = nums[filt].mean(axis=0)
    numerator = np.sum(np.multiply(elements_count, np.power(np.subtract(elements_avg, avgtotal), 2)))
    denominator = np.sum(np.power(np.subtract(nums, avgtotal), 2))  # total variance
    return 0.0 if numerator == 0 else np.sqrt(numerator / denominator)

rows = []
for cat in cat_cols:
    col = []
    for num in num_cols:
        col.append(round(corr_ratio(train[cat], train[num]), 2))
    rows.append(col)

df = pd.DataFrame(np.array(rows), columns=num_cols, index=cat_cols)
sns.heatmap(df)
plt.tight_layout()
plt.show()

    标签: python statistics data-science correlation exploratory-data-analysis


    【解决方案1】:

    如果我没记错的话,还有另一种方法叫做泰尔的你.试试这个,看看是否会出现同样的问题?

    你可以使用这个:
    num_cols:your_df.select_dtypes(include=['number']).columns.to_list()
    cat_target_cols:your_df.select_dtypes(include=['object']).columns.to_list()

    corr_df = pd.DataFrame(associations(dataset=your_df, numerical_columns=num_cols, nom_nom_assoc='theil', figsize=(20, 20), nominal_columns=cat_target_cols).get('corr'))
    

    【讨论】:

    • 据我所知,Theil's U 用于衡量两个分类变量之间的相关性,类似于 Cramer's V,而这两者之间的区别在于,Theil's U 是不对称的。
    • 我懂了。抱歉没能帮到你?。因为我在进行相关分析时也面临困难。我不确定这个dython 库包是否足够可靠,无法告诉我数据集中每个变量之间的相关性。上面的答案显示了我如何使用这个库。不确定是否正确?
    • 是的,我也尝试过dython 包。它的默认设置是数值/数值的 Pearson's R,分类/分类的 Cramer's V,以及差的相关比率。有趣的是,这些可以被一些自定义函数替换。
    • 我懂了。你的意思是我们可以通过将一些参数传递给associations()函数来定制它?
    • 是的,像 associations(nom_num_assoc=custom_function) 这样指定 kwarg,然后在代码中定义 custom_function()。如果你不指定这个 kwarg,dython 会默认使用correlation_ratio。
    【解决方案2】:

    这可能是因为我认为您正在想象一些与您的 seaborn 情节中的 chi-2 更相关的东西。 Cramer 的 V 是从 chi-2 派生的数字,但不等价。因此,这意味着您可以对特定单元格具有较高的值,但对 Cramer 的 V 值具有更高的相关性。我什至不确定比较原始模态值是否有意义,因为它们可能处于完全不同的数量级。

    Chi 2 formula Cramer's V formula

    【讨论】:

      猜你喜欢
      • 2020-04-18
      • 2015-07-20
      • 2021-01-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-13
      • 1970-01-01
      • 2018-01-17
      相关资源
      最近更新 更多