likelihood 1.2.20__tar.gz → 1.2.21__tar.gz

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.
Files changed (24) hide show
  1. {likelihood-1.2.20 → likelihood-1.2.21}/PKG-INFO +1 -1
  2. {likelihood-1.2.20 → likelihood-1.2.21}/likelihood/main.py +86 -116
  3. {likelihood-1.2.20 → likelihood-1.2.21}/likelihood/models/deep/autoencoders.py +8 -4
  4. {likelihood-1.2.20 → likelihood-1.2.21}/likelihood/tools/numeric_tools.py +87 -0
  5. {likelihood-1.2.20 → likelihood-1.2.21}/likelihood.egg-info/PKG-INFO +1 -1
  6. {likelihood-1.2.20 → likelihood-1.2.21}/LICENSE +0 -0
  7. {likelihood-1.2.20 → likelihood-1.2.21}/README.md +0 -0
  8. {likelihood-1.2.20 → likelihood-1.2.21}/likelihood/__init__.py +0 -0
  9. {likelihood-1.2.20 → likelihood-1.2.21}/likelihood/graph/__init__.py +0 -0
  10. {likelihood-1.2.20 → likelihood-1.2.21}/likelihood/graph/graph.py +0 -0
  11. {likelihood-1.2.20 → likelihood-1.2.21}/likelihood/graph/nn.py +0 -0
  12. {likelihood-1.2.20 → likelihood-1.2.21}/likelihood/models/__init__.py +0 -0
  13. {likelihood-1.2.20 → likelihood-1.2.21}/likelihood/models/deep/__init__.py +0 -0
  14. {likelihood-1.2.20 → likelihood-1.2.21}/likelihood/models/regression.py +0 -0
  15. {likelihood-1.2.20 → likelihood-1.2.21}/likelihood/models/simulation.py +0 -0
  16. {likelihood-1.2.20 → likelihood-1.2.21}/likelihood/models/utils.py +0 -0
  17. {likelihood-1.2.20 → likelihood-1.2.21}/likelihood/tools/__init__.py +0 -0
  18. {likelihood-1.2.20 → likelihood-1.2.21}/likelihood/tools/tools.py +0 -0
  19. {likelihood-1.2.20 → likelihood-1.2.21}/likelihood.egg-info/SOURCES.txt +0 -0
  20. {likelihood-1.2.20 → likelihood-1.2.21}/likelihood.egg-info/dependency_links.txt +0 -0
  21. {likelihood-1.2.20 → likelihood-1.2.21}/likelihood.egg-info/requires.txt +0 -0
  22. {likelihood-1.2.20 → likelihood-1.2.21}/likelihood.egg-info/top_level.txt +0 -0
  23. {likelihood-1.2.20 → likelihood-1.2.21}/setup.cfg +0 -0
  24. {likelihood-1.2.20 → likelihood-1.2.21}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: likelihood
3
- Version: 1.2.20
3
+ Version: 1.2.21
4
4
  Summary: A package that performs the maximum likelihood algorithm.
5
5
  Home-page: https://github.com/jzsmoreno/likelihood/
6
6
  Author: J. A. Moreno-Guerra
@@ -3,10 +3,9 @@ from typing import Callable, List, Tuple
3
3
  import corner
4
4
  import matplotlib.pyplot as plt
5
5
  import numpy as np
6
- from numpy import ndarray
7
6
 
8
7
 
9
- def lnprior(theta: ndarray, conditions: List[Tuple[float, float]]) -> float:
8
+ def lnprior(theta: np.ndarray, conditions: List[Tuple[float, float]]) -> float:
10
9
  """Computes the prior probability.
11
10
 
12
11
  Parameters
@@ -22,29 +21,22 @@ def lnprior(theta: ndarray, conditions: List[Tuple[float, float]]) -> float:
22
21
  lp : `float`
23
22
  The a priori probability.
24
23
  """
24
+ if len(conditions) != 2 * len(theta):
25
+ raise ValueError("Length of conditions must be twice the length of theta.")
25
26
 
26
- try:
27
- if len(conditions) != 2 * len(theta):
28
- error_type = "IndexError"
29
- msg = "Length of conditions must be twice the length of theta."
30
- print(f"{error_type}: {msg}")
31
- else:
32
- cond = np.array(conditions).reshape((len(theta), 2))
33
- for i in range(len(theta)):
34
- if cond[i, 0] < theta[i] < cond[i, 1]:
35
- lp = 0.0
36
- else:
37
- return np.inf
38
- return lp
39
- except:
40
- return 0.0
27
+ cond = np.array(conditions).reshape((len(theta), 2))
28
+ within_bounds = np.logical_and(cond[:, 0] < theta, theta < cond[:, 1])
29
+ if not np.all(within_bounds):
30
+ return np.inf
31
+
32
+ return 0.0
41
33
 
42
34
 
43
35
  def fun_like(
44
- x: ndarray,
45
- y: ndarray,
36
+ x: np.ndarray,
37
+ y: np.ndarray,
46
38
  model: Callable,
47
- theta: ndarray,
39
+ theta: np.ndarray,
48
40
  conditions: List[Tuple[float, float]] = None,
49
41
  var2: float = 1.0,
50
42
  ) -> float:
@@ -57,14 +49,14 @@ def fun_like(
57
49
  y : `np.ndarray`
58
50
  An $n$ dimensional array that will be compared with model's output.
59
51
  model : `Callable`
60
- A Python function defined by the user. This function should recieve
61
- two arguments $(`x`, `theta`)$.
52
+ A Python function defined by the user. This function should receive
53
+ two arguments $(x, theta)$.
62
54
  theta : `np.ndarray`
63
55
  The array containing the model's parameters.
64
- conditions : `list`
56
+ conditions : `list`, optional
65
57
  A list containing $2n$-conditions for the (min, max) range of the
66
- $n$ parameters.
67
- var2 : `float`
58
+ $n$ parameters. Defaults to None.
59
+ var2 : `float`, optional
68
60
  Determines the step size of the walker. By default it is set to `1.0`.
69
61
 
70
62
  Returns
@@ -72,28 +64,25 @@ def fun_like(
72
64
  lhood : `float`
73
65
  The computed likelihood.
74
66
  """
75
-
76
- lp = lnprior(theta, conditions)
77
- inv_sigma2 = 1.0 / (var2)
67
+ lp = 0.0 if conditions is None else lnprior(theta, conditions)
68
+ inv_sigma2 = 1.0 / var2
78
69
  y_hat = model(x, theta)
79
70
 
80
71
  try:
81
72
  y_hat.shape[1]
82
- except:
73
+ except IndexError:
83
74
  y_hat = y_hat[np.newaxis, ...].T
84
75
 
85
76
  y_sum = np.sum((y - y_hat) ** 2 * inv_sigma2 - np.log(inv_sigma2))
86
77
  lhood = 0.5 * y_sum
87
78
 
88
- if not np.isfinite(lp):
89
- lhood = np.inf
90
- else:
91
- lhood += lp
79
+ if not np.isfinite(lhood):
80
+ return np.inf
92
81
 
93
- return lhood
82
+ return lhood + lp
94
83
 
95
84
 
96
- def update_theta(theta: ndarray, d: float) -> ndarray:
85
+ def update_theta(theta: np.ndarray, d: float) -> np.ndarray:
97
86
  """Updates the theta parameters.
98
87
 
99
88
  Parameters
@@ -108,21 +97,18 @@ def update_theta(theta: ndarray, d: float) -> ndarray:
108
97
  theta_new : `np.array`
109
98
  An ndarray with the updated theta values.
110
99
  """
111
-
112
- theta_new = [np.random.normal(theta[k], d / 2.0) for k in range(len(theta))]
113
-
114
- return theta_new
100
+ return np.random.normal(theta, d / 2.0)
115
101
 
116
102
 
117
103
  def walk(
118
- x: ndarray,
119
- y: ndarray,
104
+ x: np.ndarray,
105
+ y: np.ndarray,
120
106
  model: Callable,
121
- theta: ndarray,
107
+ theta: np.ndarray,
122
108
  conditions: List[Tuple[float, float]] = None,
123
109
  var2: float = 0.01,
124
110
  mov: int = 100,
125
- d: int = 1,
111
+ d: float = 1.0,
126
112
  tol: float = 1e-4,
127
113
  mode: bool = True,
128
114
  ):
@@ -135,25 +121,25 @@ def walk(
135
121
  y : np.ndarray
136
122
  An $n$ dimensional array that will be compared with model's output.
137
123
  model : `Callable`
138
- A Python function defined by the user. This function should recieve
124
+ A Python function defined by the user. This function should receive
139
125
  two arguments $(x, theta)$.
140
126
  theta : `np.ndarray`
141
127
  The array containing the model's parameters.
142
- conditions : `list`
128
+ conditions : `list`, optional
143
129
  A list containing $2n$-conditions for the (min, max) range of the
144
- $n$ parameters.
145
- var2 : `float`
130
+ $n$ parameters. Defaults to None.
131
+ var2 : `float`, optional
146
132
  Determines the step size of the walker. By default it is set to `1.0`.
147
- mov : `int`
133
+ mov : `int`, optional
148
134
  Number of movements that walker will perform. By default it is set
149
135
  to `100`.
150
- d : `float`
136
+ d : `float`, optional
151
137
  Size of the Gaussian step for the walker.
152
- tol : `float`
138
+ tol : `float`, optional
153
139
  Convergence criteria for the log-likelihood. By default it is set
154
140
  to `1e-3`.
155
- mode : `bool`
156
- By default it is set to `True`.
141
+ mode : `bool`, optional
142
+ Defaults to `True`.
157
143
 
158
144
  Returns
159
145
  -------
@@ -164,43 +150,29 @@ def walk(
164
150
  y0 : `float`
165
151
  The log-likelihood value.
166
152
  """
167
-
168
- greach = False
169
153
  nwalk = []
170
154
 
171
155
  for i in range(mov):
172
156
  nwalk.append(theta)
173
157
  theta_new = update_theta(theta, d)
174
158
 
175
- if not greach:
176
- y0 = fun_like(x, y, model, theta, conditions, var2)
177
- y1 = fun_like(x, y, model, theta_new, conditions, var2)
178
-
179
- if y0 <= tol and mode:
159
+ y0 = fun_like(x, y, model, theta, conditions, var2)
160
+ y1 = fun_like(x, y, model, theta_new, conditions, var2)
161
+ if y0 <= tol or y1 <= tol:
162
+ if mode:
180
163
  print("Goal reached!")
181
- greach = True
182
-
183
- return theta, nwalk, y0
184
- else:
185
- if y1 <= tol and mode:
186
- print("Goal reached!")
187
- greach = True
188
-
189
- return theta_new, nwalk, y1
190
- else:
191
- ratio = y0 / y1
192
- boltz = np.random.rand(1)
193
- prob = np.exp(-ratio)
194
-
195
- if y1 < y0:
196
- theta = theta_new
197
- theta_new = update_theta(theta, d)
198
- else:
199
- if prob > boltz:
200
- theta = theta_new
201
- theta_new = update_theta(theta, d)
202
- else:
203
- theta_new = update_theta(theta, d)
164
+ return (theta_new, nwalk, y1) if y1 <= tol else (theta, nwalk, y0)
165
+
166
+ if y1 >= y0:
167
+ ratio = y0 / y1
168
+ prob = np.exp(-ratio)
169
+
170
+ if prob > np.random.rand():
171
+ theta = theta_new
172
+ else:
173
+ theta = theta_new
174
+ theta_new = update_theta(theta, d)
175
+
204
176
  if mode:
205
177
  print("Maximum number of iterations reached!")
206
178
  print(f"The log-likelihood is: {y0}")
@@ -210,14 +182,14 @@ def walk(
210
182
 
211
183
  def walkers(
212
184
  nwalkers: int,
213
- x: ndarray,
214
- y: ndarray,
185
+ x: np.ndarray,
186
+ y: np.ndarray,
215
187
  model: Callable,
216
- theta: ndarray,
217
- conditions: bool = None,
188
+ theta: np.ndarray,
189
+ conditions: List[Tuple[float, float]] = None,
218
190
  var2: float = 0.01,
219
191
  mov: int = 100,
220
- d: int = 1,
192
+ d: float = 1.0,
221
193
  tol: float = 1e-4,
222
194
  mode: bool = False,
223
195
  figname: str = "fig_out.png",
@@ -233,27 +205,27 @@ def walkers(
233
205
  y : `np.ndarray`
234
206
  An $n$ dimensional array that will be compared with model's output.
235
207
  model : `Callable`
236
- A Python function defined by the user. This function should recieve
208
+ A Python function defined by the user. This function should receive
237
209
  two arguments $(x, theta)$.
238
210
  theta : `np.ndarray`
239
211
  The array containing the model's parameters.
240
- conditions : `list`
212
+ conditions : `list`, optional
241
213
  A list containing $2n$-conditions for the (min, max) range of the
242
- $n$ parameters.
243
- var2 : `float`
214
+ $n$ parameters. Defaults to None.
215
+ var2 : `float`, optional
244
216
  Determines the step size of the walker. By default it is set to `1.0`.
245
- mov : `int`
217
+ mov : `int`, optional
246
218
  Number of movements that walker will perform. By default it is set
247
219
  to `100`.
248
- d : `float`
220
+ d : `float`, optional
249
221
  Size of the Gaussian step for the walker.
250
- tol : `float`
251
- Convergence criteria for the log-likelihhod. By default it is set
222
+ tol : `float`, optional
223
+ Convergence criteria for the log-likelihood. By default it is set
252
224
  to `1e-3`.
253
- mode : `bool`
225
+ mode : `bool`, optional
254
226
  Specifies that we will be working with more than one walker. By
255
227
  default it is set to `False`.
256
- figname : `str`
228
+ figname : `str`, optional
257
229
  The name of the output file for the figure. By default it is set
258
230
  to `fig_out.png`.
259
231
 
@@ -264,7 +236,6 @@ def walkers(
264
236
  error : `np.array`
265
237
  The log-likelihood array.
266
238
  """
267
-
268
239
  error = []
269
240
  par = []
270
241
 
@@ -274,30 +245,29 @@ def walkers(
274
245
  nwalk = np.array(nwalk).reshape((len(nwalk), len(nwalk[i])))
275
246
  error.append(y0)
276
247
 
277
- if figname != None:
248
+ if figname:
278
249
  for k in range(nwalk.shape[1]):
279
- sub = "$\\theta _{" + str(k) + "}$"
250
+ sub = f"$\\theta _{k}$"
280
251
  plt.plot(range(len(nwalk[:, k])), nwalk[:, k], "-", label=sub)
281
252
  plt.ylabel("$\\theta$")
282
253
  plt.xlabel("iterations")
283
- plt.savefig("walkers_" + figname, dpi=300, transparent=True)
254
+ plt.savefig(f"walkers_{figname}", dpi=300, transparent=True)
284
255
 
285
- if figname != None:
256
+ if figname:
286
257
  plt.show()
287
258
 
288
- if nwalk.shape[1] == 2:
289
- if figname != None:
290
- fig = corner.hist2d(
291
- nwalk[:, 0],
292
- nwalk[:, 1],
293
- range=None,
294
- bins=18,
295
- smooth=True,
296
- plot_datapoints=True,
297
- plot_density=True,
298
- )
299
- plt.ylabel("$\\theta_{1}$")
300
- plt.xlabel("$\\theta_{0}$")
301
- plt.savefig("theta_" + figname, dpi=300, transparent=True)
259
+ if len(theta) == 2 and figname:
260
+ corner.hist2d(
261
+ nwalk[:, 0],
262
+ nwalk[:, 1],
263
+ range=None,
264
+ bins=18,
265
+ smooth=True,
266
+ plot_datapoints=True,
267
+ plot_density=True,
268
+ )
269
+ plt.ylabel("$\\theta_{1}$")
270
+ plt.xlabel("$\\theta_{0}$")
271
+ plt.savefig(f"theta_{figname}", dpi=300, transparent=True)
302
272
 
303
273
  return par, error
@@ -1,3 +1,4 @@
1
+ import logging
1
2
  import os
2
3
  from functools import partial
3
4
  from shutil import rmtree
@@ -6,9 +7,12 @@ import keras_tuner
6
7
  import numpy as np
7
8
  import pandas as pd
8
9
  import tensorflow as tf
9
- from likelihood.tools import OneHotEncoder
10
10
  from pandas.core.frame import DataFrame
11
11
 
12
+ from likelihood.tools import OneHotEncoder
13
+
14
+ logging.getLogger("tensorflow").setLevel(logging.ERROR)
15
+
12
16
  tf.compat.v1.logging.set_verbosity(tf.compat.v1.logging.ERROR)
13
17
 
14
18
 
@@ -141,7 +145,7 @@ def call_existing_code(
141
145
  )
142
146
  model.compile(
143
147
  optimizer=optimizer,
144
- loss="categorical_crossentropy",
148
+ loss=tf.keras.losses.CategoricalCrossentropy(),
145
149
  metrics=[tf.keras.metrics.F1Score(threshold=threshold)],
146
150
  )
147
151
  return model
@@ -250,9 +254,9 @@ def setup_model(
250
254
  if train_mode:
251
255
  # Create a new directory if it does not exist
252
256
  try:
253
- if not os.path.exists(directory):
257
+ if (not os.path.exists(directory)) and directory != "./":
254
258
  os.makedirs(directory)
255
- else:
259
+ elif directory != "./":
256
260
  print(f"Directory {directory} already exists, it will be deleted.")
257
261
  rmtree(directory)
258
262
  os.makedirs(directory)
@@ -8,6 +8,93 @@ from pandas.core.frame import DataFrame
8
8
 
9
9
 
10
10
  # -------------------------------------------------------------------------
11
+ def get_metrics(dataset, actual_column_name, predicted_column_name, verbose=False):
12
+ # Variables to keep track of the number of correct and total predictions
13
+ true_positives = 0 # Correctly predicted positives
14
+ true_negatives = 0 # Correctly predicted negatives
15
+ false_positives = 0 # Negatives predicted as positives
16
+ false_negatives = 0 # Positives predicted as negatives
17
+ total_predictions = len(dataset)
18
+
19
+ # Counters for actual and predicted classes
20
+ actual_positive_count = 0
21
+ actual_negative_count = 0
22
+ predicted_positive_count = 0
23
+ predicted_negative_count = 0
24
+
25
+ for index, row in dataset.iterrows():
26
+ actual_class = row[actual_column_name]
27
+ predicted_class = row[predicted_column_name]
28
+
29
+ # Update confusion matrix counts
30
+ if actual_class == 1 and predicted_class == 1: # True positive
31
+ true_positives += 1
32
+ elif actual_class == 0 and predicted_class == 0: # True negative
33
+ true_negatives += 1
34
+ elif actual_class == 0 and predicted_class == 1: # False positive
35
+ false_positives += 1
36
+ elif actual_class == 1 and predicted_class == 0: # False negative
37
+ false_negatives += 1
38
+
39
+ # Update class counts
40
+ if actual_class == 1:
41
+ actual_positive_count += 1
42
+ else:
43
+ actual_negative_count += 1
44
+
45
+ if predicted_class == 1:
46
+ predicted_positive_count += 1
47
+ else:
48
+ predicted_negative_count += 1
49
+
50
+ # Calculate accuracy
51
+ accuracy = (true_positives + true_negatives) / total_predictions * 100
52
+
53
+ # Calculate precision
54
+ if true_positives + false_positives > 0:
55
+ precision = true_positives / (true_positives + false_positives) * 100
56
+ else:
57
+ precision = 0 # Avoid division by zero
58
+
59
+ # Calculate recall
60
+ if true_positives + false_negatives > 0:
61
+ recall = true_positives / (true_positives + false_negatives) * 100
62
+ else:
63
+ recall = 0 # Avoid division by zero
64
+
65
+ # Calculate F1-Score
66
+ if precision + recall > 0:
67
+ f1_score = 2 * (precision * recall) / (precision + recall)
68
+ else:
69
+ f1_score = 0 # Avoid division by zero
70
+
71
+ coeff_1 = (true_positives + false_positives) * (false_positives + true_negatives)
72
+ coeff_2 = (true_positives + false_negatives) * (false_negatives + true_negatives)
73
+ if coeff_1 + coeff_2 > 0:
74
+ kappa = (
75
+ 2
76
+ * (true_positives * true_negatives - false_negatives * false_positives)
77
+ / (coeff_1 + coeff_2)
78
+ )
79
+
80
+ metrics = {
81
+ "accuracy": accuracy,
82
+ "precision": precision,
83
+ "recall": recall,
84
+ "f1_score": f1_score,
85
+ "kappa": kappa,
86
+ }
87
+
88
+ if verbose:
89
+ print(f"Accuracy: {accuracy:.2f}%")
90
+ print(f"Precision: {precision:.2f}%")
91
+ print(f"Recall: {recall:.2f}%")
92
+ print(f"F1-Score: {f1_score:.2f}")
93
+ print(f"Cohen's Kappa: {kappa:.4f}")
94
+ else:
95
+ return metrics
96
+
97
+
11
98
  def xi_corr(df: pd.DataFrame) -> pd.DataFrame:
12
99
  """Calculate new coefficient of correlation for all pairs of columns in a `DataFrame`.
13
100
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: likelihood
3
- Version: 1.2.20
3
+ Version: 1.2.21
4
4
  Summary: A package that performs the maximum likelihood algorithm.
5
5
  Home-page: https://github.com/jzsmoreno/likelihood/
6
6
  Author: J. A. Moreno-Guerra
File without changes
File without changes
File without changes
File without changes