Kernels
Kernels convert adapted COBRA distance matrices into similarity or weight matrices.
They sit after the distance and adapter layers:
The current source implements ten kernel classes under:
kfc_procedure/cobra/core/kernels/
├── base.py
├── radial.py
├── exponential.py
├── reverse_cosh.py
├── cauchy.py
├── epanechnikov.py
├── biweight.py
├── triweight.py
├── triangular.py
├── naive.py
└── cobra.py
All kernels are registered through:
Kernel layer vs bandwidth layer
A key design choice in the current source is that the kernel usually does not own the COBRA bandwidth.
Instead, a kernel adapter transforms the raw distance matrix first.
For the one-parameter adapter:
where:
Then the kernel receives:
For example, the default RBF kernel computes:
So the effective default one-parameter COBRA weight is:
This is important when interpreting the package's bandwidth parameter.
COBRA kernel pipeline
flowchart LR
A["Representation"]
D["Distance matrix D"]
T["Kernel adapter"]
DP["Adapted distance D'"]
K["Kernel K(D')"]
W["Similarity / weight matrix"]
G["Aggregator"]
A --> D --> T --> DP --> K --> W --> G
The distance determines the geometry.
The adapter inserts tunable parameters such as:
The kernel maps the adapted distances to weights.
Built-in kernels
The current source registers:
| Registry name | Aliases | Class | Formula / behavior | Mode |
|---|---|---|---|---|
radial |
gaussian, rbf |
RadialKernel |
\(e^{-D}\) | continuous |
exponential |
— | ExponentialKernel |
\(e^{-D^p}\) | continuous |
reverse_cosh |
— | ReverseCoshKernel |
\(\cosh(D)^{-p}\) | continuous |
cauchy |
— | CauchyKernel |
\(1/(1+D)\) | continuous |
epanechnikov |
— | EpanechnikovKernel |
\(1-D\) for \(D<1\), else 0 | compact |
biweight |
— | BiweightKernel |
\((1-D)^2\) for \(D<1\), else 0 | compact |
triweight |
— | TriweightKernel |
\((1-D)^3\) for \(D<1\), else 0 | compact |
triangular |
— | TriangularKernel |
(1- | D |
naive |
— | NaiveKernel |
identity \(K(D)=D\) | discrete |
cobra |
— | COBRAKernel |
1 if \(D<t\), else 0 | discrete |
BaseKernel
Every built-in kernel inherits from:
The base interface provides:
A custom kernel must implement:
which returns the transformed matrix.
Base metadata
BaseKernel defines two class-level attributes:
Concrete kernels override these values where needed.
The source uses:
to decide whether gradient-style optimization is allowed.
The source uses:
to describe the kernel behavior.
Kernel modes
The source documents three modes:
The helper:
returns:
and:
returns:
Compact kernels are a third category
A kernel with:
returns False from both:
because the current helper methods test only exact string equality.
Kernel parameters
BaseKernel.__init__() stores keyword parameters in:
and also sets same-named attributes.
For example:
stores:
and:
get_params()
returns a copy of the internal parameter dictionary.
The deep argument exists for scikit-learn-style compatibility but is not
otherwise used by the current implementation.
set_params()
updates both:
and:
and returns the same object.
KernelFactory
Create a registered kernel with:
from kfc_procedure.cobra.core.kernels import (
KernelFactory,
)
kernel = KernelFactory.create(
"rbf"
)
Because KernelFactory inherits the package's BaseFactory, names are
normalized before lookup.
RBF aliases
The radial kernel is registered as:
Therefore all three names create:
The high-level COBRA estimators use:
as their default kernel name.
Radial / RBF kernel
The class is:
with registry names:
Its formula is:
The implementation is exactly:
No gamma parameter in RadialKernel
The current RadialKernel constructor is inherited from BaseKernel.
Its implementation does not define or use:
inside the kernel formula.
Bandwidth scaling is handled by the adapter layer.
So for the one-parameter adapter:
followed by:
gives:
Example
import numpy as np
from kfc_procedure.cobra.core.kernels import (
RadialKernel,
)
D = np.array([
[0.0, 0.5],
[1.0, 2.0],
])
kernel = RadialKernel()
K = kernel(D)
print(
K
)
Exponential kernel
The class is:
registered as:
Its formula is:
where:
Constructor
The default:
makes the formula identical to the radial kernel:
So with its default constructor:
and:
produce the same mathematical mapping.
Change curvature
then:
Configure through a COBRA estimator with:
Reverse-cosh kernel
The class is:
registered as:
Its formula is:
where:
Constructor
The source describes this as a smooth kernel that strongly suppresses large distances.
Example configuration
Cauchy kernel
The class is:
registered as:
Its formula is:
The source describes it as a heavy-tailed kernel with robust similarity decay.
Implementation
It has no specialized constructor parameters in the current source.
Compact-support kernels
Four built-ins have:
and:
They produce exactly zero weight outside their support.
The current compact kernels are:
All use a cutoff at:
Epanechnikov kernel
The class is:
registered as:
The current source formula is:
The implementation is:
Important naming detail
The implementation called EpanechnikovKernel is exactly the linear compact
mapping shown above.
This page preserves the package's source formula rather than substituting a different textbook normalization or polynomial form.
Biweight kernel
The class is:
registered as:
Its source formula is:
Implementation:
Triweight kernel
The class is:
registered as:
Its source formula is:
Implementation:
Triangular kernel
The class is:
registered as:
The implementation is:
So the source formula is:
For ordinary non-negative distance matrices this reduces to:
inside the support.
Source boundary condition
The condition used in the current implementation is:
not:
The absolute value is applied only inside:
This distinction normally does not matter for valid non-negative distances, but it is the exact current source behavior.
COBRA threshold kernel
The class is:
registered as:
It implements hard neighborhood selection.
Its formula is:
Constructor
The default cutoff is:
Implementation
So the output is a floating-point binary matrix.
Example
from kfc_procedure.cobra.core.kernels import (
COBRAKernel,
)
kernel = COBRAKernel(
threshold=0.7,
)
K = kernel(D)
Naive kernel
The class is:
registered as:
It performs no similarity transformation:
The implementation simply returns:
Important interpretation
Unlike most other kernels, larger distances remain larger output values.
So if the output is later used as aggregation weights, the naive kernel does not convert "near" into "large similarity."
The source describes it mainly as useful for:
Source metadata
Despite being an identity mapping, the current class sets:
This page preserves that metadata exactly as implemented.
requires_grad
The current continuous kernels set or inherit:
These are:
The compact and discrete kernels set:
These are:
Why requires_grad matters
GradientCOBRA checks:
MixCOBRARegressor uses the same logic.
Therefore if:
is requested with a non-gradient kernel, the current source silently changes the local optimization method to:
rather than continuing with gradient optimization.
Example
Conceptually:
resolves a kernel with:
and the optimization method is switched internally to grid mode.
Default kernels
The current defaults are:
| Estimator | Default kernel |
|---|---|
GradientCOBRA |
rbf |
MixCOBRARegressor |
rbf |
CombinedClassifier |
rbf |
Because:
is an alias for:
all three default to:
after adapter transformation.
Kernel parameters in COBRA estimators
The high-level estimators accept:
and:
For example:
The source resolves this with:
Inspect the resolved kernel
After component resolution or fitting:
Inspect its parameters:
Inspect optimization metadata:
Adapter scaling in GradientCOBRA
GradientCOBRA creates:
through the factory.
During cross-validation:
self.adapter_.set_params(
bandwidth=bandwidth
)
D = self.adapter_.transform(
self.distance_matrix_
)
K = self.kernel_(D)
Therefore candidate bandwidths act before the kernel.
Effective RBF formula in GradientCOBRA
The adapter computes:
The radial kernel computes:
Therefore:
Bandwidth direction
In this source, increasing:
multiplies the distance by a larger number before applying exp(-D).
So larger bandwidth values produce faster decay and narrower effective neighborhoods.
This is the opposite parameter direction from conventions written as:
where increasing \(h\) broadens the neighborhood.
Effective compact-kernel support with bandwidth
The same adapter logic changes the support radius of compact kernels.
For example, Epanechnikov is positive when:
Since:
the nonzero condition is:
or:
Thus larger bandwidth values shrink the raw-distance support.
Effective COBRA threshold with bandwidth
With:
the source applies:
With:
this becomes:
Therefore both:
influence the effective hard neighborhood radius.
MixCOBRA two-parameter kernel input
In two-parameter MixCOBRA, the adapter combines two distance matrices:
Then the selected kernel receives this fused distance:
With the default RBF kernel:
MixCOBRA one-parameter kernel input
With:
MixCOBRA first computes a distance on a concatenated representation and then uses:
The selected kernel is applied to that scaled distance exactly as in GradientCOBRA.
CombinedClassifier kernel flow
CombinedClassifier also creates:
and during optimization:
self.adapter_.set_params(
bandwidth=bandwidth
)
D = self.adapter_.transform(
self.distance_matrix_
)
K = self.kernel_(D)
So the same bandwidth-before-kernel interpretation applies.
Kernel matrix shape
The kernel does not change matrix shape.
If:
then:
normally has:
The values are transformed element-wise by all current built-in kernels.
Pairwise training kernel
During calibration and hyperparameter optimization, COBRA estimators often start with a square distance matrix:
The kernel transforms it to a square similarity/weight matrix of the same shape.
Cross-validation then extracts blocks such as:
for aggregation.
Query-to-calibration kernel
At prediction time, a query-to-calibration distance matrix:
is transformed into a kernel matrix of the same shape.
Each row then provides the calibration-sample weights used by the aggregator.
Zero-weight rows
Compact and threshold kernels can easily produce rows containing only zeros.
For example, if every adapted distance is outside the compact support:
then:
produce zero for every calibration point.
Likewise, cobra produces all zeros when no distance is below its threshold.
The downstream aggregator/fitted estimator determines the fallback behavior.
Regression fallback
For GradientCOBRA final prediction, the source passes:
to the weighted-mean aggregator.
Thus if kernel weights have effectively zero total mass, regression can fall back to the global calibration target mean.
Cross-validation code may use a different explicit fallback such as:
inside its objective.
Classification fallback
CombinedClassifier explicitly checks:
during cross-validation prediction.
The final prediction path similarly has class-fallback logic in the wrapped classifier.
This matters most for compact or hard-threshold kernels.
Continuous vs compact behavior
A practical source-level distinction is:
continuous kernels:
normally assign a nonzero decaying value over broad distance ranges
compact kernels:
assign exactly zero at D >= 1 after adaptation
discrete kernels:
hard / special mappings in current source
The package does not enforce a universal probabilistic normalization on kernel outputs.
They become raw weights for the configured aggregator.
Kernel outputs are not normalized probabilities
For example, the RBF kernel may return:
for one query row.
These values are not normalized to sum to one by the kernel itself.
A weighted aggregator can normalize them internally when computing a weighted mean or vote.
Direct kernel comparison
import numpy as np
from kfc_procedure.cobra.core.kernels import (
KernelFactory,
)
D = np.array([
[0.0, 0.25, 0.75, 1.25],
])
for name in [
"rbf",
"cauchy",
"epanechnikov",
"biweight",
"triweight",
"triangular",
"cobra",
"naive",
]:
kernel = KernelFactory.create(
name
)
print(
name,
kernel(D),
)
This uses the same adapted-distance values for every source implementation.
Direct RBF with adapter
from kfc_procedure.cobra.core.adapters import (
OneParameterKernelAdapter,
)
from kfc_procedure.cobra.core.kernels import (
RadialKernel,
)
adapter = OneParameterKernelAdapter(
bandwidth=2.0,
)
kernel = RadialKernel()
D_adapted = adapter.transform(
D
)
K = kernel(
D_adapted
)
This computes:
Exponential vs RBF
With:
the mapping is:
which is the same as:
The difference appears when:
For example:
produces:
Compact-kernel comparison
For:
the current source gives:
As the power increases, values inside the support decay more strongly away from zero.
At:
all three are exactly zero.
For non-negative distances, the current triangular implementation also reduces to:
inside the support, making it numerically equivalent to the current Epanechnikov implementation on ordinary non-negative distance input.
Current source equivalence
Because valid distance matrices are normally non-negative:
currently produce the same values for ordinary COBRA distance inputs.
Their code differs only through abs(D) inside the triangular branch.
KernelFactory inspection
List registered names:
The current source registers names including:
biweight
cauchy
cobra
epanechnikov
exponential
gaussian
naive
radial
rbf
reverse_cosh
triangular
triweight
Inspect one registration
Because:
are aliases, they resolve to the same registered class.
Custom kernel
A custom kernel should subclass:
and implement:
Example:
import numpy as np
from kfc_procedure.cobra.core.kernels import (
BaseKernel,
KernelFactory,
)
@KernelFactory.register(
"inverse_square"
)
class InverseSquareKernel(
BaseKernel
):
requires_grad = True
mode = "continuous"
def __call__(
self,
D,
):
D = np.asarray(D)
return 1.0 / (
1.0 + D ** 2
)
Then:
can resolve it through the normal factory path.
Custom kernel with parameters
@KernelFactory.register(
"scaled_cauchy"
)
class ScaledCauchyKernel(
BaseKernel
):
requires_grad = True
mode = "continuous"
def __init__(
self,
power=1.0,
):
super().__init__(
power=power,
)
def __call__(
self,
D,
):
return 1.0 / (
1.0 + D
) ** self.power
Configure with:
Choosing requires_grad for a custom kernel
The optimizer compatibility check trusts the kernel's:
attribute.
Set:
only when the kernel is intended to participate in the package's gradient-style optimization path.
Set:
for non-smooth, compact-threshold, or otherwise unsupported cases.
The current source does not derive this capability automatically from the kernel formula.
Custom kernel mode
Use one of the source's descriptive mode strings:
For example:
for a bounded-support mapping.
Remember that the current convenience helpers only explicitly recognize:
and have no separate:
method.
Debugging kernel configuration
Check configured name
Check kernel parameters
Inspect the resolved object
Inspect source metadata
Inspect effective parameters
Inspect the adapter too
Because bandwidth is not normally stored in the RBF kernel itself:
This is essential when interpreting the effective similarity rule.
Debugging unexpected zero weights
If using a compact kernel:
D = model.adapter_.transform(
distance_matrix
)
K = model.kernel_(
D
)
print(
np.min(D),
np.max(D),
)
print(
np.sum(
K > 0,
axis=1,
)
)
Rows with zero positive entries have no neighbors inside the current support.
Debugging RBF decay
For the default RBF path:
and:
Then:
Inspecting both matrices can reveal whether the optimized bandwidth makes the kernel too concentrated or too broad.
Current implementation summary
| Kernel | requires_grad |
Mode | Parameters |
|---|---|---|---|
radial / gaussian / rbf |
Yes | continuous |
none |
exponential |
Yes | continuous |
exponent=1.0 |
reverse_cosh |
Yes | continuous |
exponent=1.0 |
cauchy |
Yes | continuous |
none |
epanechnikov |
No | compact |
none |
biweight |
No | compact |
none |
triweight |
No | compact |
none |
triangular |
No | compact |
none |
naive |
No | discrete |
none |
cobra |
No | discrete |
threshold=0.5 |
Quick reference
| Goal | Source option |
|---|---|
| default smooth decay | rbf |
| alternate smooth power decay | exponential |
| heavy-tailed decay | cauchy |
| hyperbolic decay | reverse_cosh |
| compact linear support | epanechnikov / triangular |
| stronger compact decay | biweight, triweight |
| hard neighborhood | cobra |
| identity/debug mapping | naive |
Mental model
The distance says how far two prediction representations are apart; the adapter decides how strongly that distance is scaled; the kernel turns the adapted distance into the weight used for consensus.
For the default KFC/COBRA RBF path:
so the optimized bandwidth belongs to the adapter rather than to the
RadialKernel implementation itself.