Skip to content

Commit bc8d278

Browse files
authored
Stabilize SDCA logistic regression test (#7677)
The strict SdcaLogisticRegression quality assertions now use a single training thread, making their results deterministic. A separate four-thread test retains correctness coverage of SDCA's nondeterministic parallel path by preserving the original AUC requirement and verifying that its LogLoss outperforms a featureless Prior baseline. My theory is that the macOS arm64 runners have more threads than the Windows/Linux runners which leads to more non-determinism, triggering the flaky failure.
1 parent e294266 commit bc8d278

1 file changed

Lines changed: 46 additions & 1 deletion

File tree

‎test/Microsoft.ML.Tests/TrainerEstimators/SdcaTests.cs‎

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,14 @@ public void SdcaLogisticRegression()
7272

7373
// Step 2: Create a binary classifier.
7474
// We set the "Label" column as the label of the dataset, and the "Features" column as the features column.
75-
var pipeline = mlContext.BinaryClassification.Trainers.SdcaLogisticRegression(labelColumnName: "Label", featureColumnName: "Features", l2Regularization: 0.001f);
75+
var pipeline = mlContext.BinaryClassification.Trainers.SdcaLogisticRegression(
76+
new SdcaLogisticRegressionBinaryTrainer.Options
77+
{
78+
LabelColumnName = "Label",
79+
FeatureColumnName = "Features",
80+
L2Regularization = 0.001f,
81+
NumberOfThreads = 1
82+
});
7683

7784
// Step 3: Train the pipeline created.
7885
var model = pipeline.Fit(data);
@@ -97,6 +104,44 @@ public void SdcaLogisticRegression()
97104
Assert.InRange(first.Probability, 0.8, 1);
98105
}
99106

107+
[Fact]
108+
public void SdcaLogisticRegressionMultithreaded()
109+
{
110+
// Keep coverage of the nondeterministic parallel path while the quality test above remains deterministic.
111+
// See https://github.com/dotnet/machinelearning/blob/240a849becda954f3e17d39f7606328be3a7f0de/src/Microsoft.ML.StandardTrainers/Standard/SdcaBinary.cs#L180-L188.
112+
113+
// Generate C# objects as training examples.
114+
var rawData = SamplesUtils.DatasetUtils.GenerateBinaryLabelFloatFeatureVectorFloatWeightSamples(100);
115+
116+
// Create a new context for ML.NET operations.
117+
var mlContext = new MLContext(1);
118+
119+
// Step 1: Read and cache the data as an IDataView.
120+
var data = mlContext.Data.Cache(mlContext.Data.LoadFromEnumerable(rawData));
121+
122+
// Step 2: Create a binary classifier that exercises the parallel training path.
123+
var pipeline = mlContext.BinaryClassification.Trainers.SdcaLogisticRegression(
124+
new SdcaLogisticRegressionBinaryTrainer.Options
125+
{
126+
LabelColumnName = "Label",
127+
FeatureColumnName = "Features",
128+
L2Regularization = 0.001f,
129+
NumberOfThreads = 4
130+
});
131+
132+
// Step 3: Train and evaluate the classifier on the training data.
133+
var transformedData = pipeline.Fit(data).Transform(data);
134+
var metrics = mlContext.BinaryClassification.Evaluate(transformedData);
135+
136+
// Step 4: Evaluate a featureless classifier as a quality baseline.
137+
var priorModel = mlContext.BinaryClassification.Trainers.Prior().Fit(data);
138+
var priorMetrics = mlContext.BinaryClassification.Evaluate(priorModel.Transform(data));
139+
140+
// Verify the multithreaded classifier learns the signal in the generated data.
141+
Assert.InRange(metrics.AreaUnderRocCurve, 0.9, 1);
142+
Assert.True(metrics.LogLoss < priorMetrics.LogLoss);
143+
}
144+
100145
[Fact]
101146
public void SdcaLogisticRegressionWithWeight()
102147
{

0 commit comments

Comments
 (0)