From 43be3168f4f040385ec9e84f9f4d2fdde6a08640 Mon Sep 17 00:00:00 2001 From: Wei-Sheng Chin Date: Fri, 1 Mar 2019 14:38:21 -0800 Subject: [PATCH] Make accessor of linear coefficients unique to the public (#2807) * Make accessor of linear coefficients unique to the public 1. Internalize GetFeatureWeights(ref VBuffer weights) 2. Internalize IHaveFeatureWeights * Fix typo --- .../Dynamic/FeatureContributionCalculationTransform.cs | 5 ++--- .../samples/Microsoft.ML.Samples/Static/SDCARegression.cs | 8 +++----- src/Microsoft.ML.Data/Dirty/PredictorInterfaces.cs | 3 ++- .../SymSgdClassificationTrainer.cs | 2 +- .../Standard/LinearModelParameters.cs | 3 +-- .../Standard/ModelStatistics.cs | 2 +- .../Standard/Online/OnlineLinear.cs | 3 ++- src/Microsoft.ML.StandardLearners/Standard/SdcaBinary.cs | 2 +- test/Microsoft.ML.StaticPipelineTesting/Training.cs | 8 ++------ .../Scenarios/Api/Estimators/IntrospectiveTraining.cs | 3 +-- 10 files changed, 16 insertions(+), 23 deletions(-) diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/FeatureContributionCalculationTransform.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/FeatureContributionCalculationTransform.cs index b238fa7efc..541e708cf7 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/FeatureContributionCalculationTransform.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/FeatureContributionCalculationTransform.cs @@ -44,8 +44,7 @@ public static void Example() var outData = featureContributionCalculator.Fit(scoredData).Transform(scoredData); // Let's extract the weights from the linear model to use as a comparison - var weights = new VBuffer(); - model.Model.GetFeatureWeights(ref weights); + var weights = model.Model.Weights; // Let's now walk through the first ten records and see which feature drove the values the most // Get prediction scores and contributions @@ -63,7 +62,7 @@ public static void Example() var value = row.Features[featureOfInterest]; var contribution = row.FeatureContributions[featureOfInterest]; var name = data.Schema[featureOfInterest + 1].Name; - var weight = weights.GetValues()[featureOfInterest]; + var weight = weights[featureOfInterest]; Console.WriteLine("{0:0.00}\t{1:0.00}\t{2}\t{3:0.00}\t{4:0.00}\t{5:0.00}", row.MedianHomeValue, diff --git a/docs/samples/Microsoft.ML.Samples/Static/SDCARegression.cs b/docs/samples/Microsoft.ML.Samples/Static/SDCARegression.cs index 0ff84068dd..09da261fb6 100644 --- a/docs/samples/Microsoft.ML.Samples/Static/SDCARegression.cs +++ b/docs/samples/Microsoft.ML.Samples/Static/SDCARegression.cs @@ -46,12 +46,10 @@ public static void SdcaRegression() var model = learningPipeline.Fit(trainData); // Check the weights that the model learned - VBuffer weights = default; - pred.GetFeatureWeights(ref weights); + var weights = pred.Weights; - var weightsValues = weights.GetValues(); - Console.WriteLine($"weight 0 - {weightsValues[0]}"); - Console.WriteLine($"weight 1 - {weightsValues[1]}"); + Console.WriteLine($"weight 0 - {weights[0]}"); + Console.WriteLine($"weight 1 - {weights[1]}"); // Evaluate how the model is doing on the test data var dataWithPredictions = model.Transform(testData); diff --git a/src/Microsoft.ML.Data/Dirty/PredictorInterfaces.cs b/src/Microsoft.ML.Data/Dirty/PredictorInterfaces.cs index ec91ff9108..594be3bf86 100644 --- a/src/Microsoft.ML.Data/Dirty/PredictorInterfaces.cs +++ b/src/Microsoft.ML.Data/Dirty/PredictorInterfaces.cs @@ -146,7 +146,8 @@ internal interface ICanSaveInSourceCode /// /// Interface implemented by components that can assign weights to features. /// - public interface IHaveFeatureWeights + [BestFriend] + internal interface IHaveFeatureWeights { /// /// Returns the weights for the features. diff --git a/src/Microsoft.ML.HalLearners/SymSgdClassificationTrainer.cs b/src/Microsoft.ML.HalLearners/SymSgdClassificationTrainer.cs index 14da40b3a9..009e6efd1e 100644 --- a/src/Microsoft.ML.HalLearners/SymSgdClassificationTrainer.cs +++ b/src/Microsoft.ML.HalLearners/SymSgdClassificationTrainer.cs @@ -671,7 +671,7 @@ private TPredictor TrainCore(IChannel ch, RoleMappedData data, LinearModelParame float bias = 0.0f; if (predictor != null) { - predictor.GetFeatureWeights(ref weights); + ((IHaveFeatureWeights)predictor).GetFeatureWeights(ref weights); VBufferUtils.Densify(ref weights); bias = predictor.Bias; } diff --git a/src/Microsoft.ML.StandardLearners/Standard/LinearModelParameters.cs b/src/Microsoft.ML.StandardLearners/Standard/LinearModelParameters.cs index 3b56c40106..17c1eadc36 100644 --- a/src/Microsoft.ML.StandardLearners/Standard/LinearModelParameters.cs +++ b/src/Microsoft.ML.StandardLearners/Standard/LinearModelParameters.cs @@ -11,7 +11,6 @@ using Microsoft.ML; using Microsoft.ML.Calibrators; using Microsoft.ML.Data; -using Microsoft.ML.Internal.Internallearn; using Microsoft.ML.Internal.Utilities; using Microsoft.ML.Model; using Microsoft.ML.Model.OnnxConverter; @@ -384,7 +383,7 @@ private protected virtual DataViewRow GetSummaryIRowOrNull(RoleMappedSchema sche void ICanSaveInIniFormat.SaveAsIni(TextWriter writer, RoleMappedSchema schema, ICalibrator calibrator) => SaveAsIni(writer, schema, calibrator); - public void GetFeatureWeights(ref VBuffer weights) + void IHaveFeatureWeights.GetFeatureWeights(ref VBuffer weights) { Weight.CopyTo(ref weights); } diff --git a/src/Microsoft.ML.StandardLearners/Standard/ModelStatistics.cs b/src/Microsoft.ML.StandardLearners/Standard/ModelStatistics.cs index 79f6a0dfa1..dae648acf5 100644 --- a/src/Microsoft.ML.StandardLearners/Standard/ModelStatistics.cs +++ b/src/Microsoft.ML.StandardLearners/Standard/ModelStatistics.cs @@ -438,7 +438,7 @@ internal DataViewSchema.Annotations MakeStatisticsMetadata(LinearBinaryModelPara builder.AddPrimitiveValue("BiasPValue", NumberDataViewType.Single, biasPValue); var weights = default(VBuffer); - parent.GetFeatureWeights(ref weights); + ((IHaveFeatureWeights)parent).GetFeatureWeights(ref weights); var estimate = default(VBuffer); var stdErr = default(VBuffer); var zScore = default(VBuffer); diff --git a/src/Microsoft.ML.StandardLearners/Standard/Online/OnlineLinear.cs b/src/Microsoft.ML.StandardLearners/Standard/Online/OnlineLinear.cs index ad571155de..803eff6afb 100644 --- a/src/Microsoft.ML.StandardLearners/Standard/Online/OnlineLinear.cs +++ b/src/Microsoft.ML.StandardLearners/Standard/Online/OnlineLinear.cs @@ -10,6 +10,7 @@ using Microsoft.ML.EntryPoints; using Microsoft.ML.Internal.Internallearn; using Microsoft.ML.Internal.Utilities; +using Microsoft.ML.Model; using Microsoft.ML.Numeric; namespace Microsoft.ML.Trainers @@ -130,7 +131,7 @@ protected TrainStateBase(IChannel ch, int numFeatures, LinearModelParameters pre // unless we have a lot of features. if (predictor != null) { - predictor.GetFeatureWeights(ref Weights); + ((IHaveFeatureWeights)predictor).GetFeatureWeights(ref Weights); VBufferUtils.Densify(ref Weights); Bias = predictor.Bias; } diff --git a/src/Microsoft.ML.StandardLearners/Standard/SdcaBinary.cs b/src/Microsoft.ML.StandardLearners/Standard/SdcaBinary.cs index 9c1c628101..7e1526c1c2 100644 --- a/src/Microsoft.ML.StandardLearners/Standard/SdcaBinary.cs +++ b/src/Microsoft.ML.StandardLearners/Standard/SdcaBinary.cs @@ -1937,7 +1937,7 @@ private protected override TModel TrainCore(IChannel ch, RoleMappedData data, Li float bias = 0.0f; if (predictor != null) { - predictor.GetFeatureWeights(ref weights); + ((IHaveFeatureWeights)predictor).GetFeatureWeights(ref weights); VBufferUtils.Densify(ref weights); bias = predictor.Bias; } diff --git a/test/Microsoft.ML.StaticPipelineTesting/Training.cs b/test/Microsoft.ML.StaticPipelineTesting/Training.cs index afdd2d368e..85aa462334 100644 --- a/test/Microsoft.ML.StaticPipelineTesting/Training.cs +++ b/test/Microsoft.ML.StaticPipelineTesting/Training.cs @@ -627,9 +627,7 @@ public void PoissonRegression() var model = pipe.Fit(dataSource); Assert.NotNull(pred); // 11 input features, so we ought to have 11 weights. - VBuffer weights = new VBuffer(); - pred.GetFeatureWeights(ref weights); - Assert.Equal(11, weights.Length); + Assert.Equal(11, pred.Weights.Count); var data = model.Load(dataSource); @@ -751,9 +749,7 @@ public void OnlineGradientDescent() var model = pipe.Fit(dataSource); Assert.NotNull(pred); // 11 input features, so we ought to have 11 weights. - VBuffer weights = new VBuffer(); - pred.GetFeatureWeights(ref weights); - Assert.Equal(11, weights.Length); + Assert.Equal(11, pred.Weights.Count); var data = model.Load(dataSource); diff --git a/test/Microsoft.ML.Tests/Scenarios/Api/Estimators/IntrospectiveTraining.cs b/test/Microsoft.ML.Tests/Scenarios/Api/Estimators/IntrospectiveTraining.cs index 2900ecf425..e82545cd34 100644 --- a/test/Microsoft.ML.Tests/Scenarios/Api/Estimators/IntrospectiveTraining.cs +++ b/test/Microsoft.ML.Tests/Scenarios/Api/Estimators/IntrospectiveTraining.cs @@ -42,8 +42,7 @@ public void IntrospectiveTraining() var model = pipeline.Fit(data); // Get feature weights. - VBuffer weights = default; - model.LastTransformer.Model.GetFeatureWeights(ref weights); + var weights = model.LastTransformer.Model.Weights; } [Fact]