Skip to content

Commit e3d4331

Browse files
authored
Merge pull request #2 from pat-alt/camera-ready-branch
Camera ready branch
2 parents 1c20597 + ad8ec4a commit e3d4331

26 files changed

+219
-159
lines changed

Manifest.toml

Lines changed: 71 additions & 70 deletions
Large diffs are not rendered by default.

dev/poster/poster.pptx

1.96 MB
Binary file not shown.

dev/poster/www/logo-repo.png

6.24 KB
Loading

dev/poster/www/logo_appendix.png

16.8 KB
Loading

dev/poster/www/logo_package.png

11 KB
Loading

dev/poster/www/qr-appendix.png

71.7 KB
Loading

dev/poster/www/qr-package.png

25.5 KB
Loading

dev/poster/www/qr-repo.png

29.7 KB
Loading

dev/poster/~$poster.pptx

165 Bytes
Binary file not shown.

intro.qmd

Lines changed: 40 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,22 +15,17 @@ To start with, we will look at a proof-of-concept that demonstrates the main obs
1515

1616
We begin by generating the synthetic data for a simple binary classification problem. For illustrative purposes, we will use data that is linearly separable. The chart below shows the data $\mathcal{D}$ at time zero, before any implementation of recourse.
1717

18+
1819
```{julia}
1920
#| output: true
2021
#| label: fig-data
2122
#| fig-cap: "Linearly separable synthetic data"
2223
23-
N = 1000
24-
xmax = 2
25-
X, ys = make_blobs(
26-
N, 2;
27-
centers=2, as_table=false, center_box=(-xmax => xmax), cluster_std=0.1
28-
)
29-
ys .= ys.==2
30-
X = X'
31-
xs = Flux.unstack(X,2)
32-
data = zip(xs,ys)
33-
counterfactual_data = CounterfactualData(X,ys')
24+
max_obs = 1000
25+
catalogue = load_synthetic(max_obs)
26+
counterfactual_data = catalogue[:linearly_separable]
27+
X = counterfactual_data.X
28+
ys = vec(counterfactual_data.y)
3429
plot()
3530
scatter!(counterfactual_data)
3631
```
@@ -44,6 +39,7 @@ n_epochs = 100
4439
model = Chain(Dense(2,1))
4540
mod = FluxModel(model)
4641
Models.train(mod, counterfactual_data; n_epochs=n_epochs)
42+
mod_orig = deepcopy(mod)
4743
```
4844

4945
@fig-model below shows the linear separation of the two classes.
@@ -72,7 +68,7 @@ Markdown.parse(
7268
```
7369

7470
```{julia}
75-
opt = Flux.Adam(0.01)
71+
opt = Flux.Descent(0.01)
7672
gen = GenericGenerator(;decision_threshold=γ, opt=opt)
7773
```
7874

@@ -143,5 +139,37 @@ plt_single_repeat = plot(mod,counterfactual_data′;zoom=0,colorbar=false,title=
143139
144140
plt = plot(plt_original, plt_single, plt_single_retrained, plt_single_repeat, layout=(1,4), legend=false, axis=nothing, size=(600,165))
145141
savefig(plt, joinpath(www_path, "poc.png"))
142+
savefig(plt, "paper/www/poc.png")
143+
display(plt)
144+
```
145+
146+
## Mitigation Strategies
147+
148+
```{julia}
149+
#| output: true
150+
#| label: fig-mitigate
151+
#| fig-cap: "Mitigation strategies."
152+
153+
# Generators:
154+
generators = Dict(
155+
"Generic (γ=0.5)" => GenericGenerator(opt = opt, decision_threshold=0.5),
156+
"Generic (γ=0.9)" => GenericGenerator(opt = opt, decision_threshold=0.9),
157+
"Gravitational" => GravitationalGenerator(opt = opt),
158+
"ClaPROAR" => ClapROARGenerator(opt = opt)
159+
)
160+
161+
# Counterfactuals
162+
x = select_factual(counterfactual_data, rand(candidates))
163+
counterfactuals = Dict([name => generate_counterfactual(x, 1, counterfactual_data, mod_orig, gen;) for (name, gen) in generators])
164+
165+
# Plots:
166+
plts = []
167+
for (name,ce) ∈ counterfactuals
168+
plt = plot(ce; title=name, colorbar=false, ticks = false, legend=false, zoom=0)
169+
plts = vcat(plts..., plt)
170+
end
171+
plt = plot(plts..., size=(750,200), layout=(1,4))
172+
savefig(plt, joinpath(www_path, "mitigation.png"))
173+
savefig(plt, "paper/www/mitigation.png")
146174
display(plt)
147175
```

0 commit comments

Comments
 (0)