Python 如何在sklearn中禁用GLMs(泊松回归器)的正则化?
我在sklearn中使用泊松回归函数拟合模型。然而,代码似乎对我的模型施加了一种未要求的正则化,即使我已将正则化参数设置为0。任何关于如何阻止这种情况的想法都将不胜感激 我有一个时变预测器x,它由一个基集来描述,以生成预测矩阵x。我使用x来预测(稀疏)计数向量Y。我的代码如下所示:Python 如何在sklearn中禁用GLMs(泊松回归器)的正则化?,python,scikit-learn,regression,non-linear-regression,poisson,Python,Scikit Learn,Regression,Non Linear Regression,Poisson,我在sklearn中使用泊松回归函数拟合模型。然而,代码似乎对我的模型施加了一种未要求的正则化,即使我已将正则化参数设置为0。任何关于如何阻止这种情况的想法都将不胜感激 我有一个时变预测器x,它由一个基集来描述,以生成预测矩阵x。我使用x来预测(稀疏)计数向量Y。我的代码如下所示: from sklearn.linear_model import PoissonRegressor PR = PoissonRegressor(alpha = 0.0) PR.fit(X,Y) 但是,尽管alpha
from sklearn.linear_model import PoissonRegressor
PR = PoissonRegressor(alpha = 0.0)
PR.fit(X,Y)
但是,尽管alpha=0
,也就是说,(应该)禁用了正则化,但最终的拟合似乎是平滑/正则化的
为了测试这一点,我复制并粘贴了sklearn的GeneralizedLinearRegressor函数中使用的最小化函数到我自己的代码中,并用alpha=0对其进行了测试。为了避免出现一大块代码,我将把它放在问题的底部。在回归器对象外部使用解算器会给出与PR.fit()
不同的答案,但与使用statsmodels获得的解决方案的答案几乎相同。这里说明了这种差异
重要的是,sklearn行比我的代码/statsmodels生成的版本平滑得多,这表明sklearn-poisson回归函数中仍然存在某种正则化
那么,我的问题是:
如何禁用此(不需要的)正则化
谢谢
我的代码:
from scipy.optimize import minimize
from sklearn._loss.glm_distribution import PoissonDistribution
from sklearn.utils.optimize import _check_optimize_result
from sklearn.linear_model._glm.link import LogLink
alpha = 0
def _safe_lin_pred(X, coef):
"""Compute the linear predictor taking care if intercept is present."""
if coef.size == X.shape[1] + 1:
return X @ coef[1:] + coef[0]
else:
return X @ coef
def _y_pred_deviance_derivative(coef, X, y, family,link):
"""Compute y_pred and the derivative of the deviance w.r.t coef."""
lin_pred = _safe_lin_pred(X, coef)
y_pred = link.inverse(lin_pred)
d1 = link.inverse_derivative(lin_pred)
temp = d1 * family.deviance_derivative(y, y_pred)
if coef.size == X.shape[1] + 1:
devp = np.concatenate(([temp.sum()], temp @ X))
else:
devp = temp @ X # same as X.T @ temp
return y_pred, devp
# Same as PoissonRegressor, but with regularization removed.
def func(coef, X, y,alpha,family,link):
y_pred, devp = _y_pred_deviance_derivative(
coef, X, y,family,link
)
coef_scaled = alpha * coef
dev = family.deviance(y, y_pred)
obj = 0.5 * dev + 0.5 * (coef @ coef_scaled)
objp = 0.5 * devp
objp += coef_scaled
return obj, objp
args = (X, Y ,alpha,PoissonDistribution(),LogLink())
coef0 = np.ones(X.shape[1])
opt_res = minimize(
func, coef0, method=method, jac=True,
options={
"maxiter": self.max_iter,
"iprint": (self.verbose > 0) - 1,
"gtol": self.tol,
"ftol": 1e3*np.finfo(float).eps,
},
args=args)
答案很简单:泊松回归器的默认公差为1E-4。将此项(增加所需的配合精度)更改为1E-5可纠正此问题
为什么我的代码和sklearn之间存在差异?sklearn目标函数最小化1/(2*n_样本)*和(偏差)。由于我有大量的样本,这种重新缩放会改变泊松回归函数的有效容差。这并不能真正回答为什么尽管设置了
alpha=0.0
,但我的解决方法是使用GridSearchCV
,因为它允许将此参数设置为0