我可以安全地分配给Scikit-Learn中的“ COEF_”和其他估计参数



scikit-learn建议将泡菜用于模型持久性。但是,他们注意到泡菜的局限性在Scikit-Learn或Python的不同版本方面的局限性。(另请参阅此堆叠问题)

在许多机器学习方法中,只有很少的参数从大型数据集中学到。这些估计的参数存储在属性下,例如尾随下划线,例如coef_

现在我的问题是:可以通过持续估计属性并稍后分配给它们来实现模型持久性?在Scikit-learn中,该方法对是否有安全的副作用(例如,必须设置的私有变量)在某些估计器中?

如下所示,它似乎适用于逻辑回归:

from sklearn import datasets
from sklearn.linear_model import LogisticRegression
try:
    from sklearn.model_selection import train_test_split
except ImportError:
    from sklearn.cross_validation import train_test_split
iris = datasets.load_iris()
tt_split = train_test_split(iris.data, iris.target, test_size=0.4)
X_train, X_test, y_train, y_test = tt_split
# Here we train the logistic regression
lr = LogisticRegression(class_weight='balanced')
lr.fit(X_train, y_train)
print(lr.score(X_test, y_test))     # prints 0.95
# Persisting
params = lr.get_params()
coef = lr.coef_
intercept = lr.intercept_
# classes_ is not documented as public member, 
# but not explicitely private (not starting with underscore)
classes = lr.classes_ 
lr.n_iter_ #This is meta-data. No need to persist

# Now we try to load the Classifier 
lr2 = LogisticRegression()
lr2.set_params(**params)
lr2.coef_ = coef
lr2.intercept_ = intercept
lr2.classes_ = classes
print(lr2.score(X_test, y_test)) #Prints the same: 0.95

设置单独的估计属性是不够的 - 至少在的一般情况下,所有估计器

我至少知道一个示例会失败。 LinearDiscriminantAnalysis.transform()使用私有属性_max_components

def transform(self, X):
        # ... code omitted
        return X_new[:, :self._max_components]

但是,它可能适用于某些估计器。如果您只需要特定的估算器,则最佳方法是查看估算器源代码并保存在__init__().fit()方法中设置的所有属性。

一种更通用的方法可能是保存估算器.__dict__中的所有项目。例如:

from sklearn.discriminant_analysis import LinearDiscriminantAnalysis as LDA
lda = LDA().fit([[1, 2, 3], [1, 2, 1], [4, 5, 6], [9, 9, 9]], [1, 2, 1, 2])
lda.__dict__
# {'_max_components': 1,
#  'classes_': array([1, 2]),
#  'coef_': array([[ -9.55555556,  21.55555556,  -9.55555556]]),
#  'explained_variance_ratio_': array([ 1.]),
#  'intercept_': array([-15.77777778]),
#  'means_': array([[ 2.5,  3.5,  4.5],
#         [ 5. ,  5.5,  5. ]]),
#  'n_components': None,
#  'priors': None,
#  'priors_': array([ 0.5,  0.5]),
#  'scalings_': array([[-2.51423299],
#         [ 5.67164186],
#         [-2.51423299]]),
#  'shrinkage': None,
#  'solver': 'svd',
#  'store_covariance': False,
#  'tol': 0.0001,
#  'xbar_': array([ 3.75,  4.5 ,  4.75])}

对于包含更复杂数据的估计器,例如包含多个估计器的集合,这不会是微不足道的。有关更多详细信息,请参见博客文章Scikit-Learn Pipeline持久性和JSON序列化。

不幸的是,这不会安全地将估计器带到Scikit-Learn的新版本。私有属性本质上是一个实现细节,可以在发行版之间随时改变。

相关内容

  • 没有找到相关文章

最新更新