{"action":"created","comment":{"url":"https://api.github.com/repos/apache/spark/pulls/comments/60779700","id":60779700,"diff_hunk":"@@ -261,58 +261,93 @@ object MatrixFactorizationModel extends Loader[MatrixFactorizationModel] {\n   }\n \n   /**\n-   * Makes recommendations for all users (or products).\n-   * @param rank rank\n-   * @param srcFeatures src features to receive recommendations\n-   * @param dstFeatures dst features used to make recommendations\n-   * @param num number of recommendations for each record\n-   * @return an RDD of (srcId: Int, recommendations), where recommendations are stored as an array\n-   *         of (dstId, rating) pairs.\n+   * Makes recommendations for all users (or items).\n+   *\n+   * @param rank rank the dimension of the factor vectors\n+   * @param srcFactors src factor to receive recommendations\n+   * @param dstFactors dst factor used to make recommendations\n+   * @param num number of recommendations for each user (or item)\n+   * @return an RDD of (srcId, recommendations) pairs, where recommendations are stored as an array\n+   *         of (dstId, score) pairs.\n    */\n-  private def recommendForAll(\n+  private[spark] def recommendForAll[T: ClassTag : Fractional](\n       rank: Int,\n-      srcFeatures: RDD[(Int, Array[Double])],\n-      dstFeatures: RDD[(Int, Array[Double])],\n-      num: Int): RDD[(Int, Array[(Int, Double)])] = {\n-    val srcBlocks = blockify(rank, srcFeatures)\n-    val dstBlocks = blockify(rank, dstFeatures)\n+      srcFactors: RDD[(Int, Array[T])],\n+      dstFactors: RDD[(Int, Array[T])],\n+      num: Int): RDD[(Int, Array[(Int, T)])] = {\n+    val srcBlocks = blockify(rank, srcFactors)\n+    val dstBlocks = blockify(rank, dstFactors)\n+    val tag = implicitly[ClassTag[T]].runtimeClass\n     val ratings = srcBlocks.cartesian(dstBlocks).flatMap {\n       case ((srcIds, srcFactors), (dstIds, dstFactors)) =>","path":"mllib/src/main/scala/org/apache/spark/mllib/recommendation/MatrixFactorizationModel.scala","position":60,"original_position":60,"commit_id":"f8cf8b4b73fd2bce64239f5d9617024285c13e90","original_commit_id":"f8cf8b4b73fd2bce64239f5d9617024285c13e90","user":{"login":"frreiss","id":12436991,"avatar_url":"https://avatars.githubusercontent.com/u/12436991?v=3","gravatar_id":"","url":"https://api.github.com/users/frreiss","html_url":"https://github.com/frreiss","followers_url":"https://api.github.com/users/frreiss/followers","following_url":"https://api.github.com/users/frreiss/following{/other_user}","gists_url":"https://api.github.com/users/frreiss/gists{/gist_id}","starred_url":"https://api.github.com/users/frreiss/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/frreiss/subscriptions","organizations_url":"https://api.github.com/users/frreiss/orgs","repos_url":"https://api.github.com/users/frreiss/repos","events_url":"https://api.github.com/users/frreiss/events{/privacy}","received_events_url":"https://api.github.com/users/frreiss/received_events","type":"User","site_admin":false},"body":"For large inputs it's probably going to be more efficient to use `mllib.linalg.distributed.BlockMatrix`, which uses a custom partitioner. If BlockMatrix is *not* more efficient here, then BlockMatrix ought to have an alternate implementation of multiply for skinny matrices IMO.","created_at":"2016-04-22T18:08:08Z","updated_at":"2016-04-22T18:08:08Z","html_url":"https://github.com/apache/spark/pull/12574#discussion_r60779700","pull_request_url":"https://api.github.com/repos/apache/spark/pulls/12574","_links":{"self":{"href":"https://api.github.com/repos/apache/spark/pulls/comments/60779700"},"html":{"href":"https://github.com/apache/spark/pull/12574#discussion_r60779700"},"pull_request":{"href":"https://api.github.com/repos/apache/spark/pulls/12574"}}},"pull_request":{"url":"https://api.github.com/repos/apache/spark/pulls/12574","id":67342367,"html_url":"https://github.com/apache/spark/pull/12574","diff_url":"https://github.com/apache/spark/pull/12574.diff","patch_url":"https://github.com/apache/spark/pull/12574.patch","issue_url":"https://api.github.com/repos/apache/spark/issues/12574","number":12574,"state":"open","locked":false,"title":"[SPARK-13857][ML][WIP] Add \"recommend all\" functionality in ALS","user":{"login":"MLnick","id":1036807,"avatar_url":"https://avatars.githubusercontent.com/u/1036807?v=3","gravatar_id":"","url":"https://api.github.com/users/MLnick","html_url":"https://github.com/MLnick","followers_url":"https://api.github.com/users/MLnick/followers","following_url":"https://api.github.com/users/MLnick/following{/other_user}","gists_url":"https://api.github.com/users/MLnick/gists{/gist_id}","starred_url":"https://api.github.com/users/MLnick/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/MLnick/subscriptions","organizations_url":"https://api.github.com/users/MLnick/orgs","repos_url":"https://api.github.com/users/MLnick/repos","events_url":"https://api.github.com/users/MLnick/events{/privacy}","received_events_url":"https://api.github.com/users/MLnick/received_events","type":"User","site_admin":false},"body":"This PR adds \"recommend all\" functionality to ML's `ALSModel`, similar to what exists in the `recommendProductsForUsers/recommendUsersForProducts` methods in MLlib's `MatrixFactorizationModel`.\r\n\r\nThis is a WIP to get some feedback around:\r\n1. my approach to generic `blockify` and `recommendAll` methods in`MatrixFactorizationModel`, to handle `Double` and `Float` types (since `ml` uses `Float` for ratings and factors while `mllib` uses `Double`)\r\n2. the approach to the new params related to recommending top-k in `ALSModel`\r\n3. semantics of `ALSModel.transform` and how it relates to pipelines, cross-validation & evaluation (see this JIRA as well as [SPARK-14409](http://issues.apache.org/jira/browse/SPARK-14409) and the linked [design doc](\r\nhttps://docs.google.com/document/d/1YEvf5eEm2vRcALJs39yICWmUx6xFW5j8DvXFWbRbStE/edit#heading=h.a06u73tsuqc5) and #12461).\r\n\r\ncc @mengxr @jkbradley @srowen @debasish83 @yongtang \r\n\r\n### TODO\r\n- [ ] Decide on `transform` semantics and how this fits in with cross-validation and evaluation.\r\n- [ ] Performance testing vs `MatrixFactorizationModel` and vs the alternative `transform` semantics.\r\n- [ ] Clean up schema validation a bit and add related tests.\r\n\r\n## How was this patch tested?\r\n\r\nNew unit tests in `ml.recommendation.ALSSuite`","created_at":"2016-04-21T12:03:59Z","updated_at":"2016-04-22T18:08:08Z","closed_at":null,"merged_at":null,"merge_commit_sha":"995c9dd08a038e1a23650c596fd4a5eb5697fda4","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/apache/spark/pulls/12574/commits","review_comments_url":"https://api.github.com/repos/apache/spark/pulls/12574/comments","review_comment_url":"https://api.github.com/repos/apache/spark/pulls/comments{/number}","comments_url":"https://api.github.com/repos/apache/spark/issues/12574/comments","statuses_url":"https://api.github.com/repos/apache/spark/statuses/f8cf8b4b73fd2bce64239f5d9617024285c13e90","head":{"label":"MLnick:SPARK-13857-als-parity","ref":"SPARK-13857-als-parity","sha":"f8cf8b4b73fd2bce64239f5d9617024285c13e90","user":{"login":"MLnick","id":1036807,"avatar_url":"https://avatars.githubusercontent.com/u/1036807?v=3","gravatar_id":"","url":"https://api.github.com/users/MLnick","html_url":"https://github.com/MLnick","followers_url":"https://api.github.com/users/MLnick/followers","following_url":"https://api.github.com/users/MLnick/following{/other_user}","gists_url":"https://api.github.com/users/MLnick/gists{/gist_id}","starred_url":"https://api.github.com/users/MLnick/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/MLnick/subscriptions","organizations_url":"https://api.github.com/users/MLnick/orgs","repos_url":"https://api.github.com/users/MLnick/repos","events_url":"https://api.github.com/users/MLnick/events{/privacy}","received_events_url":"https://api.github.com/users/MLnick/received_events","type":"User","site_admin":false},"repo":{"id":56315295,"name":"spark","full_name":"MLnick/spark","owner":{"login":"MLnick","id":1036807,"avatar_url":"https://avatars.githubusercontent.com/u/1036807?v=3","gravatar_id":"","url":"https://api.github.com/users/MLnick","html_url":"https://github.com/MLnick","followers_url":"https://api.github.com/users/MLnick/followers","following_url":"https://api.github.com/users/MLnick/following{/other_user}","gists_url":"https://api.github.com/users/MLnick/gists{/gist_id}","starred_url":"https://api.github.com/users/MLnick/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/MLnick/subscriptions","organizations_url":"https://api.github.com/users/MLnick/orgs","repos_url":"https://api.github.com/users/MLnick/repos","events_url":"https://api.github.com/users/MLnick/events{/privacy}","received_events_url":"https://api.github.com/users/MLnick/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/MLnick/spark","description":"Mirror of Apache Spark","fork":true,"url":"https://api.github.com/repos/MLnick/spark","forks_url":"https://api.github.com/repos/MLnick/spark/forks","keys_url":"https://api.github.com/repos/MLnick/spark/keys{/key_id}","collaborators_url":"https://api.github.com/repos/MLnick/spark/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/MLnick/spark/teams","hooks_url":"https://api.github.com/repos/MLnick/spark/hooks","issue_events_url":"https://api.github.com/repos/MLnick/spark/issues/events{/number}","events_url":"https://api.github.com/repos/MLnick/spark/events","assignees_url":"https://api.github.com/repos/MLnick/spark/assignees{/user}","branches_url":"https://api.github.com/repos/MLnick/spark/branches{/branch}","tags_url":"https://api.github.com/repos/MLnick/spark/tags","blobs_url":"https://api.github.com/repos/MLnick/spark/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/MLnick/spark/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/MLnick/spark/git/refs{/sha}","trees_url":"https://api.github.com/repos/MLnick/spark/git/trees{/sha}","statuses_url":"https://api.github.com/repos/MLnick/spark/statuses/{sha}","languages_url":"https://api.github.com/repos/MLnick/spark/languages","stargazers_url":"https://api.github.com/repos/MLnick/spark/stargazers","contributors_url":"https://api.github.com/repos/MLnick/spark/contributors","subscribers_url":"https://api.github.com/repos/MLnick/spark/subscribers","subscription_url":"https://api.github.com/repos/MLnick/spark/subscription","commits_url":"https://api.github.com/repos/MLnick/spark/commits{/sha}","git_commits_url":"https://api.github.com/repos/MLnick/spark/git/commits{/sha}","comments_url":"https://api.github.com/repos/MLnick/spark/comments{/number}","issue_comment_url":"https://api.github.com/repos/MLnick/spark/issues/comments{/number}","contents_url":"https://api.github.com/repos/MLnick/spark/contents/{+path}","compare_url":"https://api.github.com/repos/MLnick/spark/compare/{base}...{head}","merges_url":"https://api.github.com/repos/MLnick/spark/merges","archive_url":"https://api.github.com/repos/MLnick/spark/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/MLnick/spark/downloads","issues_url":"https://api.github.com/repos/MLnick/spark/issues{/number}","pulls_url":"https://api.github.com/repos/MLnick/spark/pulls{/number}","milestones_url":"https://api.github.com/repos/MLnick/spark/milestones{/number}","notifications_url":"https://api.github.com/repos/MLnick/spark/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/MLnick/spark/labels{/name}","releases_url":"https://api.github.com/repos/MLnick/spark/releases{/id}","deployments_url":"https://api.github.com/repos/MLnick/spark/deployments","created_at":"2016-04-15T11:28:56Z","updated_at":"2016-04-15T11:29:18Z","pushed_at":"2016-04-21T14:34:50Z","git_url":"git://github.com/MLnick/spark.git","ssh_url":"git@github.com:MLnick/spark.git","clone_url":"https://github.com/MLnick/spark.git","svn_url":"https://github.com/MLnick/spark","homepage":null,"size":160402,"stargazers_count":0,"watchers_count":0,"language":"Scala","has_issues":false,"has_downloads":true,"has_wiki":false,"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":"apache:master","ref":"master","sha":"6fdd0e32a6c3fdce1f3f7e1f8d252af05c419f7b","user":{"login":"apache","id":47359,"avatar_url":"https://avatars.githubusercontent.com/u/47359?v=3","gravatar_id":"","url":"https://api.github.com/users/apache","html_url":"https://github.com/apache","followers_url":"https://api.github.com/users/apache/followers","following_url":"https://api.github.com/users/apache/following{/other_user}","gists_url":"https://api.github.com/users/apache/gists{/gist_id}","starred_url":"https://api.github.com/users/apache/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/apache/subscriptions","organizations_url":"https://api.github.com/users/apache/orgs","repos_url":"https://api.github.com/users/apache/repos","events_url":"https://api.github.com/users/apache/events{/privacy}","received_events_url":"https://api.github.com/users/apache/received_events","type":"Organization","site_admin":false},"repo":{"id":17165658,"name":"spark","full_name":"apache/spark","owner":{"login":"apache","id":47359,"avatar_url":"https://avatars.githubusercontent.com/u/47359?v=3","gravatar_id":"","url":"https://api.github.com/users/apache","html_url":"https://github.com/apache","followers_url":"https://api.github.com/users/apache/followers","following_url":"https://api.github.com/users/apache/following{/other_user}","gists_url":"https://api.github.com/users/apache/gists{/gist_id}","starred_url":"https://api.github.com/users/apache/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/apache/subscriptions","organizations_url":"https://api.github.com/users/apache/orgs","repos_url":"https://api.github.com/users/apache/repos","events_url":"https://api.github.com/users/apache/events{/privacy}","received_events_url":"https://api.github.com/users/apache/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/apache/spark","description":"Mirror of Apache Spark","fork":false,"url":"https://api.github.com/repos/apache/spark","forks_url":"https://api.github.com/repos/apache/spark/forks","keys_url":"https://api.github.com/repos/apache/spark/keys{/key_id}","collaborators_url":"https://api.github.com/repos/apache/spark/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/apache/spark/teams","hooks_url":"https://api.github.com/repos/apache/spark/hooks","issue_events_url":"https://api.github.com/repos/apache/spark/issues/events{/number}","events_url":"https://api.github.com/repos/apache/spark/events","assignees_url":"https://api.github.com/repos/apache/spark/assignees{/user}","branches_url":"https://api.github.com/repos/apache/spark/branches{/branch}","tags_url":"https://api.github.com/repos/apache/spark/tags","blobs_url":"https://api.github.com/repos/apache/spark/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/apache/spark/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/apache/spark/git/refs{/sha}","trees_url":"https://api.github.com/repos/apache/spark/git/trees{/sha}","statuses_url":"https://api.github.com/repos/apache/spark/statuses/{sha}","languages_url":"https://api.github.com/repos/apache/spark/languages","stargazers_url":"https://api.github.com/repos/apache/spark/stargazers","contributors_url":"https://api.github.com/repos/apache/spark/contributors","subscribers_url":"https://api.github.com/repos/apache/spark/subscribers","subscription_url":"https://api.github.com/repos/apache/spark/subscription","commits_url":"https://api.github.com/repos/apache/spark/commits{/sha}","git_commits_url":"https://api.github.com/repos/apache/spark/git/commits{/sha}","comments_url":"https://api.github.com/repos/apache/spark/comments{/number}","issue_comment_url":"https://api.github.com/repos/apache/spark/issues/comments{/number}","contents_url":"https://api.github.com/repos/apache/spark/contents/{+path}","compare_url":"https://api.github.com/repos/apache/spark/compare/{base}...{head}","merges_url":"https://api.github.com/repos/apache/spark/merges","archive_url":"https://api.github.com/repos/apache/spark/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/apache/spark/downloads","issues_url":"https://api.github.com/repos/apache/spark/issues{/number}","pulls_url":"https://api.github.com/repos/apache/spark/pulls{/number}","milestones_url":"https://api.github.com/repos/apache/spark/milestones{/number}","notifications_url":"https://api.github.com/repos/apache/spark/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/apache/spark/labels{/name}","releases_url":"https://api.github.com/repos/apache/spark/releases{/id}","deployments_url":"https://api.github.com/repos/apache/spark/deployments","created_at":"2014-02-25T08:00:08Z","updated_at":"2016-04-22T16:18:27Z","pushed_at":"2016-04-22T18:01:43Z","git_url":"git://github.com/apache/spark.git","ssh_url":"git@github.com:apache/spark.git","clone_url":"https://github.com/apache/spark.git","svn_url":"https://github.com/apache/spark","homepage":null,"size":467818,"stargazers_count":8250,"watchers_count":8250,"language":"Scala","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":7628,"mirror_url":"git://git.apache.org/spark.git","open_issues_count":454,"forks":7628,"open_issues":454,"watchers":8250,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/apache/spark/pulls/12574"},"html":{"href":"https://github.com/apache/spark/pull/12574"},"issue":{"href":"https://api.github.com/repos/apache/spark/issues/12574"},"comments":{"href":"https://api.github.com/repos/apache/spark/issues/12574/comments"},"review_comments":{"href":"https://api.github.com/repos/apache/spark/pulls/12574/comments"},"review_comment":{"href":"https://api.github.com/repos/apache/spark/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/apache/spark/pulls/12574/commits"},"statuses":{"href":"https://api.github.com/repos/apache/spark/statuses/f8cf8b4b73fd2bce64239f5d9617024285c13e90"}}}}