如何关联 pandas 中的有序分类列?
How to correlate an Ordinal Categorical column in pandas?
我有一个带有非数字列 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
但它不包括相关分析中具有标称值的列。
我强烈不同意其他评论。
他们忽略了相关性的要点:随着变量 2 的增加或减少,变量 1 增加或减少了多少。所以首先,在 factorization/encoding 期间必须保留序数变量的顺序。如果改变变量的顺序,相关性将完全改变。如果您正在构建基于树的方法,这不是问题,但对于相关性分析,必须特别注意序数变量中顺序的保存。
让我使我的论点可重现。 A 和 B 是数字,C 是以下 table 中的序数分类,与问题中的那个有意略有不同。
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 < 1 < 2 意味着 High < Medium < Medium-High,这是不正确的。因此,当 C 从高到中再到中高时,我们不小心计算了 A 和 B 的响应。正确答案必须保留顺序,并将 [2, 0, 1] 分配给 [High, Medium, Medium-High]。方法如下:
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:如果你想把你的变量当成名义变量,你可以看看contingency tables, Cramer's V之类的;或按名义类别等对连续变量进行分组。不过,我认为这不对。
注意 2:如果您有另一个名为 Low 的类别,我的回答可能会受到批评,因为我将等距数字分配给了不等距类别。您可以提出应该将 [2, 1, 1.5, 0] 分配给 [High, Medium, Medium-High, Small] 的论点,这是有效的。我相信这就是人们所说的数据科学的艺术部分。
将分类列与 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
基本上,没有什么好的科学方法可以做到。我会使用以下方法:
1. 将数字字段分成 n 组,其中 n = 分类字段的组数。
2. 计算 2 个分类字段之间的 Cramer 相关性。
我有一个带有非数字列 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
但它不包括相关分析中具有标称值的列。
我强烈不同意其他评论。
他们忽略了相关性的要点:随着变量 2 的增加或减少,变量 1 增加或减少了多少。所以首先,在 factorization/encoding 期间必须保留序数变量的顺序。如果改变变量的顺序,相关性将完全改变。如果您正在构建基于树的方法,这不是问题,但对于相关性分析,必须特别注意序数变量中顺序的保存。
让我使我的论点可重现。 A 和 B 是数字,C 是以下 table 中的序数分类,与问题中的那个有意略有不同。
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 < 1 < 2 意味着 High < Medium < Medium-High,这是不正确的。因此,当 C 从高到中再到中高时,我们不小心计算了 A 和 B 的响应。正确答案必须保留顺序,并将 [2, 0, 1] 分配给 [High, Medium, Medium-High]。方法如下:
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:如果你想把你的变量当成名义变量,你可以看看contingency tables, Cramer's V之类的;或按名义类别等对连续变量进行分组。不过,我认为这不对。
注意 2:如果您有另一个名为 Low 的类别,我的回答可能会受到批评,因为我将等距数字分配给了不等距类别。您可以提出应该将 [2, 1, 1.5, 0] 分配给 [High, Medium, Medium-High, Small] 的论点,这是有效的。我相信这就是人们所说的数据科学的艺术部分。
将分类列与 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
基本上,没有什么好的科学方法可以做到。我会使用以下方法: 1. 将数字字段分成 n 组,其中 n = 分类字段的组数。 2. 计算 2 个分类字段之间的 Cramer 相关性。