Skip to content

Commit

Permalink
integer intercept if rounding=True
Browse files Browse the repository at this point in the history
  • Loading branch information
guillermo-navas-palencia committed Apr 13, 2022
1 parent 3830fe2 commit 53af39d
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 5 deletions.
30 changes: 26 additions & 4 deletions optbinning/scorecard/scorecard.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,22 +61,26 @@ def _check_parameters(binning_process, estimator, scaling_method,
if not isinstance(rounding, bool):
raise TypeError("rounding must be a boolean; got {}.".format(rounding))

if rounding and scaling_method is None:
raise ValueError("rounding is only applied if scaling method is "
"not None.")

if not isinstance(verbose, bool):
raise TypeError("verbose must be a boolean; got {}.".format(verbose))


def _check_scorecard_scaling(scaling_method, scaling_method_params,
target_type):
rounding, target_type):
if scaling_method is not None:
if scaling_method == "pdo_odds":
default_keys = ["pdo", "odds", "scorecard_points"]
default_keys = ("pdo", "odds", "scorecard_points")

if target_type != "binary":
raise ValueError('scaling_method "pd_odds" is not supported '
'for a continuous target.')

elif scaling_method == "min_max":
default_keys = ["min", "max"]
default_keys = ("min", "max")

if set(scaling_method_params.keys()) != set(default_keys):
raise ValueError("scaling_method_params must be {} given "
Expand All @@ -102,6 +106,17 @@ def _check_scorecard_scaling(scaling_method, scaling_method_params,
.format(scaling_method_params["min"],
scaling_method_params["max"]))

if rounding:
score_min = scaling_method_params['min']
if int(score_min) != score_min:
raise ValueError("min must be an integer if rounding=True"
"; got {}.".format(score_min))

score_max = scaling_method_params['max']
if int(score_max) != score_max:
raise ValueError("max must be an integer if rounding=True"
"; got {}.".format(score_max))


def _compute_scorecard_points(points, binning_tables, method, method_data,
intercept, reverse_scorecard):
Expand Down Expand Up @@ -483,6 +498,7 @@ def _fit(self, X, y, sample_weight, metric_special, metric_missing,

_check_scorecard_scaling(self.scaling_method,
self.scaling_method_params,
self.rounding,
self._target_dtype)

# Check sample weight
Expand Down Expand Up @@ -595,8 +611,11 @@ def _fit(self, X, y, sample_weight, metric_special, metric_missing,
time_rounding = time.perf_counter()
if self.rounding:
points = df_scorecard["Points"]
if self.scaling_method == "pdo_odds":
if self.scaling_method in ("pdo_odds", None):
round_points = np.rint(points)

if self.intercept_based:
self.intercept_ = np.rint(self.intercept_)
elif self.scaling_method == "min_max":
round_mip = RoundingMIP()
round_mip.build_model(df_scorecard)
Expand All @@ -609,6 +628,9 @@ def _fit(self, X, y, sample_weight, metric_special, metric_missing,
# Back-up method
round_points = np.rint(points)

if self.intercept_based:
self.intercept_ = np.rint(self.intercept_)

df_scorecard.loc[:, "Points"] = round_points
self._time_rounding = time.perf_counter() - time_rounding

Expand Down
22 changes: 21 additions & 1 deletion tests/test_scorecard.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,26 @@ def test_params():
estimator=estimator, intercept_based=1)
scorecard.fit(X, y)

with raises(ValueError):
scorecard = Scorecard(binning_process=binning_process,
estimator=estimator,
scaling_method=None, rounding=True)
scorecard.fit(X, y)

with raises(ValueError):
scorecard = Scorecard(binning_process=binning_process,
estimator=estimator, scaling_method="min_max",
scaling_method_params={'min': 1.1, 'max': 10},
rounding=True)
scorecard.fit(X, y)

with raises(ValueError):
scorecard = Scorecard(binning_process=binning_process,
estimator=estimator, scaling_method="min_max",
scaling_method_params={'min': 1, 'max': 10.1},
rounding=True)
scorecard.fit(X, y)

with raises(TypeError):
scorecard = Scorecard(binning_process=binning_process,
estimator=estimator, reverse_scorecard=1)
Expand Down Expand Up @@ -296,7 +316,7 @@ def test_rounding():
binning_process = BinningProcess(variable_names)
estimator = LogisticRegression()

scaling_method_params = {"min": 200.52, "max": 850.66}
scaling_method_params = {"min": 200, "max": 851}

scorecard = Scorecard(binning_process=binning_process,
estimator=estimator, scaling_method="min_max",
Expand Down

0 comments on commit 53af39d

Please sign in to comment.