22"""
33Tests for learn_weights module.
44"""
5- import json
65import numpy as np
76import geopandas as gpd
87import pytest
@@ -54,11 +53,9 @@ class TestPrepareData:
5453
5554 def test_basic_splits (self , synthetic_grid , synthetic_labels ):
5655 """Test that data splits are created with correct sizes."""
57- attributes = ["feature_a_score" , "feature_b_score" , "feature_c_score" ]
5856 splits = prepare_pu_data (
5957 grid_df = synthetic_grid ,
6058 labels_gdf = synthetic_labels ,
61- attributes = attributes ,
6259 background_samples = 50 ,
6360 test_size = 0.2 ,
6461 validation_size = 0.1 ,
@@ -77,11 +74,9 @@ def test_basic_splits(self, synthetic_grid, synthetic_labels):
7774
7875 def test_background_size_capped (self , synthetic_grid , synthetic_labels ):
7976 """Test that background sampling respects available cells."""
80- attributes = ["feature_a_score" , "feature_b_score" , "feature_c_score" ]
8177 splits = prepare_pu_data (
8278 grid_df = synthetic_grid ,
8379 labels_gdf = synthetic_labels ,
84- attributes = attributes ,
8580 background_samples = 1000 , # More than available
8681 random_state = 42 ,
8782 )
@@ -98,7 +93,6 @@ def test_train_produces_importances(self, synthetic_grid, synthetic_labels):
9893 splits = prepare_pu_data (
9994 grid_df = synthetic_grid ,
10095 labels_gdf = synthetic_labels ,
101- attributes = attributes ,
10296 background_samples = 50 ,
10397 random_state = 42 ,
10498 )
@@ -115,6 +109,65 @@ def test_train_produces_importances(self, synthetic_grid, synthetic_labels):
115109 assert len (results ["feature_importances" ]) == 3
116110 assert results ["model" ] is not None
117111
112+ def test_empty_positives_raises (self , synthetic_grid ):
113+ """Test that empty positive training set raises ValueError."""
114+ attributes = ["feature_a_score" , "feature_b_score" , "feature_c_score" ]
115+ splits = {
116+ "train_gids" : np .array ([]),
117+ "validation_gids" : np .array ([]),
118+ "test_gids" : np .array ([]),
119+ "background_gids" : np .array ([0 , 1 , 2 , 3 , 4 ]),
120+ "background_test_gids" : np .array ([]),
121+ "background_val_gids" : np .array ([]),
122+ }
123+ with pytest .raises (ValueError , match = "No positive training samples" ):
124+ train_pu_model (
125+ grid_df = synthetic_grid ,
126+ data_splits = splits ,
127+ attributes = attributes ,
128+ n_estimators = 10 ,
129+ random_state = 42 ,
130+ )
131+
132+ def test_empty_background_raises (self , synthetic_grid ):
133+ """Test that empty background training set raises ValueError."""
134+ attributes = ["feature_a_score" , "feature_b_score" , "feature_c_score" ]
135+ splits = {
136+ "train_gids" : np .array ([0 , 1 , 2 , 3 , 4 ]),
137+ "validation_gids" : np .array ([]),
138+ "test_gids" : np .array ([]),
139+ "background_gids" : np .array ([]),
140+ "background_test_gids" : np .array ([]),
141+ "background_val_gids" : np .array ([]),
142+ }
143+ with pytest .raises (ValueError , match = "No background" ):
144+ train_pu_model (
145+ grid_df = synthetic_grid ,
146+ data_splits = splits ,
147+ attributes = attributes ,
148+ n_estimators = 10 ,
149+ random_state = 42 ,
150+ )
151+
152+ def test_invalid_class_prior_raises (self , synthetic_grid , synthetic_labels ):
153+ """Test that class_prior outside (0,1) raises ValueError."""
154+ attributes = ["feature_a_score" , "feature_b_score" , "feature_c_score" ]
155+ splits = prepare_pu_data (
156+ grid_df = synthetic_grid ,
157+ labels_gdf = synthetic_labels ,
158+ background_samples = 50 ,
159+ random_state = 42 ,
160+ )
161+ with pytest .raises (ValueError , match = "class_prior must be between" ):
162+ train_pu_model (
163+ grid_df = synthetic_grid ,
164+ data_splits = splits ,
165+ attributes = attributes ,
166+ n_estimators = 10 ,
167+ class_prior = 1.0 ,
168+ random_state = 42 ,
169+ )
170+
118171
119172class TestImportancesToWeights :
120173 """Tests for importances_to_weights."""
@@ -195,7 +248,6 @@ def test_full_pipeline(self, synthetic_grid, synthetic_labels):
195248 splits = prepare_pu_data (
196249 grid_df = synthetic_grid ,
197250 labels_gdf = synthetic_labels ,
198- attributes = attributes ,
199251 background_samples = 50 ,
200252 random_state = 42 ,
201253 )
@@ -235,7 +287,6 @@ def test_returns_best_prior(self, synthetic_grid, synthetic_labels):
235287 splits = prepare_pu_data (
236288 grid_df = synthetic_grid ,
237289 labels_gdf = synthetic_labels ,
238- attributes = attributes ,
239290 background_samples = 50 ,
240291 random_state = 42 ,
241292 )
@@ -262,7 +313,6 @@ def test_tpr_metric(self, synthetic_grid, synthetic_labels):
262313 splits = prepare_pu_data (
263314 grid_df = synthetic_grid ,
264315 labels_gdf = synthetic_labels ,
265- attributes = attributes ,
266316 background_samples = 50 ,
267317 random_state = 42 ,
268318 )
@@ -286,7 +336,6 @@ def test_tuned_prior_used_in_training(self, synthetic_grid, synthetic_labels):
286336 splits = prepare_pu_data (
287337 grid_df = synthetic_grid ,
288338 labels_gdf = synthetic_labels ,
289- attributes = attributes ,
290339 background_samples = 50 ,
291340 random_state = 42 ,
292341 )
0 commit comments