simdec 1.2.0.dev0__tar.gz → 1.4.0__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.
@@ -32,5 +32,6 @@ htmlcov/*
32
32
  build/*
33
33
  dist/*
34
34
  sdist/*
35
- docs/_build
35
+ docs/html
36
+ docs/jupyter_execute
36
37
  app.html
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.3
1
+ Metadata-Version: 2.4
2
2
  Name: simdec
3
- Version: 1.2.0.dev0
3
+ Version: 1.4.0
4
4
  Summary: Sensitivity analysis using simulation decomposition
5
5
  Project-URL: homepage, https://www.simdec.fi/
6
6
  Project-URL: documentation, https://simdec.readthedocs.io
@@ -16,9 +16,9 @@ Classifier: License :: OSI Approved :: BSD License
16
16
  Classifier: Operating System :: OS Independent
17
17
  Classifier: Programming Language :: Python
18
18
  Classifier: Programming Language :: Python :: 3
19
- Classifier: Programming Language :: Python :: 3.10
20
19
  Classifier: Programming Language :: Python :: 3.11
21
20
  Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
22
  Requires-Python: >=3.10
23
23
  Requires-Dist: numpy
24
24
  Requires-Dist: pandas
@@ -26,20 +26,23 @@ Requires-Dist: salib
26
26
  Requires-Dist: seaborn
27
27
  Provides-Extra: dashboard
28
28
  Requires-Dist: cryptography; extra == 'dashboard'
29
- Requires-Dist: panel>=1.3.8; extra == 'dashboard'
29
+ Requires-Dist: panel>=1.4.5; extra == 'dashboard'
30
30
  Provides-Extra: dev
31
31
  Requires-Dist: accessible-pygments; extra == 'dev'
32
32
  Requires-Dist: cryptography; extra == 'dev'
33
33
  Requires-Dist: hatch; extra == 'dev'
34
+ Requires-Dist: myst-nb; extra == 'dev'
34
35
  Requires-Dist: numpydoc; extra == 'dev'
35
- Requires-Dist: panel>=1.3.8; extra == 'dev'
36
+ Requires-Dist: panel>=1.4.5; extra == 'dev'
36
37
  Requires-Dist: pre-commit; extra == 'dev'
37
38
  Requires-Dist: pydata-sphinx-theme; extra == 'dev'
38
39
  Requires-Dist: pytest; extra == 'dev'
39
40
  Requires-Dist: pytest-cov; extra == 'dev'
40
41
  Requires-Dist: sphinx; extra == 'dev'
42
+ Requires-Dist: watchfiles; extra == 'dev'
41
43
  Provides-Extra: doc
42
44
  Requires-Dist: accessible-pygments; extra == 'doc'
45
+ Requires-Dist: myst-nb; extra == 'doc'
43
46
  Requires-Dist: numpydoc; extra == 'doc'
44
47
  Requires-Dist: pydata-sphinx-theme; extra == 'doc'
45
48
  Requires-Dist: sphinx; extra == 'doc'
@@ -92,6 +95,5 @@ Foundation, and Finnish Foundation for Economic Education.
92
95
  If you use SimDec in your research we would appreciate a citation to the
93
96
  following publications:
94
97
 
95
- - Kozlova, M., & Yeomans, J. S. (2022). Monte Carlo Enhancement via Simulation Decomposition: A “Must-Have” Inclusion for Many Disciplines. _INFORMS Transactions on Education, 22_(3), 147-159. [Available here](https://pubsonline.informs.org/doi/10.1287/ited.2019.0240).
96
98
  - Kozlova, M., Moss, R. J., Yeomans, J. S., & Caers, J. (2024). Uncovering Heterogeneous Effects in Computational Models for Sustainable Decision-making. _Environmental Modelling & Software_, 171, 105898. [https://doi.org/10.1016/j.envsoft.2023.105898](https://doi.org/10.1016/j.envsoft.2023.105898)
97
- - Kozlova, M., Moss, R. J., Roy, P., Alam, A., & Yeomans, J. S. (forthcoming). SimDec algorithm and guidelines for its usage and interpretation. In M. Kozlova & J. S. Yeomans (Eds.), _Sensitivity Analysis for Business, Technology, and Policymaking. Made Easy with Simulation Decomposition_. Routledge.
99
+ - Kozlova, M., Moss, R. J., Roy, P., Alam, A., & Yeomans, J. S. (2024). SimDec algorithm and guidelines for its usage and interpretation. In M. Kozlova & J. S. Yeomans (Eds.), _Sensitivity Analysis for Business, Technology, and Policymaking. Made Easy with Simulation Decomposition_. Routledge. [Available here](https://doi.org/10.4324/9781003453789-3).
@@ -42,6 +42,5 @@ Foundation, and Finnish Foundation for Economic Education.
42
42
  If you use SimDec in your research we would appreciate a citation to the
43
43
  following publications:
44
44
 
45
- - Kozlova, M., & Yeomans, J. S. (2022). Monte Carlo Enhancement via Simulation Decomposition: A “Must-Have” Inclusion for Many Disciplines. _INFORMS Transactions on Education, 22_(3), 147-159. [Available here](https://pubsonline.informs.org/doi/10.1287/ited.2019.0240).
46
45
  - Kozlova, M., Moss, R. J., Yeomans, J. S., & Caers, J. (2024). Uncovering Heterogeneous Effects in Computational Models for Sustainable Decision-making. _Environmental Modelling & Software_, 171, 105898. [https://doi.org/10.1016/j.envsoft.2023.105898](https://doi.org/10.1016/j.envsoft.2023.105898)
47
- - Kozlova, M., Moss, R. J., Roy, P., Alam, A., & Yeomans, J. S. (forthcoming). SimDec algorithm and guidelines for its usage and interpretation. In M. Kozlova & J. S. Yeomans (Eds.), _Sensitivity Analysis for Business, Technology, and Policymaking. Made Easy with Simulation Decomposition_. Routledge.
46
+ - Kozlova, M., Moss, R. J., Roy, P., Alam, A., & Yeomans, J. S. (2024). SimDec algorithm and guidelines for its usage and interpretation. In M. Kozlova & J. S. Yeomans (Eds.), _Sensitivity Analysis for Business, Technology, and Policymaking. Made Easy with Simulation Decomposition_. Routledge. [Available here](https://doi.org/10.4324/9781003453789-3).
@@ -0,0 +1,115 @@
1
+ @article{Herman2017,
2
+ doi = {10.21105/joss.00097},
3
+ year = {2017},
4
+ month = {jan},
5
+ publisher = {The Open Journal},
6
+ volume = {2},
7
+ number = {9},
8
+ author = {Jon Herman and Will Usher},
9
+ title = {{SALib}: An open-source {Python} library for Sensitivity Analysis},
10
+ journal = {The Journal of Open Source Software}
11
+ }
12
+
13
+ @article{Kozlova2024,
14
+ title = {Uncovering heterogeneous effects in computational models for sustainable decision-making},
15
+ journal = {Environmental Modelling & Software},
16
+ volume = {171},
17
+ pages = {105898},
18
+ year = {2024},
19
+ issn = {1364-8152},
20
+ doi = {10.1016/j.envsoft.2023.105898},
21
+ author = {Mariia Kozlova and Robert J. Moss and Julian Scott Yeomans and Jef Caers},
22
+ keywords = {Global sensitivity analysis, Simulation decomposition, Monte Carlo simulation, Decision-making under uncertainty}
23
+ }
24
+
25
+ @article{Roy2023,
26
+ doi = {10.21105/joss.05309},
27
+ year = {2023},
28
+ publisher = {The Open Journal},
29
+ volume = {8},
30
+ number = {84},
31
+ pages = {5309},
32
+ author = {Pamphile T. Roy and Art B. Owen and Maximilian Balandat and Matt Haberland},
33
+ title = {Quasi-Monte Carlo Methods in {Python}},
34
+ journal = {Journal of Open Source Software}
35
+ }
36
+
37
+ @article{Virtanen2020,
38
+ title={SciPy 1.0: fundamental algorithms for scientific computing in {P}ython},
39
+ author={Virtanen, Pauli and Gommers, Ralf and Oliphant, Travis E and Haberland, Matt and Reddy, Tyler and Cournapeau, David and Burovski, Evgeni and Peterson, Pearu and Weckesser, Warren and Bright, Jonathan et al.},
40
+ journal={Nature methods},
41
+ volume={17},
42
+ number={3},
43
+ pages={261--272},
44
+ year={2020},
45
+ publisher={Nature Publishing Group},
46
+ doi={10.1038/s41592-019-0686-2}
47
+ }
48
+
49
+ @book{Saltelli2007,
50
+ author = {Saltelli, Andrea and Ratto, Marco and Andres, Terry and Campolongo, Francesca and Cariboni, Jessica and Gatelli, Debora and Saisana, Michaela and Tarantola, Stefano},
51
+ booktitle = {Global Sensitivity Analysis. The Primer},
52
+ doi = {10.1002/9780470725184},
53
+ isbn = {9780470725184},
54
+ month = {dec},
55
+ pages = {237--275},
56
+ publisher = {John Wiley {\&} Sons, Ltd},
57
+ title = {{Global Sensitivity Analysis. The Primer}},
58
+ year = {2007}
59
+ }
60
+
61
+ @article{sobol1993,
62
+ title={Sensitivity analysis for non-linear mathematical models, originally “Sensitivity estimates for non-linear mathematical models”},
63
+ author={Sobol, Ilya M},
64
+ journal={Math Model Comput Exp},
65
+ volume={1},
66
+ pages={407--414},
67
+ year={1993}
68
+ }
69
+
70
+ @report{europeancommission2021,
71
+ title = {Better {{Regulation Toolbox}}},
72
+ author = {{European Commission}},
73
+ date = {2021-11},
74
+ url = {https://ec.europa.eu/info/law/law-making-process/planning-and-proposing-law/better-regulation-why-and-how/better-regulation-guidelines-and-toolbox_en},
75
+ city = {Brussels},
76
+ keywords = {\#nosource}
77
+ }
78
+
79
+ @software{panel,
80
+ author = {Philipp Rudiger and
81
+ Marc Skov Madsen and
82
+ Simon Høxbro Hansen and
83
+ Maxime Liquet and
84
+ Andrew and
85
+ Xavier Artusi and
86
+ James A. Bednar and
87
+ Chris B and
88
+ Jean-Luc Stevens and
89
+ Christoph Deil and
90
+ Demetris Roumis and
91
+ Julia Signell and
92
+ Mateusz Paprocki and
93
+ Jerry Wu and
94
+ Jon Mease and
95
+ Arne and
96
+ Coderambling and
97
+ Hugues-Yanis Amanieu and
98
+ thuydotm and
99
+ Simon and
100
+ sdc50 and
101
+ Luca Fabbri and
102
+ kbowen and
103
+ Theom and
104
+ Joel Ostblom and
105
+ Govinda Totla and
106
+ Niko Föhr and
107
+ TBym},
108
+ title = {holoviz/panel: Version 1.4.3},
109
+ month = may,
110
+ year = 2024,
111
+ publisher = {Zenodo},
112
+ version = {v1.4.3},
113
+ doi = {10.5281/zenodo.11261266},
114
+ url = {https://doi.org/10.5281/zenodo.11261266}
115
+ }
@@ -0,0 +1,76 @@
1
+ ---
2
+ title: 'Simulation Decomposition in Python'
3
+ tags:
4
+ - Python
5
+ - SimDec
6
+ - statistics
7
+ - Sensitivity Analysis
8
+ - Visualization
9
+ authors:
10
+ - name: Pamphile T. Roy
11
+ affiliation: 1
12
+ corresponding: true
13
+ orcid: 0000-0001-9816-1416
14
+ - name: Mariia Kozlova
15
+ affiliation: 2
16
+ orcid: 0000-0002-6952-7682
17
+ affiliations:
18
+ - name: Consulting Manao GmbH, Vienna, Austria
19
+ index: 1
20
+ - name: LUT Business School, LUT University, Lappeenranta, Finland
21
+ index: 2
22
+ date: 1 April 2024
23
+ bibliography: paper.bib
24
+
25
+ ---
26
+
27
+ # Summary
28
+
29
+ Uncertainties are everywhere. Whether you are developing a new Artificial Intelligence (AI) system,
30
+ running complex simulations or making an experiment in a lab, uncertainties
31
+ influence the system. Therefore, an approach is needed to understand how these uncertainties impact the system's performance.
32
+
33
+ SimDec offers a novel visual way to understand the intricate role that
34
+ uncertainties play. A clear Python Application Programming Interface (API) and a no-code interactive web
35
+ dashboard make uncertainty analysis with SimDec accessible to everyone.
36
+
37
+ # Statement of need
38
+
39
+ From real life experiments to numerical simulations, uncertainties play a
40
+ crucial role in the system under study. With the advent of AI
41
+ and new regulations such as the [AI Act](https://artificialintelligenceact.eu) or the
42
+ *Better Regulation Guideline* [@europeancommission2021], there is a growing need for explainability and
43
+ impact assessments of systems under uncertainties.
44
+
45
+ Traditional methods to analyse the uncertainties focus on quantitative methods
46
+ to compare the importance of factors, there is a large body of literature and
47
+ the field is known as: Sensitivity Analysis (SA) [@Saltelli2007]. The indices of Sobol' are a
48
+ prominent example of such methods [@sobol1993].
49
+
50
+ Simulation Decomposition or SimDec moves the field of SA forward by supplementing the computation of sensitivity indices with the visualization of the type of interactions involved, which proves critical for understanding the system's behavior and decision-making [@Kozlova2024].
51
+ In short, SimDec is a hybrid uncertainty-sensitivity analysis approach
52
+ that reveals the critical behavior of a computational model or an empirical
53
+ dataset. It decomposes the distribution of the output
54
+ (target variable) by automatically forming scenarios that reveal the most critical behavior of the system. The scenarios are formed out of the most influential input variables (defined with variance-based sensitivity indices) by breaking down their numeric ranges into states (e.g. _low_ and _high_) and creating an exhaustive list of their combinations (e.g. (i) _low_ _**A**_ & _low_ _**B**_, (ii) _low_ _**A**_ & _high_ _**B**_, (iii) _high_ **_A_** & _low_ **_B_**, and (iv) _high_ **_A_** and _high_ **_B_**). The resulting visualization shows how different
55
+ output ranges can be achieved and what kind of critical interactions affect
56
+ the output—as seen in \autoref{fig:simdec}. The method has shown value for
57
+ various computational models from different fields, including business,
58
+ environment, and engineering, as well as an emerging evidence of use for
59
+ empirical data and AI.
60
+
61
+ ![SimDec: explanation of output by most important inputs. A simulation dataset of a structural reliability model with one key output variable and four input variables is used for this case. Inputs 3 and 1 have the highest sensitivity indices and thus are automatically chosen for decomposition. The most influential input 3 divides the distribution of the output into three main states with distinct colors. Input 1 further subdivides them into shades. From the graph, it becomes obvious that input 1 influences the output when input 3 is low, but has a negligible effect when input 3 is medium or high.\label{fig:simdec}](simdec_presentation.png)
62
+
63
+ Besides proposing a comprehensive yet simple API through a Python package
64
+ available on PyPi, SimDec is also made available
65
+ to practitioners through an online dashboard at [https://simdec.io](https://simdec.io). The project
66
+ relies on powerful variance-based sensitivity analysis methods from SALib [@Herman2017] and
67
+ SciPy [@Virtanen2020; @Roy2023]—notably the Quasi-Monte Carlo capabilities with
68
+ `sp.stats.qmc` and in the future sensitivity indices with `sp.stats.sensitivity_indices`.
69
+ The dashboard is made possible thanks to Panel [@panel].
70
+
71
+ # Acknowledgements
72
+
73
+ The work on this open-source software was supported by grant #220177 from
74
+ Finnish Foundation for Economic Foundation.
75
+
76
+ # References
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "simdec"
7
- version = "1.2.0dev0"
7
+ version = "1.4.0"
8
8
  description = "Sensitivity analysis using simulation decomposition"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -23,9 +23,9 @@ classifiers = [
23
23
  "Operating System :: OS Independent",
24
24
  "Programming Language :: Python",
25
25
  "Programming Language :: Python :: 3",
26
- "Programming Language :: Python :: 3.10",
27
26
  "Programming Language :: Python :: 3.11",
28
27
  "Programming Language :: Python :: 3.12",
28
+ "Programming Language :: Python :: 3.13",
29
29
  ]
30
30
 
31
31
  dependencies = [
@@ -37,7 +37,7 @@ dependencies = [
37
37
 
38
38
  [project.optional-dependencies]
39
39
  dashboard = [
40
- "panel>=1.3.8",
40
+ "panel>=1.4.5",
41
41
  "cryptography",
42
42
  ]
43
43
 
@@ -51,10 +51,12 @@ doc = [
51
51
  "pydata-sphinx-theme",
52
52
  "accessible-pygments",
53
53
  "numpydoc",
54
+ "myst-nb",
54
55
  ]
55
56
 
56
57
  dev = [
57
58
  "simdec[doc,test,dashboard]",
59
+ "watchfiles",
58
60
  "pre-commit",
59
61
  "hatch",
60
62
  ]
@@ -22,6 +22,8 @@ def states_expansion(states: list[int], inputs: pd.DataFrame) -> list[list[str]]
22
22
  expanded_states.append(["low", "high"])
23
23
  elif state == 3:
24
24
  expanded_states.append(["low", "medium", "high"])
25
+ else:
26
+ expanded_states.append([i for i in range(state)])
25
27
  else:
26
28
  expanded_states.append(state)
27
29
 
@@ -109,11 +111,9 @@ def decomposition(
109
111
  var_names = inputs.columns
110
112
 
111
113
  cat_cols = inputs.select_dtypes(exclude=["number"])
112
- cat_cols_idx = []
113
114
  for cat_col in cat_cols:
114
115
  codes, cat_states_ = pd.factorize(inputs[cat_col])
115
116
  inputs[cat_col] = codes
116
- cat_cols_idx.append(inputs.columns.get_loc(cat_col))
117
117
 
118
118
  inputs = inputs.to_numpy()
119
119
  output = output.to_numpy()
@@ -136,10 +136,9 @@ def decomposition(
136
136
  states = 3 if n_var_dec < 3 else 2
137
137
  states = [states] * n_var_dec
138
138
 
139
- # categorical for a given variable
140
- for i in cat_cols_idx:
139
+ for i in range(n_var_dec):
141
140
  n_unique = np.unique(inputs[:, i]).size
142
- states[i] = n_unique if n_unique < 5 else states[i]
141
+ states[i] = n_unique if n_unique <= 5 else states[i]
143
142
 
144
143
  if auto_ordering:
145
144
  var_names = var_names[var_order[:n_var_dec]].tolist()
@@ -163,8 +162,20 @@ def decomposition(
163
162
  bins.append(inputs)
164
163
  return statistic_method(inputs)
165
164
 
165
+ # make bins with equal number of samples for a given dimension
166
+ # sort and then split in n-state
167
+ sorted_inputs = np.sort(inputs, axis=0)
168
+ bin_edges = []
169
+ for i, states_ in enumerate(states):
170
+ splits = np.array_split(sorted_inputs[:, i], states_)
171
+ bin_edges_ = [splits_[0] for splits_ in splits]
172
+ bin_edges_.append(splits[-1][-1]) # last point to close the edges
173
+ # bin_edges_ = np.unique(bin_edges_) # remove duplicate points, sorted
174
+ bin_edges_ += 1e-10 * np.linspace(0, 1, len(bin_edges_))
175
+ bin_edges.append(bin_edges_)
176
+
166
177
  res = stats.binned_statistic_dd(
167
- inputs, values=output, statistic=statistic_, bins=states
178
+ inputs, values=output, statistic=statistic_, bins=bin_edges
168
179
  )
169
180
 
170
181
  bins = pd.DataFrame(bins[1:]).T
@@ -164,7 +164,6 @@ def sensitivity_indices(
164
164
 
165
165
  soe[i, j] = (var_ij - var_i - var_j) / var_y
166
166
 
167
- soe = np.clip(soe, a_min=0, a_max=None)
168
167
  soe = np.where(soe == 0, soe.T, soe)
169
168
  si[i] = foe[i] + soe[:, i].sum() / 2
170
169
 
@@ -1,3 +1,4 @@
1
+ import copy
1
2
  import functools
2
3
  import itertools
3
4
  from typing import Literal
@@ -202,6 +203,8 @@ def tableau(
202
203
  ----------
203
204
  var_names : list of str
204
205
  Variables name.
206
+ statistic : ndarray of shape (n_factors, 1)
207
+ Statistic in each bin.
205
208
  states : list of int or list of str
206
209
  For each variable, number of states. Can either be a scalar or a list.
207
210
 
@@ -225,16 +228,17 @@ def tableau(
225
228
  table.rename(columns={"index": "colour"}, inplace=True)
226
229
 
227
230
  # Default states for 2 or 3
228
- for i, state in enumerate(states):
231
+ states_ = copy.deepcopy(states)
232
+ for i, state in enumerate(states_):
229
233
  if isinstance(state, int):
230
- states: list
234
+ states_: list
231
235
  if state == 2:
232
- states[i] = ["low", "high"]
236
+ states_[i] = ["low", "high"]
233
237
  elif state == 3:
234
- states[i] = ["low", "medium", "high"]
238
+ states_[i] = ["low", "medium", "high"]
235
239
 
236
240
  # get the list of states
237
- gen_states = [range(x) if isinstance(x, int) else x for x in states]
241
+ gen_states = [range(x) if isinstance(x, int) else x for x in states_]
238
242
  states_ = np.asarray(list(itertools.product(*gen_states)))
239
243
  for i, var_name in enumerate(var_names):
240
244
  table.insert(loc=i + 1, column=var_name, value=states_[:, i])
File without changes
File without changes
File without changes
File without changes