pyAgrum-nightly 2.3.0.9.dev202512061764412981__cp310-abi3-macosx_11_0_arm64.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.
- pyagrum/__init__.py +165 -0
- pyagrum/_pyagrum.so +0 -0
- pyagrum/bnmixture/BNMInference.py +268 -0
- pyagrum/bnmixture/BNMLearning.py +376 -0
- pyagrum/bnmixture/BNMixture.py +464 -0
- pyagrum/bnmixture/__init__.py +60 -0
- pyagrum/bnmixture/notebook.py +1058 -0
- pyagrum/causal/_CausalFormula.py +280 -0
- pyagrum/causal/_CausalModel.py +436 -0
- pyagrum/causal/__init__.py +81 -0
- pyagrum/causal/_causalImpact.py +356 -0
- pyagrum/causal/_dSeparation.py +598 -0
- pyagrum/causal/_doAST.py +761 -0
- pyagrum/causal/_doCalculus.py +361 -0
- pyagrum/causal/_doorCriteria.py +374 -0
- pyagrum/causal/_exceptions.py +95 -0
- pyagrum/causal/_types.py +61 -0
- pyagrum/causal/causalEffectEstimation/_CausalEffectEstimation.py +1175 -0
- pyagrum/causal/causalEffectEstimation/_IVEstimators.py +718 -0
- pyagrum/causal/causalEffectEstimation/_RCTEstimators.py +132 -0
- pyagrum/causal/causalEffectEstimation/__init__.py +46 -0
- pyagrum/causal/causalEffectEstimation/_backdoorEstimators.py +774 -0
- pyagrum/causal/causalEffectEstimation/_causalBNEstimator.py +324 -0
- pyagrum/causal/causalEffectEstimation/_frontdoorEstimators.py +396 -0
- pyagrum/causal/causalEffectEstimation/_learners.py +118 -0
- pyagrum/causal/causalEffectEstimation/_utils.py +466 -0
- pyagrum/causal/notebook.py +171 -0
- pyagrum/clg/CLG.py +658 -0
- pyagrum/clg/GaussianVariable.py +111 -0
- pyagrum/clg/SEM.py +312 -0
- pyagrum/clg/__init__.py +63 -0
- pyagrum/clg/canonicalForm.py +408 -0
- pyagrum/clg/constants.py +54 -0
- pyagrum/clg/forwardSampling.py +202 -0
- pyagrum/clg/learning.py +776 -0
- pyagrum/clg/notebook.py +480 -0
- pyagrum/clg/variableElimination.py +271 -0
- pyagrum/common.py +60 -0
- pyagrum/config.py +319 -0
- pyagrum/ctbn/CIM.py +513 -0
- pyagrum/ctbn/CTBN.py +573 -0
- pyagrum/ctbn/CTBNGenerator.py +216 -0
- pyagrum/ctbn/CTBNInference.py +459 -0
- pyagrum/ctbn/CTBNLearner.py +161 -0
- pyagrum/ctbn/SamplesStats.py +671 -0
- pyagrum/ctbn/StatsIndepTest.py +355 -0
- pyagrum/ctbn/__init__.py +79 -0
- pyagrum/ctbn/constants.py +54 -0
- pyagrum/ctbn/notebook.py +264 -0
- pyagrum/defaults.ini +199 -0
- pyagrum/deprecated.py +95 -0
- pyagrum/explain/_ComputationCausal.py +75 -0
- pyagrum/explain/_ComputationConditional.py +48 -0
- pyagrum/explain/_ComputationMarginal.py +48 -0
- pyagrum/explain/_CustomShapleyCache.py +110 -0
- pyagrum/explain/_Explainer.py +176 -0
- pyagrum/explain/_Explanation.py +70 -0
- pyagrum/explain/_FIFOCache.py +54 -0
- pyagrum/explain/_ShallCausalValues.py +204 -0
- pyagrum/explain/_ShallConditionalValues.py +155 -0
- pyagrum/explain/_ShallMarginalValues.py +155 -0
- pyagrum/explain/_ShallValues.py +296 -0
- pyagrum/explain/_ShapCausalValues.py +208 -0
- pyagrum/explain/_ShapConditionalValues.py +126 -0
- pyagrum/explain/_ShapMarginalValues.py +191 -0
- pyagrum/explain/_ShapleyValues.py +298 -0
- pyagrum/explain/__init__.py +81 -0
- pyagrum/explain/_explGeneralizedMarkovBlanket.py +152 -0
- pyagrum/explain/_explIndependenceListForPairs.py +146 -0
- pyagrum/explain/_explInformationGraph.py +264 -0
- pyagrum/explain/notebook/__init__.py +54 -0
- pyagrum/explain/notebook/_bar.py +142 -0
- pyagrum/explain/notebook/_beeswarm.py +174 -0
- pyagrum/explain/notebook/_showShapValues.py +97 -0
- pyagrum/explain/notebook/_waterfall.py +220 -0
- pyagrum/explain/shapley.py +225 -0
- pyagrum/lib/__init__.py +46 -0
- pyagrum/lib/_colors.py +390 -0
- pyagrum/lib/bn2graph.py +299 -0
- pyagrum/lib/bn2roc.py +1026 -0
- pyagrum/lib/bn2scores.py +217 -0
- pyagrum/lib/bn_vs_bn.py +605 -0
- pyagrum/lib/cn2graph.py +305 -0
- pyagrum/lib/discreteTypeProcessor.py +1102 -0
- pyagrum/lib/discretizer.py +58 -0
- pyagrum/lib/dynamicBN.py +390 -0
- pyagrum/lib/explain.py +57 -0
- pyagrum/lib/export.py +84 -0
- pyagrum/lib/id2graph.py +258 -0
- pyagrum/lib/image.py +387 -0
- pyagrum/lib/ipython.py +307 -0
- pyagrum/lib/mrf2graph.py +471 -0
- pyagrum/lib/notebook.py +1821 -0
- pyagrum/lib/proba_histogram.py +552 -0
- pyagrum/lib/utils.py +138 -0
- pyagrum/pyagrum.py +31495 -0
- pyagrum/skbn/_MBCalcul.py +242 -0
- pyagrum/skbn/__init__.py +49 -0
- pyagrum/skbn/_learningMethods.py +282 -0
- pyagrum/skbn/_utils.py +297 -0
- pyagrum/skbn/bnclassifier.py +1014 -0
- pyagrum_nightly-2.3.0.9.dev202512061764412981.dist-info/LICENSE.md +12 -0
- pyagrum_nightly-2.3.0.9.dev202512061764412981.dist-info/LICENSES/LGPL-3.0-or-later.txt +304 -0
- pyagrum_nightly-2.3.0.9.dev202512061764412981.dist-info/LICENSES/MIT.txt +18 -0
- pyagrum_nightly-2.3.0.9.dev202512061764412981.dist-info/METADATA +145 -0
- pyagrum_nightly-2.3.0.9.dev202512061764412981.dist-info/RECORD +107 -0
- pyagrum_nightly-2.3.0.9.dev202512061764412981.dist-info/WHEEL +4 -0
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
############################################################################
|
|
2
|
+
# This file is part of the aGrUM/pyAgrum library. #
|
|
3
|
+
# #
|
|
4
|
+
# Copyright (c) 2005-2025 by #
|
|
5
|
+
# - Pierre-Henri WUILLEMIN(_at_LIP6) #
|
|
6
|
+
# - Christophe GONZALES(_at_AMU) #
|
|
7
|
+
# #
|
|
8
|
+
# The aGrUM/pyAgrum library is free software; you can redistribute it #
|
|
9
|
+
# and/or modify it under the terms of either : #
|
|
10
|
+
# #
|
|
11
|
+
# - the GNU Lesser General Public License as published by #
|
|
12
|
+
# the Free Software Foundation, either version 3 of the License, #
|
|
13
|
+
# or (at your option) any later version, #
|
|
14
|
+
# - the MIT license (MIT), #
|
|
15
|
+
# - or both in dual license, as here. #
|
|
16
|
+
# #
|
|
17
|
+
# (see https://agrum.gitlab.io/articles/dual-licenses-lgplv3mit.html) #
|
|
18
|
+
# #
|
|
19
|
+
# This aGrUM/pyAgrum library is distributed in the hope that it will be #
|
|
20
|
+
# useful, but WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, #
|
|
21
|
+
# INCLUDING BUT NOT LIMITED TO THE WARRANTIES MERCHANTABILITY or FITNESS #
|
|
22
|
+
# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE #
|
|
23
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER #
|
|
24
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, #
|
|
25
|
+
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR #
|
|
26
|
+
# OTHER DEALINGS IN THE SOFTWARE. #
|
|
27
|
+
# #
|
|
28
|
+
# See LICENCES for more details. #
|
|
29
|
+
# #
|
|
30
|
+
# SPDX-FileCopyrightText: Copyright 2005-2025 #
|
|
31
|
+
# - Pierre-Henri WUILLEMIN(_at_LIP6) #
|
|
32
|
+
# - Christophe GONZALES(_at_AMU) #
|
|
33
|
+
# SPDX-License-Identifier: LGPL-3.0-or-later OR MIT #
|
|
34
|
+
# #
|
|
35
|
+
# Contact : info_at_agrum_dot_org #
|
|
36
|
+
# homepage : http://agrum.gitlab.io #
|
|
37
|
+
# gitlab : https://gitlab.com/agrumery/agrum #
|
|
38
|
+
# #
|
|
39
|
+
############################################################################
|
|
40
|
+
|
|
41
|
+
from abc import abstractmethod
|
|
42
|
+
from typing import List
|
|
43
|
+
from scipy.stats import f, chi2
|
|
44
|
+
import logging
|
|
45
|
+
import math
|
|
46
|
+
|
|
47
|
+
import pyagrum
|
|
48
|
+
|
|
49
|
+
from pyagrum.ctbn import CIM
|
|
50
|
+
from pyagrum.ctbn import CTBN
|
|
51
|
+
from pyagrum.ctbn.constants import ALPHA, FAIL_TO_REJECT, REJECT
|
|
52
|
+
from pyagrum.ctbn import Trajectory, Stats
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
class IndepTest:
|
|
56
|
+
"""
|
|
57
|
+
Mother class used to test independance between 2 variables knowing some other parents.
|
|
58
|
+
"""
|
|
59
|
+
|
|
60
|
+
@abstractmethod
|
|
61
|
+
def testIndep(self, X: str, Y: str, U: List[str]) -> bool:
|
|
62
|
+
"""
|
|
63
|
+
Parameters
|
|
64
|
+
----------
|
|
65
|
+
X : str
|
|
66
|
+
Head of the arc we want to test.
|
|
67
|
+
Y : str
|
|
68
|
+
Tail of the arc we want to test.
|
|
69
|
+
U : List[str]
|
|
70
|
+
Known parents.
|
|
71
|
+
"""
|
|
72
|
+
pass
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
class Oracle(IndepTest):
|
|
76
|
+
"""
|
|
77
|
+
Oracle's testing tools.
|
|
78
|
+
|
|
79
|
+
Parameters
|
|
80
|
+
----------
|
|
81
|
+
ctbn : CTBN
|
|
82
|
+
"""
|
|
83
|
+
|
|
84
|
+
def __init__(self, ctbn: CTBN):
|
|
85
|
+
super().__init__()
|
|
86
|
+
self.ctbn = ctbn
|
|
87
|
+
|
|
88
|
+
def testIndep(self, X: str, Y: str, U: List[str]) -> bool:
|
|
89
|
+
"""
|
|
90
|
+
Parameters
|
|
91
|
+
----------
|
|
92
|
+
X : str
|
|
93
|
+
Head of the arc we want to test.
|
|
94
|
+
Y : str
|
|
95
|
+
Tail of the arc we want to test.
|
|
96
|
+
U : List[str]
|
|
97
|
+
Known parents.
|
|
98
|
+
|
|
99
|
+
Returns
|
|
100
|
+
-------
|
|
101
|
+
bool
|
|
102
|
+
False if there is an arc from Y to X knowing U, True otherwise.
|
|
103
|
+
"""
|
|
104
|
+
return not self.ctbn.graph.existsArc(self.ctbn.name2id[Y], self.ctbn.name2id[X])
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def sqrtTensor(tensor: pyagrum.Tensor) -> "pyagrum.Tensor":
|
|
108
|
+
"""
|
|
109
|
+
Applies sqrt function to all values inside the tensor.
|
|
110
|
+
|
|
111
|
+
Parameters
|
|
112
|
+
----------
|
|
113
|
+
tensor : pyagrum.Tensor
|
|
114
|
+
tensor to play sqrt to.
|
|
115
|
+
|
|
116
|
+
Returns
|
|
117
|
+
-------
|
|
118
|
+
pyagrum.Tensor
|
|
119
|
+
sqrt of tensor.
|
|
120
|
+
"""
|
|
121
|
+
res = pyagrum.Tensor(tensor)
|
|
122
|
+
i: pyagrum.Instantiation = pyagrum.Instantiation(res)
|
|
123
|
+
i.setFirst()
|
|
124
|
+
while not i.end():
|
|
125
|
+
res.set(i, math.sqrt(res.get(i)))
|
|
126
|
+
i.inc()
|
|
127
|
+
|
|
128
|
+
return res
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
class FChi2Test(IndepTest):
|
|
132
|
+
"""
|
|
133
|
+
This class use 2 independence tests : Fisher Test (F-test) and chi2 Test.
|
|
134
|
+
To test independence between 2 variables, we first consider them independent. There is independence until
|
|
135
|
+
one of the 2 tests (F and chi2) contradict the independence hypothesis. If the hyopothesis is not rejected,
|
|
136
|
+
the variables are considered independent.
|
|
137
|
+
|
|
138
|
+
Parameters
|
|
139
|
+
----------
|
|
140
|
+
tr : Trajectory
|
|
141
|
+
Samples used to extract stats.
|
|
142
|
+
"""
|
|
143
|
+
|
|
144
|
+
def __init__(self, tr: Trajectory):
|
|
145
|
+
self.tr = tr
|
|
146
|
+
self.stats_added = False
|
|
147
|
+
self.chiSqValue = None
|
|
148
|
+
|
|
149
|
+
def addVariables(self, X: str, Y: str, U: List[str]):
|
|
150
|
+
"""
|
|
151
|
+
Saves variables ``X`` and ``Y`` and the conditioning set ``U``, and generates stats to be used in statistical tests.
|
|
152
|
+
|
|
153
|
+
Parameters
|
|
154
|
+
----------
|
|
155
|
+
X : str
|
|
156
|
+
Name of the variable.
|
|
157
|
+
Y : str
|
|
158
|
+
Name of the variable to test independence from, not in ``U``.
|
|
159
|
+
U : List[str]
|
|
160
|
+
List of conditioning variables.
|
|
161
|
+
"""
|
|
162
|
+
self.stats: Stats = Stats(self.tr, X, Y, U)
|
|
163
|
+
|
|
164
|
+
# logging.debug("Means: %s\n%s", self.stats.Qxy, self.stats.Qx)
|
|
165
|
+
|
|
166
|
+
self.x_from: str = CIM.varI(X)
|
|
167
|
+
self.x_to: str = CIM.varJ(X)
|
|
168
|
+
|
|
169
|
+
self.r1: pyagrum.Tensor = self.stats.Mxy.sumOut([self.x_to])
|
|
170
|
+
self.r2: pyagrum.Tensor = self.stats.Mx.sumOut([self.x_to])
|
|
171
|
+
|
|
172
|
+
logging.debug("Qx\n%s", str(self.stats.Qx))
|
|
173
|
+
logging.debug("Qx,y\n%s", str(self.stats.Qxy))
|
|
174
|
+
logging.debug("Mxx\n%s", str(self.stats.Mxy))
|
|
175
|
+
|
|
176
|
+
self.stats_added = True
|
|
177
|
+
self.chiSqValue = None
|
|
178
|
+
self._X: str = X
|
|
179
|
+
self._Y: str = Y
|
|
180
|
+
self._U: List[str] = U
|
|
181
|
+
|
|
182
|
+
def testIndep(self, X: str, Y: str, U: List[str]) -> bool:
|
|
183
|
+
"""
|
|
184
|
+
Parameters
|
|
185
|
+
----------
|
|
186
|
+
X : str
|
|
187
|
+
Name of the variable.
|
|
188
|
+
Y : str
|
|
189
|
+
Name of the variable to test independence from, not in ``U``.
|
|
190
|
+
U : List[str]
|
|
191
|
+
List of conditioning variables.
|
|
192
|
+
|
|
193
|
+
Returns
|
|
194
|
+
-------
|
|
195
|
+
bool
|
|
196
|
+
true if ``X`` is independent to ``Y`` given ``U``, otherwise false.
|
|
197
|
+
"""
|
|
198
|
+
if not self.stats_added or self._X != X or self._Y != Y or set(self._U) != set(U):
|
|
199
|
+
self.addVariables(X, Y, U)
|
|
200
|
+
|
|
201
|
+
chi2_is_relevant: bool = len(self.stats.Mx.variable(CIM.varI(X)).labels()) >= 3
|
|
202
|
+
|
|
203
|
+
if self.nullTimeToTransitionHypothesisF(X, Y, U) == REJECT:
|
|
204
|
+
return False
|
|
205
|
+
if chi2_is_relevant and not self.nullStateToStateTransitionHypothesisChi2(X, Y, U):
|
|
206
|
+
return False
|
|
207
|
+
|
|
208
|
+
return True
|
|
209
|
+
|
|
210
|
+
def getMxxGivenU(self, M: pyagrum.Tensor, Y: str) -> "pyagrum.Tensor":
|
|
211
|
+
"""
|
|
212
|
+
Parameters
|
|
213
|
+
----------
|
|
214
|
+
M : pyagrum.Tensor
|
|
215
|
+
A matrix M_{x, x' | y, U}, for some instantiation U of the conditioning set and y of a specific parent.
|
|
216
|
+
Y : str
|
|
217
|
+
A parent.
|
|
218
|
+
|
|
219
|
+
Returns
|
|
220
|
+
-------
|
|
221
|
+
pyagrum.Tensor
|
|
222
|
+
The tensor M_{x, x' | U} by summing over all values of y.
|
|
223
|
+
"""
|
|
224
|
+
return M.sumOut([Y])
|
|
225
|
+
|
|
226
|
+
def computeF(self) -> "pyagrum.Tensor":
|
|
227
|
+
"""
|
|
228
|
+
Compute F-test value for every instance of the variables.
|
|
229
|
+
|
|
230
|
+
Returns
|
|
231
|
+
-------
|
|
232
|
+
pyagrum.Tensor
|
|
233
|
+
F-test value.
|
|
234
|
+
"""
|
|
235
|
+
F: pyagrum.Tensor = self.stats.Qx / self.stats.Qxy
|
|
236
|
+
return F
|
|
237
|
+
|
|
238
|
+
def computeChi2(self) -> "pyagrum.Tensor":
|
|
239
|
+
"""
|
|
240
|
+
Compute chi2-test value for every instance of the variables.
|
|
241
|
+
|
|
242
|
+
Returns
|
|
243
|
+
-------
|
|
244
|
+
pyagrum.Tensor
|
|
245
|
+
chi2-test value.
|
|
246
|
+
"""
|
|
247
|
+
Ksq: pyagrum.Tensor = self.r2 / self.r1
|
|
248
|
+
Lsq: pyagrum.Tensor = self.r1 / self.r2
|
|
249
|
+
|
|
250
|
+
logging.debug("r1:\n%s", self.r1)
|
|
251
|
+
logging.debug("r2:\n%s", self.r2)
|
|
252
|
+
logging.debug("Ksq:\n%s", Ksq)
|
|
253
|
+
logging.debug("Lsq:\n%s", Lsq)
|
|
254
|
+
|
|
255
|
+
K = sqrtTensor(Ksq)
|
|
256
|
+
L = sqrtTensor(Lsq)
|
|
257
|
+
|
|
258
|
+
logging.debug("K:\n%s", K)
|
|
259
|
+
logging.debug("L:\n%s", L)
|
|
260
|
+
|
|
261
|
+
T: pyagrum.Tensor = ((K * self.stats.Mxy - L * self.stats.Mx).sq()) / (self.stats.Mxy + self.stats.Mx)
|
|
262
|
+
|
|
263
|
+
logging.debug("T before:\n%s", T)
|
|
264
|
+
i: pyagrum.Instantiation
|
|
265
|
+
for i in T.loopIn():
|
|
266
|
+
if i[self.x_from] == i[self.x_to]:
|
|
267
|
+
T.set(i, 0)
|
|
268
|
+
|
|
269
|
+
logging.debug("T:\n%s", T)
|
|
270
|
+
|
|
271
|
+
self.chiSqValue: pyagrum.Tensor = T.sumOut(self.x_to)
|
|
272
|
+
|
|
273
|
+
return self.chiSqValue
|
|
274
|
+
|
|
275
|
+
def nullTimeToTransitionHypothesisF(self, X: str, Y: str, _: List[str]) -> bool:
|
|
276
|
+
"""
|
|
277
|
+
Decides if the null time to transition hypothesis is rejected using F-test.
|
|
278
|
+
|
|
279
|
+
Parameters
|
|
280
|
+
----------
|
|
281
|
+
X : str
|
|
282
|
+
A random variable.
|
|
283
|
+
Y : str
|
|
284
|
+
A parent of ``X``.
|
|
285
|
+
_: List[str]
|
|
286
|
+
A subset of the parents of ``X`` that does not contain ``Y``.
|
|
287
|
+
|
|
288
|
+
Returns
|
|
289
|
+
-------
|
|
290
|
+
bool
|
|
291
|
+
False if ``X`` is not independent of ``Y`` given the conditioning set ``U``.
|
|
292
|
+
"""
|
|
293
|
+
logging.debug("PERFORMING F TEST")
|
|
294
|
+
|
|
295
|
+
F: pyagrum.Tensor = self.computeF()
|
|
296
|
+
|
|
297
|
+
logging.debug("F\n%s", F)
|
|
298
|
+
|
|
299
|
+
rej = False
|
|
300
|
+
i: pyagrum.Instantiation
|
|
301
|
+
for i in F.loopIn():
|
|
302
|
+
max_f = f.ppf(ALPHA, self.r1.get(i), self.r2.get(i))
|
|
303
|
+
min_f = f.ppf(1 - ALPHA, self.r1.get(i), self.r2.get(i))
|
|
304
|
+
logging.debug("\t%f, %f, %f", F.get(i), min_f, max_f)
|
|
305
|
+
if not (min_f <= F.get(i) <= max_f):
|
|
306
|
+
# Reject the hypothesis
|
|
307
|
+
rej = True
|
|
308
|
+
break
|
|
309
|
+
|
|
310
|
+
if rej:
|
|
311
|
+
return REJECT
|
|
312
|
+
|
|
313
|
+
# Fail to reject the hypothesis
|
|
314
|
+
return FAIL_TO_REJECT
|
|
315
|
+
|
|
316
|
+
def nullStateToStateTransitionHypothesisChi2(self, X: str, Y: str, _: List[str]):
|
|
317
|
+
"""
|
|
318
|
+
Decides if the null state to state transition hypothesis is rejected using chi2-test.
|
|
319
|
+
|
|
320
|
+
Parameters
|
|
321
|
+
----------
|
|
322
|
+
X : str
|
|
323
|
+
A random variable.
|
|
324
|
+
Y : str
|
|
325
|
+
A parent of ``X``.
|
|
326
|
+
_: List[str]
|
|
327
|
+
A subset of the parents of ``X`` that does not contain ``Y``.
|
|
328
|
+
|
|
329
|
+
Returns
|
|
330
|
+
-------
|
|
331
|
+
bool
|
|
332
|
+
False if ``X`` is not independent of ``Y`` given the conditioning set ``U``.
|
|
333
|
+
"""
|
|
334
|
+
logging.debug("PERFORMING CHI2 TEST")
|
|
335
|
+
|
|
336
|
+
card_val_x = len(self.tr.ctbn.variable(X).labels())
|
|
337
|
+
|
|
338
|
+
chiSqValue: pyagrum.Tensor = self.computeChi2()
|
|
339
|
+
|
|
340
|
+
degrees_of_freedom: int = card_val_x - 1
|
|
341
|
+
max_chi2 = chi2.ppf(ALPHA, degrees_of_freedom)
|
|
342
|
+
|
|
343
|
+
logging.debug("max chi2: %f", max_chi2)
|
|
344
|
+
logging.debug(chiSqValue)
|
|
345
|
+
|
|
346
|
+
i: pyagrum.Instantiation
|
|
347
|
+
for i in chiSqValue.loopIn():
|
|
348
|
+
if chiSqValue.get(i) > max_chi2:
|
|
349
|
+
logging.debug(i)
|
|
350
|
+
logging.debug("\tRejecting the hypothesis: %s is NOT independent to %s given the conditioning set.", X, Y)
|
|
351
|
+
# X is NOT independent of Y
|
|
352
|
+
return False
|
|
353
|
+
|
|
354
|
+
logging.debug("Confirming the hypothesis: %s IS independent to %s given the conditioning set.", X, Y)
|
|
355
|
+
return True
|
pyagrum/ctbn/__init__.py
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
############################################################################
|
|
2
|
+
# This file is part of the aGrUM/pyAgrum library. #
|
|
3
|
+
# #
|
|
4
|
+
# Copyright (c) 2005-2025 by #
|
|
5
|
+
# - Pierre-Henri WUILLEMIN(_at_LIP6) #
|
|
6
|
+
# - Christophe GONZALES(_at_AMU) #
|
|
7
|
+
# #
|
|
8
|
+
# The aGrUM/pyAgrum library is free software; you can redistribute it #
|
|
9
|
+
# and/or modify it under the terms of either : #
|
|
10
|
+
# #
|
|
11
|
+
# - the GNU Lesser General Public License as published by #
|
|
12
|
+
# the Free Software Foundation, either version 3 of the License, #
|
|
13
|
+
# or (at your option) any later version, #
|
|
14
|
+
# - the MIT license (MIT), #
|
|
15
|
+
# - or both in dual license, as here. #
|
|
16
|
+
# #
|
|
17
|
+
# (see https://agrum.gitlab.io/articles/dual-licenses-lgplv3mit.html) #
|
|
18
|
+
# #
|
|
19
|
+
# This aGrUM/pyAgrum library is distributed in the hope that it will be #
|
|
20
|
+
# useful, but WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, #
|
|
21
|
+
# INCLUDING BUT NOT LIMITED TO THE WARRANTIES MERCHANTABILITY or FITNESS #
|
|
22
|
+
# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE #
|
|
23
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER #
|
|
24
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, #
|
|
25
|
+
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR #
|
|
26
|
+
# OTHER DEALINGS IN THE SOFTWARE. #
|
|
27
|
+
# #
|
|
28
|
+
# See LICENCES for more details. #
|
|
29
|
+
# #
|
|
30
|
+
# SPDX-FileCopyrightText: Copyright 2005-2025 #
|
|
31
|
+
# - Pierre-Henri WUILLEMIN(_at_LIP6) #
|
|
32
|
+
# - Christophe GONZALES(_at_AMU) #
|
|
33
|
+
# SPDX-License-Identifier: LGPL-3.0-or-later OR MIT #
|
|
34
|
+
# #
|
|
35
|
+
# Contact : info_at_agrum_dot_org #
|
|
36
|
+
# homepage : http://agrum.gitlab.io #
|
|
37
|
+
# gitlab : https://gitlab.com/agrumery/agrum #
|
|
38
|
+
# #
|
|
39
|
+
############################################################################
|
|
40
|
+
|
|
41
|
+
""" """
|
|
42
|
+
|
|
43
|
+
__author__ = "Pierre-Henri Wuillemin, Rodolphe Tavernier"
|
|
44
|
+
__copyright__ = "(c) 2022-2023 PARIS"
|
|
45
|
+
|
|
46
|
+
from .CIM import CIM
|
|
47
|
+
from .CTBN import CTBN
|
|
48
|
+
from .CTBNGenerator import randomCTBN
|
|
49
|
+
from .CTBNInference import CTBNInference, SimpleInference, ForwardSamplingInference
|
|
50
|
+
from .SamplesStats import (
|
|
51
|
+
readTrajectoryCSV,
|
|
52
|
+
CTBNFromData,
|
|
53
|
+
computeCIMFromStats,
|
|
54
|
+
Trajectory,
|
|
55
|
+
Stats,
|
|
56
|
+
plotTrajectory,
|
|
57
|
+
plotFollowVar,
|
|
58
|
+
)
|
|
59
|
+
from .StatsIndepTest import IndepTest, FChi2Test
|
|
60
|
+
from .CTBNLearner import Learner
|
|
61
|
+
|
|
62
|
+
__all__ = [
|
|
63
|
+
"CIM",
|
|
64
|
+
"CTBN",
|
|
65
|
+
"randomCTBN",
|
|
66
|
+
"CTBNInference",
|
|
67
|
+
"SimpleInference",
|
|
68
|
+
"ForwardSamplingInference",
|
|
69
|
+
"readTrajectoryCSV",
|
|
70
|
+
"CTBNFromData",
|
|
71
|
+
"computeCIMFromStats",
|
|
72
|
+
"Trajectory",
|
|
73
|
+
"Stats",
|
|
74
|
+
"plotTrajectory",
|
|
75
|
+
"plotFollowVar",
|
|
76
|
+
"IndepTest",
|
|
77
|
+
"FChi2Test",
|
|
78
|
+
"Learner",
|
|
79
|
+
]
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
############################################################################
|
|
2
|
+
# This file is part of the aGrUM/pyAgrum library. #
|
|
3
|
+
# #
|
|
4
|
+
# Copyright (c) 2005-2025 by #
|
|
5
|
+
# - Pierre-Henri WUILLEMIN(_at_LIP6) #
|
|
6
|
+
# - Christophe GONZALES(_at_AMU) #
|
|
7
|
+
# #
|
|
8
|
+
# The aGrUM/pyAgrum library is free software; you can redistribute it #
|
|
9
|
+
# and/or modify it under the terms of either : #
|
|
10
|
+
# #
|
|
11
|
+
# - the GNU Lesser General Public License as published by #
|
|
12
|
+
# the Free Software Foundation, either version 3 of the License, #
|
|
13
|
+
# or (at your option) any later version, #
|
|
14
|
+
# - the MIT license (MIT), #
|
|
15
|
+
# - or both in dual license, as here. #
|
|
16
|
+
# #
|
|
17
|
+
# (see https://agrum.gitlab.io/articles/dual-licenses-lgplv3mit.html) #
|
|
18
|
+
# #
|
|
19
|
+
# This aGrUM/pyAgrum library is distributed in the hope that it will be #
|
|
20
|
+
# useful, but WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, #
|
|
21
|
+
# INCLUDING BUT NOT LIMITED TO THE WARRANTIES MERCHANTABILITY or FITNESS #
|
|
22
|
+
# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE #
|
|
23
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER #
|
|
24
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, #
|
|
25
|
+
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR #
|
|
26
|
+
# OTHER DEALINGS IN THE SOFTWARE. #
|
|
27
|
+
# #
|
|
28
|
+
# See LICENCES for more details. #
|
|
29
|
+
# #
|
|
30
|
+
# SPDX-FileCopyrightText: Copyright 2005-2025 #
|
|
31
|
+
# - Pierre-Henri WUILLEMIN(_at_LIP6) #
|
|
32
|
+
# - Christophe GONZALES(_at_AMU) #
|
|
33
|
+
# SPDX-License-Identifier: LGPL-3.0-or-later OR MIT #
|
|
34
|
+
# #
|
|
35
|
+
# Contact : info_at_agrum_dot_org #
|
|
36
|
+
# homepage : http://agrum.gitlab.io #
|
|
37
|
+
# gitlab : https://gitlab.com/agrumery/agrum #
|
|
38
|
+
# #
|
|
39
|
+
############################################################################
|
|
40
|
+
|
|
41
|
+
from typing import List, Union, NewType
|
|
42
|
+
|
|
43
|
+
"""
|
|
44
|
+
This file contains constants and defines types.
|
|
45
|
+
"""
|
|
46
|
+
|
|
47
|
+
ALPHA: float = 0.95
|
|
48
|
+
INFINITY: float = 10e9
|
|
49
|
+
REJECT = True
|
|
50
|
+
FAIL_TO_REJECT = False
|
|
51
|
+
|
|
52
|
+
Domain: type = List[str]
|
|
53
|
+
NodeId: type = NewType("NodeId", int)
|
|
54
|
+
NameOrId: type = Union[str, NodeId]
|