{"action":"created","comment":{"url":"https://api.github.com/repos/scikit-learn/scikit-learn/pulls/comments/36873226","id":36873226,"diff_hunk":"@@ -254,8 +340,222 @@ def _nls_subproblem(V, W, H, tol, max_iter, sigma=0.01, beta=0.1):\n     return H, grad, n_iter\n \n \n-class ProjectedGradientNMF(BaseEstimator, TransformerMixin):\n-    \"\"\"Non-Negative matrix factorization by Projected Gradient (NMF)\n+def _update_projected_gradient_w(X, W, H, tolW, nls_max_iter, alpha, l1_ratio,\n+                                 sparseness, beta, eta):\n+    \"\"\"Helper function for _fit_projected_gradient\"\"\"\n+    n_samples, n_features = X.shape\n+    n_components_ = H.shape[0]\n+\n+    if sparseness is None:\n+        Wt, gradW, iterW = _nls_subproblem(X.T, H.T, W.T, tolW, nls_max_iter,\n+                                           regul=alpha, l1_ratio=l1_ratio)\n+    elif sparseness == 'data':\n+        Wt, gradW, iterW = _nls_subproblem(\n+            safe_vstack([X.T, np.zeros((1, n_samples))]),\n+            safe_vstack([H.T, np.sqrt(beta) * np.ones((1,\n+                         n_components_))]),\n+            W.T, tolW, nls_max_iter, regul=alpha, l1_ratio=l1_ratio)\n+    elif sparseness == 'components':\n+        Wt, gradW, iterW = _nls_subproblem(\n+            safe_vstack([X.T,\n+                         np.zeros((n_components_, n_samples))]),\n+            safe_vstack([H.T,\n+                         np.sqrt(eta) * np.eye(n_components_)]),\n+            W.T, tolW, nls_max_iter, regul=alpha, l1_ratio=l1_ratio)\n+\n+    return Wt.T, gradW.T, iterW\n+\n+\n+def _update_projected_gradient_h(X, W, H, tolH, nls_max_iter, alpha, l1_ratio,\n+                                 sparseness, beta, eta):\n+    \"\"\"Helper function for _fit_projected_gradient\"\"\"\n+    n_samples, n_features = X.shape\n+    n_components_ = W.shape[1]\n+\n+    if sparseness is None:\n+        H, gradH, iterH = _nls_subproblem(X, W, H, tolH, nls_max_iter,\n+                                          regul=alpha, l1_ratio=l1_ratio)\n+    elif sparseness == 'data':\n+        H, gradH, iterH = _nls_subproblem(\n+            safe_vstack([X, np.zeros((n_components_, n_features))]),\n+            safe_vstack([W,\n+                         np.sqrt(eta) * np.eye(n_components_)]),\n+            H, tolH, nls_max_iter, regul=alpha, l1_ratio=l1_ratio)\n+    elif sparseness == 'components':\n+        H, gradH, iterH = _nls_subproblem(\n+            safe_vstack([X, np.zeros((1, n_features))]),\n+            safe_vstack([W,\n+                         np.sqrt(beta)\n+                         * np.ones((1, n_components_))]),\n+            H, tolH, nls_max_iter, regul=alpha, l1_ratio=l1_ratio)\n+\n+    return H, gradH, iterH\n+\n+\n+def _fit_projected_gradient(X, W, H, tol, max_iter,\n+                            nls_max_iter, alpha, l1_ratio,\n+                            sparseness, beta, eta):\n+    \"\"\"Compute Non-negative Matrix Factorization (NMF) with Projected Gradient\n+    \"\"\"\n+    gradW = (np.dot(W, np.dot(H, H.T))\n+             - safe_sparse_dot(X, H.T, dense_output=True))\n+    gradH = (np.dot(np.dot(W.T, W), H)\n+             - safe_sparse_dot(W.T, X, dense_output=True))\n+\n+    init_grad = squared_norm(gradW) + squared_norm(gradH.T)\n+    # max(0.001, tol) to force alternating minimizations of W and H\n+    tolW = max(0.001, tol) * np.sqrt(init_grad)\n+    tolH = tolW\n+\n+    for n_iter in range(1, max_iter + 1):\n+        # stopping condition\n+        # as discussed in paper\n+        proj_grad_W = squared_norm(gradW * np.logical_or(gradW < 0, W > 0))\n+        proj_grad_H = squared_norm(gradH * np.logical_or(gradH < 0, H > 0))\n+\n+        if (proj_grad_W + proj_grad_H) / init_grad < tol ** 2:\n+            break\n+\n+        # update W\n+        W, gradW, iterW = _update_projected_gradient_w(X, W, H, tolW,\n+                                                       nls_max_iter,\n+                                                       alpha, l1_ratio,\n+                                                       sparseness, beta, eta)\n+        if iterW == 1:\n+            tolW = 0.1 * tolW\n+\n+        # update H\n+        H, gradH, iterH = _update_projected_gradient_h(X, W, H, tolH,\n+                                                       nls_max_iter,\n+                                                       alpha, l1_ratio,\n+                                                       sparseness, beta, eta)\n+        if iterH == 1:\n+            tolH = 0.1 * tolH\n+\n+    H[H == 0] = 0   # fix up negative zeros\n+\n+    if n_iter == max_iter:\n+        warnings.warn(\"Iteration limit reached during fit. \")\n+        W, _, _ = _update_projected_gradient_w(X, W, H, tol, nls_max_iter,\n+                                               alpha, l1_ratio, sparseness,\n+                                               beta, eta)\n+\n+    return W, H, n_iter\n+\n+\n+def _update_coordinate_descent(X, W, Ht, alpha, l1_ratio):\n+    \"\"\"Helper function for fit_coordinate_descent\"\"\"\n+    WtW = fast_dot(W.T, W)\n+    WtX = safe_sparse_dot(W.T, X)\n+\n+    if WtW.flags['F_CONTIGUOUS']:\n+        WtW = WtW.T\n+\n+    if WtX.flags['F_CONTIGUOUS']:\n+        return _update_cdnmf_fast(Ht, WtW, WtX.T, alpha, l1_ratio, True)\n+    else:\n+        return _update_cdnmf_fast(Ht, WtW, WtX, alpha, l1_ratio, False)\n+\n+\n+def fit_coordinate_descent(X, W, H, tol=1e-4, max_iter=200, alpha=0.001,\n+                           l1_ratio=0., regularization=None,\n+                           update_H=True, verbose=0):\n+    \"\"\"Compute Non-negative Matrix Factorization (NMF) with Coordinate Descent\n+\n+    Find (W, H) that minimize || X - W.H ||_2\n+    with an alternative least square minimization of W and H.\n+    Each minimization is done with a Coordinate Descent.\n+\n+    Parameters\n+    ----------\n+    X : array-like, shape (n_samples, n_features)\n+        Constant matrix.\n+\n+    W : array-like, shape (n_samples, n_components)\n+        Initial guess for the solution.\n+\n+    H : array-like, shape (n_components, n_features)\n+        Initial guess for the solution.\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+    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+    verbose : integer, default: 0\n+        The verbosity level.\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+        The number of iterations done by the algorithm.\n+\n+    References\n+    ----------\n+    Hsieh, Cho-Jui, and Inderjit S. Dhillon. \"Fast coordinate descent methods\n+    with variable selection for non-negative matrix factorization.\"\n+    Proceedings of the 17th ACM SIGKDD. ACM, 2011.","path":"sklearn/decomposition/nmf.py","position":508,"original_position":457,"commit_id":"79e8bd793746580bec090fcaa9a001a627d3bef0","original_commit_id":"b0aa83046335c046e06a6c09dd5b82ea931fc873","user":{"login":"mblondel","id":233706,"avatar_url":"https://avatars.githubusercontent.com/u/233706?v=3","gravatar_id":"","url":"https://api.github.com/users/mblondel","html_url":"https://github.com/mblondel","followers_url":"https://api.github.com/users/mblondel/followers","following_url":"https://api.github.com/users/mblondel/following{/other_user}","gists_url":"https://api.github.com/users/mblondel/gists{/gist_id}","starred_url":"https://api.github.com/users/mblondel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mblondel/subscriptions","organizations_url":"https://api.github.com/users/mblondel/orgs","repos_url":"https://api.github.com/users/mblondel/repos","events_url":"https://api.github.com/users/mblondel/events{/privacy}","received_events_url":"https://api.github.com/users/mblondel/received_events","type":"User","site_admin":false},"body":"Same here, remove the reference for the time being.","created_at":"2015-08-12T15:25:35Z","updated_at":"2015-08-12T15:25:35Z","html_url":"https://github.com/scikit-learn/scikit-learn/pull/4852#discussion_r36873226","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/36873226"},"html":{"href":"https://github.com/scikit-learn/scikit-learn/pull/4852#discussion_r36873226"},"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-12T15:25:35Z","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-12T14:09:49Z","pushed_at":"2015-08-12T14:28:55Z","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":129984,"stargazers_count":7127,"watchers_count":7127,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":4226,"mirror_url":null,"open_issues_count":765,"forks":4226,"open_issues":765,"watchers":7127,"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"}}}}