Computational branches
If you have multiple forks, they should all have the same branches. Each branch will execute independently of the rest (non-fork inputs are shared between them). You can even create machine learning model forks, where a different model is applied on different branches:
from sklearn.linear_model import LogisticRegression, MLPClassifier
x, y = ...
classifier = fb.Fork(case1=LogisticRegression(), case2=MLPClassifier())
classifier = classifier.fit(x, y)
yhat = classifier.predict(x)
Forks automatically try to call wrapped class methods,
i.e., classifier.fit
is also a fork whose branches
hold the outcome of applying fit
on each branch's model.
The inputs x,y
could also have been forks,
in which case each branch would have been trained on
respective values.
Recall that branch values can be accessed via class fields,
for example like yhat = (yhat.case1+yhat.case2)/2
. This
computation produces a factual value that is not
bound to any branch. On the other hand yhat.case1
and yhat.case2
would be used during assessment of
case1 sensitive attribute values and case2 sensitive
attribute values.
print(classifier)
# case2: MLPClassifier()
# case1: LogisticRegression()
print(yhat)
# case2: [0 1 0 1 0 1 1 1]
# case1: [0 1 0 1 1 1 1 1]
print((yhat.case1+yhat.case2)/2)
# [0. 1. 0. 1. 0.5 1. 1. 1. ]
A visual view of how data are organized across branches follows. Some variables are identical but others obtain different values per branch. The same code is run on all branches concurrently and independently.
Tip
Use branches to run several computation pipelines concurrently.
Danger
Avoid overlapping names between branches and class fields or methods, as they are both accessed with the same annotation. If there is confusion, branch values will be obtained.