Skip to main content
Affiliate marketplaces use AI models to recommend financial products and predict each user’s approval odds for credit cards, personal loans, and insurance. Pairing each recommendation with specific reasoning for why a user is likely to be approved drives strong incremental sign-up uplift from users who interact with their odds. OuterProduct bolts onto your existing approval-odds model without replacing it, adding a reasoning engine that runs at marketplace volume and leaves the production recommendation path untouched. This guide walks you through wrapping your existing approval-odds model in a reasoning app with intelligence at three levels:
  • Recommender model: what the model does in aggregate, how it aligns with marketplace KPIs and product-partner constraints, and its data efficiency for feature sourcing and model improvement.
  • Patterns and trends: fingerprinting user cohorts and tracking how approval and conversion patterns emerge and evolve.
  • Cases: for one user, why a product was recommended (or why their odds are low) and what would flip them, in real time.
1

Distill your approval-odds model

Point at historical user data via a connector, wrap your approval-odds endpoint as a Predictor, and pass it as teacher to op.reasoning.fit. OuterProduct trains a reasoning engine alongside your recommender and leaves the production recommendation path untouched.
import outerproduct as op

op.init()

# Historical users + approval outcomes (for training) — already in
# Databricks. Replace the angle-bracket placeholders below with your
# workspace's values; `connector_credential_name` references a Databricks
# credential you've already added in console.outerproduct.com.
connector = op.DatabricksConnector(
    server_hostname="<workspace>.cloud.databricks.com",
    http_path="/sql/1.0/warehouses/<warehouse-id>",
    catalog="<catalog>",
    schema_name="<schema>",
    connector_credential_name="marketplace-prod",
)
dataset = connector.table("recommendations_train")

# Your production scorer — typically a Databricks Model Serving endpoint.
teacher = op.model.Predictor(
    "https://marketplace.example.com/approval-odds",
    headers={"Authorization": "Bearer ..."},
)

reasoning_model = op.reasoning.fit(dataset, teacher=teacher).wait()
See the Connectors guide for Databricks, Snowflake, and S3 sources, and the Training guide for full distillation details.
2

Plug in the live user stream

Marketplaces see a constant stream of users browsing for products, each scored on arrival. Pull the day’s batch from your warehouse using the same feature schema as training and pass it through the reasoning engine. Predictions come back paired in real time with the rich context that powers every level of the app.
import pandas as pd
from databricks import sql

with sql.connect(**databricks_config) as cnx:
    users_today = pd.read_sql(
        "SELECT * FROM marketplace.users_today",
        cnx,
    )

today = op.LocalDataset.from_pandas(users_today).upload()
predictions, reasoning = reasoning_model.predict_and_explain(today)
3

Reason at three altitudes

Use the predictions and reasoning context to power every level of your marketplace app -from portfolio-wide KPIs down to a single user’s personalized recommendation.

Scoring engine - KPIs, drivers, and drift

Track headline KPIs (approval rate, conversion lift, sign-ups) over time, watch for anomalies and drift, and characterize the features driving approval odds. Because get_global_drivers() exposes the features the model relies on.
importance = reasoning_model.get_global_drivers()
for name, score in zip(importance.feature_names, importance.attributions):
    print(f"{name}: {score:.4f}")

User patterns - recurring approval profiles

Fit a PatternTracker on the approved band to surface the dominant combinations of features that drive recommendation outcomes. Each pattern is an executable filter with precision and lift stats, ready to apply to live users.
pt = op.reasoning.pattern_tracker.fit(
    reasoning_model, dataset, target_range=(0.5, None)
).wait()
for fp in pt.patterns:
    print(f"{fp.label}: precision={fp.precision:.2f} lift={fp.lift:.2f}")

# Score live users: which patterns each one matches.
matches = pt.transform(today)
distribution = pt.distribution(today)
See the Pattern Tracker guide for the full API including partition and labeling options.

Individual users - explanation and scenario

For one user, pair the explanation with a counterfactual scenario using scenario(). The explanation is the personalized “why this product fits you” that builds confidence for strong applicants and drives sign-ups. For weaker applicants the scenario doubles as a credit-advisor recommendation - specific steps to improve their approval likelihood - and as operator-facing traceability linking every recommendation back to its data inputs in one click.
user = op.LocalDataset.from_pandas(users_today.iloc[[42]]).upload()

prediction, explanation = reasoning_model.predict_and_explain(user)
result = reasoning_model.scenario(user, target_class=1, max_steps=10)

for cf in result.queries[0].counterfactuals:
    print(f"If the user changes {cf.n_changes} factor(s), this product fits:")
    for feature, change in cf.changes.items():
        print(f"  {feature}: {change.before}{change.after}")

Where to go next

Explanations

Feature attributions and rule-based explanations for every prediction.

Counterfactuals

Control scenario search and read the returned ScenarioResult.