Как отключить регуляризацию для GLM (PoissonRegressor) в sklearn? - PullRequest
0 голосов
/ 05 августа 2020

Я настраиваю модели с помощью функции PoissonRegressor в sklearn. Однако код, похоже, навязывает мою модель регуляризации, даже если я установил для параметра регуляризации значение 0. Любые идеи о том, как это остановить, будут очень признательны!

У меня есть время переменный предиктор x, который описывается базисным набором для создания матрицы прогнозирования X. Я использую X для прогнозирования (разреженного) вектора подсчета Y. Мой код выглядит следующим образом:

from sklearn.linear_model import PoissonRegressor
PR = PoissonRegressor(alpha = 0.0)
PR.fit(X,Y)

Однако полученная подгонка кажется сглаженной / упорядоченной, НЕСМОТРЯ на тот факт, что alpha = 0, то есть регуляризация (должна быть) отключена.

Чтобы проверить это, я скопировал + вставил функцию минимизации, используемую в sklearn. Функция GeneralizedLinearRegressor в моем собственном коде и протестировала ее с альфа = 0. Чтобы избежать большого блока кода, я отнесен к концу моего вопроса. Использование решателя вне объекта Regressor дает РАЗНЫЙ ответ, чем PR.fit(), но почти идентичный ответ на решение, полученное с помощью statsmodels. Это различие показано здесь.

введите описание изображения здесь

Важно отметить, что строка sklearn намного более гладкая, чем версия, созданная моим кодом / statsmodels, что позволяет предположить, что в функции PoissonRegression sklearn все еще происходит какая-то регуляризация.

Мой вопрос , затем: Как мне отключить эту (нежелательную) регуляризацию?

Спасибо!

Мой код:

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)

1 Ответ

0 голосов
/ 06 августа 2020

Ответ оказывается довольно простым: допуск по умолчанию для PoissonRegressor равен 1E-4. Изменение этого (увеличение требуемой точности подгонки) на 1E-5 устраняет эту проблему.

Почему разница между моим кодом и sklearn? целевая функция sklearn минимизирует 1 / (2 * n_samples) * sum (отклонение). Поскольку у меня есть большое количество образцов, это изменение масштаба изменяет эффективный допуск функции PoissonRegressor.

...