{"record":{"id":"6be0c4ad8ca75a7c","repo":"microsoft/qlib","slug":"lightgbm-doesn-t-support-multi-label-training-6be0c4","errorCode":null,"errorMessage":"LightGBM doesn't support multi-label training","messagePattern":"LightGBM doesn't support multi-label training","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"qlib/contrib/model/highfreq_gdbt_model.py","lineNumber":110,"sourceCode":"            # Convert label into alpha\n            df_train.loc[:, (\"label\", l_name)] = (\n                df_train.loc[:, (\"label\", l_name)]\n                - df_train.loc[:, (\"label\", l_name)].groupby(level=0, group_keys=False).mean()\n            )\n            df_valid.loc[:, (\"label\", l_name)] = (\n                df_valid.loc[:, (\"label\", l_name)]\n                - df_valid.loc[:, (\"label\", l_name)].groupby(level=0, group_keys=False).mean()\n            )\n\n            def mapping_fn(x):\n                return 0 if x < 0 else 1\n\n            df_train[\"label_c\"] = df_train[\"label\"][l_name].apply(mapping_fn)\n            df_valid[\"label_c\"] = df_valid[\"label\"][l_name].apply(mapping_fn)\n            x_train, y_train = df_train[\"feature\"], df_train[\"label_c\"].values\n            x_valid, y_valid = df_valid[\"feature\"], df_valid[\"label_c\"].values\n        else:\n            raise ValueError(\"LightGBM doesn't support multi-label training\")\n\n        dtrain = lgb.Dataset(x_train, label=y_train)\n        dvalid = lgb.Dataset(x_valid, label=y_valid)\n        return dtrain, dvalid\n\n    def fit(\n        self,\n        dataset: DatasetH,\n        num_boost_round=1000,\n        early_stopping_rounds=50,\n        verbose_eval=20,\n        evals_result=None,\n    ):\n        if evals_result is None:\n            evals_result = dict()\n        dtrain, dvalid = self._prepare_data(dataset)\n        early_stopping_callback = lgb.early_stopping(early_stopping_rounds)\n        verbose_eval_callback = lgb.log_evaluation(period=verbose_eval)","sourceCodeStart":92,"sourceCodeEnd":128,"githubUrl":"https://github.com/microsoft/qlib/blob/79633dd9506ea689e5400dea0197717b5b3d74b7/qlib/contrib/model/highfreq_gdbt_model.py#L92-L128","documentation":"Thrown by HFMLGBModel._prepare_data when the label block is not exactly one column. The model converts the single label into a per-timestamp alpha and then a binary label_c (0/1 by sign) for the LightGBM classifier; multiple label columns leave no unambiguous target, and LightGBM needs a 1D label anyway.","triggerScenarios":"Fitting HFMLGBModel with a handler label list containing more than one expression, so y_train.values.shape[1] != 1.","commonSituations":"Reusing a multi-label handler config from another model with the high-frequency workflow; adding auxiliary label columns for analysis.","solutions":["Configure exactly one label expression in the data handler","Move any extra targets into features or pick a multi-output-capable model"],"exampleFix":"# before\nlabel: [\"Ref($close, -2)/Ref($close, -1) - 1\", \"$vwap/$close - 1\"]\n\n# after\nlabel: [\"Ref($close, -2)/Ref($close, -1) - 1\"]","handlingStrategy":"validation","validationCode":"y = dataset.prepare(\"train\", col_set=\"label\", data_key=\"learn\")\nassert y.values.ndim == 2 and y.values.shape[1] == 1, \"HFMLGBModel needs a single label column to build the binary target\"","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Single label expression in high-frequency handler configs","The label is binarized internally (up/down by sign), so extra label columns are meaningless here anyway"],"tags":["high-frequency","lightgbm","multi-label","qlib"],"backgroundTag":null,"analyzedSha":"79633dd9506ea689e5400dea0197717b5b3d74b7","analyzedAt":"2026-08-15T07:01:27.511Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}