Repository: scikit-learn/scikit-learn
File: sklearn/tree/tests/test_tree.py (Python)

Code before:
        "feature",
        "n_node_samples",
    ]:
        value = getattr(DecisionTreeClassifier().fit([[0], [1]], [0, 1]).tree_, attr)
        # if pointing to freed memory, contents may be arbitrary
        assert -3 <= value.flat[0] < 3, "Array points to arbitrary memory"


def test_only_constant_features():
    random_state = check_random_state(0)
    X = np.zeros((10, 20))
    y = random_state.randint(0, 2, (10,))
    for name, TreeEstimator in ALL_TREES.items():
        est = TreeEstimator(random_state=0)
        est.fit(X, y)
        assert est.tree_.max_depth == 0


@pytest.mark.parametrize("tree_cls", ALL_TREES.values())
def test_almost_constant_feature(tree_cls):
    # Non regression test for
    # https://github.com/scikit-learn/scikit-learn/pull/32259
    # Make sure that almost constant features are discarded.
    random_state = check_random_state(0)
    X = random_state.rand(10, 2)
    # FEATURE_TRESHOLD=1e-7 is defined in sklearn/tree/_partitioner.pyx but not
    # accessible from Python
    feature_threshold = 1e-7
    X[:, 0] *= feature_threshold  # almost constant feature
    y = random_state.randint(0, 2, (10,))

    est = tree_cls(random_state=0)
    est.fit(X, y)
    # the almost constant feature should not be used
    assert est.feature_importances_[0] == 0
    # other feature should be used
    assert est.feature_importances_[1] > 0


def test_behaviour_constant_feature_after_splits():
    X = np.transpose(
        np.vstack(([[0, 0, 0, 0, 0, 1, 2, 4, 5, 6, 7]], np.zeros((4, 11))))
    )
    y = [0, 0, 0, 1, 1, 2, 2, 2, 3, 3, 3]
    for name, TreeEstimator in ALL_TREES.items():
        # do not check extra random trees
        if "ExtraTree" not in name:
            est = TreeEstimator(random_state=0, max_features=1)
            est.fit(X, y)
            assert est.tree_.max_depth == 2
            assert est.tree_.node_count == 5

Review comment (suggestion):
```suggestion
    # FEATURE_TRESHOLD=1e-7 is defined in sklearn/tree/_partitioner.pxd but not
```

Code after:
        "feature",
        "n_node_samples",
    ]:
        value = getattr(DecisionTreeClassifier().fit([[0], [1]], [0, 1]).tree_, attr)
        # if pointing to freed memory, contents may be arbitrary
        assert -3 <= value.flat[0] < 3, "Array points to arbitrary memory"


def test_only_constant_features():
    random_state = check_random_state(0)
    X = np.zeros((10, 20))
    y = random_state.randint(0, 2, (10,))
    for name, TreeEstimator in ALL_TREES.items():
        est = TreeEstimator(random_state=0)
        est.fit(X, y)
        assert est.tree_.max_depth == 0


@pytest.mark.parametrize("tree_cls", ALL_TREES.values())
def test_almost_constant_feature(tree_cls):
    # Non regression test for
    # https://github.com/scikit-learn/scikit-learn/pull/32259
    # Make sure that almost constant features are discarded.
    random_state = check_random_state(0)
    X = random_state.rand(10, 2)
    # FEATURE_TRESHOLD=1e-7 is defined in sklearn/tree/_partitioner.pxd but not
    # accessible from Python
    feature_threshold = 1e-7
    X[:, 0] *= feature_threshold  # almost constant feature
    y = random_state.randint(0, 2, (10,))

    est = tree_cls(random_state=0)
    est.fit(X, y)
    # the almost constant feature should not be used
    assert est.feature_importances_[0] == 0
    # other feature should be used
    assert est.feature_importances_[1] > 0


def test_behaviour_constant_feature_after_splits():
    X = np.transpose(
        np.vstack(([[0, 0, 0, 0, 0, 1, 2, 4, 5, 6, 7]], np.zeros((4, 11))))
    )
    y = [0, 0, 0, 1, 1, 2, 2, 2, 3, 3, 3]
    for name, TreeEstimator in ALL_TREES.items():
        # do not check extra random trees
        if "ExtraTree" not in name:
            est = TreeEstimator(random_state=0, max_features=1)
            est.fit(X, y)
            assert est.tree_.max_depth == 2
            assert est.tree_.node_count == 5