|
3 | 3 | from numba import int32, float64 |
4 | 4 |
|
5 | 5 | from skglm.datafits.base import BaseDatafit |
6 | | -from skglm.datafits.single_task import Logistic |
| 6 | +from skglm.datafits.single_task import Logistic, Poisson |
7 | 7 | from skglm.utils.sparse_ops import spectral_norm, sparse_columns_slice |
8 | 8 |
|
9 | 9 |
|
@@ -161,3 +161,52 @@ def gradient_g(self, X, y, w, Xw, g): |
161 | 161 | grad_g[idx] = X[:, j] @ raw_grad_val |
162 | 162 |
|
163 | 163 | return grad_g |
| 164 | + |
| 165 | + |
| 166 | +class PoissonGroup(Poisson): |
| 167 | + r"""Poisson datafit used with group penalties. |
| 168 | +
|
| 169 | + The datafit reads: |
| 170 | +
|
| 171 | + .. math:: 1 / n_"samples" \sum_{i=1}^{n_"samples"} (\exp((Xw)_i) - y_i (Xw)_i) |
| 172 | +
|
| 173 | + Attributes |
| 174 | + ---------- |
| 175 | + grp_indices : array, shape (n_features,) |
| 176 | + The group indices stacked contiguously |
| 177 | + ``[grp1_indices, grp2_indices, ...]``. |
| 178 | +
|
| 179 | + grp_ptr : array, shape (n_groups + 1,) |
| 180 | + The group pointers such that two consecutive elements delimit |
| 181 | + the indices of a group in ``grp_indices``. |
| 182 | + """ |
| 183 | + |
| 184 | + def __init__(self, grp_ptr, grp_indices): |
| 185 | + self.grp_ptr, self.grp_indices = grp_ptr, grp_indices |
| 186 | + |
| 187 | + def get_spec(self): |
| 188 | + return ( |
| 189 | + ('grp_ptr', int32[:]), |
| 190 | + ('grp_indices', int32[:]), |
| 191 | + ) |
| 192 | + |
| 193 | + def params_to_dict(self): |
| 194 | + return dict(grp_ptr=self.grp_ptr, grp_indices=self.grp_indices) |
| 195 | + |
| 196 | + def gradient_g(self, X, y, w, Xw, g): |
| 197 | + grp_ptr, grp_indices = self.grp_ptr, self.grp_indices |
| 198 | + grp_g_indices = grp_indices[grp_ptr[g]: grp_ptr[g+1]] |
| 199 | + raw_grad_val = self.raw_grad(y, Xw) |
| 200 | + grad_g = np.zeros(len(grp_g_indices)) |
| 201 | + for idx, j in enumerate(grp_g_indices): |
| 202 | + grad_g[idx] = X[:, j] @ raw_grad_val |
| 203 | + return grad_g |
| 204 | + |
| 205 | + def gradient_g_sparse(self, X_data, X_indptr, X_indices, y, w, Xw, g): |
| 206 | + grp_ptr, grp_indices = self.grp_ptr, self.grp_indices |
| 207 | + grp_g_indices = grp_indices[grp_ptr[g]: grp_ptr[g+1]] |
| 208 | + grad_g = np.zeros(len(grp_g_indices)) |
| 209 | + for idx, j in enumerate(grp_g_indices): |
| 210 | + grad_g[idx] = self.gradient_scalar_sparse( |
| 211 | + X_data, X_indptr, X_indices, y, Xw, j) |
| 212 | + return grad_g |
0 commit comments