Skip to content

Commit

Permalink
Merge tag '3.33.0' into stable
Browse files Browse the repository at this point in the history
  • Loading branch information
markotoplak committed Sep 30, 2022
2 parents 7d399e7 + e2282bb commit 1d35646
Show file tree
Hide file tree
Showing 187 changed files with 7,127 additions and 2,728 deletions.
6 changes: 4 additions & 2 deletions .github/workflows/doc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
strategy:
fail-fast: False
matrix:
python: [3.7]
python: [3.9]
os: [ubuntu-18.04]

steps:
Expand All @@ -31,4 +31,6 @@ jobs:
run: pip install tox

- name: Build documentation
run: xvfb-run -a -s "-screen 0 1280x1024x24" tox -e build_doc
run: tox -e build_doc
env:
QT_QPA_PLATFORM: offscreen
2 changes: 1 addition & 1 deletion .github/workflows/rebase.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ jobs:
token: ${{ secrets.BIOLAB_HELPER_PAT }}
fetch-depth: 0 # otherwise, you will fail to push refs to dest repo
- name: Automatic Rebase
uses: cirrus-actions/rebase@1.4
uses: cirrus-actions/rebase@1.6
env:
GITHUB_TOKEN: ${{ secrets.BIOLAB_HELPER_PAT }}
45 changes: 30 additions & 15 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ on:

jobs:
lint:
runs-on: ubuntu-18.04
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
with:
Expand All @@ -36,19 +36,24 @@ jobs:
strategy:
fail-fast: False
matrix:
os: [ubuntu-18.04]
python-version: [3.7, 3.8, 3.9]
os: [ubuntu-20.04]
python-version: [3.8, 3.9, '3.10']
tox_env: [orange-released]
name: [Released]
include:
- os: ubuntu-18.04
python-version: 3.8
- os: ubuntu-20.04
python-version: '3.10'
tox_env: orange-latest
name: Latest
- os: ubuntu-18.04
python-version: 3.7
python-version: 3.8
tox_env: orange-oldest
name: Oldest dependencies
- os: ubuntu-20.04
python-version: 3.9
tox_env: pyqt6
name: PyQt6


services:
postgres:
Expand Down Expand Up @@ -77,17 +82,19 @@ jobs:
python-version: ${{ matrix.python-version }}

- name: Install linux system dependencies
run: sudo apt-get install -y libxkbcommon-x11-0
run: |
sudo apt-get update
sudo apt-get install -y libxkbcommon-x11-0 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 libxcb-xinerama0 libxcb-xfixes0 libegl1-mesa libxcb-shape0
- name: Install Tox
run: |
python -m pip install --upgrade pip
python -m pip install --upgrade tox tox-pip-version
- name: Run Tox
run: xvfb-run -a -s "-screen 0 1280x1024x24" tox -e ${{ matrix.tox_env }}
run: catchsegv xvfb-run -a -s "$XVFBARGS" tox -e ${{ matrix.tox_env }}
env:
# QT_QPA_PLATFORM: offscreen
XVFBARGS: "-screen 0 1280x1024x24"
ORANGE_TEST_DB_URI: postgres://postgres_user:postgres_password@localhost:5432/postgres_db|mssql://SA:sqlServerPassw0rd@localhost:1433

- name: Upload code coverage
Expand All @@ -105,19 +112,27 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [macos-10.15, windows-2019]
python-version: [3.7, 3.8, 3.9]
os: [macos-11, windows-2019]
python-version: [3.8, 3.9, '3.10']
tox_env: [orange-released]
name: [Released]
include:
- os: windows-latest
python-version: 3.8
python-version: '3.10'
tox_env: orange-latest
name: Latest
- os: macos-10.15
python-version: 3.8
- os: macos-11
python-version: '3.10'
tox_env: orange-latest
name: Latest
- os: windows-latest
python-version: '3.10'
tox_env: pyqt6
name: PyQt6
- os: macos-11
python-version: 3.9
tox_env: pyqt6
name: PyQt6

steps:
- uses: actions/checkout@v2
Expand All @@ -128,7 +143,7 @@ jobs:

- name: Install system dependencies on MacOS
run: brew install libomp
if: matrix.os == 'macos-10.15' || matrix.os == 'macos-11.0'
if: matrix.os == 'macos-10.15' || matrix.os == 'macos-11'

- name: Install dependencies
run: |
Expand Down
33 changes: 32 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,36 @@ Change Log
------------


[3.33.0] - 2022-09-30
--------------------
##### Enhancements
* drophandlers: Preserve defaults history ([#6069](../../pull/6069))
* owlogisticregression: Add option for no regularization ([#6093](../../pull/6093))
* Predictions: Show errors ([#6012](../../pull/6012))
* Add support for PyQt6 ([#5884](../../pull/5884))
* Feature Constructor: Make concurrent ([#5992](../../pull/5992))
* Feature constructor optimization ([#5975](../../pull/5975))
* Discretize: Simplify interface, add nicer binning ([#5919](../../pull/5919))

##### Bugfixes
* owboxplot: Fix an error in widget cleanup during tests ([#6136](../../pull/6136))
* Group By - fix std and sum for TimeVariable ([#6133](../../pull/6133))
* Handle timezones in Edit Domain ([#6123](../../pull/6123))
* owfeatureconstructor: Cast FeatureFunc result to array ([#6115](../../pull/6115))
* Server embedder - send bytes as content ([#6051](../../pull/6051))
* plotutils - replace MidButton with MiddleButton ([#6124](../../pull/6124))
* Feature Constructor cast function is not picklable ([#6002](../../pull/6002))
* test_owfile: Fix unreliable `test_warning_from_another_thread` ([#6085](../../pull/6085))
* Embedders - fix proxies, default on http, tests ([#6028](../../pull/6028))
* TableModel: Define foreground color when providing background ([#6011](../../pull/6011))
* owdistancemap: Fix an implicit float->int conversion error ([#5998](../../pull/5998))
* Neighbours - support Table derived output types ([#5986](../../pull/5986))
* Predictions: allow predicting probabilities for classless data ([#5972](../../pull/5972))
* owcsvimport: Reduce sample size ([#5960](../../pull/5960))
* make usable_scorers backwards compatible ([#5943](../../pull/5943))
* owpythonscript: Fix implicit float to int cast error ([#5944](../../pull/5944))


[3.32.0] - 2022-04-01
--------------------
##### Enhancements
Expand Down Expand Up @@ -1678,7 +1708,8 @@ Change Log
* Initial version based on Python 1.5.2 and Qt 2.3


[next]: https://github.com/biolab/orange3/compare/3.32.0...HEAD
[next]: https://github.com/biolab/orange3/compare/3.33.0...HEAD
[3.32.0]: https://github.com/biolab/orange3/compare/3.32.0...3.33.0
[3.32.0]: https://github.com/biolab/orange3/compare/3.31.1...3.32.0
[3.31.1]: https://github.com/biolab/orange3/compare/3.31.0...3.31.1
[3.31.0]: https://github.com/biolab/orange3/compare/3.30.2...3.31.0
Expand Down
34 changes: 20 additions & 14 deletions Orange/classification/_simple_tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -310,13 +310,13 @@ mse_c(struct Example *examples, int size, int attr, float cls_mse, struct Args *
var_lt.sum += ex->weight * cls_val;
var_lt.sum2 += ex->weight * cls_val * cls_val;

/* this calculation might be numarically unstable - fix */
/* this calculation might be numerically unstable - fix */
var_ge.n -= ex->weight;
var_ge.sum -= ex->weight * cls_val;
var_ge.sum2 -= ex->weight * cls_val * cls_val;
}

if (ex->x[attr] == ex_next->x[attr] || i + 1 < min_instances)
if (ex->x[attr] == ex_next->x[attr] || i + 1 < min_instances || var_lt.n == 0)
continue;

/* compute mse */
Expand Down Expand Up @@ -346,6 +346,10 @@ mse_d(struct Example *examples, int size, int attr, float cls_mse, struct Args *
float n, sum, sum2;
} *variances, *v, *v_end;

if (cls_mse <= 0) {
return 0.0;
}

attr_vals = args->attr_vals[attr];

ASSERT(variances = (struct Variance *)calloc(attr_vals, sizeof *variances));
Expand Down Expand Up @@ -381,8 +385,8 @@ mse_d(struct Example *examples, int size, int attr, float cls_mse, struct Args *
score += v->sum2 - v->sum * v->sum / v->n;
score = (cls_mse - score / size_attr_cls_known) / cls_mse * (size_attr_known / size_weight);

if (size_attr_cls_known <= 0.0 || cls_mse <= 0.0 || size_weight <= 0.0)
score = 0.0;
if (size_attr_cls_known <= 0.0 || size_weight <= 0.0)
score = -INFINITY;

finish:
free(attr_dist);
Expand Down Expand Up @@ -441,15 +445,6 @@ build_tree_(struct Example *examples, int size, int depth, struct SimpleTreeNode
float n, sum, sum2, cls_val;

assert(args->type == Regression);
if (size == 0) {
assert(parent);
node->type = PredictorNode;
node->children_size = 0;
node->n = parent->n;
node->sum = parent->sum;
return node;
}

n = sum = sum2 = 0.0;
for (ex = examples, ex_end = examples + size; ex < ex_end; ex++)
if (!isnan(ex->y)) {
Expand All @@ -461,6 +456,17 @@ build_tree_(struct Example *examples, int size, int depth, struct SimpleTreeNode

node->n = n;
node->sum = sum;

if (n == 0) {
node->type = PredictorNode;
node->children_size = 0;
if (parent) {
node->n = parent->n;
node->sum = parent->sum;
}
return node;
}

cls_mse = (sum2 - sum * sum / n) / n;

if (cls_mse < 1e-5) {
Expand Down Expand Up @@ -747,7 +753,7 @@ predict_regression(double *x, int size, struct SimpleTreeNode *node, int num_att
for (i = 0; i < size; i++) {
sum = n = 0;
predict_regression_(x + i * num_attrs, node, &sum, &n);
p[i] = sum / n;
p[i] = n > 0 ? sum / n : sum;
}
}

Expand Down
3 changes: 2 additions & 1 deletion Orange/classification/base_classification.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ def incompatibility_reason(self, domain):


class ModelClassification(Model):
pass
def predict_proba(self, data):
return self(data, ret=Model.Probs)


class SklModelClassification(SklModel, ModelClassification):
Expand Down
9 changes: 7 additions & 2 deletions Orange/classification/catgb.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@

import catboost

from Orange.base import CatGBBaseLearner
from Orange.classification import Learner
from Orange.base import CatGBBaseLearner, CatGBModel
from Orange.classification import Learner, Model
from Orange.data import Variable, DiscreteVariable, Table
from Orange.preprocess.score import LearnerScorer

Expand All @@ -21,5 +21,10 @@ def score(self, data: Table) -> Tuple[np.ndarray, Tuple[Variable]]:
return model.cat_model.feature_importances_, model.domain.attributes


class CatGBClsModel(CatGBModel, Model):
pass


class CatGBClassifier(CatGBBaseLearner, Learner, _FeatureScorerMixin):
__wraps__ = catboost.CatBoostClassifier
__returns__ = CatGBClsModel
55 changes: 55 additions & 0 deletions Orange/classification/tests/test_simple_tree.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import unittest

import numpy as np

from Orange.classification import SimpleTreeLearner
from Orange.data import ContinuousVariable, DiscreteVariable, Domain, \
Table


class SimpleTreeTest(unittest.TestCase):
def test_nonan_classification(self):
x = ContinuousVariable("x")
y = DiscreteVariable("y", values=tuple("ab"))
d = Domain([x], y)
t = Table.from_numpy(d, [[0]], [np.nan])
m = SimpleTreeLearner()(t)
self.assertFalse(np.isnan(m(t)[0]))

def test_nonan_regression(self):
x = ContinuousVariable("x")
y = ContinuousVariable("y")
d = Domain([x], y)
t = Table.from_numpy(d, [[42]], [np.nan])
m = SimpleTreeLearner()(t)
# must not be nan ...
self.assertFalse(np.isnan(m(t)[0]))
# ... and currently, it's zero (although mathematicians disagree,
# we, engineers *know* that 0 is the mean of R)
self.assertEqual(m(t)[0], 0)

x2 = ContinuousVariable("x2")
d = Domain([x, x2], y)
t = Table.from_numpy(d,
[[-1, np.nan], [1, -1], [1, 1]],
[-20, 20, np.nan])
m = SimpleTreeLearner(min_instances=1)(t)
# must not be nan ...
self.assertFalse(np.isnan(m(t)[0]))
# ... and currently, it's zero (although mathematicians disagree,
# we, engineers *know* that 0 is the mean of R)
np.testing.assert_equal(m(t), [-20, 20, 20])

def test_stub(self):
x = ContinuousVariable("x")
y = ContinuousVariable("y")
d = Domain([x], y)
t = Table.from_numpy(d, [[-1], [1]], [-5, 0])
m = SimpleTreeLearner(min_instances=1)(t)
np.testing.assert_equal(m(t), [-5, 0])
m = SimpleTreeLearner()(t)
np.testing.assert_equal(m(t), [-2.5, -2.5])


if __name__ == "__main__":
unittest.main()
4 changes: 3 additions & 1 deletion Orange/classification/xgb.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import xgboost

from Orange.base import XGBBase
from Orange.classification import Learner
from Orange.classification import Learner, SklModel
from Orange.data import Variable, DiscreteVariable, Table
from Orange.preprocess.score import LearnerScorer

Expand All @@ -24,6 +24,7 @@ def score(self, data: Table) -> Tuple[np.ndarray, Tuple[Variable]]:

class XGBClassifier(XGBBase, Learner, _FeatureScorerMixin):
__wraps__ = xgboost.XGBClassifier
__returns__ = SklModel

def __init__(self,
max_depth=None,
Expand Down Expand Up @@ -87,6 +88,7 @@ def __init__(self,

class XGBRFClassifier(XGBBase, Learner, _FeatureScorerMixin):
__wraps__ = xgboost.XGBRFClassifier
__returns__ = SklModel

def __init__(self,
max_depth=None,
Expand Down

0 comments on commit 1d35646

Please sign in to comment.