Skip to content

Commit bb09503

Browse files
authored
Merge pull request #63 from pat-alt/original-paper
added registry version
2 parents 5113df7 + 5cd86d0 commit bb09503

File tree

13 files changed

+10379
-16
lines changed

13 files changed

+10379
-16
lines changed

.github/workflows/CI.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ jobs:
1818
fail-fast: false
1919
matrix:
2020
version:
21-
- '1.6'
2221
- '1.7'
2322
- '1.8'
2423
- 'nightly'

Project.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
2626
StatsBase = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91"
2727

2828
[compat]
29-
CounterfactualExplanations = "0.1.4"
3029
CSV = "0.10"
3130
DataFrames = "1"
3231
Distances = "0.10"
@@ -40,7 +39,7 @@ Plots = "1.37.2"
4039
ProgressMeter = "1"
4140
RCall = "0.13.14"
4241
StatsBase = "0.33"
43-
julia = "1.6, 1.7, 1.8"
42+
julia = "1.7, 1.8"
4443

4544
[extras]
4645
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

README.md

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
## Basic Usage
99

10-
### Data and Model
10+
Below we first generate some synthetic data for a binary classification task and instantiate an instance of `CounterfactualData`.
1111

1212
``` julia
1313
N = 1000
@@ -21,43 +21,57 @@ X = X'
2121
counterfactual_data = CounterfactualData(X,ys')
2222
```
2323

24+
We then define a simple model for the task and prepare it for use with `CounterfactualExplanations.jl`:
25+
2426
``` julia
2527
n_epochs = 100
2628
model = Chain(Dense(2,1))
2729
mod = FluxModel(model)
30+
```
2831

32+
To generate algorithmic recourse, we will use a simple generic generator:
33+
34+
``` julia
2935
generator = GenericGenerator()
3036
```
3137

38+
Finally we train our model on a subset of the data. The chart below shows the results.
39+
3240
``` julia
3341
data_train, data_test = Data.train_test_split(counterfactual_data)
3442
Models.train(mod, data_train; n_epochs=n_epochs)
3543
plt_original = plot(mod, counterfactual_data; zoom=0, colorbar=false)
3644
display(plt_original)
3745
```
3846

39-
![](README_files/figure-commonmark/cell-5-output-1.svg)
47+
![](README_files/figure-commonmark/cell-6-output-1.svg)
4048

4149
### Simulation
4250

51+
To model the dynamics of algorithmic recourse, we use simulations, in which we repeatedly select as subset of individuals from the non-target class, generate and implement recourse for all of them and finally retrain the model. To set this experiment up, we can use the code below:
52+
4353
``` julia
4454
models = Dict(:mymodel => mod)
4555
generators = Dict(:wachter => generator)
4656
experiment = set_up_experiment(data_train, data_test, models, generators)
4757
```
4858

59+
Finally, we just run the experiment using default parameter settings that specify the number of rounds, the proportion of individuals to select for recourse and related aspects:
60+
4961
``` julia
5062
run!(experiment)
5163
```
5264

65+
The chart below shows the data and predictions at the end of the simulation:
66+
5367
``` julia
5468
new_data = experiment.recourse_systems[1][1].data
5569
new_model = experiment.recourse_systems[1][1].model
5670
plt_original = plot(new_model, new_data; zoom=0, colorbar=false)
5771
```
5872

59-
![](README_files/figure-commonmark/cell-8-output-1.svg)
73+
![](README_files/figure-commonmark/cell-9-output-1.svg)
6074

6175
## Related Research Paper 📝
6276

63-
The package was developed for a research project that investigates the dynamics of various counterfactual generators.
77+
The package was developed for a research project that investigates the dynamics of various counterfactual generators. You can find the details [here](https://github.com/pat-alt/endogenous-macrodynamics-in-algorithmic-recourse).

README_files/figure-commonmark/cell-6-output-1.svg

Lines changed: 1793 additions & 0 deletions
Loading

README_files/figure-commonmark/cell-9-output-1.svg

Lines changed: 1625 additions & 0 deletions
Loading
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"hash": "c09a7fb63498691e9bb0649a137d89b5",
3+
"result": {
4+
"markdown": "```@meta\nCurrentModule = AlgorithmicRecourseDynamics\n```\n\n# AlgorithmicRecourseDynamics\n\nDocumentation for [AlgorithmicRecourseDynamics.jl](https://github.com/pat-alt/AlgorithmicRecourseDynamics.jl).\n\n\n\n`AlgorithmicRecourseDynamics.jl` is a small package for modeling Algorithmic Recourse Dynamics. It builds on `CounterfactualExplanations`, a package for generating counterfactual explanations.\n\n## Basic Usage\n\nBelow we first generate some synthetic data for a binary classification task and instantiate an instance of `CounterfactualData`.\n\n::: {.cell execution_count=2}\n``` {.julia .cell-code}\nN = 1000\nxmax = 2\nX, ys = make_blobs(\n N, 2; \n centers=2, as_table=false, center_box=(-xmax => xmax), cluster_std=0.1\n)\nys .= ys.==2\nX = X'\ncounterfactual_data = CounterfactualData(X,ys')\n```\n:::\n\n\nWe then define a simple model for the task and prepare it for use with `CounterfactualExplanations.jl`:\n\n::: {.cell execution_count=3}\n``` {.julia .cell-code}\nn_epochs = 100\nmodel = Chain(Dense(2,1))\nmod = FluxModel(model)\n```\n:::\n\n\nTo generate algorithmic recourse, we will use a simple generic generator:\n\n::: {.cell execution_count=4}\n``` {.julia .cell-code}\ngenerator = GenericGenerator()\n```\n:::\n\n\nFinally we train our model on a subset of the data. The chart below shows the results.\n\n::: {.cell execution_count=5}\n``` {.julia .cell-code}\ndata_train, data_test = Data.train_test_split(counterfactual_data)\nModels.train(mod, data_train; n_epochs=n_epochs)\nplt_original = plot(mod, counterfactual_data; zoom=0, colorbar=false)\ndisplay(plt_original)\n```\n\n::: {.cell-output .cell-output-display}\n![](index_files/figure-commonmark/cell-6-output-1.svg){}\n:::\n:::\n\n\n### Simulation\n\nTo model the dynamics of algorithmic recourse, we use simulations, in which we repeatedly select as subset of individuals from the non-target class, generate and implement recourse for all of them and finally retrain the model. To set this experiment up, we can use the code below:\n\n::: {.cell execution_count=6}\n``` {.julia .cell-code}\nmodels = Dict(:mymodel => mod)\ngenerators = Dict(:wachter => generator)\nexperiment = set_up_experiment(data_train, data_test, models, generators)\n```\n:::\n\n\nFinally, we just run the experiment using default parameter settings that specify the number of rounds, the proportion of individuals to select for recourse and related aspects:\n\n::: {.cell execution_count=7}\n``` {.julia .cell-code}\nrun!(experiment)\n```\n\n::: {.cell-output .cell-output-display execution_count=8}\n\\begin{tabular}{r|ccccccccc}\n\t& value & p\\_value & name & scope & k & n & model & generator & \\\\\n\t\\hline\n\t& Float64 & Float64? & Symbol & Symbol & Int64 & Int64 & Symbol & Symbol & \\\\\n\t\\hline\n\t1 & -0.000308861 & \\emph{missing} & mmd & domain & 1 & 0 & mymodel & wachter & $\\dots$ \\\\\n\t2 & 0.0 & \\emph{missing} & perturbation & model & 1 & 0 & mymodel & wachter & $\\dots$ \\\\\n\t3 & -0.000865245 & \\emph{missing} & mmd & model & 1 & 0 & mymodel & wachter & $\\dots$ \\\\\n\t4 & -0.000790169 & \\emph{missing} & mmd\\_grid & model & 1 & 0 & mymodel & wachter & $\\dots$ \\\\\n\t5 & 0.0 & \\emph{missing} & disagreement & model & 1 & 0 & mymodel & wachter & $\\dots$ \\\\\n\t6 & 0.0 & \\emph{missing} & decisiveness & model & 1 & 0 & mymodel & wachter & $\\dots$ \\\\\n\t7 & 0.0 & \\emph{missing} & model\\_performance & model & 1 & 0 & mymodel & wachter & $\\dots$ \\\\\n\t8 & 0.0859171 & 0.0 & mmd & domain & 1 & 10 & mymodel & wachter & $\\dots$ \\\\\n\t9 & 2.29844 & \\emph{missing} & perturbation & model & 1 & 10 & mymodel & wachter & $\\dots$ \\\\\n\t10 & -0.000654647 & 1.0 & mmd & model & 1 & 10 & mymodel & wachter & $\\dots$ \\\\\n\t11 & 0.0867767 & 0.0 & mmd\\_grid & model & 1 & 10 & mymodel & wachter & $\\dots$ \\\\\n\t12 & 0.0 & \\emph{missing} & disagreement & model & 1 & 10 & mymodel & wachter & $\\dots$ \\\\\n\t13 & 0.216456 & \\emph{missing} & decisiveness & model & 1 & 10 & mymodel & wachter & $\\dots$ \\\\\n\t14 & 0.0 & \\emph{missing} & model\\_performance & model & 1 & 10 & mymodel & wachter & $\\dots$ \\\\\n\t15 & -0.000308861 & \\emph{missing} & mmd & domain & 2 & 0 & mymodel & wachter & $\\dots$ \\\\\n\t16 & 0.0 & \\emph{missing} & perturbation & model & 2 & 0 & mymodel & wachter & $\\dots$ \\\\\n\t17 & -0.000865245 & \\emph{missing} & mmd & model & 2 & 0 & mymodel & wachter & $\\dots$ \\\\\n\t18 & -0.000791949 & \\emph{missing} & mmd\\_grid & model & 2 & 0 & mymodel & wachter & $\\dots$ \\\\\n\t19 & 0.0 & \\emph{missing} & disagreement & model & 2 & 0 & mymodel & wachter & $\\dots$ \\\\\n\t20 & 0.0 & \\emph{missing} & decisiveness & model & 2 & 0 & mymodel & wachter & $\\dots$ \\\\\n\t21 & 0.0 & \\emph{missing} & model\\_performance & model & 2 & 0 & mymodel & wachter & $\\dots$ \\\\\n\t22 & 0.105827 & 0.0 & mmd & domain & 2 & 10 & mymodel & wachter & $\\dots$ \\\\\n\t23 & 2.39989 & \\emph{missing} & perturbation & model & 2 & 10 & mymodel & wachter & $\\dots$ \\\\\n\t24 & -0.000623466 & 1.0 & mmd & model & 2 & 10 & mymodel & wachter & $\\dots$ \\\\\n\t25 & 0.0969255 & 0.0 & mmd\\_grid & model & 2 & 10 & mymodel & wachter & $\\dots$ \\\\\n\t26 & 0.0 & \\emph{missing} & disagreement & model & 2 & 10 & mymodel & wachter & $\\dots$ \\\\\n\t27 & 0.2318 & \\emph{missing} & decisiveness & model & 2 & 10 & mymodel & wachter & $\\dots$ \\\\\n\t28 & 0.0 & \\emph{missing} & model\\_performance & model & 2 & 10 & mymodel & wachter & $\\dots$ \\\\\n\t29 & -0.000308861 & \\emph{missing} & mmd & domain & 3 & 0 & mymodel & wachter & $\\dots$ \\\\\n\t30 & 0.0 & \\emph{missing} & perturbation & model & 3 & 0 & mymodel & wachter & $\\dots$ \\\\\n\t$\\dots$ & $\\dots$ & $\\dots$ & $\\dots$ & $\\dots$ & $\\dots$ & $\\dots$ & $\\dots$ & $\\dots$ & \\\\\n\\end{tabular}\n\n:::\n:::\n\n\nThe chart below shows the data and predictions at the end of the simulation:\n\n::: {.cell execution_count=8}\n``` {.julia .cell-code}\nnew_data = experiment.recourse_systems[1][1].data\nnew_model = experiment.recourse_systems[1][1].model\nplt_original = plot(new_model, new_data; zoom=0, colorbar=false)\n```\n\n::: {.cell-output .cell-output-display execution_count=9}\n![](index_files/figure-commonmark/cell-9-output-1.svg){}\n:::\n:::\n\n\n## Related Research Paper 📝\n\nThe package was developed for a research project that investigates the dynamics of various counterfactual generators. You can find the details [here](https://github.com/pat-alt/endogenous-macrodynamics-in-algorithmic-recourse).\n\n",
5+
"supporting": [
6+
"index_files"
7+
],
8+
"filters": []
9+
}
10+
}

0 commit comments

Comments
 (0)