{"action":"created","comment":{"url":"https://api.github.com/repos/scikit-learn/scikit-learn/pulls/comments/37311452","id":37311452,"diff_hunk":"@@ -277,30 +632,208 @@ class ProjectedGradientNMF(BaseEstimator, TransformerMixin):\n             'nndsvdar': NNDSVD with zeros filled with small random values\n                 (generally faster, less accurate alternative to NNDSVDa\n                 for when sparsity is not desired)\n-            'random': non-negative random matrices\n+            'custom': use custom matrices W and H\n+\n+    update_H : boolean, default: True\n+        Set to True, both W and H will be estimated from initial guesses.\n+        Set to False, only W will be estimated.\n+\n+    solver : 'proj-grad' | 'coordinate'\n+        Numerical solver to use.\n+\n+    tol : float, default: 1e-4\n+        Tolerance of the stopping condition.\n+\n+    max_iter : integer, default: 200\n+        Maximum number of iterations before timing out.\n+\n+    alpha : double, default: 0.\n+        Constant that multiplies the regularization terms.\n+\n+    l1_ratio : double, default: 0.\n+        The regularization mixing parameter, with 0 <= l1_ratio <= 1.\n+        For l1_ratio = 0 the penalty is an L2 penalty.\n+        For l1_ratio = 1 it is an L1 penalty.\n+        For 0 < l1_ratio < 1, the penalty is a combination of L1 and L2.\n+\n+    regularization : 'both' | 'components' | 'transformation' | None\n+        Select whether the regularization affects the components (H), the\n+        transformation (W), both or none of them.\n+\n+    random_state : integer seed, RandomState instance, or None (default)\n+        Random number generator seed control.\n+\n+    verbose : integer, default: 0\n+        The verbosity level.\n+\n+    shuffle : boolean\n+        If True, the samples will be taken in shuffled order during\n+        coordinate descent.\n+\n+    nls_max_iter : integer, default: 2000\n+        Number of iterations in NLS subproblem.\n+        Used only in deprecated proj-grad solver.\n \n     sparseness : 'data' | 'components' | None, default: None\n         Where to enforce sparsity in the model.\n+        Used only in deprecated proj-grad solver.\n \n     beta : double, default: 1\n         Degree of sparseness, if sparseness is not None. Larger values mean\n-        more sparseness.\n+        more sparseness. Used only in deprecated proj-grad solver.\n \n     eta : double, default: 0.1\n         Degree of correctness to maintain, if sparsity is not None. Smaller\n-        values mean larger error.\n+        values mean larger error. Used only in deprecated proj-grad solver.\n+\n+    Returns\n+    -------\n+    W : array-like, shape (n_samples, n_components)\n+        Solution to the non-negative least squares problem.\n+\n+    H : array-like, shape (n_components, n_features)\n+        Solution to the non-negative least squares problem.\n+\n+    n_iter : int\n+        Actual number of iterations.\n+\n+    References\n+    ----------\n+    C.-J. Lin. Projected gradient methods for non-negative matrix\n+    factorization. Neural Computation, 19(2007), 2756-2779.\n+    http://www.csie.ntu.edu.tw/~cjlin/nmf/\n+    \"\"\"\n+\n+    X = check_array(X, accept_sparse=('csr', 'csc'))\n+    check_non_negative(X, \"NMF (input X)\")\n+    _check_string_param(sparseness, solver)\n+\n+    n_samples, n_features = X.shape\n+    if n_components is None:\n+        n_components = n_features\n+\n+    if not isinstance(n_components, six.integer_types) or n_components <= 0:\n+        raise ValueError(\"Number of components must be positive;\"\n+                         \" got (n_components=%r)\" % n_components)\n+    if not isinstance(max_iter, numbers.Number) or max_iter < 0:\n+        raise ValueError(\"Maximum number of iteration must be positive;\"\n+                         \" got (max_iter=%r)\" % max_iter)\n+    if not isinstance(tol, numbers.Number) or tol < 0:\n+        raise ValueError(\"Tolerance for stopping criteria must be \"\n+                         \"positive; got (tol=%r)\" % tol)\n+\n+    # check W and H, or initialize them\n+    if init == 'custom':\n+        _check_init(H, (n_components, n_features), \"NMF (input H)\")\n+        _check_init(W, (n_samples, n_components), \"NMF (input W)\")\n+    elif not update_H:\n+        _check_init(H, (n_components, n_features), \"NMF (input H)\")\n+        W = np.zeros((n_samples, n_components))\n+    else:\n+        W, H = _initialize_nmf(X, n_components, init,\n+                               random_state=random_state)\n+\n+    if solver == 'proj-grad':\n+        warnings.warn(\"'proj-grad' solver will be removed in release 0.19.\"\n+                      \" Use 'coordinate' solver instead.\", DeprecationWarning)\n+        if update_H:  # fit_transform\n+            W, H, n_iter = _fit_projected_gradient(X, W, H, tol,\n+                                                   max_iter,\n+                                                   nls_max_iter,\n+                                                   alpha, l1_ratio,\n+                                                   sparseness,\n+                                                   beta, eta)\n+        else:  # transform\n+            W, H, n_iter = _update_projected_gradient_w(X, W, H,\n+                                                        tol, nls_max_iter,\n+                                                        alpha, l1_ratio,\n+                                                        sparseness, beta,\n+                                                        eta)\n+    elif solver == 'coordinate':\n+        W, H, n_iter = _fit_coordinate_descent(X, W, H, tol,\n+                                               max_iter,\n+                                               alpha, l1_ratio,\n+                                               regularization,\n+                                               update_H=update_H,\n+                                               verbose=verbose,\n+                                               shuffle=shuffle,\n+                                               random_state=random_state)\n+    else:\n+        raise ValueError(\"Invalid solver parameter '%s'.\" % solver)\n+\n+    if n_iter == max_iter:\n+        warnings.warn(\"Maximum number of iteration %d reached. Increase it to\"\n+                      \" improve convergence.\" % max_iter, ConvergenceWarning)\n+\n+    return W, H, n_iter\n+\n+\n+class NMF(BaseEstimator, TransformerMixin):\n+    \"\"\"Non-Negative matrix factorization (NMF)\n+\n+    Read more in the :ref:`User Guide <NMF>`.\n+\n+    Parameters\n+    ----------\n+    n_components : int or None\n+        Number of components, if n_components is not set all features\n+        are kept.\n+\n+    solver : 'proj-grad' | 'coordinate'\n+        Numerical solver to use.\n+\n+    init :  'random' | 'nndsvd' |  'nndsvda' | 'nndsvdar' | 'custom'\n+        Method used to initialize the procedure.\n+        Default: 'nndsvdar' if n_components < n_features, otherwise random.\n+        Valid options::\n+            'random': non-negative random matrices\n+            'nndsvd': Nonnegative Double Singular Value Decomposition (NNDSVD)\n+                initialization (better for sparseness)\n+            'nndsvda': NNDSVD with zeros filled with the average of X\n+                (better when sparsity is not desired)\n+            'nndsvdar': NNDSVD with zeros filled with small random values\n+                (generally faster, less accurate alternative to NNDSVDa\n+                for when sparsity is not desired)\n+            'custom': use custom matrices W and H, given in fit()","path":"sklearn/decomposition/nmf.py","position":760,"original_position":760,"commit_id":"79e8bd793746580bec090fcaa9a001a627d3bef0","original_commit_id":"79e8bd793746580bec090fcaa9a001a627d3bef0","user":{"login":"vene","id":241745,"avatar_url":"https://avatars.githubusercontent.com/u/241745?v=3","gravatar_id":"","url":"https://api.github.com/users/vene","html_url":"https://github.com/vene","followers_url":"https://api.github.com/users/vene/followers","following_url":"https://api.github.com/users/vene/following{/other_user}","gists_url":"https://api.github.com/users/vene/gists{/gist_id}","starred_url":"https://api.github.com/users/vene/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/vene/subscriptions","organizations_url":"https://api.github.com/users/vene/orgs","repos_url":"https://api.github.com/users/vene/repos","events_url":"https://api.github.com/users/vene/events{/privacy}","received_events_url":"https://api.github.com/users/vene/received_events","type":"User","site_admin":false},"body":"+0.5 for ```s/fit()/`fit` ```","created_at":"2015-08-18T15:21:34Z","updated_at":"2015-08-18T15:21:34Z","html_url":"https://github.com/scikit-learn/scikit-learn/pull/4852#discussion_r37311452","pull_request_url":"https://api.github.com/repos/scikit-learn/scikit-learn/pulls/4852","_links":{"self":{"href":"https://api.github.com/repos/scikit-learn/scikit-learn/pulls/comments/37311452"},"html":{"href":"https://github.com/scikit-learn/scikit-learn/pull/4852#discussion_r37311452"},"pull_request":{"href":"https://api.github.com/repos/scikit-learn/scikit-learn/pulls/4852"}}},"pull_request":{"url":"https://api.github.com/repos/scikit-learn/scikit-learn/pulls/4852","id":37473716,"html_url":"https://github.com/scikit-learn/scikit-learn/pull/4852","diff_url":"https://github.com/scikit-learn/scikit-learn/pull/4852.diff","patch_url":"https://github.com/scikit-learn/scikit-learn/pull/4852.patch","issue_url":"https://api.github.com/repos/scikit-learn/scikit-learn/issues/4852","number":4852,"state":"open","locked":false,"title":"[MRG] refactor NMF and add CD solver","user":{"login":"TomDLT","id":11065596,"avatar_url":"https://avatars.githubusercontent.com/u/11065596?v=3","gravatar_id":"","url":"https://api.github.com/users/TomDLT","html_url":"https://github.com/TomDLT","followers_url":"https://api.github.com/users/TomDLT/followers","following_url":"https://api.github.com/users/TomDLT/following{/other_user}","gists_url":"https://api.github.com/users/TomDLT/gists{/gist_id}","starred_url":"https://api.github.com/users/TomDLT/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/TomDLT/subscriptions","organizations_url":"https://api.github.com/users/TomDLT/orgs","repos_url":"https://api.github.com/users/TomDLT/repos","events_url":"https://api.github.com/users/TomDLT/events{/privacy}","received_events_url":"https://api.github.com/users/TomDLT/received_events","type":"User","site_admin":false},"body":"This PR is a first part of what is discussed in #4811.\r\nIt includes:\r\n- refactor ProjectedGradientNMF into NMF, with a 'proj-grad' solver\r\n- include random initialization into `_initialize_nmf()`\r\n- add ElasticNet-like regularization (with parameters `alpha` and `l1_ratio`)\r\n- add a solver with Coordinate Descent (from @mblondel) with Cython for critical part\r\n- update some tests and bench_plot_nmf (which looks terrible btw)\r\n\r\nIn some future PR, I will:\r\n- include MM (cf [comment](https://github.com/scikit-learn/scikit-learn/issues/4811#issuecomment-110391396)) in order to include more loss functions (I-divergence and IS-divergence)\r\n- investigate more on initialization of NMF\r\n- ...\r\n\r\nPlease tell me what you think :)","created_at":"2015-06-11T15:08:32Z","updated_at":"2015-08-18T15:21:34Z","closed_at":null,"merged_at":null,"merge_commit_sha":"ca47b25e7a34841c189c805270cef0044aebcc04","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/scikit-learn/scikit-learn/pulls/4852/commits","review_comments_url":"https://api.github.com/repos/scikit-learn/scikit-learn/pulls/4852/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/4852/comments","statuses_url":"https://api.github.com/repos/scikit-learn/scikit-learn/statuses/79e8bd793746580bec090fcaa9a001a627d3bef0","head":{"label":"TomDLT:nmf","ref":"nmf","sha":"79e8bd793746580bec090fcaa9a001a627d3bef0","user":{"login":"TomDLT","id":11065596,"avatar_url":"https://avatars.githubusercontent.com/u/11065596?v=3","gravatar_id":"","url":"https://api.github.com/users/TomDLT","html_url":"https://github.com/TomDLT","followers_url":"https://api.github.com/users/TomDLT/followers","following_url":"https://api.github.com/users/TomDLT/following{/other_user}","gists_url":"https://api.github.com/users/TomDLT/gists{/gist_id}","starred_url":"https://api.github.com/users/TomDLT/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/TomDLT/subscriptions","organizations_url":"https://api.github.com/users/TomDLT/orgs","repos_url":"https://api.github.com/users/TomDLT/repos","events_url":"https://api.github.com/users/TomDLT/events{/privacy}","received_events_url":"https://api.github.com/users/TomDLT/received_events","type":"User","site_admin":false},"repo":{"id":34376788,"name":"scikit-learn","full_name":"TomDLT/scikit-learn","owner":{"login":"TomDLT","id":11065596,"avatar_url":"https://avatars.githubusercontent.com/u/11065596?v=3","gravatar_id":"","url":"https://api.github.com/users/TomDLT","html_url":"https://github.com/TomDLT","followers_url":"https://api.github.com/users/TomDLT/followers","following_url":"https://api.github.com/users/TomDLT/following{/other_user}","gists_url":"https://api.github.com/users/TomDLT/gists{/gist_id}","starred_url":"https://api.github.com/users/TomDLT/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/TomDLT/subscriptions","organizations_url":"https://api.github.com/users/TomDLT/orgs","repos_url":"https://api.github.com/users/TomDLT/repos","events_url":"https://api.github.com/users/TomDLT/events{/privacy}","received_events_url":"https://api.github.com/users/TomDLT/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/TomDLT/scikit-learn","description":"scikit-learn: machine learning in Python","fork":true,"url":"https://api.github.com/repos/TomDLT/scikit-learn","forks_url":"https://api.github.com/repos/TomDLT/scikit-learn/forks","keys_url":"https://api.github.com/repos/TomDLT/scikit-learn/keys{/key_id}","collaborators_url":"https://api.github.com/repos/TomDLT/scikit-learn/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/TomDLT/scikit-learn/teams","hooks_url":"https://api.github.com/repos/TomDLT/scikit-learn/hooks","issue_events_url":"https://api.github.com/repos/TomDLT/scikit-learn/issues/events{/number}","events_url":"https://api.github.com/repos/TomDLT/scikit-learn/events","assignees_url":"https://api.github.com/repos/TomDLT/scikit-learn/assignees{/user}","branches_url":"https://api.github.com/repos/TomDLT/scikit-learn/branches{/branch}","tags_url":"https://api.github.com/repos/TomDLT/scikit-learn/tags","blobs_url":"https://api.github.com/repos/TomDLT/scikit-learn/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/TomDLT/scikit-learn/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/TomDLT/scikit-learn/git/refs{/sha}","trees_url":"https://api.github.com/repos/TomDLT/scikit-learn/git/trees{/sha}","statuses_url":"https://api.github.com/repos/TomDLT/scikit-learn/statuses/{sha}","languages_url":"https://api.github.com/repos/TomDLT/scikit-learn/languages","stargazers_url":"https://api.github.com/repos/TomDLT/scikit-learn/stargazers","contributors_url":"https://api.github.com/repos/TomDLT/scikit-learn/contributors","subscribers_url":"https://api.github.com/repos/TomDLT/scikit-learn/subscribers","subscription_url":"https://api.github.com/repos/TomDLT/scikit-learn/subscription","commits_url":"https://api.github.com/repos/TomDLT/scikit-learn/commits{/sha}","git_commits_url":"https://api.github.com/repos/TomDLT/scikit-learn/git/commits{/sha}","comments_url":"https://api.github.com/repos/TomDLT/scikit-learn/comments{/number}","issue_comment_url":"https://api.github.com/repos/TomDLT/scikit-learn/issues/comments{/number}","contents_url":"https://api.github.com/repos/TomDLT/scikit-learn/contents/{+path}","compare_url":"https://api.github.com/repos/TomDLT/scikit-learn/compare/{base}...{head}","merges_url":"https://api.github.com/repos/TomDLT/scikit-learn/merges","archive_url":"https://api.github.com/repos/TomDLT/scikit-learn/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/TomDLT/scikit-learn/downloads","issues_url":"https://api.github.com/repos/TomDLT/scikit-learn/issues{/number}","pulls_url":"https://api.github.com/repos/TomDLT/scikit-learn/pulls{/number}","milestones_url":"https://api.github.com/repos/TomDLT/scikit-learn/milestones{/number}","notifications_url":"https://api.github.com/repos/TomDLT/scikit-learn/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/TomDLT/scikit-learn/labels{/name}","releases_url":"https://api.github.com/repos/TomDLT/scikit-learn/releases{/id}","created_at":"2015-04-22T07:53:08Z","updated_at":"2015-05-12T12:17:35Z","pushed_at":"2015-08-05T11:37:45Z","git_url":"git://github.com/TomDLT/scikit-learn.git","ssh_url":"git@github.com:TomDLT/scikit-learn.git","clone_url":"https://github.com/TomDLT/scikit-learn.git","svn_url":"https://github.com/TomDLT/scikit-learn","homepage":"http://scikit-learn.org","size":65195,"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":"13c241fb6b229c4fa80a4e67babaa052d65b0a2a","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}","created_at":"2010-08-17T09:43:38Z","updated_at":"2015-08-18T11:31:23Z","pushed_at":"2015-08-18T15:13:02Z","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":131194,"stargazers_count":7206,"watchers_count":7206,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":4259,"mirror_url":null,"open_issues_count":763,"forks":4259,"open_issues":763,"watchers":7206,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/scikit-learn/scikit-learn/pulls/4852"},"html":{"href":"https://github.com/scikit-learn/scikit-learn/pull/4852"},"issue":{"href":"https://api.github.com/repos/scikit-learn/scikit-learn/issues/4852"},"comments":{"href":"https://api.github.com/repos/scikit-learn/scikit-learn/issues/4852/comments"},"review_comments":{"href":"https://api.github.com/repos/scikit-learn/scikit-learn/pulls/4852/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/4852/commits"},"statuses":{"href":"https://api.github.com/repos/scikit-learn/scikit-learn/statuses/79e8bd793746580bec090fcaa9a001a627d3bef0"}}}}