如何在不拟合的情况下实例化具有已知系数的 Scikit-Learn 线性模型
Posted
技术标签:
【中文标题】如何在不拟合的情况下实例化具有已知系数的 Scikit-Learn 线性模型【英文标题】:How to instantiate a Scikit-Learn linear model with known coefficients without fitting it 【发布时间】:2020-08-12 22:39:26 【问题描述】:背景
作为实验的一部分,我正在测试各种保存的模型,但其中一个模型来自我编写的算法,而不是来自 sklearn 模型拟合。
但是,我的自定义模型仍然是线性模型,因此我想实例化一个 LinearModel
实例并将 coef_
和 intercept_
属性设置为我的自定义拟合算法中的值,以便我可以将其用于预测。
到目前为止我尝试了什么:
from sklearn.linear_model import LinearRegression
my_intercepts = np.ones(2)
my_coefficients = np.random.randn(2, 3)
new_model = LinearRegression()
new_model.intercept_ = my_intercepts
new_model.coef_ = my_coefficients
它似乎可以用于预测:
X_test = np.random.randn(5, 3)
new_model.predict(X_test)
它通过了这个测试:
from sklearn.utils.validation import check_is_fitted
check_is_fitted(new_model)
问题
这个方法好吗?感觉就像是 hack,我怀疑有一种“正确”的方法可以做到这一点。
【问题讨论】:
不确定是否有任何“正确”的方法可以做到这一点,从某种意义上说,我非常怀疑这种用法在构建 scikit-learn 的人的脑海中是否存在,但因为它通过了测试并且没有给出.predict
的错误,我看不到任何问题。
【参考方案1】:
虽然问题中的简单技术有效,但危险在于您稍后可能会调用对象的 fit 方法并覆盖您的系数。
如果模型仅用于预测,则更“正确”的方法是从 sklearn 的类继承并重载 fit 方法,如下所示:
class LinearPredictionModel(LinearRegression):
"""
This model is for prediction only. It has no fit method.
You can initialize it with fixed values for coefficients
and intercepts.
Parameters
----------
coef, intercept : arrays
See attribute descriptions below.
Attributes
----------
coef_ : array of shape (n_features, ) or (n_targets, n_features)
Coefficients of the linear model. If there are multiple targets
(y 2D), this is a 2D array of shape (n_targets, n_features),
whereas if there is only one target, this is a 1D array of
length n_features.
intercept_ : float or array of shape of (n_targets,)
Independent term in the linear model.
"""
def __init__(self, coef=None, intercept=None):
if coef is not None:
coef = np.array(coef)
if intercept is None:
intercept = np.zeros(coef.shape[0])
else:
intercept = np.array(intercept)
assert coef.shape[0] == intercept.shape[0]
else:
if intercept is not None:
raise ValueError("Provide coef only or both coef and intercept")
self.intercept_ = intercept
self.coef_ = coef
def fit(self, X, y):
"""This model does not have a fit method."""
raise NotImplementedError("model is only for prediction")
然后,实例化模型如下:
new_model = LinearPredictionModel(coef=my_coefficients, intercept=my_intercepts)
我认为唯一“正确”的方法是让我在 fit 方法中使用我的自定义算法完全实现一个新类。但是对于在 scikit-learn 环境中测试系数的简单需求,这种方法似乎可以正常工作。
【讨论】:
【参考方案2】:这种方法非常适用于原始方法(例如线性回归),但是您如何针对更复杂的模型(例如套索或弹性网络或...)进行调整。似乎可以像这样修改线性回归器,但套索回归器仍然会抛出错误(不适合的投诉:As in this question, which is indicated as a duplicate of the above.
【讨论】:
好点。我没有研究其他类型的模型。 In the documentation 它说check_is_fitted
方法通过“验证拟合属性的存在(以尾随下划线结尾)”来工作。所以大概你需要确保为每个必需的属性设置一个值。
@Bill 这很有趣。我自己也会调查的。如果它可以告诉我缺少哪些属性,那将对我有很大帮助。以上是关于如何在不拟合的情况下实例化具有已知系数的 Scikit-Learn 线性模型的主要内容,如果未能解决你的问题,请参考以下文章
如何在不实例化整个 Laravel 的情况下加载 Laravel 模型?
如何在不使用 Nib 的情况下实例化和调用 UIView 子类