Skip to content

Commit

Permalink
Merge pull request #938 from VesnaT/log_coef
Browse files Browse the repository at this point in the history
OWLogisticRegression: Add coefficients to output signals
  • Loading branch information
janezd committed Dec 18, 2015
2 parents 465ce7f + 47b9298 commit a4db24e
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 4 deletions.
10 changes: 8 additions & 2 deletions Orange/classification/logistic_regression.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,17 @@ class _FeatureScorerMixin(LearnerScorer):

def score(self, model):
# Take the maximum attribute score across all classes
return np.max(np.abs(model.skl_model.coef_), axis=0)
return np.max(np.abs(model.coefficients), axis=0)


class LogisticRegressionClassifier(SklModel):
pass
@property
def intercept(self):
return self.skl_model.intercept_

@property
def coefficients(self):
return self.skl_model.coef_


class LogisticRegressionLearner(SklLearner, _FeatureScorerMixin):
Expand Down
7 changes: 7 additions & 0 deletions Orange/tests/test_logistic_regression.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,10 @@ def test_learner_scorer(self):
self.assertEqual('physician-fee-freeze',
data.domain.attributes[np.argmax(scores)].name)
self.assertEqual(len(scores), len(data.domain.attributes))

def test_coefficients(self):
data = Table("voting")
learn = LogisticRegressionLearner()
model = learn(data)
coef = model.coefficients
self.assertEqual(len(coef[0]), len(model.domain.attributes))
27 changes: 25 additions & 2 deletions Orange/widgets/classify/owlogisticregression.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from PyQt4 import QtGui
from PyQt4.QtCore import Qt

from Orange.data import Table
from Orange.data import Table, Domain, ContinuousVariable, StringVariable
from Orange.classification import logistic_regression as lr
from Orange.widgets import widget, settings, gui
from Orange.widgets.utils.owlearnerwidget import OWProvidesLearner
Expand All @@ -18,7 +18,8 @@ class OWLogisticRegression(OWProvidesLearner, widget.OWWidget):

inputs = [("Data", Table, "set_data")] + OWProvidesLearner.inputs
outputs = [("Learner", lr.LogisticRegressionLearner),
("Classifier", lr.LogisticRegressionClassifier)]
("Classifier", lr.LogisticRegressionClassifier),
("Coefficients", Table)]

want_main_area = False
resizing_enabled = False
Expand Down Expand Up @@ -99,6 +100,7 @@ def apply(self):
)
learner.name = self.learner_name
classifier = None
coef_table = None

if self.data is not None:
self.error([0, 1])
Expand All @@ -109,9 +111,11 @@ def apply(self):
else:
classifier = learner(self.data)
classifier.name = self.learner_name
coef_table = create_coef_table(classifier)

self.send("Learner", learner)
self.send("Classifier", classifier)
self.send("Coefficients", coef_table)

def send_report(self):
self.report_items((("Name", self.learner_name),))
Expand All @@ -122,6 +126,25 @@ def send_report(self):
if self.data:
self.report_data("Data", self.data)


def create_coef_table(classifier):
i = classifier.intercept
c = classifier.coefficients
if len(classifier.domain.class_var.values) > 2:
values = classifier.domain.class_var.values
else:
values = ["coef"]
domain = Domain([ContinuousVariable(value, number_of_decimals=7)
for value in values], metas=[StringVariable("name")])
coefs = np.vstack((i.reshape(1, len(i)), c.T))
names = [[attr.name] for attr in classifier.domain.attributes]
names = [["intercept"]] + names
names = np.array(names, dtype=object)
coef_table = Table.from_numpy(domain, X=coefs, metas=names)
coef_table.name = "coefficients"
return coef_table


if __name__ == "__main__":
app = QtGui.QApplication([])
w = OWLogisticRegression()
Expand Down
1 change: 1 addition & 0 deletions Orange/widgets/classify/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

26 changes: 26 additions & 0 deletions Orange/widgets/classify/tests/test_owlogisticregression.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import unittest
import bottlechest as bn
from Orange.data import Table
from Orange.classification import LogisticRegressionLearner
from Orange.widgets.classify.owlogisticregression import create_coef_table


class LogisticRegressionTest(unittest.TestCase):
def test_coef_table_single(self):
data = Table("titanic")
learn = LogisticRegressionLearner()
classifier = learn(data)
coef_table = create_coef_table(classifier)
self.assertEqual(1, len(bn.stats(coef_table.metas, None)))
self.assertEqual(len(coef_table), len(classifier.domain.attributes) + 1)
self.assertEqual(len(coef_table[0]), 1)

def test_coef_table_multiple(self):
data = Table("zoo")
learn = LogisticRegressionLearner()
classifier = learn(data)
coef_table = create_coef_table(classifier)
self.assertEqual(1, len(bn.stats(coef_table.metas, None)))
self.assertEqual(len(coef_table), len(classifier.domain.attributes) + 1)
self.assertEqual(len(coef_table[0]),
len(classifier.domain.class_var.values))

0 comments on commit a4db24e

Please sign in to comment.