Repository: nilearn/nilearn

Issue:
Spacenet classifier score gives r2_score
`score` method is actually inherited from sklearn regressor class. 



Discussion:

Resolving patch:
diff --git a/nilearn/decoding/space_net.py b/nilearn/decoding/space_net.py
--- a/nilearn/decoding/space_net.py
+++ b/nilearn/decoding/space_net.py
@@ -26,6 +26,7 @@
 from sklearn.externals.joblib import Memory, Parallel, delayed
 from sklearn.cross_validation import check_cv
 from sklearn.preprocessing import LabelBinarizer
+from sklearn.metrics import accuracy_score
 from .._utils.compat import _basestring
 from .._utils.fixes import atleast2d_or_csr
 from .._utils.cache_mixin import CacheMixin
@@ -195,11 +196,11 @@ def _space_net_alpha_grid(X, y, eps=1e-3, n_alphas=10, l1_ratio=1.,
         For ``l1_ratio = 0`` the penalty is purely a spatial prior
         (Graph-Net, TV, etc.). ``For l1_ratio = 1`` it is an L1 penalty.
         For ``0 < l1_ratio < 1``, the penalty is a combination of L1
-        and a spatial prior
+        and a spatial prior.
 
     eps : float, optional
         Length of the path. ``eps=1e-3`` means that
-        ``alpha_min / alpha_max = 1e-3``
+        ``alpha_min / alpha_max = 1e-3``.
 
     n_alphas : int, optional
         Number of alphas along the regularization path.
@@ -313,7 +314,7 @@ def test_score(self, w):
         correlation, which captures ordering between input and
         output, but tends to have 'flat' regions. The other
         is the Pearson correlation, that we can use to disambiguate
-        between regions of equivalent Spearman correlations
+        between regions with equivalent Spearman correlation.
 
         """
         if self.is_classif:
@@ -352,10 +353,10 @@ def path_scores(solver, X, y, mask, alphas, l1_ratios, train, test,
         List of regularization parameters being considered.
 
     train : array or list of integers
-        List of indices for the train samples
+        List of indices for the train samples.
 
     test : array or list of integers
-        List of indices for the test samples
+        List of indices for the test samples.
 
     l1_ratio : float in the interval [0, 1]; optional (default .5)
         Constant that mixes L1 and TV (resp. Graph-Net) penalization.
@@ -363,7 +364,7 @@ def path_scores(solver, X, y, mask, alphas, l1_ratios, train, test,
 
     eps : float, optional (default 1e-3)
         Length of the path. For example, ``eps=1e-3`` means that
-        ``alpha_min / alpha_max = 1e-3``
+        ``alpha_min / alpha_max = 1e-3``.
 
     n_alphas : int, optional (default 10).
         Generate this number of alphas per regularization path.
@@ -500,7 +501,7 @@ class BaseSpaceNet(LinearModel, RegressorMixin, CacheMixin):
     `SpaceNet` implements Graph-Net and TV-L1 priors /
     penalties. Thus, the penalty is a sum an L1 term and a spatial term. The
     aim of such a hybrid prior is to obtain weights maps which are structured
-    (due to the spatial prior) and sparse (enforced by L1 norm)
+    (due to the spatial prior) and sparse (enforced by L1 norm).
 
     Parameters
     ----------
@@ -551,15 +552,15 @@ class BaseSpaceNet(LinearModel, RegressorMixin, CacheMixin):
 
     low_pass : False or float, optional, (default None)
         This parameter is passed to signal.clean. Please see the related
-        documentation for details
+        documentation for details.
 
     high_pass : False or float, optional (default None)
         This parameter is passed to signal. Clean. Please see the related
-        documentation for details
+        documentation for details.
 
     t_r : float, optional (default None)
         This parameter is passed to signal.clean. Please see the related
-        documentation for details
+        documentation for details.
 
     screening_percentile : float in the interval [0, 100]; Optional (
     default 20)
@@ -578,8 +579,8 @@ class BaseSpaceNet(LinearModel, RegressorMixin, CacheMixin):
     fit_intercept : bool, optional (default True)
         Fit or not an intercept.
 
-    max_iter : int
-        Defines the iterations for the solver. Defaults to 1000
+    max_iter : int (default 1000)
+        Defines the iterations for the solver.
 
     tol : float, optional (default 1e-4)
         Defines the tolerance for convergence for the backend fista solver.
@@ -611,7 +612,7 @@ class BaseSpaceNet(LinearModel, RegressorMixin, CacheMixin):
     Attributes
     ----------
     `alpha_` : float
-         Best alpha found by cross-validation
+         Best alpha found by cross-validation.
 
     `coef_` : ndarray, shape (n_classes-1, n_features)
         Coefficient of the features in the decision function.
@@ -738,13 +739,12 @@ def fit(self, X, y):
         Parameters
         ----------
         X : list of Niimg-like objects
-            See http://nilearn.github.io/building_blocks/
-            manipulating_mr_images.html#niimg.
+            See http://nilearn.github.io/manipulating_visualizing/manipulating_images.html#niimg
             Data on which model is to be fitted. If this is a list,
             the affine is considered the same for all.
 
         y : array or list of length n_samples
-            The dependent variable (age, sex, QI, etc.)
+            The dependent variable (age, sex, QI, etc.).
 
         Notes
         -----
@@ -929,8 +929,7 @@ def predict(self, X):
         Parameters
         ----------
         X : list of Niimg-like objects
-            See http://nilearn.github.io/building_blocks/
-            manipulating_mr_images.html#niimg.
+            See http://nilearn.github.io/manipulating_visualizing/manipulating_images.html#niimg
             Data on prediction is to be made. If this is a list,
             the affine is considered the same for all.
 
@@ -970,8 +969,8 @@ class SpaceNetClassifier(BaseSpaceNet):
     penalty : string, optional (default 'graph-net')
         Penalty to used in the model. Can be 'graph-net' or 'tv-l1'.
 
-    loss : string, optional (default "mse")
-        Loss to be used in the model. Must be an one of "mse", or "logistic".
+    loss : string, optional (default "logistic")
+        Loss to be used in the classifier. Must be one of "mse", or "logistic".
 
     l1_ratios : float or list of floats in the interval [0, 1];
     optional (default .5)
@@ -990,13 +989,9 @@ class SpaceNetClassifier(BaseSpaceNet):
         Generate this number of alphas per regularization path.
         This parameter is mutually exclusive with the `alphas` parameter.
 
-    loss: string, optional (default "logistic"):
-        Loss to use in the classification problems. Must be one of "mse" and
-        "logistic".
-
     eps : float, optional (default 1e-3)
         Length of the path. For example, ``eps=1e-3`` means that
-        ``alpha_min / alpha_max = 1e-3``
+        ``alpha_min / alpha_max = 1e-3``.
 
     mask : filename, niimg, NiftiMasker instance, optional default None)
         Mask to be used on data. If an instance of masker is passed,
@@ -1040,8 +1035,8 @@ class SpaceNetClassifier(BaseSpaceNet):
     fit_intercept : bool, optional (default True)
         Fit or not an intercept.
 
-    max_iter : int
-        Defines the iterations for the solver. Defaults to 1000.
+    max_iter : int (default 1000)
+        Defines the iterations for the solver.
 
     tol : float
         Defines the tolerance for convergence. Defaults to 1e-4.
@@ -1097,7 +1092,7 @@ class SpaceNetClassifier(BaseSpaceNet):
          samples for the corresponding fold.
 
     `cv_scores_` : 2d array of shape (n_alphas, n_folds)
-        Scores (misclassification) for each alpha, and on each fold
+        Scores (misclassification) for each alpha, and on each fold.
 
     `screening_percentile_` : float
         Screening percentile corrected according to volume of mask,
@@ -1124,7 +1119,7 @@ def __init__(self, penalty="graph-net", loss="logistic",
             target_affine=target_affine, verbose=verbose)
 
     def _binarize_y(self, y):
-        """Helper function invoked just before fitting a classifier"""
+        """Helper function invoked just before fitting a classifier."""
         y = np.array(y)
 
         # encode target classes as -1 and 1
@@ -1134,6 +1129,26 @@ def _binarize_y(self, y):
         self.n_classes_ = len(self.classes_)
         return y
 
+    def score(self, X, y):
+        """Returns the mean accuracy on the given test data and labels.
+
+        Parameters
+        ----------
+        X : list of Niimg-like objects
+            See http://nilearn.github.io/manipulating_visualizing/manipulating_images.html#niimg
+            Data on which model is to be fitted. If this is a list,
+            the affine is considered the same for all.
+
+        y : array or list of length n_samples.
+            Labels.
+
+        Returns
+        -------
+        score : float
+            Mean accuracy of self.predict(X)  w.r.t y.
+        """
+        return accuracy_score(y, self.predict(X))
+
 
 class SpaceNetRegressor(BaseSpaceNet):
     """
@@ -1212,8 +1227,8 @@ class SpaceNetRegressor(BaseSpaceNet):
     fit_intercept : bool, optional (default True)
         Fit or not an intercept.
 
-    max_iter : int
-        Defines the iterations for the solver. Defaults to 1000
+    max_iter : int (default 1000)
+        Defines the iterations for the solver.
 
     tol : float
         Defines the tolerance for convergence. Defaults to 1e-4.


Test patch:
diff --git a/nilearn/decoding/tests/test_space_net.py b/nilearn/decoding/tests/test_space_net.py
--- a/nilearn/decoding/tests/test_space_net.py
+++ b/nilearn/decoding/tests/test_space_net.py
@@ -12,7 +12,9 @@
 from sklearn.linear_model import Lasso
 from sklearn.utils import check_random_state
 from sklearn.linear_model import LogisticRegression
-from nilearn._utils.testing import assert_raises_regex, assert_warns
+from sklearn.metrics import accuracy_score
+from nilearn._utils.testing import (assert_raises_regex, assert_warns,
+                                    assert_less_equal)
 from nilearn.decoding.space_net import (
     _EarlyStoppingCallback, _space_net_alpha_grid, MNI152_BRAIN_VOLUME,
     path_scores, BaseSpaceNet, _crop_mask, _univariate_feature_screening,
@@ -187,6 +189,19 @@ def test_tv_regression_3D_image_doesnt_crash():
                      penalty="tv-l1", is_classif=False, max_iter=10).fit(X, y)
 
 
+def test_graph_net_classifier_score():
+    iris = load_iris()
+    X, y = iris.data, iris.target
+    y = 2 * (y > 0) - 1
+    X_, mask = to_niimgs(X, (2, 2, 2))
+    gnc = SpaceNetClassifier(mask=mask, alphas=1. / .01 / X.shape[0],
+                             l1_ratios=1., tol=1e-10,
+                             standardize=False, verbose=0,
+                             screening_percentile=100.).fit(X_, y)
+    accuracy = gnc.score(X_, y)
+    assert_equal(accuracy, accuracy_score(y, gnc.predict(X_)))
+
+
 def test_log_reg_vs_graph_net_two_classes_iris(C=.01, tol=1e-10,
                                                zero_thr=1e-4):
     # Test for one of the extreme cases of Graph-Net: That is, with