{"action":"created","issue":{"url":"https://api.github.com/repos/accord-net/framework/issues/282","repository_url":"https://api.github.com/repos/accord-net/framework","labels_url":"https://api.github.com/repos/accord-net/framework/issues/282/labels{/name}","comments_url":"https://api.github.com/repos/accord-net/framework/issues/282/comments","events_url":"https://api.github.com/repos/accord-net/framework/issues/282/events","html_url":"https://github.com/accord-net/framework/issues/282","id":172341684,"number":282,"title":"Issue in LogisticRegression.Transform() returns true for all inputs","user":{"login":"snives","id":2513094,"avatar_url":"https://avatars.githubusercontent.com/u/2513094?v=3","gravatar_id":"","url":"https://api.github.com/users/snives","html_url":"https://github.com/snives","followers_url":"https://api.github.com/users/snives/followers","following_url":"https://api.github.com/users/snives/following{/other_user}","gists_url":"https://api.github.com/users/snives/gists{/gist_id}","starred_url":"https://api.github.com/users/snives/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/snives/subscriptions","organizations_url":"https://api.github.com/users/snives/orgs","repos_url":"https://api.github.com/users/snives/repos","events_url":"https://api.github.com/users/snives/events{/privacy}","received_events_url":"https://api.github.com/users/snives/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":1,"created_at":"2016-08-21T21:10:32Z","updated_at":"2016-08-21T22:21:38Z","closed_at":null,"body":"In release 3.2.0.5706, when testing the LogisticRegression class in the trivial [GeneralizedLinearRegression code sample](http://accord-framework.net/docs/html/T_Accord_Statistics_Models_Regression_GeneralizedLinearRegression.htm) it appears that the Transform() function is assigning every input to the same classification label.\r\n\r\nTo recreate the issue:\r\n```C#\r\n// Suppose we have the following data about some patients.\r\n// The first variable is continuous and represent patient\r\n// age. The second variable is dichotomic and give whether\r\n// they smoke or not (This is completely fictional data).\r\ndouble[][] input =\r\n{\r\n    new double[] { 55, 0 }, // 0 - no cancer\r\n    new double[] { 28, 0 }, // 0\r\n    new double[] { 65, 1 }, // 0\r\n    new double[] { 46, 0 }, // 1 - have cancer\r\n    new double[] { 86, 1 }, // 1\r\n    new double[] { 56, 1 }, // 1\r\n    new double[] { 85, 0 }, // 0\r\n    new double[] { 33, 0 }, // 0\r\n    new double[] { 21, 1 }, // 0\r\n    new double[] { 42, 1 }, // 1\r\n};\r\n\r\n// We also know if they have had lung cancer or not, and \r\n// we would like to know whether smoking has any connection\r\n// with lung cancer (This is completely fictional data).\r\ndouble[] output =\r\n{\r\n    0, 0, 0, 1, 1, 1, 0, 0, 0, 1\r\n};\r\n\r\n\r\n// To verify this hypothesis, we are going to create a GLM\r\n// regression model for those two inputs (age and smoking).\r\nvar regression = new GeneralizedLinearRegression(new ProbitLinkFunction(), inputs: 2);\r\n\r\n// Next, we are going to estimate this model. For this, we\r\n// will use the Iteratively Reweighted Least Squares method.\r\nvar teacher = new IterativeReweightedLeastSquares(regression);\r\n\r\n// Now, we will iteratively estimate our model. The Run method returns\r\n// the maximum relative change in the model parameters and we will use\r\n// it as the convergence criteria.\r\n\r\ndouble delta = 0;\r\ndo\r\n{\r\n    // Perform an iteration\r\n    delta = teacher.Run(input, output);\r\n\r\n} while (delta > 0.001);\r\n\r\n//Test cases\r\ndouble[][] samples =\r\n{\r\n    new double[] { 1, 0 },\r\n    new double[] { 1, 1 },\r\n    new double[] { 20, 0 },\r\n    new double[] { 20, 1 },\r\n    new double[] { 40, 0 },\r\n    new double[] { 40, 1 },\r\n    new double[] { 60, 0 },\r\n    new double[] { 60, 1 },\r\n    new double[] { 80, 0 },\r\n    new double[] { 80, 1 },\r\n};\r\nfor (int i = 0; i < samples.Length; i++)\r\n{\r\n    Console.WriteLine(\"Input({0},{1}) => Predicted label {2}\",\r\n        samples[i][0], samples[i][1], regression.Transform(samples[i]));\r\n}\r\n```\r\n\r\nOutput:\r\n```\r\nInput(1,0) => Predicted label True\r\nInput(1,1) => Predicted label True\r\nInput(20,0) => Predicted label True\r\nInput(20,1) => Predicted label True\r\nInput(40,0) => Predicted label True\r\nInput(40,1) => Predicted label True\r\nInput(60,0) => Predicted label True\r\nInput(60,1) => Predicted label True\r\nInput(80,0) => Predicted label True\r\nInput(80,1) => Predicted label True\r\n```\r\n\r\nI've traced it back to the GeneralizedLinearRegression class, Decide() method, which adds 0.5 to the link function's inverse and passes that to the Classes.Decide() method.  This causes all the distances to falling the range of [0.5 .. 1.5], which always end up being coerced to a (bool) true.  It seems to label correctly if we instead subtract 0.5 from the link function's inverse.  Alternatively, it could also be that the Classes.Decide() method should be comparing the distance to 1.0 instead of to 0.0, which would achieve the same result.  However, I don't know what other implications this would have to the greater abstract nature of this class, otherwise I would commit the fix.\r\n\r\nIf anyone is intimately familiar with this part of code, please comment with your recommendation."},"comment":{"url":"https://api.github.com/repos/accord-net/framework/issues/comments/241286013","html_url":"https://github.com/accord-net/framework/issues/282#issuecomment-241286013","issue_url":"https://api.github.com/repos/accord-net/framework/issues/282","id":241286013,"user":{"login":"cesarsouza","id":528455,"avatar_url":"https://avatars.githubusercontent.com/u/528455?v=3","gravatar_id":"","url":"https://api.github.com/users/cesarsouza","html_url":"https://github.com/cesarsouza","followers_url":"https://api.github.com/users/cesarsouza/followers","following_url":"https://api.github.com/users/cesarsouza/following{/other_user}","gists_url":"https://api.github.com/users/cesarsouza/gists{/gist_id}","starred_url":"https://api.github.com/users/cesarsouza/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cesarsouza/subscriptions","organizations_url":"https://api.github.com/users/cesarsouza/orgs","repos_url":"https://api.github.com/users/cesarsouza/repos","events_url":"https://api.github.com/users/cesarsouza/events{/privacy}","received_events_url":"https://api.github.com/users/cesarsouza/received_events","type":"User","site_admin":false},"created_at":"2016-08-21T22:21:38Z","updated_at":"2016-08-21T22:21:38Z","body":"Oops, thanks for catching that, it is very likely that the addition of 0.5 is indeed incorrect. Normally the Decide function should cast a decision based on the sign of the input (negatives are false, positives are true). I will take a look at it tomorrow and continue fixing a few other bugs so we could have updated NuGet packages by the next weekend.\r\n\r\nAdditionally, the documentation also needs to be updated with the new preferred interface for creation regressions and classifiers... Thanks for pointing it out as well!\r\n\r\nRegards,\r\nCesar"}}
{"actor":{"display_login":"cesarsouza"}}