GitHub PullRequestReviewCommentEvent at 2014-09-04 09:45:26
Repository: nilearn
Actor: dohmatob
Payload: {"action":"created","comment":{"url":"https://api.github.com/repos/nilearn/nilearn/pulls/comments/17104182","id":17104182,"diff_hunk":"@@ -0,0 +1,1240 @@\n+\"\"\"\n+sklearn-compatible Cross-Validation module for TV-l1, S-LASSO, etc. models\n+\n+\"\"\"\n+# Author: DOHMATOB Elvis Dopgima,\n+#         Gaspar Pizarro,\n+#         Gael Varoquaux,\n+#         Alexandre Gramfort,\n+#         Bertrand Thirion,\n+#         and others.\n+# License: simplified BSD\n+\n+from functools import partial\n+import numpy as np\n+from sklearn.externals.joblib import Memory, Parallel, delayed\n+from sklearn.cross_validation import check_cv\n+from ..._utils.fixes import (center_data, LabelBinarizer, roc_auc_score,\n+                             is_regressor, is_classifier)\n+from .common import _sigmoid\n+from .estimators import _BaseRegressor, _BaseClassifier, _BaseEstimator\n+from .smooth_lasso import smooth_lasso_logistic, smooth_lasso_squared_loss\n+from .tv import tvl1_solver\n+from ._cv_tricks import (EarlyStoppingCallback, RegressorFeatureSelector,\n+                         ClassifierFeatureSelector, _my_alpha_grid)\n+\n+\n+def logistic_path_scores(solver, X, y, alphas, l1_ratio, train,\n+                         test, tol=1e-4, max_iter=1000, init=None,\n+                         mask=None, verbose=0, key=None,\n+                         screening_percentile=10., memory=Memory(None),\n+                         callback=None, **kwargs):\n+    \"\"\"Function to compute scores of different alphas in classification\n+    used by CV objects.\n+\n+    Parameters\n+    ----------\n+    alphas: list of floats\n+        List of regularization parameters being considered.\n+\n+    l1_ratio: float in the interval [0, 1]; optinal (default .5)\n+        Constant that mixes L1 and TV (resp. Smooth Lasso) penalization.\n+        l1_ratio == 0: just smooth. l1_ratio == 1: just lasso.\n+\n+    solver: function handle\n+       See for example tv.TVl1Classifier documentation.\n+\n+    \"\"\"\n+\n+    alphas = sorted(alphas)[::-1]\n+\n+    # univariate feature screening\n+    selector = ClassifierFeatureSelector(percentile=screening_percentile,\n+                                         mask=mask)\n+    X = selector.fit_transform(X, y)\n+    mask = selector.mask_\n+\n+    X_train, y_train = X[train], y[train]\n+    X_test, y_test = X[test], y[test]\n+    test_scores = []\n+\n+    best_alpha = alphas[0]\n+    if len(test) > 0.:\n+        def _test_score(w):\n+            return 1. - roc_auc_score(\n+                (y_test > 0.), _sigmoid(np.dot(X_test, w[:-1]) + w[-1]))\n+\n+        # setup callback mechanism for early stopping\n+        earlystopper = EarlyStoppingCallback(X_test, y_test, verbose=verbose)\n+        env = dict(counter=0)\n+\n+        def _callback(_env):\n+            if callback:\n+                # they wan't us to use their callback\n+                return callback(_env)\n+\n+            # our callback\n+            if not isinstance(_env, dict):\n+                _env = dict(w=_env)\n+\n+            _env['w'] = _env['w'][:-1]  # strip off intercept\n+            env[\"counter\"] += 1\n+            _env[\"counter\"] = env[\"counter\"]\n+            return earlystopper(_env)\n+\n+        best_score = np.inf\n+        for alpha in alphas:\n+            w, _, init = solver(\n+                X_train, y_train, alpha, l1_ratio, mask=mask, tol=tol,\n+                max_iter=max_iter, init=init, verbose=verbose,\n+                callback=_callback, **kwargs)\n+            score = _test_score(w)\n+            test_scores.append(score)\n+            if score <= best_score:\n+                best_score = score\n+                best_alpha = alpha\n+\n+    # Re-fit best model to high precision (i.e without early stopping, etc.).\n+    # N.B: This work is cached, just in case another worker on another fold\n+    # reports the same best alpha. Also note that the re-fit is done only on\n+    # the train (i.e X_train), a piece of the design X.\n+    best_w, _, init = memory.cache(solver)(\n+        X_train, y_train, best_alpha, l1_ratio, mask=mask, tol=tol,\n+        max_iter=max_iter, verbose=verbose, **kwargs)\n+\n+    if len(test) == 0.:\n+        test_scores.append(np.nan)\n+\n+    # unmask univariate screening\n+    best_w = selector.inverse_transform(best_w)\n+\n+    return test_scores, best_w, key\n+\n+\n+def squared_loss_path_scores(solver, X, y, alphas, l1_ratio, train, test,\n+                             tol=1e-4, max_iter=1000, init=None, mask=None,\n+                             debias=False, ymean=0., verbose=0,\n+                             key=None, screening_percentile=10.,\n+                             memory=Memory(None), callback=None, **kwargs):\n+    \"\"\"Function to compute scores of different alphas in regression.\n+    used by CV objects.\n+\n+    Parameters\n+    ----------\n+    alphas: list of floats\n+        List of regularization parameters being considered.\n+\n+    l1_ratio: float in the interval [0, 1]; optinal (default .5)\n+        Constant that mixes L1 and TV (resp. Smooth Lasso) penalization.\n+        l1_ratio == 0: just smooth. l1_ratio == 1: just lasso.\n+\n+    solver: function handle\n+       See for example tv.TVl1Regressor documentation.\n+\n+    \"\"\"\n+\n+    alphas = sorted(alphas)[::-1]\n+\n+    # univariate feature screening\n+    selector = RegressorFeatureSelector(percentile=screening_percentile,\n+                                        mask=mask)\n+    X = selector.fit_transform(X, y)\n+    mask = selector.mask_\n+\n+    # make train / test datasets\n+    X_train, y_train = X[train], y[train]\n+    X_test, y_test = X[test], y[test]\n+\n+    test_scores = []\n+\n+    def _test_score(w):\n+        \"\"\"Helper function to compute score of model with given weights map (\n+        loadings vector).\n+\n+        \"\"\"\n+\n+        # debias to correct for DoF\n+        if debias:\n+            y_pred = np.dot(X_test, w)\n+            scaling = np.dot(y_pred, y_pred)\n+            if scaling > 0.:\n+                scaling = np.dot(y_pred, y_test) / scaling\n+                w *= scaling\n+        y_pred = np.dot(X_test, w) + ymean  # don't forget to add intercept!\n+        score = .5 * np.mean((y_test - y_pred) ** 2)\n+        return score\n+\n+    best_alpha = alphas[0]\n+    if len(test) > 0.:\n+        # setup callback mechanism for early stopping\n+        earlystopper = EarlyStoppingCallback(X_test, y_test, verbose=verbose)\n+        env = dict(counter=0)\n+\n+        def _callback(_env):\n+            if callback:\n+                # they wan't us to use their callback\n+                return callback(_env)\n+\n+            # our callback\n+            if not isinstance(_env, dict):\n+                _env = dict(w=_env)\n+            env[\"counter\"] += 1\n+            _env[\"counter\"] = env[\"counter\"]\n+            return earlystopper(_env)\n+\n+        # rumble down regularization path (with warm-starts)\n+        best_score = np.inf\n+        for alpha in alphas:\n+            w, _, init = solver(\n+                X_train, y_train, alpha, l1_ratio, mask=mask, tol=tol,\n+                max_iter=max_iter, init=init, callback=_callback,\n+                verbose=verbose, **kwargs)\n+\n+            # compute score on test data\n+            score = _test_score(w)\n+            test_scores.append(score)\n+            if score <= best_score:\n+                best_alpha = alpha\n+\n+                best_score = score\n+\n+    # Re-fit best model to high precision (i.e without early stopping, etc.).\n+    # N.B: This work is cached, just in case another worker on another fold\n+    # reports the same best alpha. Also note that the re-fit is done only on\n+    # the train (i.e X_train), a piece of the design X.\n+    best_w, _, init = memory.cache(solver)(\n+        X_train, y_train, best_alpha, l1_ratio, mask=mask, tol=tol,\n+        max_iter=max_iter, verbose=verbose, callback=callback, **kwargs)\n+\n+    if len(test) == 0.:\n+        test_scores.append(np.nan)\n+\n+    # Unmask univariate screening\n+    best_w = selector.inverse_transform(best_w)\n+\n+    return test_scores, best_w, key\n+\n+\n+class _BaseCV(_BaseEstimator):\n+    \"\"\"\n+    Parameters\n+    ----------\n+    alphas: list of floats, optional (default None)\n+        Choices for the constant that scales the overall regularization term.\n+        This parameter is mutually exclusive with the `n_alphas` parameter.\n+\n+    n_alphas: int, optional (default 10).\n+        Generate this number of alphas per regularization path.\n+        This parameter is mutually exclusive with the `alphas` parameter.\n+\n+    eps: float, optional\n+        Length of the path. ``eps=1e-3`` means that\n+        ``alpha_min / alpha_max = 1e-3``\n+\n+    alpha_min: float, optional (default 1e-6)\n+        Minimum value of alpha to consider. This is mutually exclusive with the\n+        `eps` parameter.\n+\n+    l1_ratio: float in the interval [0, 1]; optinal (default .5)\n+        Constant that mixes L1 and TV, etc., penalization.\n+        l1_ratio == 0: just smooth. l1_ratio == 1: just lasso.\n+\n+    mask: multidimensional array of booleans, optional (default None)\n+        The support of this mask defines the ROIs being considered in\n+        the problem.\n+\n+    screening_percentile: float in the interval [0, 100]; Optional (default 10)\n+        Percentile value for ANOVA univariate feature selection. A value of\n+        100 means \"keep all features\".\n+\n+    standardize: bool, optional (default False):\n+       If set, then input data (X, y) will be standardized (i.e converted to\n+       standard Gaussian) before model is fitted.\n+\n+    normalize: boolean, optional, default False\n+        Parameter passed to sklearn's `center_data` function for centralizing\n+        the input data (X, y)\n+\n+    fit_intercept: bool\n+        Fit or not an intercept.\n+\n+    max_iter: int\n+        Defines the iterations for the solver. Defaults to 1000\n+\n+    tol: float\n+        Defines the tolerance for convergence. Defaults to 1e-4.\n+\n+    verbose: int, optional (default 0)\n+        Verbosity level.\n+\n+    backtracking: bool\n+        If True, the solver does backtracking in the step size for the proximal\n+        operator.\n+\n+    callback: callable(dict) -> bool\n+        Function called at the end of every energy descendent iteration of the\n+        solver. If it returns True, the loop breaks.\n+\n+    n_jobs: int, optional (default 1)\n+        Number of jobs to use for One-vs-All classification.\n+\n+    cv: int, a cv generator instance, or None (default 10)\n+        The input specifying which cross-validation generator to use.\n+        It can be an integer, in which case it is the number of folds in a\n+        KFold, None, in which case 3 fold is used, or another object, that\n+        will then be used as a cv generator.\n+\n+    Attributes\n+    ----------\n+    `alpha_`: float\n+         Best alpha found by cross-validation\n+\n+    `coef_`: array, shape = [n_classes-1, n_features]\n+        Coefficient of the features in the decision function.\n+\n+        `coef_` is readonly property derived from `raw_coef_` that \\\n+        follows the internal memory layout of liblinear.\n+\n+    `intercept_`: array, shape = [n_classes-1]\n+         Intercept (a.k.a. bias) added to the decision function.\n+         It is available only when parameter intercept is set to True.\n+\n+    `scores_`: 2d array of shape (n_alphas, n_folds)\n+        Scores (misclassification) for each alpha, and on each fold\n+\n+    \"\"\"\n+\n+    def __init__(self, alpha=None, alphas=None, l1_ratio=.5, mask=None,\n+                 max_iter=1000, tol=1e-4, memory=Memory(None), copy_data=True,\n+                 standardize=False, normalize=False, alpha_min=1e-6,\n+                 verbose=0, n_jobs=1, callback=None, n_alphas=10, eps=1e-3,\n+                 fit_intercept=True, cv=10, backtracking=False,\n+                 screening_percentile=10., solver=None, path_scores_func=None):\n+        super(_BaseCV, self).__init__(\n+            l1_ratio=l1_ratio, mask=mask, max_iter=max_iter, tol=tol,\n+            memory=memory, copy_data=copy_data, verbose=verbose,\n+            fit_intercept=fit_intercept, backtracking=backtracking,\n+            normalize=normalize, standardize=standardize)\n+        self.n_jobs = n_jobs\n+        self.cv = cv\n+        self.alpha = alpha\n+        self.n_alphas = n_alphas\n+        self.eps = eps\n+        self.alphas = alphas\n+        self.alpha_min = alpha_min\n+        self.callback = callback\n+        self.solver = solver\n+        self.path_scores_func = path_scores_func\n+        if not (0. <= screening_percentile <= 100.):\n+            raise ValueError(\n+                (\"screening_percentile should be in the interval\"\n+                 \" [0, 100], got %g\" % screening_percentile))\n+        self.screening_percentile = screening_percentile\n+\n+    @property\n+    def short_name(self):\n+        return '%s(l1_ratio=%g)' % (self.__class__.__name__, self.l1_ratio)\n+\n+    def fit(self, X, y):\n+        assert self.solver is not None\n+\n+        # sanitize path_scores_func\n+        if self.path_scores_func is None:\n+            raise ValueError(\n+                \"Class '%s' doesn't have a `path_scores_func` attribute!\" % (\n+                    self.__class__.__name__))\n+\n+        X = np.array(X)\n+        y = np.array(y).ravel()\n+        n_samples, _ = X.shape\n+\n+        self.__class__.__name__.endswith(\"CV\")\n+        solver = self.solver\n+        path_scores_func = self.path_scores_func\n+        tricky_kwargs = {}\n+        if hasattr(self, \"debias\"):\n+            tricky_kwargs[\"debias\"] = getattr(self, \"debias\")\n+\n+        # always a good idea to centralize / normalize data\n+        ymean = 0.\n+        if self.standardize:\n+            X, y, Xmean, ymean, Xstd = center_data(\n+                X, y, copy=True, normalize=self.normalize,\n+                fit_intercept=self.fit_intercept)\n+            if is_regressor(self):\n+                tricky_kwargs[\"ymean\"] = ymean\n+\n+        # make / sanitize alpha grid\n+        if self.alpha is not None:\n+            alphas = [self.alpha]\n+        elif self.alphas is None:\n+            # XXX Are these alphas reasonable ?\n+            alphas = _my_alpha_grid(X, y, l1_ratio=self.l1_ratio,\n+                                    eps=self.eps, n_alphas=self.n_alphas,\n+                                    standardize=self.standardize,\n+                                    normalize=self.normalize,\n+                                    alpha_min=self.alpha_min,\n+                                    fit_intercept=self.fit_intercept,\n+                                    logistic=is_classifier(self))\n+        else:\n+            alphas = np.array(self.alphas)\n+\n+        # always sort alphas from largest to smallest\n+        alphas = np.array(sorted(alphas)[::-1])\n+\n+        if len(alphas) > 1:\n+            cv = list(check_cv(self.cv, X=X, y=y, classifier=True))\n+        else:\n+            cv = [(range(n_samples), [])]","path":"nilearn/decoding/sparse_models/cv.py","position":377,"original_position":388,"commit_id":"b641c9e22963cd37d2d9dba65b93ed35a1b74228","original_commit_id":"c1c90eb7efe266e0f6bc46551008ca18fe7f70a9","user":{"login":"dohmatob","id":634068,"avatar_url":"https://avatars.githubusercontent.com/u/634068?v=2","gravatar_id":"3f99b639fc16183758ab2b38bca26ee4","url":"https://api.github.com/users/dohmatob","html_url":"https://github.com/dohmatob","followers_url":"https://api.github.com/users/dohmatob/followers","following_url":"https://api.github.com/users/dohmatob/following{/other_user}","gists_url":"https://api.github.com/users/dohmatob/gists{/gist_id}","starred_url":"https://api.github.com/users/dohmatob/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dohmatob/subscriptions","organizations_url":"https://api.github.com/users/dohmatob/orgs","repos_url":"https://api.github.com/users/dohmatob/repos","events_url":"https://api.github.com/users/dohmatob/events{/privacy}","received_events_url":"https://api.github.com/users/dohmatob/received_events","type":"User","site_admin":false},"body":"Does this have an explicit advantage. Is this best-practice-related ?","created_at":"2014-09-04T09:45:26Z","updated_at":"2014-09-04T09:45:26Z","html_url":"https://github.com/nilearn/nilearn/pull/219#discussion_r17104182","pull_request_url":"https://api.github.com/repos/nilearn/nilearn/pulls/219","_links":{"self":{"href":"https://api.github.com/repos/nilearn/nilearn/pulls/comments/17104182"},"html":{"href":"https://github.com/nilearn/nilearn/pull/219#discussion_r17104182"},"pull_request":{"href":"https://api.github.com/repos/nilearn/nilearn/pulls/219"}}},"pull_request":{"url":"https://api.github.com/repos/nilearn/nilearn/pulls/219","id":17693110,"html_url":"https://github.com/nilearn/nilearn/pull/219","diff_url":"https://github.com/nilearn/nilearn/pull/219.diff","patch_url":"https://github.com/nilearn/nilearn/pull/219.patch","issue_url":"https://api.github.com/repos/nilearn/nilearn/issues/219","number":219,"state":"open","locked":false,"title":"(WIP) Sparse models: S-LASSO and TV-l1","user":{"login":"dohmatob","id":634068,"avatar_url":"https://avatars.githubusercontent.com/u/634068?v=2","gravatar_id":"3f99b639fc16183758ab2b38bca26ee4","url":"https://api.github.com/users/dohmatob","html_url":"https://github.com/dohmatob","followers_url":"https://api.github.com/users/dohmatob/followers","following_url":"https://api.github.com/users/dohmatob/following{/other_user}","gists_url":"https://api.github.com/users/dohmatob/gists{/gist_id}","starred_url":"https://api.github.com/users/dohmatob/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dohmatob/subscriptions","organizations_url":"https://api.github.com/users/dohmatob/orgs","repos_url":"https://api.github.com/users/dohmatob/repos","events_url":"https://api.github.com/users/dohmatob/events{/privacy}","received_events_url":"https://api.github.com/users/dohmatob/received_events","type":"User","site_admin":false},"body":"- Supports TV-l1 and S-LASSO priors\r\n- Supports logistic and squared losses\r\n- Has cross validation\r\n- Can automatically select alpha by CV (+ automatic computation of useful alpha ranges for the CV)\r\n- Warning: User must supply l1_ratio","created_at":"2014-06-27T09:16:58Z","updated_at":"2014-09-04T09:45:26Z","closed_at":null,"merged_at":null,"merge_commit_sha":"58b71e2ba86a6197e2f26c4012c2afbf3e6993ac","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/nilearn/nilearn/pulls/219/commits","review_comments_url":"https://api.github.com/repos/nilearn/nilearn/pulls/219/comments","review_comment_url":"https://api.github.com/repos/nilearn/nilearn/pulls/comments/{number}","comments_url":"https://api.github.com/repos/nilearn/nilearn/issues/219/comments","statuses_url":"https://api.github.com/repos/nilearn/nilearn/statuses/b641c9e22963cd37d2d9dba65b93ed35a1b74228","head":{"label":"dohmatob:sparse-models","ref":"sparse-models","sha":"b641c9e22963cd37d2d9dba65b93ed35a1b74228","user":{"login":"dohmatob","id":634068,"avatar_url":"https://avatars.githubusercontent.com/u/634068?v=2","gravatar_id":"3f99b639fc16183758ab2b38bca26ee4","url":"https://api.github.com/users/dohmatob","html_url":"https://github.com/dohmatob","followers_url":"https://api.github.com/users/dohmatob/followers","following_url":"https://api.github.com/users/dohmatob/following{/other_user}","gists_url":"https://api.github.com/users/dohmatob/gists{/gist_id}","starred_url":"https://api.github.com/users/dohmatob/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dohmatob/subscriptions","organizations_url":"https://api.github.com/users/dohmatob/orgs","repos_url":"https://api.github.com/users/dohmatob/repos","events_url":"https://api.github.com/users/dohmatob/events{/privacy}","received_events_url":"https://api.github.com/users/dohmatob/received_events","type":"User","site_admin":false},"repo":{"id":10718029,"name":"nilearn","full_name":"dohmatob/nilearn","owner":{"login":"dohmatob","id":634068,"avatar_url":"https://avatars.githubusercontent.com/u/634068?v=2","gravatar_id":"3f99b639fc16183758ab2b38bca26ee4","url":"https://api.github.com/users/dohmatob","html_url":"https://github.com/dohmatob","followers_url":"https://api.github.com/users/dohmatob/followers","following_url":"https://api.github.com/users/dohmatob/following{/other_user}","gists_url":"https://api.github.com/users/dohmatob/gists{/gist_id}","starred_url":"https://api.github.com/users/dohmatob/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dohmatob/subscriptions","organizations_url":"https://api.github.com/users/dohmatob/orgs","repos_url":"https://api.github.com/users/dohmatob/repos","events_url":"https://api.github.com/users/dohmatob/events{/privacy}","received_events_url":"https://api.github.com/users/dohmatob/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/dohmatob/nilearn","description":"NeuroImaging with the Scikit-learn: fMRI inverse inference tutorial","fork":true,"url":"https://api.github.com/repos/dohmatob/nilearn","forks_url":"https://api.github.com/repos/dohmatob/nilearn/forks","keys_url":"https://api.github.com/repos/dohmatob/nilearn/keys{/key_id}","collaborators_url":"https://api.github.com/repos/dohmatob/nilearn/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/dohmatob/nilearn/teams","hooks_url":"https://api.github.com/repos/dohmatob/nilearn/hooks","issue_events_url":"https://api.github.com/repos/dohmatob/nilearn/issues/events{/number}","events_url":"https://api.github.com/repos/dohmatob/nilearn/events","assignees_url":"https://api.github.com/repos/dohmatob/nilearn/assignees{/user}","branches_url":"https://api.github.com/repos/dohmatob/nilearn/branches{/branch}","tags_url":"https://api.github.com/repos/dohmatob/nilearn/tags","blobs_url":"https://api.github.com/repos/dohmatob/nilearn/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/dohmatob/nilearn/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/dohmatob/nilearn/git/refs{/sha}","trees_url":"https://api.github.com/repos/dohmatob/nilearn/git/trees{/sha}","statuses_url":"https://api.github.com/repos/dohmatob/nilearn/statuses/{sha}","languages_url":"https://api.github.com/repos/dohmatob/nilearn/languages","stargazers_url":"https://api.github.com/repos/dohmatob/nilearn/stargazers","contributors_url":"https://api.github.com/repos/dohmatob/nilearn/contributors","subscribers_url":"https://api.github.com/repos/dohmatob/nilearn/subscribers","subscription_url":"https://api.github.com/repos/dohmatob/nilearn/subscription","commits_url":"https://api.github.com/repos/dohmatob/nilearn/commits{/sha}","git_commits_url":"https://api.github.com/repos/dohmatob/nilearn/git/commits{/sha}","comments_url":"https://api.github.com/repos/dohmatob/nilearn/comments{/number}","issue_comment_url":"https://api.github.com/repos/dohmatob/nilearn/issues/comments/{number}","contents_url":"https://api.github.com/repos/dohmatob/nilearn/contents/{+path}","compare_url":"https://api.github.com/repos/dohmatob/nilearn/compare/{base}...{head}","merges_url":"https://api.github.com/repos/dohmatob/nilearn/merges","archive_url":"https://api.github.com/repos/dohmatob/nilearn/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/dohmatob/nilearn/downloads","issues_url":"https://api.github.com/repos/dohmatob/nilearn/issues{/number}","pulls_url":"https://api.github.com/repos/dohmatob/nilearn/pulls{/number}","milestones_url":"https://api.github.com/repos/dohmatob/nilearn/milestones{/number}","notifications_url":"https://api.github.com/repos/dohmatob/nilearn/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/dohmatob/nilearn/labels{/name}","releases_url":"https://api.github.com/repos/dohmatob/nilearn/releases{/id}","created_at":"2013-06-16T09:21:03Z","updated_at":"2014-07-01T14:32:45Z","pushed_at":"2014-09-04T09:44:11Z","git_url":"git://github.com/dohmatob/nilearn.git","ssh_url":"git@github.com:dohmatob/nilearn.git","clone_url":"https://github.com/dohmatob/nilearn.git","svn_url":"https://github.com/dohmatob/nilearn","homepage":"http://nilearn.github.com/","size":5715,"stargazers_count":1,"watchers_count":1,"language":"Python","has_issues":false,"has_downloads":true,"has_wiki":true,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":1,"default_branch":"master"}},"base":{"label":"nilearn:master","ref":"master","sha":"1d8e680085512457245f943702c3f68d47c68aff","user":{"login":"nilearn","id":4646912,"avatar_url":"https://avatars.githubusercontent.com/u/4646912?v=2","gravatar_id":"8b35c948467638a5527d0bad1de7880e","url":"https://api.github.com/users/nilearn","html_url":"https://github.com/nilearn","followers_url":"https://api.github.com/users/nilearn/followers","following_url":"https://api.github.com/users/nilearn/following{/other_user}","gists_url":"https://api.github.com/users/nilearn/gists{/gist_id}","starred_url":"https://api.github.com/users/nilearn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nilearn/subscriptions","organizations_url":"https://api.github.com/users/nilearn/orgs","repos_url":"https://api.github.com/users/nilearn/repos","events_url":"https://api.github.com/users/nilearn/events{/privacy}","received_events_url":"https://api.github.com/users/nilearn/received_events","type":"Organization","site_admin":false},"repo":{"id":1235740,"name":"nilearn","full_name":"nilearn/nilearn","owner":{"login":"nilearn","id":4646912,"avatar_url":"https://avatars.githubusercontent.com/u/4646912?v=2","gravatar_id":"8b35c948467638a5527d0bad1de7880e","url":"https://api.github.com/users/nilearn","html_url":"https://github.com/nilearn","followers_url":"https://api.github.com/users/nilearn/followers","following_url":"https://api.github.com/users/nilearn/following{/other_user}","gists_url":"https://api.github.com/users/nilearn/gists{/gist_id}","starred_url":"https://api.github.com/users/nilearn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nilearn/subscriptions","organizations_url":"https://api.github.com/users/nilearn/orgs","repos_url":"https://api.github.com/users/nilearn/repos","events_url":"https://api.github.com/users/nilearn/events{/privacy}","received_events_url":"https://api.github.com/users/nilearn/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/nilearn/nilearn","description":"Machine learning for NeuroImaging in Python","fork":false,"url":"https://api.github.com/repos/nilearn/nilearn","forks_url":"https://api.github.com/repos/nilearn/nilearn/forks","keys_url":"https://api.github.com/repos/nilearn/nilearn/keys{/key_id}","collaborators_url":"https://api.github.com/repos/nilearn/nilearn/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/nilearn/nilearn/teams","hooks_url":"https://api.github.com/repos/nilearn/nilearn/hooks","issue_events_url":"https://api.github.com/repos/nilearn/nilearn/issues/events{/number}","events_url":"https://api.github.com/repos/nilearn/nilearn/events","assignees_url":"https://api.github.com/repos/nilearn/nilearn/assignees{/user}","branches_url":"https://api.github.com/repos/nilearn/nilearn/branches{/branch}","tags_url":"https://api.github.com/repos/nilearn/nilearn/tags","blobs_url":"https://api.github.com/repos/nilearn/nilearn/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/nilearn/nilearn/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/nilearn/nilearn/git/refs{/sha}","trees_url":"https://api.github.com/repos/nilearn/nilearn/git/trees{/sha}","statuses_url":"https://api.github.com/repos/nilearn/nilearn/statuses/{sha}","languages_url":"https://api.github.com/repos/nilearn/nilearn/languages","stargazers_url":"https://api.github.com/repos/nilearn/nilearn/stargazers","contributors_url":"https://api.github.com/repos/nilearn/nilearn/contributors","subscribers_url":"https://api.github.com/repos/nilearn/nilearn/subscribers","subscription_url":"https://api.github.com/repos/nilearn/nilearn/subscription","commits_url":"https://api.github.com/repos/nilearn/nilearn/commits{/sha}","git_commits_url":"https://api.github.com/repos/nilearn/nilearn/git/commits{/sha}","comments_url":"https://api.github.com/repos/nilearn/nilearn/comments{/number}","issue_comment_url":"https://api.github.com/repos/nilearn/nilearn/issues/comments/{number}","contents_url":"https://api.github.com/repos/nilearn/nilearn/contents/{+path}","compare_url":"https://api.github.com/repos/nilearn/nilearn/compare/{base}...{head}","merges_url":"https://api.github.com/repos/nilearn/nilearn/merges","archive_url":"https://api.github.com/repos/nilearn/nilearn/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/nilearn/nilearn/downloads","issues_url":"https://api.github.com/repos/nilearn/nilearn/issues{/number}","pulls_url":"https://api.github.com/repos/nilearn/nilearn/pulls{/number}","milestones_url":"https://api.github.com/repos/nilearn/nilearn/milestones{/number}","notifications_url":"https://api.github.com/repos/nilearn/nilearn/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/nilearn/nilearn/labels{/name}","releases_url":"https://api.github.com/repos/nilearn/nilearn/releases{/id}","created_at":"2011-01-09T19:02:23Z","updated_at":"2014-09-02T13:39:38Z","pushed_at":"2014-09-02T13:39:38Z","git_url":"git://github.com/nilearn/nilearn.git","ssh_url":"git@github.com:nilearn/nilearn.git","clone_url":"https://github.com/nilearn/nilearn.git","svn_url":"https://github.com/nilearn/nilearn","homepage":"http://nilearn.github.io","size":8479,"stargazers_count":59,"watchers_count":59,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"forks_count":42,"mirror_url":null,"open_issues_count":43,"forks":42,"open_issues":43,"watchers":59,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/nilearn/nilearn/pulls/219"},"html":{"href":"https://github.com/nilearn/nilearn/pull/219"},"issue":{"href":"https://api.github.com/repos/nilearn/nilearn/issues/219"},"comments":{"href":"https://api.github.com/repos/nilearn/nilearn/issues/219/comments"},"review_comments":{"href":"https://api.github.com/repos/nilearn/nilearn/pulls/219/comments"},"review_comment":{"href":"https://api.github.com/repos/nilearn/nilearn/pulls/comments/{number}"},"commits":{"href":"https://api.github.com/repos/nilearn/nilearn/pulls/219/commits"},"statuses":{"href":"https://api.github.com/repos/nilearn/nilearn/statuses/b641c9e22963cd37d2d9dba65b93ed35a1b74228"}}}}