Precomputed Predictions
The COBRA subsystem can operate on a matrix that already contains model predictions instead of fitting and evaluating an internal estimator pool.
The main source-level switch is:
and it is supported directly by:
through the shared:
helper.
This mode is especially important for KFC integration because the KFC F-Step already produces a prediction matrix that can be passed directly into a COBRA combiner.
What counts as a precomputed prediction matrix?
Suppose you already have predictions from \(M\) models for \(n\) observations.
For regression:
For classification, the current CombinedClassifier prediction space is based
on hard class predictions, so a row can look like:
rather than a probability vector.
The expected layout is:
Why use precomputed predictions?
Precomputed mode is useful when prediction features were generated by another part of a pipeline.
Examples include:
KFC F-Step predictions
external ensemble predictions
out-of-fold predictions from another framework
predictions loaded from disk
predictions generated by models managed outside kfc_procedure
With as_predictions=True, COBRA skips its normal internal base-estimator
training stage and treats the supplied matrix directly as its aggregation
representation.
Normal mode vs precomputed mode
Normal mode
raw X
↓
split into estimator-training and calibration subsets
↓
fit base estimators
↓
predict calibration data
↓
prediction space
↓
COBRA distance/kernel/aggregation
Precomputed mode
prediction matrix P
↓
as_predictions=True
↓
use P directly as calibration prediction space
↓
COBRA distance/kernel/aggregation
Shared training-context behavior
The central source logic is in:
Its precomputed branch is:
if as_predictions:
return TrainingContext(
X_k=None,
y_k=None,
X_l=np.asarray(X),
y_l=np.asarray(y),
as_predictions=True,
)
This branch runs before:
Resulting TrainingContext
With:
the resolver returns:
So there is no separate base-estimator training subset.
No automatic train/calibration split
Because the as_predictions branch returns immediately, parameters such as:
do not create an additional first-level COBRA split in this mode.
The entire supplied prediction matrix becomes the calibration-side data.
Input validation
Before the branch logic, the shared resolver calls:
So in precomputed mode:
must have a compatible number of rows.
For example:
must hold.
GradientCOBRA with precomputed predictions
GradientCOBRA.fit() accepts:
To supply a ready-made prediction matrix:
from kfc_procedure.cobra import (
GradientCOBRA,
)
model = GradientCOBRA(
random_state=42,
)
model.fit(
P_train,
y_train,
as_predictions=True,
)
GradientCOBRA fit behavior
After resolving the training context, the source stores:
self.X_k_ = ctx.X_k
self.y_k_ = ctx.y_k
self.X_l_ = ctx.X_l
self.y_l_ = ctx.y_l
self.as_predictions_ = ctx.as_predictions
Then:
if not self.as_predictions_:
self.estimators_ = self._fit_estimators(
self.X_k_,
self.y_k_,
)
prediction_space = self._load_predictions(
self.X_l_,
)
else:
prediction_space = self.X_l_
So with:
the supplied matrix is assigned directly to:
and:
is not created by this branch.
GradientCOBRA normalization still applies
Precomputed predictions do not bypass GradientCOBRA's scalar normalization.
The source computes:
self.normalize_constant_ = (
compute_normalization_constant(
y=y,
norm_constant=self.norm_constant,
scale_factor=30.0,
M=prediction_space.shape[1],
)
)
then:
So the workflow is:
GradientCOBRA prediction is symmetrical
GradientCOBRA.predict() explicitly checks:
Therefore, if fitting used:
prediction should also receive a prediction matrix:
The supplied P_test is interpreted directly as new prediction-space
coordinates.
Full GradientCOBRA example
from kfc_procedure.cobra import (
GradientCOBRA,
)
cobra = GradientCOBRA(
distance="euclidean",
kernel="rbf",
random_state=42,
)
cobra.fit(
P_train,
y_train,
as_predictions=True,
)
y_pred = cobra.predict(
P_test
)
Required column consistency
The source does not store or validate semantic column names.
Therefore the caller is responsible for ensuring that:
and:
represent predictions from the same underlying model or prediction source.
The same requirement applies to every column.
Inspect GradientCOBRA precomputed state
After fitting:
should be:
and:
should show:
while:
should match the precomputed training-matrix row and column counts.
No estimators_ in GradientCOBRA precomputed mode
Because the source skips:
when:
the fitted object does not rely on an internal estimator pool for prediction.
This is why:
works directly.
CombinedClassifier with precomputed predictions
CombinedClassifier.fit() supports the same switch:
CombinedClassifier fit branch
The current source does:
if not self.as_predictions_:
self.classes_ = np.unique(
self.y_k_
)
self.estimators_ = self._fit_estimators(
self.X_k_,
self.y_k_,
)
self.pred_l_ = self._load_predictions(
self.X_l_
)
else:
self.classes_ = np.unique(
self.y_l_
)
self.pred_l_ = self.X_l_
So with precomputed mode:
CombinedClassifier prediction space
The calibration distance matrix is computed directly from:
using:
The current default distance is:
which fits hard class-prediction vectors.
CombinedClassifier prediction is symmetrical
At prediction time:
Therefore:
treats P_test directly as prediction-space data after a precomputed fit.
CombinedClassifier probabilities
predict_proba() has the same source branch:
So:
also accepts precomputed prediction-space rows directly.
Probability caveat
The current default:
does not use the supplied kernel weights.
Therefore query-specific probabilities from the current default
CombinedClassifier.predict_proba() are affected by that implementation
limitation.
See:
for the exact behavior.
Full CombinedClassifier example
from kfc_procedure.cobra import (
CombinedClassifier,
)
classifier = CombinedClassifier(
distance="hamming",
kernel="rbf",
random_state=42,
)
classifier.fit(
P_train,
y_train,
as_predictions=True,
)
y_pred = classifier.predict(
P_test
)
proba = classifier.predict_proba(
P_test
)
Hard predictions, not probabilities
When CombinedClassifier builds prediction space internally, it uses:
rather than:
Therefore a precomputed matrix that mirrors the built-in semantics should normally contain hard class predictions.
Example:
rather than concatenated probability vectors.
MixCOBRA with precomputed predictions
MixCOBRARegressor.fit() also accepts:
and its fit branch initially behaves similarly.
if not self.as_predictions_:
self.estimators_ = self._fit_estimators(
self.X_k_,
self.y_k_,
)
prediction_space = self._load_predictions(
self.X_l_
)
else:
prediction_space = self.X_l_
So internal base-estimator fitting is skipped.
MixCOBRA stores the same matrix in two roles
In precomputed mode, the shared resolver gives:
and the fit branch sets:
MixCOBRA then computes:
self.X_l_norm_ = (
self.X_l_
*
self.normalize_constant_x_
)
self.Y_l_norm_ = (
prediction_space
*
self.normalize_constant_y_
)
Thus the same supplied prediction matrix participates as both:
under two different scalar normalizations.
MixCOBRA one-parameter mode
If:
the source concatenates:
into:
even though both originated from the same supplied matrix in
as_predictions=True mode.
MixCOBRA two-parameter mode
If:
the source computes:
from two differently scaled copies of the same supplied prediction matrix.
Important MixCOBRA prediction limitation
The current MixCOBRARegressor.predict() does not mirror the
as_predictions_ branch used by GradientCOBRA and CombinedClassifier.
Its code begins with:
There is no:
branch.
Consequence
When MixCOBRARegressor is fitted with:
the fit method skips creation of:
but later:
still tries to execute:
when pred_X is omitted.
That path expects internal estimators that were never fitted.
Current source limitation
MixCOBRARegressor(as_predictions=True) is not symmetrical between
fit() and the default predict() path.
Unlike GradientCOBRA and CombinedClassifier, precomputed fit mode does not
automatically make the predict(X) argument act as prediction space.
Why pred_X= does not fully solve standalone precomputed MixCOBRA
MixCOBRARegressor.predict() accepts:
and if pred_X is supplied it skips:
However, it still separately computes:
So the method expects:
This matches ordinary MixCOBRA's two-space design.
In as_predictions=True fit mode, however, the training code used the same
supplied matrix for both roles.
Source-aligned workaround
To reproduce the same source geometry during prediction, one can supply the same precomputed test matrix in both arguments:
This causes:
which mirrors the two differently scaled copies created during precomputed fitting.
Caution
This is a workaround inferred directly from the current implementation.
The source does not contain a dedicated high-level helper documenting this as the intended public precomputed-prediction API for MixCOBRA.
MixCOBRA example with current source behavior
from kfc_procedure.cobra import (
MixCOBRARegressor,
)
model = MixCOBRARegressor(
one_parameter=False,
random_state=42,
)
model.fit(
P_train,
y_train,
as_predictions=True,
)
y_pred = model.predict(
P_test,
pred_X=P_test,
)
This avoids the internal-estimator lookup in predict().
The separate pred_features argument
MixCOBRA also exposes:
in:
Its docstring describes this as:
However, the current resolver and fit implementation do not use that branch in the straightforward way the description suggests.
Resolver behavior for pred_features
When:
and:
the resolver returns:
TrainingContext(
X_k=np.asarray(X),
y_k=np.asarray(y),
X_l=pred_features,
y_l=np.asarray(y),
as_predictions=False,
)
So:
MixCOBRA fit after pred_features
Because:
the current MixCOBRA fit branch runs:
self.estimators_ = self._fit_estimators(
self.X_k_,
self.y_k_,
)
prediction_space = self._load_predictions(
self.X_l_
)
But:
now contains:
rather than ordinary calibration feature rows.
Therefore the source attempts to feed those precomputed prediction rows into the newly fitted base estimators.
Consequence
The current implementation does not directly assign:
in the pred_features branch.
So pred_features is not presently a clean substitute for
as_predictions=True.
Current source inconsistency
The MixCOBRA docstring describes pred_features as precomputed model
predictions.
The actual current fit path passes those values back through internal base estimators.
This page documents the implementation rather than silently assuming the docstring's intended behavior.
Prefer as_predictions=True when the whole matrix is already prediction space
For the current source:
have clean, symmetrical precomputed-prediction workflows through:
For MixCOBRA, the fit side supports that mode but the prediction side requires special care as described above.
KFC integration
KFC's C-Step wrappers use precomputed mode automatically.
The F-Step already produces:
so the wrappers call their COBRA estimator with:
rather than fitting another base-estimator pool.
GradientCOBRA KFC wrapper
The current wrapper is:
class GradientCOBRACombiner(
BaseCombiner
):
def __init__(
self,
**cobra_params,
):
self.cobra = GradientCOBRA(
**cobra_params
)
def fit(
self,
X,
y,
):
self.cobra.fit(
X,
y,
as_predictions=True,
)
return self
def combine(
self,
X,
):
return self.cobra.predict(
X
)
This works naturally because GradientCOBRA.predict() honors
as_predictions_.
CombinedClassifier KFC wrapper
The classifier wrapper similarly uses:
and later:
which is symmetrical in the current CombinedClassifier source.
MixCOBRA KFC wrapper caveat
The current MixCOBRACombiner uses:
but its combine() method simply calls:
without supplying:
Because MixCOBRARegressor.predict() does not branch on as_predictions_,
this wrapper can encounter the same missing-internal-estimator problem.
Current KFC integration issue
The current MixCOBRA C-Step wrapper fits with as_predictions=True but
predicts through the default MixCOBRARegressor.predict(X) path.
Those two code paths are not currently symmetrical.
Precomputed regression predictions from external models
Suppose you train three external regressors and create:
P_train = np.column_stack([
pred_a_train,
pred_b_train,
pred_c_train,
])
P_test = np.column_stack([
pred_a_test,
pred_b_test,
pred_c_test,
])
Then GradientCOBRA can use them directly:
model = GradientCOBRA(
random_state=42,
)
model.fit(
P_train,
y_train,
as_predictions=True,
)
y_pred = model.predict(
P_test
)
No estimator objects need to be passed into GradientCOBRA.
Precomputed classification predictions from external models
P_train = np.column_stack([
clf_a.predict(
X_train
),
clf_b.predict(
X_train
),
clf_c.predict(
X_train
),
])
P_test = np.column_stack([
clf_a.predict(
X_test
),
clf_b.predict(
X_test
),
clf_c.predict(
X_test
),
])
Then:
classifier = CombinedClassifier(
distance="hamming",
random_state=42,
)
classifier.fit(
P_train,
y_train,
as_predictions=True,
)
y_pred = classifier.predict(
P_test
)
Train/test column alignment
The package does not retain metadata such as:
So you should preserve column order explicitly.
For example:
and construct both matrices in that order.
Row alignment
Every training row must correspond to the same target row.
Likewise, every row in:
must correspond to the output row you expect in:
Prediction-space width
The training and prediction matrices should normally have the same number of columns:
Otherwise the configured distance operation is likely to fail because query and calibration vectors have incompatible coordinate dimensions.
Numeric dtype
GradientCOBRA and MixCOBRA eventually perform numerical scaling and distance calculations, so their precomputed regression matrices should be numeric.
CombinedClassifier with Hamming distance can naturally work with discrete class prediction values, subject to the rest of the pipeline's dtype behavior.
Missing values
The precomputed mode does not add a dedicated missing-value cleaning stage.
Downstream behavior depends on:
For regression prediction matrices, verify finite values before fitting:
Out-of-fold predictions
The source supports any matrix supplied through:
and does not inspect how those predictions were generated.
If the matrix was created externally, the responsibility for avoiding leakage or inappropriate reuse lies outside the COBRA implementation.
The package does not tag rows as:
or verify provenance.
No internal estimator refitting in precomputed mode
A central benefit of as_predictions=True is that the COBRA estimator does
not fit its configured estimator pool.
That means settings such as:
are not used for the skipped internal fit branch.
The downstream COBRA components are still resolved and optimized.
Cross-validation still runs
Precomputed mode bypasses the first-level train/calibration split, but it does not bypass COBRA hyperparameter cross-validation.
For GradientCOBRA:
still executes.
CombinedClassifier and MixCOBRA likewise construct their internal CV folds.
Optimization still runs
After distance matrices and folds are built, the normal optimization stage still selects parameters such as:
So:
means:
not:
Inspect whether precomputed mode was used
Expected:
for a model fitted with:
Inspect calibration representation
GradientCOBRA:
CombinedClassifier:
MixCOBRA:
Verify GradientCOBRA did not fit estimators
A source-aligned check is:
In a fresh model fitted only through:
the internal estimator-fit branch does not create that attribute.
Verify CombinedClassifier did not fit estimators
Likewise:
should normally be false for a fresh precomputed-mode fit.
Reusing externally saved matrices
A simple workflow can save:
and later load:
before fitting a COBRA estimator.
The package itself does not define a custom persistence format specifically for prediction-space matrices.
DataFrame input
check_X_y() and check_array() convert compatible tabular input into NumPy
arrays.
Therefore a pandas DataFrame can be supplied, but column labels are not retained as semantic prediction-source metadata inside the fitted COBRA estimator.
If names matter, keep them separately.
Precomputed probabilities are not the default classification representation
A matrix like:
can be numeric input mathematically, but that is not the representation
generated by the current CombinedClassifier base-estimator helper.
Its internal helper uses:
to build hard-label columns.
So a probability matrix would represent a custom prediction space rather than the current source's default semantics.
Precomputed predictions and normalization
GradientCOBRA
Still applies:
derived from:
MixCOBRA
Still applies:
CombinedClassifier
Applies no internal normalization before distance computation.
See:
for the exact formulas.
Precomputed predictions and distances
Once accepted, the matrix is just a coordinate representation.
The configured distance decides how rows are compared.
Examples:
See:
Precomputed predictions and kernels
The prediction matrix itself does not determine neighbor weights directly.
The flow remains:
So all normal kernel and optimization settings remain relevant in precomputed mode.
KFC F-Step as precomputed prediction space
The KFC Procedure naturally creates a matrix:
where each column is a divergence-specific prediction stream.
That matrix is already in the exact structural form expected by the COBRA precomputed mode:
This is why the COBRA C-Step wrappers call:
Manual KFC-to-GradientCOBRA workflow
You can reproduce the idea explicitly.
clusters_train = (
kfc_model
.kstep_
.predict(
X_train
)
)
P_train = (
kfc_model
.fstep_
.predict(
X_train,
clusters_train,
)
)
Then:
For test data:
clusters_test = (
kfc_model
.kstep_
.predict(
X_test
)
)
P_test = (
kfc_model
.fstep_
.predict(
X_test,
clusters_test,
)
)
y_pred = cobra.predict(
P_test
)
Manual KFC-to-CombinedClassifier workflow
The same concept applies to classification:
classifier = CombinedClassifier(
distance="hamming",
)
classifier.fit(
P_train,
y_train,
as_predictions=True,
)
y_pred = classifier.predict(
P_test
)
The F-Step rows become hard-label prediction-space coordinates.
Precomputed mode is not the same as explicit calibration data
These two interfaces have different meanings.
Explicit calibration data
means:
fit internal base estimators on X_k/y_k
generate their predictions on X_l
use those predictions as calibration prediction space.
Precomputed mode
means:
Precomputed mode is not the same as pred_features
For current MixCOBRA source:
and:
follow different code paths.
as_predictions=True directly assigns the supplied matrix to prediction
space during fit.
pred_features currently becomes X_l while as_predictions remains false,
after which internal estimators are still applied.
Do not treat these two arguments as equivalent in the current implementation.
Common errors
Mismatched sample count
from the shared check_X_y() path can occur if:
Mismatched prediction width
If:
distance computation can fail because query and calibration coordinates have different dimensions.
Reordered prediction columns
This may not raise an error because shapes still match.
But it changes the geometry.
For example:
is semantically incorrect even though both matrices have three columns.
Calling MixCOBRA predict(P_test) after precomputed fit
The current source can try to use missing internal estimators.
Use the source-aware workaround:
if you intentionally use this current precomputed MixCOBRA mode.
Validation checklist
Before fitting:
Before prediction:
For numeric regression spaces:
Recommended metadata to keep externally
Because COBRA does not store prediction-column names, keep something like:
alongside saved matrices.
For reproducibility, also keep:
outside the COBRA estimator.
Current source comparison
| Estimator | as_predictions=True fit |
predict(X) treats X as prediction space |
Notes |
|---|---|---|---|
GradientCOBRA |
Yes | Yes | clean symmetric path |
CombinedClassifier |
Yes | Yes | hard-label prediction space by default |
MixCOBRARegressor |
Yes | No | current predict path still derives pred_X unless supplied |
KFC wrapper comparison
| KFC combiner | Fits wrapped model with as_predictions=True |
Current prediction compatibility |
|---|---|---|
GradientCOBRACombiner |
Yes | compatible |
CobraClassifierCombiner |
Yes | compatible |
MixCOBRACombiner |
Yes | current wrapper affected by MixCOBRA predict asymmetry |
Quick reference
| Goal | Current source path |
|---|---|
| GradientCOBRA from external predictions | fit(P, y, as_predictions=True) |
| GradientCOBRA new prediction matrix | predict(P_test) |
| CombinedClassifier from hard predictions | fit(P, y, as_predictions=True) |
| CombinedClassifier new prediction matrix | predict(P_test) |
| CombinedClassifier probabilities | predict_proba(P_test) |
| MixCOBRA precomputed fit | fit(P, y, as_predictions=True) |
| MixCOBRA current-source prediction workaround | predict(P_test, pred_X=P_test) |
| Skip automatic data split | use as_predictions=True |
| Skip internal base estimators | use as_predictions=True |
| Keep COBRA CV/optimization | happens automatically |
Mental model
Precomputed-prediction mode says: “the prediction space already exists; start the COBRA procedure from that matrix instead of fitting another ensemble to create it.”
For GradientCOBRA:
For CombinedClassifier:
The current MixCOBRA source also accepts the matrix during fitting, but its prediction API does not yet mirror that precomputed mode automatically.