将系数正则化添加到 Statsmodels(或 Patsy)
Adding Regularization of Coefficients to Statsmodels (or Patsy)
鉴于我有以下 patsy 公式,
'y ~ a + b + c'
并将其传递给statsmodels.ols,如何向回归系数添加正则化项?
在这种情况下,我希望创建自己的惩罚函数,而不是简单地使用岭、套索或 elasticnet 回归。
这是一个可重现的示例,其中包含与我的问题相似的数据:
import numpy as np
import pandas as pd
import statsmodels.api as sm
import statsmodels.formula.api as smf
a = np.clip(np.random.normal(loc=60, scale=40, size=(100)), 0, 100)
b = np.clip(np.random.normal(loc=40, scale=40, size=(100)), 0, 100)
c = np.clip(np.random.normal(loc=20, scale=20, size=(100)), 0, 100)
y = (
32 * (a + 8 * np.random.random(a.shape))
+ 21 * (b + 5 * np.random.random(b.shape))
+ 36 * (c + 5 * np.random.random(c.shape))
) + (50 * np.random.random(a.shape))
data = pd.DataFrame(
data=np.array([a, b, c, y]).T,
columns=['a', 'b', 'c', 'y']
)
formula = 'y ~ a + b + c'
mod = smf.ols(formula=formula, data=data,)
OLS 依靠线性代数计算来计算参数估计值,因此无法直接处理需要非线性优化的扩展。
具有高斯族的 GLM 等效于 OLS,但使用(可选)非线性优化来查找最大似然参数估计值。因此,对 OLS 的一些扩展在 GLM 中更容易实现。
statsmodels 有一个通用的惩罚设置,可以添加到 fit
基于非线性优化的任何模型,如 scipy 中的模型。
这是实验性的,没有得到很好的宣传,但形成了内部重用的设置,例如在广义加法模型 GAM 中。
我们可以将现有模型与提供的惩罚 class 结合起来,其中优化假设惩罚对数似然函数是平滑的或平滑的,例如平滑的 SCAD 惩罚 https://github.com/statsmodels/statsmodels/blob/master/statsmodels/base/_penalties.py#L314
实验意味着已经针对多种情况进行了测试,但可能不适用于所有可以与之组合的模型,或者可能需要进行更改才能使其在这些模型上正常工作。此外,一些 API 决定和选项仍然是悬而未决的问题,可能会发生变化。
例如要定义 PenalizedGLM,我们只需将 PenalizedMixin 和 GLM 子class,并在创建模型时提供系列和惩罚实例:
class GLMPenalized(PenalizedMixin, GLM):
pass
penalty = smpen.SCADSmoothed(0.1, c0=0.0001)
mod = GLMPenalized(y, x, family=family.Gaussian(), penal=penalty)
https://github.com/statsmodels/statsmodels/blob/master/statsmodels/base/tests/test_penalized.py#L34
链接
https://github.com/statsmodels/statsmodels/pull/4576 添加了 PenalizedMixin 的 PR
https://github.com/statsmodels/statsmodels/pull/4683 用来超高筛选的PR
https://github.com/statsmodels/statsmodels/pull/5481 PR 添加 GAM
鉴于我有以下 patsy 公式,
'y ~ a + b + c'
并将其传递给statsmodels.ols,如何向回归系数添加正则化项?
在这种情况下,我希望创建自己的惩罚函数,而不是简单地使用岭、套索或 elasticnet 回归。
这是一个可重现的示例,其中包含与我的问题相似的数据:
import numpy as np
import pandas as pd
import statsmodels.api as sm
import statsmodels.formula.api as smf
a = np.clip(np.random.normal(loc=60, scale=40, size=(100)), 0, 100)
b = np.clip(np.random.normal(loc=40, scale=40, size=(100)), 0, 100)
c = np.clip(np.random.normal(loc=20, scale=20, size=(100)), 0, 100)
y = (
32 * (a + 8 * np.random.random(a.shape))
+ 21 * (b + 5 * np.random.random(b.shape))
+ 36 * (c + 5 * np.random.random(c.shape))
) + (50 * np.random.random(a.shape))
data = pd.DataFrame(
data=np.array([a, b, c, y]).T,
columns=['a', 'b', 'c', 'y']
)
formula = 'y ~ a + b + c'
mod = smf.ols(formula=formula, data=data,)
OLS 依靠线性代数计算来计算参数估计值,因此无法直接处理需要非线性优化的扩展。
具有高斯族的 GLM 等效于 OLS,但使用(可选)非线性优化来查找最大似然参数估计值。因此,对 OLS 的一些扩展在 GLM 中更容易实现。
statsmodels 有一个通用的惩罚设置,可以添加到 fit
基于非线性优化的任何模型,如 scipy 中的模型。
这是实验性的,没有得到很好的宣传,但形成了内部重用的设置,例如在广义加法模型 GAM 中。
我们可以将现有模型与提供的惩罚 class 结合起来,其中优化假设惩罚对数似然函数是平滑的或平滑的,例如平滑的 SCAD 惩罚 https://github.com/statsmodels/statsmodels/blob/master/statsmodels/base/_penalties.py#L314
实验意味着已经针对多种情况进行了测试,但可能不适用于所有可以与之组合的模型,或者可能需要进行更改才能使其在这些模型上正常工作。此外,一些 API 决定和选项仍然是悬而未决的问题,可能会发生变化。
例如要定义 PenalizedGLM,我们只需将 PenalizedMixin 和 GLM 子class,并在创建模型时提供系列和惩罚实例:
class GLMPenalized(PenalizedMixin, GLM):
pass
penalty = smpen.SCADSmoothed(0.1, c0=0.0001)
mod = GLMPenalized(y, x, family=family.Gaussian(), penal=penalty)
https://github.com/statsmodels/statsmodels/blob/master/statsmodels/base/tests/test_penalized.py#L34
链接 https://github.com/statsmodels/statsmodels/pull/4576 添加了 PenalizedMixin 的 PR https://github.com/statsmodels/statsmodels/pull/4683 用来超高筛选的PR https://github.com/statsmodels/statsmodels/pull/5481 PR 添加 GAM