-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathprocess_results.py
More file actions
155 lines (129 loc) · 5.1 KB
/
Copy pathprocess_results.py
File metadata and controls
155 lines (129 loc) · 5.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
"""
Process the causal estimation results from the attack sequences.
"""
import os
from glob import glob
import json
import sys
import pandas as pd
if len(sys.argv) != 2:
raise ValueError("Please provide a file (or directory of files) to convert.")
fname = sys.argv[1]
outfile = fname.replace(".json", ".csv")
if os.path.isdir(fname):
if outfile.endswith("/"):
outfile = outfile[:-1]
outfile += ".csv"
log = []
for fname in glob(f"{fname}/*.json"):
with open(fname) as f:
log += json.load(f)
with open(outfile.replace(".csv", ".json"), "w") as f:
json.dump(log, f)
else:
with open(fname) as f:
log = json.load(f)
data = []
for record in log:
attack = record["attack"]
attack_index = record["attack_index"]
outcome = record["outcome"]
spurious = record.get("spurious", [])
basic_attack = {
"attack_index": record["attack_index"],
# "attack": record["attack"],
"outcome": outcome,
"failure": record["failure"],
# "variable": var,
# "value": val,
}
if "error" in record:
print("WARNING: Error in record")
data += [
basic_attack
| {
"intervention_index": inx,
"error": record["error"],
"result": False,
}
for inx, (t, var, val) in enumerate(record["attack"])
]
continue
# assert len(record["treatment_strategies"]) == len(record["attack"])
for inx, ((t, var, val), record) in enumerate(zip(record["attack"], record["treatment_strategies"])):
if "error" in record:
data.append(
basic_attack
| {
"intervention_index": record["intervention_index"],
"spurious": record["intervention_index"] in spurious,
"error": record["error"],
"result": False,
}
)
continue
result = record["result"]
if "adequacy" in result:
result = result | result.pop("adequacy")
result["kurtosis"] = result["kurtosis"]["trtrand"]
result["effect_estimate"] = result["effect_estimate"]["trtrand"]
result["ci_low"] = result["ci_low"][0]
result["ci_high"] = result["ci_high"][0]
result["significant"] = not result["ci_low"] < 1 < result["ci_high"]
data.append(
basic_attack
| {
"intervention_index": record["intervention_index"],
"spurious": record["intervention_index"] in spurious,
"error": None,
"result": True,
"len_control_group": record["len_control_group"],
"len_treatment_group": record["len_treatment_group"],
}
| result
)
data = pd.DataFrame(data).sort_values(["attack_index", "intervention_index"]).reset_index(drop=True)
data["spurious"] = data["spurious"]
data["necessary"] = ~data["spurious"]
data["significant"] = data.pop("significant")
data["correct"] = data["necessary"] == data["significant"]
# data["treatment_value"] = [t[i] for t, i in zip(data["treatment_value"], data["intervention_index"])]
# data["control"] = [t[i] for t, i in zip(data["control_value"], data["intervention_index"])]
data["treatment"] = [t[i] if isinstance(t, list) else t for t, i in zip(data["treatment"], data["intervention_index"])]
data.drop(["adjustment_set", "effect_measure"], axis=1, inplace=True)
def highlight_greaterthan(row):
"""
Colour the rows based on the attack_index so that the results are easier to read.
:param row: Pandas object representing a row of data.
"""
index = pd.Series(data=False, index=row.index)
index["attack_index"] = attack_indices[row.loc["attack_index"]] % 2 == 0
return ["background-color: #eee" if index["attack_index"] else "" for v in index]
attack_indices = {v: k for k, v in enumerate(sorted(list(set(data["attack_index"]))))}
styled_df = data.style.apply(highlight_greaterthan, axis=1)
styled_df.to_excel(outfile.replace(".csv", ".xlsx"), engine="openpyxl")
print(data.dtypes)
data.to_csv(outfile, index=False)
# data["attack"] = [tuple(map(tuple, attack)) for attack in data["attack"]]
data = data.groupby("attack_index").filter(lambda gp: gp["necessary"].any())
if len(data) > 0:
result = data.loc[data["result"]]
print(result)
tp = len(result.loc[result["necessary"] & result["significant"]])
tn = len(result.loc[(~result["necessary"]) & ~result["significant"]])
fp = len(result.loc[~result["necessary"] & result["significant"]])
fn = len(result.loc[result["necessary"] & ~result["significant"]])
print("True positives", tp)
print("True negatives", tn)
print("False positives", fp)
print("False negatives", fn)
sensitivity = tp / (tp + fp)
specificity = tn / (tn + fp)
bcr = (sensitivity + specificity) / 2
print()
print("sensitivity", sensitivity)
print("specificity", specificity)
print("bcr", bcr)
print("Failed estimates", len(data.loc[~data["result"]]))
else:
print("No successful estimates")