{"action":"created","comment":{"url":"https://api.github.com/repos/scikit-learn/scikit-learn/pulls/comments/54574246","id":54574246,"diff_hunk":"@@ -520,6 +548,475 @@ def inverse_transform(self, Xt):\n         \"\"\"\n         return self.best_estimator_.transform(Xt)\n \n+\n+class UnsupervisedSearchMixin(object):\n+\n+    \"\"\"Adds unsupervised search to BaseSearch.\"\"\"\n+\n+    def _fit(self, X, y=None, parameter_iterable=None):\n+        \"\"\"Draws heavily on the _fit method of BaseSearchCV.\n+        \"\"\"\n+        self.scorer_ = check_scoring(self.estimator, scoring=self.scoring)\n+        estimator = self.estimator\n+\n+        grid_scores = list()\n+        out = Parallel(n_jobs=1\n+                       )(\n+            delayed(fit_and_score_unsupervised)(clone(estimator),\n+                                                X, scorer=self.scorer_,\n+                                                verbose=self.verbose,\n+                                                parameters=parameters,\n+                                                fit_params=self.fit_params,\n+                                                error_score=self.error_score)\n+            for parameters in parameter_iterable)\n+\n+        for score, parameters, _time in out:\n+            grid_scores.append(_ScoreTuple(parameters, score))\n+\n+        # Store the computed scores\n+        self.grid_scores_ = grid_scores\n+\n+        # Find the best parameters by comparing on the score:\n+        # note that `sorted` is deterministic in the way it breaks ties\n+        best = sorted(grid_scores, key=lambda x: x.score,\n+                      reverse=True)[0]\n+\n+        self.best_params_ = best.parameters\n+        self.best_score_ = best.score\n+\n+        if self.refit:\n+            # fit the best estimator using the entire dataset\n+            # clone first to work around broken estimators\n+            best_estimator = clone(estimator).set_params(\n+                **best.parameters)\n+            if y is not None:\n+                best_estimator.fit(X, y=None, **self.fit_params)\n+            else:\n+                best_estimator.fit(X, **self.fit_params)\n+            self.best_estimator_ = best_estimator\n+        return self\n+\n+\n+def fit_and_score_unsupervised(estimator, X, scorer, verbose, parameters,\n+                               fit_params, y=None, error_score='raise'):\n+    \"\"\"Fit estimator and compute scores for a given dataset.\n+\n+    Parameters\n+    ----------\n+    estimator : estimator object implementing 'fit'\n+        The object to use to fit the data.\n+\n+    X : array-like of shape at least 2D\n+        The data to fit.\n+\n+    y : array-like, shape = [n_samples] or [n_samples, n_output], optional\n+            Target relative to X for classification or regression;\n+            None for unsupervised learning.\n+\n+    scorer : callable\n+        A scorer callable object / function with signature\n+        ``scorer(estimator, X, y)``.\n+\n+    verbose : integer\n+        The verbosity level.\n+\n+    error_score : 'raise' (default) or numeric\n+        Value to assign to the score if an error occurs in estimator fitting.\n+        If set to 'raise', the error is raised. If a numeric value is given,\n+        FitFailedWarning is raised. This parameter does not affect the refit\n+        step, which will always raise the error.\n+\n+    parameters : dict or None\n+        Parameters to be set on the estimator.\n+\n+    fit_params : dict or None\n+        Parameters that will be passed to ``estimator.fit``.\n+\n+    Returns\n+    -------\n+    score : float\n+        Score on the data to fit.\n+\n+    parameters : dict or None, optional\n+        The parameters that have been evaluated.\n+\n+    scoring_time : float\n+        Time spent for fitting and scoring in seconds.\n+\n+    \"\"\"\n+    if parameters is not None:\n+        estimator.set_params(**parameters)\n+\n+    start_time = time.time()\n+\n+    try:\n+        estimator.fit(X, y, **fit_params)\n+        score = scorer(estimator, X)\n+    except Exception as e:\n+        if error_score == 'raise':\n+            raise\n+        elif isinstance(error_score, numbers.Number):\n+            warnings.warn(\"Unsupervised model score failed. \"\n+                          \"The score will be set to %f. \"\n+                          \"Details: \\n%r\" % (error_score, e), FitFailedWarning)\n+\n+            score = error_score\n+        else:\n+            raise ValueError(\"error_score must be the string 'raise' or a\"\n+                             \" numeric value. (Hint: if using 'raise', please\"\n+                             \" make sure that it has been spelled correctly.)\"\n+                             )\n+    # TODO: Handle `verbose` level to produce output\n+    scoring_time = time.time() - start_time\n+\n+    return score, parameters, scoring_time\n+\n+\n+class UnsupervisedGridSearch(BaseSearch, UnsupervisedSearchMixin):\n+\n+    \"\"\"Exhaustive search over specified parameter values for an estimator.\n+\n+    Important members are fit, predict.\n+\n+    GridSearch implements a \"fit\" and a \"score\" method.\n+    It also implements \"predict\", \"predict_proba\", \"decision_function\",\n+    \"transform\" and \"inverse_transform\" if they are implemented in the\n+    estimator used.\n+\n+    The parameters of the estimator used to apply these methods are optimized\n+    by grid-search over a parameter grid.\n+\n+    Read more in the :ref:`User Guide <grid_search>`.\n+\n+    Parameters\n+    ----------\n+    estimator : estimator object.\n+        This is assumed to implement the scikit-learn estimator interface.\n+        Either estimator needs to provide a ``score`` function,\n+        or ``scoring`` must be passed.\n+\n+    param_grid : dict or list of dictionaries\n+        Dictionary with parameters names (string) as keys and lists of\n+        parameter settings to try as values, or a list of such\n+        dictionaries, in which case the grids spanned by each dictionary\n+        in the list are explored. This enables searching over any sequence\n+        of parameter settings.\n+\n+    scoring : string, callable or None, default=None\n+        A string (see model evaluation documentation) or\n+        a scorer callable object / function with signature\n+        ``scorer(estimator, X)``.\n+        If ``None``, the ``score`` method of the estimator is used.\n+\n+    fit_params : dict, optional\n+        Parameters to pass to the fit method.\n+\n+    n_jobs : int, default=1\n+        Number of jobs to run in parallel.\n+\n+    pre_dispatch : int, or string, optional\n+        Controls the number of jobs that get dispatched during parallel\n+        execution. Reducing this number can be useful to avoid an\n+        explosion of memory consumption when more jobs get dispatched\n+        than CPUs can process. This parameter can be:\n+\n+            - None, in which case all the jobs are immediately\n+              created and spawned. Use this for lightweight and\n+              fast-running jobs, to avoid delays due to on-demand\n+              spawning of the jobs\n+\n+            - An int, giving the exact number of total jobs that are\n+              spawned\n+\n+            - A string, giving an expression as a function of n_jobs,\n+              as in '2*n_jobs'\n+\n+    refit : boolean, default=True\n+        Refit the best estimator with the entire dataset.\n+        If \"False\", it is impossible to make predictions using\n+        this GridSearchCV instance after fitting.\n+\n+    verbose : integer\n+        Controls the verbosity: the higher, the more messages.\n+\n+    error_score : 'raise' (default) or numeric\n+        Value to assign to the score if an error occurs in estimator fitting.\n+        If set to 'raise', the error is raised. If a numeric value is given,\n+        FitFailedWarning is raised. This parameter does not affect the refit\n+        step, which will always raise the error.\n+\n+\n+    Examples\n+    --------\n+    >>> from sklearn import datasets, cluster\n+    >>> from sklearn.metrics import silhouette_score, make_scorer\n+    >>> from sklearn.model_selection import UnsupervisedGridSearch\n+    >>> def silhouette_scorer(estimator, X, y=None):\n+    ...     return silhouette_score(X, estimator.labels_)\n+    >>> X, _ = datasets.make_blobs(random_state=8, centers=3, n_samples=1000)\n+    >>> parameters = {'n_clusters': [2,3,4]}\n+    >>> km = cluster.KMeans()\n+    >>> scorer = silhouette_scorer\n+    >>> grid_search = UnsupervisedGridSearch(km, parameters, scoring=scorer)\n+    >>> grid_search.fit(X)\n+    ...                             # doctest: +NORMALIZE_WHITESPACE +ELLIPSIS\n+    UnsupervisedGridSearch(error_score=...,\n+                estimator=KMeans(copy_x=..., init=..., max_iter=300, \n+                n_clusters=8, n_init=10,\n+        n_jobs=1, precompute_distances='auto', random_state=None, tol=0.0001,\n+        verbose=0),\n+                fit_params={}, n_jobs=1, param_grid={'n_clusters': [2, 3, 4]},\n+                pre_dispatch='2*n_jobs', refit=True,\n+                scoring=...,\n+                verbose=0)\n+\n+    Attributes\n+    ----------\n+    grid_scores_ : list of named tuples\n+        Contains scores for all parameter combinations in param_grid.\n+        Each entry corresponds to one parameter setting.\n+        Each named tuple has the attributes:\n+\n+            * ``parameters``, a dict of parameter settings\n+            * ``score``, the score for the estimator\n+\n+    best_estimator_ : estimator\n+        Estimator that was chosen by the search, i.e. estimator\n+        which gave highest score (or smallest loss if specified)\n+        on the left out data. Not available if refit=False.\n+\n+    best_score_ : float\n+        Score of best_estimator.\n+\n+    best_params_ : dict\n+        Parameter setting that gave the best results.\n+\n+    scorer_ : function\n+        Scorer function used to choose the best parameters for the model.\n+\n+    Notes\n+    ------\n+    The parameters selected are those that maximize the score, unless an\n+    explicit score is passed in which case it is used instead.\n+\n+    If `n_jobs` was set to a value higher than one, the data is copied for each\n+    point in the grid (and not `n_jobs` times). This is done for efficiency\n+    reasons if individual jobs take very little time, but may raise errors if\n+    the dataset is large and not enough memory is available.  A workaround in\n+    this case is to set `pre_dispatch`. Then, the memory is copied only\n+    `pre_dispatch` many times. A reasonable value for `pre_dispatch` is `2 *\n+    n_jobs`.\n+\n+    See Also\n+    ---------\n+    :class:`ParameterGrid`:\n+        generates all the combinations of a an hyperparameter grid.\n+\n+    :func:`sklearn.metrics.make_scorer`:\n+        Make a scorer from a performance metric or loss function.\n+\n+    \"\"\"\n+\n+    def __init__(self, estimator, param_grid, scoring=None, fit_params=None,\n+                 n_jobs=1, refit=True, verbose=0,\n+                 pre_dispatch='2*n_jobs', error_score='raise'):\n+\n+        super(UnsupervisedGridSearch, self).__init__(\n+            estimator=estimator, scoring=scoring, fit_params=fit_params,\n+            n_jobs=n_jobs, refit=refit, verbose=verbose,\n+            pre_dispatch=pre_dispatch, error_score=error_score)\n+        self.param_grid = param_grid\n+        _check_param_grid(param_grid)\n+\n+    def fit(self, X, y=None):\n+        \"\"\"Run fit with all sets of parameters.\n+\n+        Parameters\n+        ----------\n+\n+        X : array-like, shape = [n_samples, n_features]\n+            Training vector, where n_samples is the number of samples and\n+            n_features is the number of features.\n+\n+        y : array-like, shape = [n_samples] or [n_samples, n_output], optional\n+            Target relative to X for classification or regression;\n+            None for unsupervised learning.\n+\n+                        \"\"\"\n+        return self._fit(X, y, ParameterGrid(self.param_grid))\n+\n+\n+class UnsupervisedRandomizedSearch(BaseSearch, UnsupervisedSearchMixin):\n+\n+    \"\"\"Randomized search on hyper parameters.\n+\n+    RandomizedSearchCV implements a \"fit\" and a \"score\" method.\n+    It also implements \"predict\", \"predict_proba\", \"decision_function\",\n+    \"transform\" and \"inverse_transform\" if they are implemented in the\n+    estimator used.\n+\n+    The parameters of the estimator used to apply these methods are optimized\n+    by random search over parameter settings.\n+\n+    In contrast to UnsupervisedGridSearch, not all parameter values are tried out,\n+    but rather a fixed number of parameter settings is sampled from the\n+    specified distributions. The number of parameter settings that are tried\n+    is given by n_iter.\n+\n+    If all parameters are presented as a list,\n+    sampling without replacement is performed. If at least one parameter\n+    is given as a distribution, sampling with replacement is used.\n+    It is highly recommended to use continuous distributions for continuous\n+    parameters.\n+\n+    Read more in the :ref:`User Guide <randomized_parameter_search>`.\n+\n+    Parameters\n+    ----------\n+    estimator : estimator object.\n+        A object of that type is instantiated for each grid point.\n+        This is assumed to implement the scikit-learn estimator interface.\n+        Either estimator needs to provide a ``score`` function,\n+        or ``scoring`` must be passed.\n+\n+    param_distributions : dict\n+        Dictionary with parameters names (string) as keys and distributions\n+        or lists of parameters to try. Distributions must provide a ``rvs``\n+        method for sampling (such as those from scipy.stats.distributions).\n+        If a list is given, it is sampled uniformly.\n+\n+    n_iter : int, default=10\n+        Number of parameter settings that are sampled. n_iter trades\n+        off runtime vs quality of the solution.\n+\n+    scoring : string, callable or None, default=None\n+        A string (see model evaluation documentation) or\n+        a scorer callable object / function with signature\n+        ``scorer(estimator, X)``.\n+        If ``None``, the ``score`` method of the estimator is used.\n+\n+    fit_params : dict, optional\n+        Parameters to pass to the fit method.\n+\n+    n_jobs : int, default=1\n+        Number of jobs to run in parallel.\n+\n+    pre_dispatch : int, or string, optional\n+        Controls the number of jobs that get dispatched during parallel\n+        execution. Reducing this number can be useful to avoid an\n+        explosion of memory consumption when more jobs get dispatched\n+        than CPUs can process. This parameter can be:\n+\n+            - None, in which case all the jobs are immediately\n+              created and spawned. Use this for lightweight and\n+              fast-running jobs, to avoid delays due to on-demand\n+              spawning of the jobs\n+\n+            - An int, giving the exact number of total jobs that are\n+              spawned\n+\n+            - A string, giving an expression as a function of n_jobs,\n+              as in '2*n_jobs'\n+\n+    refit : boolean, default=True\n+        Refit the best estimator with the entire dataset.\n+        If \"False\", it is impossible to make predictions using\n+        this RandomizedSearchCV instance after fitting.\n+\n+    verbose : integer\n+        Controls the verbosity: the higher, the more messages.\n+\n+    random_state : int or RandomState\n+        Pseudo random number generator state used for random uniform sampling\n+        from lists of possible values instead of scipy.stats distributions.\n+\n+    error_score : 'raise' (default) or numeric\n+        Value to assign to the score if an error occurs in estimator fitting.\n+        If set to 'raise', the error is raised. If a numeric value is given,\n+        FitFailedWarning is raised. This parameter does not affect the refit\n+        step, which will always raise the error.\n+\n+    Attributes\n+    ----------\n+    grid_scores_ : list of named tuples\n+        Contains scores for all parameter combinations in param_grid.\n+        Each entry corresponds to one parameter setting.\n+        Each named tuple has the attributes:\n+\n+            * ``parameters``, a dict of parameter settings\n+            * ``score``, the score for the estimator\n+\n+    best_estimator_ : estimator\n+        Estimator that was chosen by the search, i.e. estimator\n+        which gave highest score (or smallest loss if specified).\n+        Not available if refit=False.\n+\n+    best_score_ : float\n+        Score of best_estimator.\n+\n+    best_params_ : dict\n+        Parameter setting that gave the best results.\n+\n+    Notes\n+    -----\n+    The parameters selected are those that maximize the score, according to the\n+    scoring parameter.\n+\n+    If `n_jobs` was set to a value higher than one, the data is copied for each\n+    parameter setting(and not `n_jobs` times). This is done for efficiency\n+    reasons if individual jobs take very little time, but may raise errors if\n+    the dataset is large and not enough memory is available.  A workaround in\n+    this case is to set `pre_dispatch`. Then, the memory is copied only\n+    `pre_dispatch` many times. A reasonable value for `pre_dispatch` is `2 *\n+    n_jobs`.\n+\n+    See Also\n+    --------\n+    :class:`UnsupervisedGridSearch`:\n+        Does exhaustive search over a grid of parameters.","path":"sklearn/model_selection/_search.py","position":533,"original_position":533,"commit_id":"ea872a9137431ac3e0d88204da5df241407fa0e6","original_commit_id":"ea872a9137431ac3e0d88204da5df241407fa0e6","user":{"login":"rvraghav93","id":9487348,"avatar_url":"https://avatars.githubusercontent.com/u/9487348?v=3","gravatar_id":"","url":"https://api.github.com/users/rvraghav93","html_url":"https://github.com/rvraghav93","followers_url":"https://api.github.com/users/rvraghav93/followers","following_url":"https://api.github.com/users/rvraghav93/following{/other_user}","gists_url":"https://api.github.com/users/rvraghav93/gists{/gist_id}","starred_url":"https://api.github.com/users/rvraghav93/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rvraghav93/subscriptions","organizations_url":"https://api.github.com/users/rvraghav93/orgs","repos_url":"https://api.github.com/users/rvraghav93/repos","events_url":"https://api.github.com/users/rvraghav93/events{/privacy}","received_events_url":"https://api.github.com/users/rvraghav93/received_events","type":"User","site_admin":false},"body":"... `\"for supervised methods/algorithms\"`?","created_at":"2016-03-01T14:36:31Z","updated_at":"2016-03-01T14:36:31Z","html_url":"https://github.com/scikit-learn/scikit-learn/pull/6160#discussion_r54574246","pull_request_url":"https://api.github.com/repos/scikit-learn/scikit-learn/pulls/6160","_links":{"self":{"href":"https://api.github.com/repos/scikit-learn/scikit-learn/pulls/comments/54574246"},"html":{"href":"https://github.com/scikit-learn/scikit-learn/pull/6160#discussion_r54574246"},"pull_request":{"href":"https://api.github.com/repos/scikit-learn/scikit-learn/pulls/6160"}}},"pull_request":{"url":"https://api.github.com/repos/scikit-learn/scikit-learn/pulls/6160","id":55922361,"html_url":"https://github.com/scikit-learn/scikit-learn/pull/6160","diff_url":"https://github.com/scikit-learn/scikit-learn/pull/6160.diff","patch_url":"https://github.com/scikit-learn/scikit-learn/pull/6160.patch","issue_url":"https://api.github.com/repos/scikit-learn/scikit-learn/issues/6160","number":6160,"state":"open","locked":false,"title":"[MRG] Refactor model_selection._search to include transductive estimators","user":{"login":"jamiebull1","id":3817160,"avatar_url":"https://avatars.githubusercontent.com/u/3817160?v=3","gravatar_id":"","url":"https://api.github.com/users/jamiebull1","html_url":"https://github.com/jamiebull1","followers_url":"https://api.github.com/users/jamiebull1/followers","following_url":"https://api.github.com/users/jamiebull1/following{/other_user}","gists_url":"https://api.github.com/users/jamiebull1/gists{/gist_id}","starred_url":"https://api.github.com/users/jamiebull1/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jamiebull1/subscriptions","organizations_url":"https://api.github.com/users/jamiebull1/orgs","repos_url":"https://api.github.com/users/jamiebull1/repos","events_url":"https://api.github.com/users/jamiebull1/events{/privacy}","received_events_url":"https://api.github.com/users/jamiebull1/received_events","type":"User","site_admin":false},"body":"This generalises `BaseSearchCV` as `BaseSearch` so that it can be used on unsupervised learning where cross-validation does not make sense. The approach is to use a pair of mixins, `SearchClusterMixin` and `SearchCVMixin` to add `_fit` methods appropriate to each type of search.\r\n\r\nThe existing `GridSearchCV` and `RandomizedSearchCV` now inherit `BaseSearch` and `SearchCVMixin` while the new `GridSearchCluster` and `RandomizedSearchCluster` inherit `BaseSearch` and `SearchClusterMixin`.\r\n\r\nSee #6154 for a little more background.\r\n","created_at":"2016-01-13T16:41:33Z","updated_at":"2016-03-01T14:36:31Z","closed_at":null,"merged_at":null,"merge_commit_sha":"4e3854b844a474a6b960ed8349c2af13cca1d182","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/scikit-learn/scikit-learn/pulls/6160/commits","review_comments_url":"https://api.github.com/repos/scikit-learn/scikit-learn/pulls/6160/comments","review_comment_url":"https://api.github.com/repos/scikit-learn/scikit-learn/pulls/comments{/number}","comments_url":"https://api.github.com/repos/scikit-learn/scikit-learn/issues/6160/comments","statuses_url":"https://api.github.com/repos/scikit-learn/scikit-learn/statuses/ea872a9137431ac3e0d88204da5df241407fa0e6","head":{"label":"jamiebull1:refactor_model_selection","ref":"refactor_model_selection","sha":"ea872a9137431ac3e0d88204da5df241407fa0e6","user":{"login":"jamiebull1","id":3817160,"avatar_url":"https://avatars.githubusercontent.com/u/3817160?v=3","gravatar_id":"","url":"https://api.github.com/users/jamiebull1","html_url":"https://github.com/jamiebull1","followers_url":"https://api.github.com/users/jamiebull1/followers","following_url":"https://api.github.com/users/jamiebull1/following{/other_user}","gists_url":"https://api.github.com/users/jamiebull1/gists{/gist_id}","starred_url":"https://api.github.com/users/jamiebull1/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jamiebull1/subscriptions","organizations_url":"https://api.github.com/users/jamiebull1/orgs","repos_url":"https://api.github.com/users/jamiebull1/repos","events_url":"https://api.github.com/users/jamiebull1/events{/privacy}","received_events_url":"https://api.github.com/users/jamiebull1/received_events","type":"User","site_admin":false},"repo":{"id":49583401,"name":"scikit-learn","full_name":"jamiebull1/scikit-learn","owner":{"login":"jamiebull1","id":3817160,"avatar_url":"https://avatars.githubusercontent.com/u/3817160?v=3","gravatar_id":"","url":"https://api.github.com/users/jamiebull1","html_url":"https://github.com/jamiebull1","followers_url":"https://api.github.com/users/jamiebull1/followers","following_url":"https://api.github.com/users/jamiebull1/following{/other_user}","gists_url":"https://api.github.com/users/jamiebull1/gists{/gist_id}","starred_url":"https://api.github.com/users/jamiebull1/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jamiebull1/subscriptions","organizations_url":"https://api.github.com/users/jamiebull1/orgs","repos_url":"https://api.github.com/users/jamiebull1/repos","events_url":"https://api.github.com/users/jamiebull1/events{/privacy}","received_events_url":"https://api.github.com/users/jamiebull1/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/jamiebull1/scikit-learn","description":"scikit-learn: machine learning in Python","fork":true,"url":"https://api.github.com/repos/jamiebull1/scikit-learn","forks_url":"https://api.github.com/repos/jamiebull1/scikit-learn/forks","keys_url":"https://api.github.com/repos/jamiebull1/scikit-learn/keys{/key_id}","collaborators_url":"https://api.github.com/repos/jamiebull1/scikit-learn/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/jamiebull1/scikit-learn/teams","hooks_url":"https://api.github.com/repos/jamiebull1/scikit-learn/hooks","issue_events_url":"https://api.github.com/repos/jamiebull1/scikit-learn/issues/events{/number}","events_url":"https://api.github.com/repos/jamiebull1/scikit-learn/events","assignees_url":"https://api.github.com/repos/jamiebull1/scikit-learn/assignees{/user}","branches_url":"https://api.github.com/repos/jamiebull1/scikit-learn/branches{/branch}","tags_url":"https://api.github.com/repos/jamiebull1/scikit-learn/tags","blobs_url":"https://api.github.com/repos/jamiebull1/scikit-learn/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/jamiebull1/scikit-learn/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/jamiebull1/scikit-learn/git/refs{/sha}","trees_url":"https://api.github.com/repos/jamiebull1/scikit-learn/git/trees{/sha}","statuses_url":"https://api.github.com/repos/jamiebull1/scikit-learn/statuses/{sha}","languages_url":"https://api.github.com/repos/jamiebull1/scikit-learn/languages","stargazers_url":"https://api.github.com/repos/jamiebull1/scikit-learn/stargazers","contributors_url":"https://api.github.com/repos/jamiebull1/scikit-learn/contributors","subscribers_url":"https://api.github.com/repos/jamiebull1/scikit-learn/subscribers","subscription_url":"https://api.github.com/repos/jamiebull1/scikit-learn/subscription","commits_url":"https://api.github.com/repos/jamiebull1/scikit-learn/commits{/sha}","git_commits_url":"https://api.github.com/repos/jamiebull1/scikit-learn/git/commits{/sha}","comments_url":"https://api.github.com/repos/jamiebull1/scikit-learn/comments{/number}","issue_comment_url":"https://api.github.com/repos/jamiebull1/scikit-learn/issues/comments{/number}","contents_url":"https://api.github.com/repos/jamiebull1/scikit-learn/contents/{+path}","compare_url":"https://api.github.com/repos/jamiebull1/scikit-learn/compare/{base}...{head}","merges_url":"https://api.github.com/repos/jamiebull1/scikit-learn/merges","archive_url":"https://api.github.com/repos/jamiebull1/scikit-learn/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/jamiebull1/scikit-learn/downloads","issues_url":"https://api.github.com/repos/jamiebull1/scikit-learn/issues{/number}","pulls_url":"https://api.github.com/repos/jamiebull1/scikit-learn/pulls{/number}","milestones_url":"https://api.github.com/repos/jamiebull1/scikit-learn/milestones{/number}","notifications_url":"https://api.github.com/repos/jamiebull1/scikit-learn/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/jamiebull1/scikit-learn/labels{/name}","releases_url":"https://api.github.com/repos/jamiebull1/scikit-learn/releases{/id}","deployments_url":"https://api.github.com/repos/jamiebull1/scikit-learn/deployments","created_at":"2016-01-13T15:43:13Z","updated_at":"2016-01-13T15:43:20Z","pushed_at":"2016-03-01T13:16:02Z","git_url":"git://github.com/jamiebull1/scikit-learn.git","ssh_url":"git@github.com:jamiebull1/scikit-learn.git","clone_url":"https://github.com/jamiebull1/scikit-learn.git","svn_url":"https://github.com/jamiebull1/scikit-learn","homepage":"http://scikit-learn.org","size":66115,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"scikit-learn:master","ref":"master","sha":"4c7619be1b67565be9198dba4001555019d29c32","user":{"login":"scikit-learn","id":365630,"avatar_url":"https://avatars.githubusercontent.com/u/365630?v=3","gravatar_id":"","url":"https://api.github.com/users/scikit-learn","html_url":"https://github.com/scikit-learn","followers_url":"https://api.github.com/users/scikit-learn/followers","following_url":"https://api.github.com/users/scikit-learn/following{/other_user}","gists_url":"https://api.github.com/users/scikit-learn/gists{/gist_id}","starred_url":"https://api.github.com/users/scikit-learn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/scikit-learn/subscriptions","organizations_url":"https://api.github.com/users/scikit-learn/orgs","repos_url":"https://api.github.com/users/scikit-learn/repos","events_url":"https://api.github.com/users/scikit-learn/events{/privacy}","received_events_url":"https://api.github.com/users/scikit-learn/received_events","type":"Organization","site_admin":false},"repo":{"id":843222,"name":"scikit-learn","full_name":"scikit-learn/scikit-learn","owner":{"login":"scikit-learn","id":365630,"avatar_url":"https://avatars.githubusercontent.com/u/365630?v=3","gravatar_id":"","url":"https://api.github.com/users/scikit-learn","html_url":"https://github.com/scikit-learn","followers_url":"https://api.github.com/users/scikit-learn/followers","following_url":"https://api.github.com/users/scikit-learn/following{/other_user}","gists_url":"https://api.github.com/users/scikit-learn/gists{/gist_id}","starred_url":"https://api.github.com/users/scikit-learn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/scikit-learn/subscriptions","organizations_url":"https://api.github.com/users/scikit-learn/orgs","repos_url":"https://api.github.com/users/scikit-learn/repos","events_url":"https://api.github.com/users/scikit-learn/events{/privacy}","received_events_url":"https://api.github.com/users/scikit-learn/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/scikit-learn/scikit-learn","description":"scikit-learn: machine learning in Python","fork":false,"url":"https://api.github.com/repos/scikit-learn/scikit-learn","forks_url":"https://api.github.com/repos/scikit-learn/scikit-learn/forks","keys_url":"https://api.github.com/repos/scikit-learn/scikit-learn/keys{/key_id}","collaborators_url":"https://api.github.com/repos/scikit-learn/scikit-learn/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/scikit-learn/scikit-learn/teams","hooks_url":"https://api.github.com/repos/scikit-learn/scikit-learn/hooks","issue_events_url":"https://api.github.com/repos/scikit-learn/scikit-learn/issues/events{/number}","events_url":"https://api.github.com/repos/scikit-learn/scikit-learn/events","assignees_url":"https://api.github.com/repos/scikit-learn/scikit-learn/assignees{/user}","branches_url":"https://api.github.com/repos/scikit-learn/scikit-learn/branches{/branch}","tags_url":"https://api.github.com/repos/scikit-learn/scikit-learn/tags","blobs_url":"https://api.github.com/repos/scikit-learn/scikit-learn/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/scikit-learn/scikit-learn/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/scikit-learn/scikit-learn/git/refs{/sha}","trees_url":"https://api.github.com/repos/scikit-learn/scikit-learn/git/trees{/sha}","statuses_url":"https://api.github.com/repos/scikit-learn/scikit-learn/statuses/{sha}","languages_url":"https://api.github.com/repos/scikit-learn/scikit-learn/languages","stargazers_url":"https://api.github.com/repos/scikit-learn/scikit-learn/stargazers","contributors_url":"https://api.github.com/repos/scikit-learn/scikit-learn/contributors","subscribers_url":"https://api.github.com/repos/scikit-learn/scikit-learn/subscribers","subscription_url":"https://api.github.com/repos/scikit-learn/scikit-learn/subscription","commits_url":"https://api.github.com/repos/scikit-learn/scikit-learn/commits{/sha}","git_commits_url":"https://api.github.com/repos/scikit-learn/scikit-learn/git/commits{/sha}","comments_url":"https://api.github.com/repos/scikit-learn/scikit-learn/comments{/number}","issue_comment_url":"https://api.github.com/repos/scikit-learn/scikit-learn/issues/comments{/number}","contents_url":"https://api.github.com/repos/scikit-learn/scikit-learn/contents/{+path}","compare_url":"https://api.github.com/repos/scikit-learn/scikit-learn/compare/{base}...{head}","merges_url":"https://api.github.com/repos/scikit-learn/scikit-learn/merges","archive_url":"https://api.github.com/repos/scikit-learn/scikit-learn/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/scikit-learn/scikit-learn/downloads","issues_url":"https://api.github.com/repos/scikit-learn/scikit-learn/issues{/number}","pulls_url":"https://api.github.com/repos/scikit-learn/scikit-learn/pulls{/number}","milestones_url":"https://api.github.com/repos/scikit-learn/scikit-learn/milestones{/number}","notifications_url":"https://api.github.com/repos/scikit-learn/scikit-learn/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/scikit-learn/scikit-learn/labels{/name}","releases_url":"https://api.github.com/repos/scikit-learn/scikit-learn/releases{/id}","deployments_url":"https://api.github.com/repos/scikit-learn/scikit-learn/deployments","created_at":"2010-08-17T09:43:38Z","updated_at":"2016-03-01T13:47:26Z","pushed_at":"2016-03-01T14:31:37Z","git_url":"git://github.com/scikit-learn/scikit-learn.git","ssh_url":"git@github.com:scikit-learn/scikit-learn.git","clone_url":"https://github.com/scikit-learn/scikit-learn.git","svn_url":"https://github.com/scikit-learn/scikit-learn","homepage":"http://scikit-learn.org","size":101142,"stargazers_count":9963,"watchers_count":9963,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":5836,"mirror_url":null,"open_issues_count":1087,"forks":5836,"open_issues":1087,"watchers":9963,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/scikit-learn/scikit-learn/pulls/6160"},"html":{"href":"https://github.com/scikit-learn/scikit-learn/pull/6160"},"issue":{"href":"https://api.github.com/repos/scikit-learn/scikit-learn/issues/6160"},"comments":{"href":"https://api.github.com/repos/scikit-learn/scikit-learn/issues/6160/comments"},"review_comments":{"href":"https://api.github.com/repos/scikit-learn/scikit-learn/pulls/6160/comments"},"review_comment":{"href":"https://api.github.com/repos/scikit-learn/scikit-learn/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/scikit-learn/scikit-learn/pulls/6160/commits"},"statuses":{"href":"https://api.github.com/repos/scikit-learn/scikit-learn/statuses/ea872a9137431ac3e0d88204da5df241407fa0e6"}}}}