diff --git a/Orange/classification/scoringsheet.py b/Orange/classification/scoringsheet.py index 2f18123e60..0651a6e825 100644 --- a/Orange/classification/scoringsheet.py +++ b/Orange/classification/scoringsheet.py @@ -56,7 +56,9 @@ def __init__( if preprocessors is None: self.preprocessors = [ *self.preprocessors, - SelectBestFeatures(method=ReliefF(), k=num_attr_after_selection), + SelectBestFeatures( + method=ReliefF(random_state=42), k=num_attr_after_selection + ), ] super().__init__(preprocessors=preprocessors) diff --git a/Orange/widgets/model/tests/test_owscoringsheet.py b/Orange/widgets/model/tests/test_owscoringsheet.py index cdc6bc2fc7..0a31c702a7 100644 --- a/Orange/widgets/model/tests/test_owscoringsheet.py +++ b/Orange/widgets/model/tests/test_owscoringsheet.py @@ -1,25 +1,19 @@ import unittest +import numpy as np from orangewidget.tests.base import WidgetTest from Orange.data import Table from Orange.preprocess import Impute -from Orange.classification.scoringsheet import ScoringSheetLearner from Orange.widgets.model.owscoringsheet import OWScoringSheet class TestOWScoringSheet(WidgetTest): - @classmethod - def setUpClass(cls): - super().setUpClass() - cls.heart = Table("heart_disease") - cls.housing = Table("housing") - cls.scoring_sheet_learner = ScoringSheetLearner(20, 5, 5, None) - cls.scoring_sheet_model = cls.scoring_sheet_learner(cls.heart) - def setUp(self): self.widget = self.create_widget(OWScoringSheet) + self.heart = Table("heart_disease") + self.housing = Table("housing") def test_no_data_input(self): self.assertIsNotNone(self.get_output(self.widget.Outputs.learner)) @@ -64,14 +58,49 @@ def test_settings_in_model(self): self.assertEqual(len(coefficients), self.widget.num_attr_after_selection) - # most often equal, but in some cases the optimizer finds fewer parameters - self.assertLessEqual(len(non_zero_coefficients), self.widget.num_decision_params) + self.assertEqual(len(non_zero_coefficients), self.widget.num_decision_params) self.assertLessEqual( max(non_zero_coefficients, key=lambda x: abs(x)), self.widget.max_points_per_param, ) + def test_model_reproducibility(self): + self.widget = self.create_widget(OWScoringSheet) + self.widget.num_attr_after_selection = 20 + self.widget.num_decision_params = 7 + self.widget.max_points_per_param = 8 + self.widget.custom_features_checkbox = True + self.widget.num_input_features = 4 + + self.widget.apply() + + self.send_signal(self.widget.Inputs.data, self.heart) + self.wait_until_finished() + model = self.get_output(self.widget.Outputs.model) + + coefficients = np.array( + [ + -8.0, 6.0, 0.0, 0.0, -3.0, 4.0, 0.0, -2.0, -1.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -6.0, 0.0, 0.0, 0.0, 0.0, + ] + ) + feature_names = [ + "major vessels colored=< 1", "chest pain=asymptomatic", "gender=female", + "gender=male", "thal=normal", "thal=reversable defect", "rest SBP=125 - 150", + "chest pain=non-anginal", "major vessels colored=1 - 2", "major vessels colored=2 - 3", + "chest pain=atypical ang", "chest pain=typical ang", "rest SBP=150 - 175", + "rest ECG=left vent hypertrophy", "rest ECG=normal", "ST by exercise=< 2", + "rest SBP=100 - 125", "exerc ind ang=0", "exerc ind ang=1", "age=40 - 60", + ] + intercept = 7.0 + multiplier = 3.4567159 + + np.testing.assert_equal(model.model.coefficients, coefficients) + self.assertEqual(model.model.featureNames, feature_names) + self.assertEqual(model.model.intercept, intercept) + self.assertAlmostEqual(model.model.multiplier, multiplier, places=5) + def test_custom_number_input_features_information(self): self.widget.custom_features_checkbox = True self.widget.custom_input_features()