Moh*_*mad 3 pipeline classification treemodel scikit-learn shap
我正在使用 sklearn 管道进行分类任务,如下所示:
from sklearn.datasets import fetch_openml
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.impute import SimpleImputer
from sklearn.compose import ColumnTransformer
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import OrdinalEncoder
import shap
# -----------------------------------------------------------------------------
# Data
# -----------------------------------------------------------------------------
X, y = fetch_openml("titanic", version=1, as_frame=True, return_X_y=True)
categorical_columns = ["pclass", "sex", "embarked"]
numerical_columns = ["age", "sibsp", "parch", "fare"]
X = X[categorical_columns + numerical_columns] # [1309, 7] , there is Nan values.
X_train, X_test, y_train, y_test = train_test_split(X, y, stratify=y, random_state=42)
# -----------------------------------------------------------------------------
# Data preprocessing
# -----------------------------------------------------------------------------
categorical_encoder = OrdinalEncoder(
handle_unknown="use_encoded_value", unknown_value=-1, encoded_missing_value=-1
)
numerical_imputer = SimpleImputer(strategy="mean")
preprocessing = ColumnTransformer(
[
("cat", categorical_encoder, categorical_columns),
("num", numerical_imputer, numerical_columns),
],
verbose_feature_names_out=False,
)
# -----------------------------------------------------------------------------
# Pipeline
# -----------------------------------------------------------------------------
rf = Pipeline(
[
("preprocess", preprocessing),
("classifier", RandomForestClassifier(random_state=42)),
]
)
rf.fit(X_train, y_train)
print(f"RF train accuracy: {rf.score(X_train, y_train):.3f}")
print(f"RF test accuracy: {rf.score(X_test, y_test):.3f}")
# -----------------------------------------------------------------------------
# Shap
# -----------------------------------------------------------------------------
explainer = shap.Explainer(rf["classifier"], feature_names=rf["preprocess"].get_feature_names_out())
X_test_processed = rf['preprocess'].transform(X_test)
shap_values = explainer(X_test_processed)
Run Code Online (Sandbox Code Playgroud)
然而,当我尝试获取 Shap 图时,出现以下错误:
shap.summary_plot(shap_values, X_test_processed)
shap.summary_plot(shap_values, X_test_processed, plot_type="bar")
shap.plots.beeswarm(shap_values)
shap.plots.bar(shap_values)
我究竟做错了什么?请让我知道解决这个问题的任何想法。
之后,shap_values有 shape (328, 7, 2),并且 beeswarm 错误消息是最有用的:一切都只期望一个二维数组。由于某种原因,你得到了两个类的解释,而不仅仅是正类的解释(负类的解释正好与那些类相反);把所有地方都放在[:, :, 1]后面shap_values,情节就会为我显示。
我已经在 Colab 上对此进行了测试,但这并不容易允许 python 3.8,因此也不允许 sklearn 1.1,所以我必须进行一些修改。如果它不适合您,请告诉我,我将在本地构建一个更紧密的环境。
理解为什么shap 为您提供这两个类的解释仍然是件好事。我确实注意到它y有明确的 pandas 类型,但转换为 int 不会改变任何东西。
| 归档时间: |
|
| 查看次数: |
2706 次 |
| 最近记录: |