# Environment.fairnessMeasures module¶

Define some function to measure fairness of a vector of cumulated rewards, of shape (nbPlayers, horizon).

• All functions are valued in $$[0, 1]$$: $$100\%$$ means fully unfair (one player has $$0$$ rewards, another one has $$>0$$ rewards), and $$0\%$$ means fully fair (they all have exactly the same rewards).

Environment.fairnessMeasures.amplitude_fairness(X, axis=0)[source]

(Normalized) Amplitude fairness, homemade formula: $$1 - \min(X, axis) / \max(X, axis)$$.

Examples:

>>> import numpy.random as rn; rn.seed(1)  # for reproductibility
>>> X = np.cumsum(rn.rand(10, 1000))
>>> amplitude_fairness(X)
0.999...
>>> amplitude_fairness(X ** 2)  # More spreadout
0.999...
>>> amplitude_fairness(np.log(1 + np.abs(X)))  # Less spreadout
0.959...

>>> rn.seed(3)  # for reproductibility
>>> X = rn.randint(0, 10, (10, 1000)); Y = np.cumsum(X, axis=1)
>>> np.min(Y, axis=0)[0], np.max(Y, axis=0)[0]
(3, 9)
>>> np.min(Y, axis=0)[-1], np.max(Y, axis=0)[-1]
(4387, 4601)
>>> amplitude_fairness(Y, axis=0).shape
(1000,)
>>> list(amplitude_fairness(Y, axis=0))
[0.666..., 0.764..., ..., 0.0465...]

>>> X[X >= 3] = 3; Y = np.cumsum(X, axis=1)
>>> np.min(Y, axis=0)[0], np.max(Y, axis=0)[0]
(3, 3)
>>> np.min(Y, axis=0)[-1], np.max(Y, axis=0)[-1]
(2353, 2433)
>>> amplitude_fairness(Y, axis=0).shape
(1000,)
>>> list(amplitude_fairness(Y, axis=0))  # Less spreadout
[0.0, 0.5, ..., 0.0328...]

Environment.fairnessMeasures.std_fairness(X, axis=0)[source]

(Normalized) Standard-variation fairness, homemade formula: $$2 * \mathrm{std}(X, axis) / \max(X, axis)$$.

Examples:

>>> import numpy.random as rn; rn.seed(1)  # for reproductibility
>>> X = np.cumsum(rn.rand(10, 1000))
>>> std_fairness(X)
0.575...
>>> std_fairness(X ** 2)  # More spreadout
0.594...
0.470...

>>> rn.seed(2)  # for reproductibility
>>> X = np.cumsum(rn.randint(0, 10, (10, 100)))
>>> std_fairness(X)
0.570...
>>> std_fairness(X ** 2)  # More spreadout
0.587...
0.463...

Environment.fairnessMeasures.rajjain_fairness(X, axis=0)[source]

Raj Jain’s fairness index: $$(\sum_{i=1}^{n} x_i)^2 / (n \times \sum_{i=1}^{n} x_i^2)$$, projected to $$[0, 1]$$ instead of $$[\frac{1}{n}, 1]$$ as introduced in the reference article.

Examples:

>>> import numpy.random as rn; rn.seed(1)  # for reproductibility
>>> X = np.cumsum(rn.rand(10, 1000))
>>> rajjain_fairness(X)
0.248...
>>> rajjain_fairness(X ** 2)  # More spreadout
0.441...
0.110...

>>> rn.seed(2)  # for reproductibility
>>> X = np.cumsum(rn.randint(0, 10, (10, 100)))
>>> rajjain_fairness(X)
0.246...
>>> rajjain_fairness(X ** 2)  # More spreadout
0.917...
0.107...

Environment.fairnessMeasures.mo_walrand_fairness(X, axis=0, alpha=2)[source]

Mo and Walrand’s family fairness index: $$U_{\alpha}(X)$$, NOT projected to $$[0, 1]$$.

$\begin{split}U_{\alpha}(X) = \begin{cases} \frac{1}{1 - \alpha} \sum_{i=1}^n x_i^{1 - \alpha} & \;\text{if}\; \alpha\in[0,+\infty)\setminus\{1\}, \\ \sum_{i=1}^{n} \ln(x_i) & \;\text{otherwise}. \end{cases}\end{split}$

Examples:

>>> import numpy.random as rn; rn.seed(1)  # for reproductibility
>>> X = np.cumsum(rn.rand(10, 1000))

>>> alpha = 0
>>> mo_walrand_fairness(X, alpha=alpha)
24972857.013...
>>> mo_walrand_fairness(X ** 2, alpha=alpha)  # More spreadout
82933940429.039...
>>> mo_walrand_fairness(np.sqrt(np.abs(X)), alpha=alpha)  # Less spreadout
471371.219...

>>> alpha = 0.99999
>>> mo_walrand_fairness(X, alpha=alpha)
1000075176.390...
>>> mo_walrand_fairness(X ** 2, alpha=alpha)  # More spreadout
1000150358.528...
>>> mo_walrand_fairness(np.sqrt(np.abs(X)), alpha=alpha)  # Less spreadout
1000037587.478...

>>> alpha = 1
>>> mo_walrand_fairness(X, alpha=alpha)
75173.509...
>>> mo_walrand_fairness(X ** 2, alpha=alpha)  # More spreadout
150347.019...
>>> mo_walrand_fairness(np.sqrt(np.abs(X)), alpha=alpha)  # Less spreadout
37586.754...

>>> alpha = 1.00001
>>> mo_walrand_fairness(X, alpha=alpha)
-999924829.359...
>>> mo_walrand_fairness(X ** 2, alpha=alpha)  # More spreadout
-999849664.476...
>>> mo_walrand_fairness(np.sqrt(np.abs(X)), alpha=alpha)  # Less spreadout
-999962413.957...

>>> alpha = 2
>>> mo_walrand_fairness(X, alpha=alpha)
-22.346...
>>> mo_walrand_fairness(X ** 2, alpha=alpha)  # More spreadout
-9.874...
>>> mo_walrand_fairness(np.sqrt(np.abs(X)), alpha=alpha)  # Less spreadout
-283.255...

>>> alpha = 5
>>> mo_walrand_fairness(X, alpha=alpha)
-8.737...
>>> mo_walrand_fairness(X ** 2, alpha=alpha)  # More spreadout
-273.522...
>>> mo_walrand_fairness(np.sqrt(np.abs(X)), alpha=alpha)  # Less spreadout
-2.468...

Environment.fairnessMeasures.mean_fairness(X, axis=0, methods=(<function amplitude_fairness>, <function std_fairness>, <function rajjain_fairness>))[source]

Fairness index, based on mean of the 3 fairness measures: Amplitude, STD and Raj Jain fairness.

Examples:

>>> import numpy.random as rn; rn.seed(1)  # for reproductibility
>>> X = np.cumsum(rn.rand(10, 1000))
>>> mean_fairness(X)
0.607...
>>> mean_fairness(X ** 2)  # More spreadout
0.678...
0.523...

>>> rn.seed(2)  # for reproductibility
>>> X = np.cumsum(rn.randint(0, 10, (10, 100)))
>>> mean_fairness(X)
0.605...
>>> mean_fairness(X ** 2)  # More spreadout
0.834...

Environment.fairnessMeasures.fairnessMeasure(X, axis=0, methods=(<function amplitude_fairness>, <function std_fairness>, <function rajjain_fairness>))
Environment.fairnessMeasures.fairness_mapping = {'Amplitude': <function amplitude_fairness>, 'Default': <function mean_fairness>, 'Mean': <function mean_fairness>, 'MoWalrand': <function mo_walrand_fairness>, 'RajJain': <function rajjain_fairness>, 'STD': <function std_fairness>}