compiled-knowledge 4.1.0a1__cp312-cp312-macosx_11_0_arm64.whl → 4.1.0a3__cp312-cp312-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.

Potentially problematic release.


This version of compiled-knowledge might be problematic. Click here for more details.

Files changed (36) hide show
  1. ck/circuit/_circuit_cy.c +1 -1
  2. ck/circuit/_circuit_cy.cpython-312-darwin.so +0 -0
  3. ck/circuit_compiler/cython_vm_compiler/_compiler.c +152 -152
  4. ck/circuit_compiler/cython_vm_compiler/_compiler.cpython-312-darwin.so +0 -0
  5. ck/circuit_compiler/support/circuit_analyser/_circuit_analyser_cy.c +1 -1
  6. ck/circuit_compiler/support/circuit_analyser/_circuit_analyser_cy.cpython-312-darwin.so +0 -0
  7. ck/dataset/cross_table.py +143 -79
  8. ck/dataset/dataset.py +143 -38
  9. ck/dataset/dataset_builder.py +519 -0
  10. ck/dataset/dataset_from_crosstable.py +21 -2
  11. ck/dataset/dataset_from_csv.py +5 -1
  12. ck/learning/coalesce_cross_tables.py +395 -0
  13. ck/learning/model_from_cross_tables.py +242 -0
  14. ck/learning/parameters.py +117 -0
  15. ck/learning/train_generative_bn.py +198 -0
  16. ck/pgm.py +10 -8
  17. ck/pgm_circuit/marginals_program.py +5 -0
  18. ck/pgm_circuit/wmc_program.py +5 -0
  19. ck/pgm_compiler/support/circuit_table/_circuit_table_cy.c +1 -1
  20. ck/pgm_compiler/support/circuit_table/_circuit_table_cy.cpython-312-darwin.so +0 -0
  21. ck/probability/divergence.py +226 -0
  22. ck/probability/probability_space.py +43 -19
  23. ck_demos/dataset/__init__.py +0 -0
  24. ck_demos/dataset/demo_dataset_builder.py +37 -0
  25. ck_demos/dataset/demo_dataset_from_sampler.py +18 -0
  26. ck_demos/learning/__init__.py +0 -0
  27. ck_demos/learning/demo_bayesian_network_from_cross_tables.py +71 -0
  28. ck_demos/learning/demo_simple_learning.py +55 -0
  29. ck_demos/sampling/demo_wmc_direct_sampler.py +2 -2
  30. {compiled_knowledge-4.1.0a1.dist-info → compiled_knowledge-4.1.0a3.dist-info}/METADATA +2 -1
  31. {compiled_knowledge-4.1.0a1.dist-info → compiled_knowledge-4.1.0a3.dist-info}/RECORD +35 -24
  32. ck/learning/train_generative.py +0 -149
  33. /ck/{dataset/cross_table_probabilities.py → probability/cross_table_probability_space.py} +0 -0
  34. {compiled_knowledge-4.1.0a1.dist-info → compiled_knowledge-4.1.0a3.dist-info}/WHEEL +0 -0
  35. {compiled_knowledge-4.1.0a1.dist-info → compiled_knowledge-4.1.0a3.dist-info}/licenses/LICENSE.txt +0 -0
  36. {compiled_knowledge-4.1.0a1.dist-info → compiled_knowledge-4.1.0a3.dist-info}/top_level.txt +0 -0
@@ -1,3 +1,5 @@
1
+ from __future__ import annotations
2
+
1
3
  import math
2
4
  from abc import ABC, abstractmethod
3
5
  from itertools import chain
@@ -203,16 +205,19 @@ class ProbabilitySpace(ABC):
203
205
  loop_rvs.append([rv[i] for i in sorted(states)])
204
206
  reduced_space = True
205
207
 
208
+ best_probability = float('-inf')
209
+ best_states = None
210
+
206
211
  # If the random variables we are looping over does not have any conditions
207
212
  # then it is expected to be faster by using computed marginal probabilities.
208
213
  if not reduced_space:
209
214
  prs = self.marginal_distribution(*rvs, condition=condition)
210
- best_probability = float('-inf')
211
- best_states = None
212
215
  for probability, inst in zip(prs, rv_instances(*rvs)):
213
216
  if probability > best_probability:
214
217
  best_probability = probability
215
218
  best_states = inst
219
+ if best_states is None:
220
+ return _NAN, ()
216
221
  return best_probability, best_states
217
222
 
218
223
  else:
@@ -220,8 +225,6 @@ class ProbabilitySpace(ABC):
220
225
  new_conditions = tuple(ind for ind in condition if ind.rv_idx not in rv_indexes)
221
226
 
222
227
  # Loop over the state space of the 'loop' rvs
223
- best_probability = float('-inf')
224
- best_states = None
225
228
  indicators: Tuple[Indicator, ...]
226
229
  for indicators in _combos(loop_rvs):
227
230
  probability = self.wmc(*(indicators + new_conditions))
@@ -229,6 +232,8 @@ class ProbabilitySpace(ABC):
229
232
  best_probability = probability
230
233
  best_states = tuple(ind.state_idx for ind in indicators)
231
234
  condition_probability = self.wmc(*condition)
235
+ if best_states is None:
236
+ return _NAN, ()
232
237
  return best_probability / condition_probability, best_states
233
238
 
234
239
  def correlation(self, indicator1: Indicator, indicator2: Indicator, condition: Condition = ()) -> float:
@@ -245,6 +250,20 @@ class ProbabilitySpace(ABC):
245
250
  """
246
251
  condition = check_condition(condition)
247
252
 
253
+ if indicator1.rv_idx == indicator2.rv_idx:
254
+ # Special case - same random variable
255
+ condition_groups: MapSet[int, Indicator] = _group_indicators(condition)
256
+ rv_idx: int = indicator1.rv_idx
257
+ if indicator1 not in condition_groups.get(rv_idx, (indicator1,)):
258
+ return _NAN
259
+ if indicator1 == indicator2:
260
+ return 1
261
+ else:
262
+ if indicator2 not in condition_groups.get(rv_idx, (indicator2,)):
263
+ return _NAN
264
+ else:
265
+ return 0
266
+
248
267
  p1 = self.probability(indicator1, condition=condition)
249
268
  p2 = self.probability(indicator2, condition=condition)
250
269
  p12 = self._joint_probability(indicator1, indicator2, condition=condition)
@@ -267,12 +286,7 @@ class ProbabilitySpace(ABC):
267
286
  entropy of the given random variable.
268
287
  """
269
288
  condition = check_condition(condition)
270
- e = 0.0
271
- for ind in rv:
272
- p = self.probability(ind, condition=condition)
273
- if p > 0.0:
274
- e -= p * math.log2(p)
275
- return e
289
+ return -sum(plogp(self.probability(ind, condition=condition)) for ind in rv)
276
290
 
277
291
  def conditional_entropy(self, rv1: RandomVariable, rv2: RandomVariable, condition: Condition = ()) -> float:
278
292
  """
@@ -309,13 +323,11 @@ class ProbabilitySpace(ABC):
309
323
  joint entropy of the given random variables.
310
324
  """
311
325
  condition = check_condition(condition)
312
- e = 0.0
313
- for ind1 in rv1:
314
- for ind2 in rv2:
315
- p = self._joint_probability(ind1, ind2, condition=condition)
316
- if p > 0.0:
317
- e -= p * math.log2(p)
318
- return e
326
+ return -sum(
327
+ plogp(self._joint_probability(ind1, ind2, condition=condition))
328
+ for ind1 in rv1
329
+ for ind2 in rv2
330
+ )
319
331
 
320
332
  def mutual_information(self, rv1: RandomVariable, rv2: RandomVariable, condition: Condition = ()) -> float:
321
333
  """
@@ -419,8 +431,12 @@ class ProbabilitySpace(ABC):
419
431
  denominator = self.joint_entropy(rv1, rv2, condition=condition)
420
432
  return self._normalised_mutual_information(rv1, rv2, denominator, condition=condition)
421
433
 
422
- def covariant_normalised_mutual_information(self, rv1: RandomVariable, rv2: RandomVariable,
423
- condition: Condition = ()) -> float:
434
+ def covariant_normalised_mutual_information(
435
+ self,
436
+ rv1: RandomVariable,
437
+ rv2: RandomVariable,
438
+ condition: Condition = (),
439
+ ) -> float:
424
440
  """
425
441
  Calculate the covariant normalised mutual information
426
442
  = I(rv1; rv2) / sqrt(H(rv1) * H(rv2)).
@@ -549,6 +565,14 @@ class ProbabilitySpace(ABC):
549
565
  return wmc
550
566
 
551
567
 
568
+ def plogp(p: float) -> float:
569
+ """
570
+ Returns:
571
+ p * log2(p)
572
+ """
573
+ return p * math.log2(p) if p > 0 else 0
574
+
575
+
552
576
  def check_condition(condition: Condition) -> Tuple[Indicator, ...]:
553
577
  """
554
578
  Make the best effort to interpret the given condition.
File without changes
@@ -0,0 +1,37 @@
1
+ from ck.dataset import HardDataset, SoftDataset
2
+ from ck.dataset.dataset_builder import DatasetBuilder, soft_dataset_from_builder, hard_dataset_from_builder
3
+ from ck.pgm import PGM
4
+
5
+
6
+ def main() -> None:
7
+ pgm = PGM()
8
+ x = pgm.new_rv('x', (True, False))
9
+ y = pgm.new_rv('y', ('yes', 'no', 'maybe'))
10
+
11
+ builder = DatasetBuilder([x, y])
12
+ builder.append()
13
+ builder.append(1, 2).weight = 3
14
+ builder.append(None, [0.7, 0.1, 0.2])
15
+ builder.append().set_states(True, 'maybe')
16
+
17
+ print('DatasetBuilder dump')
18
+ builder.dump()
19
+ print()
20
+
21
+ print('DatasetBuilder dump, showing states and custom missing values')
22
+ builder.dump(as_states=True, missing='?')
23
+ print()
24
+
25
+ print('HardDataset dump')
26
+ dataset: HardDataset = hard_dataset_from_builder(builder, missing=99)
27
+ dataset.dump()
28
+ print()
29
+
30
+ print('SoftDataset dump')
31
+ dataset: SoftDataset = soft_dataset_from_builder(builder)
32
+ dataset.dump()
33
+ print()
34
+
35
+
36
+ if __name__ == '__main__':
37
+ main()
@@ -0,0 +1,18 @@
1
+ from ck import example
2
+ from ck.dataset.sampled_dataset import dataset_from_sampler
3
+ from ck.pgm import PGM
4
+ from ck.pgm_circuit.wmc_program import WMCProgram
5
+ from ck.pgm_compiler import DEFAULT_PGM_COMPILER
6
+ from ck.sampling.sampler import Sampler
7
+
8
+
9
+ def main() -> None:
10
+ pgm: PGM = example.Student()
11
+ sampler: Sampler = WMCProgram(DEFAULT_PGM_COMPILER(pgm)).sample_direct()
12
+ dataset = dataset_from_sampler(sampler, 10)
13
+
14
+ dataset.dump()
15
+
16
+
17
+ if __name__ == '__main__':
18
+ main()
File without changes
@@ -0,0 +1,71 @@
1
+ from typing import List, Set
2
+
3
+ from ck import example
4
+ from ck.dataset import HardDataset
5
+ from ck.dataset.cross_table import CrossTable, cross_table_from_hard_dataset
6
+ from ck.dataset.sampled_dataset import dataset_from_sampler
7
+ from ck.learning.model_from_cross_tables import model_from_cross_tables
8
+ from ck.pgm import PGM, RandomVariable
9
+ from ck.pgm_circuit.wmc_program import WMCProgram
10
+ from ck.pgm_compiler import DEFAULT_PGM_COMPILER
11
+ from ck.probability import divergence
12
+
13
+ EXCLUDE_UNNECESSARY_CROSS_TABLES = True
14
+
15
+
16
+ def main() -> None:
17
+ number_of_samples: int = 10000 # How many instances to make for the model dataset
18
+
19
+ # Create a dataset based on model which is an example PGM
20
+ model: PGM = example.Student()
21
+ model_dataset = dataset_from_sampler(
22
+ WMCProgram(DEFAULT_PGM_COMPILER(model)).sample_direct(),
23
+ number_of_samples,
24
+ )
25
+
26
+ # Clone the model, without factors, and transport the dataset to the new PGM
27
+ pgm = PGM()
28
+ dataset = HardDataset(weights=model_dataset.weights)
29
+ for model_rv in model.rvs:
30
+ rv = pgm.new_rv(model_rv.name, model_rv.states)
31
+ dataset.add_rv_from_state_idxs(rv, model_dataset.state_idxs(model_rv))
32
+
33
+ # What model rvs have a child
34
+ model_rvs_with_children: Set[RandomVariable] = set()
35
+ for model_factor in model.factors:
36
+ for parent_rv in model_factor.rvs[1:]:
37
+ model_rvs_with_children.add(parent_rv)
38
+
39
+ # Construct cross-tables from the dataset
40
+ cross_tables: List[CrossTable] = []
41
+ for model_factor in model.factors:
42
+ if (
43
+ EXCLUDE_UNNECESSARY_CROSS_TABLES
44
+ and len(model_factor.rvs) == 1
45
+ and model_factor.rvs[0] in model_rvs_with_children
46
+ ):
47
+ # The factor relates to a single random variable (has
48
+ # no parents) but it does have children.
49
+ # No need to include a cross-table as it is inferable from
50
+ # cross-tables of its children.
51
+ continue
52
+
53
+ rvs = tuple(pgm.rvs[model_rv.idx] for model_rv in model_factor.rvs)
54
+ cross_tables.append(cross_table_from_hard_dataset(dataset, rvs))
55
+ print('cross-table:', *rvs)
56
+
57
+ # Train the PGM
58
+ model_from_cross_tables(pgm, cross_tables)
59
+
60
+ # Show results
61
+ print()
62
+ pgm.dump(show_function_values=True)
63
+ print()
64
+ model_space = WMCProgram(DEFAULT_PGM_COMPILER(model))
65
+ pgm_space = WMCProgram(DEFAULT_PGM_COMPILER(pgm))
66
+ print('HI', divergence.hi(model_space, pgm_space))
67
+ print('KL', divergence.kl(model_space, pgm_space))
68
+
69
+
70
+ if __name__ == '__main__':
71
+ main()
@@ -0,0 +1,55 @@
1
+ from ck.dataset.dataset_from_csv import hard_dataset_from_csv
2
+ from ck.learning.train_generative_bn import train_generative_bn
3
+ from ck.pgm import PGM
4
+
5
+
6
+ def main() -> None:
7
+ pgm = PGM('Student')
8
+
9
+ difficult = pgm.new_rv('difficult', ['y', 'n'])
10
+ intelligent = pgm.new_rv('intelligent', ['y', 'n'])
11
+ grade = pgm.new_rv('grade', ['low', 'medium', 'high'])
12
+ award = pgm.new_rv('award', ['y', 'n'])
13
+ letter = pgm.new_rv('letter', ['y', 'n'])
14
+
15
+ pgm.new_factor(difficult)
16
+ pgm.new_factor(intelligent)
17
+ pgm.new_factor(grade, intelligent, difficult)
18
+ pgm.new_factor(award, intelligent)
19
+ pgm.new_factor(letter, grade)
20
+
21
+ rvs = (difficult, intelligent, grade, award, letter)
22
+ csv = """
23
+ 0,1,2,0,1
24
+ 1,1,2,0,1
25
+ 1,1,2,0,1
26
+ 0,0,2,0,0
27
+ 0,1,1,1,0
28
+ 1,1,1,1,1
29
+ 1,1,0,0,0
30
+ 1,1,0,0,1
31
+ 1,0,0,0,0
32
+ """
33
+
34
+ dataset = hard_dataset_from_csv(rvs, csv.splitlines())
35
+
36
+ # Learn parameters values for `pgm` using the training data `dataset`.
37
+ # This updates the PGMs potential functions.
38
+ train_generative_bn(pgm, dataset)
39
+
40
+ show_pgm_factors(pgm)
41
+
42
+ print('Done.')
43
+
44
+
45
+ def show_pgm_factors(pgm: PGM) -> None:
46
+ for factor in pgm.factors:
47
+ potential_function = factor.function
48
+ print(f'Factor: {factor} {type(potential_function)}')
49
+ for instance, _, param_value in potential_function.keys_with_param:
50
+ print(f'Factor{instance} = {param_value}')
51
+ print()
52
+
53
+
54
+ if __name__ == '__main__':
55
+ main()
@@ -2,7 +2,7 @@ import random
2
2
 
3
3
  from ck import example
4
4
  from ck.pgm import PGM
5
- from ck.pgm_compiler import factor_elimination
5
+ from ck.pgm_compiler import DEFAULT_PGM_COMPILER
6
6
  from ck.pgm_circuit import PGMCircuit
7
7
  from ck.pgm_circuit.wmc_program import WMCProgram
8
8
  from ck.probability.empirical_probability_space import EmpiricalProbabilitySpace
@@ -18,7 +18,7 @@ def main():
18
18
 
19
19
  pgm: PGM = example.Rain()
20
20
 
21
- pgm_cct: PGMCircuit = factor_elimination.compile_pgm(pgm)
21
+ pgm_cct: PGMCircuit = DEFAULT_PGM_COMPILER(pgm)
22
22
  wmc = WMCProgram(pgm_cct)
23
23
  sampler = wmc.sample_direct()
24
24
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: compiled-knowledge
3
- Version: 4.1.0a1
3
+ Version: 4.1.0a3
4
4
  Summary: A Python package for compiling and querying discrete probabilistic graphical models.
5
5
  Author-email: Barry Drake <barry@compiledknowledge.org>
6
6
  License-Expression: MIT
@@ -13,6 +13,7 @@ Description-Content-Type: text/markdown
13
13
  License-File: LICENSE.txt
14
14
  Requires-Dist: llvmlite
15
15
  Requires-Dist: numpy
16
+ Requires-Dist: scipy
16
17
  Dynamic: license-file
17
18
 
18
19
  Compiled Knowledge
@@ -1,11 +1,17 @@
1
1
  ck_demos/all_demos.py,sha256=tqnMFbW6t1F4ksErf6QYTz9XtvbfayWl35lD3Bjm47E,2468
2
2
  ck_demos/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
+ ck_demos/dataset/demo_dataset_from_sampler.py,sha256=N2UDctHWePuUfJNWDnsd-UOSqeRfio6YQI21ZvyYhts,485
4
+ ck_demos/dataset/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
+ ck_demos/dataset/demo_dataset_builder.py,sha256=a9o-rw8PzpLq_5wtwjH0L15-eacbELlc7tfLrREJBqM,987
6
+ ck_demos/learning/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
+ ck_demos/learning/demo_simple_learning.py,sha256=CZPzcsnTD8TK7nzGg3XUsx4exqggQXOT6UVwrV0ScF8,1483
8
+ ck_demos/learning/demo_bayesian_network_from_cross_tables.py,sha256=sUpeUFI8WjveRo8Evz4woWyarrVN84E1DzYcM-2NOy0,2579
3
9
  ck_demos/circuit/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
10
  ck_demos/circuit/demo_derivatives.py,sha256=6VwnW_Dbm2MWQFfJ46UQQFecV56QdfGpL7srthw5Py0,1143
5
11
  ck_demos/circuit/demo_circuit_dump.py,sha256=85x7UJV6cg6XVYU-PPsuKQVTBw5WZBfkhi6Avo9XbOs,436
6
12
  ck_demos/sampling/demo_uniform_sampler.py,sha256=zY5Kz97r43b1YvFz_4xNAeXvSpd7Kc2l0geZhWrz2no,924
7
13
  ck_demos/sampling/check_sampler.py,sha256=9Xy7oS3KnlNzcbdIU3bLnWlQ1SNo6S9hEp3TWoSM6C8,2035
8
- ck_demos/sampling/demo_wmc_direct_sampler.py,sha256=USz7vynHOEYUQgu5dJY-dG_Z_zNEDAfoYJ3VtX6uFmk,1073
14
+ ck_demos/sampling/demo_wmc_direct_sampler.py,sha256=zLwygZ-LNZ_L47XM5czdhCDkj8m8dcq7eZyie-dtmiM,1065
9
15
  ck_demos/sampling/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
16
  ck_demos/sampling/demo_marginal_direct_sampler.py,sha256=nv4smqYl1VhpB6pkF4L_aqnpVgVMcv3FrSvUkJ0EJz0,1109
11
17
  ck_demos/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -52,21 +58,28 @@ ck_demos/pgm_inference/demo_inferencing_mpe_cancer.py,sha256=hS9U2kyqjFgJ8jnVBtT
52
58
  ck_demos/pgm_inference/demo_inferencing_wmc_and_mpe_sprinkler.py,sha256=-q4Z1Fzf7-BuwVFTFXdGRY-zUNrY-SAU7ooaov2o_lM,5128
53
59
  ck_demos/getting_started/simple_demo.py,sha256=hiYscNnfkEwHCQ3ymXAswAYO5jAKR7cseb36pjzuus8,650
54
60
  ck_demos/getting_started/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
55
- ck/pgm.py,sha256=PsB2DboRtuiOrnbYGbYNOB-R2k94iET2o02UalKFy3I,117611
61
+ compiled_knowledge-4.1.0a3.dist-info/RECORD,,
62
+ compiled_knowledge-4.1.0a3.dist-info/WHEEL,sha256=V1loQ6TpxABu1APUg0MoTRBOzSKT5xVc3skizX-ovCU,136
63
+ compiled_knowledge-4.1.0a3.dist-info/top_level.txt,sha256=Cf8DAfd2vcnLiA7HlxoduOzV0Q-8surE3kzX8P9qdks,12
64
+ compiled_knowledge-4.1.0a3.dist-info/METADATA,sha256=GsnkOBTsYHaifQhlQzBzQdrpKIBNWLPhSNuC6sUjET8,1808
65
+ compiled_knowledge-4.1.0a3.dist-info/licenses/LICENSE.txt,sha256=-LmkmqXKYojmS3zDxXAeTbsA82fnHA0KaRvpfIoEdjA,1068
66
+ ck/pgm.py,sha256=EwKTWuYV9-0OfgJQfBw59MfGDLtxFe3wlgbYlkTqj1Y,117703
56
67
  ck/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
57
68
  ck/pgm_circuit/target_marginals_program.py,sha256=qWz9FkAFzt8YHLZJzPkpRnvDH76BXm-dcEWhoqCkrOw,3665
58
69
  ck/pgm_circuit/slot_map.py,sha256=pqN0t5ElmUjR7SzvzldQwnO-jjRIz1rNZHH1PzE-V88,822
59
70
  ck/pgm_circuit/mpe_program.py,sha256=uDOykbBIbvvDQtxXOgBj6gzoehq1AfaQzZIWW3rMZnY,9990
60
71
  ck/pgm_circuit/program_with_slotmap.py,sha256=31Rgk4WoY7KW09L3TGySf1teYnf-ItvICTYEC17zB1w,7808
61
72
  ck/pgm_circuit/__init__.py,sha256=FctIFEYdL1pwxFMMEEu5Rwgq3kjPar-vJTqAmgIqb-I,36
62
- ck/pgm_circuit/marginals_program.py,sha256=E-L-4Rc2YLs3ndXIfXpTxUYGEFJG1_BkaZVDBs9gcgQ,14434
63
- ck/pgm_circuit/wmc_program.py,sha256=Btq7jUot-PodWXrgDFaE6zhUtr6GPUNF217CVLTaB70,12376
73
+ ck/pgm_circuit/marginals_program.py,sha256=SOc31sxk_hNL0QgNQAbdYjVYRf0aOwsiHTh6CSyVsiM,14782
74
+ ck/pgm_circuit/wmc_program.py,sha256=v7DLS2oq34uW5v99fvtadk8CbRSu7gipLA--DxtGSYo,12724
64
75
  ck/pgm_circuit/pgm_circuit.py,sha256=XBXANPREwp5Cl8P0x5XuG9besOJV5DjVxtNkqyt2DK8,3287
65
76
  ck/pgm_circuit/support/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
66
77
  ck/pgm_circuit/support/compile_circuit.py,sha256=XJFzi-BdFNTsdozRv0EHBM8cJ0SUZpbQwuTWONUzGck,3125
67
- ck/probability/probability_space.py,sha256=TTNSe6z40hs94kLBR_YHNjjRvBGVI86tza-CU2FKd9M,25482
78
+ ck/probability/probability_space.py,sha256=fn_z3KWcRyBMF9XqoIE89Kij8-jpcmIjytGdnoNg2os,26125
79
+ ck/probability/cross_table_probability_space.py,sha256=exaAVxzpQkqTmGIQx6ui64p6QTcy66IRYi5eWz6DFiE,1944
68
80
  ck/probability/pgm_probability_space.py,sha256=9al9sZk2LGvnTITvxS8x_ntabHKhaliUW-6JUeAEEl4,1231
69
81
  ck/probability/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
82
+ ck/probability/divergence.py,sha256=l9mhHmCJQWNtY6Xf67ZCBeW1nry0B7-Jec6Tb99DP08,8258
70
83
  ck/probability/empirical_probability_space.py,sha256=Lp7_N_uNYq-W_S5caUC5ub9sTqaL-Vn4hudF0WYXPdU,2088
71
84
  ck/example/survey.py,sha256=ubjM8EP7aQMQbx7XFMaXvSYBOPuUDHeyG6wZIlRDqD8,1565
72
85
  ck/example/pathfinder.py,sha256=rQckvasnbzBYYESxngE_xbhyXxoJlELeiYc6Ghh7iFk,2257125
@@ -100,22 +113,25 @@ ck/example/diamond_square.py,sha256=ic8adEomQHMFlGQ3gMYGEja0LxEla8KEQKhET0XpULs,
100
113
  ck/example/rain.py,sha256=kLTU_9f_-_yy0ymPnS9-cbFVT6fYyCanDgszk3vQOgc,1187
101
114
  ck/example/cancer.py,sha256=-FnLbfb9yxriLl97N5BDZ0VrDZ5UnOWlT-Ep_tzO6QI,1698
102
115
  ck/dataset/dataset_compute.py,sha256=Bdxjl4c_0OttHgVWx-C3WdOI-imgupUQnnQVzNesPCw,5705
103
- ck/dataset/cross_table.py,sha256=KXhkAsMZBKc50V-kHDdj3sxGbEIiqdj72XqvGLCi6cs,9474
116
+ ck/dataset/cross_table.py,sha256=-uBlzapzZ5SKB3Y2OdUs51syZZp4x9805NM3yfLJfk8,13014
104
117
  ck/dataset/__init__.py,sha256=QXCZWPHusMfXtl9bLPrIJP89ZnqWMz9KfdxScVrB3UQ,55
105
- ck/dataset/dataset.py,sha256=929eC2I8x4Nc3OF3sSsbeZ4xFQ-6CaMKPwv7emAVzjo,21121
106
- ck/dataset/dataset_from_crosstable.py,sha256=f-H9Q9G5HF6RRT1ltReuqg69HhnDcrKn8vJrAviyMkA,1278
118
+ ck/dataset/dataset_builder.py,sha256=ewsz6znW_GtBvwsw6k9uXHT8yh_u6zQI5PFBZ_ykXlM,18873
119
+ ck/dataset/dataset.py,sha256=iQGOqVrNll6QMPcRcV2phUbe0fCfpVmUVbcBIaqYx0s,25531
120
+ ck/dataset/dataset_from_crosstable.py,sha256=rOdDFfb_2rnUJT3iZrLbZkeQcRJa5EzFVBs0hSdE57U,2281
107
121
  ck/dataset/sampled_dataset.py,sha256=Vcz2WN6IKdmK8DsFeXLten7Id3Kc2epC6qs2ZW7mvWU,3261
108
- ck/dataset/dataset_from_csv.py,sha256=wzDjGtMEgvrfrMRdddYhJJQ53QhMM6t9_nhrA7EpB3I,5551
109
- ck/dataset/cross_table_probabilities.py,sha256=exaAVxzpQkqTmGIQx6ui64p6QTcy66IRYi5eWz6DFiE,1944
110
- ck/learning/train_generative.py,sha256=_mXWcslgW1Tqfv1o0HhHDnU4CI7_KOUMdpxypQD3tQs,5551
122
+ ck/dataset/dataset_from_csv.py,sha256=q4qjOsJFYAmw22xDaHcS6XC3nwqmkT-RoOaRNr_zJ8I,5802
123
+ ck/learning/model_from_cross_tables.py,sha256=nB4dCsGgFtTMS-WaNvlJjzKCvRbs7uTUUxFQr5EcGG4,9083
111
124
  ck/learning/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
112
- ck/circuit/_circuit_cy.c,sha256=EGE0-TkFq-i7AbXZEqs04yxFwdez8u-RmSy-j7Siskk,1704292
125
+ ck/learning/parameters.py,sha256=x5yP-zxkpm0HfBusOxK5vImUnYanUJeZUjxgOwKNVAc,4388
126
+ ck/learning/coalesce_cross_tables.py,sha256=dQcHXasQU1bEmTCLuiuCVDHEIRt77BNbFp1E5y-qfaI,12926
127
+ ck/learning/train_generative_bn.py,sha256=hwmhbg4RKh3JvDlG7xOJm1apScXJ1Mmfgu4nasM-cwQ,8019
128
+ ck/circuit/_circuit_cy.c,sha256=aUtvxUkF49UVCUYoFIuvdVRUgW9iBIBorKLciPlRaMA,1704292
113
129
  ck/circuit/_circuit_cy.pyx,sha256=mER1HK5yyf4UAj9ibn7fUQNyXwoxwxp7PClULPhY9B4,26995
114
130
  ck/circuit/__init__.py,sha256=B1jwDE_Xb6hOQE8DecjaTVotOnDxJaT7jsvPfGDXqCU,401
115
131
  ck/circuit/_circuit_cy.pxd,sha256=ZcW8xjw4oGQqD5gwz73GXc1H8NxpdAswFWzc2CUWWcA,1025
116
132
  ck/circuit/_circuit_py.py,sha256=hADjCFDC1LJKUdyiKZzNLFt7ZkUNJ0IYwEYRj594K4g,27495
117
133
  ck/circuit/tmp_const.py,sha256=q01bkIvTEg1l-qFcfl2B8NrSzKlqcWU7McNm4HKv7bU,2300
118
- ck/circuit/_circuit_cy.cpython-312-darwin.so,sha256=vgIJ6FY91q20TS23uceX0XnuEtp8r2_pzxyhys0xyNc,335296
134
+ ck/circuit/_circuit_cy.cpython-312-darwin.so,sha256=vHyDzjVhhIfFWG3m4vFqZkdh09lq25c22SUOcIVrDtE,335296
119
135
  ck/sampling/wmc_metropolis_sampler.py,sha256=jfXb-MG0jAoMyepgq9zel2amqK-gmYrCtKuxJStl8VY,6305
120
136
  ck/sampling/wmc_direct_sampler.py,sha256=Pkv-u4GjN3npBrcQ92raoTrEIel1vpiDoE8LrlcfYJE,7094
121
137
  ck/sampling/sampler_support.py,sha256=AD47QPXlXSTiy7Jm-adD6US3cYeSwBimOY2jB5b2qn4,9534
@@ -148,8 +164,8 @@ ck/pgm_compiler/support/named_compiler_maker.py,sha256=Qz8a9gwY46Q3dtRCZEZ2czq5z
148
164
  ck/pgm_compiler/support/circuit_table/__init__.py,sha256=1kWjAZR5Rj6PYNdbCEbuyE2VtIDQU4Qf-3HPFzBlezs,562
149
165
  ck/pgm_compiler/support/circuit_table/_circuit_table_cy.pyx,sha256=Fsjw8P9clKQioqlLyr1JirUK5oYkeotpDMy5sMo7Khk,11683
150
166
  ck/pgm_compiler/support/circuit_table/_circuit_table_py.py,sha256=OZJC-JGX3ovCSv7nJtNYq7735KZ2eb4TQOlZdZbhPmk,10983
151
- ck/pgm_compiler/support/circuit_table/_circuit_table_cy.c,sha256=wLdeh90m24Mp9Vo_-rHra8HRlIRg_-AIzlr1vof5abE,714044
152
- ck/pgm_compiler/support/circuit_table/_circuit_table_cy.cpython-312-darwin.so,sha256=7CKogglc_wM9o6w6t4UlrPGeA2pPq-qPC-RqM2V6-IY,165096
167
+ ck/pgm_compiler/support/circuit_table/_circuit_table_cy.c,sha256=Ga_LmT5hlGc_mn8muLefX9zdt3vXEMiZDUxtMOLTKFU,714044
168
+ ck/pgm_compiler/support/circuit_table/_circuit_table_cy.cpython-312-darwin.so,sha256=AupPKDwtObM-KjI_dNhVC46hsCE3lKCNU86ArZJKbFo,165096
153
169
  ck/pgm_compiler/ace/ace.py,sha256=An83dHxE_gQFcEs6H5qgm0PlNFnJSGGuvLJNC2H3hGU,10098
154
170
  ck/pgm_compiler/ace/__init__.py,sha256=5HWep-yL1Mr6z5VWEaIYpLumCdeso85J-l_-hQaVusM,96
155
171
  ck/program/raw_program.py,sha256=U7kLBCSLtP1CfG09RrzmGo7E3sZdNr7wr2V1qkTfVGc,4106
@@ -165,15 +181,15 @@ ck/circuit_compiler/llvm_vm_compiler.py,sha256=rM_6F5st3k9X5K1_MwzKJwDhQo1794voo
165
181
  ck/circuit_compiler/cython_vm_compiler/cython_vm_compiler.py,sha256=GdtBkipud8vylXYArOJvZ-10U9L_PL0oJrkyrnFGH2Q,4345
166
182
  ck/circuit_compiler/cython_vm_compiler/__init__.py,sha256=ks0sISOJ-XHIHgHnESyFsheNWvcSJQkbsrj1wVlnzTE,48
167
183
  ck/circuit_compiler/cython_vm_compiler/_compiler.pyx,sha256=RssdkoAcB3Ahes8xisqFy0PQyOPmC3GLEC2xR-miQaE,12898
168
- ck/circuit_compiler/cython_vm_compiler/_compiler.cpython-312-darwin.so,sha256=y4HfSLn8gXs9J5nG85cRYRTVSoTiCDG4XUe4DIOkeng,163488
169
- ck/circuit_compiler/cython_vm_compiler/_compiler.c,sha256=GWW9MMB1dCN2Mc4YBszRtsmAxsTuJ3Mf1TxzuSuByLE,857789
184
+ ck/circuit_compiler/cython_vm_compiler/_compiler.cpython-312-darwin.so,sha256=2wyk0kvPM3Fh5jhKb4vYxEjNXmugaqPSDMwsVA7Ss9c,163488
185
+ ck/circuit_compiler/cython_vm_compiler/_compiler.c,sha256=BQYbYiuXvCtEBoKnQZIRfX7pMcCsZ0zTg1BVrGxMDc0,857789
170
186
  ck/circuit_compiler/support/llvm_ir_function.py,sha256=sMLKfwz90YcsrVyxsuY0Ymo1ibFOcul4Qiwdake-VkI,8321
171
187
  ck/circuit_compiler/support/input_vars.py,sha256=EZrvyhD9XVtf5GuDBluFNWhAOVixP7-_ETxAHLTpBcs,4664
172
188
  ck/circuit_compiler/support/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
173
189
  ck/circuit_compiler/support/circuit_analyser/_circuit_analyser_cy.pyx,sha256=a0fKmkwRNscJmy6qoO2AOqJYmHYptrQmkRSrDg3G-wg,3233
174
190
  ck/circuit_compiler/support/circuit_analyser/__init__.py,sha256=WhNwfg7GHVeI4k_m7owPGWxX0MyZg_wtcp2MA07qbWg,523
175
- ck/circuit_compiler/support/circuit_analyser/_circuit_analyser_cy.cpython-312-darwin.so,sha256=h-xNWP4PJgtB6E_CsiYvP9seLXYkdFit_sixZvmJpEA,104936
176
- ck/circuit_compiler/support/circuit_analyser/_circuit_analyser_cy.c,sha256=MQoSbJVg537-Uexx2X-9WGPs3xt4xO07ehW5NZQ_2R8,438223
191
+ ck/circuit_compiler/support/circuit_analyser/_circuit_analyser_cy.cpython-312-darwin.so,sha256=uJDX2rKQ7KKz5JJ2SHRfAH2c8ZA_fJIXn_l688fFUAo,104936
192
+ ck/circuit_compiler/support/circuit_analyser/_circuit_analyser_cy.c,sha256=R9IDuwbPkxUv9Xne8j_ulU0Dd3eXhY2hq5I1XmjnbUk,438223
177
193
  ck/circuit_compiler/support/circuit_analyser/_circuit_analyser_py.py,sha256=CMdXV6Rot5CCoK1UsurQdGK0UOx_09B6V7mCc_6-gfI,2993
178
194
  ck/in_out/render_net.py,sha256=VePvN6aYWuzEkW-Hv-qGT9QneOvsnrBMmS_KYueuj2I,4970
179
195
  ck/in_out/render_bugs.py,sha256=c39KbaD4gEiauFsZq2KUhDEEa-3cuY5kuvz97pEWVpw,3272
@@ -185,8 +201,3 @@ ck/in_out/render_pomegranate.py,sha256=tU7iDHkLWTJyFrxPa2LbZnD06qia8mG2FGi0aZAKu
185
201
  ck/in_out/parse_ace_nnf.py,sha256=faTCrCeuc-m_EUHNJFAg9IItZJ77-bvPzSbLYBeDFaw,13028
186
202
  ck/in_out/pgm_pickle.py,sha256=UhGCDHGVNEDtTwZjcCWyUWw00YXVgBGxek4fbBvLExs,962
187
203
  ck/in_out/pgm_python.py,sha256=6dnF9gzVdMrY0kkdsPg-ryVBwfmAo4bKoTwx17ociGg,9824
188
- compiled_knowledge-4.1.0a1.dist-info/RECORD,,
189
- compiled_knowledge-4.1.0a1.dist-info/WHEEL,sha256=V1loQ6TpxABu1APUg0MoTRBOzSKT5xVc3skizX-ovCU,136
190
- compiled_knowledge-4.1.0a1.dist-info/top_level.txt,sha256=Cf8DAfd2vcnLiA7HlxoduOzV0Q-8surE3kzX8P9qdks,12
191
- compiled_knowledge-4.1.0a1.dist-info/METADATA,sha256=2MW6jH05yr21k1jcKhFjlBQs4bVg4GtByq6zrhtzzDU,1787
192
- compiled_knowledge-4.1.0a1.dist-info/licenses/LICENSE.txt,sha256=-LmkmqXKYojmS3zDxXAeTbsA82fnHA0KaRvpfIoEdjA,1068
@@ -1,149 +0,0 @@
1
- from dataclasses import dataclass
2
- from typing import Dict, Tuple, List
3
-
4
- import numpy as np
5
-
6
- from ck.dataset import SoftDataset, HardDataset
7
- from ck.dataset.cross_table import CrossTable, cross_table_from_dataset
8
- from ck.pgm import PGM, Instance, DensePotentialFunction, Shape, natural_key_idx, SparsePotentialFunction
9
- from ck.utils.iter_extras import multiply
10
- from ck.utils.np_extras import NDArrayFloat64
11
-
12
-
13
- @dataclass
14
- class ParameterValues:
15
- """
16
- A ParameterValues object represents learned parameter values of a PGM.
17
- """
18
- pgm: PGM
19
- """
20
- The PGM that the parameter values pertains to.
21
- """
22
-
23
- cpts: List[Dict[Instance, NDArrayFloat64]]
24
- """
25
- A list of CPTs co-indexed with `pgm.factors`. Each CPT is a dict
26
- mapping from instances of the parent random variables (of the factors)
27
- to the child conditional probability distribution (CPD).
28
- """
29
-
30
- def set_zero(self) -> None:
31
- """
32
- Set the potential function of each PGM factor to zero.
33
- """
34
- for factor in self.pgm.factors:
35
- factor.set_zero()
36
-
37
- def set_cpt(self) -> None:
38
- """
39
- Set the potential function of each PGM factor to a CPTPotentialFunction,
40
- using our parameter values.
41
- """
42
- for factor, cpt in zip(self.pgm.factors, self.cpts):
43
- factor.set_cpt().set(*cpt.items())
44
-
45
- def set_dense(self) -> None:
46
- """
47
- Set the potential function of each PGM factor to a DensePotentialFunction,
48
- using our parameter values.
49
- """
50
- for factor, cpt in zip(self.pgm.factors, self.cpts):
51
- pot_function: DensePotentialFunction = factor.set_dense()
52
- parent_shape: Shape = factor.shape[1:]
53
- child_state: int
54
- value: float
55
- if len(parent_shape) == 0:
56
- cpd: NDArrayFloat64 = cpt[()]
57
- for child_state, value in enumerate(cpd):
58
- pot_function[child_state] = value
59
- else:
60
- parent_space: int = multiply(parent_shape)
61
- parent_states: Instance
62
- cpd: NDArrayFloat64
63
- for parent_states, cpd in cpt.items():
64
- idx: int = natural_key_idx(parent_shape, parent_states)
65
- for value in cpd:
66
- pot_function[idx] = value
67
- idx += parent_space
68
-
69
- def set_sparse(self) -> None:
70
- """
71
- Set the potential function of each PGM factor to a SparsePotentialFunction,
72
- using our parameter values.
73
- """
74
- for factor, cpt in zip(self.pgm.factors, self.cpts):
75
- pot_function: SparsePotentialFunction = factor.set_sparse()
76
- parent_states: Instance
77
- child_state: int
78
- cpd: NDArrayFloat64
79
- value: float
80
- for parent_states, cpd in cpt.items():
81
- for child_state, value in enumerate(cpd):
82
- key = (child_state,) + parent_states
83
- pot_function[key] = value
84
-
85
-
86
- def train_generative_bn(
87
- pgm: PGM,
88
- dataset: HardDataset | SoftDataset,
89
- *,
90
- dirichlet_prior: float = 0,
91
- check_bayesian_network: bool = True,
92
- ) -> ParameterValues:
93
- """
94
- Maximum-likelihood, generative training for a Bayesian network.
95
-
96
- Args:
97
- pgm: the probabilistic graphical model defining the model structure.
98
- Potential function values are ignored and need not be set.
99
- dataset: a dataset of random variable states.
100
- dirichlet_prior: a real number >= 0. See `CrossTable` for an explanation.
101
- check_bayesian_network: if true and not pgm.is_structure_bayesian an exception will be raised.
102
-
103
- Returns:
104
- a ParameterValues object that can be used to update the parameters of the given PGM.
105
-
106
- Raises:
107
- ValueError: if the given PGM does not have a Bayesian network structure, and check_bayesian_network is True.
108
- """
109
- if check_bayesian_network and not pgm.is_structure_bayesian:
110
- raise ValueError('the given PGM is not a Bayesian network')
111
- cpts: List[Dict[Instance, NDArrayFloat64]] = [
112
- cpt_from_crosstab(cross_table_from_dataset(dataset, factor.rvs, dirichlet_prior=dirichlet_prior))
113
- for factor in pgm.factors
114
- ]
115
- return ParameterValues(pgm, cpts)
116
-
117
-
118
- def cpt_from_crosstab(crosstab: CrossTable) -> Dict[Instance, NDArrayFloat64]:
119
- """
120
- Make a conditional probability table (CPT) from a cross-table.
121
-
122
- Args:
123
- crosstab: a CrossTable representing the weight of unique instances.
124
-
125
- Returns:
126
- a mapping from instances of the parent random variables to the child
127
- conditional probability distribution (CPD).
128
-
129
- Assumes:
130
- the first random variable in `crosstab.rvs` is the child random variable.
131
- """
132
- # Number of states for the child random variable.
133
- child_size: int = len(crosstab.rvs[0])
134
-
135
- # Get distribution over child states for seen parent states
136
- parents_weights: Dict[Instance, NDArrayFloat64] = {}
137
- for state, weight in crosstab.items():
138
- parent_state: Tuple[int, ...] = state[1:]
139
- child_state: int = state[0]
140
- parent_weights = parents_weights.get(parent_state)
141
- if parent_weights is None:
142
- parents_weights[parent_state] = parent_weights = np.zeros(child_size, dtype=np.float64)
143
- parent_weights[child_state] += weight
144
-
145
- # Normalise
146
- for parent_state, parent_weights in parents_weights.items():
147
- parent_weights /= parent_weights.sum()
148
-
149
- return parents_weights