矩阵未看到列

时间:2018-10-25 11:50:13

标签: python patsy

我下面有这段代码,假设在给定列上创建2个数据框。 df的“地区”列具有5个变量; W,E,N,S和C。但是,结果数据帧只有W,E,N,S和一个拦截列。

import statsmodels.api as sm
from patsy import dmatrices
df = sm.datasets.get_rdataset('Guerry','HistData').data
vars = ['Department','Lottery','Literacy','Wealth','Region']
df = df[vars]
df = df.dropna()
#      Department  Lottery  Literacy  Wealth Region
# 0           Ain       41        37      73      E
# 1         Aisne       38        51      22      N
# 2        Allier       66        13      61      C
# 3  Basses-Alpes       80        46      76      E
# 4  Hautes-Alpes       79        69      83      E

y, X = dmatrices('Lottery ~ Literacy + Wealth + Region', data=df, return_type='dataframe')
print(X.columns.tolist())
# ['Intercept', 'Region[T.E]', 'Region[T.N]', 'Region[T.S]', 'Region[T.W]', 'Literacy', 'Wealth']

当我如下所示更改到最后一行时,它可以正常工作并显示5个Region值 数据框。

y, X = dmatrices('Literacy + Wealth + Region ~ Lottery', data=df, return_type='dataframe')
print(y.columns.tolist())
# ['Region[C]', 'Region[E]', 'Region[N]', 'Region[S]', 'Region[W]', 'Literacy', 'Wealth']

有人可以解释一下这是什么原因吗?在第一个代码而不是Region C上创建的拦截列是什么?

1 个答案:

答案 0 :(得分:0)

猫咪automatically adds a constant "Intercept" term位于 公式。这将导致设计矩阵的Intercept列为全1。 For example

import pandas as pd
import patsy

data = patsy.demo_data("a", "b", "y")
#     a   b         y
# 0  a1  b1  1.764052
# 1  a1  b2  0.400157
# 2  a2  b1  0.978738
# 3  a2  b2  2.240893
# 4  a1  b1  1.867558
# 5  a1  b2 -0.977278
# 6  a2  b1  0.950088
# 7  a2  b2 -0.151357

mat = patsy.dmatrices("y ~ a + b ", data, return_type='dataframe')[1]
print(mat)

收益

   Intercept  a[T.a2]  b[T.b2]
0        1.0      0.0      0.0
1        1.0      0.0      1.0
2        1.0      1.0      0.0
3        1.0      1.0      1.0
4        1.0      0.0      0.0
5        1.0      0.0      1.0
6        1.0      1.0      0.0
7        1.0      1.0      1.0

Patsy分析公式两边的表达式,然后only adds new terms when such a term is needed为表单增加所需的灵活性。 模型。就设计矩阵而言,这意味着不添加新列 除非列所跨的向量空间通过添加来扩展 新列。换句话说,新列已经在 其他列将是多余的,因此不会添加。

当您拥有必须等于W,E,N,S或C的分类变量时,知道变量的值不是W,E,N或S等于知道变量等于C。 / p>

查看上一个示例的输出。知道a变量 不是a2等于知道它等于a1。在设计方面 矩阵,则不会通过包含a1列来增加列空间,因为 Intercept - a2a1。 (下面的a1列标记为a[T.a1],并且 对于a2也是如此:

   Intercept  a[T.a2]  b[T.b2]  a[T.a1]
0        1.0      0.0      0.0      1.0
1        1.0      0.0      1.0      1.0
2        1.0      1.0      0.0      0.0
3        1.0      1.0      1.0      0.0
4        1.0      0.0      0.0      1.0
5        1.0      0.0      1.0      1.0
6        1.0      1.0      0.0      0.0
7        1.0      1.0      1.0      0.0

类似地,在您的情况下,没有为分类值C添加任何列, 因为拦截-(W + E + N + S)等于C。


现在,我们可以返回您的原始代码并更清楚地了解结果:

import statsmodels.api as sm
from patsy import dmatrices

df = sm.datasets.get_rdataset('Guerry','HistData').data
vars_ = ['Department','Lottery','Literacy','Wealth','Region']
df = df[vars_]
df = df.dropna()

formula1 = 'Lottery ~ Literacy + Wealth + Region'
print(formula1)
y1, X1 = dmatrices(formula1, data=df, return_type='dataframe')
print('LHS: {}'.format(y1.columns.tolist()))
# ['Lottery'], 
print('RHS: {}'.format(X1.columns.tolist()))
# ['Intercept', 'Region[T.E]', 'Region[T.N]', 'Region[T.S]', 'Region[T.W]', 'Literacy', 'Wealth']

formula2 = 'Literacy + Wealth + Region ~ Lottery'
print(formula2)

y2, X2 = dmatrices(formula2, data=df, return_type='dataframe')
print('LHS: {}'.format(y2.columns.tolist()))
# ['Region[C]', 'Region[E]', 'Region[N]', 'Region[S]', 'Region[W]', 'Literacy', 'Wealth']
print('RHS: {}'.format(X2.columns.tolist()))
# ['Intercept', 'Lottery']

请注意,Intercept已自动添加到右侧 每个公式。当既有拦截术语又有类别 公式同一侧的变量,分类变量的一个值 总是缺少,因为它的存在不会扩展设计矩阵的 列空间。


您可以通过在公式的右侧包含+ 0或包含- 1来告诉patsy不要添加Intercept列。他们俩do the same thing

formula3 = 'Lottery ~ Literacy + Wealth + Region + 0'
print(formula3)
y1, X1 = dmatrices(formula3, data=df, return_type='dataframe')
print('LHS: {}'.format(y1.columns.tolist()))
print('RHS: {}'.format(X1.columns.tolist()))

现在,右侧有一个Region[C]列:

LHS: ['Lottery']
RHS: ['Region[C]', 'Region[E]', 'Region[N]', 'Region[S]', 'Region[W]', 'Literacy', 'Wealth']