Overview#
This article documents the current target-construction and object-weighting logic used in the layered CatBoost notebook for the P6 task.
The reference implementation currently lives in NN/NN_5/CatBoost_5_layered/CatBoost_5_EAM_on_P6_bump2_Layered.ipynb.
The important distinction is that the notebook keeps a binary target for training and threshold selection, but it also preserves the raw P6 signal strength so Pool(weight=...) can amplify stronger positive examples during fit.
Why this logic exists#
P6aimsdefines whether a row belongs to the positive class.P6devadds a business constraint: some rows that look positive byP6aimsstill become negative if deviation is too weak.- raw
P6aimsandP6devstill contain useful gradation above that binary split, so the notebook stores them in service columns and uses them for weighting. - the model remains a classifier, not a regressor; weighting only changes how strongly each training row influences the loss.
Primary runtime flow#
- Load raw rows and convert textual
P6aims/P6devvalues into fractions. - Store raw fractions in service columns before binary target conversion.
- Build the binary target from
P6aims. - Apply the business reclassification rule for
P6dev < -6%. - Optionally drop rows with
P6dev > 0%. - Build object weights from raw
P6aimsand rawP6dev. - Pass these weights into
CatBoost.Pool(weight=...)for train, validation, and test splits.
Target construction#
P6aims threshold#
The binary target is built from P6aims using an inclusive threshold:
t_frac < P6AIMS_POS_THRESHOLD_FRAC -> class 0
t_frac >= P6AIMS_POS_THRESHOLD_FRAC -> class 1
In the current notebook P6AIMS_POS_THRESHOLD_FRAC = 0.15, so a row with exactly 15% is treated as class 1.
P6dev negative reclassification#
After the initial P6aims-based target is built, the notebook applies a business guard:
if P6dev < -0.06:
target = 0
This means a row can first qualify as positive by P6aims and then still be forced back into class 0 by P6dev.
P6dev > 0% drop#
The current notebook also uses APPLY_P6DEV_GT_ZERO_DROP = True.
When enabled, rows with P6dev > 0% are removed from the dataset before training.
This matters because the weighting formula would otherwise interpret any positive P6dev as maximum P6dev strength after clipping.
Service columns used for weighting#
The notebook stores raw fractions in service columns before target conversion:
_P6aims_raw_frac_P6dev_raw_frac
This is necessary because after binary conversion the target no longer distinguishes cases such as 0.15, 0.20, 0.80, and 1.20, while weighting still needs that strength information.
Object-weighting formula#
Each row starts with a base weight of 1.0.
Additional weight is applied only to rows that remain in class 1 after the full target pipeline.
weight = 1.0
+ OBJECT_WEIGHT_POSITIVE_P6AIMS_GAIN * p6aims_strength
+ OBJECT_WEIGHT_POSITIVE_P6DEV_GAIN * p6dev_strength
In the current notebook configuration:
OBJECT_WEIGHT_POSITIVE_P6AIMS_GAIN = 0.90OBJECT_WEIGHT_POSITIVE_P6DEV_GAIN = 0.25
How P6aims strength is computed#
P6aims is the main weighting driver.
The notebook maps raw P6aims from the positive threshold to a configurable cap:
p6aims_strength = clip(
(P6aims_raw_frac - P6AIMS_POS_THRESHOLD_FRAC)
/ (OBJECT_WEIGHT_P6AIMS_CAP_FRAC - P6AIMS_POS_THRESHOLD_FRAC),
0,
1
)
With the current defaults:
P6AIMS_POS_THRESHOLD_FRAC = 0.15OBJECT_WEIGHT_P6AIMS_CAP_FRAC = 1.20
Operational meaning:
P6aims = 0.15->p6aims_strength = 0P6aims = 0.20-> small positive bonusP6aims = 0.80-> strong positive bonusP6aims >= 1.20-> capped maximum bonus
How P6dev strength is computed#
P6dev is a secondary, softer weighting signal.
p6dev_strength = clip(
(P6dev_raw_frac - P6DEV_NEG_THRESHOLD_FRAC)
/ (P6DEV_GT_ZERO_THRESHOLD_FRAC - P6DEV_NEG_THRESHOLD_FRAC),
0,
1
)
With the current defaults:
P6DEV_NEG_THRESHOLD_FRAC = -0.06P6DEV_GT_ZERO_THRESHOLD_FRAC = 0.00OBJECT_WEIGHT_P6DEV_MISSING_STRENGTH = 0.0
Operational meaning:
P6dev = -0.06->p6dev_strength = 0P6dev = -0.03-> medium bonusP6dev = 0.00-> maximum bonus- missing
P6dev-> neutral bonus0
Important edge case: disabling P6dev > 0% drop#
If APPLY_P6DEV_GT_ZERO_DROP is changed from True to False, rows with P6dev > 0% are no longer removed.
Under the current weighting formula such rows do not just remain in the dataset. If they still belong to class 1, they receive the maximum P6dev bonus because the formula clips all values above 0% to p6dev_strength = 1.
That means values such as P6dev = 1%, 2%, ..., 6% would be treated by weighting as the strongest possible P6dev cases unless the formula is changed as well.
What happens to the negative class#
The notebook intentionally amplifies only the positive class.
Rows that end up in class 0 do not receive a custom negative bonus. They keep the base weight, subject only to final clipping and normalization.
This is important for rows reclassified by P6dev < -6%: once they become negative, they stop receiving any positive weighting bonus even if raw P6aims looked strong.
Clip and normalization#
After the raw bonuses are applied, the notebook stabilizes the scale in two steps:
- clip weights into
[OBJECT_WEIGHT_CLIP_MIN, OBJECT_WEIGHT_CLIP_MAX] - optionally divide all weights by the split mean so the average weight becomes
1.0
Current defaults:
OBJECT_WEIGHT_CLIP_MIN = 0.75OBJECT_WEIGHT_CLIP_MAX = 2.25OBJECT_WEIGHT_NORMALIZE_TO_MEAN_1 = True
This keeps the overall loss scale close to the baseline experiment and prevents a small subset of extreme rows from dominating fit.
Where the weights are used#
The notebook builds weights separately for the train, validation, and test splits and passes them directly into CatBoost pools:
train_pool = Pool(..., weight=train_object_weights)
val_pool = Pool(..., weight=val_object_weights)
test_pool = Pool(..., weight=test_object_weights)
Weight summaries are printed before fit so changes in mean, median, max, and positive/negative split behavior can be checked before a long training run starts.
Practical diagnosis checklist#
- If the positive share suddenly changes, first inspect the
P6aims >= thresholdrule and theP6dev < -6%reclassification path. - If unexpectedly strong rows dominate fit, inspect
OBJECT_WEIGHT_P6AIMS_CAP_FRAC, gains, clip bounds, and the final weight summaries. - If
P6dev > 0%rows start appearing, confirm whetherAPPLY_P6DEV_GT_ZERO_DROPwas disabled intentionally. - If that drop was disabled, verify whether the weighting formula was also adapted so positive
P6devvalues do not receive an unintended maximum bonus.