spforge 0.8.30__tar.gz → 0.8.31__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.
Potentially problematic release.
This version of spforge might be problematic. Click here for more details.
- {spforge-0.8.30/spforge.egg-info → spforge-0.8.31}/PKG-INFO +1 -1
- {spforge-0.8.30 → spforge-0.8.31}/pyproject.toml +1 -1
- {spforge-0.8.30 → spforge-0.8.31}/spforge/ratings/_player_rating.py +2 -2
- {spforge-0.8.30 → spforge-0.8.31/spforge.egg-info}/PKG-INFO +1 -1
- {spforge-0.8.30 → spforge-0.8.31}/tests/ratings/test_player_rating_generator.py +53 -0
- {spforge-0.8.30 → spforge-0.8.31}/LICENSE +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/MANIFEST.in +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/README.md +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/examples/__init__.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/examples/game_level_example.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/examples/lol/__init__.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/examples/lol/data/__init__.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/examples/lol/data/subsample_lol_data.parquet +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/examples/lol/data/utils.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/examples/lol/pipeline_transformer_example.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/examples/nba/__init__.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/examples/nba/cross_validation_example.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/examples/nba/data/__init__.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/examples/nba/data/game_player_subsample.parquet +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/examples/nba/data/utils.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/examples/nba/feature_engineering_example.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/examples/nba/game_winner_example.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/examples/nba/predictor_transformers_example.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/setup.cfg +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/spforge/__init__.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/spforge/autopipeline.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/spforge/base_feature_generator.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/spforge/cross_validator/__init__.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/spforge/cross_validator/_base.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/spforge/cross_validator/cross_validator.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/spforge/data_structures.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/spforge/distributions/__init__.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/spforge/distributions/_negative_binomial_estimator.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/spforge/distributions/_normal_distribution_predictor.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/spforge/distributions/_student_t_distribution_estimator.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/spforge/estimator/__init__.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/spforge/estimator/_conditional_estimator.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/spforge/estimator/_frequency_bucketing_classifier.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/spforge/estimator/_granularity_estimator.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/spforge/estimator/_group_by_estimator.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/spforge/estimator/_ordinal_classifier.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/spforge/estimator/_sklearn_enhancer_estimator.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/spforge/feature_generator/__init__.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/spforge/feature_generator/_base.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/spforge/feature_generator/_lag.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/spforge/feature_generator/_net_over_predicted.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/spforge/feature_generator/_regressor_feature_generator.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/spforge/feature_generator/_rolling_against_opponent.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/spforge/feature_generator/_rolling_mean_binary.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/spforge/feature_generator/_rolling_mean_days.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/spforge/feature_generator/_rolling_window.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/spforge/feature_generator/_utils.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/spforge/features_generator_pipeline.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/spforge/hyperparameter_tuning/__init__.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/spforge/hyperparameter_tuning/_default_search_spaces.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/spforge/hyperparameter_tuning/_tuner.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/spforge/performance_transformers/__init__.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/spforge/performance_transformers/_performance_manager.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/spforge/performance_transformers/_performances_transformers.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/spforge/ratings/__init__.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/spforge/ratings/_base.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/spforge/ratings/_team_rating.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/spforge/ratings/enums.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/spforge/ratings/league_identifier.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/spforge/ratings/league_start_rating_optimizer.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/spforge/ratings/player_performance_predictor.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/spforge/ratings/start_rating_generator.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/spforge/ratings/team_performance_predictor.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/spforge/ratings/team_start_rating_generator.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/spforge/ratings/utils.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/spforge/scorer/__init__.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/spforge/scorer/_score.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/spforge/transformers/__init__.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/spforge/transformers/_base.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/spforge/transformers/_net_over_predicted.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/spforge/transformers/_operator.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/spforge/transformers/_other_transformer.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/spforge/transformers/_predictor.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/spforge/transformers/_simple_transformer.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/spforge/transformers/_team_ratio_predictor.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/spforge/utils.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/spforge.egg-info/SOURCES.txt +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/spforge.egg-info/dependency_links.txt +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/spforge.egg-info/requires.txt +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/spforge.egg-info/top_level.txt +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/tests/cross_validator/test_cross_validator.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/tests/distributions/test_distribution.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/tests/end_to_end/test_estimator_hyperparameter_tuning.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/tests/end_to_end/test_league_start_rating_optimizer.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/tests/end_to_end/test_lol_player_kills.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/tests/end_to_end/test_nba_player_points.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/tests/end_to_end/test_nba_player_ratings_hyperparameter_tuning.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/tests/end_to_end/test_nba_prediction_consistency.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/tests/estimator/test_sklearn_estimator.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/tests/feature_generator/test_lag.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/tests/feature_generator/test_regressor_feature_generator.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/tests/feature_generator/test_rolling_against_opponent.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/tests/feature_generator/test_rolling_mean_binary.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/tests/feature_generator/test_rolling_mean_days.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/tests/feature_generator/test_rolling_window.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/tests/hyperparameter_tuning/test_estimator_tuner.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/tests/hyperparameter_tuning/test_rating_tuner.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/tests/performance_transformers/test_performance_manager.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/tests/performance_transformers/test_performances_transformers.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/tests/ratings/test_player_rating_no_mutation.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/tests/ratings/test_ratings_property.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/tests/ratings/test_team_rating_generator.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/tests/ratings/test_utils_scaled_weights.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/tests/scorer/test_score.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/tests/scorer/test_score_aggregation_granularity.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/tests/scorer/test_scorer_name.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/tests/test_autopipeline.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/tests/test_autopipeline_context.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/tests/test_feature_generator_pipeline.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/tests/transformers/test_estimator_transformer_context.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/tests/transformers/test_net_over_predicted.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/tests/transformers/test_other_transformer.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/tests/transformers/test_predictor_transformer.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/tests/transformers/test_simple_transformer.py +0 -0
- {spforge-0.8.30 → spforge-0.8.31}/tests/transformers/test_team_ratio_predictor.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: spforge
|
|
3
|
-
Version: 0.8.
|
|
3
|
+
Version: 0.8.31
|
|
4
4
|
Summary: A flexible framework for generating features, ratings, and building machine learning or other models for training and inference on sports data.
|
|
5
5
|
Author-email: Mathias Holmstrøm <mathiasholmstom@gmail.com>
|
|
6
6
|
License: See LICENSE file
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "spforge"
|
|
7
|
-
version = "0.8.
|
|
7
|
+
version = "0.8.31"
|
|
8
8
|
description = "A flexible framework for generating features, ratings, and building machine learning or other models for training and inference on sports data."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.11"
|
|
@@ -595,7 +595,7 @@ class PlayerRatingGenerator(RatingGenerator):
|
|
|
595
595
|
* float(pre_player.match_performance.participation_weight)
|
|
596
596
|
)
|
|
597
597
|
|
|
598
|
-
if
|
|
598
|
+
if team1_def_perf is None:
|
|
599
599
|
def_change = 0.0
|
|
600
600
|
else:
|
|
601
601
|
def_perf = float(team1_def_perf)
|
|
@@ -689,7 +689,7 @@ class PlayerRatingGenerator(RatingGenerator):
|
|
|
689
689
|
* float(pre_player.match_performance.participation_weight)
|
|
690
690
|
)
|
|
691
691
|
|
|
692
|
-
if
|
|
692
|
+
if team2_def_perf is None:
|
|
693
693
|
def_change = 0.0
|
|
694
694
|
else:
|
|
695
695
|
def_perf = float(team2_def_perf)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: spforge
|
|
3
|
-
Version: 0.8.
|
|
3
|
+
Version: 0.8.31
|
|
4
4
|
Summary: A flexible framework for generating features, ratings, and building machine learning or other models for training and inference on sports data.
|
|
5
5
|
Author-email: Mathias Holmstrøm <mathiasholmstom@gmail.com>
|
|
6
6
|
License: See LICENSE file
|
|
@@ -2133,6 +2133,59 @@ def test_fit_transform_when_all_players_have_null_performance_then_no_rating_cha
|
|
|
2133
2133
|
)
|
|
2134
2134
|
|
|
2135
2135
|
|
|
2136
|
+
def test_null_individual_perf_still_updates_def_rating(base_cn):
|
|
2137
|
+
"""
|
|
2138
|
+
Regression test: Players with null individual performance should still get DEF updates.
|
|
2139
|
+
|
|
2140
|
+
Bug: Line 598 had `if perf_value is None or team1_def_perf is None: def_change = 0.0`
|
|
2141
|
+
This incorrectly skipped DEF updates when player had null individual performance.
|
|
2142
|
+
|
|
2143
|
+
Fix: Changed to `if team1_def_perf is None: def_change = 0.0`
|
|
2144
|
+
Defense is team-level, so null individual perf should NOT block DEF updates.
|
|
2145
|
+
|
|
2146
|
+
Test creates scenario where P1 has null perf but team defense is known (poor).
|
|
2147
|
+
Verifies P1's DEF rating decreases (proving defensive update logic ran).
|
|
2148
|
+
"""
|
|
2149
|
+
# Match 1: Balanced to establish baseline ratings
|
|
2150
|
+
# Match 2: P1 null perf, but T2 dominates offense (0.9) so T1 defense is poor (0.1)
|
|
2151
|
+
df = pl.DataFrame(
|
|
2152
|
+
{
|
|
2153
|
+
"pid": ["P1", "P2", "P3", "P4", "P1", "P2", "P3", "P4"],
|
|
2154
|
+
"tid": ["T1", "T1", "T2", "T2", "T1", "T1", "T2", "T2"],
|
|
2155
|
+
"mid": ["M1", "M1", "M1", "M1", "M2", "M2", "M2", "M2"],
|
|
2156
|
+
"dt": ["2024-01-01"] * 4 + ["2024-01-02"] * 4,
|
|
2157
|
+
"perf": [0.5, 0.5, 0.5, 0.5, None, 0.1, 0.9, 0.9],
|
|
2158
|
+
"pw": [1.0] * 8,
|
|
2159
|
+
}
|
|
2160
|
+
)
|
|
2161
|
+
|
|
2162
|
+
gen = PlayerRatingGenerator(
|
|
2163
|
+
performance_column="perf",
|
|
2164
|
+
column_names=base_cn,
|
|
2165
|
+
use_off_def_split=True,
|
|
2166
|
+
rating_change_multiplier_offense=50.0, # High multipliers to ensure visible changes
|
|
2167
|
+
rating_change_multiplier_defense=50.0,
|
|
2168
|
+
start_rating_value=1000.0,
|
|
2169
|
+
)
|
|
2170
|
+
gen.fit_transform(df)
|
|
2171
|
+
|
|
2172
|
+
# P1 had null perf in M2, so OFF rating should be unchanged from baseline
|
|
2173
|
+
p1_off = gen._player_off_ratings["P1"].rating_value
|
|
2174
|
+
assert p1_off == 1000.0, f"P1 OFF should be 1000 (null perf), got {p1_off}"
|
|
2175
|
+
|
|
2176
|
+
# P1's DEF rating MUST decrease because T1's defense was poor (0.1) in M2
|
|
2177
|
+
# Team defense = 1.0 - opponent offense = 1.0 - 0.9 = 0.1 (much worse than expected 0.5)
|
|
2178
|
+
p1_def = gen._player_def_ratings["P1"].rating_value
|
|
2179
|
+
assert p1_def < 1000.0, (
|
|
2180
|
+
f"P1 DEF should decrease (team defended poorly), but got {p1_def}. "
|
|
2181
|
+
f"Bug: defensive update was incorrectly skipped for null individual performance."
|
|
2182
|
+
)
|
|
2183
|
+
|
|
2184
|
+
# Sanity check: P2 had valid perf (0.1) so OFF should change too
|
|
2185
|
+
p2_off = gen._player_off_ratings["P2"].rating_value
|
|
2186
|
+
assert p2_off != 1000.0, f"P2 OFF should change (valid perf 0.1), got {p2_off}"
|
|
2187
|
+
|
|
2188
|
+
|
|
2136
2189
|
# --- team_players_playing_time Tests ---
|
|
2137
2190
|
|
|
2138
2191
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{spforge-0.8.30 → spforge-0.8.31}/spforge/distributions/_student_t_distribution_estimator.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{spforge-0.8.30 → spforge-0.8.31}/spforge/performance_transformers/_performances_transformers.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{spforge-0.8.30 → spforge-0.8.31}/tests/end_to_end/test_nba_player_ratings_hyperparameter_tuning.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{spforge-0.8.30 → spforge-0.8.31}/tests/feature_generator/test_regressor_feature_generator.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{spforge-0.8.30 → spforge-0.8.31}/tests/performance_transformers/test_performance_manager.py
RENAMED
|
File without changes
|
{spforge-0.8.30 → spforge-0.8.31}/tests/performance_transformers/test_performances_transformers.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|