{"action":"created","issue":{"url":"https://api.github.com/repos/apache/spark/issues/14834","repository_url":"https://api.github.com/repos/apache/spark","labels_url":"https://api.github.com/repos/apache/spark/issues/14834/labels{/name}","comments_url":"https://api.github.com/repos/apache/spark/issues/14834/comments","events_url":"https://api.github.com/repos/apache/spark/issues/14834/events","html_url":"https://github.com/apache/spark/pull/14834","id":173509623,"number":14834,"title":"[SPARK-17163][ML] Unified LogisticRegression interface","user":{"login":"sethah","id":7275795,"avatar_url":"https://avatars.githubusercontent.com/u/7275795?v=3","gravatar_id":"","url":"https://api.github.com/users/sethah","html_url":"https://github.com/sethah","followers_url":"https://api.github.com/users/sethah/followers","following_url":"https://api.github.com/users/sethah/following{/other_user}","gists_url":"https://api.github.com/users/sethah/gists{/gist_id}","starred_url":"https://api.github.com/users/sethah/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sethah/subscriptions","organizations_url":"https://api.github.com/users/sethah/orgs","repos_url":"https://api.github.com/users/sethah/repos","events_url":"https://api.github.com/users/sethah/events{/privacy}","received_events_url":"https://api.github.com/users/sethah/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":24,"created_at":"2016-08-26T18:03:02Z","updated_at":"2016-09-09T22:13:10Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/apache/spark/pulls/14834","html_url":"https://github.com/apache/spark/pull/14834","diff_url":"https://github.com/apache/spark/pull/14834.diff","patch_url":"https://github.com/apache/spark/pull/14834.patch"},"body":"## What changes were proposed in this pull request?\r\n\r\nMerge `MultinomialLogisticRegression` into `LogisticRegression` and remove `MultinomialLogisticRegression`.\r\n\r\nMarked as WIP because we should discuss the coefficients API in the model. See discussion below.\r\n\r\nJIRA: [SPARK-17163](https://issues.apache.org/jira/browse/SPARK-17163)\r\n\r\n\r\n## How was this patch tested?\r\n\r\nMerged test suites and added some new unit tests.\r\n\r\n## Design\r\n\r\n### Switching between binomial and multinomial\r\n\r\nWe default to automatically detecting whether we should run binomial or multinomial lor. We expose a new parameter called `family` which defaults to auto. When \"auto\" is used, we run normal binomial lor with pivoting if there are 1 or 2 label classes. Otherwise, we run multinomial. If the user explicitly sets the family, then we abide by that setting. In the case where \"binomial\" is set but multiclass lor is detected, we throw an error.\r\n\r\n### coefficients/intercept model API (TODO)\r\n\r\nThis is the biggest design point remaining, IMO. We need to decide how to store the coefficients and intercepts in the model, and in turn how to expose them via the API. Two important points:\r\n\r\n* We must maintain compatibility with the old API, i.e. we must expose `def coefficients: Vector` and `def intercept: Double`\r\n* There are two separate cases: binomial lr where we have a single set of coefficients and a single intercept and multinomial lr where we have `numClasses` sets of coefficients and `numClasses` intercepts.\r\n\r\nSome options:\r\n\r\n1. **Store the binomial coefficients as a `2 x numFeatures` matrix.** This means that we would center the model coefficients before storing them in the model. The BLOR algorithm gives `1 * numFeatures` coefficients, but we would convert them to `2 x numFeatures` coefficients before storing them, effectively doubling the storage in the model. This has the advantage that we can make the code cleaner (i.e. less `if (isMultinomial) ... else ...`) and we don't have to reason about the different cases as much. It has the disadvantage that we double the storage space and we could see small regressions at prediction time since there are 2x the number of operations in the prediction algorithms. Additionally, we still have to produce the uncentered coefficients/intercept via the API, so we will have to either ALSO store the uncentered version, or compute it in `def coefficients: Vector` every time.\r\n\r\n2. **Store the binomial coefficients as a `1 x numFeatures` matrix.** We still store the coefficients as a matrix and the intercepts as a vector. When users call `coefficients` we return them a `Vector` that is backed by the same underlying array as the `coefficientMatrix`, so we don't duplicate any data. At prediction time, we use the old prediction methods that are specialized for binary LOR. The benefits here are that we don't store extra data, and we won't see any regressions in performance. The cost of this is that we have separate implementations for predict methods in the binary vs multiclass case. The duplicated code is really not very high, but it's still a bit messy. \r\n\r\nIf we do decide to store the 2x coefficients, we would likely want to see some performance tests to understand the potential regressions.\r\n\r\n### Threshold/thresholds (TODO)\r\n\r\nCurrently, when `threshold` is set we clear whatever value is in `thresholds` and when `thresholds` is set we clear whatever value is in `threshold`. [SPARK-11543](https://issues.apache.org/jira/browse/SPARK-11543) was created to prefer thresholds over threshold. We should decide if we should implement this behavior now or if we want to do it in a separate JIRA.\r\n\r\n## Follow up\r\n\r\n* Summary model for multiclass logistic regression [SPARK-17139](https://issues.apache.org/jira/browse/SPARK-17139)\r\n* Thresholds vs threshold [SPARK-11543](https://issues.apache.org/jira/browse/SPARK-11543)\r\n"},"comment":{"url":"https://api.github.com/repos/apache/spark/issues/comments/246055255","html_url":"https://github.com/apache/spark/pull/14834#issuecomment-246055255","issue_url":"https://api.github.com/repos/apache/spark/issues/14834","id":246055255,"user":{"login":"SparkQA","id":8108735,"avatar_url":"https://avatars.githubusercontent.com/u/8108735?v=3","gravatar_id":"","url":"https://api.github.com/users/SparkQA","html_url":"https://github.com/SparkQA","followers_url":"https://api.github.com/users/SparkQA/followers","following_url":"https://api.github.com/users/SparkQA/following{/other_user}","gists_url":"https://api.github.com/users/SparkQA/gists{/gist_id}","starred_url":"https://api.github.com/users/SparkQA/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/SparkQA/subscriptions","organizations_url":"https://api.github.com/users/SparkQA/orgs","repos_url":"https://api.github.com/users/SparkQA/repos","events_url":"https://api.github.com/users/SparkQA/events{/privacy}","received_events_url":"https://api.github.com/users/SparkQA/received_events","type":"User","site_admin":false},"created_at":"2016-09-09T22:13:10Z","updated_at":"2016-09-09T22:13:10Z","body":"**[Test build #65169 has finished](https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder/65169/consoleFull)** for PR 14834 at commit [`e600e0f`](https://github.com/apache/spark/commit/e600e0f34b0abbf6f3ab020281e75c1a69a84a4c).\n * This patch **fails Spark unit tests**.\n * This patch merges cleanly.\n * This patch adds no public classes."}}
{"actor":{"display_login":"SparkQA"}}