状态模型 + 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_weightsfreq_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实际上是数据的一部分,而不是估计器的超参数,例如alphaL1_wt。所以,我认为如果你在 fit 方法中传递数组而不是传递到 class 构造函数中会更有凝聚力。

所以,当你真的想要 cross-validate 时,你可以 运行:

cross_val_score(sm_glm, X, y, scoring, fit_params={'var_weights':var_weights})

并且 fit_params 将被传递到您的自定义 .fit() 方法中。