pg-sui 1.0.2.1__py3-none-any.whl → 1.6.8__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 pg-sui might be problematic. Click here for more details.

Files changed (112) hide show
  1. {pg_sui-1.0.2.1.dist-info → pg_sui-1.6.8.dist-info}/METADATA +51 -70
  2. pg_sui-1.6.8.dist-info/RECORD +78 -0
  3. {pg_sui-1.0.2.1.dist-info → pg_sui-1.6.8.dist-info}/WHEEL +1 -1
  4. pg_sui-1.6.8.dist-info/entry_points.txt +4 -0
  5. pg_sui-1.6.8.dist-info/top_level.txt +1 -0
  6. pgsui/__init__.py +35 -54
  7. pgsui/_version.py +34 -0
  8. pgsui/cli.py +635 -0
  9. pgsui/data_processing/config.py +576 -0
  10. pgsui/data_processing/containers.py +1782 -0
  11. pgsui/data_processing/transformers.py +121 -1103
  12. pgsui/electron/app/__main__.py +5 -0
  13. pgsui/electron/app/icons/icons/1024x1024.png +0 -0
  14. pgsui/electron/app/icons/icons/128x128.png +0 -0
  15. pgsui/electron/app/icons/icons/16x16.png +0 -0
  16. pgsui/electron/app/icons/icons/24x24.png +0 -0
  17. pgsui/electron/app/icons/icons/256x256.png +0 -0
  18. pgsui/electron/app/icons/icons/32x32.png +0 -0
  19. pgsui/electron/app/icons/icons/48x48.png +0 -0
  20. pgsui/electron/app/icons/icons/512x512.png +0 -0
  21. pgsui/electron/app/icons/icons/64x64.png +0 -0
  22. pgsui/electron/app/icons/icons/icon.icns +0 -0
  23. pgsui/electron/app/icons/icons/icon.ico +0 -0
  24. pgsui/electron/app/main.js +189 -0
  25. pgsui/electron/app/package-lock.json +6893 -0
  26. pgsui/electron/app/package.json +50 -0
  27. pgsui/electron/app/preload.js +15 -0
  28. pgsui/electron/app/server.py +146 -0
  29. pgsui/electron/app/ui/logo.png +0 -0
  30. pgsui/electron/app/ui/renderer.js +130 -0
  31. pgsui/electron/app/ui/styles.css +59 -0
  32. pgsui/electron/app/ui/ui_shim.js +72 -0
  33. pgsui/electron/bootstrap.py +43 -0
  34. pgsui/electron/launch.py +59 -0
  35. pgsui/electron/package.json +14 -0
  36. pgsui/example_data/popmaps/{test.popmap → phylogen_nomx.popmap} +185 -99
  37. pgsui/example_data/vcf_files/phylogen_subset14K.vcf.gz +0 -0
  38. pgsui/example_data/vcf_files/phylogen_subset14K.vcf.gz.tbi +0 -0
  39. pgsui/impute/deterministic/imputers/allele_freq.py +691 -0
  40. pgsui/impute/deterministic/imputers/mode.py +679 -0
  41. pgsui/impute/deterministic/imputers/nmf.py +221 -0
  42. pgsui/impute/deterministic/imputers/phylo.py +971 -0
  43. pgsui/impute/deterministic/imputers/ref_allele.py +530 -0
  44. pgsui/impute/supervised/base.py +339 -0
  45. pgsui/impute/supervised/imputers/hist_gradient_boosting.py +293 -0
  46. pgsui/impute/supervised/imputers/random_forest.py +287 -0
  47. pgsui/impute/unsupervised/base.py +924 -0
  48. pgsui/impute/unsupervised/callbacks.py +89 -263
  49. pgsui/impute/unsupervised/imputers/autoencoder.py +972 -0
  50. pgsui/impute/unsupervised/imputers/nlpca.py +1264 -0
  51. pgsui/impute/unsupervised/imputers/ubp.py +1288 -0
  52. pgsui/impute/unsupervised/imputers/vae.py +957 -0
  53. pgsui/impute/unsupervised/loss_functions.py +158 -0
  54. pgsui/impute/unsupervised/models/autoencoder_model.py +208 -558
  55. pgsui/impute/unsupervised/models/nlpca_model.py +149 -468
  56. pgsui/impute/unsupervised/models/ubp_model.py +198 -1317
  57. pgsui/impute/unsupervised/models/vae_model.py +259 -618
  58. pgsui/impute/unsupervised/nn_scorers.py +215 -0
  59. pgsui/utils/classification_viz.py +591 -0
  60. pgsui/utils/misc.py +35 -480
  61. pgsui/utils/plotting.py +514 -824
  62. pgsui/utils/scorers.py +212 -438
  63. pg_sui-1.0.2.1.dist-info/RECORD +0 -75
  64. pg_sui-1.0.2.1.dist-info/top_level.txt +0 -3
  65. pgsui/example_data/phylip_files/test_n10.phy +0 -118
  66. pgsui/example_data/phylip_files/test_n100.phy +0 -118
  67. pgsui/example_data/phylip_files/test_n2.phy +0 -118
  68. pgsui/example_data/phylip_files/test_n500.phy +0 -118
  69. pgsui/example_data/structure_files/test.nopops.1row.10sites.str +0 -117
  70. pgsui/example_data/structure_files/test.nopops.2row.100sites.str +0 -234
  71. pgsui/example_data/structure_files/test.nopops.2row.10sites.str +0 -234
  72. pgsui/example_data/structure_files/test.nopops.2row.30sites.str +0 -234
  73. pgsui/example_data/structure_files/test.nopops.2row.allsites.str +0 -234
  74. pgsui/example_data/structure_files/test.pops.1row.10sites.str +0 -117
  75. pgsui/example_data/structure_files/test.pops.2row.10sites.str +0 -234
  76. pgsui/example_data/trees/test.iqtree +0 -376
  77. pgsui/example_data/trees/test.qmat +0 -5
  78. pgsui/example_data/trees/test.rate +0 -2033
  79. pgsui/example_data/trees/test.tre +0 -1
  80. pgsui/example_data/trees/test_n10.rate +0 -19
  81. pgsui/example_data/trees/test_n100.rate +0 -109
  82. pgsui/example_data/trees/test_n500.rate +0 -509
  83. pgsui/example_data/trees/test_siterates.txt +0 -2024
  84. pgsui/example_data/trees/test_siterates_n10.txt +0 -10
  85. pgsui/example_data/trees/test_siterates_n100.txt +0 -100
  86. pgsui/example_data/trees/test_siterates_n500.txt +0 -500
  87. pgsui/example_data/vcf_files/test.vcf +0 -244
  88. pgsui/example_data/vcf_files/test.vcf.gz +0 -0
  89. pgsui/example_data/vcf_files/test.vcf.gz.tbi +0 -0
  90. pgsui/impute/estimators.py +0 -735
  91. pgsui/impute/impute.py +0 -1486
  92. pgsui/impute/simple_imputers.py +0 -1439
  93. pgsui/impute/supervised/iterative_imputer_fixedparams.py +0 -785
  94. pgsui/impute/supervised/iterative_imputer_gridsearch.py +0 -1027
  95. pgsui/impute/unsupervised/keras_classifiers.py +0 -702
  96. pgsui/impute/unsupervised/models/in_development/cnn_model.py +0 -486
  97. pgsui/impute/unsupervised/neural_network_imputers.py +0 -1424
  98. pgsui/impute/unsupervised/neural_network_methods.py +0 -1549
  99. pgsui/pg_sui.py +0 -261
  100. pgsui/utils/sequence_tools.py +0 -407
  101. simulation/sim_benchmarks.py +0 -333
  102. simulation/sim_treeparams.py +0 -475
  103. test/__init__.py +0 -0
  104. test/pg_sui_simtest.py +0 -215
  105. test/pg_sui_testing.py +0 -523
  106. test/test.py +0 -297
  107. test/test_pgsui.py +0 -374
  108. test/test_tkc.py +0 -214
  109. {pg_sui-1.0.2.1.dist-info → pg_sui-1.6.8.dist-info/licenses}/LICENSE +0 -0
  110. /pgsui/{example_data/trees → electron/app}/__init__.py +0 -0
  111. /pgsui/impute/{unsupervised/models/in_development → supervised/imputers}/__init__.py +0 -0
  112. {simulation → pgsui/impute/unsupervised/imputers}/__init__.py +0 -0
@@ -0,0 +1,215 @@
1
+ from typing import Dict, Literal
2
+
3
+ import numpy as np
4
+ from sklearn.metrics import (
5
+ accuracy_score,
6
+ average_precision_score,
7
+ f1_score,
8
+ precision_score,
9
+ recall_score,
10
+ roc_auc_score,
11
+ )
12
+ from snpio.utils.logging import LoggerManager
13
+ from torch import Tensor
14
+
15
+ from pgsui.utils.misc import validate_input_type
16
+
17
+
18
+ class Scorer:
19
+ """Class for evaluating the performance of a model using various metrics.
20
+
21
+ This module provides a unified interface for computing common evaluation metrics. It supports accuracy, F1 score, precision, recall, ROC AUC, average precision, and macro-average precision. The class can handle both raw and one-hot encoded labels and includes options for logging and averaging methods.
22
+ """
23
+
24
+ def __init__(
25
+ self,
26
+ prefix: str,
27
+ average: Literal["weighted", "macro", "micro"] = "macro",
28
+ verbose: bool = False,
29
+ debug: bool = False,
30
+ ) -> None:
31
+ """Initialize a Scorer object.
32
+
33
+ This class provides a unified interface for computing common evaluation metrics. It supports accuracy, F1 score, precision, recall, ROC AUC, average precision, and macro-average precision. The class can handle both raw and one-hot encoded labels and includes options for logging and averaging methods.
34
+
35
+ Args:
36
+ prefix (str): The prefix to use for logging.
37
+ average (Literal["weighted", "macro", "micro"]): The averaging method to use for metrics. Must be one of 'micro', 'macro', or 'weighted'. Defaults to 'weighted'.
38
+ verbose (bool): If True, enable verbose logging. Defaults to False.
39
+ debug (bool): If True, enable debug logging. Defaults to False.
40
+ """
41
+ logman = LoggerManager(
42
+ name=__name__, prefix=prefix, debug=debug, verbose=verbose
43
+ )
44
+ self.logger = logman.get_logger()
45
+
46
+ if average not in {"micro", "macro", "weighted"}:
47
+ msg = f"Invalid average parameter: {average}. Must be one of 'micro', 'macro', or 'weighted'."
48
+ self.logger.error(msg)
49
+ raise ValueError(msg)
50
+
51
+ self.average = average
52
+
53
+ def accuracy(self, y_true: np.ndarray, y_pred: np.ndarray) -> float:
54
+ """Compute the accuracy score.
55
+
56
+ Args:
57
+ y_true (np.ndarray): Ground truth (correct) target values.
58
+ y_pred (np.ndarray): Estimated target values.
59
+
60
+ Returns:
61
+ float: The accuracy score.
62
+ """
63
+ return accuracy_score(y_true, y_pred)
64
+
65
+ def f1(self, y_true: np.ndarray, y_pred: np.ndarray) -> float:
66
+ """Compute the F1 score.
67
+
68
+ Args:
69
+ y_true (np.ndarray): Ground truth (correct) target values.
70
+ y_pred (np.ndarray): Estimated target values.
71
+
72
+ Returns:
73
+ float: The F1 score.
74
+ """
75
+ return f1_score(y_true, y_pred, average=self.average, zero_division=0.0)
76
+
77
+ def precision(self, y_true: np.ndarray, y_pred: np.ndarray) -> float:
78
+ """Compute the precision score.
79
+
80
+ Args:
81
+ y_true (np.ndarray): Ground truth (correct) target values.
82
+ y_pred (np.ndarray): Estimated target values.
83
+
84
+ Returns:
85
+ float: The precision score.
86
+ """
87
+ return precision_score(y_true, y_pred, average=self.average, zero_division=0.0)
88
+
89
+ def recall(self, y_true: np.ndarray, y_pred: np.ndarray) -> float:
90
+ """Compute the recall score.
91
+
92
+ Args:
93
+ y_true (np.ndarray): Ground truth (correct) target values.
94
+ y_pred (np.ndarray): Estimated target values.
95
+
96
+ Returns:
97
+ float: The recall score.
98
+ """
99
+ return recall_score(y_true, y_pred, average=self.average, zero_division=0.0)
100
+
101
+ def roc_auc(self, y_true: np.ndarray, y_pred_proba: np.ndarray) -> float:
102
+ """Compute the ROC AUC score.
103
+
104
+ Args:
105
+ y_true (np.ndarray): Ground truth (correct) target values.
106
+ y_pred_proba (np.ndarray): Predicted probabilities.
107
+
108
+ Returns:
109
+ float: The ROC AUC score.
110
+ """
111
+ if len(np.unique(y_true)) < 2:
112
+ return 0.5
113
+ return roc_auc_score(
114
+ y_true, y_pred_proba, average=self.average, multi_class="ovr"
115
+ )
116
+
117
+ # This method now correctly expects one-hot encoded true labels
118
+ def average_precision(
119
+ self, y_true_ohe: np.ndarray, y_pred_proba: np.ndarray
120
+ ) -> float:
121
+ """Compute the average precision score.
122
+
123
+ Args:
124
+ y_true_ohe (np.ndarray): One-hot encoded ground truth target values.
125
+ y_pred_proba (np.ndarray): Predicted probabilities.
126
+
127
+ Returns:
128
+ float: The average precision score.
129
+ """
130
+ return average_precision_score(y_true_ohe, y_pred_proba, average=self.average)
131
+
132
+ def pr_macro(self, y_true_ohe: np.ndarray, y_pred_proba: np.ndarray) -> float:
133
+ """Compute the macro-average precision score.
134
+
135
+ Args:
136
+ y_true_ohe (np.ndarray): One-hot encoded ground truth target values.
137
+ y_pred_proba (np.ndarray): Predicted probabilities.
138
+
139
+ Returns:
140
+ float: The macro-average precision score.
141
+ """
142
+ return average_precision_score(y_true_ohe, y_pred_proba, average="macro")
143
+
144
+ def evaluate(
145
+ self,
146
+ y_true: np.ndarray | Tensor | list,
147
+ y_pred: np.ndarray | Tensor | list,
148
+ y_true_ohe: np.ndarray | Tensor | list,
149
+ y_pred_proba: np.ndarray | Tensor | list,
150
+ objective_mode: bool = False,
151
+ tune_metric: Literal[
152
+ "pr_macro",
153
+ "roc_auc",
154
+ "average_precision",
155
+ "accuracy",
156
+ "f1",
157
+ "precision",
158
+ "recall",
159
+ ] = "pr_macro",
160
+ ) -> Dict[str, float]:
161
+ """Evaluate the model using various metrics.
162
+
163
+ Args:
164
+ y_true: Ground truth (correct) target values.
165
+ y_pred: Estimated target values.
166
+ y_true_ohe: One-hot encoded ground truth target values.
167
+ y_pred_proba: Predicted probabilities.
168
+ objective_mode: If True, only compute the metric specified by ``tune_metric``. Defaults to False.
169
+ tune_metric: The metric to optimize during tuning. Defaults to "pr_macro".
170
+ """
171
+ y_true, y_pred, y_true_ohe, y_pred_proba = [
172
+ validate_input_type(x) for x in (y_true, y_pred, y_true_ohe, y_pred_proba)
173
+ ]
174
+
175
+ # NOTE: This is redundant because it's handled in the calling class
176
+ # TODO: Remove redundancy
177
+ valid_mask = np.logical_and(y_true >= 0, ~np.isnan(y_true))
178
+
179
+ if not np.any(valid_mask):
180
+ return {tune_metric: 0.0} if objective_mode else {}
181
+
182
+ y_true = y_true[valid_mask]
183
+ y_pred = y_pred[valid_mask]
184
+ y_true_ohe = y_true_ohe[valid_mask]
185
+ y_pred_proba = y_pred_proba[valid_mask]
186
+
187
+ if objective_mode:
188
+ metric_calculators = {
189
+ "pr_macro": lambda: self.pr_macro(y_true_ohe, y_pred_proba),
190
+ "roc_auc": lambda: self.roc_auc(y_true, y_pred_proba),
191
+ "average_precision": lambda: self.average_precision(
192
+ y_true_ohe, y_pred_proba
193
+ ),
194
+ "accuracy": lambda: self.accuracy(y_true, y_pred),
195
+ "f1": lambda: self.f1(y_true, y_pred),
196
+ "precision": lambda: self.precision(y_true, y_pred),
197
+ "recall": lambda: self.recall(y_true, y_pred),
198
+ }
199
+ if tune_metric not in metric_calculators:
200
+ msg = f"Invalid tune_metric provided: '{tune_metric}'."
201
+ self.logger.error(msg)
202
+ raise ValueError(msg)
203
+
204
+ metrics = {tune_metric: metric_calculators[tune_metric]()}
205
+ else:
206
+ metrics = {
207
+ "accuracy": self.accuracy(y_true, y_pred),
208
+ "f1": self.f1(y_true, y_pred),
209
+ "precision": self.precision(y_true, y_pred),
210
+ "recall": self.recall(y_true, y_pred),
211
+ "roc_auc": self.roc_auc(y_true, y_pred_proba),
212
+ "average_precision": self.average_precision(y_true_ohe, y_pred_proba),
213
+ "pr_macro": self.pr_macro(y_true_ohe, y_pred_proba),
214
+ }
215
+ return {k: float(v) for k, v in metrics.items()}