microsoft/qlib · error · ValueError

The length of sub_weights should be equal to num_models.

Error message

The length of sub_weights should be equal to num_models.

What it means

Thrown by DEnsembleModel's __init__ when len(sub_weights) != num_models. Each of the num_models sub-models in the ensemble gets one weight used to combine predictions (pred = sum(w_k * pred_k) / sum(w)), so the weights list must have exactly one entry per sub-model. The default is [1]*num_models.

Source

Thrown at qlib/contrib/model/double_ensemble.py:53

    ):
        self.base_model = base_model  # "gbm" or "mlp", specifically, we use lgbm for "gbm"
        self.num_models = num_models  # the number of sub-models
        self.enable_sr = enable_sr
        self.enable_fs = enable_fs
        self.alpha1 = alpha1
        self.alpha2 = alpha2
        self.bins_sr = bins_sr
        self.bins_fs = bins_fs
        self.decay = decay
        if sample_ratios is None:  # the default values for sample_ratios
            sample_ratios = [0.8, 0.7, 0.6, 0.5, 0.4]
        if sub_weights is None:  # the default values for sub_weights
            sub_weights = [1] * self.num_models
        if not len(sample_ratios) == bins_fs:
            raise ValueError("The length of sample_ratios should be equal to bins_fs.")
        self.sample_ratios = sample_ratios
        if not len(sub_weights) == num_models:
            raise ValueError("The length of sub_weights should be equal to num_models.")
        self.sub_weights = sub_weights
        self.epochs = epochs
        self.logger = get_module_logger("DEnsembleModel")
        self.logger.info("Double Ensemble Model...")
        self.ensemble = []  # the current ensemble model, a list contains all the sub-models
        self.sub_features = []  # the features for each sub model in the form of pandas.Index
        self.params = {"objective": loss}
        self.params.update(kwargs)
        self.loss = loss
        self.early_stopping_rounds = early_stopping_rounds

    def fit(self, dataset: DatasetH):
        df_train, df_valid = dataset.prepare(
            ["train", "valid"], col_set=["feature", "label"], data_key=DataHandlerLP.DK_L
        )
        if df_train.empty or df_valid.empty:
            raise ValueError("Empty data from dataset, please check your dataset config.")
        x_train, y_train = df_train["feature"], df_train["label"]

View on GitHub (pinned to 79633dd950)

Solutions

  1. Set sub_weights to None (default, all ones) unless per-model weighting is required
  2. Provide exactly num_weights entries: sub_weights=[1]*num_models or your weights list of that length

Example fix

# before
model = DEnsembleModel(num_models=5, sub_weights=[1, 2, 3])

# after
model = DEnsembleModel(num_models=5, sub_weights=[1, 2, 3, 2, 1])
Defensive patterns

Strategy: validation

Validate before calling

if sub_weights is None:
    sub_weights = [1] * num_models
assert len(sub_weights) == num_models, "sub_weights length must match num_models"

Prevention

When it happens

Trigger: Passing DEnsembleModel(num_models=5, sub_weights=[1, 2]) or any explicit sub_weights list shorter/longer than num_models; changing num_models while keeping a hand-written sub_weights.

Common situations: Hyperparameter sweeps that vary num_models but fix sub_weights; manually weighting sub-models and miscounting.

Related errors


AI-assisted analysis of microsoft/qlib@79633dd950 (2026-08-15). Data as JSON: /api/errors/58a543b3687b9d1d. Report an issue: GitHub.