Skip to content

mlgorithm/orchid-ranker

Orchid Ranker

PyPI version Python License

A first-class adaptive-learning engine for products where user outcomes matter more than short-term clicks.

Orchid Ranker is built for systems where the user is getting better at something over time: adaptive learning, corporate training, tutoring, onboarding, rehabilitation, fitness progression, and skill-based practice. It combines learner-state tracking, prerequisite-aware candidate selection, live learner-state updates, progression metrics, and safe fallback patterns.

It is not a generic CTR, ads, social-feed, or movie-recommendation model zoo. The core question is: what should this learner work on next so they make measurable progress?

Quickstart

pip install 'orchid-ranker[adaptive]'
import pandas as pd
from orchid_ranker import AdaptiveRanker

outcomes = pd.read_csv("learner_outcomes.csv")  # learner_id, item_id, correct, ts
catalog = pd.read_csv("exercise_catalog.csv")   # item_id, concept_id, difficulty, item_text

ranker = AdaptiveRanker(
    kt_backbone="saint+",
    policy="auto",
    epochs=2,
    d_model=32,
).fit_kt(
    outcomes.merge(catalog, on="item_id"),
    correct_col="correct",
    concept_col="concept_id",
    item_difficulty_col="difficulty",
)

ranker.fit_semantic_items(catalog, text_col="item_text", metadata_cols=["concept_id"])
ranked = ranker.recommend(learner_id="7", candidate_item_ids=[101, 102, 201, 202], top_k=3)
ranker.observe(learner_id="7", ts=123, item_id=ranked[0].item_id, concept_id=None, correct=1)

policy="auto" uses the progression-value policy: the most stable default for adaptive learning today. Delayed-gain and support-constrained delayed-gain policies are available as explicit opt-ins when you have the logged support and reward-model diagnostics to justify them.

Legacy recommender fallback

Use orchid_ranker.legacy.OrchidRecommender when you need ordinary batch recommendations or old experiments without learning concepts, difficulty, or prerequisites:

from orchid_ranker.legacy import OrchidRecommender

rec = OrchidRecommender.from_interactions(interactions, strategy="neural_mf")
streamer = rec.as_streaming(lr=0.05)

streamer.observe(user_id=7, item_id=42, correct=True, category="onboarding")
top5 = streamer.rank(user_id=7, candidate_item_ids=[1, 2, 3, 42, 99], top_k=5)

Try it

Get up and running in under 5 minutes:

Build with it

Go from adaptive-learning fit to monitored rollout:

  • Serve streaming --- generic live adaptation when learning metadata is unavailable
  • Operate safely --- add progression guardrails, Prometheus metrics, Grafana dashboards

Evaluate it

Understand what makes Orchid different:


Adaptive-learning capabilities

  1. Learner state. SAINT+/SAINT, AKT/SAKT, and Bayesian tracing estimate competence from learner outcomes.
  2. Catalog structure. Dependency graphs and difficulty metadata keep recommendations in the valid next-step set.
  3. Semantic cold start. SemanticItemEncoder retrieves new exercises from text and metadata before interaction support exists.
  4. Adaptive ranking. Per-user online updates let the next recommendation change after each response.
  5. Logged policy learning. AdaptiveRanker.fit_policy(..., algo="cql") trains a conservative discrete policy from candidate sets, propensities, and rewards.
  6. Sketch mode. Count-Min, Bloom-filter, reservoir, and exact-vector utilities shrink candidate generation before final reranking.
  7. Offline policy evaluation. IPS, SNIPS, direct-method, doubly robust, and bootstrap reports test adaptive policies before rollout.
  8. Safe operation. Guardrails and frozen fallback rankings keep adaptive rollouts reviewable.
  9. Privacy hooks. Opt-in DP-SGD presets, RBAC, HMAC audit chains, and hashed event IDs support regulated deployments.

Supported strategies

Strategy Type Best for
auto Selector Let Orchid choose legacy_binary_mf or explicit_mf
legacy_binary_mf Legacy binary MF Backward-compatible Adam+BCE baseline
als Deprecated alias Alias for legacy_binary_mf; use implicit_als for true ALS
explicit_mf Matrix factorization Explicit rating scales
neural_mf Neural MF Streaming adaptation through as_streaming()
linucb Contextual bandit Cold-start exploration
user_knn Collaborative filtering Small catalogs
popularity Non-personalized Baseline comparison
+ 4 more See OrchidRecommender.available_strategies()

Install orchid-ranker[implicit] to use true implicit_als or implicit_bpr.

For adaptive learning, start with AdaptiveRanker when you want staged KT/reward/policy/OPE workflows, or AdaptiveLearningEngine when you only need fit/rank/observe. They compose SAINT+/SAINT, AKT/SAKT-style tracing, progression reward, difficulty/prerequisite metadata, semantic item retrieval, and live observe() updates into one fit/rank/observe API. Use lower-level pieces such as BayesianKnowledgeTracing, DependencyGraph, ProgressionRecommender, orchid_ranker.kt.SAKTTracer, and orchid_ranker.kt.SAINTPlusTracer only when you need a custom policy. Use orchid_ranker.ope to evaluate a new learning policy from logged randomized traffic before serving it, bootstrap_logged_policy when rollout decisions need row-resampled confidence intervals, and evaluate_rollout_gate to enforce minimum support/coverage/clipping thresholds before live learners see a policy. Modern KT and policy-learning algorithms are tracked in the algorithm roadmap.

For the legacy OrchidRecommender API, use neural_mf when you want to promote a fitted model into StreamingAdaptiveRanker with as_streaming(). TwoTowerRecommender remains available as a lower-level advanced model API, but it is not a strategy= value.

Status

Tests Python License

License

Apache 2.0. See LICENSE.

Contributing

See CONTRIBUTING.md. All contributions welcome.

Citation

@software{orchid_ranker,
  title={Orchid Ranker: Adaptive-Learning Engine},
  author={Sam Urmian},
  year={2024},
  url={https://github.com/mlgorithm/orchid-ranker}
}

About

No description, website, or topics provided.

Resources

License

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages