aplr 10.12.1__cp312-cp312-win32.whl → 10.14.0__cp312-cp312-win32.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 aplr might be problematic. Click here for more details.
- aplr/aplr.py +139 -1
- {aplr-10.12.1.dist-info → aplr-10.14.0.dist-info}/METADATA +10 -1
- aplr-10.14.0.dist-info/RECORD +8 -0
- aplr_cpp.cp312-win32.pyd +0 -0
- aplr-10.12.1.dist-info/RECORD +0 -8
- {aplr-10.12.1.dist-info → aplr-10.14.0.dist-info}/WHEEL +0 -0
- {aplr-10.12.1.dist-info → aplr-10.14.0.dist-info}/licenses/LICENSE +0 -0
- {aplr-10.12.1.dist-info → aplr-10.14.0.dist-info}/top_level.txt +0 -0
aplr/aplr.py
CHANGED
|
@@ -315,6 +315,115 @@ class APLRRegressor:
|
|
|
315
315
|
def set_intercept(self, value: float):
|
|
316
316
|
self.APLRRegressor.set_intercept(value)
|
|
317
317
|
|
|
318
|
+
def plot_affiliation_shape(
|
|
319
|
+
self,
|
|
320
|
+
affiliation: str,
|
|
321
|
+
plot: bool = True,
|
|
322
|
+
save: bool = False,
|
|
323
|
+
path: str = "",
|
|
324
|
+
):
|
|
325
|
+
"""
|
|
326
|
+
Plots or saves the shape of a given unique term affiliation.
|
|
327
|
+
|
|
328
|
+
For main effects, it produces a line plot. For two-way interactions, it produces a heatmap.
|
|
329
|
+
Plotting for higher-order interactions is not supported.
|
|
330
|
+
|
|
331
|
+
:param affiliation: A string specifying which unique_term_affiliation to use.
|
|
332
|
+
:param plot: If True, displays the plot.
|
|
333
|
+
:param save: If True, saves the plot to a file.
|
|
334
|
+
:param path: The file path to save the plot. If empty and save is True, a default path will be used.
|
|
335
|
+
"""
|
|
336
|
+
try:
|
|
337
|
+
import matplotlib.pyplot as plt
|
|
338
|
+
except ImportError:
|
|
339
|
+
raise ImportError("matplotlib is required for plotting. Please install it.")
|
|
340
|
+
|
|
341
|
+
all_affiliations = self.get_unique_term_affiliations()
|
|
342
|
+
if affiliation not in all_affiliations:
|
|
343
|
+
raise ValueError(
|
|
344
|
+
f"Affiliation '{affiliation}' not found in model. "
|
|
345
|
+
f"Available affiliations are: {all_affiliations}"
|
|
346
|
+
)
|
|
347
|
+
|
|
348
|
+
affiliation_index = all_affiliations.index(affiliation)
|
|
349
|
+
|
|
350
|
+
predictors_in_each_affiliation = (
|
|
351
|
+
self.get_base_predictors_in_each_unique_term_affiliation()
|
|
352
|
+
)
|
|
353
|
+
predictor_indexes_used = predictors_in_each_affiliation[affiliation_index]
|
|
354
|
+
|
|
355
|
+
shape = self.get_unique_term_affiliation_shape(affiliation)
|
|
356
|
+
if shape.shape[0] == 0:
|
|
357
|
+
print(f"No shape data available for affiliation '{affiliation}'.")
|
|
358
|
+
return
|
|
359
|
+
|
|
360
|
+
predictor_names = affiliation.split(" & ")
|
|
361
|
+
|
|
362
|
+
is_main_effect: bool = len(predictor_indexes_used) == 1
|
|
363
|
+
is_two_way_interaction: bool = len(predictor_indexes_used) == 2
|
|
364
|
+
|
|
365
|
+
if is_main_effect:
|
|
366
|
+
fig = plt.figure()
|
|
367
|
+
# Sort by predictor value for a clean line plot
|
|
368
|
+
sorted_indices = np.argsort(shape[:, 0])
|
|
369
|
+
plt.plot(shape[sorted_indices, 0], shape[sorted_indices, 1])
|
|
370
|
+
plt.xlabel(predictor_names[0])
|
|
371
|
+
plt.ylabel("Contribution to linear predictor")
|
|
372
|
+
plt.title(f"Main effect of {predictor_names[0]}")
|
|
373
|
+
plt.grid(True)
|
|
374
|
+
elif is_two_way_interaction:
|
|
375
|
+
fig = plt.figure(figsize=(8, 6))
|
|
376
|
+
|
|
377
|
+
# Get unique coordinates and their inverse mapping
|
|
378
|
+
y_unique, y_inv = np.unique(shape[:, 0], return_inverse=True)
|
|
379
|
+
x_unique, x_inv = np.unique(shape[:, 1], return_inverse=True)
|
|
380
|
+
|
|
381
|
+
# Create grid for sums and counts
|
|
382
|
+
grid_sums = np.zeros((len(y_unique), len(x_unique)))
|
|
383
|
+
grid_counts = np.zeros((len(y_unique), len(x_unique)))
|
|
384
|
+
|
|
385
|
+
# Populate sums and counts to later calculate the mean
|
|
386
|
+
np.add.at(grid_sums, (y_inv, x_inv), shape[:, 2])
|
|
387
|
+
np.add.at(grid_counts, (y_inv, x_inv), 1)
|
|
388
|
+
|
|
389
|
+
# Calculate mean, avoiding division by zero
|
|
390
|
+
with np.errstate(divide="ignore", invalid="ignore"):
|
|
391
|
+
pivot_table_values = np.true_divide(grid_sums, grid_counts)
|
|
392
|
+
# Where there's no data, pivot_table_values will be nan, which is fine for imshow.
|
|
393
|
+
|
|
394
|
+
plt.imshow(
|
|
395
|
+
pivot_table_values,
|
|
396
|
+
aspect="auto",
|
|
397
|
+
origin="lower",
|
|
398
|
+
extent=[
|
|
399
|
+
x_unique.min(),
|
|
400
|
+
x_unique.max(),
|
|
401
|
+
y_unique.min(),
|
|
402
|
+
y_unique.max(),
|
|
403
|
+
],
|
|
404
|
+
cmap="Blues_r",
|
|
405
|
+
)
|
|
406
|
+
plt.colorbar(label="Contribution to the linear predictor")
|
|
407
|
+
plt.xlabel(predictor_names[1])
|
|
408
|
+
plt.ylabel(predictor_names[0])
|
|
409
|
+
plt.title(
|
|
410
|
+
f"Interaction between {predictor_names[0]} and {predictor_names[1]}"
|
|
411
|
+
)
|
|
412
|
+
else:
|
|
413
|
+
print(
|
|
414
|
+
f"Plotting for interaction level > 2 is not supported. Affiliation: {affiliation}"
|
|
415
|
+
)
|
|
416
|
+
return
|
|
417
|
+
|
|
418
|
+
if save:
|
|
419
|
+
save_path = path or f"shape_of_{affiliation.replace(' & ', '_')}.png"
|
|
420
|
+
plt.savefig(save_path)
|
|
421
|
+
|
|
422
|
+
if plot:
|
|
423
|
+
plt.show()
|
|
424
|
+
|
|
425
|
+
plt.close(fig)
|
|
426
|
+
|
|
318
427
|
def remove_provided_custom_functions(self):
|
|
319
428
|
self.APLRRegressor.remove_provided_custom_functions()
|
|
320
429
|
self.calculate_custom_validation_error_function = None
|
|
@@ -504,7 +613,36 @@ class APLRClassifier:
|
|
|
504
613
|
return self.APLRClassifier.get_categories()
|
|
505
614
|
|
|
506
615
|
def get_logit_model(self, category: str) -> APLRRegressor:
|
|
507
|
-
|
|
616
|
+
logit_model_cpp = self.APLRClassifier.get_logit_model(category)
|
|
617
|
+
|
|
618
|
+
logit_model_py = APLRRegressor(
|
|
619
|
+
m=self.m,
|
|
620
|
+
v=self.v,
|
|
621
|
+
random_state=self.random_state,
|
|
622
|
+
loss_function="binomial",
|
|
623
|
+
link_function="logit",
|
|
624
|
+
n_jobs=self.n_jobs,
|
|
625
|
+
cv_folds=self.cv_folds,
|
|
626
|
+
bins=self.bins,
|
|
627
|
+
max_interaction_level=self.max_interaction_level,
|
|
628
|
+
max_interactions=self.max_interactions,
|
|
629
|
+
min_observations_in_split=self.min_observations_in_split,
|
|
630
|
+
ineligible_boosting_steps_added=self.ineligible_boosting_steps_added,
|
|
631
|
+
max_eligible_terms=self.max_eligible_terms,
|
|
632
|
+
verbosity=self.verbosity,
|
|
633
|
+
boosting_steps_before_interactions_are_allowed=self.boosting_steps_before_interactions_are_allowed,
|
|
634
|
+
monotonic_constraints_ignore_interactions=self.monotonic_constraints_ignore_interactions,
|
|
635
|
+
early_stopping_rounds=self.early_stopping_rounds,
|
|
636
|
+
num_first_steps_with_linear_effects_only=self.num_first_steps_with_linear_effects_only,
|
|
637
|
+
penalty_for_non_linearity=self.penalty_for_non_linearity,
|
|
638
|
+
penalty_for_interactions=self.penalty_for_interactions,
|
|
639
|
+
max_terms=self.max_terms,
|
|
640
|
+
ridge_penalty=self.ridge_penalty,
|
|
641
|
+
)
|
|
642
|
+
|
|
643
|
+
logit_model_py.APLRRegressor = logit_model_cpp
|
|
644
|
+
|
|
645
|
+
return logit_model_py
|
|
508
646
|
|
|
509
647
|
def get_validation_error_steps(self) -> FloatMatrix:
|
|
510
648
|
return self.APLRClassifier.get_validation_error_steps()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: aplr
|
|
3
|
-
Version: 10.
|
|
3
|
+
Version: 10.14.0
|
|
4
4
|
Summary: Automatic Piecewise Linear Regression
|
|
5
5
|
Home-page: https://github.com/ottenbreit-data-science/aplr
|
|
6
6
|
Author: Mathias von Ottenbreit
|
|
@@ -14,6 +14,8 @@ Requires-Python: >=3.8
|
|
|
14
14
|
Description-Content-Type: text/markdown
|
|
15
15
|
License-File: LICENSE
|
|
16
16
|
Requires-Dist: numpy>=1.11
|
|
17
|
+
Provides-Extra: plots
|
|
18
|
+
Requires-Dist: matplotlib>=3.0; extra == "plots"
|
|
17
19
|
Dynamic: author
|
|
18
20
|
Dynamic: author-email
|
|
19
21
|
Dynamic: classifier
|
|
@@ -23,6 +25,7 @@ Dynamic: home-page
|
|
|
23
25
|
Dynamic: license
|
|
24
26
|
Dynamic: license-file
|
|
25
27
|
Dynamic: platform
|
|
28
|
+
Dynamic: provides-extra
|
|
26
29
|
Dynamic: requires-dist
|
|
27
30
|
Dynamic: requires-python
|
|
28
31
|
Dynamic: summary
|
|
@@ -42,6 +45,12 @@ To install APLR, use the following command:
|
|
|
42
45
|
pip install aplr
|
|
43
46
|
```
|
|
44
47
|
|
|
48
|
+
To include dependencies for plotting, use this command instead:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
pip install aplr[plots]
|
|
52
|
+
```
|
|
53
|
+
|
|
45
54
|
## Availability
|
|
46
55
|
APLR is available for Windows, most Linux distributions, and macOS.
|
|
47
56
|
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
aplr_cpp.cp312-win32.pyd,sha256=d-rxNTorAgTsfcthV3QDfqoONLHniINjRmtbwSq8Bp0,592384
|
|
2
|
+
aplr/__init__.py,sha256=oDFSgVytP_qQ8ilun6oHxKr-DYEeqjEQp5FciX45lls,21
|
|
3
|
+
aplr/aplr.py,sha256=ZID8qOCi4UoE6sm9vSIUZvX1W1mrRsnzMacSOAhfl4Q,32828
|
|
4
|
+
aplr-10.14.0.dist-info/licenses/LICENSE,sha256=YOMo-RaL4P7edMZGD96-NskKpxyMZdP3-WiiMMmihNk,1134
|
|
5
|
+
aplr-10.14.0.dist-info/METADATA,sha256=I-iGE_rYV8PlMzKmjBgwYleYLbTwEnCsmJDP3WpqpZY,2627
|
|
6
|
+
aplr-10.14.0.dist-info/WHEEL,sha256=LwxTQZ0gyDP_uaeNCLm-ZIktY9hv6x0e22Q-hgFd-po,97
|
|
7
|
+
aplr-10.14.0.dist-info/top_level.txt,sha256=DXVC0RIFGpzVnPeKWAZTXQdJheOEZL51Wip6Fx7zbR4,14
|
|
8
|
+
aplr-10.14.0.dist-info/RECORD,,
|
aplr_cpp.cp312-win32.pyd
CHANGED
|
Binary file
|
aplr-10.12.1.dist-info/RECORD
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
aplr_cpp.cp312-win32.pyd,sha256=eRLyYH9cPaxeVI3aeAoaYp-0aexpMe0gnkFLz_MMHL0,592384
|
|
2
|
-
aplr/__init__.py,sha256=oDFSgVytP_qQ8ilun6oHxKr-DYEeqjEQp5FciX45lls,21
|
|
3
|
-
aplr/aplr.py,sha256=Sgpwe0h22J_B8aZGK1uexgb1MVS_Pq4Ygr7YNj3kE_Q,27090
|
|
4
|
-
aplr-10.12.1.dist-info/licenses/LICENSE,sha256=YOMo-RaL4P7edMZGD96-NskKpxyMZdP3-WiiMMmihNk,1134
|
|
5
|
-
aplr-10.12.1.dist-info/METADATA,sha256=tBju0tUk75uA0Mx08Iin6hz8ga8B2EyTUpccfzG_CUI,2421
|
|
6
|
-
aplr-10.12.1.dist-info/WHEEL,sha256=LwxTQZ0gyDP_uaeNCLm-ZIktY9hv6x0e22Q-hgFd-po,97
|
|
7
|
-
aplr-10.12.1.dist-info/top_level.txt,sha256=DXVC0RIFGpzVnPeKWAZTXQdJheOEZL51Wip6Fx7zbR4,14
|
|
8
|
-
aplr-10.12.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|