Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion optbinning/binning/binning_process.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@
"quality_score": {"min": 0, "max": 1}
},
"continuous": {
"metrics": ["woe", "quality_score"],
"metrics": ["iv", "woe", "quality_score"],
"iv": {"min": 0, "max": np.inf},
"woe": {"min": 0, "max": np.inf},
"quality_score": {"min": 0, "max": 1}
}
Expand Down Expand Up @@ -426,6 +427,7 @@ def _binning_selection_criteria(self):
"quality_score": optb.binning_table.quality_score}
elif self._target_dtype == "continuous":
metrics = {
"iv": optb.binning_table.iv,
"woe": optb.binning_table.woe,
"quality_score": optb.binning_table.quality_score}

Expand Down
34 changes: 34 additions & 0 deletions tests/test_binning_process.py
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,40 @@ def test_default_transform_pandas():
X_transform.values[:, 5], rel=1e-6)


def test_selection_criteria_iv_continuous():
# "iv" was not accepted as a selection_criteria metric for continuous
# targets, even though ContinuousBinningTable already exposes it via
# its .iv property (same as the binary case). See GH issue #307.
data = load_boston()
variable_names = data.feature_names
X = data.data
y = data.target

process = BinningProcess(variable_names)
process.fit(X, y)

summary = process.summary()
assert "iv" in summary.columns

for name in variable_names:
optb = process.get_binned_variable(name)
row_iv = summary.loc[summary["name"] == name, "iv"].iloc[0]
assert row_iv == approx(optb.binning_table.iv, rel=1e-6)

# selection_criteria on "iv" must work for continuous targets exactly
# like it already does for binary/multiclass metrics.
selection_criteria = {"iv": {"min": 4.0}}
process = BinningProcess(variable_names=variable_names,
selection_criteria=selection_criteria)
process.fit(X, y)

summary = process.summary()
assert summary.loc[summary["selected"], "iv"].min() >= 4.0
assert summary.loc[~summary["selected"], "iv"].max() < 4.0
assert summary["selected"].sum() > 0
assert summary["selected"].sum() < len(summary)


def test_default_transform_continuous():
data = load_boston()
variable_names = data.feature_names
Expand Down