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.
Files changed (310) hide show
  1. {scikit_rec-0.3.2 → scikit_rec-0.4}/.gitignore +1 -0
  2. scikit_rec-0.4/CODE_OF_CONDUCT.md +33 -0
  3. scikit_rec-0.4/CONTRIBUTING.md +146 -0
  4. {scikit_rec-0.3.2 → scikit_rec-0.4}/PKG-INFO +71 -4
  5. {scikit_rec-0.3.2 → scikit_rec-0.4}/README.md +68 -3
  6. {scikit_rec-0.3.2 → scikit_rec-0.4}/docs/advanced/orchestration.md +72 -10
  7. {scikit_rec-0.3.2 → scikit_rec-0.4}/docs/advanced/production.md +22 -1
  8. {scikit_rec-0.3.2 → scikit_rec-0.4}/docs/getting-started/installation.md +5 -1
  9. {scikit_rec-0.3.2 → scikit_rec-0.4}/docs/getting-started/quick-start.md +28 -0
  10. {scikit_rec-0.3.2 → scikit_rec-0.4}/docs/recommender-types/ranking.md +25 -1
  11. {scikit_rec-0.3.2 → scikit_rec-0.4}/docs/user-guide/capability-matrix.md +16 -0
  12. scikit_rec-0.4/docs/user-guide/decision-rule.md +124 -0
  13. {scikit_rec-0.3.2 → scikit_rec-0.4}/docs/user-guide/scorers.md +218 -3
  14. scikit_rec-0.4/examples/mixed_type_multi_target/conditional.ipynb +693 -0
  15. scikit_rec-0.4/examples/mixed_type_multi_target/independent.ipynb +760 -0
  16. scikit_rec-0.4/examples/mixed_type_multi_target/joint_families.ipynb +886 -0
  17. {scikit_rec-0.3.2 → scikit_rec-0.4}/examples/movielens-1m/composability_demo.ipynb +2 -2
  18. scikit_rec-0.4/mixed_type_multi_target_plan_v2.md +1082 -0
  19. scikit_rec-0.4/mixed_type_multi_target_plan_v3.md +235 -0
  20. {scikit_rec-0.3.2 → scikit_rec-0.4}/mkdocs.yml +1 -0
  21. {scikit_rec-0.3.2 → scikit_rec-0.4}/pyproject.toml +8 -0
  22. {scikit_rec-0.3.2 → scikit_rec-0.4}/scikit_rec.egg-info/PKG-INFO +71 -4
  23. {scikit_rec-0.3.2 → scikit_rec-0.4}/scikit_rec.egg-info/SOURCES.txt +29 -0
  24. {scikit_rec-0.3.2 → scikit_rec-0.4}/scikit_rec.egg-info/requires.txt +3 -0
  25. scikit_rec-0.4/skrec/constants.py +16 -0
  26. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/dataset/interactions_dataset.py +24 -0
  27. scikit_rec-0.4/skrec/dataset/required_schemas/users_schema.yaml +3 -0
  28. scikit_rec-0.4/skrec/estimator/classification/__init__.py +29 -0
  29. scikit_rec-0.4/skrec/estimator/classification/_conditional_joint_multi_target_base.py +601 -0
  30. scikit_rec-0.4/skrec/estimator/classification/_conditional_label_encoding.py +382 -0
  31. scikit_rec-0.4/skrec/estimator/classification/_joint_multi_target_base.py +794 -0
  32. scikit_rec-0.4/skrec/estimator/classification/_joint_multi_target_encoders.py +309 -0
  33. scikit_rec-0.4/skrec/estimator/classification/_multi_target_protocol.py +249 -0
  34. scikit_rec-0.4/skrec/estimator/classification/conditional_joint_multi_target_mlp.py +54 -0
  35. scikit_rec-0.4/skrec/estimator/classification/conditional_joint_multi_target_transformer.py +81 -0
  36. scikit_rec-0.4/skrec/estimator/classification/independent_multi_target.py +545 -0
  37. scikit_rec-0.4/skrec/estimator/classification/joint_multi_target_mlp.py +64 -0
  38. scikit_rec-0.4/skrec/estimator/classification/joint_multi_target_transformer.py +76 -0
  39. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/metrics/base_metric.py +16 -0
  40. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/metrics/datatypes.py +3 -0
  41. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/metrics/factory.py +2 -0
  42. scikit_rec-0.4/skrec/metrics/multiclass_accuracy.py +63 -0
  43. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/orchestrator/__init__.py +27 -0
  44. scikit_rec-0.4/skrec/orchestrator/factory.py +1411 -0
  45. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/recommender/base_recommender.py +19 -5
  46. scikit_rec-0.4/skrec/recommender/inference_input.py +223 -0
  47. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/recommender/ranking/ranking_recommender.py +418 -6
  48. scikit_rec-0.4/skrec/scorer/__init__.py +11 -0
  49. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/scorer/base_scorer.py +83 -0
  50. scikit_rec-0.4/skrec/scorer/mixed_type_multi_target.py +1233 -0
  51. scikit_rec-0.4/tests/test_conditional_joint_multi_target.py +1474 -0
  52. scikit_rec-0.4/tests/test_factory_multi_target.py +961 -0
  53. scikit_rec-0.4/tests/test_independent_multi_target.py +886 -0
  54. scikit_rec-0.4/tests/test_joint_multi_target_mlp.py +578 -0
  55. scikit_rec-0.4/tests/test_joint_multi_target_transformer.py +347 -0
  56. scikit_rec-0.4/tests/test_mixed_type_multi_target_evaluation.py +1339 -0
  57. scikit_rec-0.4/tests/test_mixed_type_multi_target_gates.py +508 -0
  58. scikit_rec-0.4/tests/test_mixed_type_multi_target_scorer.py +1940 -0
  59. {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_orchestrator_factory.py +158 -18
  60. {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_s3.py +7 -2
  61. scikit_rec-0.3.2/skrec/constants.py +0 -9
  62. scikit_rec-0.3.2/skrec/orchestrator/factory.py +0 -724
  63. scikit_rec-0.3.2/skrec/recommender/inference_input.py +0 -107
  64. scikit_rec-0.3.2/skrec/scorer/__init__.py +0 -0
  65. scikit_rec-0.3.2/tests/__init__.py +0 -0
  66. {scikit_rec-0.3.2 → scikit_rec-0.4}/.github/workflows/ci.yml +0 -0
  67. {scikit_rec-0.3.2 → scikit_rec-0.4}/.github/workflows/docs.yml +0 -0
  68. {scikit_rec-0.3.2 → scikit_rec-0.4}/.github/workflows/publish.yml +0 -0
  69. {scikit_rec-0.3.2 → scikit_rec-0.4}/LICENSE +0 -0
  70. {scikit_rec-0.3.2 → scikit_rec-0.4}/docs/advanced/hpo.md +0 -0
  71. {scikit_rec-0.3.2 → scikit_rec-0.4}/docs/advanced/hybrid.md +0 -0
  72. {scikit_rec-0.3.2 → scikit_rec-0.4}/docs/examples/index.md +0 -0
  73. {scikit_rec-0.3.2 → scikit_rec-0.4}/docs/getting-started/datasets.md +0 -0
  74. {scikit_rec-0.3.2 → scikit_rec-0.4}/docs/images/3layers.png +0 -0
  75. {scikit_rec-0.3.2 → scikit_rec-0.4}/docs/images/RecommenderFlowcharts.pptx +0 -0
  76. {scikit_rec-0.3.2 → scikit_rec-0.4}/docs/images/recommender_dataset.png +0 -0
  77. {scikit_rec-0.3.2 → scikit_rec-0.4}/docs/images/scorer.png +0 -0
  78. {scikit_rec-0.3.2 → scikit_rec-0.4}/docs/index.md +0 -0
  79. {scikit_rec-0.3.2 → scikit_rec-0.4}/docs/recommender-types/bandits.md +0 -0
  80. {scikit_rec-0.3.2 → scikit_rec-0.4}/docs/recommender-types/comparison.md +0 -0
  81. {scikit_rec-0.3.2 → scikit_rec-0.4}/docs/recommender-types/gcsl.md +0 -0
  82. {scikit_rec-0.3.2 → scikit_rec-0.4}/docs/recommender-types/hierarchical.md +0 -0
  83. {scikit_rec-0.3.2 → scikit_rec-0.4}/docs/recommender-types/sequential.md +0 -0
  84. {scikit_rec-0.3.2 → scikit_rec-0.4}/docs/recommender-types/uplift.md +0 -0
  85. {scikit_rec-0.3.2 → scikit_rec-0.4}/docs/stylesheets/extra.css +0 -0
  86. {scikit_rec-0.3.2 → scikit_rec-0.4}/docs/user-guide/architecture.md +0 -0
  87. {scikit_rec-0.3.2 → scikit_rec-0.4}/docs/user-guide/collaborative-filtering.md +0 -0
  88. {scikit_rec-0.3.2 → scikit_rec-0.4}/docs/user-guide/estimators.md +0 -0
  89. {scikit_rec-0.3.2 → scikit_rec-0.4}/docs/user-guide/evaluation.md +0 -0
  90. {scikit_rec-0.3.2 → scikit_rec-0.4}/docs/user-guide/hrnn.md +0 -0
  91. {scikit_rec-0.3.2 → scikit_rec-0.4}/docs/user-guide/inference.md +0 -0
  92. {scikit_rec-0.3.2 → scikit_rec-0.4}/docs/user-guide/ncf.md +0 -0
  93. {scikit_rec-0.3.2 → scikit_rec-0.4}/docs/user-guide/retrieval.md +0 -0
  94. {scikit_rec-0.3.2 → scikit_rec-0.4}/docs/user-guide/sasrec.md +0 -0
  95. {scikit_rec-0.3.2 → scikit_rec-0.4}/docs/user-guide/training.md +0 -0
  96. {scikit_rec-0.3.2 → scikit_rec-0.4}/docs/user-guide/two-tower.md +0 -0
  97. {scikit_rec-0.3.2 → scikit_rec-0.4}/examples/amazon-books/deepfm_amazon_books.ipynb +0 -0
  98. {scikit_rec-0.3.2 → scikit_rec-0.4}/examples/amazon-books/lightgbm_amazon_books.ipynb +0 -0
  99. {scikit_rec-0.3.2 → scikit_rec-0.4}/examples/amazon-books/ncf_amazon_books.ipynb +0 -0
  100. {scikit_rec-0.3.2 → scikit_rec-0.4}/examples/amazon-books/sasrec_amazon_books_positives.ipynb +0 -0
  101. {scikit_rec-0.3.2 → scikit_rec-0.4}/examples/generic/factory_pipeline_demo.ipynb +0 -0
  102. {scikit_rec-0.3.2 → scikit_rec-0.4}/examples/generic/retrieval_two_stage.ipynb +0 -0
  103. {scikit_rec-0.3.2 → scikit_rec-0.4}/examples/generic/uplift_modeling.ipynb +0 -0
  104. {scikit_rec-0.3.2 → scikit_rec-0.4}/examples/movielens-1m/contextualized_two_tower_context_modes.ipynb +0 -0
  105. {scikit_rec-0.3.2 → scikit_rec-0.4}/examples/movielens-1m/gcsl_multi_objective_movielens1m.ipynb +0 -0
  106. {scikit_rec-0.3.2 → scikit_rec-0.4}/examples/movielens-1m/hpo_xgboost_movielens1m.ipynb +0 -0
  107. {scikit_rec-0.3.2 → scikit_rec-0.4}/examples/movielens-1m/hrnn_movielens1m.ipynb +0 -0
  108. {scikit_rec-0.3.2 → scikit_rec-0.4}/examples/movielens-1m/ranking_xgboost_movielens1m.ipynb +0 -0
  109. {scikit_rec-0.3.2 → scikit_rec-0.4}/examples/movielens-1m/sasrec_movielens1m_positives.ipynb +0 -0
  110. {scikit_rec-0.3.2 → scikit_rec-0.4}/examples/movielens-1m/sasrec_movielens1m_ratings.ipynb +0 -0
  111. {scikit_rec-0.3.2 → scikit_rec-0.4}/examples/movielens-1m/sasrec_movielens1m_ratings_mse.ipynb +0 -0
  112. {scikit_rec-0.3.2 → scikit_rec-0.4}/examples/ope_validation/obd_ope_validation.ipynb +0 -0
  113. {scikit_rec-0.3.2 → scikit_rec-0.4}/scikit_rec.egg-info/dependency_links.txt +0 -0
  114. {scikit_rec-0.3.2 → scikit_rec-0.4}/scikit_rec.egg-info/top_level.txt +0 -0
  115. {scikit_rec-0.3.2 → scikit_rec-0.4}/setup.cfg +0 -0
  116. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/__init__.py +0 -0
  117. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/__version.py +0 -0
  118. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/dataset/batch_training_dataset.py +0 -0
  119. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/dataset/dataset.py +0 -0
  120. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/dataset/datatypes.py +0 -0
  121. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/dataset/items_dataset.py +0 -0
  122. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/dataset/local_data_reader.py +0 -0
  123. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/dataset/required_schemas/interaction_multiclass_schema_training.yaml +0 -0
  124. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/dataset/required_schemas/interaction_multioutput_schema_training.yaml +0 -0
  125. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/dataset/required_schemas/interactions_schema_inference.yaml +0 -0
  126. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/dataset/required_schemas/interactions_schema_training.yaml +0 -0
  127. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/dataset/required_schemas/interactions_schema_with_timestamp_training.yaml +0 -0
  128. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/dataset/required_schemas/items_schema.yaml +0 -0
  129. /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
  130. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/dataset/s3_data_reader.py +0 -0
  131. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/dataset/schema.py +0 -0
  132. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/dataset/users_dataset.py +0 -0
  133. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/estimator/__init__.py +0 -0
  134. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/estimator/base_estimator.py +0 -0
  135. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/estimator/classification/base_classifier.py +0 -0
  136. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/estimator/classification/deep_fm_classifier.py +0 -0
  137. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/estimator/classification/lightgbm_classifier.py +0 -0
  138. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/estimator/classification/logreg_classifier.py +0 -0
  139. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/estimator/classification/multioutput_classifier.py +0 -0
  140. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/estimator/classification/sklearn_universal_classifier.py +0 -0
  141. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/estimator/classification/xgb_classifier.py +0 -0
  142. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/estimator/datatypes.py +0 -0
  143. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/estimator/embedding/base_embedding_estimator.py +0 -0
  144. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/estimator/embedding/base_pytorch_estimator.py +0 -0
  145. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/estimator/embedding/contextualized_two_tower_estimator.py +0 -0
  146. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/estimator/embedding/deep_cross_network_estimator.py +0 -0
  147. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/estimator/embedding/matrix_factorization_estimator.py +0 -0
  148. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/estimator/embedding/ncf_estimator.py +0 -0
  149. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/estimator/embedding/neural_factorization_estimator.py +0 -0
  150. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/estimator/numpy_predictor.py +0 -0
  151. {scikit_rec-0.3.2/skrec/estimator/classification → scikit_rec-0.4/skrec/estimator/regression}/__init__.py +0 -0
  152. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/estimator/regression/base_regressor.py +0 -0
  153. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/estimator/regression/lightgbm_regressor.py +0 -0
  154. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/estimator/regression/multioutput_regressor.py +0 -0
  155. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/estimator/regression/sklearn_universal_regressor.py +0 -0
  156. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/estimator/regression/xgb_regressor.py +0 -0
  157. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/estimator/sequential/__init__.py +0 -0
  158. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/estimator/sequential/base_sequential_estimator.py +0 -0
  159. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/estimator/sequential/hrnn_estimator.py +0 -0
  160. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/estimator/sequential/sasrec_estimator.py +0 -0
  161. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/estimator/tuned_estimator.py +0 -0
  162. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/evaluator/README.md +0 -0
  163. {scikit_rec-0.3.2/skrec/estimator/regression → scikit_rec-0.4/skrec/evaluator}/__init__.py +0 -0
  164. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/evaluator/base_evaluator.py +0 -0
  165. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/evaluator/categories.py +0 -0
  166. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/evaluator/datatypes.py +0 -0
  167. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/evaluator/direct_method.py +0 -0
  168. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/evaluator/doubly_robust.py +0 -0
  169. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/evaluator/evaluation_session.py +0 -0
  170. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/evaluator/factory.py +0 -0
  171. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/evaluator/inverse_propensity_score.py +0 -0
  172. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/evaluator/policy_weighted.py +0 -0
  173. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/evaluator/replay_match.py +0 -0
  174. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/evaluator/simple.py +0 -0
  175. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/evaluator/snips.py +0 -0
  176. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/evaluator/utils.py +0 -0
  177. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/examples/datasets/README.md +0 -0
  178. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/examples/datasets/__init__.py +0 -0
  179. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/examples/datasets/sample_binary_reward/interactions.csv +0 -0
  180. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/examples/datasets/sample_binary_reward/interactions_schema.yaml +0 -0
  181. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/examples/datasets/sample_binary_reward/items.csv +0 -0
  182. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/examples/datasets/sample_binary_reward/items_schema.yaml +0 -0
  183. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/examples/datasets/sample_binary_reward/users.csv +0 -0
  184. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/examples/datasets/sample_binary_reward/users_schema.yaml +0 -0
  185. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/examples/datasets/sample_continuous_reward/interactions.csv +0 -0
  186. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/examples/datasets/sample_continuous_reward/interactions_schema.yaml +0 -0
  187. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/examples/datasets/sample_continuous_reward/items.csv +0 -0
  188. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/examples/datasets/sample_continuous_reward/items_schema.yaml +0 -0
  189. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/examples/datasets/sample_continuous_reward/users.csv +0 -0
  190. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/examples/datasets/sample_continuous_reward/users_schema.yaml +0 -0
  191. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/examples/datasets/sample_multi_class/interactions_multi_class.csv +0 -0
  192. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/examples/datasets/sample_multi_class/interactions_schema.yaml +0 -0
  193. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/examples/datasets/sample_multi_outcome/interactions_multi_outcome.csv +0 -0
  194. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/examples/datasets/sample_multi_outcome/items.csv +0 -0
  195. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/examples/datasets/sample_multi_outcome/users.csv +0 -0
  196. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/examples/datasets/sample_multi_output/interactions.csv +0 -0
  197. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/examples/datasets/sample_multi_output/interactions_schema.yaml +0 -0
  198. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/examples/datasets/sample_uplift/interactions.csv +0 -0
  199. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/examples/datasets/sample_uplift/interactions_schema.yaml +0 -0
  200. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/examples/datasets/sample_uplift/interactions_schema_with_feats.yaml +0 -0
  201. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/examples/datasets/sample_uplift/interactions_with_feats.csv +0 -0
  202. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/examples/datasets/sample_uplift/users.csv +0 -0
  203. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/examples/datasets/sample_uplift/users_schema.yaml +0 -0
  204. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/examples/estimators/estimator_hyperparameters.yaml +0 -0
  205. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/examples/estimators/generated_personalized_data.csv +0 -0
  206. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/examples/estimators/multi_class_data.csv +0 -0
  207. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/examples/estimators/reward_model_data_classification.csv +0 -0
  208. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/examples/estimators/reward_model_data_regression.csv +0 -0
  209. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/examples/scripts/example_script.py +0 -0
  210. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/metrics/MAE.py +0 -0
  211. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/metrics/MAP.py +0 -0
  212. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/metrics/MRR.py +0 -0
  213. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/metrics/NDCG.py +0 -0
  214. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/metrics/PRAUC.py +0 -0
  215. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/metrics/README.md +0 -0
  216. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/metrics/RMSE.py +0 -0
  217. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/metrics/ROCAUC.py +0 -0
  218. {scikit_rec-0.3.2/skrec/evaluator → scikit_rec-0.4/skrec/metrics}/__init__.py +0 -0
  219. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/metrics/expected_reward.py +0 -0
  220. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/metrics/recall.py +0 -0
  221. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/metrics/recommender_precision.py +0 -0
  222. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/metrics/utils.py +0 -0
  223. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/orchestrator/hpo.py +0 -0
  224. {scikit_rec-0.3.2/skrec/metrics → scikit_rec-0.4/skrec/recommender}/__init__.py +0 -0
  225. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/recommender/bandits/contextual_bandits.py +0 -0
  226. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/recommender/bandits/datatypes.py +0 -0
  227. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/recommender/bandits/factory.py +0 -0
  228. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/recommender/bandits/strategy/base_strategy.py +0 -0
  229. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/recommender/bandits/strategy/epsilon_greedy.py +0 -0
  230. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/recommender/bandits/strategy/static_action.py +0 -0
  231. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/recommender/gcsl/__init__.py +0 -0
  232. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/recommender/gcsl/gcsl_recommender.py +0 -0
  233. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/recommender/gcsl/inference/__init__.py +0 -0
  234. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/recommender/gcsl/inference/base_inference.py +0 -0
  235. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/recommender/gcsl/inference/mean_scalarization.py +0 -0
  236. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/recommender/gcsl/inference/percentile_value.py +0 -0
  237. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/recommender/gcsl/inference/predefined_value.py +0 -0
  238. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/recommender/ranking/__init__.py +0 -0
  239. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/recommender/sequential/__init__.py +0 -0
  240. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/recommender/sequential/hierarchical_recommender.py +0 -0
  241. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/recommender/sequential/sequential_recommender.py +0 -0
  242. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/recommender/training_coordinator.py +0 -0
  243. {scikit_rec-0.3.2/skrec/recommender → scikit_rec-0.4/skrec/recommender/uplift_model}/__init__.py +0 -0
  244. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/recommender/uplift_model/uplift_recommender.py +0 -0
  245. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/recommender/uplift_model/uplift_scorer_adapter.py +0 -0
  246. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/retriever/__init__.py +0 -0
  247. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/retriever/base_retriever.py +0 -0
  248. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/retriever/content_based_retriever.py +0 -0
  249. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/retriever/embedding_retriever.py +0 -0
  250. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/retriever/popularity_retriever.py +0 -0
  251. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/scorer/hierarchical.py +0 -0
  252. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/scorer/independent.py +0 -0
  253. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/scorer/multiclass.py +0 -0
  254. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/scorer/multioutput.py +0 -0
  255. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/scorer/sequential.py +0 -0
  256. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/scorer/universal.py +0 -0
  257. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/split.py +0 -0
  258. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/util/config_loader.py +0 -0
  259. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/util/logger.py +0 -0
  260. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/util/numpy_util.py +0 -0
  261. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/util/s3.py +0 -0
  262. {scikit_rec-0.3.2 → scikit_rec-0.4}/skrec/util/torch_device.py +0 -0
  263. {scikit_rec-0.3.2/skrec/recommender/uplift_model → scikit_rec-0.4/tests}/__init__.py +0 -0
  264. {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/conftest.py +0 -0
  265. {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_bandits_recommender.py +0 -0
  266. {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_base_estimator.py +0 -0
  267. {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_base_retriever.py +0 -0
  268. {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_base_scorer.py +0 -0
  269. {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_classifier_estimators.py +0 -0
  270. {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_content_based_retriever.py +0 -0
  271. {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_dataset.py +0 -0
  272. {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_dataset_iterator.py +0 -0
  273. {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_deep_fm_network.py +0 -0
  274. {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_embedding_estimators.py +0 -0
  275. {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_embedding_retriever.py +0 -0
  276. {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_estimator_smoke.py +0 -0
  277. {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_evaluator_utils.py +0 -0
  278. {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_example_datasets.py +0 -0
  279. {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_gcsl_recommender.py +0 -0
  280. {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_hrnn_estimator.py +0 -0
  281. {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_import.py +0 -0
  282. {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_independent_scorer.py +0 -0
  283. {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_matrix_factorization_estimator.py +0 -0
  284. {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_matrix_factorization_integration.py +0 -0
  285. {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_metrics_utils.py +0 -0
  286. {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_multiclass_scorer.py +0 -0
  287. {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_multioutput_evaluation.py +0 -0
  288. {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_multioutput_scorer.py +0 -0
  289. {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_ncf_estimator.py +0 -0
  290. {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_ncf_integration.py +0 -0
  291. {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_numpy.py +0 -0
  292. {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_orchestrator_hpo.py +0 -0
  293. {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_popularity_retriever.py +0 -0
  294. {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_ranking_recommender.py +0 -0
  295. {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_rec_datasets.py +0 -0
  296. {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_recommender_evaluation_session.py +0 -0
  297. {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_recommender_evaluator.py +0 -0
  298. {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_recommender_metrics.py +0 -0
  299. {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_regression_estimators.py +0 -0
  300. {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_retrieval_integration.py +0 -0
  301. {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_sasrec_estimator.py +0 -0
  302. {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_schema.py +0 -0
  303. {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_sequential_recommender.py +0 -0
  304. {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_split.py +0 -0
  305. {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_strategy.py +0 -0
  306. {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_universal_scorer.py +0 -0
  307. {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_uplift_s_learner.py +0 -0
  308. {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_uplift_t_learner.py +0 -0
  309. {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/test_uplift_x_learner.py +0 -0
  310. {scikit_rec-0.3.2 → scikit_rec-0.4}/tests/utils.py +0 -0
@@ -30,3 +30,4 @@ coverage.xml
30
30
 
31
31
  # Example notebook data (auto-fetched/regenerated on first run; not tracked)
32
32
  examples/*/data/
33
+
@@ -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.2
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
+ [![Python Package](https://img.shields.io/pypi/v/scikit-rec?color=blue&logo=python&logoColor=white)](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] # Deep learning models (DeepFM, NCF, SASRec, HRNN, Two-Tower)
67
- pip install scikit-rec[aws] # S3 data loading
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
+ [![Python Package](https://img.shields.io/pypi/v/scikit-rec?color=blue&logo=python&logoColor=white)](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] # Deep learning models (DeepFM, NCF, SASRec, HRNN, Two-Tower)
35
- pip install scikit-rec[aws] # S3 data loading
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 three authoritative enum tuples plus a `capability_matrix()` accessor. These are the same values the factory validates against internally, so they stay in lockstep automatically.
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 # ('ranking', 'bandits', 'sequential', 'hierarchical_sequential', 'uplift', 'gcsl')
160
- SCORER_TYPES # ('universal', 'independent', 'multiclass', 'multioutput', 'sequential', 'hierarchical')
161
- ESTIMATOR_TYPES # ('tabular', 'embedding', 'sequential')
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
- # "independent": (),
176
- # "universal": (),
177
- # "sequential": (),
178
- # "hierarchical": (),
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
- Evaluator and metric enums are **not** included in `capability_matrix()` — those already live as proper `Enum` subclasses in `skrec.evaluator.datatypes.RecommenderEvaluatorType` and `skrec.metrics.datatypes.RecommenderMetricType` and are enumerable directly (e.g. `list(RecommenderEvaluatorType)`).
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
- The full compatibility reference (which scorer works with which estimator, retriever constraints, etc.) is on the [Capability Matrix](../user-guide/capability-matrix.md) page.
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. Parallel Processing
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.9** or higher
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: