ctdGAN 0.3.1__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.
ctdGAN/Tools.py ADDED
@@ -0,0 +1,175 @@
1
+ import random
2
+ import numpy as np
3
+ import pandas as pd
4
+ from scipy.stats import chi2_contingency
5
+ import torch
6
+
7
+ import gc
8
+ import contextlib
9
+
10
+
11
+ def set_random_states(manual_seed):
12
+ """Initializes the random number generators of NumPy, PyTorch, and PyTorch CUDA by passing the input seed.
13
+
14
+ Args:
15
+ manual_seed: An integer to be passed to the random number generators.
16
+ """
17
+ np.random.seed(manual_seed)
18
+
19
+ if manual_seed is None:
20
+ torch.manual_seed(0)
21
+ torch.cuda.manual_seed(0)
22
+ else:
23
+ torch.manual_seed(manual_seed)
24
+ torch.cuda.manual_seed(manual_seed)
25
+
26
+ torch.backends.cudnn.deterministic = True
27
+ torch.backends.cudnn.benchmark = False
28
+
29
+ def get_random_states():
30
+ """Retrieves the current states of randomness of NumPy, PyTorch, and PyTorch CUDA.
31
+
32
+ Returns:
33
+ Three states of randomness for NumPy, PyTorch, and PyTorch CUDA respectively.
34
+ """
35
+ np_random_state = np.random.get_state()
36
+ torch_random_state = torch.random.get_rng_state()
37
+ if torch.cuda.is_available():
38
+ cuda_random_state = torch.cuda.random.get_rng_state()
39
+ else:
40
+ cuda_random_state = None
41
+
42
+ return np_random_state, torch_random_state, cuda_random_state
43
+
44
+
45
+ def reset_random_states(np_random_state, torch_random_state, cuda_random_state):
46
+ """Sets the current states of randomness of NumPy, PyTorch, and PyTorch CUDA.
47
+
48
+ Args:
49
+ np_random_state: The state at which the NumPy random generator will be set.
50
+ torch_random_state: The state at which the PyTorch random generator will be set.
51
+ cuda_random_state: The state at which the PyTorch CUDA random generator will be set.
52
+ """
53
+ np.random.set_state(np_random_state)
54
+ torch.random.set_rng_state(torch_random_state)
55
+
56
+ if torch.cuda.is_available():
57
+ torch.cuda.random.set_rng_state(cuda_random_state)
58
+ torch.cuda.empty_cache()
59
+
60
+ gc.collect()
61
+
62
+
63
+ def relabel_clusters(labels):
64
+ """
65
+ Relabel cluster IDs so they become consecutive integers starting from 0.
66
+
67
+ Example:
68
+ [0,0,0,0,2,2,2] -> [0,0,0,0,1,1,1]
69
+ """
70
+ mapping = {}
71
+ new_labels = []
72
+ next_label = 0
73
+
74
+ for label in labels:
75
+ if label not in mapping:
76
+ mapping[label] = next_label
77
+ next_label += 1
78
+ new_labels.append(mapping[label])
79
+
80
+ return new_labels
81
+
82
+ @contextlib.contextmanager
83
+ def ct_set_random_states(seed, set_model_random_state):
84
+ """Context manager for managing the random state.
85
+
86
+ Args:
87
+ seed (int or tuple):
88
+ The random seed or a tuple of (numpy.random.RandomState, torch.Generator).
89
+ set_model_random_state (function):
90
+ Function to set the random state on the model.
91
+ """
92
+ original_np_state = np.random.get_state()
93
+ original_torch_state = torch.get_rng_state()
94
+
95
+ random_np_state, random_torch_state = seed
96
+
97
+ np.random.set_state(random_np_state.get_state())
98
+ torch.set_rng_state(random_torch_state.get_state())
99
+
100
+ try:
101
+ yield
102
+ finally:
103
+ current_np_state = np.random.RandomState()
104
+ current_np_state.set_state(np.random.get_state())
105
+ current_torch_state = torch.Generator()
106
+ current_torch_state.set_state(torch.get_rng_state())
107
+ set_model_random_state((current_np_state, current_torch_state))
108
+
109
+ np.random.set_state(original_np_state)
110
+ torch.set_rng_state(original_torch_state)
111
+
112
+
113
+ def random_state(function):
114
+ """Set the random state before calling the function.
115
+
116
+ Args:
117
+ function (Callable): The function to wrap around.
118
+ """
119
+
120
+ def wrapper(self, *args, **kwargs):
121
+ if self.random_states is None:
122
+ return function(self, *args, **kwargs)
123
+
124
+ else:
125
+ with ct_set_random_states(self.random_states, self.set_random_state):
126
+ return function(self, *args, **kwargs)
127
+
128
+ return wrapper
129
+
130
+ def cramers_v(x, y):
131
+ confusion_matrix = pd.crosstab(x, y)
132
+ chi2 = chi2_contingency(confusion_matrix)[0]
133
+ n = confusion_matrix.sum().sum()
134
+ r, k = confusion_matrix.shape
135
+ return np.sqrt(chi2 / (n * (min(k - 1, r - 1) + 1e-8)))
136
+
137
+ def correlation_ratio(categories, measurements):
138
+ categories = pd.Categorical(categories)
139
+ groups = [measurements[categories == cat] for cat in categories.categories]
140
+
141
+ grand_mean = np.mean(measurements)
142
+
143
+ ss_between = sum(len(g) * (np.mean(g) - grand_mean) ** 2 for g in groups)
144
+ ss_total = sum((measurements - grand_mean)**2)
145
+
146
+ return np.sqrt(ss_between / (ss_total + 1e-8))
147
+
148
+ def compute_mixed_matrix(df, cat_cols):
149
+ cols = df.columns
150
+ mat = pd.DataFrame(np.zeros((len(cols), len(cols))), index=cols, columns=cols)
151
+
152
+ num_cols = [c for c in cols if c not in cat_cols]
153
+
154
+ for i, col1 in enumerate(cols):
155
+ for j, col2 in enumerate(cols):
156
+
157
+ if col1 == col2:
158
+ mat.loc[col1, col2] = 1.0
159
+
160
+ elif col1 in num_cols and col2 in num_cols:
161
+ mat.loc[col1, col2] = df[col1].corr(df[col2])
162
+
163
+ elif col1 in cat_cols and col2 in cat_cols:
164
+ mat.loc[col1, col2] = cramers_v(df[col1], df[col2])
165
+
166
+ else:
167
+ # numeric-categorical
168
+ if col1 in cat_cols:
169
+ cat, num = col1, col2
170
+ else:
171
+ cat, num = col2, col1
172
+
173
+ mat.loc[col1, col2] = correlation_ratio(df[cat], df[num])
174
+
175
+ return mat
ctdGAN/__init__.py ADDED
@@ -0,0 +1,3 @@
1
+ from .ctdgan import ctdGAN
2
+
3
+ __all__ = ["ctdGAN"]