synomicsbench 1.0.0__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.
- synomicsbench/__init__.py +1 -0
- synomicsbench/metrics/__init__.py +13 -0
- synomicsbench/metrics/fidelity/BayesianComparison.py +356 -0
- synomicsbench/metrics/fidelity/MissingValueSimilarity.py +32 -0
- synomicsbench/metrics/fidelity/PairwiseSimilarity.py +643 -0
- synomicsbench/metrics/fidelity/UnivariateSimilarity.py +188 -0
- synomicsbench/metrics/fidelity/__init__.py +1 -0
- synomicsbench/metrics/fidelity/utils.py +196 -0
- synomicsbench/metrics/fidelity/visualization.py +288 -0
- synomicsbench/metrics/narrow_utility/BayesianComparison.py +547 -0
- synomicsbench/metrics/narrow_utility/DGE.py +399 -0
- synomicsbench/metrics/narrow_utility/GSEA.py +367 -0
- synomicsbench/metrics/narrow_utility/__init__.py +1 -0
- synomicsbench/metrics/narrow_utility/cell_deconvolution.py +86 -0
- synomicsbench/metrics/narrow_utility/predictive_model_comp.py +92 -0
- synomicsbench/metrics/narrow_utility/survival_analysis.py +418 -0
- synomicsbench/metrics/privacy/__init__.py +1 -0
- synomicsbench/metrics/privacy/inference.py +96 -0
- synomicsbench/metrics/privacy/linkability.py +90 -0
- synomicsbench/metrics/privacy/singling_out.py +107 -0
- synomicsbench/metrics/privacy/visualization.py +606 -0
- synomicsbench/processing/__init__.py +0 -0
- synomicsbench/processing/gene_query.py +202 -0
- synomicsbench/processing/metadata.py +264 -0
- synomicsbench/processing/pipeline.py +683 -0
- synomicsbench/processing/postprocessing.py +235 -0
- synomicsbench/processing/preprocessing.py +1004 -0
- synomicsbench/synthesizer/BaseSynthesizer.py +326 -0
- synomicsbench/synthesizer/CTGANsynthesizer.py +133 -0
- synomicsbench/synthesizer/GaussianCopulasynthesizer.py +351 -0
- synomicsbench/synthesizer/GaussianMultivariate_Parallel.py +463 -0
- synomicsbench/synthesizer/Synthpopsynthesizer.py +352 -0
- synomicsbench/synthesizer/TVAEsynthesizer.py +141 -0
- synomicsbench/synthesizer/__init__.py +0 -0
- synomicsbench/utils/__init__.py +1 -0
- synomicsbench/utils/correlations.py +799 -0
- synomicsbench/utils/monitoring.py +135 -0
- synomicsbench-1.0.0.dist-info/METADATA +162 -0
- synomicsbench-1.0.0.dist-info/RECORD +41 -0
- synomicsbench-1.0.0.dist-info/WHEEL +4 -0
- synomicsbench-1.0.0.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "1.0.0"
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Metrics module for evaluating synthetic data quality.
|
|
3
|
+
|
|
4
|
+
This module provides comprehensive evaluation metrics across three dimensions:
|
|
5
|
+
- Statistical Fidelity: Univariate and bivariate similarity measures
|
|
6
|
+
- Biological Utility: Downstream bioinformatics task performance
|
|
7
|
+
- Privacy Risk: Attack-based privacy assessment
|
|
8
|
+
|
|
9
|
+
Submodules:
|
|
10
|
+
- fidelity: Statistical similarity metrics
|
|
11
|
+
- narrow_utility: Biological signal preservation metrics
|
|
12
|
+
- privacy: Privacy attack risk assessment
|
|
13
|
+
"""
|
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass, field
|
|
4
|
+
from typing import Dict, List, Mapping, Optional, Sequence, Tuple
|
|
5
|
+
|
|
6
|
+
import numpy as np
|
|
7
|
+
import pandas as pd
|
|
8
|
+
import seaborn as sns
|
|
9
|
+
import matplotlib.pyplot as plt
|
|
10
|
+
|
|
11
|
+
try:
|
|
12
|
+
import baycomp
|
|
13
|
+
except ImportError as e:
|
|
14
|
+
raise ImportError("baycomp is required. Install with: pip install baycomp") from e
|
|
15
|
+
|
|
16
|
+
from matplotlib.colors import LinearSegmentedColormap, TwoSlopeNorm
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
# -----------------------------
|
|
20
|
+
# Nature-style + consistent colormap
|
|
21
|
+
# -----------------------------
|
|
22
|
+
|
|
23
|
+
_FONT = {
|
|
24
|
+
"family": "sans-serif",
|
|
25
|
+
"sans-serif": ["Helvetica", "Arial", "DejaVu Sans"],
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
STABILITY_PLOT_COLORS = {
|
|
29
|
+
"grid": "#e6e6e6",
|
|
30
|
+
"heatmap_bg": "#f7f7f7",
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
PBETTER_FOCUS_CMAP = LinearSegmentedColormap.from_list(
|
|
34
|
+
"pbetter_focus",
|
|
35
|
+
[
|
|
36
|
+
(0.0, "#ffffff"),
|
|
37
|
+
(0.5, "#ffffff"),
|
|
38
|
+
(1.0, "#1a9850"),
|
|
39
|
+
],
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
CANCER_COLORS = {
|
|
43
|
+
"ccRCC": "#4C72B0",
|
|
44
|
+
"Melanoma": "#DD8452",
|
|
45
|
+
"NSCLC": "#55A868",
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def _set_nature_rcparams(fontsize: int = 11) -> None:
|
|
50
|
+
"""
|
|
51
|
+
Apply Nature-like matplotlib rcParams (Helvetica/Arial and clean axes).
|
|
52
|
+
|
|
53
|
+
Args:
|
|
54
|
+
fontsize (int): Base font size for the figure.
|
|
55
|
+
|
|
56
|
+
Raises:
|
|
57
|
+
ValueError: If fontsize is not positive.
|
|
58
|
+
"""
|
|
59
|
+
if fontsize <= 0:
|
|
60
|
+
raise ValueError("fontsize must be a positive integer.")
|
|
61
|
+
|
|
62
|
+
plt.rcParams.update(
|
|
63
|
+
{
|
|
64
|
+
"font.size": fontsize,
|
|
65
|
+
"font.family": _FONT["family"],
|
|
66
|
+
"font.sans-serif": _FONT["sans-serif"],
|
|
67
|
+
"pdf.fonttype": 42,
|
|
68
|
+
"ps.fonttype": 42,
|
|
69
|
+
"axes.titlesize": fontsize + 1,
|
|
70
|
+
"axes.labelsize": fontsize,
|
|
71
|
+
"xtick.labelsize": fontsize - 1,
|
|
72
|
+
"ytick.labelsize": fontsize - 1,
|
|
73
|
+
"legend.fontsize": fontsize - 1,
|
|
74
|
+
}
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
@dataclass(frozen=True)
|
|
79
|
+
class BaycompStyle:
|
|
80
|
+
"""
|
|
81
|
+
Store manuscript-style visualization settings for baycomp heatmaps.
|
|
82
|
+
|
|
83
|
+
Args:
|
|
84
|
+
fontsize (int): Base font size used in matplotlib rcParams.
|
|
85
|
+
nature_font (Dict[str, Sequence[str]]): Font family configuration.
|
|
86
|
+
plot_colors (Dict[str, str]): Common background/grid colors.
|
|
87
|
+
pbetter_cmap (LinearSegmentedColormap): Colormap for P(Better) heatmaps.
|
|
88
|
+
cancer_colors (Dict[str, str]): Color strip mapping for each cancer panel.
|
|
89
|
+
|
|
90
|
+
Raises:
|
|
91
|
+
ValueError: If fontsize is not positive.
|
|
92
|
+
"""
|
|
93
|
+
fontsize: int = 11
|
|
94
|
+
nature_font: Dict[str, Sequence[str]] = field(default_factory=lambda: dict(_FONT))
|
|
95
|
+
plot_colors: Dict[str, str] = field(default_factory=lambda: dict(STABILITY_PLOT_COLORS))
|
|
96
|
+
pbetter_cmap: LinearSegmentedColormap = field(default_factory=lambda: PBETTER_FOCUS_CMAP)
|
|
97
|
+
cancer_colors: Dict[str, str] = field(default_factory=lambda: dict(CANCER_COLORS))
|
|
98
|
+
|
|
99
|
+
def __post_init__(self) -> None:
|
|
100
|
+
if self.fontsize <= 0:
|
|
101
|
+
raise ValueError("fontsize must be a positive integer.")
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
@dataclass
|
|
105
|
+
class BayesianComparison:
|
|
106
|
+
"""
|
|
107
|
+
Compute Bayesian pairwise comparisons using the external baycomp package.
|
|
108
|
+
|
|
109
|
+
Args:
|
|
110
|
+
rope (float): ROPE threshold for practical equivalence.
|
|
111
|
+
seed (int): Random seed for reproducibility in baycomp.
|
|
112
|
+
style (BaycompStyle): Plot styling settings for consistent manuscript figures.
|
|
113
|
+
|
|
114
|
+
Raises:
|
|
115
|
+
ValueError: If rope is not positive.
|
|
116
|
+
"""
|
|
117
|
+
rope: float = 0.01
|
|
118
|
+
seed: int = 0
|
|
119
|
+
style: BaycompStyle = field(default_factory=BaycompStyle)
|
|
120
|
+
|
|
121
|
+
def __post_init__(self) -> None:
|
|
122
|
+
if self.rope <= 0:
|
|
123
|
+
raise ValueError("rope must be > 0.")
|
|
124
|
+
|
|
125
|
+
@staticmethod
|
|
126
|
+
def _validate_scores(scores: Sequence[float], method: str) -> np.ndarray:
|
|
127
|
+
"""
|
|
128
|
+
Validate and coerce a score sequence to a finite numpy array.
|
|
129
|
+
"""
|
|
130
|
+
x = np.asarray(scores, dtype=float)
|
|
131
|
+
x = x[np.isfinite(x)]
|
|
132
|
+
if x.size < 2:
|
|
133
|
+
raise ValueError(f"Method '{method}' must have at least 2 finite scores for baycomp.")
|
|
134
|
+
return x
|
|
135
|
+
|
|
136
|
+
@staticmethod
|
|
137
|
+
def _resolve_methods_order(
|
|
138
|
+
method_to_scores: Mapping[str, Sequence[float]],
|
|
139
|
+
methods_order: Optional[Sequence[str]],
|
|
140
|
+
) -> List[str]:
|
|
141
|
+
"""
|
|
142
|
+
Resolve and validate the method ordering.
|
|
143
|
+
"""
|
|
144
|
+
if not method_to_scores or len(method_to_scores) < 2:
|
|
145
|
+
raise ValueError("method_to_scores must contain at least 2 methods.")
|
|
146
|
+
|
|
147
|
+
if methods_order is None:
|
|
148
|
+
return list(method_to_scores.keys())
|
|
149
|
+
|
|
150
|
+
resolved = list(methods_order)
|
|
151
|
+
missing = [m for m in resolved if m not in method_to_scores]
|
|
152
|
+
if missing:
|
|
153
|
+
raise ValueError(f"methods_order contains methods missing in method_to_scores: {missing}")
|
|
154
|
+
return resolved
|
|
155
|
+
|
|
156
|
+
def compare_methods(
|
|
157
|
+
self,
|
|
158
|
+
method_to_scores: Mapping[str, Sequence[float]],
|
|
159
|
+
methods_order: Optional[Sequence[str]] = None,
|
|
160
|
+
) -> pd.DataFrame:
|
|
161
|
+
"""
|
|
162
|
+
Compute ordered-pair Bayesian comparison probabilities for a set of methods.
|
|
163
|
+
|
|
164
|
+
Args:
|
|
165
|
+
method_to_scores (Mapping[str, Sequence[float]]): Mapping method -> scores across seeds/folds.
|
|
166
|
+
methods_order (Optional[Sequence[str]]): Optional ordering for methods.
|
|
167
|
+
|
|
168
|
+
Returns:
|
|
169
|
+
pd.DataFrame: Table with columns:
|
|
170
|
+
["Method 1", "Method 2", "Better Prob", "Worse Prob", "Equivalent Prob"].
|
|
171
|
+
|
|
172
|
+
Raises:
|
|
173
|
+
ValueError: If fewer than 2 methods are provided.
|
|
174
|
+
ValueError: If any method has fewer than 2 finite scores.
|
|
175
|
+
"""
|
|
176
|
+
methods = self._resolve_methods_order(method_to_scores, methods_order)
|
|
177
|
+
scores_np = {m: self._validate_scores(method_to_scores[m], method=m) for m in methods}
|
|
178
|
+
|
|
179
|
+
rows: List[dict] = []
|
|
180
|
+
for i, m1 in enumerate(methods):
|
|
181
|
+
for j, m2 in enumerate(methods):
|
|
182
|
+
if i == j:
|
|
183
|
+
continue
|
|
184
|
+
|
|
185
|
+
probs = baycomp.two_on_single(scores_np[m1], scores_np[m2], rope=self.rope)
|
|
186
|
+
p_better = float(probs[0])
|
|
187
|
+
p_equiv = float(probs[1])
|
|
188
|
+
p_worse = float(probs[2])
|
|
189
|
+
|
|
190
|
+
rows.append(
|
|
191
|
+
{
|
|
192
|
+
"Method 1": m1,
|
|
193
|
+
"Method 2": m2,
|
|
194
|
+
"Better Prob": p_better,
|
|
195
|
+
"Worse Prob": p_worse,
|
|
196
|
+
"Equivalent Prob": p_equiv,
|
|
197
|
+
}
|
|
198
|
+
)
|
|
199
|
+
|
|
200
|
+
return pd.DataFrame(rows)
|
|
201
|
+
|
|
202
|
+
@staticmethod
|
|
203
|
+
def comparison_to_matrix(
|
|
204
|
+
comparison_df: pd.DataFrame,
|
|
205
|
+
methods_order: Sequence[str],
|
|
206
|
+
value_col: str = "Better Prob",
|
|
207
|
+
nan_diagonal: bool = True,
|
|
208
|
+
) -> pd.DataFrame:
|
|
209
|
+
"""
|
|
210
|
+
Convert a comparison table into a square matrix suitable for heatmap plotting.
|
|
211
|
+
|
|
212
|
+
Args:
|
|
213
|
+
comparison_df (pd.DataFrame): Output of compare_methods.
|
|
214
|
+
methods_order (Sequence[str]): Method ordering for rows and columns.
|
|
215
|
+
value_col (str): Which column to visualize.
|
|
216
|
+
nan_diagonal (bool): If True, set diagonal values to NaN.
|
|
217
|
+
|
|
218
|
+
Returns:
|
|
219
|
+
pd.DataFrame: Square matrix with index=Method 1 and columns=Method 2.
|
|
220
|
+
|
|
221
|
+
Raises:
|
|
222
|
+
ValueError: If value_col is not present in comparison_df.
|
|
223
|
+
"""
|
|
224
|
+
if value_col not in comparison_df.columns:
|
|
225
|
+
raise ValueError(f"value_col must be a column in comparison_df, got '{value_col}'.")
|
|
226
|
+
|
|
227
|
+
mat = comparison_df.pivot(index="Method 1", columns="Method 2", values=value_col)
|
|
228
|
+
mat = mat.reindex(index=list(methods_order), columns=list(methods_order))
|
|
229
|
+
|
|
230
|
+
if nan_diagonal:
|
|
231
|
+
for m in methods_order:
|
|
232
|
+
if m in mat.index and m in mat.columns:
|
|
233
|
+
mat.loc[m, m] = np.nan
|
|
234
|
+
|
|
235
|
+
return mat
|
|
236
|
+
|
|
237
|
+
def plot_pbetter_heatmap_grid(
|
|
238
|
+
self,
|
|
239
|
+
cancer_to_method_scores: Dict[str, Dict[str, Sequence[float]]],
|
|
240
|
+
cancers_order: Sequence[str] = ("ccRCC", "Melanoma", "NSCLC"),
|
|
241
|
+
methods_order: Optional[Sequence[str]] = None,
|
|
242
|
+
value_col: str = "Better Prob",
|
|
243
|
+
figsize: Tuple[int, int] = (18, 5.5),
|
|
244
|
+
annot: bool = True,
|
|
245
|
+
fmt: str = ".2f",
|
|
246
|
+
show: bool = True,
|
|
247
|
+
) -> Tuple[plt.Figure, np.ndarray, Dict[str, pd.DataFrame], Dict[str, pd.DataFrame]]:
|
|
248
|
+
"""
|
|
249
|
+
Plot a 1xN grid of Bayesian comparison probability heatmaps (one per cancer cohort).
|
|
250
|
+
|
|
251
|
+
Args:
|
|
252
|
+
cancer_to_method_scores (Dict[str, Dict[str, Sequence[float]]]): cancer -> {method -> scores across seeds/folds}.
|
|
253
|
+
cancers_order (Sequence[str]): Order of cohorts in the grid.
|
|
254
|
+
methods_order (Optional[Sequence[str]]): Global method ordering. If None, uses union over cancers.
|
|
255
|
+
value_col (str): One of ["Better Prob", "Worse Prob", "Equivalent Prob"] to visualize.
|
|
256
|
+
figsize (Tuple[int, int]): Figure size in inches.
|
|
257
|
+
annot (bool): If True, annotate each cell with numeric values.
|
|
258
|
+
fmt (str): Annotation format passed to seaborn.
|
|
259
|
+
show (bool): If True, calls plt.show().
|
|
260
|
+
|
|
261
|
+
Returns:
|
|
262
|
+
Tuple[plt.Figure, np.ndarray, Dict[str, pd.DataFrame], Dict[str, pd.DataFrame]]:
|
|
263
|
+
fig, axes, matrices_by_cancer, comparisons_by_cancer
|
|
264
|
+
|
|
265
|
+
Raises:
|
|
266
|
+
ValueError: If value_col is invalid.
|
|
267
|
+
ValueError: If cancers_order contains a cohort not present in cancer_to_method_scores.
|
|
268
|
+
"""
|
|
269
|
+
allowed = {"Better Prob", "Worse Prob", "Equivalent Prob"}
|
|
270
|
+
if value_col not in allowed:
|
|
271
|
+
raise ValueError(f"value_col must be one of {sorted(allowed)}.")
|
|
272
|
+
|
|
273
|
+
cancers = list(cancers_order)
|
|
274
|
+
for c in cancers:
|
|
275
|
+
if c not in cancer_to_method_scores:
|
|
276
|
+
raise ValueError(f"Cancer '{c}' missing from cancer_to_method_scores.")
|
|
277
|
+
|
|
278
|
+
if methods_order is None:
|
|
279
|
+
union_methods: List[str] = []
|
|
280
|
+
for c in cancers:
|
|
281
|
+
for m in cancer_to_method_scores[c].keys():
|
|
282
|
+
if m not in union_methods:
|
|
283
|
+
union_methods.append(m)
|
|
284
|
+
methods = union_methods
|
|
285
|
+
else:
|
|
286
|
+
methods = list(methods_order)
|
|
287
|
+
|
|
288
|
+
_set_nature_rcparams(fontsize=self.style.fontsize)
|
|
289
|
+
sns.set(style="white", rc={"axes.facecolor": self.style.plot_colors["heatmap_bg"]})
|
|
290
|
+
|
|
291
|
+
fig, axes = plt.subplots(1, len(cancers), figsize=figsize)
|
|
292
|
+
if len(cancers) == 1:
|
|
293
|
+
axes = np.array([axes])
|
|
294
|
+
|
|
295
|
+
norm = TwoSlopeNorm(vmin=0.0, vcenter=0.5, vmax=1.0)
|
|
296
|
+
|
|
297
|
+
mats_by_cancer: Dict[str, pd.DataFrame] = {}
|
|
298
|
+
comps_by_cancer: Dict[str, pd.DataFrame] = {}
|
|
299
|
+
|
|
300
|
+
for ax, cancer in zip(axes, cancers):
|
|
301
|
+
comp_df = self.compare_methods(
|
|
302
|
+
method_to_scores=cancer_to_method_scores[cancer],
|
|
303
|
+
methods_order=methods,
|
|
304
|
+
)
|
|
305
|
+
comps_by_cancer[cancer] = comp_df
|
|
306
|
+
|
|
307
|
+
mat = self.comparison_to_matrix(
|
|
308
|
+
comparison_df=comp_df,
|
|
309
|
+
methods_order=methods,
|
|
310
|
+
value_col=value_col,
|
|
311
|
+
nan_diagonal=True,
|
|
312
|
+
)
|
|
313
|
+
mats_by_cancer[cancer] = mat
|
|
314
|
+
|
|
315
|
+
if value_col == "Better Prob":
|
|
316
|
+
cmap = self.style.pbetter_cmap.copy()
|
|
317
|
+
used_norm = norm
|
|
318
|
+
else:
|
|
319
|
+
cmap = plt.cm.viridis.copy()
|
|
320
|
+
used_norm = None
|
|
321
|
+
cmap.set_bad(color="#D3D3D3")
|
|
322
|
+
|
|
323
|
+
sns.heatmap(
|
|
324
|
+
mat,
|
|
325
|
+
ax=ax,
|
|
326
|
+
cmap=cmap,
|
|
327
|
+
norm=used_norm,
|
|
328
|
+
annot=annot,
|
|
329
|
+
fmt=fmt,
|
|
330
|
+
linewidths=0.5,
|
|
331
|
+
linecolor="lightgray",
|
|
332
|
+
cbar=(ax is axes[-1]),
|
|
333
|
+
cbar_kws={"label": value_col} if (ax is axes[-1]) else None,
|
|
334
|
+
square=True,
|
|
335
|
+
)
|
|
336
|
+
|
|
337
|
+
ax.set_title(cancer, fontsize=self.style.fontsize + 1, fontweight="bold", pad=10)
|
|
338
|
+
|
|
339
|
+
cancer_color = self.style.cancer_colors.get(cancer, "#333333")
|
|
340
|
+
ax.plot(
|
|
341
|
+
[0.02, 0.98],
|
|
342
|
+
[1.02, 1.02],
|
|
343
|
+
transform=ax.transAxes,
|
|
344
|
+
color=cancer_color,
|
|
345
|
+
lw=4,
|
|
346
|
+
clip_on=False,
|
|
347
|
+
)
|
|
348
|
+
|
|
349
|
+
ax.tick_params(axis="x", rotation=45)
|
|
350
|
+
ax.tick_params(axis="y", rotation=0)
|
|
351
|
+
|
|
352
|
+
plt.tight_layout()
|
|
353
|
+
if show:
|
|
354
|
+
plt.show()
|
|
355
|
+
|
|
356
|
+
return fig, axes, mats_by_cancer, comps_by_cancer
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
from sdmetrics.single_column import MissingValueSimilarity
|
|
2
|
+
import pandas as pd
|
|
3
|
+
|
|
4
|
+
def MissingValue_Similarity(
|
|
5
|
+
origin_data: pd.DataFrame, synthetic_data: pd.DataFrame, missing_indicators: list
|
|
6
|
+
):
|
|
7
|
+
"""
|
|
8
|
+
Compute missing value similarity scores for each target column.
|
|
9
|
+
|
|
10
|
+
Args:
|
|
11
|
+
origin_data (pd.DataFrame): Original data.
|
|
12
|
+
synthetic_data (pd.DataFrame): Synthetic data.
|
|
13
|
+
missing_indicators (list): List of column names with missing indicators.
|
|
14
|
+
|
|
15
|
+
Returns:
|
|
16
|
+
dict: Mapping from column name to similarity score.
|
|
17
|
+
|
|
18
|
+
Raises:
|
|
19
|
+
Exception: If computation fails for any column.
|
|
20
|
+
"""
|
|
21
|
+
MissingValue_dict = {}
|
|
22
|
+
target_cols = [col.replace("missingindicator_", "") for col in missing_indicators]
|
|
23
|
+
for target_col in target_cols:
|
|
24
|
+
try:
|
|
25
|
+
simi_score = MissingValueSimilarity.compute(
|
|
26
|
+
real_data=origin_data[target_col], synthetic_data=synthetic_data[target_col]
|
|
27
|
+
)
|
|
28
|
+
MissingValue_dict[target_col] = simi_score
|
|
29
|
+
except Exception:
|
|
30
|
+
# Continue but note error in dict
|
|
31
|
+
MissingValue_dict[target_col] = None
|
|
32
|
+
return MissingValue_dict
|