如何关联熊猫中的Ordinal Categorical列?

时间:2017-12-19 20:02:53

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

我有一个DataFrame df,其中包含非数字列CatColumn

   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,但它没有在相关性分析中包含具有名义值的列。

3 个答案:

答案 0 :(得分:16)

我将强烈不同意其他评论。

他们错过了主要的相关点:随着变量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从中等高到高 - 高时,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根据其值的字母数字排序进行分解。 [高,中,中 - 高]被指定为[0,1,2],因此排序被改变:0 <0。 1&lt; 2意味着高&lt;中&lt;中高,这不是真的。因此,当C从高到中高到中高时,我们意外地计算了A和B的响应。正确答案必须保留排序,并将[2,0,1]分配给[高,中,中 - 高]。方法如下:

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的V等等;或者按照名义上的类别对连续变量进行分组等。但我不认为这是正确的。

注意2:如果您有另一个名为Low的类别,我的答案可能会受到批评,因为我将等间距数字分配给不等间距的类别。您可以建立一个参数,即应该将[2,1,1.5,0]分配给[高,中,中,高,小],这将是有效的。我相信这就是人们所说的数据科学的艺术部分。

答案 1 :(得分:0)

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

答案 2 :(得分:-1)

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

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

<events>
    <event>
        <start time="2018-10-20T10:11:36.465Z"/>
        <end time="2018-10-20T09:33:04.349Z"/>
    </event>
</events>

然后可以计算每个类别与其他列之间的相关性:

 #include <iostream>
 #include <new>
 using namespace std;

int main ()
{
  int i,n;
  int * p;
  cout << "How many numbers would you like to type? ";
  cin >> i;
  p= new (nothrow) int[i];
  if (p == 0)
    cout << "Error: memory could not be allocated";
  else
  {
    for (n=0; n<i; n++)
    {
      cout << "Enter number: ";
      cin >> p[n];
    }
    cout << "You have entered: ";
    for (n=0; n<i; n++)
      cout <<"Value= "<< p[n] << ",Address = "<<&p[n]<<endl;
    delete p;
    cout<<endl<<"After Deallocation"<<endl;
  for (n=0; n<i; n++)
      cout <<"Value= " <<p[n] << ",Address = "<<&p[n]<<endl;
}
  return 0;
}

输出:

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