Explanation#

Recommendation explainability for debugging and user trust.

Quick Start#

from corerec.explanation import FeatureExplainer

explainer = FeatureExplainer(
    item_features=item_features,
    user_preferences=user_prefs,
    templates={"category": "Matches your interest in {value}"}
)
explanation = explainer.explain(item_id=42, context={"user_id": 5})
print(explanation.text)

API Reference#

Base classes for explanation generation.

Explanations help users understand why items were recommended, increasing trust and engagement.

class corerec.explanation.base.Explanation(item_id: ~typing.Any, text: str, explanation_type: str = 'generic', confidence: float = 1.0, supporting_items: ~typing.List[~typing.Any] = <factory>, features: ~typing.Dict[str, ~typing.Any] = <factory>)[source]#

Bases: object

An explanation for a recommendation.

item_id: Any#

the item being explained

text: str#

human-readable explanation

explanation_type: str = 'generic'#

category of explanation

confidence: float = 1.0#

how confident we are in this explanation

supporting_items: List[Any]#

items that support this explanation

features: Dict[str, Any]#

key features that drove the recommendation

class corerec.explanation.base.BaseExplainer(name: str | None = None)[source]#

Bases: ABC

Abstract base class for explanation generators.

Explainers take recommendation context and generate human-readable explanations for why items were recommended.

Common explanation types: - “collaborative”: “Users like you also bought…” - “content”: “Because you liked similar items…” - “popularity”: “Trending in your area…” - “personalized”: “Based on your preferences…”

abstractmethod explain(item_id: Any, context: Dict[str, Any], **kwargs) → Explanation[source]#

Generate an explanation for a recommended item.

Parameters:
  • item_id – the item to explain

  • context – user context, recommendation context, etc.

  • **kwargs – explainer-specific parameters

Returns:

Explanation object

explain_batch(item_ids: List[Any], context: Dict[str, Any], **kwargs) → List[Explanation][source]#

Generate explanations for multiple items.

Default implementation loops; subclasses can optimize.

Feature-Based Explainer#

Feature-based Explanations

Generate explanations based on matching features between user preferences and item attributes.

class corerec.explanation.feature_based.FeatureExplainer(item_features: Dict[Any, Dict[str, Any]] | None = None, user_preferences: Dict[Any, Dict[str, Any]] | None = None, templates: Dict[str, str] | None = None, feature_extractor: Callable[[Any], Dict[str, Any]] | None = None, preference_extractor: Callable[[Any], Dict[str, Any]] | None = None, name: str = 'feature_explainer')[source]#

Bases: BaseExplainer

Generates explanations based on feature matches.

Looks at which features of the item match user preferences and generates explanations like: - “Because you liked action movies” - “Similar to items in your history” - “Matches your preferred price range”

Example:

explainer = FeatureExplainer(
    item_features=item_feature_dict,
    user_preferences=user_pref_dict,
    templates={
        'category': "Because you like {value}",
        'brand': "From {value}, a brand you've purchased before",
    }
)

explanation = explainer.explain(item_id=123, context={'user_id': 456})
__init__(item_features: Dict[Any, Dict[str, Any]] | None = None, user_preferences: Dict[Any, Dict[str, Any]] | None = None, templates: Dict[str, str] | None = None, feature_extractor: Callable[[Any], Dict[str, Any]] | None = None, preference_extractor: Callable[[Any], Dict[str, Any]] | None = None, name: str = 'feature_explainer')[source]#
Parameters:
  • item_features – dict mapping item_id -> feature_dict

  • user_preferences – dict mapping user_id -> preference_dict

  • templates – templates for each feature type

  • feature_extractor – function(item_id) -> features (alternative to dict)

  • preference_extractor – function(user_id) -> preferences

  • name – identifier

explain(item_id: Any, context: Dict[str, Any], **kwargs) → Explanation[source]#

Generate feature-based explanation.

class corerec.explanation.feature_based.HistoryExplainer(user_history: Dict[Any, List[Any]] | None = None, item_similarity: Callable[[Any, Any], float] | None = None, item_names: Dict[Any, str] | None = None, name: str = 'history_explainer')[source]#

Bases: BaseExplainer

Explains based on similar items in user history.

Generates explanations like: - “Because you watched Movie X” - “Similar to items you purchased recently”

__init__(user_history: Dict[Any, List[Any]] | None = None, item_similarity: Callable[[Any, Any], float] | None = None, item_names: Dict[Any, str] | None = None, name: str = 'history_explainer')[source]#
Parameters:
  • user_history – dict mapping user_id -> list of interacted item_ids

  • item_similarity – function(item_a, item_b) -> similarity score

  • item_names – dict mapping item_id -> display name

  • name – identifier

explain(item_id: Any, context: Dict[str, Any], **kwargs) → Explanation[source]#

Generate history-based explanation.

Generative Explainer#

Generative Explanations using LLMs

Generate natural language explanations using language models. More flexible and natural than template-based approaches.

class corerec.explanation.generative.GenerativeExplainer(llm: Any | None = None, llm_fn: Callable[[str], str] | None = None, item_context_fn: Callable[[Any], Dict[str, Any]] | None = None, user_context_fn: Callable[[Any], Dict[str, Any]] | None = None, system_prompt: str | None = None, max_length: int = 100, name: str = 'generative_explainer')[source]#

Bases: BaseExplainer

Generates explanations using a language model.

Can use any LLM (OpenAI, local models, etc) to generate natural, context-aware explanations.

Example:

explainer = GenerativeExplainer(
    llm=openai_client,
    item_context_fn=get_item_info,
    user_context_fn=get_user_profile,
)

explanation = explainer.explain(item_id=123, context={'user_id': 456})
# "Based on your interest in science fiction and recent views of
#  Blade Runner, you might enjoy this cyberpunk thriller..."
__init__(llm: Any | None = None, llm_fn: Callable[[str], str] | None = None, item_context_fn: Callable[[Any], Dict[str, Any]] | None = None, user_context_fn: Callable[[Any], Dict[str, Any]] | None = None, system_prompt: str | None = None, max_length: int = 100, name: str = 'generative_explainer')[source]#
Parameters:
  • llm – LLM client with a generate/complete method

  • llm_fn – simple function(prompt) -> response (alternative to client)

  • item_context_fn – function(item_id) -> item context dict

  • user_context_fn – function(user_id) -> user context dict

  • system_prompt – system prompt for the LLM

  • max_length – max explanation length

  • name – identifier

explain(item_id: Any, context: Dict[str, Any], **kwargs) → Explanation[source]#

Generate explanation using LLM.

explain_batch(item_ids: List[Any], context: Dict[str, Any], **kwargs) → List[Explanation][source]#

Batch explanation generation.

For LLMs that support batching, this can be more efficient.