metric_dimensionality

mcda.metric_dimensionality(scores, polarity, groups, metric_ids=None, min_pairwise=3, n_iter=500, seed=0)

Count the factors in each construct group of metrics.

Each method-by-dataset cell is one observation. The function orients every metric to higher-is-better, computes the Spearman rank correlation between every pair of metrics over their shared observations (the same engine as metric_validity and metric_reliability), and, for each group, takes the eigenvalues of the within-group correlation matrix. It reports how many factors the group carries by the Kaiser rule and by parallel analysis, and flags the groups that read as one factor.

Parameters

Name Type Description Default
scores Array-like of shape (n_observations, n_metrics) or a tensor of shape (n_methods, n_datasets, n_metrics), reshaped so that each method-by-dataset cell is one observation row. Missing cells are NaN and handled pairwise. required
polarity Sequence[str] Length n_metrics sequence of "higher_is_better" or "lower_is_better". Use beam.cards.polarities_for to source it from the registry. A "target_value" metric has no monotone quality direction; drop it before calling. required
groups Sequence[str] Length n_metrics construct label per metric. Metrics sharing a label are read together as one composite scale. required
metric_ids Sequence[str] | None Optional length n_metrics labels carried into the report. None
min_pairwise int Minimum shared observations for a pair’s correlation to be computed. Default 3. 3
n_iter int Number of random matrices parallel analysis averages over. Default 500. 500
seed int Seed for the parallel-analysis random draws, so the result reproduces. Default 0. 0

Returns

Type Description
MetricDimensionalityReport

Raises

Type Description
ValueError If the shapes do not line up, a polarity is not one of the two monotone values, or no group has at least two metrics (so no factor count is defined).

Examples

>>> import numpy as np
>>> from beam.mcda import metric_dimensionality
>>> rng = np.random.default_rng(0)
>>> factor = rng.normal(size=(60, 1))
>>> scores = np.hstack([factor + rng.normal(0, 0.2, (60, 1)) for _ in range(4)])
>>> report = metric_dimensionality(
...     scores,
...     ["higher_is_better"] * 4,
...     ["bio"] * 4,
... )
>>> "bio" in report.unidimensional_groups
True