【问题标题】:How to correlate an Ordinal Categorical column in pandas?如何关联熊猫中的序数分类列?
【发布时间】:2018-06-02 07:49:42
【问题描述】:

我有一个带有非数字列 CatColumn 的 DataFrame df

   A         B         CatColumn
0  381.1396  7.343921  Medium
1  481.3268  6.786945  Medium
2  263.3766  7.628746  High
3  177.2400  5.225647  Medium-High

我想将 CatColumn 包含在与 Dataframe 中其他列的相关性分析中。我试过DataFrame.corr,但它不包括相关分析中具有标称值的列。

【问题讨论】:

    标签: python pandas scikit-learn correlation categorical-data


    【解决方案1】:

    基本上,没有一个好的科学方法可以做到这一点。我会使用以下方法: 1. 将数值字段拆分为 n 个组,其中 n = 分类字段的组数。 2.计算2个分类字段之间的Cramer相关性。

    【讨论】:

      【解决方案2】:

      将分类列与 N 个值相关联的正确方法是将此列拆分为 N 个单独的布尔列。

      让我们采用原始问题数据框。制作类别列:

      for i in df.CatColumn.astype('category'):
          df[i] = df.CatColumn == i
      

      那么就可以计算每个类别与其他列的相关性了:

      df.corr()
      

      输出:

                          A         B    Medium      High  Medium-High
      A            1.000000  0.490608  0.914322 -0.312309    -0.743459
      B            0.490608  1.000000  0.343620  0.548589    -0.945367
      Medium       0.914322  0.343620  1.000000 -0.577350    -0.577350
      High        -0.312309  0.548589 -0.577350  1.000000    -0.333333
      Medium-High -0.743459 -0.945367 -0.577350 -0.333333     1.000000
      

      【讨论】:

      • 那么你会如何回答这个问题呢?您可以调整答案以实际回答 OP 吗?
      • @FatihAkici 我认为没关系,因为它直接回答了如何关联熊猫中的分类列的问题,但我对其进行了更新以匹配 OP 中使用的数据框。
      • 请重新阅读问题,并查看所有给出的答案。您找不到变量A 与另一个变量Medium 的类别之间的相关性。那是零意义。目标是找到ACatColumnAB 以及BCatColumn 之间的相关性。很抱歉这么说,但您的回答没有任何明智的信息。
      • 随机变量之间存在相关性。不是对它们的固定值。 Medium 是一个固定值,它不会改变,方差为零,因此它不能与任何变量有协方差或相关性。它与任何事物的相关性为零。甚至试图计算它与任何事物的相关性都是没有意义的。
      • 不,您可以在表格中看到每个类别的相关值:)。对于具有多个类别的分类特征,相关性不能用一个数字表示,这将毫无意义,因为分类特征不能用其定义的度量值来表示。
      【解决方案3】:

      我将强烈不同意其他 cmets。

      他们忽略了相关的要点:随着变量 2 的增加或减少,变量 1 增加或减少了多少。因此,首先,必须在分解/编码期间保留序数变量的顺序。如果改变变量的顺序,相关性将完全改变。如果您正在构建基于树的方法,这不是问题,但对于相关性分析,必须特别注意保持序数变量中的顺序。

      让我让我的论点可重现。 A 和 B 是数字,C 是下表中的序数分类,故意与问题中的略有不同。

      rawText = StringIO("""
       A         B         C
      0  100.1396  1.343921  Medium
      1  105.3268  1.786945  Medium
      2  200.3766  9.628746  High
      3  150.2400  4.225647  Medium-High
      """)
      myData = pd.read_csv(rawText, sep = "\s+")
      

      注意:随着 C 从 Medium 到 Medium-High 再到 High,A 和 B 都单调增加。因此,我们应该看到元组 (C,A) 和 (C,B) 之间的强相关性。让我们重现两个建议的答案:

      In[226]: myData.assign(C=myData.C.astype('category').cat.codes).corr()
      Out[226]: 
                A         B         C
      A  1.000000  0.986493 -0.438466
      B  0.986493  1.000000 -0.579650
      C -0.438466 -0.579650  1.000000
      

      等等……什么?负相关?怎么会?有些事情肯定是不对的。那到底是怎么回事?

      C 是根据其值的字母数字排序进行因式分解的。 [High, Medium, Medium-High] 被赋值为 [0, 1, 2],因此顺序改变了:0

      In[227]: myData['C'] = myData['C'].astype('category')
      myData['C'].cat.categories = [2,0,1]
      myData['C'] = myData['C'].astype('float')
      myData.corr()
      Out[227]: 
                A         B         C
      A  1.000000  0.986493  0.998874
      B  0.986493  1.000000  0.982982
      C  0.998874  0.982982  1.000000
      

      好多了!

      注意1:如果要将变量视为名义变量,可以查看列联表、Cramer's V 等;或按名义类别等对连续变量进行分组。不过,我认为这是不对的。

      注意2:如果您有另一个名为“低”的类别,我的回答可能会受到批评,因为我将等距数字分配给不等距的类别。您可以提出应该将 [2, 1, 1.5, 0] 分配给 [High, Medium, Medium-High, Small] 的论点,这将是有效的。我相信这就是人们所说的数据科学的艺术部分。

      【讨论】:

      • 这不是关于分类列的答案,因为类别只是转换为相应的度量值。但如果有可能 - 那么该列并不是真正的分类列。
      • @ei-grad 分类变量有两种类型:有序变量和名义变量。序数意味着可以对类别进行排序,例如小/中/高,这就是问题所在,以及为什么我以数字格式对它们进行排序。名义上的意思是没有固有顺序的类别,例如男性/女性/其他,我的“Note1”暗示了这一点。我真的不明白你的反对意见。分类变量(序数)肯定可以转换为数值,只要实现者知道他在做什么。
      • 订购的可能性并不意味着您可以用任意整数值替换类别,如果您这样做,相关性将以错误的方式计算。
      • @ei-grad 感谢您通过提及“订购的可能性”来伪造您的声明“如果可能 - 那么该列并不是真正的分类列”。至于不正确的计算,首先你需要了解软件包是如何做的。当您调用corr(NumericVar, CategoricalVar) 之类的名称时,默认处理是将CategoricalVar 转换为整数。如果选择那条路,就必须注意我的论点。如果没有,其他“正确”的方法是列联表和 Cramer's V(在我的 Note1 中提到)。您的 cmets 没有添加任何额外信息。
      • 请仔细阅读,我之前的评论没有任何篡改。进一步的讨论应该移到聊天中,但我不确定是否需要。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-01
      • 2019-08-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-02
      相关资源
      最近更新 更多