Skip to content

Commit 9957180

Browse files
author
Christian Jorgensen
committed
Adding score methods for multiclass-multilabel problems
1 parent e008a65 commit 9957180

File tree

2 files changed

+34
-12
lines changed

2 files changed

+34
-12
lines changed

src/skmatter/decomposition/_kernel_pcovc.py

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ class KernelPCovC(LinearClassifierMixin, _BaseKPCov):
5353
5454
n_components == n_samples
5555
56-
n_outputs : int
56+
n_outputs_ : int
5757
The number of outputs when ``fit`` is performed.
5858
5959
svd_solver : {'auto', 'full', 'arpack', 'randomized'}, default='auto'
@@ -88,8 +88,8 @@ class KernelPCovC(LinearClassifierMixin, _BaseKPCov):
8888
- ``sklearn.linear_model.Perceptron()``
8989
9090
If a pre-fitted classifier is provided, it is used to compute :math:`{\mathbf{Z}}`.
91-
If None and ``n_outputs < 2``, ``sklearn.linear_model.LogisticRegression()`` is used.
92-
If None and ``n_outputs == 2``, ``sklearn.multioutput.MultiOutputClassifier()`` is used.
91+
If None and ``n_outputs_ < 2``, ``sklearn.linear_model.LogisticRegression()`` is used.
92+
If None and ``n_outputs_ == 2``, ``sklearn.multioutput.MultiOutputClassifier()`` is used.
9393
9494
kernel : {"linear", "poly", "rbf", "sigmoid", "precomputed"} or callable, default="linear"
9595
Kernel.
@@ -137,7 +137,7 @@ class KernelPCovC(LinearClassifierMixin, _BaseKPCov):
137137
138138
Attributes
139139
----------
140-
n_outputs : int
140+
n_outputs_ : int
141141
The number of outputs when ``fit`` is performed.
142142
143143
classifier : estimator object
@@ -280,7 +280,7 @@ def fit(self, X, Y, W=None):
280280

281281
check_classification_targets(Y)
282282
self.classes_ = np.unique(Y)
283-
self.n_outputs = 1 if Y.ndim == 1 else Y.shape[1]
283+
self.n_outputs_ = 1 if Y.ndim == 1 else Y.shape[1]
284284

285285
super()._set_fit_params(X)
286286

@@ -311,7 +311,7 @@ def fit(self, X, Y, W=None):
311311
", or `precomputed`"
312312
)
313313

314-
multioutput = self.n_outputs != 1
314+
multioutput = self.n_outputs_ != 1
315315
precomputed = self.classifier == "precomputed"
316316

317317
if self.classifier is None or precomputed:
@@ -453,10 +453,10 @@ def decision_function(self, X=None, T=None):
453453
Returns
454454
-------
455455
Z : numpy.ndarray, shape (n_samples,) or (n_samples, n_classes), or a list of \
456-
n_outputs such arrays if n_outputs > 1
456+
n_outputs_ such arrays if n_outputs_ > 1
457457
Confidence scores. For binary classification, has shape `(n_samples,)`,
458458
for multiclass classification, has shape `(n_samples, n_classes)`.
459-
If n_outputs > 1, the list can contain arrays with differing shapes
459+
If n_outputs_ > 1, the list can contain arrays with differing shapes
460460
depending on the number of classes in each output of Y.
461461
"""
462462
check_is_fitted(self, attributes=["pkz_", "ptz_"])
@@ -470,7 +470,7 @@ def decision_function(self, X=None, T=None):
470470
if self.center:
471471
K = self.centerer_.transform(K)
472472

473-
if self.n_outputs == 1:
473+
if self.n_outputs_ == 1:
474474
# Or self.classifier_.decision_function(K @ self.pkt_)
475475
return K @ self.pkz_ + self.classifier_.intercept_
476476
else:
@@ -482,11 +482,22 @@ def decision_function(self, X=None, T=None):
482482
else:
483483
T = check_array(T)
484484

485-
if self.n_outputs == 1:
485+
if self.n_outputs_ == 1:
486486
T @ self.ptz_ + self.classifier_.intercept_
487487
else:
488488
return [
489489
est_.decision_function(T) for est_ in self.classifier_.estimators_
490490
]
491491

492-
#TODO: add MultiOutputClassifier's score function for KPCovC to allow for multiclass-multioutput case
492+
def score(self, X, y):
493+
494+
# accuracy_score will handle everything but multiclass-multilabel
495+
if self.n_outputs_ > 1 and len(self.classes_) > 2:
496+
y_pred = self.predict(X)
497+
return np.mean(np.all(y == y_pred, axis=1))
498+
499+
else:
500+
return super().score(X, y)
501+
502+
# Inherit the docstring from scikit-learn
503+
score.__doc__ = LinearClassifierMixin.score.__doc__

src/skmatter/decomposition/_pcovc.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -514,4 +514,15 @@ def transform(self, X=None):
514514
"""
515515
return super().transform(X)
516516

517-
#TODO: add MultiOutputClassifier's score function for PCovC to allow for multiclass-multioutput case
517+
def score(self, X, y):
518+
519+
# accuracy_score will handle everything but multiclass-multilabel
520+
if self.n_outputs_ > 1 and len(self.classes_) > 2:
521+
y_pred = self.predict(X)
522+
return np.mean(np.all(y == y_pred, axis=1))
523+
524+
else:
525+
return super().score(X, y)
526+
527+
# Inherit the docstring from scikit-learn
528+
score.__doc__ = LinearClassifierMixin.score.__doc__

0 commit comments

Comments
 (0)