{"action":"created","comment":{"url":"https://api.github.com/repos/apache/flink/pulls/comments/40442397","id":40442397,"diff_hunk":"@@ -0,0 +1,900 @@\n+/*\n+ * Licensed to the Apache Software Foundation (ASF) under one\n+ * or more contributor license agreements.  See the NOTICE file\n+ * distributed with this work for additional information\n+ * regarding copyright ownership.  The ASF licenses this file\n+ * to you under the Apache License, Version 2.0 (the\n+ * \"License\"); you may not use this file except in compliance\n+ * with the License.  You may obtain a copy of the License at\n+ *\n+ *     http://www.apache.org/licenses/LICENSE-2.0\n+ *\n+ * Unless required by applicable law or agreed to in writing, software\n+ * distributed under the License is distributed on an \"AS IS\" BASIS,\n+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n+ * See the License for the specific language governing permissions and\n+ * limitations under the License.\n+ */\n+\n+package org.apache.flink.ml.classification\n+\n+import java.{lang, util}\n+\n+import org.apache.flink.api.common.functions._\n+import org.apache.flink.api.scala._\n+import org.apache.flink.configuration.Configuration\n+import org.apache.flink.core.fs.FileSystem.WriteMode\n+import org.apache.flink.ml.common.{ParameterMap, Parameter}\n+import org.apache.flink.ml.pipeline.{PredictDataSetOperation, FitOperation, Predictor}\n+import org.apache.flink.util.Collector\n+\n+import scala.collection.JavaConverters._\n+import scala.collection.mutable\n+import scala.collection.mutable.ListBuffer\n+import scala.collection.mutable.Map\n+\n+/**\n+ * While building the model different approaches need to be compared.\n+ * For that purpose the fitParameters are used. Every possibility that might enhance\n+ * the implementation can be chosen separately by using the following list of parameters:\n+ *\n+ * Possibility 1: way of calculating document count\n+ *  P1 = 0 -> use .count() to get count of all documents\n+ *  P1 = 1 -> use a reducer and a mapper to create a broadcast data set containing the count of\n+ *    all documents\n+ *\n+ * Possibility 2: all words in class (order of operators)\n+ *    If p2 = 1 improves the speed, many other calculations must switch their operators, too.\n+ *  P2 = 0 -> first the reducer, than the mapper\n+ *  P2 = 1 -> first the mapper, than the reducer\n+ *\n+ * Possibility 3: way of calculating pwc\n+ *  P2 = 0 -> join singleWordsInClass and allWordsInClass to wordsInClass data set\n+ *  P3 = 1 -> work on singleWordsInClass data set and broadcast allWordsInClass data set\n+ *\n+ * Schneider/Rennie 1: ignore/reduce word frequency information\n+ *  SR1 = 0 -> word frequency information is not ignored\n+ *  SR1 = 1 -> word frequency information is ignored (Schneiders approach)\n+ *  SR1 = 2 -> word frequency information is reduced (Rennies approach)\n+ *\n+ * Schneider1: ignore P(c_j) in cMAP formula\n+ *  S1 = 0 -> normal cMAP formula\n+ *  S2 = 1 -> cMAP without P(c_j)\n+ *\n+ * Rennie1: transform document frequency\n+ *  R1 = 0 -> normal formula\n+ *  R1 = 1 -> apply inverse document frequecy\n+ * Note: if R1 = 1 and SR1 = 2, both approaches get applied.\n+ *\n+ */\n+class MultinomialNaiveBayes extends Predictor[MultinomialNaiveBayes] {\n+\n+  import MultinomialNaiveBayes._\n+\n+  //The model, that stores all needed information that are related to one specific word\n+  var wordRelatedModelData: Option[DataSet[(String, String, Double)]] =\n+    None // (class name -> word -> log P(w|c))\n+\n+  //The model, that stores all needed information that are related to one specifc class+\n+  var classRelatedModelData: Option[DataSet[(String, Double, Double)]] =\n+    None // (class name -> p(c) -> log p(w|c) not in class)\n+\n+  //A data set that stores additional needed information for some of the improvements\n+  var improvementData: Option[DataSet[(String, Double)]] =\n+    None // (word -> log number of documents in all classes / word frequency in all classes\n+\n+  // ============================== Parameter configuration ========================================\n+\n+  def setP1(value: Int): MultinomialNaiveBayes = {\n+    parameters.add(P1, value)\n+    this\n+  }\n+\n+  def setP2(value: Int): MultinomialNaiveBayes = {\n+    parameters.add(P2, value)\n+    this\n+  }\n+\n+  def setP3(value: Int): MultinomialNaiveBayes = {\n+    parameters.add(P3, value)\n+    this\n+  }\n+\n+  def setSR1(value: Int): MultinomialNaiveBayes = {\n+    parameters.add(SR1, value)\n+    this\n+  }\n+\n+  def setS1(value: Int): MultinomialNaiveBayes = {\n+    parameters.add(S1, value)\n+    this\n+  }\n+\n+  def setR1(value: Int): MultinomialNaiveBayes = {\n+    parameters.add(R1, value)\n+    this\n+  }\n+\n+  // =============================================== Methods =======================================\n+\n+  /**\n+   * Save already existing model data created by the NaiveBayes algorithm. Requires the designated\n+   * locations. The saved data is a representation of the [[wordRelatedModelData]] and\n+   * [[classRelatedModelData]].\n+   * @param wordRelated, the save location for the wordRelated data\n+   * @param classRelated, the save location for the classRelated data\n+   */\n+  def saveModelDataSet(wordRelated: String, classRelated: String) : Unit = {\n+    wordRelatedModelData.get.writeAsCsv(wordRelated, \"\\n\", \"|\", WriteMode.OVERWRITE)\n+    classRelatedModelData.get.writeAsCsv(classRelated, \"\\n\", \"|\", WriteMode.OVERWRITE)\n+  }\n+\n+  /**\n+   * Save the improvment data set. Requires the designated save location. The saved data is a\n+   * representation of the [[improvementData]] data set.\n+   * @param path, the save location for the improvment data\n+   */\n+  def saveImprovementDataSet(path: String) : Unit = {\n+    improvementData.get.writeAsCsv(path, \"\\n\", \"|\", WriteMode.OVERWRITE)\n+  }\n+\n+  /**\n+   * Sets the [[wordRelatedModelData]] and the [[classRelatedModelData]] to the given data sets.\n+   * @param wordRelated, the data set representing the wordRelated model\n+   * @param classRelated, the data set representing the classRelated model\n+   */\n+  def setModelDataSet(wordRelated : DataSet[(String, String, Double)],\n+                      classRelated: DataSet[(String, Double, Double)]) : Unit = {\n+    this.wordRelatedModelData = Some(wordRelated)\n+    this.classRelatedModelData = Some(classRelated)\n+  }\n+\n+  def setImprovementDataSet(impSet : DataSet[(String, Double)]) : Unit = {\n+    this.improvementData = Some(impSet)\n+  }\n+\n+}\n+\n+object MultinomialNaiveBayes {\n+\n+  // ========================================== Parameters =========================================\n+  case object P1 extends Parameter[Int] {\n+    override val defaultValue: Option[Int] = Some(0)\n+  }\n+\n+  case object P2 extends Parameter[Int] {\n+    override val defaultValue: Option[Int] = Some(0)\n+  }\n+\n+  case object P3 extends Parameter[Int] {\n+    override val defaultValue: Option[Int] = Some(0)\n+  }\n+\n+  case object SR1 extends Parameter[Int] {\n+    override val defaultValue: Option[Int] = Some(0)\n+  }\n+\n+  case object S1 extends Parameter[Int] {\n+    override val defaultValue: Option[Int] = Some(0)\n+  }\n+\n+  case object R1 extends Parameter[Int] {\n+    override val defaultValue: Option[Int] = Some(0)\n+  }\n+\n+  // ======================================== Factory Methods ======================================\n+  def apply(): MultinomialNaiveBayes = {\n+    new MultinomialNaiveBayes()\n+  }\n+\n+  // ====================================== Operations =============================================\n+  /**\n+   * Trains the models to fit the training data. The resulting\n+   * [[MultinomialNaiveBayes.wordRelatedModelData]] and\n+   * [[MultinomialNaiveBayes.classRelatedModelData]] are stored in the [[MultinomialNaiveBayes]]\n+   * instance.\n+   */\n+\n+  implicit val fitNNB = new FitOperation[MultinomialNaiveBayes, (String, String)] {\n+    /**\n+     * The [[FitOperation]] used to create the model. Requires an instance of\n+     * [[MultinomialNaiveBayes]], a [[ParameterMap]] and the input data set. This data set\n+     * maps (string -> string) containing (label -> text, words separated by \",\")\n+     * @param instance of [[MultinomialNaiveBayes]]\n+     * @param fitParameters, additional parameters\n+     * @param input, the to processed data set\n+     */\n+    override def fit(instance: MultinomialNaiveBayes,\n+                     fitParameters: ParameterMap,\n+                     input: DataSet[(String, String)]): Unit = {\n+\n+      val resultingParameters = instance.parameters ++ fitParameters\n+\n+      //Count the amount of documents for each class.\n+      // 1. Map: replace the document text by a 1\n+      // 2. Group-Reduce: sum the 1s by class\n+      val documentsPerClass: DataSet[(String, Int)] = input.map { input => (input._1, 1)}\n+        .groupBy(0).sum(1) // (class name -> count of documents)\n+\n+      //Count the amount of occurrences of each word for each class.\n+      // 1. FlatMap: split the document into its words and add a 1 to each tuple\n+      // 2. Group-Reduce: sum the 1s by class, word\n+      var singleWordsInClass: DataSet[(String, String, Int)] = input\n+        .flatMap(new SingleWordSplitter())\n+        .groupBy(0, 1).sum(2) // (class name -> word -> count of that word)\n+\n+      //POSSIBILITY 2: all words in class (order of operators)\n+      //SCHNEIDER/RENNIE 1: ignore/reduce word frequency information\n+        //the allWordsInClass data set does only contain distinct\n+        //words for schneiders approach: ndw(cj), nothing changes for rennies approach\n+\n+      val p2 = resultingParameters(P2)\n+\n+      val sr1 = resultingParameters(SR1)\n+\n+      var allWordsInClass: DataSet[(String, Int)] =\n+        null // (class name -> count of all words in that class)\n+\n+      if (p2 == 0) {\n+        if (sr1 == 0 || sr1 == 2) {\n+          //Count all the words for each class.\n+          // 1. Reduce: add the count for each word in a class together\n+          // 2. Map: remove the field that contains the word\n+          allWordsInClass = singleWordsInClass.groupBy(0).reduce {\n+            (singleWords1, singleWords2) =>\n+              (singleWords1._1, singleWords1._2, singleWords1._3 + singleWords2._3)\n+          }.map(singleWords =>\n+            (singleWords._1, singleWords._3)) // (class name -> count of all words in that class)\n+        } else if (sr1 == 1) {\n+          //Count all distinct words for each class.\n+          // 1. Map: set the word count to 1\n+          // 2. Reduce: add the count for each word in a class together\n+          // 3. Map: remove the field that contains the word\n+          allWordsInClass = singleWordsInClass\n+            .map(singleWords => (singleWords._1, singleWords._2, 1))\n+            .groupBy(0).reduce {\n+            (singleWords1, singleWords2) =>\n+              (singleWords1._1, singleWords1._2, singleWords1._3 + singleWords2._3)\n+          }.map(singleWords =>\n+            (singleWords._1, singleWords._3))//(class name -> count of distinct words in that class)\n+        }\n+      } else if (p2 == 1) {\n+        if (sr1 == 0 || sr1 == 2) {\n+          //Count all the words for each class.\n+          // 1. Map: remove the field that contains the word\n+          // 2. Reduce: add the count for each word in a class together\n+          allWordsInClass = singleWordsInClass.map(singleWords => (singleWords._1, singleWords._3))\n+            .groupBy(0).reduce {\n+            (singleWords1, singleWords2) => (singleWords1._1, singleWords1._2 + singleWords2._2)\n+          } // (class name -> count of all words in that class)\n+        } else if (sr1 == 1) {\n+          //Count all distinct words for each class.\n+          // 1. Map: remove the field that contains the word, set the word count to 1\n+          // 2. Reduce: add the count for each word in a class together\n+          allWordsInClass = singleWordsInClass.map(singleWords => (singleWords._1, 1))\n+            .groupBy(0).reduce {\n+            (singleWords1, singleWords2) => (singleWords1._1, singleWords1._2 + singleWords2._2)\n+          } // (class name -> count of distinct words in that class)\n+        }\n+\n+      }\n+\n+      //END SCHNEIDER/RENNIE 1\n+      //END POSSIBILITY 2\n+\n+      //POSSIBILITY 1: way of calculating document count\n+      val p1 = resultingParameters(P1)\n+","path":"flink-staging/flink-ml/src/main/scala/org/apache/flink/ml/classification/MultinomialNaiveBayes.scala","position":287,"original_position":287,"commit_id":"fadd761e175f2d7308e77f3acab03ce461b0abd5","original_commit_id":"fadd761e175f2d7308e77f3acab03ce461b0abd5","user":{"login":"sachingoel0101","id":8874261,"avatar_url":"https://avatars.githubusercontent.com/u/8874261?v=3","gravatar_id":"","url":"https://api.github.com/users/sachingoel0101","html_url":"https://github.com/sachingoel0101","followers_url":"https://api.github.com/users/sachingoel0101/followers","following_url":"https://api.github.com/users/sachingoel0101/following{/other_user}","gists_url":"https://api.github.com/users/sachingoel0101/gists{/gist_id}","starred_url":"https://api.github.com/users/sachingoel0101/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sachingoel0101/subscriptions","organizations_url":"https://api.github.com/users/sachingoel0101/orgs","repos_url":"https://api.github.com/users/sachingoel0101/repos","events_url":"https://api.github.com/users/sachingoel0101/events{/privacy}","received_events_url":"https://api.github.com/users/sachingoel0101/received_events","type":"User","site_admin":false},"body":"line break","created_at":"2015-09-25T15:31:15Z","updated_at":"2015-09-25T15:31:15Z","html_url":"https://github.com/apache/flink/pull/1156#discussion_r40442397","pull_request_url":"https://api.github.com/repos/apache/flink/pulls/1156","_links":{"self":{"href":"https://api.github.com/repos/apache/flink/pulls/comments/40442397"},"html":{"href":"https://github.com/apache/flink/pull/1156#discussion_r40442397"},"pull_request":{"href":"https://api.github.com/repos/apache/flink/pulls/1156"}}},"pull_request":{"url":"https://api.github.com/repos/apache/flink/pulls/1156","id":45539137,"html_url":"https://github.com/apache/flink/pull/1156","diff_url":"https://github.com/apache/flink/pull/1156.diff","patch_url":"https://github.com/apache/flink/pull/1156.patch","issue_url":"https://api.github.com/repos/apache/flink/issues/1156","number":1156,"state":"open","locked":false,"title":"[FLINK-1719] [ml] Add Multinomial Naive Bayes Classification","user":{"login":"JonathanH5","id":5738978,"avatar_url":"https://avatars.githubusercontent.com/u/5738978?v=3","gravatar_id":"","url":"https://api.github.com/users/JonathanH5","html_url":"https://github.com/JonathanH5","followers_url":"https://api.github.com/users/JonathanH5/followers","following_url":"https://api.github.com/users/JonathanH5/following{/other_user}","gists_url":"https://api.github.com/users/JonathanH5/gists{/gist_id}","starred_url":"https://api.github.com/users/JonathanH5/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/JonathanH5/subscriptions","organizations_url":"https://api.github.com/users/JonathanH5/orgs","repos_url":"https://api.github.com/users/JonathanH5/repos","events_url":"https://api.github.com/users/JonathanH5/events{/privacy}","received_events_url":"https://api.github.com/users/JonathanH5/received_events","type":"User","site_admin":false},"body":"This pull request is related to [FLINK-1719](https://issues.apache.org/jira/browse/FLINK-1719).\r\nMultinomial Naive Bayes was successfully implemented @tillrohrmann and different ideas proposed by other authors were incorporated.\r\n\r\n","created_at":"2015-09-21T11:47:18Z","updated_at":"2015-09-25T15:31:15Z","closed_at":null,"merged_at":null,"merge_commit_sha":"831f846a8d6ee29f6374eb6257978a932eee5e1f","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/apache/flink/pulls/1156/commits","review_comments_url":"https://api.github.com/repos/apache/flink/pulls/1156/comments","review_comment_url":"https://api.github.com/repos/apache/flink/pulls/comments{/number}","comments_url":"https://api.github.com/repos/apache/flink/issues/1156/comments","statuses_url":"https://api.github.com/repos/apache/flink/statuses/fadd761e175f2d7308e77f3acab03ce461b0abd5","head":{"label":"JonathanH5:pullrequest","ref":"pullrequest","sha":"fadd761e175f2d7308e77f3acab03ce461b0abd5","user":{"login":"JonathanH5","id":5738978,"avatar_url":"https://avatars.githubusercontent.com/u/5738978?v=3","gravatar_id":"","url":"https://api.github.com/users/JonathanH5","html_url":"https://github.com/JonathanH5","followers_url":"https://api.github.com/users/JonathanH5/followers","following_url":"https://api.github.com/users/JonathanH5/following{/other_user}","gists_url":"https://api.github.com/users/JonathanH5/gists{/gist_id}","starred_url":"https://api.github.com/users/JonathanH5/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/JonathanH5/subscriptions","organizations_url":"https://api.github.com/users/JonathanH5/orgs","repos_url":"https://api.github.com/users/JonathanH5/repos","events_url":"https://api.github.com/users/JonathanH5/events{/privacy}","received_events_url":"https://api.github.com/users/JonathanH5/received_events","type":"User","site_admin":false},"repo":{"id":34563457,"name":"flink","full_name":"JonathanH5/flink","owner":{"login":"JonathanH5","id":5738978,"avatar_url":"https://avatars.githubusercontent.com/u/5738978?v=3","gravatar_id":"","url":"https://api.github.com/users/JonathanH5","html_url":"https://github.com/JonathanH5","followers_url":"https://api.github.com/users/JonathanH5/followers","following_url":"https://api.github.com/users/JonathanH5/following{/other_user}","gists_url":"https://api.github.com/users/JonathanH5/gists{/gist_id}","starred_url":"https://api.github.com/users/JonathanH5/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/JonathanH5/subscriptions","organizations_url":"https://api.github.com/users/JonathanH5/orgs","repos_url":"https://api.github.com/users/JonathanH5/repos","events_url":"https://api.github.com/users/JonathanH5/events{/privacy}","received_events_url":"https://api.github.com/users/JonathanH5/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/JonathanH5/flink","description":"Mirror of Apache Flink","fork":true,"url":"https://api.github.com/repos/JonathanH5/flink","forks_url":"https://api.github.com/repos/JonathanH5/flink/forks","keys_url":"https://api.github.com/repos/JonathanH5/flink/keys{/key_id}","collaborators_url":"https://api.github.com/repos/JonathanH5/flink/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/JonathanH5/flink/teams","hooks_url":"https://api.github.com/repos/JonathanH5/flink/hooks","issue_events_url":"https://api.github.com/repos/JonathanH5/flink/issues/events{/number}","events_url":"https://api.github.com/repos/JonathanH5/flink/events","assignees_url":"https://api.github.com/repos/JonathanH5/flink/assignees{/user}","branches_url":"https://api.github.com/repos/JonathanH5/flink/branches{/branch}","tags_url":"https://api.github.com/repos/JonathanH5/flink/tags","blobs_url":"https://api.github.com/repos/JonathanH5/flink/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/JonathanH5/flink/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/JonathanH5/flink/git/refs{/sha}","trees_url":"https://api.github.com/repos/JonathanH5/flink/git/trees{/sha}","statuses_url":"https://api.github.com/repos/JonathanH5/flink/statuses/{sha}","languages_url":"https://api.github.com/repos/JonathanH5/flink/languages","stargazers_url":"https://api.github.com/repos/JonathanH5/flink/stargazers","contributors_url":"https://api.github.com/repos/JonathanH5/flink/contributors","subscribers_url":"https://api.github.com/repos/JonathanH5/flink/subscribers","subscription_url":"https://api.github.com/repos/JonathanH5/flink/subscription","commits_url":"https://api.github.com/repos/JonathanH5/flink/commits{/sha}","git_commits_url":"https://api.github.com/repos/JonathanH5/flink/git/commits{/sha}","comments_url":"https://api.github.com/repos/JonathanH5/flink/comments{/number}","issue_comment_url":"https://api.github.com/repos/JonathanH5/flink/issues/comments{/number}","contents_url":"https://api.github.com/repos/JonathanH5/flink/contents/{+path}","compare_url":"https://api.github.com/repos/JonathanH5/flink/compare/{base}...{head}","merges_url":"https://api.github.com/repos/JonathanH5/flink/merges","archive_url":"https://api.github.com/repos/JonathanH5/flink/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/JonathanH5/flink/downloads","issues_url":"https://api.github.com/repos/JonathanH5/flink/issues{/number}","pulls_url":"https://api.github.com/repos/JonathanH5/flink/pulls{/number}","milestones_url":"https://api.github.com/repos/JonathanH5/flink/milestones{/number}","notifications_url":"https://api.github.com/repos/JonathanH5/flink/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/JonathanH5/flink/labels{/name}","releases_url":"https://api.github.com/repos/JonathanH5/flink/releases{/id}","created_at":"2015-04-25T09:53:54Z","updated_at":"2015-04-25T09:54:04Z","pushed_at":"2015-09-22T11:16:00Z","git_url":"git://github.com/JonathanH5/flink.git","ssh_url":"git@github.com:JonathanH5/flink.git","clone_url":"https://github.com/JonathanH5/flink.git","svn_url":"https://github.com/JonathanH5/flink","homepage":null,"size":61447,"stargazers_count":0,"watchers_count":0,"language":"Java","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":"64e1dc6fe2c4970460c286a36136e9c4c32540a8","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":20587599,"name":"flink","full_name":"apache/flink","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/flink","description":"Mirror of Apache Flink","fork":false,"url":"https://api.github.com/repos/apache/flink","forks_url":"https://api.github.com/repos/apache/flink/forks","keys_url":"https://api.github.com/repos/apache/flink/keys{/key_id}","collaborators_url":"https://api.github.com/repos/apache/flink/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/apache/flink/teams","hooks_url":"https://api.github.com/repos/apache/flink/hooks","issue_events_url":"https://api.github.com/repos/apache/flink/issues/events{/number}","events_url":"https://api.github.com/repos/apache/flink/events","assignees_url":"https://api.github.com/repos/apache/flink/assignees{/user}","branches_url":"https://api.github.com/repos/apache/flink/branches{/branch}","tags_url":"https://api.github.com/repos/apache/flink/tags","blobs_url":"https://api.github.com/repos/apache/flink/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/apache/flink/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/apache/flink/git/refs{/sha}","trees_url":"https://api.github.com/repos/apache/flink/git/trees{/sha}","statuses_url":"https://api.github.com/repos/apache/flink/statuses/{sha}","languages_url":"https://api.github.com/repos/apache/flink/languages","stargazers_url":"https://api.github.com/repos/apache/flink/stargazers","contributors_url":"https://api.github.com/repos/apache/flink/contributors","subscribers_url":"https://api.github.com/repos/apache/flink/subscribers","subscription_url":"https://api.github.com/repos/apache/flink/subscription","commits_url":"https://api.github.com/repos/apache/flink/commits{/sha}","git_commits_url":"https://api.github.com/repos/apache/flink/git/commits{/sha}","comments_url":"https://api.github.com/repos/apache/flink/comments{/number}","issue_comment_url":"https://api.github.com/repos/apache/flink/issues/comments{/number}","contents_url":"https://api.github.com/repos/apache/flink/contents/{+path}","compare_url":"https://api.github.com/repos/apache/flink/compare/{base}...{head}","merges_url":"https://api.github.com/repos/apache/flink/merges","archive_url":"https://api.github.com/repos/apache/flink/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/apache/flink/downloads","issues_url":"https://api.github.com/repos/apache/flink/issues{/number}","pulls_url":"https://api.github.com/repos/apache/flink/pulls{/number}","milestones_url":"https://api.github.com/repos/apache/flink/milestones{/number}","notifications_url":"https://api.github.com/repos/apache/flink/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/apache/flink/labels{/name}","releases_url":"https://api.github.com/repos/apache/flink/releases{/id}","created_at":"2014-06-07T07:00:10Z","updated_at":"2015-09-25T03:05:24Z","pushed_at":"2015-09-25T15:27:48Z","git_url":"git://github.com/apache/flink.git","ssh_url":"git@github.com:apache/flink.git","clone_url":"https://github.com/apache/flink.git","svn_url":"https://github.com/apache/flink","homepage":null,"size":2524860,"stargazers_count":638,"watchers_count":638,"language":"Java","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":430,"mirror_url":"git://git.apache.org/incubator-flink.git","open_issues_count":74,"forks":430,"open_issues":74,"watchers":638,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/apache/flink/pulls/1156"},"html":{"href":"https://github.com/apache/flink/pull/1156"},"issue":{"href":"https://api.github.com/repos/apache/flink/issues/1156"},"comments":{"href":"https://api.github.com/repos/apache/flink/issues/1156/comments"},"review_comments":{"href":"https://api.github.com/repos/apache/flink/pulls/1156/comments"},"review_comment":{"href":"https://api.github.com/repos/apache/flink/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/apache/flink/pulls/1156/commits"},"statuses":{"href":"https://api.github.com/repos/apache/flink/statuses/fadd761e175f2d7308e77f3acab03ce461b0abd5"}}}}