• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mmschlk / shapiq / 18697371034

21 Oct 2025 08:54PM UTC coverage: 92.858% (+0.06%) from 92.799%
18697371034

Pull #431

github

web-flow
Merge 435a34452 into ac5614648
Pull Request #431: Product kernel explainer

186 of 210 new or added lines in 13 files covered. (88.57%)

22 existing lines in 5 files now uncovered.

5214 of 5615 relevant lines covered (92.86%)

0.93 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

86.49
/src/shapiq/explainer/product_kernel/game.py
1
"""Product Kernel Game.
2

3
This module implements the product kernel game defined in https://arxiv.org/abs/2505.16516.
4
It is based on machine learning models using (product) kernels as decision functions.
5
"""
6

7
from __future__ import annotations
1✔
8

9
from typing import TYPE_CHECKING
1✔
10

11
import numpy as np
1✔
12
from sklearn.metrics.pairwise import rbf_kernel
1✔
13

14
from shapiq.game import Game
1✔
15

16
if TYPE_CHECKING:
1✔
NEW
17
    from shapiq.typing import CoalitionMatrix, GameValues
×
18

NEW
19
    from .base import ProductKernelModel
×
20

21

22
class ProductKernelGame(Game):
1✔
23
    r"""Implements the product kernel game.
24

25
    For models using the product kernel as the decision function the game can be formulated as
26
    ..math::
27
        v(S) = \alpha^T (K(X_S, x_S))
28

29
    where K(., .) is the product kernel function, X_S are the samples (support vectors) restricted to the features in S and x_S is the point to explain restricted to the features in S.
30

31
    See https://arxiv.org/abs/2505.16516 for more details.
32

33
    """
34

35
    def __init__(
1✔
36
        self,
37
        n_players: int,
38
        explain_point: np.ndarray,
39
        model: ProductKernelModel,
40
        *,
41
        normalize: bool = False,
42
    ) -> None:
43
        """Initializes the product kernel game.
44

45
        Args:
46
            n_players (int): The number of players in the game.
47
            explain_point (np.ndarray): The point to explain.
48
            model (ProductKernelModel): The product kernel model.
49
            normalize (bool): Whether to normalize the game values.
50

51
        """
52
        self.model = model
1✔
53
        self.explain_point = explain_point
1✔
54
        self.n, self.d = self.model.X_train.shape
1✔
55
        self._X_train = self.model.X_train
1✔
56
        # The empty value can generally be defined by: \sum_{i=1}^n \alpha_i K(x^i, x) - \beta, where x^i are training points / support vectors.
57
        normalization_value: float = float(self.model.alpha.sum()) + model.intercept
1✔
58

59
        super().__init__(n_players, normalization_value=normalization_value, normalize=normalize)
1✔
60

61
    def value_function(self, coalitions: CoalitionMatrix) -> GameValues:
1✔
62
        """The product kernel game value function.
63

64
        Args:
65
            coalitions (CoalitionMatrix): The coalitions to evaluate.
66

67
        Raises:
68
            NotImplementedError: If the kernel type is not supported.
69

70
        Returns:
71
            GameValues: The values of the game for each coalition.
72
        """
73
        alpha = self.model.alpha
1✔
74
        n_coalitions, _ = coalitions.shape
1✔
75
        res = []
1✔
76
        if self.model.kernel_type == "rbf":
1✔
77
            for coalition in range(n_coalitions):
1✔
78
                current_coalition = coalitions[coalition, :]
1✔
79

80
                # The baseline value
81
                if current_coalition.sum() == 0:
1✔
82
                    res.append(float(self.model.alpha.sum()) + self.model.intercept)
1✔
83
                    continue
1✔
84
                # Extract X_S and x_S
85
                coalition_features = self.explain_point[current_coalition]
1✔
86
                X_train = self.model.X_train[:, current_coalition]
1✔
87

88
                # Reshape into twodimensional vectors
89
                if len(coalition_features.shape) == 1:
1✔
90
                    coalition_features = coalition_features.reshape(1, -1)
1✔
91
                if len(X_train.shape) == 1:
1✔
NEW
92
                    X_train = X_train.reshape(1, -1)
×
93

94
                # Compute the RBF kernel
95
                kernel_values = rbf_kernel(X=X_train, Y=coalition_features, gamma=self.model.gamma)
1✔
96

97
                # Compute the decision value
98
                res.append((alpha @ kernel_values + self.model.intercept).squeeze())
1✔
99
        else:
NEW
100
            msg = f"Kernel type '{self.model.kernel_type}' not supported"
×
NEW
101
            raise NotImplementedError(msg)
×
102
        return np.array(res)
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc