成功解决eli5库导入问题

         最近在复现一篇文章中关于其机器学习可解释性以及可视化特征重要度中了解到了一个库包eli5,其项目官方链接戳此处:

ELI5icon-default.png?t=O83Ahttps://github.com/facebookresearch/ELI5

        eli5包的相关介绍这里就不多叙述了,简单来说就是通过一个机器学习模型,可以是线性模型、树模型等将特征数据拟合之后输出特征的重要性,帮助理解那些特征对模型最为重要,可以帮助特征的选择。  

        本以为是一个平平无奇的调包任务,麻木的通过pip下载eli5,该环节没有任何的问题,非常的顺利的看到了Successfully。但是当我导入包的时候意外发生了,直接发生了如下错误,这一大串的红色给我整蒙了,第一次碰到因为导入一整个库包就直接报错的。

import eli5
---------------------------------------------------------------------------
ImportError                               Traceback (most recent call last)
Cell In[17], line 1
----> 1 import eli5

File c:\Users\AppData\Local\Programs\Python\Python311\Lib\site-packages\eli5\__init__.py:13
      6 from .formatters import (
      7     format_as_html,
      8     format_html_styles,
      9     format_as_text,
     10     format_as_dict,
     11 )
     12 from .explain import explain_weights, explain_prediction
---> 13 from .sklearn import explain_weights_sklearn, explain_prediction_sklearn
     14 from .transform import transform_feature_names
     17 try:

File c:\Users\AppData\Local\Programs\Python\Python311\Lib\site-packages\eli5\sklearn\__init__.py:3
      1 # -*- coding: utf-8 -*-
      2 from __future__ import absolute_import
----> 3 from .explain_weights import (
      4     explain_weights_sklearn,
      5     explain_linear_classifier_weights,
      6     explain_linear_regressor_weights,
      7     explain_rf_feature_importance,
      8     explain_decision_tree,
      9 )
     10 from .explain_prediction import (
     11     explain_prediction_sklearn,
     12     explain_prediction_linear_classifier,
     13     explain_prediction_linear_regressor,
     14 )
     15 from .unhashing import (
     16     InvertableHashingVectorizer,
     17     FeatureUnhasher,
     18     invert_hashing_and_fit,
     19 )

File c:\Users\AppData\Local\Programs\Python\Python311\Lib\site-packages\eli5\sklearn\explain_weights.py:78
     73 from eli5.transform import transform_feature_names
     74 from eli5._feature_importances import (
     75     get_feature_importances_filtered,
     76     get_feature_importance_explanation,
     77 )
---> 78 from .permutation_importance import PermutationImportance
     81 LINEAR_CAVEATS = """
     82 Caveats:
     83 1. Be careful with features which are not
   (...)
     90    classification result for most examples.
     91 """.lstrip()
     93 HASHING_CAVEATS = """
     94 Feature names are restored from their hashes; this is not 100% precise
     95 because collisions are possible. For known collisions possible feature names
   (...)
     99 the result is positive.
    100 """.lstrip()

File c:\Users\AppData\Local\Programs\Python\Python311\Lib\site-packages\eli5\sklearn\permutation_importance.py:7
      5 import numpy as np
      6 from sklearn.model_selection import check_cv
----> 7 from sklearn.utils.metaestimators import if_delegate_has_method
      8 from sklearn.utils import check_array, check_random_state
      9 from sklearn.base import (
     10     BaseEstimator,
     11     MetaEstimatorMixin,
     12     clone,
     13     is_classifier
     14 )

ImportError: cannot import name 'if_delegate_has_method' from 'sklearn.utils.metaestimators' (c:\Users\AppData\Local\Programs\Python\Python311\Lib\site-packages\sklearn\utils\metaestimators.py)

        不过报错已经发生,那我们就从上往下详细看一下报错内容吧。首先看到报错直接出在了import 部分,再往下看发现是库包中的sklearn的相关依赖的导入错误。顺着看到最后发现是permutation_importance.py 模块中 if_delegate_has_method 的导入问题。此时我们不难猜到报错原因是sklearn与eli5之间的版本兼容问题, 貌似是由于sklearn 弃用了 if_delegate_has_method 装饰器并将其替换为另一个名为 available_if 的装饰器导致的导入错误。

        既然问题原因明了,其解决方法通过查询eli5项目的issue发现一位大佬的回答,话不多说开始尝试。首先根据报错反馈将permutation_importance.py的路径复制下来黏贴到资源管理器中,会直接打开该Python文件。将第七行导入项的 if_delegate_has_method

from sklearn.utils.metaestimators import if_delegate_has_method

更改为:

from sklearn.utils.metaestimators import available_if

然后在permutation_importance.py模块中往下翻,找到使用了 if_delegate_has_method 装饰器的代码

    @if_delegate_has_method(delegate='wrapped_estimator_')
    def score(self, X, y=None, *args, **kwargs):
        return self.wrapped_estimator_.score(X, y, *args, **kwargs)

    @if_delegate_has_method(delegate='wrapped_estimator_')
    def predict(self, X):
        return self.wrapped_estimator_.predict(X)

    @if_delegate_has_method(delegate='wrapped_estimator_')
    def predict_proba(self, X):
        return self.wrapped_estimator_.predict_proba(X)

    @if_delegate_has_method(delegate='wrapped_estimator_')
    def predict_log_proba(self, X):
        return self.wrapped_estimator_.predict_log_proba(X)

    @if_delegate_has_method(delegate='wrapped_estimator_')
    def decision_function(self, X):
        return self.wrapped_estimator_.decision_function(X)

 将其改为相应的 available_if 装饰器:

    @available_if(_estimator_has('wrapped_estimator_'))
    def score(self, X, y=None, *args, **kwargs):
        return self.wrapped_estimator_.score(X, y, *args, **kwargs)

    @available_if(_estimator_has('wrapped_estimator_'))
    def predict(self, X):
        return self.wrapped_estimator_.predict(X)

    @available_if(_estimator_has('wrapped_estimator_'))
    def predict_proba(self, X):
        return self.wrapped_estimator_.predict_proba(X)

    @available_if(_estimator_has('wrapped_estimator_'))
    def predict_log_proba(self, X):
        return self.wrapped_estimator_.predict_log_proba(X)

    @available_if(_estimator_has('wrapped_estimator_'))
    def decision_function(self, X):
        return self.wrapped_estimator_.decision_function(X)

 此时会发现装饰器中的 _estimator_has 函数未被定义,此时只需在上述代码的前面定义如下函数(注意缩进):

    def _estimator_has(attr):
        def check(self):
            return hasattr(self.estimator, attr)

        return check

然后保存该模块即可。

        接下来让我们尝试验证改动是否有效。执行下述代码:

import eli5
from eli5.sklearn import PermutationImportance  # 排列重要性
from sklearn.ensemble import RandomForestClassifier

model = RandomForestClassifier(n_estimators=100,bootstrap=True,max_features='sqrt') # bootstrap

# fit data
model.fit(X_train,y_train)
perm = PermutationImportance(model,random_state=10).fit(X_test,y_test)
eli5.show_weights(perm,feature_names=X_test.columns.tolist())

成功输出相关的特征重要性,导入成功!

        通过上述输出对比论文结果,对比一致说明改动有效,不过eli5项目已经基本上没人维护了,差不多已经凉了哈哈哈,如果觉得麻烦也可以放弃使用eli5转而去使用shap库也是可以的。

        第一次写Blog,有不好的地方欢迎各位评论区指正,祝愿大家前程似锦!

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值