spforge 0.8.7__py3-none-any.whl → 0.8.9__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/features_generator_pipeline.py +8 -4
- spforge/performance_transformers/_performance_manager.py +2 -4
- {spforge-0.8.7.dist-info → spforge-0.8.9.dist-info}/METADATA +1 -1
- {spforge-0.8.7.dist-info → spforge-0.8.9.dist-info}/RECORD +9 -9
- tests/performance_transformers/test_performance_manager.py +15 -0
- tests/test_feature_generator_pipeline.py +43 -0
- {spforge-0.8.7.dist-info → spforge-0.8.9.dist-info}/WHEEL +0 -0
- {spforge-0.8.7.dist-info → spforge-0.8.9.dist-info}/licenses/LICENSE +0 -0
- {spforge-0.8.7.dist-info → spforge-0.8.9.dist-info}/top_level.txt +0 -0
|
@@ -120,7 +120,8 @@ class FeatureGeneratorPipeline(FeatureGenerator):
|
|
|
120
120
|
|
|
121
121
|
for transformer in self.feature_generators:
|
|
122
122
|
pre_row_count = len(df)
|
|
123
|
-
|
|
123
|
+
native_df = df.to_native()
|
|
124
|
+
df = nw.from_native(transformer.fit_transform(native_df, column_names=column_names))
|
|
124
125
|
assert len(df) == pre_row_count
|
|
125
126
|
for f in transformer.features_out:
|
|
126
127
|
if f in expected_feats_added:
|
|
@@ -151,7 +152,8 @@ class FeatureGeneratorPipeline(FeatureGenerator):
|
|
|
151
152
|
|
|
152
153
|
for transformer in self.feature_generators:
|
|
153
154
|
pre_row_count = len(df)
|
|
154
|
-
|
|
155
|
+
native_df = df.to_native()
|
|
156
|
+
df = nw.from_native(transformer.transform(native_df))
|
|
155
157
|
assert len(df) == pre_row_count
|
|
156
158
|
for f in transformer.features_out:
|
|
157
159
|
if f in expected_feats_added:
|
|
@@ -181,9 +183,11 @@ class FeatureGeneratorPipeline(FeatureGenerator):
|
|
|
181
183
|
for transformer in self.feature_generators:
|
|
182
184
|
pre_row_count = len(df)
|
|
183
185
|
if hasattr(transformer, "future_transform") and callable(transformer.future_transform):
|
|
184
|
-
|
|
186
|
+
native_df = df.to_native()
|
|
187
|
+
df = nw.from_native(transformer.future_transform(native_df))
|
|
185
188
|
else:
|
|
186
|
-
|
|
189
|
+
native_df = df.to_native()
|
|
190
|
+
df = nw.from_native(transformer.transform(native_df))
|
|
187
191
|
assert len(df) == pre_row_count
|
|
188
192
|
for f in transformer.features_out:
|
|
189
193
|
if f in expected_feats_added:
|
|
@@ -250,8 +250,6 @@ class PerformanceWeightsManager(PerformanceManager):
|
|
|
250
250
|
)
|
|
251
251
|
)
|
|
252
252
|
|
|
253
|
-
sum_weight = sum([w.weight for w in self.weights])
|
|
254
|
-
|
|
255
253
|
for column_weight in self.weights:
|
|
256
254
|
weight_col = f"weight__{column_weight.name}"
|
|
257
255
|
feature_col = column_weight.name
|
|
@@ -261,14 +259,14 @@ class PerformanceWeightsManager(PerformanceManager):
|
|
|
261
259
|
df = df.with_columns(
|
|
262
260
|
(
|
|
263
261
|
nw.col(tmp_out_performance_colum_name)
|
|
264
|
-
+ (nw.col(weight_col)
|
|
262
|
+
+ (nw.col(weight_col) * (1 - nw.col(feature_name)))
|
|
265
263
|
).alias(tmp_out_performance_colum_name)
|
|
266
264
|
)
|
|
267
265
|
else:
|
|
268
266
|
df = df.with_columns(
|
|
269
267
|
(
|
|
270
268
|
nw.col(tmp_out_performance_colum_name)
|
|
271
|
-
+ (nw.col(weight_col)
|
|
269
|
+
+ (nw.col(weight_col) * nw.col(feature_name))
|
|
272
270
|
).alias(tmp_out_performance_colum_name)
|
|
273
271
|
)
|
|
274
272
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: spforge
|
|
3
|
-
Version: 0.8.
|
|
3
|
+
Version: 0.8.9
|
|
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
|
|
@@ -17,7 +17,7 @@ spforge/__init__.py,sha256=8vZhy7XUpzqWkVKpXqwqOLDkQlNytRhyf4qjwObfXgU,468
|
|
|
17
17
|
spforge/autopipeline.py,sha256=ZUwv6Q6O8cD0u5TiSqG6lhW0j16RlSb160AzuOeL2R8,23186
|
|
18
18
|
spforge/base_feature_generator.py,sha256=RbD00N6oLCQQcEb_VF5wbwZztl-X8k9B0Wlaj9Os1iU,668
|
|
19
19
|
spforge/data_structures.py,sha256=k82v5r79vl0_FAVvsxVF9Nbzb5FoHqVrlHZlEXGc5gQ,7298
|
|
20
|
-
spforge/features_generator_pipeline.py,sha256=
|
|
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
|
|
23
23
|
spforge/cross_validator/_base.py,sha256=-zxZ2Q2tYlGIwjQQMf9_OglS_doppp47gVElkJuBY7E,1199
|
|
@@ -47,7 +47,7 @@ spforge/hyperparameter_tuning/__init__.py,sha256=N2sKG4SvG41hlsFT2kx_DQYMmXsQr-8
|
|
|
47
47
|
spforge/hyperparameter_tuning/_default_search_spaces.py,sha256=Sm5IrHAW0-vRC8jqCPX0pDi_C-W3L_MoEKGA8bx1Zbc,7546
|
|
48
48
|
spforge/hyperparameter_tuning/_tuner.py,sha256=uovhGqhe8-fdhi79aErUmE2h5NCycFQEIRv5WCjpC7E,16732
|
|
49
49
|
spforge/performance_transformers/__init__.py,sha256=U6d7_kltbUMLYCGBk4QAFVPJTxXD3etD9qUftV-O3q4,422
|
|
50
|
-
spforge/performance_transformers/_performance_manager.py,sha256=
|
|
50
|
+
spforge/performance_transformers/_performance_manager.py,sha256=WmjmlMEnq7y75MiI_s9Y-9eMXIyhPTUKrwsXRtgYp0k,9620
|
|
51
51
|
spforge/performance_transformers/_performances_transformers.py,sha256=0lxuWjAfWBRXRgQsNJHjw3P-nlTtHBu4_bOVdoy7hq4,15536
|
|
52
52
|
spforge/ratings/__init__.py,sha256=OZVH2Lo6END3n1X8qi4QcyAPlThIwAYwVKCiIuOQSQU,576
|
|
53
53
|
spforge/ratings/_base.py,sha256=dRMkIGj5-2zKddygaEA4g16WCyXon7v8Xa1ymm7IuoM,14335
|
|
@@ -71,10 +71,10 @@ spforge/transformers/_other_transformer.py,sha256=xLfaFIhkFsigAoitB4x3F8An2j9ymd
|
|
|
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.
|
|
74
|
+
spforge-0.8.9.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
75
75
|
tests/test_autopipeline.py,sha256=WXHeqBdjQD6xaXVkzvS8ocz0WVP9R7lN0PiHJ2iD8nA,16911
|
|
76
76
|
tests/test_autopipeline_context.py,sha256=IuRUY4IA6uMObvbl2pXSaXO2_tl3qX6wEbTZY0dkTMI,1240
|
|
77
|
-
tests/test_feature_generator_pipeline.py,sha256=
|
|
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
|
|
79
79
|
tests/distributions/test_distribution.py,sha256=aU8hfCgliM80TES4WGjs9KFXpV8XghBGF7Hu9sqEVSE,10982
|
|
80
80
|
tests/end_to_end/test_estimator_hyperparameter_tuning.py,sha256=fZCJ9rrED2vT68B9ovmVA1cIG2pHRTjy9xzZLxxpEBo,2513
|
|
@@ -92,7 +92,7 @@ tests/feature_generator/test_rolling_mean_days.py,sha256=EyOvdJDnmgPfe13uQBOkwo7
|
|
|
92
92
|
tests/feature_generator/test_rolling_window.py,sha256=YBJo36OK3ILYeXrH06ylXqviUcCaGYaVQaK5RJzwM7Y,23239
|
|
93
93
|
tests/hyperparameter_tuning/test_estimator_tuner.py,sha256=iewME41d6LR2aQ0OtohGFtN_ocJUwTeqvs6L0QDmfG4,4413
|
|
94
94
|
tests/hyperparameter_tuning/test_rating_tuner.py,sha256=PyCFP3KPc4Iy9E_X9stCVxra14uMgC1tuRwuQ30rO_o,13195
|
|
95
|
-
tests/performance_transformers/test_performance_manager.py,sha256=
|
|
95
|
+
tests/performance_transformers/test_performance_manager.py,sha256=gjuuV_hb27kCo_kUecPKG3Cbot2Gqis1W3kw2A4ovS4,10690
|
|
96
96
|
tests/performance_transformers/test_performances_transformers.py,sha256=A-tGiCx7kXrj1cVj03Bc7prOeZ1_Ryz8YFx9uj3eK6w,11064
|
|
97
97
|
tests/ratings/test_player_rating_generator.py,sha256=FGH3Tq0uFoSlkS_XMldsUKhsovBRBvzH9EbqjKvg2O0,59601
|
|
98
98
|
tests/ratings/test_ratings_property.py,sha256=ckyfGILXa4tfQvsgyXEzBDNr2DUmHwFRV13N60w66iE,6561
|
|
@@ -105,7 +105,7 @@ tests/transformers/test_other_transformer.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRk
|
|
|
105
105
|
tests/transformers/test_predictor_transformer.py,sha256=N1aBYLjN3ldpYZLwjih_gTFYSMitrZu-PNK78W6RHaQ,6877
|
|
106
106
|
tests/transformers/test_simple_transformer.py,sha256=wWR0qjLb_uS4HXrJgGdiqugOY1X7kwd1_OPS02IT2b8,4676
|
|
107
107
|
tests/transformers/test_team_ratio_predictor.py,sha256=fOUP_JvNJi-3kom3ZOs1EdG0I6Z8hpLpYKNHu1eWtOw,8562
|
|
108
|
-
spforge-0.8.
|
|
109
|
-
spforge-0.8.
|
|
110
|
-
spforge-0.8.
|
|
111
|
-
spforge-0.8.
|
|
108
|
+
spforge-0.8.9.dist-info/METADATA,sha256=-HC4cuWjOzbV-SHZiopaJQ_WJv9Q2K_QNjjLj5gHohg,20047
|
|
109
|
+
spforge-0.8.9.dist-info/WHEEL,sha256=qELbo2s1Yzl39ZmrAibXA2jjPLUYfnVhUNTlyF1rq0Y,92
|
|
110
|
+
spforge-0.8.9.dist-info/top_level.txt,sha256=6UW2M5a7WKOeaAi900qQmRKNj5-HZzE8-eUD9Y9LTq0,23
|
|
111
|
+
spforge-0.8.9.dist-info/RECORD,,
|
|
@@ -56,6 +56,21 @@ def test_performance_weights_manager_basic_flow(sample_data):
|
|
|
56
56
|
assert output_df["weighted_performance"].iloc[0] == pytest.approx(0.6)
|
|
57
57
|
|
|
58
58
|
|
|
59
|
+
def test_performance_weights_manager_keeps_mean_when_weights_not_normalized():
|
|
60
|
+
df = pd.DataFrame(
|
|
61
|
+
{
|
|
62
|
+
"feat_a": [0.0, 1.0, 2.0, 3.0],
|
|
63
|
+
"feat_b": [3.0, 2.0, 1.0, 0.0],
|
|
64
|
+
}
|
|
65
|
+
)
|
|
66
|
+
weights = [ColumnWeight(name="feat_a", weight=0.9), ColumnWeight(name="feat_b", weight=0.5)]
|
|
67
|
+
|
|
68
|
+
manager = PerformanceWeightsManager(weights=weights, transformer_names=["min_max"], prefix="")
|
|
69
|
+
output_df = nw.from_native(manager.fit_transform(df)).to_pandas()
|
|
70
|
+
|
|
71
|
+
assert output_df["weighted_performance"].mean() == pytest.approx(0.5, abs=1e-6)
|
|
72
|
+
|
|
73
|
+
|
|
59
74
|
def test_lower_is_better_logic():
|
|
60
75
|
df = pd.DataFrame({"feat_a": [1.0, 0.0]})
|
|
61
76
|
weights = [ColumnWeight(name="feat_a", weight=1.0, lower_is_better=True)]
|
|
@@ -16,6 +16,49 @@ def column_names():
|
|
|
16
16
|
)
|
|
17
17
|
|
|
18
18
|
|
|
19
|
+
class PolarsOnlyGenerator:
|
|
20
|
+
def __init__(self):
|
|
21
|
+
self._features_out = ["polars_only_feature"]
|
|
22
|
+
|
|
23
|
+
@property
|
|
24
|
+
def features_out(self):
|
|
25
|
+
return self._features_out
|
|
26
|
+
|
|
27
|
+
def fit_transform(self, df, column_names=None):
|
|
28
|
+
if not isinstance(df, pl.DataFrame):
|
|
29
|
+
raise TypeError("Expected polars DataFrame")
|
|
30
|
+
return df.with_columns((pl.col("points") * 2).alias("polars_only_feature"))
|
|
31
|
+
|
|
32
|
+
def transform(self, df):
|
|
33
|
+
if not isinstance(df, pl.DataFrame):
|
|
34
|
+
raise TypeError("Expected polars DataFrame")
|
|
35
|
+
return df.with_columns((pl.col("points") * 2).alias("polars_only_feature"))
|
|
36
|
+
|
|
37
|
+
def future_transform(self, df):
|
|
38
|
+
return self.transform(df)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def test_feature_generator_pipeline__passes_native_polars_to_custom_generator(column_names):
|
|
42
|
+
data = pl.DataFrame(
|
|
43
|
+
{
|
|
44
|
+
"game_id": [1, 1],
|
|
45
|
+
"team_id": ["A", "B"],
|
|
46
|
+
"player_id": ["p1", "p2"],
|
|
47
|
+
"date": pd.to_datetime(["2023-01-01", "2023-01-01"]),
|
|
48
|
+
"points": [10, 15],
|
|
49
|
+
}
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
pipeline = FeatureGeneratorPipeline(
|
|
53
|
+
feature_generators=[PolarsOnlyGenerator()],
|
|
54
|
+
column_names=column_names,
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
result = pipeline.fit_transform(data, column_names=column_names)
|
|
58
|
+
|
|
59
|
+
assert "polars_only_feature" in result.columns
|
|
60
|
+
|
|
61
|
+
|
|
19
62
|
@pytest.mark.parametrize("df_type", [pd.DataFrame, pl.DataFrame])
|
|
20
63
|
def test_feature_generator_pipeline__fit_transform_preserves_row_count(df_type, column_names):
|
|
21
64
|
"""FeatureGeneratorPipeline.fit_transform should preserve row count."""
|
|
File without changes
|
|
File without changes
|
|
File without changes
|