更新scikit-learn:'SVC'对象没有属性'_probA'?

4

我们升级到了Python 3.8.2,但在使用scikit-learn时出现错误:

Traceback (most recent call last):
File "manage.py", line 16, in <module>
execute_from_command_line(sys.argv)
File "/home/ubuntu/myWebApp/.venv/lib/python3.8/site-packages/django/core/management/__init__.py", line 381, in execute_from_command_line
utility.execute()
File "/home/ubuntu/myWebApp/.venv/lib/python3.8/site-packages/django/core/management/__init__.py", line 375, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/home/ubuntu/myWebApp/.venv/lib/python3.8/site-packages/django/core/management/base.py", line 316, in run_from_argv
self.execute(*args, **cmd_options)
File "/home/ubuntu/myWebApp/.venv/lib/python3.8/site-packages/django/core/management/base.py", line 353, in execute
output = self.handle(*args, **options)
File "/home/ubuntu/myWebApp/server_modules/rss_ml_score/management/commands/rssmlscore.py", line 22, in handle
run.build_and_predict(days=options['days'], rescore=options['rescore'])
File "/home/ubuntu/myWebApp/server_modules/rss_ml_score/utils/run.py", line 96, in build_and_predict
predict_all(filename)
File "/home/ubuntu/myWebApp/server_modules/rss_ml_score/models/predict_model.py", line 135, in predict_all
voting_predicted_hard, voting_predicted_soft = predict_from_multiple_estimator(fitted_estimators, X_predict_list,
File "/home/ubuntu/myWebApp/server_modules/rss_ml_score/models/train_model.py", line 66, in predict_from_multiple_estimator
pred_prob1 = np.asarray([clf.predict_proba(X)
File "/home/ubuntu/myWebApp/server_modules/rss_ml_score/models/train_model.py", line 66, in <listcomp>
pred_prob1 = np.asarray([clf.predict_proba(X)
File "/home/ubuntu/myWebApp/.venv/lib/python3.8/site-packages/sklearn/svm/_base.py", line 662, in _predict_proba
if self.probA_.size == 0 or self.probB_.size == 0:
File "/home/ubuntu/myWebApp/.venv/lib/python3.8/site-packages/sklearn/svm/_base.py", line 759, in probA_
return self._probA
AttributeError: 'SVC' object has no attribute '_probA'

我需要使用除了sci-kit learn之外的其他库来访问_probA吗?

更新:回复评论:

导致错误的代码行是:

pred_prob1 = np.asarray([clf.predict_proba(X)
                         for clf, X in zip(estimators, X_list)])

... 调用 _base.py 中的此行:

def _predict_proba(self, X):
    X = self._validate_for_predict(X)
    if self.probA_.size == 0 or self.probB_.size == 0:

...这里调用了位于_base.py中的这行代码:

@property
def probA_(self):
    return self._probA

...导致如下错误:

AttributeError:'SVC'对象没有'_probA'属性

这段时间一直能够正常工作,但即使更新到最新的scikit-learn后,现在也无法正常工作。


你是返回 probA_,但内部实际返回的是 _probA 吗?只是好奇,因为应该是 probA_ - Chrispresso
@Chrispresso,我已经更新了帖子,并根据你的问题提供了额外的信息。 - VikR
1
请展示适配您的SVC分类器的代码。 - desertnaut
@VikR,你创建SVC时是否使用了probability=True参数?我认为只有在首先使用参数probability设置为True创建SVC对象后才能使用该功能。 - Chrispresso
@Chrispresso,确实如此,这就是我为什么问的原因。 - desertnaut
我被告知如果我升级到最新的软件包,旧的训练模型将不再起作用,所以我必须不要升级。 - VikR
3个回答

9

结果发现我必须使用与我们目前所拥有的模型相同版本的Sci-kit(scikit-learn==0.21.2)。较新版本的Sci-kit不能与我们现有的代码/模型一起使用。如果我们想要升级Sci-kit,就必须使用新版本的Sci-kit重新训练我们的模型。


3
有点晚了,但我刚刚遇到了一个非常类似的问题,并成功通过在反序列化(解包)模型之前添加以下代码来解决它:
from typing import Any, Dict

from sklearn.svm import OneClassSVM


original_oneclass_setstate = OneClassSVM.__setstate__

def __monkey_patch_oneclass_setstate__(self, state: Dict[str, Any]) -> None:
    """
    Monkey-patch the `setstate` method of the `OneClassSVM` to rename
    attributes that changed only the name from version `0.22`.
    """
    if "proba_" in state:
        state["_probA"] = state.pop("probA_")
    if "probB_" in state:
        state["_probB"] = state.pop("probB_")
    original_oneclass_setstate(self, state)

OneClassSVM.__setstate__ = __monkey_patch_oneclass_setstate__


# Deserialize the model here


我的情况几乎和你的一样,需要更新在scikit-learn==0.22上训练的模型(而不是0.21.2),以便在更新的scikit-learn~=1.0.2上运行,并且它们成功运行。
0.22版本中,模型包含probA_probB_这两个内部属性,但没有_probA_probB这两个属性(就像你的情况所示)。在更新的版本中,它们将这些属性重命名为_probA_probB(作为属性,而不是属性)。在修复之前检查模型时,我发现只有两个空的numpy数组:
'probA_': array([], dtype=float64),
'probB_': array([], dtype=float64),

所以,你可以尝试另一种方法,只需将这些属性设置为空的numpy数组,然后比较它们是否生成与旧版本0.21.2相同的预测值。

0

我也遇到了这个错误,尝试了很多方法来解决它。最后发现只是版本兼容性的问题。无论在构建模型时使用哪个版本,加载时都应该使用相同的版本。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接