shapley_numba package

The shapley_numba package provides high-performance implementations of cooperative game theory computations using Numba JIT compilation.

Subpackages

Core Computational Modules

shapley_numba.common module

Common functions for shapley_numba.

Mostly subset manipulation.

shapley_numba.common.subsets(num_players, self_included=True)[source]

Compute subsets of set with num_players number of elements.

>>> from shapley_numba.common import subsets
>>> for subset in subsets(3):
...     print(subset)
[0 0 0]
[1 0 0]
[0 1 0]
[1 1 0]
[0 0 1]
[1 0 1]
[0 1 1]
[1 1 1]
Parameters:
  • num_players (int) – Number of elements in the set.

  • self_included (bool, default True) – Whether to include the total set.

Returns:

subsets – Generator of subsets. Each subset is a numpy array of length num_players with value 0, 1 depending if element is present in the subset of not

Return type:

generator

shapley_numba.common.subsets_of_subset(subset, self_included=True)[source]

Compute subsets of a subset.

>>> import numpy as np
>>> from shapley_numba.common import subsets_of_subset
>>> for subsubset in subsets_of_subset(np.array([1, 1, 0])):
...     print(subsubset)
[0 0 0]
[1 0 0]
[0 1 0]
[1 1 0]
Parameters:
  • subset (numpy array) – Subset to compute subsets of.

  • self_included (bool (default=True)) – Whether to include the subset itself.

Returns:

subsets – Generator of subsets. Each subset is a numpy array of length of the subset

Return type:

generator

shapley_numba.common.subsets_of_subset_with_base(subset, self_included, base)[source]

Iterate over subsets of a set.

Pure numba implementation, with all the parameters explicit to avoid typing questions.

>>> import numpy as np
>>> from shapley_numba.common import subsets_of_subset_with_base
>>> for subsubset in subsets_of_subset_with_base(np.array([1, 1, 0]),
...                                               self_included=True,
...                                               base=np.array([0, 0, 1])):
...     print(subsubset)
[0 0 1]
[1 0 1]
[0 1 1]
[1 1 1]
Parameters:
  • subset (numpy array) – Subset to compute subsets of.

  • self_included (bool) – Whether to include the subset itself.

  • base (numpy array (CoalitionType)) – A coalition that is held fixed and not iterated upon. If a base position overlaps with a subset position, the subset iteration overwrites it.

Returns:

subsets – Generator of subsets. Each subset is a numpy array of length of the subset

Return type:

generator

shapley_numba.common.combs_jit(num_players, dtype=<class 'numpy.int32'>)[source]

Build choose(num_players, k + 1) array in numba.

Reimplemented because scipy is not compiled in numba.

Returns:

  • np.array of int32 of length num_players - 1,

  • where k’th element is choose(num_players, k + 1)

Return type:

ndarray[tuple[Any, …], dtype[int16]] | ndarray[tuple[Any, …], dtype[int32]] | ndarray[tuple[Any, …], dtype[int64]]

shapley_numba.common.combs(num_players, player)[source]

Return choose(num_players, player).

Reimplemented because scipy is not compiled in numba.

shapley_numba.common.subsets_of_fixed_size(num_players, size)[source]

Compute subsets of fixed size using iterative combinatorial generation.

>>> from shapley_numba.common import subsets_of_fixed_size
>>> for subset in subsets_of_fixed_size(3, 2):
...     print(subset)
[1 1 0]
[1 0 1]
[0 1 1]

This uses a standard combinatorial algorithm to generate all k-combinations of n elements without recursion, making it compatible with Numba’s nopython mode.

Parameters:
  • num_players (int) – Number of players in the game.

  • size (int) – Size of the generated subset

Yields:

NDArray[np.int32] – Each subset as a 1D array of length num_players

shapley_numba.common.mask_to_subset(mask)[source]

Convert mask to subset.

Parameters:

mask (numpy array) – Mask to convert to subset.

Returns:

subset – Subset corresponding to the mask.

Return type:

numpy array

shapley_numba.common.add_subset_size(subsets_iter)[source]

Subset with number of elements in each subset.

shapley_numba.core module

Core functions to work with shapley-numba.

shapley_numba.core.numba_game(gamespec=None)[source]

Decorate the game to allow use of games with numba and without.

The game class needs to implement a value method with parameter subset. subset is a numpy integer array of zeros and ones indicating membership in every subset.

shapley_numba.core.has_jitted_game(game)[source]

Check if the game has a jitted version.

shapley_numba.core.numba_game_func(numba_function)[source]

Apply a jit compiled function onto a numba_game.

shapley_numba.game_templates module

Game templates module.

Provides templates for even easier game authoring.

class shapley_numba.game_templates.ParameterChangeExplanation(old_parameters, new_parameters)[source]

Bases: object

Parameter Change Explanation Template.

The “game” template for computing attribution due to a change in a multi-parameter model.

Provides an attribution to each parameter change.

See BlackScholesCallGame for an example of implementation.

__init__(old_parameters, new_parameters)[source]

Initialize the ParameterChangeExplanation.

model_evaluate(parameters)[source]

Evaluate the model with the given parameters.

value(subset)[source]

Compute the value of a given subset of players.

class shapley_numba.game_templates.TableGame(*args, **kwargs)[source]

Bases: ShapleyNumbaGameProtocol

Table Game Template.

A game where values are stored in a lookup table (dictionary or array). For best results use prepare_table_game to create a numba dictionary from a mapping of tuples to floats.

Without compilation, supply a mapping of ints to floats, where ints represent subsets as binary bits.

>>> import numpy as np
>>> from shapley_numba.game_templates import TableGame
>>> game = TableGame({(0, 1): 1.0, (1, 1): 2.0})
>>> game.value(np.array([1, 0]))
np.float64(0.0)
>>> game.value(np.array([0, 1]))
np.float64(1.0)
>>> game.value(np.array([0, 0]))
np.float64(0.0)
>>> game.value(np.array([1, 1]))
np.float64(2.0)
__init__(*args, **kwargs)
value(subset)

Return value of the game.

Just a convenience method to hide actual class.

jitted_class = None
original_class

alias of TableGame

shapley_numba.harsanyi module

Numba jit compiled computation of Harsanyi dividends.

class shapley_numba.harsanyi.HarsanyiDividends(game, num_players, size=None)[source]

Bases: object

Harsanyi Dividends class.

Wrapper for the numba jit compiled function.

Usage: ```python game = GloveGame(2)

hd = HarsanyiDividends(game, 5, 3)

hd(np.array([1, 1, 0, 0, 0]) ```

__init__(game, num_players, size=None)[source]

Initialize the HarsanyiDividends class.

Compute all dividends up to size size and store them as a map

Parameters:
  • game (ShapleyNumbaGameProtocol) – A game wrapped with the numba_game decorator.

  • num_players (int) – Number of players in the game.

  • size (int | None, optional) – Maximum coalition size to compute dividends for. If None, computes for all coalition sizes. Default is None.

Raises:

NotImplementedError – If the game is not JIT-compiled.

shapley_numba.harsanyi_naive module

Compute Harsanyi dividends via the naive formula.

shapley_numba.harsanyi_naive.harsanyi_dividends(game, subset, use_numba=True)[source]

Compute the naive version of Harsanyi dividends.

shapley_numba.shapley module

Shapley value computation using numba.

Provides a jitted version of Shapley value computation. And Monte Carlo approximation of Shapley value.

shapley_numba.shapley.shapley(game, num_players, *, use_numba=True)[source]

Compute shapley value of a game.

Parameters:
  • game (ShapleyNumbaGameProtocol) – numba-game or a class that implements value function.

  • num_players (int) – number of players in the game.

  • use_numba (bool) – try to use numba-compiled version of the game.

Return type:

np.array[np.float64] - shapley value of the game.

Raises:

ValueError - when use_numba=True but – the game failed to be compiled with numba or was never compiled.

shapley_numba.shapley.shapley_perm_mc(game, num_players, paths=40000, seed=3735928559, use_numba=True, *, anthithetic=True)[source]

Compute shapley value of a game using permutation Monte Carlo.

Parameters:
  • game (object) – Game object with value method.

  • num_players (int) – Number of players in the game.

  • paths (int, optional) – Number of Monte Carlo paths, by default 4e4.

  • seed (int, optional) – Seed for random number generator, by default 0xDEADBEEF in order to maintain reproducibility. Pass None to get a random result.

  • use_numba (bool, optional) – Whether to use numba jit compiled function, by default True.

  • anthithetic (bool, optional (default True)) – Apply anthithetic sampling.

Returns:

Shapley value for each player.

Return type:

numpy.ndarray

Raises:

ValueError – If the game fails to compile with numba and use_numba is True. If the game does not implement a value method and use_numba is False.

shapley_numba.tools module

Tools for games.

Currently only creating dual game for peel-off Harsanyi dividends..

shapley_numba.typing module

shapley_numba.tools.dual_game(game, num_players)[source]

Create the dual of the game.

The dual game is useful for computing “peel-off” Harsanyi dividends.

Parameters:
Returns:

The dual game wrapped with numba_game decorator.

Return type:

ShapleyNumbaGameProtocol


Typing concepts for shapley_numba.

This module provides Protocol definitions and type aliases for working with cooperative games in shapley-numba.

Examples

Define a custom game that implements the GameProtocol:

import numpy as np
from shapley_numba import GameProtocol, CoalitionType, numba_game

@numba_game()
class MyGame:
    def __init__(self, data):
        self.data = data

    def value(self, subset: CoalitionType) -> np.float64:
        # Return value for the given coalition
        return np.float64(np.sum(self.data * subset))

# Use with shapley value computation
game = MyGame(np.array([1.0, 2.0, 3.0]))
# shapley_values = shapley(game, num_players=3)
shapley_numba.typing.CoalitionType

binary array where 1 = player in coalition.

A coalition is represented as a binary array where each element corresponds to a player. A value of 1 indicates the player is in the coalition, and 0 indicates they are not.

Example: For 3 players, the coalition {0, 2} is represented as [1, 0, 1].

Type:

Type for coalition representation

alias of ndarray[tuple[Any, …], dtype[int32]]

class shapley_numba.typing.GameProtocol(*args, **kwargs)[source]

Bases: Protocol

Protocol that defines the interface for a cooperative game.

Any class implementing this protocol can be used with shapley-numba functions. The only requirement is a value method that computes the worth of a coalition.

value(subset: CoalitionType) float64[source]

Compute the value (worth) of a given coalition of players.

value(subset)[source]

Return the value of coalition.

Parameters:

subset (CoalitionType) – Binary array indicating which players are in the coalition.

Returns:

The value (worth) of the coalition.

Return type:

float64

__init__(*args, **kwargs)
class shapley_numba.typing.ShapleyNumbaGameProtocol(*args, **kwargs)[source]

Bases: Protocol

Protocol for games wrapped by the numba_game decorator.

When a game class is decorated with @numba_game, it gains additional attributes that provide both regular and JIT-compiled versions of the game. This protocol describes the interface of such decorated games.

game

The original (non-compiled) game instance.

Type:

GameProtocol

jitted_game

The numba JIT-compiled game instance, or an Exception if compilation failed.

Type:

GameProtocol | Exception

value(subset: CoalitionType) float64[source]

Compute the value of a coalition, automatically using the compiled version if available, otherwise falling back to the Python version.

game: GameProtocol
jitted_game: GameProtocol | Exception
value(subset)[source]

Return the value of coalition.

Parameters:

subset (CoalitionType) – Binary array indicating which players are in the coalition.

Returns:

The value (worth) of the coalition.

Return type:

float64

__init__(*args, **kwargs)
shapley_numba.typing.GameSpecType: TypeAlias = dict[str, type] | list[tuple[str, type]] | None

Type for numba jitclass specifications.

The game specification defines the types of attributes in a game class for numba compilation. Can be: - A dictionary mapping attribute names to types: {‘attr’: numba.float64} - A list of tuples: [(‘attr’, numba.float64)] - None for games without attributes or auto-detection

Module contents

Shapley Numba.

Compute values of cooperative games in python more efficiently, using numba. Shapley-numba aims to provide tools to author cooperative games and compute various functions connected to them more efficiently.

Package structure

core.py - contains the main decorator numba_game. shapley.py - contains implementations of computing or approximating Shapley values. harsanyi.py - contains implementation of Harsanyi dividends (also known as synergies). tools.py - contains tools for working with games. game_templates.py - contains templates for creating new games. typing.py - contains type definitions and protocols for type checking.

shapley_numba.numba_game(gamespec=None)[source]

Decorate the game to allow use of games with numba and without.

The game class needs to implement a value method with parameter subset. subset is a numpy integer array of zeros and ones indicating membership in every subset.

class shapley_numba.GameProtocol(*args, **kwargs)[source]

Bases: Protocol

Protocol that defines the interface for a cooperative game.

Any class implementing this protocol can be used with shapley-numba functions. The only requirement is a value method that computes the worth of a coalition.

value(subset: CoalitionType) float64[source]

Compute the value (worth) of a given coalition of players.

__init__(*args, **kwargs)
value(subset)[source]

Return the value of coalition.

Parameters:

subset (CoalitionType) – Binary array indicating which players are in the coalition.

Returns:

The value (worth) of the coalition.

Return type:

float64

class shapley_numba.ShapleyNumbaGameProtocol(*args, **kwargs)[source]

Bases: Protocol

Protocol for games wrapped by the numba_game decorator.

When a game class is decorated with @numba_game, it gains additional attributes that provide both regular and JIT-compiled versions of the game. This protocol describes the interface of such decorated games.

game

The original (non-compiled) game instance.

Type:

GameProtocol

jitted_game

The numba JIT-compiled game instance, or an Exception if compilation failed.

Type:

GameProtocol | Exception

value(subset: CoalitionType) float64[source]

Compute the value of a coalition, automatically using the compiled version if available, otherwise falling back to the Python version.

__init__(*args, **kwargs)
value(subset)[source]

Return the value of coalition.

Parameters:

subset (CoalitionType) – Binary array indicating which players are in the coalition.

Returns:

The value (worth) of the coalition.

Return type:

float64

game: GameProtocol
jitted_game: GameProtocol | Exception