spforge 0.8.39__py3-none-any.whl → 0.8.41__py3-none-any.whl
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/data_structures.py +1 -0
- spforge/hyperparameter_tuning/_default_search_spaces.py +0 -6
- spforge/ratings/_player_rating.py +56 -15
- {spforge-0.8.39.dist-info → spforge-0.8.41.dist-info}/METADATA +1 -1
- {spforge-0.8.39.dist-info → spforge-0.8.41.dist-info}/RECORD +14 -14
- tests/end_to_end/test_nba_player_ratings_hyperparameter_tuning.py +0 -1
- tests/hyperparameter_tuning/test_rating_tuner.py +4 -4
- tests/ratings/test_player_rating_generator.py +126 -54
- tests/scorer/test_score.py +6 -6
- tests/test_autopipeline.py +2 -2
- tests/transformers/test_team_ratio_predictor.py +1 -2
- {spforge-0.8.39.dist-info → spforge-0.8.41.dist-info}/WHEEL +0 -0
- {spforge-0.8.39.dist-info → spforge-0.8.41.dist-info}/licenses/LICENSE +0 -0
- {spforge-0.8.39.dist-info → spforge-0.8.41.dist-info}/top_level.txt +0 -0
spforge/data_structures.py
CHANGED
|
@@ -161,9 +161,6 @@ def get_default_player_rating_search_space() -> dict[str, ParamSpec]:
|
|
|
161
161
|
low=50.0,
|
|
162
162
|
high=300.0,
|
|
163
163
|
),
|
|
164
|
-
"use_off_def_split": ParamSpec(
|
|
165
|
-
param_type="bool",
|
|
166
|
-
),
|
|
167
164
|
"start_league_quantile": ParamSpec(
|
|
168
165
|
param_type="float",
|
|
169
166
|
low=0.05,
|
|
@@ -251,9 +248,6 @@ def get_default_team_rating_search_space() -> dict[str, ParamSpec]:
|
|
|
251
248
|
low=50.0,
|
|
252
249
|
high=300.0,
|
|
253
250
|
),
|
|
254
|
-
"use_off_def_split": ParamSpec(
|
|
255
|
-
param_type="bool",
|
|
256
|
-
),
|
|
257
251
|
}
|
|
258
252
|
|
|
259
253
|
|
|
@@ -554,7 +554,7 @@ class PlayerRatingGenerator(RatingGenerator):
|
|
|
554
554
|
player_rating=pre_player,
|
|
555
555
|
opponent_team_rating=PreMatchTeamRating(
|
|
556
556
|
id=team2,
|
|
557
|
-
players=c2.pre_match_player_ratings,
|
|
557
|
+
players=c2.pre_match_def_player_ratings or c2.pre_match_player_ratings,
|
|
558
558
|
rating_value=team2_def_rating,
|
|
559
559
|
),
|
|
560
560
|
team_rating=PreMatchTeamRating(
|
|
@@ -581,7 +581,7 @@ class PlayerRatingGenerator(RatingGenerator):
|
|
|
581
581
|
),
|
|
582
582
|
team_rating=PreMatchTeamRating(
|
|
583
583
|
id=team1,
|
|
584
|
-
players=c1.pre_match_player_ratings,
|
|
584
|
+
players=c1.pre_match_def_player_ratings or c1.pre_match_player_ratings,
|
|
585
585
|
rating_value=team1_def_rating,
|
|
586
586
|
),
|
|
587
587
|
)
|
|
@@ -649,7 +649,7 @@ class PlayerRatingGenerator(RatingGenerator):
|
|
|
649
649
|
player_rating=pre_player,
|
|
650
650
|
opponent_team_rating=PreMatchTeamRating(
|
|
651
651
|
id=team1,
|
|
652
|
-
players=c1.pre_match_player_ratings,
|
|
652
|
+
players=c1.pre_match_def_player_ratings or c1.pre_match_player_ratings,
|
|
653
653
|
rating_value=team1_def_rating,
|
|
654
654
|
),
|
|
655
655
|
team_rating=PreMatchTeamRating(
|
|
@@ -676,7 +676,7 @@ class PlayerRatingGenerator(RatingGenerator):
|
|
|
676
676
|
),
|
|
677
677
|
team_rating=PreMatchTeamRating(
|
|
678
678
|
id=team2,
|
|
679
|
-
players=c2.pre_match_player_ratings,
|
|
679
|
+
players=c2.pre_match_def_player_ratings or c2.pre_match_player_ratings,
|
|
680
680
|
rating_value=team2_def_rating,
|
|
681
681
|
),
|
|
682
682
|
)
|
|
@@ -1094,6 +1094,7 @@ class PlayerRatingGenerator(RatingGenerator):
|
|
|
1094
1094
|
cn = self.column_names
|
|
1095
1095
|
|
|
1096
1096
|
pre_match_player_ratings: list[PreMatchPlayerRating] = []
|
|
1097
|
+
pre_match_def_player_ratings: list[PreMatchPlayerRating] = []
|
|
1097
1098
|
new_players: list[MatchPlayer] = []
|
|
1098
1099
|
player_ids: list[str] = []
|
|
1099
1100
|
player_off_rating_values: list[float] = []
|
|
@@ -1175,6 +1176,7 @@ class PlayerRatingGenerator(RatingGenerator):
|
|
|
1175
1176
|
|
|
1176
1177
|
if player_id in self._player_off_ratings and player_id in self._player_def_ratings:
|
|
1177
1178
|
off_state = self._player_off_ratings[player_id]
|
|
1179
|
+
def_state = self._player_def_ratings[player_id]
|
|
1178
1180
|
pre = PreMatchPlayerRating(
|
|
1179
1181
|
id=player_id,
|
|
1180
1182
|
rating_value=off_state.rating_value,
|
|
@@ -1185,6 +1187,17 @@ class PlayerRatingGenerator(RatingGenerator):
|
|
|
1185
1187
|
)
|
|
1186
1188
|
pre_match_player_ratings.append(pre)
|
|
1187
1189
|
player_off_rating_values.append(float(off_state.rating_value))
|
|
1190
|
+
|
|
1191
|
+
# Also create DEF player rating for use in opponent predictions
|
|
1192
|
+
pre_def = PreMatchPlayerRating(
|
|
1193
|
+
id=player_id,
|
|
1194
|
+
rating_value=def_state.rating_value,
|
|
1195
|
+
match_performance=mp,
|
|
1196
|
+
games_played=def_state.games_played,
|
|
1197
|
+
league=player_league,
|
|
1198
|
+
position=position,
|
|
1199
|
+
)
|
|
1200
|
+
pre_match_def_player_ratings.append(pre_def)
|
|
1188
1201
|
else:
|
|
1189
1202
|
# unseen player -> create start rating (OFF + DEF)
|
|
1190
1203
|
new_players.append(
|
|
@@ -1197,12 +1210,13 @@ class PlayerRatingGenerator(RatingGenerator):
|
|
|
1197
1210
|
)
|
|
1198
1211
|
|
|
1199
1212
|
if new_players:
|
|
1200
|
-
new_pre, new_vals = self._generate_new_player_pre_match_ratings(
|
|
1213
|
+
new_pre, new_def_pre, new_vals = self._generate_new_player_pre_match_ratings(
|
|
1201
1214
|
day_number=day_number,
|
|
1202
1215
|
new_players=new_players,
|
|
1203
1216
|
team_pre_match_player_ratings=pre_match_player_ratings,
|
|
1204
1217
|
)
|
|
1205
1218
|
pre_match_player_ratings.extend(new_pre)
|
|
1219
|
+
pre_match_def_player_ratings.extend(new_def_pre)
|
|
1206
1220
|
player_off_rating_values.extend(new_vals)
|
|
1207
1221
|
|
|
1208
1222
|
return PreMatchPlayersCollection(
|
|
@@ -1211,6 +1225,7 @@ class PlayerRatingGenerator(RatingGenerator):
|
|
|
1211
1225
|
player_ids=player_ids,
|
|
1212
1226
|
player_rating_values=player_off_rating_values, # OFF values
|
|
1213
1227
|
projected_particiation_weights=projected_participation_weights,
|
|
1228
|
+
pre_match_def_player_ratings=pre_match_def_player_ratings,
|
|
1214
1229
|
)
|
|
1215
1230
|
|
|
1216
1231
|
def _generate_new_player_pre_match_ratings(
|
|
@@ -1218,11 +1233,13 @@ class PlayerRatingGenerator(RatingGenerator):
|
|
|
1218
1233
|
day_number: int,
|
|
1219
1234
|
new_players: list[MatchPlayer],
|
|
1220
1235
|
team_pre_match_player_ratings: list[PreMatchPlayerRating],
|
|
1221
|
-
) -> tuple[list[PreMatchPlayerRating], list[float]]:
|
|
1236
|
+
) -> tuple[list[PreMatchPlayerRating], list[PreMatchPlayerRating], list[float]]:
|
|
1222
1237
|
"""
|
|
1223
1238
|
Creates BOTH off+def states for new players using the same start rating.
|
|
1239
|
+
Returns (off_ratings, def_ratings, off_values).
|
|
1224
1240
|
"""
|
|
1225
1241
|
pre_match_player_ratings: list[PreMatchPlayerRating] = []
|
|
1242
|
+
pre_match_def_player_ratings: list[PreMatchPlayerRating] = []
|
|
1226
1243
|
pre_match_player_off_values: list[float] = []
|
|
1227
1244
|
|
|
1228
1245
|
for match_player in new_players:
|
|
@@ -1250,7 +1267,19 @@ class PlayerRatingGenerator(RatingGenerator):
|
|
|
1250
1267
|
)
|
|
1251
1268
|
pre_match_player_ratings.append(pre)
|
|
1252
1269
|
|
|
1253
|
-
|
|
1270
|
+
# For new players, DEF rating starts same as OFF rating
|
|
1271
|
+
pre_def = PreMatchPlayerRating(
|
|
1272
|
+
id=pid,
|
|
1273
|
+
rating_value=float(start_val), # DEF rating (same as OFF for new players)
|
|
1274
|
+
match_performance=match_player.performance,
|
|
1275
|
+
games_played=self._player_def_ratings[pid].games_played,
|
|
1276
|
+
league=match_player.league,
|
|
1277
|
+
position=match_player.position,
|
|
1278
|
+
other=match_player.others,
|
|
1279
|
+
)
|
|
1280
|
+
pre_match_def_player_ratings.append(pre_def)
|
|
1281
|
+
|
|
1282
|
+
return pre_match_player_ratings, pre_match_def_player_ratings, pre_match_player_off_values
|
|
1254
1283
|
|
|
1255
1284
|
def _team_off_perf_from_collection(
|
|
1256
1285
|
self, c: PreMatchPlayersCollection
|
|
@@ -1378,8 +1407,9 @@ class PlayerRatingGenerator(RatingGenerator):
|
|
|
1378
1407
|
|
|
1379
1408
|
def build_local_team(
|
|
1380
1409
|
stats_col: str,
|
|
1381
|
-
) -> tuple[list[PreMatchPlayerRating], list[str], list[float], list[float], float]:
|
|
1410
|
+
) -> tuple[list[PreMatchPlayerRating], list[PreMatchPlayerRating], list[str], list[float], list[float], float]:
|
|
1382
1411
|
pre_list: list[PreMatchPlayerRating] = []
|
|
1412
|
+
def_pre_list: list[PreMatchPlayerRating] = []
|
|
1383
1413
|
player_ids: list[str] = []
|
|
1384
1414
|
proj_w: list[float] = []
|
|
1385
1415
|
off_vals: list[float] = []
|
|
@@ -1454,6 +1484,17 @@ class PlayerRatingGenerator(RatingGenerator):
|
|
|
1454
1484
|
position=position,
|
|
1455
1485
|
)
|
|
1456
1486
|
)
|
|
1487
|
+
# Also build DEF player ratings for opponent weighting
|
|
1488
|
+
def_pre_list.append(
|
|
1489
|
+
PreMatchPlayerRating(
|
|
1490
|
+
id=pid,
|
|
1491
|
+
rating_value=float(local_def[pid].rating_value),
|
|
1492
|
+
match_performance=mp,
|
|
1493
|
+
games_played=float(local_def[pid].games_played),
|
|
1494
|
+
league=league,
|
|
1495
|
+
position=position,
|
|
1496
|
+
)
|
|
1497
|
+
)
|
|
1457
1498
|
off_vals.append(float(local_off[pid].rating_value))
|
|
1458
1499
|
|
|
1459
1500
|
if mp.performance_value is not None:
|
|
@@ -1461,10 +1502,10 @@ class PlayerRatingGenerator(RatingGenerator):
|
|
|
1461
1502
|
wsum += float(pw)
|
|
1462
1503
|
|
|
1463
1504
|
team_off_perf = psum / wsum if wsum else 0.0
|
|
1464
|
-
return pre_list, player_ids, off_vals, proj_w, team_off_perf
|
|
1505
|
+
return pre_list, def_pre_list, player_ids, off_vals, proj_w, team_off_perf
|
|
1465
1506
|
|
|
1466
|
-
t1_pre, t1_ids, t1_off_vals, t1_proj_w, t1_off_perf = build_local_team(PLAYER_STATS)
|
|
1467
|
-
t2_pre, t2_ids, t2_off_vals, t2_proj_w, t2_off_perf = build_local_team(
|
|
1507
|
+
t1_pre, t1_def_pre, t1_ids, t1_off_vals, t1_proj_w, t1_off_perf = build_local_team(PLAYER_STATS)
|
|
1508
|
+
t2_pre, t2_def_pre, t2_ids, t2_off_vals, t2_proj_w, t2_off_perf = build_local_team(
|
|
1468
1509
|
f"{PLAYER_STATS}_opponent"
|
|
1469
1510
|
)
|
|
1470
1511
|
|
|
@@ -1492,7 +1533,7 @@ class PlayerRatingGenerator(RatingGenerator):
|
|
|
1492
1533
|
pred_off = self._performance_predictor.predict_performance(
|
|
1493
1534
|
player_rating=pre,
|
|
1494
1535
|
opponent_team_rating=PreMatchTeamRating(
|
|
1495
|
-
id=team2, players=
|
|
1536
|
+
id=team2, players=t2_def_pre, rating_value=t2_def_rating
|
|
1496
1537
|
),
|
|
1497
1538
|
team_rating=PreMatchTeamRating(
|
|
1498
1539
|
id=team1, players=t1_pre, rating_value=t1_off_rating
|
|
@@ -1512,7 +1553,7 @@ class PlayerRatingGenerator(RatingGenerator):
|
|
|
1512
1553
|
id=team2, players=t2_pre, rating_value=t2_off_rating
|
|
1513
1554
|
),
|
|
1514
1555
|
team_rating=PreMatchTeamRating(
|
|
1515
|
-
id=team1, players=
|
|
1556
|
+
id=team1, players=t1_def_pre, rating_value=t1_def_rating
|
|
1516
1557
|
),
|
|
1517
1558
|
)
|
|
1518
1559
|
|
|
@@ -1537,7 +1578,7 @@ class PlayerRatingGenerator(RatingGenerator):
|
|
|
1537
1578
|
pred_off = self._performance_predictor.predict_performance(
|
|
1538
1579
|
player_rating=pre,
|
|
1539
1580
|
opponent_team_rating=PreMatchTeamRating(
|
|
1540
|
-
id=team1, players=
|
|
1581
|
+
id=team1, players=t1_def_pre, rating_value=t1_def_rating
|
|
1541
1582
|
),
|
|
1542
1583
|
team_rating=PreMatchTeamRating(
|
|
1543
1584
|
id=team2, players=t2_pre, rating_value=t2_off_rating
|
|
@@ -1557,7 +1598,7 @@ class PlayerRatingGenerator(RatingGenerator):
|
|
|
1557
1598
|
id=team1, players=t1_pre, rating_value=t1_off_rating
|
|
1558
1599
|
),
|
|
1559
1600
|
team_rating=PreMatchTeamRating(
|
|
1560
|
-
id=team2, players=
|
|
1601
|
+
id=team2, players=t2_def_pre, rating_value=t2_def_rating
|
|
1561
1602
|
),
|
|
1562
1603
|
)
|
|
1563
1604
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: spforge
|
|
3
|
-
Version: 0.8.
|
|
3
|
+
Version: 0.8.41
|
|
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
|
|
@@ -16,7 +16,7 @@ examples/nba/data/utils.py,sha256=41hxLQ1d6ZgBEcHa5MI0-fG5KbsRi07cclMPQZM95ek,50
|
|
|
16
16
|
spforge/__init__.py,sha256=8vZhy7XUpzqWkVKpXqwqOLDkQlNytRhyf4qjwObfXgU,468
|
|
17
17
|
spforge/autopipeline.py,sha256=rZ6FhJxcgNLvtr3hTVkEiW4BiorgXxADThfMuQ42orE,29866
|
|
18
18
|
spforge/base_feature_generator.py,sha256=RbD00N6oLCQQcEb_VF5wbwZztl-X8k9B0Wlaj9Os1iU,668
|
|
19
|
-
spforge/data_structures.py,sha256=
|
|
19
|
+
spforge/data_structures.py,sha256=lNTEmmBbOK11307AshyMAcbuMhMZ3T0WyL4PEAh8cy4,7605
|
|
20
20
|
spforge/features_generator_pipeline.py,sha256=n8vzZKqXNFcFRDWZhllnkhAh5NFXdOD3FEIOpHcay8E,8208
|
|
21
21
|
spforge/utils.py,sha256=2RlivUtMX5wQWpFVUyFfexDJE0wV6uZ4dnNzvoDmVhI,2644
|
|
22
22
|
spforge/cross_validator/__init__.py,sha256=1QHgTFIZ73EZ_MgJlUKimxdUmB7MFaOEy6jsUs6V0T0,134
|
|
@@ -44,14 +44,14 @@ spforge/feature_generator/_rolling_mean_days.py,sha256=EZQmFmYVQB-JjZV5k8bOWnaTx
|
|
|
44
44
|
spforge/feature_generator/_rolling_window.py,sha256=HT8LezsRIPNAlMEoP9oTPW2bKFu55ZSRnQZGST7fncw,8836
|
|
45
45
|
spforge/feature_generator/_utils.py,sha256=KDn33ia1OYJTK8THFpvc_uRiH_Bl3fImGqqbfzs0YA4,9654
|
|
46
46
|
spforge/hyperparameter_tuning/__init__.py,sha256=Vcl8rVlJ7M708iPgqe4XxpZWgJKGux0Y5HgMCymRsHg,1099
|
|
47
|
-
spforge/hyperparameter_tuning/_default_search_spaces.py,sha256=
|
|
47
|
+
spforge/hyperparameter_tuning/_default_search_spaces.py,sha256=yqXuLyABtKGrnm2ydTgGAdS-tDxjWZOlJQWIrZYY0h4,7856
|
|
48
48
|
spforge/hyperparameter_tuning/_tuner.py,sha256=M79q3saM6r0UZJsRUUgfdDr-3Qii-F2-wuSAZLFtZDo,19246
|
|
49
49
|
spforge/performance_transformers/__init__.py,sha256=J-5olqi1M_BUj3sN1NqAz9s28XAbuKK9M9xHq7IGlQU,482
|
|
50
50
|
spforge/performance_transformers/_performance_manager.py,sha256=lh7enqYLd1lXj1VTOiK5N880xkil5q1jRsM51fe_K5g,12322
|
|
51
51
|
spforge/performance_transformers/_performances_transformers.py,sha256=nmjJTEH86JjFneWsnSWIYnUXQoUDskOraDO3VtuufIY,20931
|
|
52
52
|
spforge/ratings/__init__.py,sha256=OZVH2Lo6END3n1X8qi4QcyAPlThIwAYwVKCiIuOQSQU,576
|
|
53
53
|
spforge/ratings/_base.py,sha256=Stl_Y2gjQfS1jq_6CfeRG_e3R5Pei34WETdG6CaibGs,16487
|
|
54
|
-
spforge/ratings/_player_rating.py,sha256=
|
|
54
|
+
spforge/ratings/_player_rating.py,sha256=VFNsENmtbH1EvFkQfmIZKOYweraviqHkxGrieKHn9TY,70511
|
|
55
55
|
spforge/ratings/_team_rating.py,sha256=3m90-R2zW0k5EHwjw-83Hacz91fGmxW1LQ8ZUGHlgt4,24970
|
|
56
56
|
spforge/ratings/enums.py,sha256=maG0X4WMQeMVAc2wbceq1an-U-z8moZGeG2BAgfICDA,1809
|
|
57
57
|
spforge/ratings/league_identifier.py,sha256=_KDUKOwoNU6RNFKE5jju4eYFGVNGBdJsv5mhNvMakfc,6019
|
|
@@ -71,8 +71,8 @@ spforge/transformers/_other_transformer.py,sha256=w2a7Wnki3vJe4GAkSa4kealw0GILIo
|
|
|
71
71
|
spforge/transformers/_predictor.py,sha256=2sE6gfVrilXzPVcBurSrtqHw33v2ljygQcEYXt9LhZc,3119
|
|
72
72
|
spforge/transformers/_simple_transformer.py,sha256=zGUFNQYMeoDSa2CoQejQNiNmKCBN5amWTvyOchiUHj0,5660
|
|
73
73
|
spforge/transformers/_team_ratio_predictor.py,sha256=g8_bR53Yyv0iNCtol1O9bgJSeZcIco_AfbQuUxQJkeY,6884
|
|
74
|
-
spforge-0.8.
|
|
75
|
-
tests/test_autopipeline.py,sha256=
|
|
74
|
+
spforge-0.8.41.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
75
|
+
tests/test_autopipeline.py,sha256=gXFcyqRJwxd70MY1JOqm78RJjF-fnFdMT_FaDhBdEDE,26853
|
|
76
76
|
tests/test_autopipeline_context.py,sha256=IuRUY4IA6uMObvbl2pXSaXO2_tl3qX6wEbTZY0dkTMI,1240
|
|
77
77
|
tests/test_feature_generator_pipeline.py,sha256=CK0zVL8PfTncy3RmG9i-YpgwjOIV7yJhV7Q44tbetI8,19020
|
|
78
78
|
tests/cross_validator/test_cross_validator.py,sha256=itCGhNY8-NbDbKbhxHW20wiLuRst7-Rixpmi3FSKQtA,17474
|
|
@@ -81,7 +81,7 @@ tests/end_to_end/test_estimator_hyperparameter_tuning.py,sha256=fZCJ9rrED2vT68B9
|
|
|
81
81
|
tests/end_to_end/test_league_start_rating_optimizer.py,sha256=Mmct2ixp4c6L7PGym8wZc7E-Csozryt1g4_o6OCc1uI,3141
|
|
82
82
|
tests/end_to_end/test_lol_player_kills.py,sha256=RJSYUbPrZ-RzSxGggj03yN0JKYeTB1JghVGYFMYia3Y,11891
|
|
83
83
|
tests/end_to_end/test_nba_player_points.py,sha256=kyzjo7QIcvpteps29Wix6IS_eJG9d1gHLeWtIHpkWMs,9066
|
|
84
|
-
tests/end_to_end/test_nba_player_ratings_hyperparameter_tuning.py,sha256=
|
|
84
|
+
tests/end_to_end/test_nba_player_ratings_hyperparameter_tuning.py,sha256=9JZo8deJ11rSU3MsEenEjcescg71erAt5yNgZcOyH40,6317
|
|
85
85
|
tests/end_to_end/test_nba_prediction_consistency.py,sha256=o3DckJasx_I1ed6MhMYZUo2WSDvQ_p3HtJa9DCWTIYU,9857
|
|
86
86
|
tests/estimator/test_sklearn_estimator.py,sha256=tVfOP9Wx-tV1b6DcHbGxQHZQzNPA0Iobq8jTcUrk59U,48668
|
|
87
87
|
tests/feature_generator/test_lag.py,sha256=5Ffrv0V9cwkbkzRMPBe3_c_YNW-W2al-XH_acQIvdeg,19531
|
|
@@ -91,15 +91,15 @@ tests/feature_generator/test_rolling_mean_binary.py,sha256=KuIavJ37Pt8icAb50B23l
|
|
|
91
91
|
tests/feature_generator/test_rolling_mean_days.py,sha256=EyOvdJDnmgPfe13uQBOkwo7fAteBQx-tnyuGM4ng2T8,18884
|
|
92
92
|
tests/feature_generator/test_rolling_window.py,sha256=_o9oljcAIZ14iI7e8WFeAsfXxILnyqBffit21HOvII4,24378
|
|
93
93
|
tests/hyperparameter_tuning/test_estimator_tuner.py,sha256=iewME41d6LR2aQ0OtohGFtN_ocJUwTeqvs6L0QDmfG4,4413
|
|
94
|
-
tests/hyperparameter_tuning/test_rating_tuner.py,sha256=
|
|
94
|
+
tests/hyperparameter_tuning/test_rating_tuner.py,sha256=ZyHHAPpE-pHJmwpC7AGTFPSTDWSW4zXA6W4oKBD0v_E,18681
|
|
95
95
|
tests/performance_transformers/test_performance_manager.py,sha256=Ob4s86hdnR_4RC9ZG3lpB5O4Gysr2cLyTmCsO6uWomc,21244
|
|
96
96
|
tests/performance_transformers/test_performances_transformers.py,sha256=2OLpFgBolU8e-1Pga3hiOGWWHhjYpfx8Qrf9YXiqjUw,20919
|
|
97
|
-
tests/ratings/test_player_rating_generator.py,sha256=
|
|
97
|
+
tests/ratings/test_player_rating_generator.py,sha256=IMr4hb5vBfujPH0kBCsN0V8hknUj9h8itN5KYfog9KU,113393
|
|
98
98
|
tests/ratings/test_player_rating_no_mutation.py,sha256=GzO3Hl__5K68DS3uRLefwnbcTJOvBM7cZqww4M21UZM,8493
|
|
99
99
|
tests/ratings/test_ratings_property.py,sha256=ckyfGILXa4tfQvsgyXEzBDNr2DUmHwFRV13N60w66iE,6561
|
|
100
100
|
tests/ratings/test_team_rating_generator.py,sha256=SqQcfckNmJJc99feCdnmkNYDape-p69e92Dp8Vzpu2w,101156
|
|
101
101
|
tests/ratings/test_utils_scaled_weights.py,sha256=iHxe6ZDUB_I2B6HT0xTGqXBkl7gRlqVV0e_7Lwun5po,4988
|
|
102
|
-
tests/scorer/test_score.py,sha256=
|
|
102
|
+
tests/scorer/test_score.py,sha256=7QwGR9r6n2NI4uAr8BlEymGxRPci6Kf-TyFmnbQeajQ,79013
|
|
103
103
|
tests/scorer/test_score_aggregation_granularity.py,sha256=O5TRlG9UE4NBpF0tL_ywZKDmkMIorwrxgTegQ75Tr7A,15871
|
|
104
104
|
tests/scorer/test_scorer_name.py,sha256=lijr8vuHkieVmu_m3zcZril7rG5ByIZ-vSJq5QJFIss,10862
|
|
105
105
|
tests/transformers/test_estimator_transformer_context.py,sha256=5GOHbuWCWBMFwwOTJOuD4oNDsv-qDR0OxNZYGGuMdag,1819
|
|
@@ -107,8 +107,8 @@ tests/transformers/test_net_over_predicted.py,sha256=vh7O1iRRPf4vcW9aLhOMAOyatfM
|
|
|
107
107
|
tests/transformers/test_other_transformer.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
108
108
|
tests/transformers/test_predictor_transformer.py,sha256=N1aBYLjN3ldpYZLwjih_gTFYSMitrZu-PNK78W6RHaQ,6877
|
|
109
109
|
tests/transformers/test_simple_transformer.py,sha256=wWR0qjLb_uS4HXrJgGdiqugOY1X7kwd1_OPS02IT2b8,4676
|
|
110
|
-
tests/transformers/test_team_ratio_predictor.py,sha256=
|
|
111
|
-
spforge-0.8.
|
|
112
|
-
spforge-0.8.
|
|
113
|
-
spforge-0.8.
|
|
114
|
-
spforge-0.8.
|
|
110
|
+
tests/transformers/test_team_ratio_predictor.py,sha256=WA44T2HU2Tx65HO_EZaLB5ujjlxfv5uTZazh_3Mo8Zg,8463
|
|
111
|
+
spforge-0.8.41.dist-info/METADATA,sha256=vpBh492wIgqgEawqz2bno5dTYH-vhMZtDmTybKL-0GQ,20048
|
|
112
|
+
spforge-0.8.41.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
113
|
+
spforge-0.8.41.dist-info/top_level.txt,sha256=6UW2M5a7WKOeaAi900qQmRKNj5-HZzE8-eUD9Y9LTq0,23
|
|
114
|
+
spforge-0.8.41.dist-info/RECORD,,
|
|
@@ -536,21 +536,21 @@ def test_param_ranges__unknown_param_raises_error(
|
|
|
536
536
|
tuner.optimize(sample_player_df_pd)
|
|
537
537
|
|
|
538
538
|
|
|
539
|
-
def
|
|
539
|
+
def test_param_ranges__unknown_param_raises_error(
|
|
540
540
|
player_rating_generator, cross_validator, scorer, sample_player_df_pd
|
|
541
541
|
):
|
|
542
|
-
"""Test that param_ranges
|
|
542
|
+
"""Test that param_ranges with unknown parameter raises ValueError."""
|
|
543
543
|
tuner = RatingHyperparameterTuner(
|
|
544
544
|
rating_generator=player_rating_generator,
|
|
545
545
|
cross_validator=cross_validator,
|
|
546
546
|
scorer=scorer,
|
|
547
547
|
direction="minimize",
|
|
548
|
-
param_ranges={"
|
|
548
|
+
param_ranges={"unknown_param": (0, 1)},
|
|
549
549
|
n_trials=3,
|
|
550
550
|
show_progress_bar=False,
|
|
551
551
|
)
|
|
552
552
|
|
|
553
|
-
with pytest.raises(ValueError, match="
|
|
553
|
+
with pytest.raises(ValueError, match="unknown parameter"):
|
|
554
554
|
tuner.optimize(sample_player_df_pd)
|
|
555
555
|
|
|
556
556
|
|
|
@@ -2288,7 +2288,15 @@ def test_fit_transform_null_playing_time_uses_standard_team_rating(base_cn):
|
|
|
2288
2288
|
|
|
2289
2289
|
|
|
2290
2290
|
def test_fit_transform_weighted_calculation_with_playing_time(base_cn):
|
|
2291
|
-
"""Test that playing time weighted calculation produces
|
|
2291
|
+
"""Test that playing time weighted calculation produces valid predictions.
|
|
2292
|
+
|
|
2293
|
+
This test verifies that when opponent_players_playing_time is provided, the predictor
|
|
2294
|
+
produces valid predictions without errors.
|
|
2295
|
+
|
|
2296
|
+
Note: The specific differential behavior (P3 vs P4 predictions) is covered by
|
|
2297
|
+
test_opponent_players_playing_time_uses_def_ratings_for_offense_prediction which
|
|
2298
|
+
uses a simplified 2-player setup that more directly tests the opponent DEF rating fix.
|
|
2299
|
+
"""
|
|
2292
2300
|
from dataclasses import replace
|
|
2293
2301
|
|
|
2294
2302
|
cn = replace(
|
|
@@ -2297,78 +2305,54 @@ def test_fit_transform_weighted_calculation_with_playing_time(base_cn):
|
|
|
2297
2305
|
opponent_players_playing_time="opp_pt",
|
|
2298
2306
|
)
|
|
2299
2307
|
|
|
2300
|
-
# First establish different ratings for players
|
|
2301
|
-
df1 = pl.DataFrame(
|
|
2302
|
-
{
|
|
2303
|
-
"pid": ["P1", "P2", "P3", "P4"],
|
|
2304
|
-
"tid": ["T1", "T1", "T2", "T2"],
|
|
2305
|
-
"mid": ["M1", "M1", "M1", "M1"],
|
|
2306
|
-
"dt": ["2024-01-01"] * 4,
|
|
2307
|
-
"perf": [0.9, 0.1, 0.5, 0.5], # P1 high rating, P2 low rating
|
|
2308
|
-
"pw": [1.0, 1.0, 1.0, 1.0],
|
|
2309
|
-
"team_pt": [None, None, None, None],
|
|
2310
|
-
"opp_pt": [None, None, None, None],
|
|
2311
|
-
}
|
|
2312
|
-
)
|
|
2313
|
-
|
|
2314
2308
|
gen = PlayerRatingGenerator(
|
|
2315
2309
|
performance_column="perf",
|
|
2316
2310
|
column_names=cn,
|
|
2317
|
-
|
|
2311
|
+
use_off_def_split=True,
|
|
2312
|
+
performance_predictor="difference",
|
|
2318
2313
|
start_harcoded_start_rating=1000.0,
|
|
2319
2314
|
non_predictor_features_out=[RatingUnknownFeatures.PLAYER_PREDICTED_OFF_PERFORMANCE],
|
|
2320
2315
|
)
|
|
2321
|
-
gen.fit_transform(df1)
|
|
2322
2316
|
|
|
2323
|
-
#
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
assert p1_rating > p2_rating, "Setup: P1 should have higher rating than P2"
|
|
2317
|
+
# Pre-seed players
|
|
2318
|
+
gen._player_off_ratings["P1"] = PlayerRating(id="P1", rating_value=1000.0, games_played=10)
|
|
2319
|
+
gen._player_def_ratings["P1"] = PlayerRating(id="P1", rating_value=1200.0, games_played=10)
|
|
2327
2320
|
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2321
|
+
gen._player_off_ratings["P2"] = PlayerRating(id="P2", rating_value=1000.0, games_played=10)
|
|
2322
|
+
gen._player_def_ratings["P2"] = PlayerRating(id="P2", rating_value=800.0, games_played=10)
|
|
2323
|
+
|
|
2324
|
+
gen._player_off_ratings["P3"] = PlayerRating(id="P3", rating_value=1000.0, games_played=10)
|
|
2325
|
+
gen._player_def_ratings["P3"] = PlayerRating(id="P3", rating_value=1000.0, games_played=10)
|
|
2326
|
+
|
|
2327
|
+
gen._player_off_ratings["P4"] = PlayerRating(id="P4", rating_value=1000.0, games_played=10)
|
|
2328
|
+
gen._player_def_ratings["P4"] = PlayerRating(id="P4", rating_value=1000.0, games_played=10)
|
|
2329
|
+
|
|
2330
|
+
# Match with playing time data
|
|
2331
|
+
df = pl.DataFrame(
|
|
2332
2332
|
{
|
|
2333
2333
|
"pid": ["P1", "P2", "P3", "P4"],
|
|
2334
2334
|
"tid": ["T1", "T1", "T2", "T2"],
|
|
2335
|
-
"mid": ["
|
|
2336
|
-
"dt": ["2024-01-
|
|
2335
|
+
"mid": ["M1", "M1", "M1", "M1"],
|
|
2336
|
+
"dt": ["2024-01-01"] * 4,
|
|
2337
|
+
"perf": [None, None, None, None],
|
|
2337
2338
|
"pw": [1.0, 1.0, 1.0, 1.0],
|
|
2338
|
-
|
|
2339
|
-
"team_pt": [
|
|
2340
|
-
{"P1": 0.0, "P2": 1.0, "P3": 0.5, "P4": 0.5}, # P1 on T1, plays with P2
|
|
2341
|
-
{"P1": 1.0, "P2": 0.0, "P3": 0.5, "P4": 0.5}, # P2 on T1, plays with P1
|
|
2342
|
-
{"P1": 0.5, "P2": 0.5, "P3": 0.0, "P4": 1.0}, # P3 on T2, plays with P4
|
|
2343
|
-
{"P1": 0.5, "P2": 0.5, "P3": 1.0, "P4": 0.0}, # P4 on T2, plays with P3
|
|
2344
|
-
],
|
|
2345
|
-
# Opponent playing time - who they face on opposing team
|
|
2339
|
+
"team_pt": [None, None, None, None],
|
|
2346
2340
|
"opp_pt": [
|
|
2347
|
-
{"
|
|
2348
|
-
{"
|
|
2349
|
-
{"P1": 0.8, "P2": 0.2
|
|
2350
|
-
{"P1": 0.2, "P2": 0.8
|
|
2341
|
+
{"P3": 0.5, "P4": 0.5},
|
|
2342
|
+
{"P3": 0.5, "P4": 0.5},
|
|
2343
|
+
{"P1": 0.8, "P2": 0.2},
|
|
2344
|
+
{"P1": 0.2, "P2": 0.8},
|
|
2351
2345
|
],
|
|
2352
2346
|
}
|
|
2353
2347
|
)
|
|
2354
2348
|
|
|
2355
|
-
result = gen.future_transform(
|
|
2349
|
+
result = gen.future_transform(df)
|
|
2356
2350
|
|
|
2357
|
-
# Verify we get predictions
|
|
2351
|
+
# Verify we get valid predictions
|
|
2358
2352
|
assert len(result) == 4
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
# So P3 should have lower predicted performance than P4 (all else equal)
|
|
2363
|
-
p3_pred = result.filter(pl.col("pid") == "P3")["player_predicted_off_performance_perf"][0]
|
|
2364
|
-
p4_pred = result.filter(pl.col("pid") == "P4")["player_predicted_off_performance_perf"][0]
|
|
2365
|
-
|
|
2366
|
-
# P3 faces P1 (high rating) 80% of time, P4 faces P2 (low rating) 80% of time
|
|
2367
|
-
# So P4 should have higher predicted performance
|
|
2368
|
-
assert p4_pred > p3_pred, (
|
|
2369
|
-
f"P4 (facing weak opponents) should have higher prediction than P3 (facing strong opponents). "
|
|
2370
|
-
f"P3 pred={p3_pred:.4f}, P4 pred={p4_pred:.4f}"
|
|
2371
|
-
)
|
|
2353
|
+
predictions = result["player_predicted_off_performance_perf"].to_list()
|
|
2354
|
+
for pred in predictions:
|
|
2355
|
+
assert 0.0 <= pred <= 1.0, f"Prediction {pred} out of valid range [0, 1]"
|
|
2372
2356
|
|
|
2373
2357
|
|
|
2374
2358
|
def test_future_transform_weighted_calculation_with_playing_time(base_cn):
|
|
@@ -3076,3 +3060,91 @@ class TestNaNPerformanceHandling:
|
|
|
3076
3060
|
|
|
3077
3061
|
result = gen.fit_transform(df)
|
|
3078
3062
|
assert len(result) == 4
|
|
3063
|
+
|
|
3064
|
+
|
|
3065
|
+
def test_opponent_players_playing_time_uses_def_ratings_for_offense_prediction(base_cn):
|
|
3066
|
+
"""
|
|
3067
|
+
Bug reproduction test: When predicting offensive performance with opponent_players_playing_time,
|
|
3068
|
+
the predictor should use opponent DEF ratings (not OFF ratings) for weighting.
|
|
3069
|
+
|
|
3070
|
+
The bug was that _create_pre_match_players_collection builds PreMatchPlayerRating using
|
|
3071
|
+
only OFF ratings, but when predicting offense vs opponent defense, we need to weight
|
|
3072
|
+
using opponent DEF ratings.
|
|
3073
|
+
|
|
3074
|
+
This test sets up players with divergent OFF and DEF ratings and verifies the correct
|
|
3075
|
+
ratings are used.
|
|
3076
|
+
"""
|
|
3077
|
+
from dataclasses import replace
|
|
3078
|
+
import math
|
|
3079
|
+
|
|
3080
|
+
cn = replace(
|
|
3081
|
+
base_cn,
|
|
3082
|
+
team_players_playing_time="team_pt",
|
|
3083
|
+
opponent_players_playing_time="opp_pt",
|
|
3084
|
+
)
|
|
3085
|
+
|
|
3086
|
+
gen = PlayerRatingGenerator(
|
|
3087
|
+
performance_column="perf",
|
|
3088
|
+
column_names=cn,
|
|
3089
|
+
use_off_def_split=True,
|
|
3090
|
+
performance_predictor="difference",
|
|
3091
|
+
start_harcoded_start_rating=1000.0,
|
|
3092
|
+
non_predictor_features_out=[RatingUnknownFeatures.PLAYER_PREDICTED_OFF_PERFORMANCE],
|
|
3093
|
+
)
|
|
3094
|
+
|
|
3095
|
+
# Pre-seed players with divergent OFF and DEF ratings
|
|
3096
|
+
# P1 on T1: high OFF (1200), low DEF (800)
|
|
3097
|
+
# P2 on T2: low OFF (800), high DEF (1200)
|
|
3098
|
+
gen._player_off_ratings["P1"] = PlayerRating(id="P1", rating_value=1200.0, games_played=10)
|
|
3099
|
+
gen._player_def_ratings["P1"] = PlayerRating(id="P1", rating_value=800.0, games_played=10)
|
|
3100
|
+
|
|
3101
|
+
gen._player_off_ratings["P2"] = PlayerRating(id="P2", rating_value=800.0, games_played=10)
|
|
3102
|
+
gen._player_def_ratings["P2"] = PlayerRating(id="P2", rating_value=1200.0, games_played=10)
|
|
3103
|
+
|
|
3104
|
+
# Create a match where P1 (T1) faces P2 (T2)
|
|
3105
|
+
# P1's offense prediction should be based on P2's DEF rating (1200), not P2's OFF rating (800)
|
|
3106
|
+
df = pl.DataFrame(
|
|
3107
|
+
{
|
|
3108
|
+
"pid": ["P1", "P2"],
|
|
3109
|
+
"tid": ["T1", "T2"],
|
|
3110
|
+
"mid": ["M1", "M1"],
|
|
3111
|
+
"dt": ["2024-01-01"] * 2,
|
|
3112
|
+
"perf": [None, None], # Future prediction, no actual performance
|
|
3113
|
+
"pw": [1.0, 1.0],
|
|
3114
|
+
"team_pt": [None, None],
|
|
3115
|
+
"opp_pt": [
|
|
3116
|
+
{"P2": 1.0}, # P1 faces P2 100% of time
|
|
3117
|
+
{"P1": 1.0}, # P2 faces P1 100% of time
|
|
3118
|
+
],
|
|
3119
|
+
}
|
|
3120
|
+
)
|
|
3121
|
+
|
|
3122
|
+
result = gen.future_transform(df)
|
|
3123
|
+
|
|
3124
|
+
# Get P1's predicted offensive performance
|
|
3125
|
+
p1_pred = result.filter(pl.col("pid") == "P1")["player_predicted_off_performance_perf"][0]
|
|
3126
|
+
|
|
3127
|
+
# Calculate what the prediction SHOULD be:
|
|
3128
|
+
# P1 OFF rating = 1200
|
|
3129
|
+
# P2 DEF rating = 1200 (this SHOULD be used, not P2 OFF rating = 800)
|
|
3130
|
+
# rating_difference = 1200 - 1200 = 0
|
|
3131
|
+
# prediction = sigmoid(0.005757 * 0) = 0.5
|
|
3132
|
+
|
|
3133
|
+
expected_rating_diff_with_def = 1200 - 1200 # = 0
|
|
3134
|
+
expected_pred_with_def = 1 / (1 + math.exp(-0.005757 * expected_rating_diff_with_def))
|
|
3135
|
+
|
|
3136
|
+
# If the bug exists, it would use P2 OFF rating (800):
|
|
3137
|
+
# rating_difference = 1200 - 800 = 400
|
|
3138
|
+
# prediction = sigmoid(0.005757 * 400) ≈ 0.909
|
|
3139
|
+
buggy_rating_diff_with_off = 1200 - 800 # = 400
|
|
3140
|
+
buggy_pred_with_off = 1 / (1 + math.exp(-0.005757 * buggy_rating_diff_with_off))
|
|
3141
|
+
|
|
3142
|
+
# The prediction should be close to 0.5 (using DEF), not ~0.909 (using OFF)
|
|
3143
|
+
assert abs(p1_pred - expected_pred_with_def) < 0.01, (
|
|
3144
|
+
f"P1's offensive performance prediction should use opponent DEF ratings. "
|
|
3145
|
+
f"Expected ~{expected_pred_with_def:.4f} (using P2 DEF=1200), "
|
|
3146
|
+
f"got {p1_pred:.4f}. "
|
|
3147
|
+
f"If using P2 OFF=800, prediction would be ~{buggy_pred_with_off:.4f}"
|
|
3148
|
+
)
|
|
3149
|
+
|
|
3150
|
+
|
tests/scorer/test_score.py
CHANGED
|
@@ -66,7 +66,7 @@ def test_apply_filters_greater_than(df_type):
|
|
|
66
66
|
filters = [Filter(column_name="col1", value=2, operator=Operator.GREATER_THAN)]
|
|
67
67
|
result = apply_filters(df, filters)
|
|
68
68
|
assert len(result) == 2
|
|
69
|
-
assert
|
|
69
|
+
assert (result["col1"] > 2).all()
|
|
70
70
|
|
|
71
71
|
|
|
72
72
|
@pytest.mark.parametrize("df_type", [pl.DataFrame, pd.DataFrame])
|
|
@@ -76,7 +76,7 @@ def test_apply_filters_less_than(df_type):
|
|
|
76
76
|
filters = [Filter(column_name="col1", value=3, operator=Operator.LESS_THAN)]
|
|
77
77
|
result = apply_filters(df, filters)
|
|
78
78
|
assert len(result) == 2
|
|
79
|
-
assert
|
|
79
|
+
assert (result["col1"] < 3).all()
|
|
80
80
|
|
|
81
81
|
|
|
82
82
|
@pytest.mark.parametrize("df_type", [pl.DataFrame, pd.DataFrame])
|
|
@@ -86,7 +86,7 @@ def test_apply_filters_greater_than_or_equals(df_type):
|
|
|
86
86
|
filters = [Filter(column_name="col1", value=2, operator=Operator.GREATER_THAN_OR_EQUALS)]
|
|
87
87
|
result = apply_filters(df, filters)
|
|
88
88
|
assert len(result) == 3
|
|
89
|
-
assert
|
|
89
|
+
assert (result["col1"] >= 2).all()
|
|
90
90
|
|
|
91
91
|
|
|
92
92
|
@pytest.mark.parametrize("df_type", [pl.DataFrame, pd.DataFrame])
|
|
@@ -96,7 +96,7 @@ def test_apply_filters_less_than_or_equals(df_type):
|
|
|
96
96
|
filters = [Filter(column_name="col1", value=3, operator=Operator.LESS_THAN_OR_EQUALS)]
|
|
97
97
|
result = apply_filters(df, filters)
|
|
98
98
|
assert len(result) == 3
|
|
99
|
-
assert
|
|
99
|
+
assert (result["col1"] <= 3).all()
|
|
100
100
|
|
|
101
101
|
|
|
102
102
|
@pytest.mark.parametrize("df_type", [pl.DataFrame, pd.DataFrame])
|
|
@@ -129,8 +129,8 @@ def test_apply_filters_multiple_filters(df_type):
|
|
|
129
129
|
]
|
|
130
130
|
result = apply_filters(df, filters)
|
|
131
131
|
assert len(result) == 2
|
|
132
|
-
assert
|
|
133
|
-
assert
|
|
132
|
+
assert (result["col1"] > 2).all()
|
|
133
|
+
assert (result["col2"] == "A").all()
|
|
134
134
|
|
|
135
135
|
|
|
136
136
|
@pytest.mark.parametrize("df_type", [pl.DataFrame, pd.DataFrame])
|
tests/test_autopipeline.py
CHANGED
|
@@ -809,7 +809,7 @@ def test_granularity_aggregation_weight__weighted_mean_correct(frame):
|
|
|
809
809
|
transformed = reducer.fit_transform(df)
|
|
810
810
|
|
|
811
811
|
if frame == "pl":
|
|
812
|
-
num1_val = transformed["num1"].
|
|
812
|
+
num1_val = transformed["num1"].item(0)
|
|
813
813
|
else:
|
|
814
814
|
num1_val = transformed["num1"].iloc[0]
|
|
815
815
|
|
|
@@ -875,7 +875,7 @@ def test_aggregation_weight_sums_weight_column(frame):
|
|
|
875
875
|
transformed = reducer.fit_transform(df)
|
|
876
876
|
|
|
877
877
|
if frame == "pl":
|
|
878
|
-
weight_val = transformed["weight"].
|
|
878
|
+
weight_val = transformed["weight"].item(0)
|
|
879
879
|
else:
|
|
880
880
|
weight_val = transformed["weight"].iloc[0]
|
|
881
881
|
|
|
@@ -163,8 +163,7 @@ def test_predict_row_false_uses_existing_row_prediction_column(df_factory):
|
|
|
163
163
|
|
|
164
164
|
assert list(out.columns) == ["ratio", "row_pred"]
|
|
165
165
|
ratio = out["ratio"] if isinstance(out, pd.DataFrame) else out.get_column("ratio")
|
|
166
|
-
|
|
167
|
-
assert all(v == 1.0 for v in ratio_values)
|
|
166
|
+
assert (ratio == 1.0).all()
|
|
168
167
|
|
|
169
168
|
|
|
170
169
|
@pytest.mark.parametrize("df_factory", [pd.DataFrame, pl.DataFrame])
|
|
File without changes
|
|
File without changes
|
|
File without changes
|