状态模型 + var_weights + cross_val_score
Statsmodels + var_weights + cross_val_score
基于 that topic I created a wrapper for statsmodels' glm
in order to use scikit's cross_val_score
. Now I need to introduce variance/analytic weights 通过 SM.GLM 的 var_weights 参数。
class Wrapper(BaseEstimator, RegressorMixin):
def __init__(self, family, alpha, L1_wt, var_weights):
self.family = family
self.alpha = alpha
self.L1_wt = L1_wt
self.var_weights = var_weights
def fit(self, X, y):
self.model = sm.GLM(endog = y, exog = X, family=self.family, var_weights = self.var_weights)
self.result = self.model.fit_regularized(alpha=self.alpha, L1_wt=self.L1_wt)
return self.result
def predict(self, X):
return self.result.predict(X)
wrapper让我成功了运行:
sm_glm = Wrapper(family, alpha, L1_wt, var_weights)
sm_glm.fit()
但是交叉验证
cross_val_score(sm_glm, x, y, cv, scoring)
不工作,因为 cross_val_score trims(在 cv 折叠之后)x 和 y,但不是 var_weights,这会导致错误:
ValueError: var weights not the same length as endog
在我看来,我需要动态地跋涉 cross_val_score
次迭代并相应地 trim var_weights
。
有什么想法可以解决这个问题吗?
我认为你的猜测是正确的:cross_val_score
没有将 weights
数组传播到 cross-validation 循环中,也没有像拆分 [=14] 那样拆分它=] 和 y
变成 k-folds。我试图用其他一些数据复制你得到的错误(受 StatsModels documentation 关于 var_weights
和 freq_weights
之间的区别的启发)并阅读回溯,看起来如果附加参数(即 var_weights
)没有通过自定义估算器实现的 fit()
方法传递,它没有被提取用于 cross-validation。
我通过以下方式解决了它:
class SMW(BaseEstimator, RegressorMixin):
def __init__(self, family, alpha, L1_wt):
self.family = family
self.alpha = alpha
self.L1_wt = L1_wt
def fit(self, X, y, var_weights):
self.model = sm.GLM(endog = y, exog = X, family=self.family, var_weights=var_weights)
self.result = self.model.fit_regularized(alpha=self.alpha, L1_wt=self.L1_wt)
return self.result
def predict(self, X):
return self.result.predict(X)
在某种程度上,var_weights
实际上是数据的一部分,而不是估计器的超参数,例如alpha
或L1_wt
。所以,我认为如果你在 fit
方法中传递数组而不是传递到 class 构造函数中会更有凝聚力。
所以,当你真的想要 cross-validate 时,你可以 运行:
cross_val_score(sm_glm, X, y, scoring, fit_params={'var_weights':var_weights})
并且 fit_params
将被传递到您的自定义 .fit()
方法中。
基于 that topic I created a wrapper for statsmodels' glm
in order to use scikit's cross_val_score
. Now I need to introduce variance/analytic weights 通过 SM.GLM 的 var_weights 参数。
class Wrapper(BaseEstimator, RegressorMixin):
def __init__(self, family, alpha, L1_wt, var_weights):
self.family = family
self.alpha = alpha
self.L1_wt = L1_wt
self.var_weights = var_weights
def fit(self, X, y):
self.model = sm.GLM(endog = y, exog = X, family=self.family, var_weights = self.var_weights)
self.result = self.model.fit_regularized(alpha=self.alpha, L1_wt=self.L1_wt)
return self.result
def predict(self, X):
return self.result.predict(X)
wrapper让我成功了运行:
sm_glm = Wrapper(family, alpha, L1_wt, var_weights)
sm_glm.fit()
但是交叉验证
cross_val_score(sm_glm, x, y, cv, scoring)
不工作,因为 cross_val_score trims(在 cv 折叠之后)x 和 y,但不是 var_weights,这会导致错误:
ValueError: var weights not the same length as endog
在我看来,我需要动态地跋涉 cross_val_score
次迭代并相应地 trim var_weights
。
有什么想法可以解决这个问题吗?
我认为你的猜测是正确的:cross_val_score
没有将 weights
数组传播到 cross-validation 循环中,也没有像拆分 [=14] 那样拆分它=] 和 y
变成 k-folds。我试图用其他一些数据复制你得到的错误(受 StatsModels documentation 关于 var_weights
和 freq_weights
之间的区别的启发)并阅读回溯,看起来如果附加参数(即 var_weights
)没有通过自定义估算器实现的 fit()
方法传递,它没有被提取用于 cross-validation。
我通过以下方式解决了它:
class SMW(BaseEstimator, RegressorMixin):
def __init__(self, family, alpha, L1_wt):
self.family = family
self.alpha = alpha
self.L1_wt = L1_wt
def fit(self, X, y, var_weights):
self.model = sm.GLM(endog = y, exog = X, family=self.family, var_weights=var_weights)
self.result = self.model.fit_regularized(alpha=self.alpha, L1_wt=self.L1_wt)
return self.result
def predict(self, X):
return self.result.predict(X)
在某种程度上,var_weights
实际上是数据的一部分,而不是估计器的超参数,例如alpha
或L1_wt
。所以,我认为如果你在 fit
方法中传递数组而不是传递到 class 构造函数中会更有凝聚力。
所以,当你真的想要 cross-validate 时,你可以 运行:
cross_val_score(sm_glm, X, y, scoring, fit_params={'var_weights':var_weights})
并且 fit_params
将被传递到您的自定义 .fit()
方法中。