scikit-rec 0.3.2__tar.gz → 0.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {scikit_rec-0.3.2 → scikit_rec-0.4}/.gitignore +1 -0
- scikit_rec-0.4/CODE_OF_CONDUCT.md +33 -0
- scikit_rec-0.4/CONTRIBUTING.md +146 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/PKG-INFO +71 -4
- {scikit_rec-0.3.2 → scikit_rec-0.4}/README.md +68 -3
- {scikit_rec-0.3.2 → scikit_rec-0.4}/docs/advanced/orchestration.md +72 -10
- {scikit_rec-0.3.2 → scikit_rec-0.4}/docs/advanced/production.md +22 -1
- {scikit_rec-0.3.2 → scikit_rec-0.4}/docs/getting-started/installation.md +5 -1
- {scikit_rec-0.3.2 → scikit_rec-0.4}/docs/getting-started/quick-start.md +28 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/docs/recommender-types/ranking.md +25 -1
- {scikit_rec-0.3.2 → scikit_rec-0.4}/docs/user-guide/capability-matrix.md +16 -0
- scikit_rec-0.4/docs/user-guide/decision-rule.md +124 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/docs/user-guide/scorers.md +218 -3
- scikit_rec-0.4/examples/mixed_type_multi_target/conditional.ipynb +693 -0
- scikit_rec-0.4/examples/mixed_type_multi_target/independent.ipynb +760 -0
- scikit_rec-0.4/examples/mixed_type_multi_target/joint_families.ipynb +886 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/examples/movielens-1m/composability_demo.ipynb +2 -2
- scikit_rec-0.4/mixed_type_multi_target_plan_v2.md +1082 -0
- scikit_rec-0.4/mixed_type_multi_target_plan_v3.md +235 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/mkdocs.yml +1 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/pyproject.toml +8 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/scikit_rec.egg-info/PKG-INFO +71 -4
- {scikit_rec-0.3.2 → scikit_rec-0.4}/scikit_rec.egg-info/SOURCES.txt +29 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/scikit_rec.egg-info/requires.txt +3 -0
- scikit_rec-0.4/skrec/constants.py +16 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/dataset/interactions_dataset.py +24 -0
- scikit_rec-0.4/skrec/dataset/required_schemas/users_schema.yaml +3 -0
- scikit_rec-0.4/skrec/estimator/classification/__init__.py +29 -0
- scikit_rec-0.4/skrec/estimator/classification/_conditional_joint_multi_target_base.py +601 -0
- scikit_rec-0.4/skrec/estimator/classification/_conditional_label_encoding.py +382 -0
- scikit_rec-0.4/skrec/estimator/classification/_joint_multi_target_base.py +794 -0
- scikit_rec-0.4/skrec/estimator/classification/_joint_multi_target_encoders.py +309 -0
- scikit_rec-0.4/skrec/estimator/classification/_multi_target_protocol.py +249 -0
- scikit_rec-0.4/skrec/estimator/classification/conditional_joint_multi_target_mlp.py +54 -0
- scikit_rec-0.4/skrec/estimator/classification/conditional_joint_multi_target_transformer.py +81 -0
- scikit_rec-0.4/skrec/estimator/classification/independent_multi_target.py +545 -0
- scikit_rec-0.4/skrec/estimator/classification/joint_multi_target_mlp.py +64 -0
- scikit_rec-0.4/skrec/estimator/classification/joint_multi_target_transformer.py +76 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/metrics/base_metric.py +16 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/metrics/datatypes.py +3 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/metrics/factory.py +2 -0
- scikit_rec-0.4/skrec/metrics/multiclass_accuracy.py +63 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/orchestrator/__init__.py +27 -0
- scikit_rec-0.4/skrec/orchestrator/factory.py +1411 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/recommender/base_recommender.py +19 -5
- scikit_rec-0.4/skrec/recommender/inference_input.py +223 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/recommender/ranking/ranking_recommender.py +418 -6
- scikit_rec-0.4/skrec/scorer/__init__.py +11 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/scorer/base_scorer.py +83 -0
- scikit_rec-0.4/skrec/scorer/mixed_type_multi_target.py +1233 -0
- scikit_rec-0.4/tests/test_conditional_joint_multi_target.py +1474 -0
- scikit_rec-0.4/tests/test_factory_multi_target.py +961 -0
- scikit_rec-0.4/tests/test_independent_multi_target.py +886 -0
- scikit_rec-0.4/tests/test_joint_multi_target_mlp.py +578 -0
- scikit_rec-0.4/tests/test_joint_multi_target_transformer.py +347 -0
- scikit_rec-0.4/tests/test_mixed_type_multi_target_evaluation.py +1339 -0
- scikit_rec-0.4/tests/test_mixed_type_multi_target_gates.py +508 -0
- scikit_rec-0.4/tests/test_mixed_type_multi_target_scorer.py +1940 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_orchestrator_factory.py +158 -18
- {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_s3.py +7 -2
- scikit_rec-0.3.2/skrec/constants.py +0 -9
- scikit_rec-0.3.2/skrec/orchestrator/factory.py +0 -724
- scikit_rec-0.3.2/skrec/recommender/inference_input.py +0 -107
- scikit_rec-0.3.2/skrec/scorer/__init__.py +0 -0
- scikit_rec-0.3.2/tests/__init__.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/.github/workflows/ci.yml +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/.github/workflows/docs.yml +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/.github/workflows/publish.yml +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/LICENSE +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/docs/advanced/hpo.md +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/docs/advanced/hybrid.md +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/docs/examples/index.md +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/docs/getting-started/datasets.md +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/docs/images/3layers.png +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/docs/images/RecommenderFlowcharts.pptx +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/docs/images/recommender_dataset.png +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/docs/images/scorer.png +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/docs/index.md +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/docs/recommender-types/bandits.md +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/docs/recommender-types/comparison.md +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/docs/recommender-types/gcsl.md +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/docs/recommender-types/hierarchical.md +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/docs/recommender-types/sequential.md +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/docs/recommender-types/uplift.md +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/docs/stylesheets/extra.css +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/docs/user-guide/architecture.md +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/docs/user-guide/collaborative-filtering.md +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/docs/user-guide/estimators.md +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/docs/user-guide/evaluation.md +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/docs/user-guide/hrnn.md +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/docs/user-guide/inference.md +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/docs/user-guide/ncf.md +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/docs/user-guide/retrieval.md +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/docs/user-guide/sasrec.md +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/docs/user-guide/training.md +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/docs/user-guide/two-tower.md +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/examples/amazon-books/deepfm_amazon_books.ipynb +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/examples/amazon-books/lightgbm_amazon_books.ipynb +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/examples/amazon-books/ncf_amazon_books.ipynb +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/examples/amazon-books/sasrec_amazon_books_positives.ipynb +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/examples/generic/factory_pipeline_demo.ipynb +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/examples/generic/retrieval_two_stage.ipynb +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/examples/generic/uplift_modeling.ipynb +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/examples/movielens-1m/contextualized_two_tower_context_modes.ipynb +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/examples/movielens-1m/gcsl_multi_objective_movielens1m.ipynb +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/examples/movielens-1m/hpo_xgboost_movielens1m.ipynb +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/examples/movielens-1m/hrnn_movielens1m.ipynb +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/examples/movielens-1m/ranking_xgboost_movielens1m.ipynb +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/examples/movielens-1m/sasrec_movielens1m_positives.ipynb +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/examples/movielens-1m/sasrec_movielens1m_ratings.ipynb +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/examples/movielens-1m/sasrec_movielens1m_ratings_mse.ipynb +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/examples/ope_validation/obd_ope_validation.ipynb +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/scikit_rec.egg-info/dependency_links.txt +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/scikit_rec.egg-info/top_level.txt +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/setup.cfg +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/__init__.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/__version.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/dataset/batch_training_dataset.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/dataset/dataset.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/dataset/datatypes.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/dataset/items_dataset.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/dataset/local_data_reader.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/dataset/required_schemas/interaction_multiclass_schema_training.yaml +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/dataset/required_schemas/interaction_multioutput_schema_training.yaml +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/dataset/required_schemas/interactions_schema_inference.yaml +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/dataset/required_schemas/interactions_schema_training.yaml +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/dataset/required_schemas/interactions_schema_with_timestamp_training.yaml +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/dataset/required_schemas/items_schema.yaml +0 -0
- /scikit_rec-0.3.2/skrec/dataset/required_schemas/users_schema.yaml → /scikit_rec-0.4/skrec/dataset/required_schemas/mixed_type_multi_target_schema_training.yaml +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/dataset/s3_data_reader.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/dataset/schema.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/dataset/users_dataset.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/estimator/__init__.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/estimator/base_estimator.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/estimator/classification/base_classifier.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/estimator/classification/deep_fm_classifier.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/estimator/classification/lightgbm_classifier.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/estimator/classification/logreg_classifier.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/estimator/classification/multioutput_classifier.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/estimator/classification/sklearn_universal_classifier.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/estimator/classification/xgb_classifier.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/estimator/datatypes.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/estimator/embedding/base_embedding_estimator.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/estimator/embedding/base_pytorch_estimator.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/estimator/embedding/contextualized_two_tower_estimator.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/estimator/embedding/deep_cross_network_estimator.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/estimator/embedding/matrix_factorization_estimator.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/estimator/embedding/ncf_estimator.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/estimator/embedding/neural_factorization_estimator.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/estimator/numpy_predictor.py +0 -0
- {scikit_rec-0.3.2/skrec/estimator/classification → scikit_rec-0.4/skrec/estimator/regression}/__init__.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/estimator/regression/base_regressor.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/estimator/regression/lightgbm_regressor.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/estimator/regression/multioutput_regressor.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/estimator/regression/sklearn_universal_regressor.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/estimator/regression/xgb_regressor.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/estimator/sequential/__init__.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/estimator/sequential/base_sequential_estimator.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/estimator/sequential/hrnn_estimator.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/estimator/sequential/sasrec_estimator.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/estimator/tuned_estimator.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/evaluator/README.md +0 -0
- {scikit_rec-0.3.2/skrec/estimator/regression → scikit_rec-0.4/skrec/evaluator}/__init__.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/evaluator/base_evaluator.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/evaluator/categories.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/evaluator/datatypes.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/evaluator/direct_method.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/evaluator/doubly_robust.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/evaluator/evaluation_session.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/evaluator/factory.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/evaluator/inverse_propensity_score.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/evaluator/policy_weighted.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/evaluator/replay_match.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/evaluator/simple.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/evaluator/snips.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/evaluator/utils.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/examples/datasets/README.md +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/examples/datasets/__init__.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/examples/datasets/sample_binary_reward/interactions.csv +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/examples/datasets/sample_binary_reward/interactions_schema.yaml +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/examples/datasets/sample_binary_reward/items.csv +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/examples/datasets/sample_binary_reward/items_schema.yaml +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/examples/datasets/sample_binary_reward/users.csv +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/examples/datasets/sample_binary_reward/users_schema.yaml +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/examples/datasets/sample_continuous_reward/interactions.csv +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/examples/datasets/sample_continuous_reward/interactions_schema.yaml +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/examples/datasets/sample_continuous_reward/items.csv +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/examples/datasets/sample_continuous_reward/items_schema.yaml +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/examples/datasets/sample_continuous_reward/users.csv +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/examples/datasets/sample_continuous_reward/users_schema.yaml +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/examples/datasets/sample_multi_class/interactions_multi_class.csv +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/examples/datasets/sample_multi_class/interactions_schema.yaml +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/examples/datasets/sample_multi_outcome/interactions_multi_outcome.csv +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/examples/datasets/sample_multi_outcome/items.csv +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/examples/datasets/sample_multi_outcome/users.csv +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/examples/datasets/sample_multi_output/interactions.csv +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/examples/datasets/sample_multi_output/interactions_schema.yaml +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/examples/datasets/sample_uplift/interactions.csv +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/examples/datasets/sample_uplift/interactions_schema.yaml +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/examples/datasets/sample_uplift/interactions_schema_with_feats.yaml +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/examples/datasets/sample_uplift/interactions_with_feats.csv +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/examples/datasets/sample_uplift/users.csv +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/examples/datasets/sample_uplift/users_schema.yaml +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/examples/estimators/estimator_hyperparameters.yaml +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/examples/estimators/generated_personalized_data.csv +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/examples/estimators/multi_class_data.csv +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/examples/estimators/reward_model_data_classification.csv +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/examples/estimators/reward_model_data_regression.csv +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/examples/scripts/example_script.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/metrics/MAE.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/metrics/MAP.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/metrics/MRR.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/metrics/NDCG.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/metrics/PRAUC.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/metrics/README.md +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/metrics/RMSE.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/metrics/ROCAUC.py +0 -0
- {scikit_rec-0.3.2/skrec/evaluator → scikit_rec-0.4/skrec/metrics}/__init__.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/metrics/expected_reward.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/metrics/recall.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/metrics/recommender_precision.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/metrics/utils.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/orchestrator/hpo.py +0 -0
- {scikit_rec-0.3.2/skrec/metrics → scikit_rec-0.4/skrec/recommender}/__init__.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/recommender/bandits/contextual_bandits.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/recommender/bandits/datatypes.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/recommender/bandits/factory.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/recommender/bandits/strategy/base_strategy.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/recommender/bandits/strategy/epsilon_greedy.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/recommender/bandits/strategy/static_action.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/recommender/gcsl/__init__.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/recommender/gcsl/gcsl_recommender.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/recommender/gcsl/inference/__init__.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/recommender/gcsl/inference/base_inference.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/recommender/gcsl/inference/mean_scalarization.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/recommender/gcsl/inference/percentile_value.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/recommender/gcsl/inference/predefined_value.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/recommender/ranking/__init__.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/recommender/sequential/__init__.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/recommender/sequential/hierarchical_recommender.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/recommender/sequential/sequential_recommender.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/recommender/training_coordinator.py +0 -0
- {scikit_rec-0.3.2/skrec/recommender → scikit_rec-0.4/skrec/recommender/uplift_model}/__init__.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/recommender/uplift_model/uplift_recommender.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/recommender/uplift_model/uplift_scorer_adapter.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/retriever/__init__.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/retriever/base_retriever.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/retriever/content_based_retriever.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/retriever/embedding_retriever.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/retriever/popularity_retriever.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/scorer/hierarchical.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/scorer/independent.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/scorer/multiclass.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/scorer/multioutput.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/scorer/sequential.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/scorer/universal.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/split.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/util/config_loader.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/util/logger.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/util/numpy_util.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/util/s3.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/util/torch_device.py +0 -0
- {scikit_rec-0.3.2/skrec/recommender/uplift_model → scikit_rec-0.4/tests}/__init__.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/conftest.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_bandits_recommender.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_base_estimator.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_base_retriever.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_base_scorer.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_classifier_estimators.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_content_based_retriever.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_dataset.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_dataset_iterator.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_deep_fm_network.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_embedding_estimators.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_embedding_retriever.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_estimator_smoke.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_evaluator_utils.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_example_datasets.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_gcsl_recommender.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_hrnn_estimator.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_import.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_independent_scorer.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_matrix_factorization_estimator.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_matrix_factorization_integration.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_metrics_utils.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_multiclass_scorer.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_multioutput_evaluation.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_multioutput_scorer.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_ncf_estimator.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_ncf_integration.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_numpy.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_orchestrator_hpo.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_popularity_retriever.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_ranking_recommender.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_rec_datasets.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_recommender_evaluation_session.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_recommender_evaluator.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_recommender_metrics.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_regression_estimators.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_retrieval_integration.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_sasrec_estimator.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_schema.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_sequential_recommender.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_split.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_strategy.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_universal_scorer.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_uplift_s_learner.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_uplift_t_learner.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_uplift_x_learner.py +0 -0
- {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/utils.py +0 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Code of Conduct
|
|
2
|
+
|
|
3
|
+
## Our Pledge
|
|
4
|
+
|
|
5
|
+
We pledge to make participation in `scikit-rec` a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
|
|
6
|
+
|
|
7
|
+
## Our Standards
|
|
8
|
+
|
|
9
|
+
Examples of behavior that contributes to a positive environment:
|
|
10
|
+
|
|
11
|
+
- Using welcoming and inclusive language
|
|
12
|
+
- Being respectful of differing viewpoints and experiences
|
|
13
|
+
- Gracefully accepting constructive criticism
|
|
14
|
+
- Showing empathy towards other community members
|
|
15
|
+
|
|
16
|
+
Examples of unacceptable behavior:
|
|
17
|
+
|
|
18
|
+
- Harassment, abusive language, or derogatory comments
|
|
19
|
+
- Disrespectful or exclusionary actions
|
|
20
|
+
- Personal attacks or public shaming
|
|
21
|
+
- Disruptive behavior or trolling
|
|
22
|
+
|
|
23
|
+
## Reporting
|
|
24
|
+
|
|
25
|
+
If you experience or witness unacceptable behavior, please report it by opening an issue on GitHub with the label `code-of-conduct` or contacting the maintainers directly.
|
|
26
|
+
|
|
27
|
+
## Enforcement
|
|
28
|
+
|
|
29
|
+
Project maintainers may take any action they deem appropriate in response to incidents of unacceptable behavior, including warning or banning individuals from the project.
|
|
30
|
+
|
|
31
|
+
## Attribution
|
|
32
|
+
|
|
33
|
+
This Code of Conduct is adapted from the Contributor Covenant.
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
# Contributing to scikit-rec
|
|
2
|
+
|
|
3
|
+
Thank you for your interest in contributing to `scikit-rec`! We welcome bug reports, feature requests, and code contributions.
|
|
4
|
+
|
|
5
|
+
## How to contribute
|
|
6
|
+
|
|
7
|
+
1. Fork the repository and create a new branch.
|
|
8
|
+
2. Make your changes in a focused branch.
|
|
9
|
+
3. Add tests for bug fixes and new functionality.
|
|
10
|
+
4. Run the test suite locally:
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
git clone https://github.com/intuit/scikit-rec.git
|
|
14
|
+
cd scikit-rec
|
|
15
|
+
python -m venv .venv && source .venv/bin/activate
|
|
16
|
+
pip install -e ".[dev]"
|
|
17
|
+
pytest tests/
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
For PyTorch-based estimators (NCF, Two-Tower, SASRec, HRNN, DeepFM), install with the torch extra:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
pip install -e ".[dev,torch]"
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
5. Commit with a clear message and open a pull request against `main`.
|
|
27
|
+
|
|
28
|
+
## Guidelines
|
|
29
|
+
|
|
30
|
+
- Keep pull requests small and focused.
|
|
31
|
+
- Follow the existing code style and conventions.
|
|
32
|
+
- Add or update documentation when behavior changes.
|
|
33
|
+
- Use descriptive commit messages.
|
|
34
|
+
|
|
35
|
+
## Reporting issues
|
|
36
|
+
|
|
37
|
+
If you find a bug or have a feature idea, please open an issue at:
|
|
38
|
+
|
|
39
|
+
https://github.com/intuit/scikit-rec/issues
|
|
40
|
+
|
|
41
|
+
Include a clear description of the problem, a minimal reproduction example, and the expected behavior.
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## Architecture guide for contributors
|
|
46
|
+
|
|
47
|
+
`scikit-rec` uses a 3-layer architecture: **Recommender → Scorer → Estimator**. Each layer has a well-defined abstract base class. Adding a new component means subclassing the right base, implementing a small set of abstract methods, and (for factory-accessible types) registering the new type in `skrec/orchestrator/factory.py`.
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
skrec/
|
|
51
|
+
estimator/
|
|
52
|
+
base_estimator.py ← BaseEstimator (tabular)
|
|
53
|
+
classification/ ← tabular classifiers
|
|
54
|
+
regression/ ← tabular regressors
|
|
55
|
+
embedding/ ← BaseEmbeddingEstimator + embedding models
|
|
56
|
+
sequential/ ← SequentialEstimator + SASRec, HRNN
|
|
57
|
+
scorer/
|
|
58
|
+
base_scorer.py ← BaseScorer
|
|
59
|
+
universal.py, independent.py, multiclass.py, multioutput.py, ...
|
|
60
|
+
recommender/
|
|
61
|
+
base_recommender.py ← BaseRecommender
|
|
62
|
+
ranking/, bandits/, sequential/, gcsl/, uplift_model/
|
|
63
|
+
orchestrator/
|
|
64
|
+
factory.py ← create_recommender_pipeline + capability_matrix
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Adding a new estimator
|
|
68
|
+
|
|
69
|
+
**Tabular classifier or regressor:**
|
|
70
|
+
|
|
71
|
+
1. Subclass `BaseClassifier` (in `skrec/estimator/classification/base_classifier.py`) or `BaseRegressor`.
|
|
72
|
+
2. Implement `fit(X, y)` and `predict_proba(X)` / `predict(X)`.
|
|
73
|
+
3. Add the file to `skrec/estimator/classification/` or `skrec/estimator/regression/`.
|
|
74
|
+
4. To expose it via `create_recommender_pipeline`, add a branch in `create_estimator()` in `factory.py` and extend `EstimatorConfig` with the new config key. Also add the new key to `capability_matrix()`.
|
|
75
|
+
|
|
76
|
+
**Embedding estimator:**
|
|
77
|
+
|
|
78
|
+
1. Subclass `BaseEmbeddingEstimator` (`skrec/estimator/embedding/base_embedding_estimator.py`).
|
|
79
|
+
2. Implement `fit_embedding_model(users, items, interactions, ...)` and `predict_proba_with_embeddings(...)`.
|
|
80
|
+
3. Add a lazy entry to `_EMBEDDING_ESTIMATOR_MAP` in `factory.py` — no eager import needed.
|
|
81
|
+
|
|
82
|
+
**Sequential estimator (SASRec-style):**
|
|
83
|
+
|
|
84
|
+
1. Subclass `SequentialEstimator` (`skrec/estimator/sequential/base_sequential_estimator.py`).
|
|
85
|
+
2. Add a lazy entry to `_SEQUENTIAL_ESTIMATOR_MAP` in `factory.py`.
|
|
86
|
+
|
|
87
|
+
### Adding a new scorer
|
|
88
|
+
|
|
89
|
+
1. Subclass `BaseScorer` (`skrec/scorer/base_scorer.py`).
|
|
90
|
+
2. Implement `score_items(interactions, users, items)` and `score_fast(features_df)` if supporting `recommend_online`.
|
|
91
|
+
3. Add it to `SCORER_TYPES` in `factory.py`, add a branch in `create_scorer()`, and add an entry (even an empty `frozenset`) to `_SCORER_CONFIG_ALLOWED`.
|
|
92
|
+
|
|
93
|
+
### Adding a new multi-target estimator family
|
|
94
|
+
|
|
95
|
+
`MixedTypeMultiTargetScorer` is polymorphic over estimator families via the runtime-checkable `MultiTargetEstimator` Protocol. To add a fourth family (e.g. a tree-based joint model, an MoE encoder, etc.):
|
|
96
|
+
|
|
97
|
+
1. Implement a class with the four attributes/methods on `skrec.estimator.classification._multi_target_protocol.MultiTargetEstimator`:
|
|
98
|
+
- `target_specs: dict[str, TargetType | TargetGroupSpec]` attribute
|
|
99
|
+
- `fit(X, y, X_valid=None, y_valid=None)`
|
|
100
|
+
- `predict_proba_dict(X) -> dict[str, np.ndarray]` (multilabel groups fanned out)
|
|
101
|
+
- `predict_targets_dict(X) -> dict[str, np.ndarray]` (multilabel groups fanned out)
|
|
102
|
+
2. The scorer's `__init__` Protocol check accepts your class automatically — no changes to `MixedTypeMultiTargetScorer` are required.
|
|
103
|
+
3. If the family fits the joint pattern (shared encoder + per-target heads), subclass `JointMultiTargetBaseEstimator` and supply an encoder via `_build_encoder(input_dim, label_input_dim)`. See `joint_multi_target_mlp.py` for the minimal template.
|
|
104
|
+
4. To expose via the factory, add a mode to `MULTI_TARGET_MODEL_TYPES` and a branch in `_create_multi_target_estimator()` in `factory.py`.
|
|
105
|
+
5. For `mode="independent"` extensions (adding a new sub-estimator type), extend `_INDEPENDENT_TARGET_COMPAT` and `_create_independent_sub_estimator()`.
|
|
106
|
+
|
|
107
|
+
Gate 1 (`tests/test_mixed_type_multi_target_gates.py`) asserts every family satisfies the Protocol; add your class to that test when contributing.
|
|
108
|
+
|
|
109
|
+
### Adding a new recommender
|
|
110
|
+
|
|
111
|
+
1. Subclass `BaseRecommender` (`skrec/recommender/base_recommender.py`).
|
|
112
|
+
2. Implement `train(...)`, `recommend(...)`, and optionally `score_items(...)`.
|
|
113
|
+
3. Add it to `RECOMMENDER_TYPES` in `factory.py` and add a branch in `create_recommender()`.
|
|
114
|
+
|
|
115
|
+
### Adding a new retriever
|
|
116
|
+
|
|
117
|
+
1. Subclass `BaseCandidateRetriever` (`skrec/retriever/base_retriever.py`).
|
|
118
|
+
2. Implement `retrieve(interactions, users, items)`.
|
|
119
|
+
3. Add an entry to `_RETRIEVER_MAP` in `factory.py`.
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## Test conventions
|
|
124
|
+
|
|
125
|
+
Tests live in `tests/`. The main patterns:
|
|
126
|
+
|
|
127
|
+
- **Unit tests** (`test_base_*.py`, `test_*_scorer.py`, etc.) use small synthetic fixtures defined in `tests/conftest.py` and `tests/utils.py`.
|
|
128
|
+
- **Integration tests** (`test_*_integration.py`) run a full train → evaluate cycle on sample data and are the primary correctness check.
|
|
129
|
+
- **Smoke tests** (`test_estimator_smoke.py`) instantiate every estimator and verify they don't error on a tiny dataset — useful for catching import or API regressions.
|
|
130
|
+
|
|
131
|
+
When adding a new component, add at minimum:
|
|
132
|
+
- A unit test covering the abstract interface.
|
|
133
|
+
- An integration test that trains and evaluates end-to-end.
|
|
134
|
+
- If the component is factory-accessible, a test in `test_orchestrator_factory.py`.
|
|
135
|
+
|
|
136
|
+
S3-dependent tests (`test_s3.py`) use `moto` to mock AWS — no real credentials needed.
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
## Community
|
|
141
|
+
|
|
142
|
+
By contributing, you agree to abide by the project's Code of Conduct:
|
|
143
|
+
|
|
144
|
+
- `CODE_OF_CONDUCT.md`
|
|
145
|
+
|
|
146
|
+
We aim to make this project welcoming, inclusive, and respectful.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: scikit-rec
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4
|
|
4
4
|
Summary: A scikit-style recommender systems library
|
|
5
5
|
License-Expression: Apache-2.0
|
|
6
6
|
Project-URL: Homepage, https://github.com/intuit/scikit-rec
|
|
@@ -19,6 +19,8 @@ Requires-Dist: pyarrow<20.0.0,>=10.0.0
|
|
|
19
19
|
Requires-Dist: optuna<5.0.0,>=3.0.0
|
|
20
20
|
Provides-Extra: torch
|
|
21
21
|
Requires-Dist: torch<3.0.0,>=2.2.0; extra == "torch"
|
|
22
|
+
Provides-Extra: deep
|
|
23
|
+
Requires-Dist: torch<3.0.0,>=2.2.0; extra == "deep"
|
|
22
24
|
Provides-Extra: aws
|
|
23
25
|
Requires-Dist: boto3<3.0.0,>=1.26.27; extra == "aws"
|
|
24
26
|
Provides-Extra: dev
|
|
@@ -32,6 +34,8 @@ Dynamic: license-file
|
|
|
32
34
|
|
|
33
35
|
# scikit-rec
|
|
34
36
|
|
|
37
|
+
[](https://pypi.org/project/scikit-rec)
|
|
38
|
+
|
|
35
39
|
A composable, scikit-style recommender systems library.
|
|
36
40
|
|
|
37
41
|
**scikit-rec** provides a 3-layer architecture that cleanly separates business logic, scoring strategy, and ML models. Any recommender works with any compatible scorer and estimator, giving you a mix-and-match toolkit for building recommendation systems.
|
|
@@ -63,10 +67,15 @@ pip install scikit-rec
|
|
|
63
67
|
Optional extras:
|
|
64
68
|
|
|
65
69
|
```bash
|
|
66
|
-
pip install scikit-rec[torch]
|
|
67
|
-
pip install scikit-rec[aws]
|
|
70
|
+
pip install scikit-rec[torch] # Deep learning models (DeepFM, NCF, SASRec, HRNN, Two-Tower)
|
|
71
|
+
pip install scikit-rec[aws] # S3 data loading
|
|
72
|
+
pip install scikit-rec[torch,aws] # All optional extras
|
|
68
73
|
```
|
|
69
74
|
|
|
75
|
+
Notes:
|
|
76
|
+
- `scikit-rec[torch]` is required only for PyTorch-based estimators and deep learning pipelines.
|
|
77
|
+
- `scikit-rec[aws]` adds S3 dataset loading support without pulling in Torch.
|
|
78
|
+
|
|
70
79
|
## Quick Start
|
|
71
80
|
|
|
72
81
|
```python
|
|
@@ -97,6 +106,55 @@ users_df = sample_binary_reward_users.fetch_data()
|
|
|
97
106
|
recommendations = recommender.recommend(interactions=interactions_df, users=users_df, top_k=5)
|
|
98
107
|
```
|
|
99
108
|
|
|
109
|
+
## Config-driven quick start
|
|
110
|
+
|
|
111
|
+
The orchestrator API lets you build a pipeline from a configuration dictionary instead of wiring classes manually.
|
|
112
|
+
|
|
113
|
+
```python
|
|
114
|
+
from skrec.orchestrator import create_recommender_pipeline
|
|
115
|
+
|
|
116
|
+
config = {
|
|
117
|
+
"recommender_type": "ranking",
|
|
118
|
+
"scorer_type": "universal",
|
|
119
|
+
"estimator_config": {
|
|
120
|
+
"ml_task": "classification",
|
|
121
|
+
"xgboost": {
|
|
122
|
+
"n_estimators": 100,
|
|
123
|
+
"max_depth": 5,
|
|
124
|
+
"learning_rate": 0.1,
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
recommender = create_recommender_pipeline(config)
|
|
130
|
+
recommender.train(
|
|
131
|
+
interactions_ds=sample_binary_reward_interactions,
|
|
132
|
+
users_ds=sample_binary_reward_users,
|
|
133
|
+
items_ds=sample_binary_reward_items,
|
|
134
|
+
)
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## Agent integration
|
|
138
|
+
|
|
139
|
+
`scikit-rec` is designed to be consumed by LLM agents via its config-driven factory and a `capability_matrix()` introspection API. The companion repo [scikit-rec-agent](https://github.com/intuit/scikit-rec-agent/) provides a ready-made conversational agent that uses this surface to guide a user through dataset preparation, model selection, training, and evaluation — no hand-coded class wiring required.
|
|
140
|
+
|
|
141
|
+
### How the agent surface works
|
|
142
|
+
|
|
143
|
+
`capability_matrix()` returns the authoritative set of valid types for every factory dimension. The factory validates its inputs against these same tuples, so the agent's knowledge is always in lockstep with what the library actually supports:
|
|
144
|
+
|
|
145
|
+
```python
|
|
146
|
+
from skrec.orchestrator import capability_matrix
|
|
147
|
+
|
|
148
|
+
cm = capability_matrix()
|
|
149
|
+
cm["recommender_types"] # ('ranking', 'bandits', 'sequential', 'hierarchical_sequential', 'uplift', 'gcsl')
|
|
150
|
+
cm["scorer_types"] # ('universal', 'independent', 'multiclass', 'multioutput', 'sequential', 'hierarchical')
|
|
151
|
+
cm["estimator_types"] # ('tabular', 'embedding', 'sequential')
|
|
152
|
+
cm["embedding_model_types"] # ('matrix_factorization', 'ncf', 'two_tower', ...)
|
|
153
|
+
cm["scorer_config_keys"] # per-scorer accepted kwargs, e.g. {"multioutput": ("on_degenerate_target",)}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
An agent can call `capability_matrix()` to populate its system prompt, then pass the user's choices directly to `create_recommender_pipeline()`. The factory validates compatibility upfront and raises a clear `ValueError` for any invalid combination before training begins.
|
|
157
|
+
|
|
100
158
|
## Components
|
|
101
159
|
|
|
102
160
|
### Recommenders
|
|
@@ -117,7 +175,8 @@ recommendations = recommender.recommend(interactions=interactions_df, users=user
|
|
|
117
175
|
| `UniversalScorer` | Single global model using item features (auto-dispatches tabular vs. embedding) |
|
|
118
176
|
| `IndependentScorer` | Separate model per item |
|
|
119
177
|
| `MulticlassScorer` | Items as competing classes |
|
|
120
|
-
| `MultioutputScorer` | Wide-format multi-label binary classification or multi-target regression (one `ITEM_<name>` column per target) |
|
|
178
|
+
| `MultioutputScorer` | Wide-format multi-label binary classification or multi-target regression (one `ITEM_<name>` column per target); accepts `scorer_config={"on_degenerate_target": "constant"}` to handle single-class training columns |
|
|
179
|
+
| `MixedTypeMultiTargetScorer` | Wide-format scorer for **heterogeneous per-target types** (binary + regression + multiclass + multilabel groups) in one model. Three estimator families: joint MLP, joint Transformer (FT-Transformer-style), independent (per-target sub-estimators). Per-target metric dispatch returns `Dict[str, float]`. See [scorers guide](docs/user-guide/scorers.md#5-mixedtypemultitargetscorer) |
|
|
121
180
|
| `SequentialScorer` | For sequential estimators (SASRec) |
|
|
122
181
|
| `HierarchicalScorer` | For HRNN estimators |
|
|
123
182
|
|
|
@@ -208,6 +267,14 @@ pip install -e ".[dev]"
|
|
|
208
267
|
pytest tests/
|
|
209
268
|
```
|
|
210
269
|
|
|
270
|
+
## Contributing
|
|
271
|
+
|
|
272
|
+
Contributions are welcome! See `CONTRIBUTING.md` for guidance on feature requests, bug reports, and pull request workflow.
|
|
273
|
+
|
|
274
|
+
## Code of Conduct
|
|
275
|
+
|
|
276
|
+
This project follows a [Code of Conduct](CODE_OF_CONDUCT.md) to ensure a respectful, inclusive community.
|
|
277
|
+
|
|
211
278
|
## License
|
|
212
279
|
|
|
213
280
|
[Apache 2.0](LICENSE)
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# scikit-rec
|
|
2
2
|
|
|
3
|
+
[](https://pypi.org/project/scikit-rec)
|
|
4
|
+
|
|
3
5
|
A composable, scikit-style recommender systems library.
|
|
4
6
|
|
|
5
7
|
**scikit-rec** provides a 3-layer architecture that cleanly separates business logic, scoring strategy, and ML models. Any recommender works with any compatible scorer and estimator, giving you a mix-and-match toolkit for building recommendation systems.
|
|
@@ -31,10 +33,15 @@ pip install scikit-rec
|
|
|
31
33
|
Optional extras:
|
|
32
34
|
|
|
33
35
|
```bash
|
|
34
|
-
pip install scikit-rec[torch]
|
|
35
|
-
pip install scikit-rec[aws]
|
|
36
|
+
pip install scikit-rec[torch] # Deep learning models (DeepFM, NCF, SASRec, HRNN, Two-Tower)
|
|
37
|
+
pip install scikit-rec[aws] # S3 data loading
|
|
38
|
+
pip install scikit-rec[torch,aws] # All optional extras
|
|
36
39
|
```
|
|
37
40
|
|
|
41
|
+
Notes:
|
|
42
|
+
- `scikit-rec[torch]` is required only for PyTorch-based estimators and deep learning pipelines.
|
|
43
|
+
- `scikit-rec[aws]` adds S3 dataset loading support without pulling in Torch.
|
|
44
|
+
|
|
38
45
|
## Quick Start
|
|
39
46
|
|
|
40
47
|
```python
|
|
@@ -65,6 +72,55 @@ users_df = sample_binary_reward_users.fetch_data()
|
|
|
65
72
|
recommendations = recommender.recommend(interactions=interactions_df, users=users_df, top_k=5)
|
|
66
73
|
```
|
|
67
74
|
|
|
75
|
+
## Config-driven quick start
|
|
76
|
+
|
|
77
|
+
The orchestrator API lets you build a pipeline from a configuration dictionary instead of wiring classes manually.
|
|
78
|
+
|
|
79
|
+
```python
|
|
80
|
+
from skrec.orchestrator import create_recommender_pipeline
|
|
81
|
+
|
|
82
|
+
config = {
|
|
83
|
+
"recommender_type": "ranking",
|
|
84
|
+
"scorer_type": "universal",
|
|
85
|
+
"estimator_config": {
|
|
86
|
+
"ml_task": "classification",
|
|
87
|
+
"xgboost": {
|
|
88
|
+
"n_estimators": 100,
|
|
89
|
+
"max_depth": 5,
|
|
90
|
+
"learning_rate": 0.1,
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
recommender = create_recommender_pipeline(config)
|
|
96
|
+
recommender.train(
|
|
97
|
+
interactions_ds=sample_binary_reward_interactions,
|
|
98
|
+
users_ds=sample_binary_reward_users,
|
|
99
|
+
items_ds=sample_binary_reward_items,
|
|
100
|
+
)
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Agent integration
|
|
104
|
+
|
|
105
|
+
`scikit-rec` is designed to be consumed by LLM agents via its config-driven factory and a `capability_matrix()` introspection API. The companion repo [scikit-rec-agent](https://github.com/intuit/scikit-rec-agent/) provides a ready-made conversational agent that uses this surface to guide a user through dataset preparation, model selection, training, and evaluation — no hand-coded class wiring required.
|
|
106
|
+
|
|
107
|
+
### How the agent surface works
|
|
108
|
+
|
|
109
|
+
`capability_matrix()` returns the authoritative set of valid types for every factory dimension. The factory validates its inputs against these same tuples, so the agent's knowledge is always in lockstep with what the library actually supports:
|
|
110
|
+
|
|
111
|
+
```python
|
|
112
|
+
from skrec.orchestrator import capability_matrix
|
|
113
|
+
|
|
114
|
+
cm = capability_matrix()
|
|
115
|
+
cm["recommender_types"] # ('ranking', 'bandits', 'sequential', 'hierarchical_sequential', 'uplift', 'gcsl')
|
|
116
|
+
cm["scorer_types"] # ('universal', 'independent', 'multiclass', 'multioutput', 'sequential', 'hierarchical')
|
|
117
|
+
cm["estimator_types"] # ('tabular', 'embedding', 'sequential')
|
|
118
|
+
cm["embedding_model_types"] # ('matrix_factorization', 'ncf', 'two_tower', ...)
|
|
119
|
+
cm["scorer_config_keys"] # per-scorer accepted kwargs, e.g. {"multioutput": ("on_degenerate_target",)}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
An agent can call `capability_matrix()` to populate its system prompt, then pass the user's choices directly to `create_recommender_pipeline()`. The factory validates compatibility upfront and raises a clear `ValueError` for any invalid combination before training begins.
|
|
123
|
+
|
|
68
124
|
## Components
|
|
69
125
|
|
|
70
126
|
### Recommenders
|
|
@@ -85,7 +141,8 @@ recommendations = recommender.recommend(interactions=interactions_df, users=user
|
|
|
85
141
|
| `UniversalScorer` | Single global model using item features (auto-dispatches tabular vs. embedding) |
|
|
86
142
|
| `IndependentScorer` | Separate model per item |
|
|
87
143
|
| `MulticlassScorer` | Items as competing classes |
|
|
88
|
-
| `MultioutputScorer` | Wide-format multi-label binary classification or multi-target regression (one `ITEM_<name>` column per target) |
|
|
144
|
+
| `MultioutputScorer` | Wide-format multi-label binary classification or multi-target regression (one `ITEM_<name>` column per target); accepts `scorer_config={"on_degenerate_target": "constant"}` to handle single-class training columns |
|
|
145
|
+
| `MixedTypeMultiTargetScorer` | Wide-format scorer for **heterogeneous per-target types** (binary + regression + multiclass + multilabel groups) in one model. Three estimator families: joint MLP, joint Transformer (FT-Transformer-style), independent (per-target sub-estimators). Per-target metric dispatch returns `Dict[str, float]`. See [scorers guide](docs/user-guide/scorers.md#5-mixedtypemultitargetscorer) |
|
|
89
146
|
| `SequentialScorer` | For sequential estimators (SASRec) |
|
|
90
147
|
| `HierarchicalScorer` | For HRNN estimators |
|
|
91
148
|
|
|
@@ -176,6 +233,14 @@ pip install -e ".[dev]"
|
|
|
176
233
|
pytest tests/
|
|
177
234
|
```
|
|
178
235
|
|
|
236
|
+
## Contributing
|
|
237
|
+
|
|
238
|
+
Contributions are welcome! See `CONTRIBUTING.md` for guidance on feature requests, bug reports, and pull request workflow.
|
|
239
|
+
|
|
240
|
+
## Code of Conduct
|
|
241
|
+
|
|
242
|
+
This project follows a [Code of Conduct](CODE_OF_CONDUCT.md) to ensure a respectful, inclusive community.
|
|
243
|
+
|
|
179
244
|
## License
|
|
180
245
|
|
|
181
246
|
[Apache 2.0](LICENSE)
|
|
@@ -31,6 +31,10 @@ recommender.train(
|
|
|
31
31
|
recommendations = recommender.recommend(interactions=query_df, top_k=5)
|
|
32
32
|
```
|
|
33
33
|
|
|
34
|
+
## Agent-Friendly Orchestration
|
|
35
|
+
|
|
36
|
+
`scikit-rec` exposes a config-driven recommender factory that is especially useful for automated and LLM-based systems. The factory validates compatibility between recommender, scorer, and estimator types, and `capability_matrix()` can be used by tooling or an agent to enumerate supported options.
|
|
37
|
+
|
|
34
38
|
## Configuration Reference
|
|
35
39
|
|
|
36
40
|
### Top-Level Config (`RecommenderConfig`)
|
|
@@ -146,43 +150,72 @@ The factory validates these constraints at pipeline creation time and raises `Va
|
|
|
146
150
|
|
|
147
151
|
## Programmatic Capability Introspection
|
|
148
152
|
|
|
149
|
-
For tooling that needs to enumerate what the factory understands (system-prompt builders, config validators, UI pickers, etc.), `skrec.orchestrator` exposes
|
|
153
|
+
For tooling that needs to enumerate what the factory understands (system-prompt builders, config validators, UI pickers, etc.), `skrec.orchestrator` exposes four authoritative enum tuples plus a `capability_matrix()` accessor. These are the same values the factory validates against internally, so they stay in lockstep automatically.
|
|
150
154
|
|
|
151
155
|
```python
|
|
152
156
|
from skrec.orchestrator import (
|
|
153
157
|
RECOMMENDER_TYPES,
|
|
154
158
|
SCORER_TYPES,
|
|
155
159
|
ESTIMATOR_TYPES,
|
|
160
|
+
TABULAR_MODEL_TYPES,
|
|
161
|
+
MULTI_TARGET_MODEL_TYPES,
|
|
156
162
|
capability_matrix,
|
|
157
163
|
)
|
|
158
164
|
|
|
159
|
-
RECOMMENDER_TYPES
|
|
160
|
-
SCORER_TYPES
|
|
161
|
-
ESTIMATOR_TYPES
|
|
165
|
+
RECOMMENDER_TYPES # ('ranking', 'bandits', 'sequential', 'hierarchical_sequential', 'uplift', 'gcsl')
|
|
166
|
+
SCORER_TYPES # ('universal', 'independent', 'multiclass', 'multioutput', 'mixed_type_multi_target', 'sequential', 'hierarchical')
|
|
167
|
+
ESTIMATOR_TYPES # ('tabular', 'embedding', 'sequential')
|
|
168
|
+
TABULAR_MODEL_TYPES # ('xgboost', 'lightgbm', 'deepfm')
|
|
169
|
+
MULTI_TARGET_MODEL_TYPES # ('joint_mlp', 'joint_transformer', 'independent')
|
|
162
170
|
|
|
163
171
|
capability_matrix()
|
|
164
172
|
# {
|
|
165
173
|
# "recommender_types": (...),
|
|
166
174
|
# "scorer_types": (...),
|
|
167
175
|
# "estimator_types": (...),
|
|
176
|
+
# "tabular_model_types": ("xgboost", "lightgbm", "deepfm"),
|
|
168
177
|
# "embedding_model_types": ("matrix_factorization", "ncf", "two_tower", ...),
|
|
169
178
|
# "sequential_model_types": ("sasrec_classifier", "sasrec_regressor", ...),
|
|
179
|
+
# "multi_target_model_types": ("joint_mlp", "joint_transformer", "independent"),
|
|
170
180
|
# "inference_method_types": ("mean_scalarization", "percentile_value", "predefined_value"),
|
|
171
181
|
# "retriever_types": ("popularity", "content_based", "embedding"),
|
|
172
182
|
# "scorer_config_keys": {
|
|
173
183
|
# "multioutput": ("on_degenerate_target",),
|
|
184
|
+
# "mixed_type_multi_target": ("target_specs",),
|
|
174
185
|
# "multiclass": (),
|
|
175
|
-
#
|
|
176
|
-
#
|
|
177
|
-
#
|
|
178
|
-
#
|
|
186
|
+
# # ...
|
|
187
|
+
# },
|
|
188
|
+
# "evaluator_types": (...),
|
|
189
|
+
# "metric_types": (...), # includes "multiclass_accuracy" (new in v2)
|
|
190
|
+
# # Multi-target capabilities (consumed by scikit-rec-agent for pre-flight validation):
|
|
191
|
+
# "target_types": ("binary", "regression", "multiclass", "multilabel"),
|
|
192
|
+
# "target_type_metric_compat": {
|
|
193
|
+
# "binary": ("roc_auc", "pr_auc"),
|
|
194
|
+
# "regression": ("rmse", "mae"),
|
|
195
|
+
# "multiclass": ("multiclass_accuracy",),
|
|
196
|
+
# "multilabel": ("roc_auc", "pr_auc"),
|
|
179
197
|
# },
|
|
198
|
+
# "independent_target_compat": {
|
|
199
|
+
# "binary": ("lightgbm", "logreg", "sklearn", "xgboost"),
|
|
200
|
+
# "regression": ("lightgbm", "sklearn", "xgboost"),
|
|
201
|
+
# "multiclass": ("lightgbm", "logreg"), # xgboost excluded — see scorers.md
|
|
202
|
+
# "multilabel": ("lightgbm", "logreg", "sklearn", "xgboost"),
|
|
203
|
+
# },
|
|
204
|
+
# # Forward-compat flag for v3: empty in v2; populates with scorer names
|
|
205
|
+
# # supporting OBSERVED_* conditioning when v3 conditional estimators land.
|
|
206
|
+
# "scorer_supports_observed_conditioning": (),
|
|
180
207
|
# }
|
|
181
208
|
```
|
|
182
209
|
|
|
183
|
-
|
|
210
|
+
### Multi-target capabilities
|
|
211
|
+
|
|
212
|
+
The four `target_*`/`independent_*`/`scorer_supports_*` keys above were added in v2 to support `MixedTypeMultiTargetScorer`. They let external tooling (like scikit-rec-agent) validate `target_specs`, metric/target compatibility, and per-target sub-estimator type choices without mirroring scikit-rec internals.
|
|
213
|
+
|
|
214
|
+
The dispatch tables (`target_type_metric_compat`, `independent_target_compat`) are mirrors of in-code constants. Gate 7 in `tests/test_mixed_type_multi_target_gates.py` asserts the runtime, capability matrix, and human-canonical doc table all agree.
|
|
184
215
|
|
|
185
|
-
|
|
216
|
+
For shape-detection symmetry between scikit-rec and scikit-rec-agent, `skrec.orchestrator` also exposes `contract_from_dataframe(df, target_specs=None)` which classifies a DataFrame into one of: `long_interactions`, `long_with_timestamp`, `wide_multioutput`, `wide_mixed_type_multi_target`, `multiclass`, `prebuilt_sequences`, `sessions`. Mixed-type vs multioutput disambiguation requires `target_specs`.
|
|
217
|
+
|
|
218
|
+
The full compatibility reference (which scorer works with which estimator, retriever constraints, etc.) is on the [Capability Matrix](../user-guide/capability-matrix.md) page; the joint-vs-independent decision tree and per-`TargetType` metric dispatch table are on the [Decision rule](../user-guide/decision-rule.md) page.
|
|
186
219
|
|
|
187
220
|
## Complete Examples
|
|
188
221
|
|
|
@@ -503,6 +536,35 @@ ValueError: scorer_type 'independent' does not support embedding estimators.
|
|
|
503
536
|
Use scorer_type='universal' with embedding estimators.
|
|
504
537
|
```
|
|
505
538
|
|
|
539
|
+
## Factory scope
|
|
540
|
+
|
|
541
|
+
The tabular estimator path supports **XGBoost**, **LightGBM**, and **DeepFM** natively. Pick one by adding its key to `estimator_config`:
|
|
542
|
+
|
|
543
|
+
```python
|
|
544
|
+
# XGBoost (default)
|
|
545
|
+
create_recommender_pipeline({
|
|
546
|
+
"recommender_type": "ranking",
|
|
547
|
+
"scorer_type": "universal",
|
|
548
|
+
"estimator_config": {"ml_task": "classification", "xgboost": {"n_estimators": 200}},
|
|
549
|
+
})
|
|
550
|
+
|
|
551
|
+
# LightGBM — same shape, just swap the key
|
|
552
|
+
create_recommender_pipeline({
|
|
553
|
+
"recommender_type": "ranking",
|
|
554
|
+
"scorer_type": "universal",
|
|
555
|
+
"estimator_config": {"ml_task": "classification", "lightgbm": {"n_estimators": 200, "num_leaves": 63}},
|
|
556
|
+
})
|
|
557
|
+
|
|
558
|
+
# DeepFM — requires scikit-rec[torch]; classification only
|
|
559
|
+
create_recommender_pipeline({
|
|
560
|
+
"recommender_type": "ranking",
|
|
561
|
+
"scorer_type": "universal",
|
|
562
|
+
"estimator_config": {"ml_task": "classification", "deepfm": {"embedding_dim": 16, "epochs": 10}},
|
|
563
|
+
})
|
|
564
|
+
```
|
|
565
|
+
|
|
566
|
+
Only one tabular key (`xgboost`, `lightgbm`, or `deepfm`) may be present in a single config — specifying more than one raises `ValueError`. For estimator types not covered here (custom sklearn models, etc.) you can still compose manually and pass the estimator directly to a scorer.
|
|
567
|
+
|
|
506
568
|
## Next Steps
|
|
507
569
|
|
|
508
570
|
- **[HPO Guide](hpo.md)** — Add hyperparameter optimization to configs
|
|
@@ -325,7 +325,28 @@ def get_recommendations(user_id, user_features, top_k=5):
|
|
|
325
325
|
return recommendations
|
|
326
326
|
```
|
|
327
327
|
|
|
328
|
-
### 4.
|
|
328
|
+
### 4. Thread Safety
|
|
329
|
+
|
|
330
|
+
**`RankingRecommender`** is thread-safe for concurrent inference after training, whether or not a retriever is attached:
|
|
331
|
+
|
|
332
|
+
- **Without a retriever** — the scorer is accessed read-only; no state is mutated per call.
|
|
333
|
+
- **With a retriever** — `_recommend_with_retriever` makes a shallow copy of the scorer at the start of each call, so per-user `item_subset` mutations are confined to that call stack and never touch the shared scorer instance.
|
|
334
|
+
|
|
335
|
+
**`IndependentScorer`** is the one remaining exception — its parallel inference configuration mutates internal state. For multi-threaded serving with `IndependentScorer`, either:
|
|
336
|
+
- Load one recommender instance **per worker process** (the safest approach, and the default for gunicorn/uvicorn multi-process deployments), or
|
|
337
|
+
- Protect the shared instance with a lock.
|
|
338
|
+
|
|
339
|
+
```python
|
|
340
|
+
import threading
|
|
341
|
+
|
|
342
|
+
_lock = threading.Lock()
|
|
343
|
+
|
|
344
|
+
def thread_safe_recommend(interactions_df, users_df, top_k=5):
|
|
345
|
+
with _lock: # only needed when using IndependentScorer
|
|
346
|
+
return recommender.recommend(interactions=interactions_df, users=users_df, top_k=top_k)
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
### 5. Parallel Processing
|
|
329
350
|
|
|
330
351
|
#### For Independent Scorer
|
|
331
352
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## Prerequisites
|
|
4
4
|
|
|
5
|
-
- **Python 3.
|
|
5
|
+
- **Python 3.10** or higher
|
|
6
6
|
|
|
7
7
|
## Install from PyPI
|
|
8
8
|
|
|
@@ -26,6 +26,10 @@ For PyTorch-based models (NCF, Two-Tower, DCN, NeuralFactorization, SASRec, HRNN
|
|
|
26
26
|
pip install scikit-rec[torch]
|
|
27
27
|
```
|
|
28
28
|
|
|
29
|
+
The base install already includes XGBoost, LightGBM, scikit-learn, and Matrix Factorization (NumPy-only). PyTorch is only required for the deep learning estimators listed above.
|
|
30
|
+
|
|
31
|
+
> **Note for contributors:** If you are testing PyTorch-based estimators locally, install with `pip install -e ".[dev,torch]"` — the plain `.[dev]` install skips torch and those tests will be skipped automatically.
|
|
32
|
+
|
|
29
33
|
### AWS Support
|
|
30
34
|
|
|
31
35
|
For S3 data loading:
|
|
@@ -112,6 +112,34 @@ print("\nTop 5 items for each user:")
|
|
|
112
112
|
print(recommendations)
|
|
113
113
|
```
|
|
114
114
|
|
|
115
|
+
## Optional: Config-driven quick start
|
|
116
|
+
|
|
117
|
+
Instead of assembling the pipeline manually, use `skrec.orchestrator` to build a recommender from a configuration dictionary. This is ideal for automated workflows and agent-based systems.
|
|
118
|
+
|
|
119
|
+
```python
|
|
120
|
+
from skrec.orchestrator import create_recommender_pipeline
|
|
121
|
+
|
|
122
|
+
config = {
|
|
123
|
+
"recommender_type": "ranking",
|
|
124
|
+
"scorer_type": "universal",
|
|
125
|
+
"estimator_config": {
|
|
126
|
+
"ml_task": "classification",
|
|
127
|
+
"xgboost": {
|
|
128
|
+
"n_estimators": 100,
|
|
129
|
+
"max_depth": 5,
|
|
130
|
+
"learning_rate": 0.1,
|
|
131
|
+
},
|
|
132
|
+
},
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
recommender = create_recommender_pipeline(config)
|
|
136
|
+
recommender.train(
|
|
137
|
+
interactions_ds=sample_binary_reward_interactions,
|
|
138
|
+
users_ds=sample_binary_reward_users,
|
|
139
|
+
items_ds=sample_binary_reward_items,
|
|
140
|
+
)
|
|
141
|
+
```
|
|
142
|
+
|
|
115
143
|
### Output Format
|
|
116
144
|
|
|
117
145
|
The output is a NumPy array where:
|