causing 2.3.0__py3-none-any.whl → 2.4.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of causing might be problematic. Click here for more details.
- causing/graph.py +13 -4
- causing/model.py +31 -4
- causing/utils.py +12 -6
- {causing-2.3.0.dist-info → causing-2.4.1.dist-info}/METADATA +28 -28
- causing-2.4.1.dist-info/RECORD +14 -0
- {causing-2.3.0.dist-info → causing-2.4.1.dist-info}/WHEEL +1 -1
- causing-2.3.0.dist-info/RECORD +0 -14
- {causing-2.3.0.dist-info → causing-2.4.1.dist-info}/LICENSE.md +0 -0
- {causing-2.3.0.dist-info → causing-2.4.1.dist-info}/top_level.txt +0 -0
causing/graph.py
CHANGED
|
@@ -69,8 +69,8 @@ def save_graph(path: Path, graph_dot):
|
|
|
69
69
|
svg_code = subprocess.check_output(
|
|
70
70
|
[DOT_COMMAND, "-Tsvg"], input=graph_dot, encoding="utf-8"
|
|
71
71
|
)
|
|
72
|
-
if dot_version()[0] < 3:
|
|
73
|
-
|
|
72
|
+
# if dot_version()[0] < 3:
|
|
73
|
+
# svg_code = fix_svg_scale(svg_code)
|
|
74
74
|
with open(path, "w") as f:
|
|
75
75
|
f.write(svg_code)
|
|
76
76
|
|
|
@@ -149,6 +149,7 @@ def graph_to_dot(
|
|
|
149
149
|
graph_options_str=GRAPH_OPTIONS_STR,
|
|
150
150
|
in_percent=False,
|
|
151
151
|
min_sig_figures=3,
|
|
152
|
+
cutoff=0.0001,
|
|
152
153
|
):
|
|
153
154
|
dot_str = "digraph {" + graph_options_str
|
|
154
155
|
max_val = max(
|
|
@@ -157,13 +158,21 @@ def graph_to_dot(
|
|
|
157
158
|
)
|
|
158
159
|
|
|
159
160
|
for node, data in g.nodes(data=True):
|
|
160
|
-
eff_str = utils.fmt_min_sig(
|
|
161
|
+
eff_str = utils.fmt_min_sig(
|
|
162
|
+
data["effect"] if abs(data["effect"]) > cutoff else 0,
|
|
163
|
+
min_sig_figures,
|
|
164
|
+
percent=in_percent,
|
|
165
|
+
)
|
|
161
166
|
label = data.get("label", node).replace("\n", r"\n") + r"\n" + eff_str
|
|
162
167
|
col_str = color(data["effect"], max_val, palette=node_palette)
|
|
163
168
|
dot_str += f' "{node}"[label = "{label}" fillcolor="{col_str}"]\n'
|
|
164
169
|
|
|
165
170
|
for from_node, to_node, data in g.edges(data=True):
|
|
166
|
-
eff_str = utils.fmt_min_sig(
|
|
171
|
+
eff_str = utils.fmt_min_sig(
|
|
172
|
+
data["effect"] if abs(data["effect"]) > cutoff else 0,
|
|
173
|
+
min_sig_figures,
|
|
174
|
+
percent=in_percent,
|
|
175
|
+
)
|
|
167
176
|
col_str = color(data["effect"], max_val, palette=edge_palette)
|
|
168
177
|
penwidth = color(data["effect"], max_val, palette=pen_width_palette)
|
|
169
178
|
dot_str += f' "{from_node}" -> "{to_node}" [label="{eff_str}" color="{col_str}" penwidth="{penwidth}"]\n'
|
causing/model.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
|
+
|
|
2
3
|
from dataclasses import dataclass, field
|
|
3
4
|
from typing import Iterable, Callable
|
|
4
5
|
from functools import cached_property
|
|
@@ -8,6 +9,10 @@ import sympy
|
|
|
8
9
|
import numpy as np
|
|
9
10
|
|
|
10
11
|
|
|
12
|
+
class NumericModelError(Exception):
|
|
13
|
+
pass
|
|
14
|
+
|
|
15
|
+
|
|
11
16
|
@dataclass
|
|
12
17
|
class Model:
|
|
13
18
|
|
|
@@ -42,6 +47,7 @@ class Model:
|
|
|
42
47
|
self.graph.add_node(var)
|
|
43
48
|
self.trans_graph = networkx.transitive_closure(self.graph, reflexive=True)
|
|
44
49
|
|
|
50
|
+
@np.errstate(all="raise")
|
|
45
51
|
def compute(
|
|
46
52
|
self,
|
|
47
53
|
xdat: np.array,
|
|
@@ -77,15 +83,36 @@ class Model:
|
|
|
77
83
|
eq_inputs[:, fixed_from_ind] = fixed_vals
|
|
78
84
|
|
|
79
85
|
try:
|
|
86
|
+
# print(f"Comuting variable: {self.yvars[i]}")
|
|
87
|
+
# yhat[i] = np.array(
|
|
88
|
+
# [eq(*eq_in, *parameters.values()) for eq_in in eq_inputs],
|
|
89
|
+
# dtype=np.float64,
|
|
90
|
+
# )
|
|
91
|
+
computed_yvars = []
|
|
92
|
+
for eq_in in eq_inputs:
|
|
93
|
+
try:
|
|
94
|
+
computed_yvars.append(eq(*eq_in, *parameters.values()))
|
|
95
|
+
except FloatingPointError:
|
|
96
|
+
# Floating Point Error for self.yvars[i]
|
|
97
|
+
# Adding 0.0 to overcome this.
|
|
98
|
+
computed_yvars.append(0.0)
|
|
99
|
+
|
|
80
100
|
yhat[i] = np.array(
|
|
81
|
-
|
|
101
|
+
computed_yvars,
|
|
82
102
|
dtype=np.float64,
|
|
83
103
|
)
|
|
84
104
|
except Exception as e:
|
|
85
|
-
|
|
105
|
+
# for eq_in in eq_inputs:
|
|
106
|
+
# print("--", self.yvars[i])
|
|
107
|
+
# for var, val in zip(
|
|
108
|
+
# self.vars + list(parameters.keys()),
|
|
109
|
+
# list(eq_in) + list(parameters.values()),
|
|
110
|
+
# ):
|
|
111
|
+
# print(var, "=", val)
|
|
112
|
+
# eq(*eq_in, *parameters.values())
|
|
113
|
+
raise NumericModelError(
|
|
86
114
|
f"Failed to compute model value for yvar {self.yvars[i]}: {e}"
|
|
87
|
-
)
|
|
88
|
-
raise
|
|
115
|
+
) from e
|
|
89
116
|
assert yhat.shape == (self.ndim, tau)
|
|
90
117
|
return yhat
|
|
91
118
|
|
causing/utils.py
CHANGED
|
@@ -11,7 +11,7 @@ def round_sig(x, sig=2) -> float:
|
|
|
11
11
|
"""Round x to the given number of significant figures"""
|
|
12
12
|
if x == 0 or not np.isfinite(x):
|
|
13
13
|
return x
|
|
14
|
-
return round(x, sig - int(floor(log10(abs(x))))
|
|
14
|
+
return round(x, sig - int(floor(log10(abs(x)))) + 1)
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
def round_sig_recursive(x, sig=2):
|
|
@@ -37,6 +37,11 @@ def round_sig_recursive(x, sig=2):
|
|
|
37
37
|
|
|
38
38
|
class MatrixEncoder(json.JSONEncoder):
|
|
39
39
|
def default(self, obj):
|
|
40
|
+
# allow serialization of numpy scalars
|
|
41
|
+
if isinstance(obj, np.integer):
|
|
42
|
+
return int(obj)
|
|
43
|
+
if isinstance(obj, np.floating):
|
|
44
|
+
return float(obj)
|
|
40
45
|
# avoid importing pytorch for isinstance check
|
|
41
46
|
if isinstance(obj, np.ndarray) or type(obj).__name__ == "Tensor":
|
|
42
47
|
return obj.tolist()
|
|
@@ -61,11 +66,12 @@ def fmt_min_sig(x, min_sig_figures=3, percent=False, percent_spacer=""):
|
|
|
61
66
|
if not math.isfinite(x):
|
|
62
67
|
return str(x)
|
|
63
68
|
if x == 0:
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
+
num = "0"
|
|
70
|
+
else:
|
|
71
|
+
if percent:
|
|
72
|
+
x *= 100
|
|
73
|
+
show_dec = max(-math.floor(math.log10(abs(x)) + 1) + min_sig_figures, 0)
|
|
74
|
+
num = locale.format_string("%." + str(show_dec) + "f", x, grouping=True)
|
|
69
75
|
if percent:
|
|
70
76
|
num += percent_spacer + "%"
|
|
71
77
|
return num
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: causing
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.4.1
|
|
4
4
|
Summary: Causing: CAUSal INterpretation using Graphs
|
|
5
5
|
Home-page: https://github.com/realrate/Causing
|
|
6
6
|
Author: Dr. Holger Bartel
|
|
@@ -11,11 +11,11 @@ Classifier: Operating System :: OS Independent
|
|
|
11
11
|
Requires-Python: >=3.9
|
|
12
12
|
Description-Content-Type: text/markdown
|
|
13
13
|
License-File: LICENSE.md
|
|
14
|
-
Requires-Dist: numpy
|
|
15
|
-
Requires-Dist: pandas
|
|
16
|
-
Requires-Dist: scipy
|
|
17
|
-
Requires-Dist: sympy
|
|
18
|
-
Requires-Dist: networkx
|
|
14
|
+
Requires-Dist: numpy~=1.23
|
|
15
|
+
Requires-Dist: pandas~=1.3
|
|
16
|
+
Requires-Dist: scipy~=1.9
|
|
17
|
+
Requires-Dist: sympy~=1.5
|
|
18
|
+
Requires-Dist: networkx~=2.7
|
|
19
19
|
Requires-Dist: pre-commit
|
|
20
20
|
|
|
21
21
|
# Causing: CAUSal INterpretation using Graphs
|
|
@@ -29,12 +29,12 @@ effects of a given equation system._
|
|
|
29
29
|
Get a nice colored graph and immediately understand the causal effects between the variables.
|
|
30
30
|
|
|
31
31
|
**Input:** You simply have to put in a dataset and provide an equation system in form of a
|
|
32
|
-
python function. The endogenous
|
|
32
|
+
python function. The endogenous variables on the left-hand side are assumed to be caused by
|
|
33
33
|
the variables on the right-hand side of the equation. Thus, you provide the causal structure
|
|
34
34
|
in form of a directed acyclic graph (DAG).
|
|
35
35
|
|
|
36
|
-
**Output:** As an output you will get a colored graph of quantified effects acting between
|
|
37
|
-
the model variables. You
|
|
36
|
+
**Output:** As an output, you will get a colored graph of quantified effects acting between
|
|
37
|
+
the model variables. You can immediately interpret mediation chains for every
|
|
38
38
|
individual observation - even for highly complex nonlinear systems.
|
|
39
39
|
|
|
40
40
|
Here is a table relating Causing to other approaches:
|
|
@@ -42,10 +42,10 @@ Here is a table relating Causing to other approaches:
|
|
|
42
42
|
Causing is | Causing is NOT
|
|
43
43
|
--- | ---
|
|
44
44
|
✅ causal model given | ❌ causal search
|
|
45
|
-
✅ DAG directed acyclic graph | ❌ cyclic, undirected or bidirected graph
|
|
45
|
+
✅ DAG directed acyclic graph | ❌ cyclic, undirected, or bidirected graph
|
|
46
46
|
✅ latent variables | ❌ just observed / manifest variables
|
|
47
47
|
✅ individual effects | ❌ just average effects
|
|
48
|
-
✅ direct, total and mediation effects | ❌ just total effects
|
|
48
|
+
✅ direct, total, and mediation effects | ❌ just total effects
|
|
49
49
|
✅ structural model | ❌ reduced model
|
|
50
50
|
✅ small and big data | ❌ big data requirement
|
|
51
51
|
✅ graphical results | ❌ just numerical results
|
|
@@ -59,21 +59,21 @@ Causing combines total effects and mediation effects in one single graph that is
|
|
|
59
59
|
|
|
60
60
|
The total effects of a variable on the final variable are shown in the corresponding nodes of the graph. The total effects are split up over their outgoing edges, yielding the mediation effects shown on the edges. Just education has more than one outgoing edge to be interpreted in this way.
|
|
61
61
|
|
|
62
|
-
The effects differ from individual to individual. To
|
|
62
|
+
The effects differ from individual to individual. To emphasize this, we talk about individual effects. And the corresponding graph, combining total and mediation effects is called the Individual Mediation Effects (IME) graph.
|
|
63
63
|
|
|
64
64
|
## Software
|
|
65
65
|
|
|
66
|
-
Causing is
|
|
66
|
+
Causing is free software written in _Python 3_. Graphs are generated using _Graphviz_. See dependencies in [setup.py](setup.py). Causing is available under MIT license. See [LICENSE](LICENSE.md "LICENSE").
|
|
67
67
|
|
|
68
|
-
The software is developed by RealRate, an AI rating agency aiming to re-invent the
|
|
68
|
+
The software is developed by RealRate, an AI rating agency aiming to re-invent the rating market by using AI, interpretability, and avoiding any conflict of interest. See www.realrate.ai.
|
|
69
69
|
|
|
70
70
|
When starting `python -m causing.examples example` after cloning / downloading the Causing repository you will find the results in the _output_ folder. The results are saved in SVG files. The IME files show the individual mediation effects graphs for the respective individual.
|
|
71
71
|
|
|
72
72
|
See `causing/examples` for the code generating some examples.
|
|
73
73
|
|
|
74
|
-
## Start your
|
|
74
|
+
## Start your Model
|
|
75
75
|
|
|
76
|
-
To start your
|
|
76
|
+
To start your model, you have to provide the following information, as done in the example code below:
|
|
77
77
|
|
|
78
78
|
- Define all your model variables as SymPy symbols.
|
|
79
79
|
- Note that in Sympy some operators are special, e.g. Max() instead of max().
|
|
@@ -94,31 +94,31 @@ Y<sub>2</sub> = X<sub>2</sub> + 2 * Y<sub>1</sub><sup>2</sup>
|
|
|
94
94
|
|
|
95
95
|
Y<sub>3</sub> = Y<sub>1</sub> + Y<sub>2</sub>.
|
|
96
96
|
|
|
97
|
-
This gives the following graphs. Some notes
|
|
97
|
+
This gives the following graphs. Some notes to understand them:
|
|
98
98
|
|
|
99
|
-
- The data used
|
|
99
|
+
- The data used consists of 200 observations. They are available for the x variables X<sub>1</sub> and X<sub>2</sub> with mean(X<sub>1</sub>) = 3 and mean(X<sub>2</sub>) = 2. Variables Y<sub>1</sub> and Y<sub>2</sub> are assumed to be latent / unobserved. Y<sub>3</sub> is assumed to be manifest / observed. Therefore, 200 observations are available for Y<sub>3</sub>.
|
|
100
100
|
|
|
101
101
|
- To allow for benchmark comparisons, each individual effect is measured with respect to the mean of all observations.
|
|
102
102
|
|
|
103
103
|
- Nodes and edges are colored, showing positive (_green_) and negative (_red_) effects they have on the final variable Y<sub>3</sub>.
|
|
104
104
|
|
|
105
|
-
- Individual effects are based on the given model. For each individual, however its _own_ exogenous data is put into the given graph function to yield the corresponding endogenous values. The effects are computed at this individual point. Individual effects are shown below just for individual no. 1 out of the 200 observations.
|
|
105
|
+
- Individual effects are based on the given model. For each individual, however, its _own_ exogenous data is put into the given graph function to yield the corresponding endogenous values. The effects are computed at this individual point. Individual effects are shown below just for individual no. 1 out of the 200 observations.
|
|
106
106
|
|
|
107
|
-
- Total effects are shown below in the nodes and they are split up over the outgoing edges yielding the Mediation effects shown on the edges. Note however, that just
|
|
107
|
+
- Total effects are shown below in the nodes and they are split up over the outgoing edges yielding the Mediation effects shown on the edges. Note, however, that just outgoing edges sum up to the node value, incoming edges do not. All effects are effects just on the final variable of interest, assumed here to be Y<sub>3</sub>.
|
|
108
108
|
|
|
109
109
|

|
|
110
110
|
|
|
111
|
-
As you can see in the right-most graph for the individual mediation effects (IME), there is one green path starting at X<sub>1</sub> passing through Y<sub>1</sub>, Y<sub>2</sub
|
|
111
|
+
As you can see in the right-most graph for the individual mediation effects (IME), there is one green path starting at X<sub>1</sub> passing through Y<sub>1</sub>, Y<sub>2</sub>, and finally ending in Y<sub>3</sub>. This means that X<sub>1</sub> is the main cause for Y<sub>3</sub> taking on a value above average with its effect on Y<sub>3</sub> being +29.81. However, this positive effect is slightly reduced by X<sub>2</sub>. In total, accounting for all exogenous and endogenous effects, Y<sub>3</sub> is +27.07 above average. You can understand at one glance why Y<sub>3</sub> is above average for individual no. 1.
|
|
112
112
|
|
|
113
113
|
You can find the full source code for this example [here](https://github.com/realrate/Causing/blob/develop/causing/examples/models.py#L16-L45).
|
|
114
114
|
|
|
115
115
|
## 2. Application to Education and Wages
|
|
116
116
|
|
|
117
|
-
To dig a bit deeper, here we have a real
|
|
117
|
+
To dig a bit deeper, here we have a real-world example from social sciences. We analyze how the wage earned by young American workers is determined by their educational attainment, family characteristics, and test scores.
|
|
118
118
|
|
|
119
|
-
This 5
|
|
119
|
+
This 5-minute introductory video gives a short overview of Causing and includes this real data example: See [Causing Introduction Video](https://youtu.be/GJLsjSZOk2w "Causing_Introduction_Video").
|
|
120
120
|
|
|
121
|
-
See here for a detailed
|
|
121
|
+
See here for a detailed analysis of the Education and Wages example: [An Application of Causing: Education and Wages](docs/education.md).
|
|
122
122
|
|
|
123
123
|
## 3. Application to Insurance Ratings
|
|
124
124
|
|
|
@@ -128,21 +128,21 @@ The Causing approach and its formulas together with an application are given in:
|
|
|
128
128
|
DOI: 10.13140/RG.2.2.31524.83848
|
|
129
129
|
https://www.researchgate.net/publication/339091133
|
|
130
130
|
|
|
131
|
-
Note that in this early paper the mediation effects on the final variable of interest are called final effects. Also, while the current Causing version just uses numerically computed
|
|
131
|
+
Note that in this early paper the mediation effects on the final variable of interest are called final effects. Also, while the current Causing version just uses numerically computed effects, that paper uses closed formulas.
|
|
132
132
|
|
|
133
133
|
The paper proposes simple linear algebra formulas for the causal analysis of equation systems. The effect of one variable on another is the total derivative. It is extended to endogenous system variables. These total effects are identical to the effects used in graph theory and its do-calculus. Further, mediation effects are defined, decomposing the total effect of one variable on a final variable of interest over all its directly caused variables. This allows for an easy but in-depth causal and mediation analysis.
|
|
134
134
|
|
|
135
|
-
The equation system provided by the user is represented as a structural neural network (SNN). The network's nodes are represented by the model variables and its edge weights are given by the effects. Unlike classical deep neural networks, we follow a sparse and 'small data' approach. This new methodology is applied to financial strength ratings of insurance companies.
|
|
135
|
+
The equation system provided by the user is represented as a structural neural network (SNN). The network's nodes are represented by the model variables and its edge weights are given by the effects. Unlike classical deep neural networks, we follow a sparse and 'small data' approach. This new methodology is applied to the financial strength ratings of insurance companies.
|
|
136
136
|
|
|
137
137
|
> **Keywords:** total derivative, graphical effect, graph theory, do-Calculus, structural neural network, linear Simultaneous Equations Model (SEM), Structural Causal Model (SCM), insurance rating
|
|
138
138
|
|
|
139
139
|
## Award
|
|
140
140
|
|
|
141
|
-
RealRate's AI software _Causing_ is a winner of PyTorch AI Hackathon.
|
|
141
|
+
RealRate's AI software _Causing_ is a winner of the PyTorch AI Hackathon.
|
|
142
142
|
|
|
143
143
|
<img src="https://github.com/realrate/Causing/raw/develop/images_readme/RealRate_AI_Software_Winner.png">
|
|
144
144
|
|
|
145
|
-
We are
|
|
145
|
+
We are excited to be a winner of the PyTorch AI Hackathon 2020 in the Responsible AI category. This is quite an honor given that more than 2,500 teams submitted their projects.
|
|
146
146
|
|
|
147
147
|
[devpost.com/software/realrate-explainable-ai-for-company-ratings](https://devpost.com/software/realrate-explainable-ai-for-company-ratings "devpost.com/software/realrate-explainable-ai-for-company-ratings").
|
|
148
148
|
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
causing/__init__.py,sha256=O_9uV9aX3q-c6M3KhY7bQAXncAecwnSfXw7ulGmMvSw,714
|
|
2
|
+
causing/graph.py,sha256=5v3t7dhFtxcIjpeJEOVdKxzSleufmXECSKqlhykMbcE,8637
|
|
3
|
+
causing/model.py,sha256=jgIuuSxoYuel1ZGwl-nj7vVoBsAqXUFAW_nkDld_OkU,8589
|
|
4
|
+
causing/utils.py,sha256=qfiNAb-MxVFeZVan7I4X-q04LVJZ8ST2YdVdvWvnjOE,2461
|
|
5
|
+
tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
|
+
tests/test_estimate.py,sha256=xr9qUVzM9XO70agw_J3PE7oy3aiytUs4CMxvsegNZ6w,3120
|
|
7
|
+
tests/utils.py,sha256=OPEuaBQF3_Azu4bW5q-6J5mtzGrVw4KJUWHd8utK4AE,510
|
|
8
|
+
tests/examples/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
9
|
+
tests/examples/models.py,sha256=lr7v4LArOi3MlcKRvjGAJ6pEHVz1IQKbmKctZ02Vcjc,3849
|
|
10
|
+
causing-2.4.1.dist-info/LICENSE.md,sha256=ypzox8OiFHlpmiHOnxpC6PSGuDCNwzn_Q0iPYPJtt2Q,1095
|
|
11
|
+
causing-2.4.1.dist-info/METADATA,sha256=G2gYzFvtJD55pQTfeLdlH13BNY6qrHMLl3LTKw96UJc,10026
|
|
12
|
+
causing-2.4.1.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
|
|
13
|
+
causing-2.4.1.dist-info/top_level.txt,sha256=AZ4fGg06-ThD38PJjnIg4Yd1x4v_4hgRtPetAcKMmug,14
|
|
14
|
+
causing-2.4.1.dist-info/RECORD,,
|
causing-2.3.0.dist-info/RECORD
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
causing/__init__.py,sha256=O_9uV9aX3q-c6M3KhY7bQAXncAecwnSfXw7ulGmMvSw,714
|
|
2
|
-
causing/graph.py,sha256=jaGe5m1eFdM4yryAOlKNNYqbRqeUiT-8g9x7PdsK5Ac,8442
|
|
3
|
-
causing/model.py,sha256=XiXIIhp6gAdn2h89lPF1YR3QvgTNPtj_0ud5D6UBWQo,7438
|
|
4
|
-
causing/utils.py,sha256=be2sjODmuscqAFIajXRqhkT-E8x5PBodBbbog_AeWKM,2250
|
|
5
|
-
tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
|
-
tests/test_estimate.py,sha256=xr9qUVzM9XO70agw_J3PE7oy3aiytUs4CMxvsegNZ6w,3120
|
|
7
|
-
tests/utils.py,sha256=OPEuaBQF3_Azu4bW5q-6J5mtzGrVw4KJUWHd8utK4AE,510
|
|
8
|
-
tests/examples/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
9
|
-
tests/examples/models.py,sha256=lr7v4LArOi3MlcKRvjGAJ6pEHVz1IQKbmKctZ02Vcjc,3849
|
|
10
|
-
causing-2.3.0.dist-info/LICENSE.md,sha256=ypzox8OiFHlpmiHOnxpC6PSGuDCNwzn_Q0iPYPJtt2Q,1095
|
|
11
|
-
causing-2.3.0.dist-info/METADATA,sha256=7SkUYDSp41ngrC9hXAZX7AT-nOJryvFTTD1gXk4SKbk,10053
|
|
12
|
-
causing-2.3.0.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
|
|
13
|
-
causing-2.3.0.dist-info/top_level.txt,sha256=AZ4fGg06-ThD38PJjnIg4Yd1x4v_4hgRtPetAcKMmug,14
|
|
14
|
-
causing-2.3.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|