如何对 patsy 矩阵进行 sm.Logit 回归?
How to make a sm.Logit regresiion on patsy matrix?
我想为 P(wage > 250) 的四个自由度的自然三次样条函数创建一个 Logit 图,但由于某种原因出现错误。我不明白为什么,因为OLS工作正常。
这是代码(它应该可以在没有任何调整的情况下完全工作,当然,有问题的部分除外):
import pandas as pd
from patsy import dmatrix
import statsmodels.api as sm
import matplotlib.pyplot as plt
import numpy as np
plt.figure(figsize=(7,5))
df = pd.read_csv('http://web.stanford.edu/~oleg2/hse/wage/wage.csv').sort_values(by=['age'])
ind_df = df[['wage', 'age']].copy()
plt.xlabel('Age', fontsize=15)
plt.ylabel('Wage', fontsize=15)
plt.ylim((0,333))
d = 4
knots = [df.age.quantile(0.25), df.age.quantile(0.5), df.age.quantile(0.75)]
my_spline_transformation = f"bs(train, knots={knots}, degree={d}, include_intercept=True)"
transformed = dmatrix( my_spline_transformation, {"train": df.age}, return_type='dataframe' )
lft = sm.Logit( (df.age > 250), transformed )
y_grid1 = lft.predict(transformed)
plt.show()
错误是:
ValueError: shapes (3000,9) and (3000,9) not aligned: 9 (dim 1) != 3000 (dim 0)
我尝试转置数据框,但结果是一些乱码图。
我该如何正确执行此操作?
首先,你的因变量是错误的,应该是df.wage>250
而不是df.age>250
。
其次,我不确定对于单个变量您是否需要具有 4 个自由度(意味着高达 x^4 多项式)的样条曲线。如果您查看您的数据,它并没有那么复杂:
df = pd.read_csv('http://web.stanford.edu/~oleg2/hse/wage/wage.csv').sort_values(by=['age'])
df['wage_factor'] = (df.wage > 250).astype('int')
fig,ax = plt.subplots(1,2,figsize=(8,3))
df.plot.scatter(x='age',y='wage',ax=ax[0])
df.plot.scatter(x='age',y='wage_factor',ax=ax[1])
第三,调用sm.Logit()
后,需要适配。请参阅下面的内容:
d = 3
knots = [30,60]
my_spline_transformation = f"bs(train, knots={knots}, degree={d}, include_intercept=True)"
transformed = dmatrix( my_spline_transformation, {"train": df.age}, return_type='dataframe' )
lft = sm.Logit( (df.wage>250), transformed)
res = lft.fit()
y_grid1 = res.predict(transformed)
这些都可以正常工作。我不太确定结果是否有意义,因为在这个例子中,你的目标严重不平衡,逻辑回归会有很大问题。
我想为 P(wage > 250) 的四个自由度的自然三次样条函数创建一个 Logit 图,但由于某种原因出现错误。我不明白为什么,因为OLS工作正常。
这是代码(它应该可以在没有任何调整的情况下完全工作,当然,有问题的部分除外):
import pandas as pd
from patsy import dmatrix
import statsmodels.api as sm
import matplotlib.pyplot as plt
import numpy as np
plt.figure(figsize=(7,5))
df = pd.read_csv('http://web.stanford.edu/~oleg2/hse/wage/wage.csv').sort_values(by=['age'])
ind_df = df[['wage', 'age']].copy()
plt.xlabel('Age', fontsize=15)
plt.ylabel('Wage', fontsize=15)
plt.ylim((0,333))
d = 4
knots = [df.age.quantile(0.25), df.age.quantile(0.5), df.age.quantile(0.75)]
my_spline_transformation = f"bs(train, knots={knots}, degree={d}, include_intercept=True)"
transformed = dmatrix( my_spline_transformation, {"train": df.age}, return_type='dataframe' )
lft = sm.Logit( (df.age > 250), transformed )
y_grid1 = lft.predict(transformed)
plt.show()
错误是:
ValueError: shapes (3000,9) and (3000,9) not aligned: 9 (dim 1) != 3000 (dim 0)
我尝试转置数据框,但结果是一些乱码图。 我该如何正确执行此操作?
首先,你的因变量是错误的,应该是df.wage>250
而不是df.age>250
。
其次,我不确定对于单个变量您是否需要具有 4 个自由度(意味着高达 x^4 多项式)的样条曲线。如果您查看您的数据,它并没有那么复杂:
df = pd.read_csv('http://web.stanford.edu/~oleg2/hse/wage/wage.csv').sort_values(by=['age'])
df['wage_factor'] = (df.wage > 250).astype('int')
fig,ax = plt.subplots(1,2,figsize=(8,3))
df.plot.scatter(x='age',y='wage',ax=ax[0])
df.plot.scatter(x='age',y='wage_factor',ax=ax[1])
第三,调用sm.Logit()
后,需要适配。请参阅下面的内容:
d = 3
knots = [30,60]
my_spline_transformation = f"bs(train, knots={knots}, degree={d}, include_intercept=True)"
transformed = dmatrix( my_spline_transformation, {"train": df.age}, return_type='dataframe' )
lft = sm.Logit( (df.wage>250), transformed)
res = lft.fit()
y_grid1 = res.predict(transformed)
这些都可以正常工作。我不太确定结果是否有意义,因为在这个例子中,你的目标严重不平衡,逻辑回归会有很大问题。