Пэтси автоматически добавляет постоянный термин "Перехват" в правой части формул.Это приводит к матрице дизайна со столбцом Intercept всех 1. Например,
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
Пэтси анализирует выражения на каждой стороне формулы, а добавляет новые термины только тогда, когда такой терминнеобходим для добавления требуемой гибкости модели.С точки зрения матрицы проектирования это означает, что новый столбец не добавляется, если векторное пространство, охватываемое столбцами, не будет расширено путем добавления нового столбца.Другими словами, новый столбец, который уже находится в диапазоне других столбцов, будет избыточным, и поэтому он не будет добавлен.
Когда у вас есть категориальная переменная, которая должна равняться W, E, N, S,или C, зная, что значение переменной не равно W, E, N или S, эквивалентно знанию, что переменная равна C.
Посмотрите на вывод из предыдущего примера.Знание того, что переменная a
не является a2
, эквивалентно знанию, что оно равно a1
.С точки зрения матрицы проектирования пространство столбца не будет увеличено путем включения столбца a1
, поскольку Intercept - a2
равен a1
.(Ниже столбец 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 не добавляется, поскольку Intercept -(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
был автоматически добавлен к правой части каждой формулы.Если в одной и той же части формулы есть и термин «Перехват», и категориальная переменная, одно значение категориальной переменной всегда отсутствует, поскольку ее наличие не расширит пространство столбцов матрицы проектирования.
Youможет сказать Пэсси не добавлять столбец «Перехват», добавив + 0
в правой части формулы или - 1
.Они оба делают одно и то же .
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']