{"action":"created","comment":{"url":"https://api.github.com/repos/apache/spark/pulls/comments/84988658","pull_request_review_id":5731822,"id":84988658,"diff_hunk":"@@ -647,6 +654,173 @@ setMethod(\"predict\", signature(object = \"KMeansModel\"),\n             predict_internal(object, newData)\n           })\n \n+#' Logistic Regression Model\n+#'\n+#' Fits an logistic regression model against a Spark DataFrame. It supports \"binomial\": Binary logistic regression\n+#' with pivoting; \"multinomial\": Multinomial logistic (softmax) regression without pivoting, similar to glmnet.\n+#' Users can print, make predictions on the produced model and save the model to the input path.\n+#'\n+#' @param data SparkDataFrame for training\n+#' @param formula A symbolic description of the model to be fitted. Currently only a few formula\n+#'                operators are supported, including '~', '.', ':', '+', and '-'.\n+#' @param regParam the regularization parameter. Default is 0.0.\n+#' @param elasticNetParam the ElasticNet mixing parameter. For alpha = 0, the penalty is an L2 penalty.\n+#'                        For alpha = 1, it is an L1 penalty. For 0 < alpha < 1, the penalty is a combination\n+#'                        of L1 and L2. Default is 0.0 which is an L2 penalty.\n+#' @param maxIter maximum iteration number.\n+#' @param tol convergence tolerance of iterations.\n+#' @param fitIntercept whether to fit an intercept term. Default is TRUE.\n+#' @param family the name of family which is a description of the label distribution to be used in the model.\n+#'               Supported options:\n+#'                 \\itemize{\n+#'                   \\item{\"auto\": Automatically select the family based on the number of classes:\n+#'                           If numClasses == 1 || numClasses == 2, set to \"binomial\".\n+#'                           Else, set to \"multinomial\".}\n+#'                   \\item{\"binomial\": Binary logistic regression with pivoting.}\n+#'                   \\item{\"multinomial\": Multinomial logistic (softmax) regression without pivoting.\n+#'                           Default is \"auto\".}\n+#'                 }\n+#' @param standardization whether to standardize the training features before fitting the model. The coefficients\n+#'                        of models will be always returned on the original scale, so it will be transparent for\n+#'                        users. Note that with/without standardization, the models should be always converged\n+#'                        to the same solution when no regularization is applied. Default is TRUE, same as glmnet.\n+#' @param thresholds in binary classification, in range [0, 1]. If the estimated probability of class label 1\n+#'                  is > threshold, then predict 1, else 0. A high threshold encourages the model to predict 0\n+#'                  more often; a low threshold encourages the model to predict 1 more often. Note: Setting this with\n+#'                  threshold p is equivalent to setting thresholds c(1-p, p). When threshold is set, any user-set\n+#'                  value for thresholds will be cleared. If both threshold and thresholds are set, then they must be\n+#'                  equivalent. In multiclass (or binary) classification to adjust the probability of\n+#'                  predicting each class. Array must have length equal to the number of classes, with values > 0,\n+#'                  excepting that at most one value may be 0. The class with largest value p/t is predicted, where p\n+#'                  is the original probability of that class and t is the class's threshold. Note: When thresholds\n+#'                  is set, any user-set value for threshold will be cleared. If both threshold and thresholds are\n+#'                  set, then they must be equivalent. Default is 0.5.\n+#' @param weightCol The weight column name.\n+#' @param aggregationDepth depth for treeAggregate (>= 2). If the dimensions of features or the number of partitions\n+#'                         are large, this param could be adjusted to a larger size. Default is 2.\n+#' @param probabilityCol column name for predicted class conditional probabilities. Default is \"probability\".\n+#' @param ... additional arguments passed to the method.\n+#' @return \\code{spark.logit} returns a fitted logistic regression model\n+#' @rdname spark.logit\n+#' @aliases spark.logit,SparkDataFrame,formula-method\n+#' @name spark.logit\n+#' @export\n+#' @examples\n+#' \\dontrun{\n+#' sparkR.session()\n+#' # binary logistic regression\n+#' label <- c(1.0, 1.0, 1.0, 0.0, 0.0)\n+#' feature <- c(1.1419053, 0.9194079, -0.9498666, -1.1069903, 0.2809776)\n+#' binary_data <- as.data.frame(cbind(label, feature))\n+#' binary_df <- suppressWarnings(createDataFrame(binary_data))\n+#' blr_model <- spark.logit(binary_df, label ~ feature, threshold = 1.0)\n+#' blr_predict <- collect(select(predict(blr_model, binary_df), \"prediction\"))\n+#'\n+#' # summary of binary logistic regression\n+#' blr_summary <- summary(blr_model)\n+#' blr_fmeasure <- collect(select(blr_summary$fMeasureByThreshold, \"threshold\", \"F-Measure\"))\n+#' # save fitted model to input path\n+#' path <- \"path/to/model\"\n+#' write.ml(blr_model, path)\n+#'\n+#' # can also read back the saved model and print\n+#' savedModel <- read.ml(path)\n+#' summary(savedModel)\n+#'\n+#' # multinomial logistic regression\n+#'\n+#' label <- c(0.0, 1.0, 2.0, 0.0, 0.0)\n+#' feature1 <- c(4.845940, 5.64480, 7.430381, 6.464263, 5.555667)\n+#' feature2 <- c(2.941319, 2.614812, 2.162451, 3.339474, 2.970987)\n+#' feature3 <- c(1.322733, 1.348044, 3.861237, 9.686976, 3.447130)\n+#' feature4 <- c(1.3246388, 0.5510444, 0.9225810, 1.2147881, 1.6020842)\n+#' data <- as.data.frame(cbind(label, feature1, feature2, feature3, feature4))\n+#' df <- createDataFrame(data)\n+#'\n+#' model <- spark.logit(df, label ~ ., family = \"multinomial\", thresholds=c(0, 1, 1))\n+#' predict1 <- collect(select(predict(model, df), \"prediction\"))\n+#' }\n+#' @note spark.logit since 2.1.0\n+setMethod(\"spark.logit\", signature(data = \"SparkDataFrame\", formula = \"formula\"),\n+          function(data, formula, regParam = 0.0, elasticNetParam = 0.0, maxIter = 100,\n+                   tol = 1E-6, fitIntercept = TRUE, family = \"auto\", standardization = TRUE,\n+                   thresholds = 0.5, weightCol = NULL, aggregationDepth = 2,\n+                   probabilityCol = \"probability\") {\n+            formula <- paste0(deparse(formula), collapse = \"\")\n+\n+            if (is.null(weightCol)) {\n+              weightCol <- \"\"\n+            }\n+\n+            jobj <- callJStatic(\"org.apache.spark.ml.r.LogisticRegressionWrapper\", \"fit\",\n+                                data@sdf, formula, as.numeric(regParam),\n+                                as.numeric(elasticNetParam), as.integer(maxIter),\n+                                as.numeric(tol), as.logical(fitIntercept),\n+                                as.character(family), as.logical(standardization),\n+                                as.array(thresholds), as.character(weightCol),\n+                                as.integer(aggregationDepth), as.character(probabilityCol))\n+            new(\"LogisticRegressionModel\", jobj = jobj)\n+          })\n+\n+#  Predicted values based on an LogisticRegressionModel model\n+\n+#' @param newData a SparkDataFrame for testing.\n+#' @return \\code{predict} returns the predicted values based on an LogisticRegressionModel.\n+#' @rdname spark.logit\n+#' @aliases predict,LogisticRegressionModel,SparkDataFrame-method\n+#' @export\n+#' @note predict(LogisticRegressionModel) since 2.1.0\n+setMethod(\"predict\", signature(object = \"LogisticRegressionModel\"),\n+          function(object, newData) {\n+            predict_internal(object, newData)\n+          })\n+\n+#  Get the summary of an LogisticRegressionModel\n+\n+#' @param object an LogisticRegressionModel fitted by \\code{spark.logit}\n+#' @return \\code{summary} returns the Binary Logistic regression results of a given model as lists. Note that\n+#'                        Multinomial logistic regression summary is not available now.\n+#' @rdname spark.logit\n+#' @aliases spark.logit,SparkDataFrame,formula-method","path":"R/pkg/R/mllib.R","position":163,"original_position":163,"commit_id":"a222de7efe93aea51f9de755f4fd29eb4ff8554a","original_commit_id":"a222de7efe93aea51f9de755f4fd29eb4ff8554a","user":{"login":"wangmiao1981","id":5033592,"avatar_url":"https://avatars.githubusercontent.com/u/5033592?v=3","gravatar_id":"","url":"https://api.github.com/users/wangmiao1981","html_url":"https://github.com/wangmiao1981","followers_url":"https://api.github.com/users/wangmiao1981/followers","following_url":"https://api.github.com/users/wangmiao1981/following{/other_user}","gists_url":"https://api.github.com/users/wangmiao1981/gists{/gist_id}","starred_url":"https://api.github.com/users/wangmiao1981/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wangmiao1981/subscriptions","organizations_url":"https://api.github.com/users/wangmiao1981/orgs","repos_url":"https://api.github.com/users/wangmiao1981/repos","events_url":"https://api.github.com/users/wangmiao1981/events{/privacy}","received_events_url":"https://api.github.com/users/wangmiao1981/received_events","type":"User","site_admin":false},"body":"`suppressWarnings` is removed. For the aliases, I followed `spark.kmeans`. Are there any specific rules? ","created_at":"2016-10-25T20:05:36Z","updated_at":"2016-10-25T20:05:36Z","html_url":"https://github.com/apache/spark/pull/15365#discussion_r84988658","pull_request_url":"https://api.github.com/repos/apache/spark/pulls/15365","_links":{"self":{"href":"https://api.github.com/repos/apache/spark/pulls/comments/84988658"},"html":{"href":"https://github.com/apache/spark/pull/15365#discussion_r84988658"},"pull_request":{"href":"https://api.github.com/repos/apache/spark/pulls/15365"}}},"pull_request":{"url":"https://api.github.com/repos/apache/spark/pulls/15365","id":88176977,"html_url":"https://github.com/apache/spark/pull/15365","diff_url":"https://github.com/apache/spark/pull/15365.diff","patch_url":"https://github.com/apache/spark/pull/15365.patch","issue_url":"https://api.github.com/repos/apache/spark/issues/15365","number":15365,"state":"open","locked":false,"title":"[SPARK-17157][SPARKR]: Add multiclass logistic regression SparkR Wrapper","user":{"login":"wangmiao1981","id":5033592,"avatar_url":"https://avatars.githubusercontent.com/u/5033592?v=3","gravatar_id":"","url":"https://api.github.com/users/wangmiao1981","html_url":"https://github.com/wangmiao1981","followers_url":"https://api.github.com/users/wangmiao1981/followers","following_url":"https://api.github.com/users/wangmiao1981/following{/other_user}","gists_url":"https://api.github.com/users/wangmiao1981/gists{/gist_id}","starred_url":"https://api.github.com/users/wangmiao1981/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wangmiao1981/subscriptions","organizations_url":"https://api.github.com/users/wangmiao1981/orgs","repos_url":"https://api.github.com/users/wangmiao1981/repos","events_url":"https://api.github.com/users/wangmiao1981/events{/privacy}","received_events_url":"https://api.github.com/users/wangmiao1981/received_events","type":"User","site_admin":false},"body":"## What changes were proposed in this pull request?\r\n\r\nAs we discussed in #14818, I added a separate R wrapper spark.logit for logistic regression. \r\n\r\nThis single interface supports both binary and multinomial logistic regression. It also has \"predict\" and \"summary\" for binary logistic regression. \r\n\r\n## How was this patch tested?\r\n\r\nNew unit tests are added.","created_at":"2016-10-05T23:41:41Z","updated_at":"2016-10-25T20:05:36Z","closed_at":null,"merged_at":null,"merge_commit_sha":"7acad03b4c8caffcfb9206fd461fb3062be8d878","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/apache/spark/pulls/15365/commits","review_comments_url":"https://api.github.com/repos/apache/spark/pulls/15365/comments","review_comment_url":"https://api.github.com/repos/apache/spark/pulls/comments{/number}","comments_url":"https://api.github.com/repos/apache/spark/issues/15365/comments","statuses_url":"https://api.github.com/repos/apache/spark/statuses/a222de7efe93aea51f9de755f4fd29eb4ff8554a","head":{"label":"wangmiao1981:glm","ref":"glm","sha":"a222de7efe93aea51f9de755f4fd29eb4ff8554a","user":{"login":"wangmiao1981","id":5033592,"avatar_url":"https://avatars.githubusercontent.com/u/5033592?v=3","gravatar_id":"","url":"https://api.github.com/users/wangmiao1981","html_url":"https://github.com/wangmiao1981","followers_url":"https://api.github.com/users/wangmiao1981/followers","following_url":"https://api.github.com/users/wangmiao1981/following{/other_user}","gists_url":"https://api.github.com/users/wangmiao1981/gists{/gist_id}","starred_url":"https://api.github.com/users/wangmiao1981/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wangmiao1981/subscriptions","organizations_url":"https://api.github.com/users/wangmiao1981/orgs","repos_url":"https://api.github.com/users/wangmiao1981/repos","events_url":"https://api.github.com/users/wangmiao1981/events{/privacy}","received_events_url":"https://api.github.com/users/wangmiao1981/received_events","type":"User","site_admin":false},"repo":{"id":41932153,"name":"spark","full_name":"wangmiao1981/spark","owner":{"login":"wangmiao1981","id":5033592,"avatar_url":"https://avatars.githubusercontent.com/u/5033592?v=3","gravatar_id":"","url":"https://api.github.com/users/wangmiao1981","html_url":"https://github.com/wangmiao1981","followers_url":"https://api.github.com/users/wangmiao1981/followers","following_url":"https://api.github.com/users/wangmiao1981/following{/other_user}","gists_url":"https://api.github.com/users/wangmiao1981/gists{/gist_id}","starred_url":"https://api.github.com/users/wangmiao1981/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wangmiao1981/subscriptions","organizations_url":"https://api.github.com/users/wangmiao1981/orgs","repos_url":"https://api.github.com/users/wangmiao1981/repos","events_url":"https://api.github.com/users/wangmiao1981/events{/privacy}","received_events_url":"https://api.github.com/users/wangmiao1981/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/wangmiao1981/spark","description":"Mirror of Apache Spark","fork":true,"url":"https://api.github.com/repos/wangmiao1981/spark","forks_url":"https://api.github.com/repos/wangmiao1981/spark/forks","keys_url":"https://api.github.com/repos/wangmiao1981/spark/keys{/key_id}","collaborators_url":"https://api.github.com/repos/wangmiao1981/spark/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/wangmiao1981/spark/teams","hooks_url":"https://api.github.com/repos/wangmiao1981/spark/hooks","issue_events_url":"https://api.github.com/repos/wangmiao1981/spark/issues/events{/number}","events_url":"https://api.github.com/repos/wangmiao1981/spark/events","assignees_url":"https://api.github.com/repos/wangmiao1981/spark/assignees{/user}","branches_url":"https://api.github.com/repos/wangmiao1981/spark/branches{/branch}","tags_url":"https://api.github.com/repos/wangmiao1981/spark/tags","blobs_url":"https://api.github.com/repos/wangmiao1981/spark/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/wangmiao1981/spark/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/wangmiao1981/spark/git/refs{/sha}","trees_url":"https://api.github.com/repos/wangmiao1981/spark/git/trees{/sha}","statuses_url":"https://api.github.com/repos/wangmiao1981/spark/statuses/{sha}","languages_url":"https://api.github.com/repos/wangmiao1981/spark/languages","stargazers_url":"https://api.github.com/repos/wangmiao1981/spark/stargazers","contributors_url":"https://api.github.com/repos/wangmiao1981/spark/contributors","subscribers_url":"https://api.github.com/repos/wangmiao1981/spark/subscribers","subscription_url":"https://api.github.com/repos/wangmiao1981/spark/subscription","commits_url":"https://api.github.com/repos/wangmiao1981/spark/commits{/sha}","git_commits_url":"https://api.github.com/repos/wangmiao1981/spark/git/commits{/sha}","comments_url":"https://api.github.com/repos/wangmiao1981/spark/comments{/number}","issue_comment_url":"https://api.github.com/repos/wangmiao1981/spark/issues/comments{/number}","contents_url":"https://api.github.com/repos/wangmiao1981/spark/contents/{+path}","compare_url":"https://api.github.com/repos/wangmiao1981/spark/compare/{base}...{head}","merges_url":"https://api.github.com/repos/wangmiao1981/spark/merges","archive_url":"https://api.github.com/repos/wangmiao1981/spark/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/wangmiao1981/spark/downloads","issues_url":"https://api.github.com/repos/wangmiao1981/spark/issues{/number}","pulls_url":"https://api.github.com/repos/wangmiao1981/spark/pulls{/number}","milestones_url":"https://api.github.com/repos/wangmiao1981/spark/milestones{/number}","notifications_url":"https://api.github.com/repos/wangmiao1981/spark/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/wangmiao1981/spark/labels{/name}","releases_url":"https://api.github.com/repos/wangmiao1981/spark/releases{/id}","deployments_url":"https://api.github.com/repos/wangmiao1981/spark/deployments","created_at":"2015-09-04T18:38:32Z","updated_at":"2016-01-19T18:24:03Z","pushed_at":"2016-10-20T21:38:20Z","git_url":"git://github.com/wangmiao1981/spark.git","ssh_url":"git@github.com:wangmiao1981/spark.git","clone_url":"https://github.com/wangmiao1981/spark.git","svn_url":"https://github.com/wangmiao1981/spark","homepage":null,"size":235832,"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":"f9a56a153e0579283160519065c7f3620d12da3e","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-10-25T19:40:41Z","pushed_at":"2016-10-25T19:08:50Z","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":602903,"stargazers_count":10497,"watchers_count":10497,"language":"Scala","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":9769,"mirror_url":"git://git.apache.org/spark.git","open_issues_count":478,"forks":9769,"open_issues":478,"watchers":10497,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/apache/spark/pulls/15365"},"html":{"href":"https://github.com/apache/spark/pull/15365"},"issue":{"href":"https://api.github.com/repos/apache/spark/issues/15365"},"comments":{"href":"https://api.github.com/repos/apache/spark/issues/15365/comments"},"review_comments":{"href":"https://api.github.com/repos/apache/spark/pulls/15365/comments"},"review_comment":{"href":"https://api.github.com/repos/apache/spark/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/apache/spark/pulls/15365/commits"},"statuses":{"href":"https://api.github.com/repos/apache/spark/statuses/a222de7efe93aea51f9de755f4fd29eb4ff8554a"}}}}
{"actor":{"display_login":"wangmiao1981"}}