Skip to content

Train Ordinal Model (Adjacent Category) Node

AI/ML/Ordinal

Fit/Train an ordinal model that compares each level with the one directly below it: `log( P(level k+1) / P(level k) ) = contrast_k + x . beta`. Its coefficients answer `what does one more unit of this feature do to my rating?` - `exp(coefficient)` is the factor on the odds of scoring one level higher rather than staying put, the same factor at every step. That is NOT what Train Ordinal Model (Proportional Odds) reports: a cumulative coefficient is the log odds ratio of everything AT OR BELOW a cut point against everything above it, pooling levels instead of comparing two neighbours. The same fitted number therefore means different things in the two families, and since one shared coefficient applies once per step here, the bottom-to-top effect is (levels - 1) times the per-step effect. Pick this for ratings, severity grades and Likert answers, where the question really is about one step; pick proportional odds when the question is about crossing a threshold (`does this case escalate past level 2?`). Fitted by penalized maximum likelihood over all levels jointly, so per-level probabilities are calibrated and the Predict node returns a confidence. Scale your features first with the Fit Feature Scaler node: this is a gradient fit, and unscaled columns make it converge slowly or not at all.

fit_ordinal_adjacent_categoryml
Inputs7
Outputs5
Security exposure6/10
Packageml

Ratings

Scores range from 0 to 10. Higher values mean more impact, exposure, or operational weight.

SecurityAttack surface and exposure impact.
6/10Medium
PrivacyPotential sensitivity of processed data.
6/10Medium
PerformanceRuntime or resource pressure.
7/10High
GovernancePolicy, audit, or compliance impact.
9/10High
ReliabilityOperational stability considerations.
7/10High
CostExternal or compute cost impact.
7/10High

Input Pins

7

Input

Execution
exec_in

Execution trigger that begins adjacent-category training

Data Source

String
source

Choose which backend supplies the training data

Default Database
Database

Class Order

String
class_order

Comma-separated level labels from LOWEST to HIGHEST, e.g. `low, medium, high`. Leave empty when the levels are numeric and their numeric order is the order you want. Non-numeric labels have no inferable order, so training fails rather than guessing one. Levels listed here but never seen in training still keep their slot in the ordering, so the contrasts stay comparable across runs.

Alpha (L2 Penalty)

Float
alpha

Strength of the L2 penalty on the shared coefficients. The level contrasts are never penalized: shrinking those would pull neighbouring levels toward equal frequency, which asserts something about your data rather than limiting model complexity. 0 fits unpenalized. Raise it when the fit diverges or the coefficients blow up.

Default 1
Range 0 to 1000

Max Iterations

Integer
max_iterations

Iteration cap for the Adam optimizer. Training stops here even if the objective is still moving, which is reported on the Converged pin.

Default 500
Range 1 to 1000000

Tolerance

Float
tolerance

Relative change in the objective below which training stops. Smaller values fit tighter but need more iterations; 0 always runs the full iteration budget.

Default 1e-7
Range 0 to 1

Learning Rate

Float
learning_rate

Adam step size. Lower it if training oscillates or produces non-finite values; raise it if the model has not converged within Max Iterations. Level scores here carry a factor of the level index, so a badly scaled step travels further than it would in a cumulative fit.

Default 0.1
Range 0.000001 to 10

Output Pins

5

Done

Execution
exec_out

Activated once training completes

Model

Struct
model

Thread-safe handle to the trained adjacent-category model. Predictions come back as your original level labels, and because the fit maximizes a likelihood the Predict node also returns a per-level confidence.

NodeMLModelNodeMLModel1 fields
model_refstringrequired
Schema enforced

Levels

Struct
levels

The level order the model was actually trained on, lowest first, plus whether it came from your Class Order list (Explicit) or from reading the labels as numbers (Numeric). Check this first when an ordinal model behaves oddly.

OrdinalLevelsOrdinalLevels2 fields
labelsArray<string>required

Level labels from lowest to highest; the index is the rank the model was trained on.

itemsstringarray item
orderingOrdinalOrderingrequired

Where the ordering came from.

variant 1constvariant

Every distinct label parsed as a number, so the order is the numeric one.

const "Numeric"
variant 2constvariant

The caller supplied the order explicitly.

const "Explicit"

Converged

Boolean
converged

False when the optimizer hit Max Iterations before the objective settled. The model is still usable but under-fitted.

Coefficients

Struct
coefficients

The shared per-feature coefficients together with the level contrasts, both of them PER-STEP quantities: `exp(coefficient)` multiplies the odds of landing one level higher rather than on the current one, which is a single step and not the cumulative `above this cut` odds ratio a proportional-odds model prints. The struct also carries `bottom_to_top_effect`, the same coefficient times (levels - 1), which is the magnitude to quote when someone asks about the full range. The contrasts are the same log odds at a zero score, one per adjacent pair; unlike cumulative cut points they are free intercepts and may DECREASE.

AdjacentCategoryCoefficientsAdjacentCategoryCoefficients5 fields
coefficientsArray<number:double>required

One coefficient per feature, shared by every adjacent pair of levels. `exp(value)` is the factor one unit of that feature applies to the odds of landing on level `k + 1` rather than on level `k`, and it is the same factor at every `k`. It is NOT the cumulative odds ratio a proportional-odds fit reports: do not compare the two numbers directly.

itemsnumber:doublearray item
format double
n_featuresinteger:uintrequired

Number of input features.

format uintmin 0
level_contrastsArray<number:double>required

The `n_levels - 1` fitted level contrasts, lowest pair first: entry `k` is the log odds of level `k + 1` against level `k` for a sample whose score is zero. These are free intercepts, one per adjacent pair — NOT ordered cut points. They may DECREASE, which only means that level is rarer than the one below it, and forcing an order on them would be wrong here.

itemsnumber:doublearray item
format double
n_levelsinteger:uintrequired

Number of ordered levels the model was fitted on.

format uintmin 0
bottom_to_top_effectArray<number:double>required

`(n_levels - 1) * coefficient`: the total log-odds effect of one unit of each feature across the whole ordering, because a shared coefficient accumulates once per step. Reported next to the per-step value because this is the magnitude a cumulative coefficient is usually quoted at, and swapping the two silently understates the effect by that factor.

itemsnumber:doublearray item
format double

Node Info

Internal name
fit_ordinal_adjacent_category
Category
AI/ML/Ordinal
Version
1