Skip to content

LightGBM error when using UseCat with count Feature selection #3659

Closed

Description

Issue

version: 0.11

  • What did you do?
  1. I trained a LightGBM multi-class classifier with UseCat to true.
  2. I added a SelectFeaturesBasedOnCount on the final Features.

If it matters: I also use early stopping (does this prune some trees?).

  • What happened?

I got an exception after training was done (successfully) and ML.NET tries to construct the InternalRegressionTree:

System.InvalidOperationException: 'Categorical split features is zero length'

Stack

>	Microsoft.ML.Core.dll!Microsoft.ML.Contracts.Check(bool f, string msg) Line 491	C#
 	Microsoft.ML.FastTree.dll!Microsoft.ML.Trainers.FastTree.InternalRegressionTree.CheckValid(System.Action<bool, string> checker) Line 471	C#
 	Microsoft.ML.FastTree.dll!Microsoft.ML.Trainers.FastTree.InternalRegressionTree.InternalRegressionTree(int[] splitFeatures, double[] splitGain, double[] gainPValue, float[] rawThresholds, float[] defaultValueForMissing, int[] lteChild, int[] gtChild, double[] leafValues, int[][] categoricalSplitFeatures, bool[] categoricalSplit) Line 224	C#
 	Microsoft.ML.FastTree.dll!Microsoft.ML.Trainers.FastTree.InternalRegressionTree.Create(int numLeaves, int[] splitFeatures, double[] splitGain, float[] rawThresholds, float[] defaultValueForMissing, int[] lteChild, int[] gtChild, double[] leafValues, int[][] categoricalSplitFeatures, bool[] categoricalSplit) Line 188	C#
 	Microsoft.ML.LightGBM.dll!Microsoft.ML.LightGBM.Booster.GetModel(int[] categoricalFeatureBoudaries) Line 257	C#
 	Microsoft.ML.LightGBM.dll!Microsoft.ML.LightGBM.LightGbmTrainerBase<Microsoft.ML.Data.VBuffer<float>, Microsoft.ML.Data.MulticlassPredictionTransformer<Microsoft.ML.Trainers.OvaModelParameters>, Microsoft.ML.Trainers.OvaModelParameters>.TrainCore(Microsoft.ML.IChannel ch, Microsoft.ML.IProgressChannel pch, Microsoft.ML.LightGBM.Dataset dtrain, Microsoft.ML.LightGBM.LightGbmTrainerBase<Microsoft.ML.Data.VBuffer<float>, Microsoft.ML.Data.MulticlassPredictionTransformer<Microsoft.ML.Trainers.OvaModelParameters>, Microsoft.ML.Trainers.OvaModelParameters>.CategoricalMetaData catMetaData, Microsoft.ML.LightGBM.Dataset dvalid) Line 375	C#
 	Microsoft.ML.LightGBM.dll!Microsoft.ML.LightGBM.LightGbmTrainerBase<Microsoft.ML.Data.VBuffer<float>, Microsoft.ML.Data.MulticlassPredictionTransformer<Microsoft.ML.Trainers.OvaModelParameters>, Microsoft.ML.Trainers.OvaModelParameters>.TrainModelCore(Microsoft.ML.TrainContext context) Line 117	C#
 	Microsoft.ML.Data.dll!Microsoft.ML.Trainers.TrainerEstimatorBase<Microsoft.ML.Data.MulticlassPredictionTransformer<Microsoft.ML.Trainers.OvaModelParameters>, Microsoft.ML.Trainers.OvaModelParameters>.TrainTransformer(Microsoft.Data.DataView.IDataView trainSet, Microsoft.Data.DataView.IDataView validationSet, Microsoft.ML.IPredictor initPredictor) Line 148	C#
 	MlnEval.exe!ConsoleApp1.MlNetSpecific.MlNetLightGbmMultiClassTrainer.TrainAndEval(ConsoleApp1.Dev.AppState app) Line 107	C#
 	MlnEval.exe!ConsoleApp1.Program.Main(string[] args) Line 116	C#

Unfortunately I failed to come up with a minimal reproducible example. Seems this requires a certain data setup.

Partial analysis

It looks like here:

if (GetIsCategoricalSplit(decisionType[node]))
{
int catIdx = (int)threshold[node];
var cats = GetCatThresholds(catThreshold, catBoundaries[catIdx], catBoundaries[catIdx + 1]);
categoricalSplitFeatures[node] = new int[cats.Length];
// Convert Cat thresholds to feature indices.
for (int j = 0; j < cats.Length; ++j)
categoricalSplitFeatures[node][j] = splitFeature[node] + cats[j] - 1;
splitFeature[node] = -1;
categoricalSplit[node] = true;
// Swap left and right child.
int t = leftChild[node];
leftChild[node] = rightChild[node];
rightChild[node] = t;
}

cats array is actually 0 length but categoricalSplit[node] is still set to true.

which then later on will throw here:

if (CategoricalSplit[index])
{
checker(CategoricalSplitFeatures[index] != null, "Categorical split features is null");
checker(CategoricalSplitFeatures[index].Length > 0,
"Categorical split features is zero length");

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

Labels

P0Priority of the issue for triage purpose: IMPORTANT, needs to be fixed right away.bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions