【发布时间】:2021-05-30 05:58:36
【问题描述】:
我不确定如何正确使用装饰器;我参考了Real Python 和Try-Except for Multiple Methods。我正在编写一个线性回归类,我意识到你需要先调用fit,然后才能进行预测,或者我的类拥有的其他方法。但是当self._fitted 标志为False 时,定义每个引发错误的方法很麻烦。所以我求助于装饰器,我不确定我是否正确使用,因为它的行为确实符合我的要求,但是它忽略了任何其他形式的错误,如 ValueError 等。在这里寻求建议。
import functools
from sklearn.exceptions import NotFittedError
def NotFitted(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
try:
return func(*args, **kwargs)
except:
raise NotFittedError
return wrapper
class LinearRegression:
def __init__(self, fit_intercept: bool = True):
self.coef_ = None
self.intercept_ = None
self.fit_intercept = fit_intercept
# a flag to turn to true once we called fit on the data
self._fitted = False
def check_shape(self, X: np.array, y: np.array):
# if X is 1D array, then it is simple linear regression, reshape to 2D
# [1,2,3] -> [[1],[2],[3]] to fit the data
if X is not None and len(X.shape) == 1:
X = X.reshape(-1, 1)
# self._features = X
# self.intercept_ = y
return X, y
def fit(self, X: np.array = None, y: np.array = None):
X, y = self.check_shape(X, y)
n_samples, n_features = X.shape[0], X.shape[1]
if self.fit_intercept:
X = np.c_[np.ones(n_samples), X]
XtX = np.dot(X.T, X)
XtX_inv = np.linalg.inv(XtX)
XtX_inv_Xt = np.dot(XtX_inv, X.T)
_optimal_betas = np.dot(XtX_inv_Xt, y)
# set attributes from None to the optimal ones
self.coef_ = _optimal_betas[1:]
self.intercept_ = _optimal_betas[0]
self._fitted = True
return self
@NotFitted
def predict(self, X: np.array):
"""
after calling .fit, you can continue to .predict to get model prediction
"""
# if self._fitted is False:
# raise NotFittedError
if self.fit_intercept:
y_hat = self.intercept_ + np.dot(X, self.coef_)
else:
y_hat = self.intercept_
return y_hat
【问题讨论】:
-
如果您对这种方法的问题是包装的
func中的错误没有传播,您可以更改装饰器中的错误处理以重新抛出错误,而不是始终使用NotFittedError。但我很困惑:除了捕捉这些错误并将它们屏蔽为NotFittedError之外,您的装饰器是否还有任何作用?我不认为_fitted有人读过吗? -
是的,这可能是我想问的,我需要在装饰器中调用
_fitted吗?
标签: python oop machine-learning scikit-learn decorator