samaan / ml /shap_explainer.py
Copilot Sync Bot
Sync backend from main branch
26c9046
from __future__ import annotations
from typing import List
import numpy as np
import pandas as pd
import shap
from sklearn.pipeline import Pipeline
def compute_shap_explanation(pipeline: Pipeline, feature_row: dict, feature_columns: list) -> list:
"""
Returns top-3 SHAP feature contributions as a list of dicts.
"""
xgb_model = pipeline.named_steps["model"]
explainer = shap.TreeExplainer(xgb_model)
preprocessor = Pipeline(steps=pipeline.steps[:-1])
row_df = pd.DataFrame([feature_row], columns=feature_columns)
transformed = preprocessor.transform(row_df)
shap_values = explainer.shap_values(transformed)
if isinstance(shap_values, list):
probabilities = xgb_model.predict_proba(transformed)
class_index = int(np.argmax(probabilities[0]))
row_values = np.asarray(shap_values[class_index])[0]
else:
row_values = np.asarray(shap_values)[0]
top_indices = np.argsort(np.abs(row_values))[::-1][:3]
result = []
for idx in top_indices:
value = float(row_values[idx])
result.append({
"feature": feature_columns[idx],
"shap_value": round(value, 4),
"direction": "positive" if value >= 0 else "negative",
})
return result