From b57261463288e5089da7536ddc1e167dc71da1bd Mon Sep 17 00:00:00 2001 From: "REDMOND\\nakazmi" Date: Tue, 19 Feb 2019 23:19:02 -0800 Subject: [PATCH 01/24] Adding a sample for LightGbm Ranking --- ...LightGBMBinaryClassificationWithOptions.cs | 1 - .../Trainers/Ranking/LightGBMRanking.cs | 42 +++++++++++++++ .../Ranking/LightGBMRankingWithOptions.cs | 44 ++++++++++++++++ docs/samples/Microsoft.ML.Samples/Program.cs | 2 +- .../Evaluators/Metrics/RankerMetrics.cs | 2 +- src/Microsoft.ML.SamplesUtils/ConsoleUtils.cs | 11 ++++ .../SamplesDatasetUtils.cs | 51 +++++++++++++++++++ 7 files changed, 150 insertions(+), 3 deletions(-) create mode 100644 docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Ranking/LightGBMRanking.cs create mode 100644 docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Ranking/LightGBMRankingWithOptions.cs diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/LightGBMBinaryClassificationWithOptions.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/LightGBMBinaryClassificationWithOptions.cs index 20924bc29f..904285aaee 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/LightGBMBinaryClassificationWithOptions.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/LightGBMBinaryClassificationWithOptions.cs @@ -1,5 +1,4 @@ using Microsoft.ML.LightGBM; -using Microsoft.ML.Transforms.Categorical; using static Microsoft.ML.LightGBM.Options; namespace Microsoft.ML.Samples.Dynamic diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Ranking/LightGBMRanking.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Ranking/LightGBMRanking.cs new file mode 100644 index 0000000000..8822a16630 --- /dev/null +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Ranking/LightGBMRanking.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Microsoft.ML.Samples.Dynamic +{ + public class LightGbmRanking + { + // This example requires installation of additional nuget package Microsoft.ML.LightGBM. + public static void Example() + { + // Creating the ML.Net IHostEnvironment object, needed for the pipeline. + var mlContext = new MLContext(); + + // Download and featurize the train and validation datasets. + (var trainData, var validationData) = SamplesUtils.DatasetUtils.LoadFeaturizedMslrWeb10kTrainAndValidate(mlContext); + + // Create the Estimator pipeline. For simplicity, we will train a small tree with 4 leaves and 2 boosting iterations. + var pipeline = mlContext.Ranking.Trainers.LightGbm( + labelColumn: "Label", + featureColumn: "Features", + groupIdColumn: "GroupId", + numLeaves: 4, + minDataPerLeaf: 10, + learningRate: 0.1, + numBoostRound: 2); + + // Fit this Pipeline to the Training Data. + var model = pipeline.Fit(trainData); + + // Evaluate how the model is doing on the test data. + var dataWithPredictions = model.Transform(validationData); + + var metrics = mlContext.Ranking.Evaluate(dataWithPredictions, "Label", "GroupId"); + SamplesUtils.ConsoleUtils.PrintMetrics(metrics); + + // Output: + // DCG @N: 1.38, 3.11, 4.94 + // NDCG @N: 7.13, 10.12, 12.62 + } + } +} diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Ranking/LightGBMRankingWithOptions.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Ranking/LightGBMRankingWithOptions.cs new file mode 100644 index 0000000000..d8f3da41ea --- /dev/null +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Ranking/LightGBMRankingWithOptions.cs @@ -0,0 +1,44 @@ +using Microsoft.ML.LightGBM; +using static Microsoft.ML.LightGBM.Options; + +namespace Microsoft.ML.Samples.Dynamic +{ + public class LightGbmRankingWithOptions + { + // This example requires installation of additional nuget package Microsoft.ML.LightGBM. + public static void Example() + { + // Creating the ML.Net IHostEnvironment object, needed for the pipeline. + var mlContext = new MLContext(); + + // Download and featurize the train and validation datasets. + (var trainData, var validationData) = SamplesUtils.DatasetUtils.LoadFeaturizedMslrWeb10kTrainAndValidate(mlContext); + + // Create the Estimator pipeline. For simplicity, we will train a small tree with 4 leaves and 2 boosting iterations. + var pipeline = mlContext.Ranking.Trainers.LightGbm( + new Options + { + LabelColumn = "Label", + FeatureColumn = "Features", + GroupIdColumn = "GroupId", + NumLeaves = 4, + MinDataPerLeaf = 10, + LearningRate = 0.1, + NumBoostRound = 2 + }); + + // Fit this Pipeline to the Training Data. + var model = pipeline.Fit(trainData); + + // Evaluate how the model is doing on the test data. + var dataWithPredictions = model.Transform(validationData); + + var metrics = mlContext.Ranking.Evaluate(dataWithPredictions, "Label", "GroupId"); + SamplesUtils.ConsoleUtils.PrintMetrics(metrics); + + // Output: + // DCG @N: 1.38, 3.11, 4.94 + // NDCG @N: 7.13, 10.12, 12.62 + } + } +} diff --git a/docs/samples/Microsoft.ML.Samples/Program.cs b/docs/samples/Microsoft.ML.Samples/Program.cs index d28cdd4d77..6fa4e40705 100644 --- a/docs/samples/Microsoft.ML.Samples/Program.cs +++ b/docs/samples/Microsoft.ML.Samples/Program.cs @@ -6,7 +6,7 @@ internal static class Program { static void Main(string[] args) { - TakeRows.Example(); + LightGbmRanking.Example(); } } } diff --git a/src/Microsoft.ML.Data/Evaluators/Metrics/RankerMetrics.cs b/src/Microsoft.ML.Data/Evaluators/Metrics/RankerMetrics.cs index b9532fd31b..d3b9ef685f 100644 --- a/src/Microsoft.ML.Data/Evaluators/Metrics/RankerMetrics.cs +++ b/src/Microsoft.ML.Data/Evaluators/Metrics/RankerMetrics.cs @@ -18,7 +18,7 @@ public sealed class RankerMetrics ///Array of discounted cumulative gains where i-th element represent DCG@i. /// Discounted Cumulative gain /// is the sum of the gains, for all the instances i, normalized by the natural logarithm of the instance + 1. - /// Note that unline the Wikipedia article, ML.Net uses the natural logarithm. + /// Note that unlike the Wikipedia article, ML.Net uses the natural logarithm. /// /// public double[] Dcg { get; } diff --git a/src/Microsoft.ML.SamplesUtils/ConsoleUtils.cs b/src/Microsoft.ML.SamplesUtils/ConsoleUtils.cs index 93de658b1e..7c40d9a4c8 100644 --- a/src/Microsoft.ML.SamplesUtils/ConsoleUtils.cs +++ b/src/Microsoft.ML.SamplesUtils/ConsoleUtils.cs @@ -1,4 +1,5 @@ using System; +using System.Linq; using Microsoft.ML.Data; namespace Microsoft.ML.SamplesUtils @@ -35,5 +36,15 @@ public static void PrintMetrics(RegressionMetrics metrics) Console.WriteLine($"RMS: {metrics.Rms:F2}"); Console.WriteLine($"RSquared: {metrics.RSquared:F2}"); } + + /// + /// Pretty-print RankerMetrics objects. + /// + /// Ranker metrics. + public static void PrintMetrics(RankerMetrics metrics) + { + Console.WriteLine($"DCG@N: {string.Join(", ", metrics.Dcg.Select(d => Math.Round(d, 2)).ToArray())}"); + Console.WriteLine($"NDCG@N: {string.Join(", ", metrics.Ndcg.Select(d => Math.Round(d, 2)).ToArray())}"); + } } } diff --git a/src/Microsoft.ML.SamplesUtils/SamplesDatasetUtils.cs b/src/Microsoft.ML.SamplesUtils/SamplesDatasetUtils.cs index 203bd6e6bd..a40212b0e6 100644 --- a/src/Microsoft.ML.SamplesUtils/SamplesDatasetUtils.cs +++ b/src/Microsoft.ML.SamplesUtils/SamplesDatasetUtils.cs @@ -146,6 +146,57 @@ public static IDataView LoadFeaturizedAdultDataset(MLContext mlContext) return featurizedData; } + public static string DownloadMslrWeb10kTrain() + { + var fileName = "MSLRWeb10KTrain720kRows.tsv"; + if (!File.Exists(fileName)) + Download("https://tlcresources.blob.core.windows.net/datasets/MSLR-WEB10K/MSLR-WEB10K_Fold1.TRAIN.500MB_720k-rows.tsv", fileName); + return fileName; + } + + public static string DownloadMslrWeb10kValidate() + { + var fileName = "MSLRWeb10KValidate240kRows.tsv"; + if (!File.Exists(fileName)) + Download("https://tlcresources.blob.core.windows.net/datasets/MSLR-WEB10K/MSLR-WEB10K_Fold1.VALIDATE.160MB_240k-rows.tsv", fileName); + return fileName; + } + + public static (IDataView, IDataView) LoadFeaturizedMslrWeb10kTrainAndValidate(MLContext mlContext) + { + // Download the training and validation files. + string trainDataFile = DownloadMslrWeb10kTrain(); + string validationDataFile = DownloadMslrWeb10kValidate(); + + // Create the reader to read the data. + var reader = mlContext.Data.CreateTextLoader( + columns: new[] + { + new TextLoader.Column("Label", DataKind.R4, 0), + new TextLoader.Column("GroupId", DataKind.TX, 1), + new TextLoader.Column("Features", DataKind.R4, new[] { new TextLoader.Range(2, 138) }) + } + ); + + // Load the raw training and validation datasets. + var trainData = reader.Read(trainDataFile); + var validationData = reader.Read(validationDataFile); + + // Create the featurization pipeline. First, hash the GroupId column. + var pipeline = mlContext.Transforms.Conversion.Hash("GroupId") + // Replace missing values in Features column with the default replacement value for its type. + .Append(mlContext.Transforms.ReplaceMissingValues("Features")); + + // Fit the pipeline on the training data. + var fittedPipeline = pipeline.Fit(trainData); + + // Use the fitted pipeline to transform the training and validation datasets. + var transformedTrainData = fittedPipeline.Transform(trainData); + var transformedValidationData = fittedPipeline.Transform(validationData); + + return (transformedTrainData, transformedValidationData); + } + /// /// Downloads the breast cancer dataset from the ML.NET repo. /// From f3d5d82ef1c1524f9d9f95c597ca40f52863a176 Mon Sep 17 00:00:00 2001 From: "REDMOND\\nakazmi" Date: Fri, 22 Feb 2019 18:19:12 -0800 Subject: [PATCH 02/24] PR feedback + cleaning up namespaces in Microsoft.ML.Samples project --- .../LightGBMBinaryClassification.cs | 24 +++++++------- ...LightGBMBinaryClassificationWithOptions.cs | 24 +++++++------- .../SDCALogisticRegression.cs | 2 +- .../SDCASupportVectorMachine.cs | 2 +- .../SymbolicStochasticGradientDescent.cs | 20 ++++++------ ...licStochasticGradientDescentWithOptions.cs | 21 ++++++------ .../LightGBMMulticlassClassification.cs | 4 +-- ...tGBMMulticlassClassificationWithOptions.cs | 4 +-- .../Trainers/Ranking/LightGBMRanking.cs | 30 ++++++++--------- .../Ranking/LightGBMRankingWithOptions.cs | 27 ++++++++-------- .../Recommendation/MatrixFactorization.cs | 2 +- .../MatrixFactorizationWithOptions.cs | 2 +- .../Trainers/Regression/LightGBMRegression.cs | 16 +++++----- .../LightGBMRegressionWithOptions.cs | 16 +++++----- .../Regression/OrdinaryLeastSquares.cs | 14 ++++---- .../OrdinaryLeastSquaresWithOptions.cs | 14 ++++---- docs/samples/Microsoft.ML.Samples/Program.cs | 2 +- .../Evaluators/Metrics/RankerMetrics.cs | 4 +-- src/Microsoft.ML.SamplesUtils/ConsoleUtils.cs | 14 ++++++-- .../SamplesDatasetUtils.cs | 32 ++++++------------- 20 files changed, 138 insertions(+), 136 deletions(-) diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/LightGBMBinaryClassification.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/LightGBMBinaryClassification.cs index edd4e31504..a6834d0082 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/LightGBMBinaryClassification.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/LightGBMBinaryClassification.cs @@ -1,8 +1,8 @@ using Microsoft.ML.Transforms.Categorical; -namespace Microsoft.ML.Samples.Dynamic +namespace Microsoft.ML.Samples.Dynamic.Trainers.BinaryClassification { - public class LightGbmBinaryClassification + public class LightGbm { // This example requires installation of additional nuget package Microsoft.ML.LightGBM. public static void Example() @@ -17,7 +17,7 @@ public static void Example() var split = mlContext.BinaryClassification.TrainTestSplit(dataview, testFraction: 0.1); // Create the Estimator. - var pipeline = mlContext.BinaryClassification.Trainers.LightGbm("IsOver50K", "Features"); + var pipeline = mlContext.BinaryClassification.Trainers.LightGbm(); // Fit this Pipeline to the Training Data. var model = pipeline.Fit(split.TrainSet); @@ -25,17 +25,17 @@ public static void Example() // Evaluate how the model is doing on the test data. var dataWithPredictions = model.Transform(split.TestSet); - var metrics = mlContext.BinaryClassification.Evaluate(dataWithPredictions, "IsOver50K"); + var metrics = mlContext.BinaryClassification.Evaluate(dataWithPredictions); SamplesUtils.ConsoleUtils.PrintMetrics(metrics); - // Output: - // Accuracy: 0.88 - // AUC: 0.93 - // F1 Score: 0.71 - // Negative Precision: 0.90 - // Negative Recall: 0.94 - // Positive Precision: 0.76 - // Positive Recall: 0.66 + // Expected output: + // Accuracy: 0.88 + // AUC: 0.93 + // F1 Score: 0.71 + // Negative Precision: 0.90 + // Negative Recall: 0.94 + // Positive Precision: 0.76 + // Positive Recall: 0.66 } } } \ No newline at end of file diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/LightGBMBinaryClassificationWithOptions.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/LightGBMBinaryClassificationWithOptions.cs index 904285aaee..7b0e21fed9 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/LightGBMBinaryClassificationWithOptions.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/LightGBMBinaryClassificationWithOptions.cs @@ -1,9 +1,9 @@ using Microsoft.ML.LightGBM; using static Microsoft.ML.LightGBM.Options; -namespace Microsoft.ML.Samples.Dynamic +namespace Microsoft.ML.Samples.Dynamic.Trainers.BinaryClassification { - class LightGbmBinaryClassificationWithOptions + class LightGbmWithOptions { // This example requires installation of additional nuget package Microsoft.ML.LightGBM. public static void Example() @@ -21,8 +21,6 @@ public static void Example() var pipeline = mlContext.BinaryClassification.Trainers.LightGbm( new Options { - LabelColumn = "IsOver50K", - FeatureColumn = "Features", Booster = new GossBooster.Options { TopRate = 0.3, @@ -36,17 +34,17 @@ public static void Example() // Evaluate how the model is doing on the test data. var dataWithPredictions = model.Transform(split.TestSet); - var metrics = mlContext.BinaryClassification.Evaluate(dataWithPredictions, "IsOver50K"); + var metrics = mlContext.BinaryClassification.Evaluate(dataWithPredictions); SamplesUtils.ConsoleUtils.PrintMetrics(metrics); - // Output: - // Accuracy: 0.88 - // AUC: 0.93 - // F1 Score: 0.71 - // Negative Precision: 0.90 - // Negative Recall: 0.94 - // Positive Precision: 0.76 - // Positive Recall: 0.67 + // Expected output: + // Accuracy: 0.88 + // AUC: 0.93 + // F1 Score: 0.71 + // Negative Precision: 0.90 + // Negative Recall: 0.94 + // Positive Precision: 0.76 + // Positive Recall: 0.67 } } } diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/SDCALogisticRegression.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/SDCALogisticRegression.cs index 3ab3257638..da12242ce4 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/SDCALogisticRegression.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/SDCALogisticRegression.cs @@ -3,7 +3,7 @@ using Microsoft.ML.Data; using Microsoft.ML.Trainers; -namespace Microsoft.ML.Samples.Dynamic +namespace Microsoft.ML.Samples.Dynamic.Trainers.BinaryClassification { public static class SDCALogisticRegression { diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/SDCASupportVectorMachine.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/SDCASupportVectorMachine.cs index d37c1cec1a..0730e3daee 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/SDCASupportVectorMachine.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/SDCASupportVectorMachine.cs @@ -2,7 +2,7 @@ using System.Linq; using Microsoft.ML.Data; -namespace Microsoft.ML.Samples.Dynamic +namespace Microsoft.ML.Samples.Dynamic.Trainers.BinaryClassification { public static class SDCASupportVectorMachine { diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/SymbolicStochasticGradientDescent.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/SymbolicStochasticGradientDescent.cs index 49b31342e0..dcdd331ab5 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/SymbolicStochasticGradientDescent.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/SymbolicStochasticGradientDescent.cs @@ -1,4 +1,4 @@ -namespace Microsoft.ML.Samples.Dynamic +namespace Microsoft.ML.Samples.Dynamic.Trainers.BinaryClassification { public static class SymbolicStochasticGradientDescent { @@ -24,15 +24,17 @@ public static void Example() // Evaluate how the model is doing on the test data. var dataWithPredictions = model.Transform(split.TestSet); - var metrics = mlContext.BinaryClassification.EvaluateNonCalibrated(dataWithPredictions, "IsOver50K"); + var metrics = mlContext.BinaryClassification.EvaluateNonCalibrated(dataWithPredictions); SamplesUtils.ConsoleUtils.PrintMetrics(metrics); - // Accuracy: 0.85 - // AUC: 0.90 - // F1 Score: 0.64 - // Negative Precision: 0.88 - // Negative Recall: 0.93 - // Positive Precision: 0.72 - // Positive Recall: 0.58 + + // Expected output: + // Accuracy: 0.85 + // AUC: 0.90 + // F1 Score: 0.64 + // Negative Precision: 0.88 + // Negative Recall: 0.93 + // Positive Precision: 0.72 + // Positive Recall: 0.58 } } } diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/SymbolicStochasticGradientDescentWithOptions.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/SymbolicStochasticGradientDescentWithOptions.cs index d05d64454c..e4363f29cc 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/SymbolicStochasticGradientDescentWithOptions.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/SymbolicStochasticGradientDescentWithOptions.cs @@ -1,4 +1,4 @@ -namespace Microsoft.ML.Samples.Dynamic +namespace Microsoft.ML.Samples.Dynamic.Trainers.BinaryClassification { public static class SymbolicStochasticGradientDescentWithOptions { @@ -22,7 +22,6 @@ public static void Example() var pipeline = mlContext.BinaryClassification.Trainers.SymbolicStochasticGradientDescent( new ML.Trainers.HalLearners.SymSgdClassificationTrainer.Options() { - LabelColumn = "IsOver50K", LearningRate = 0.2f, NumberOfIterations = 10, NumberOfThreads = 1, @@ -33,15 +32,17 @@ public static void Example() // Evaluate how the model is doing on the test data. var dataWithPredictions = model.Transform(split.TestSet); - var metrics = mlContext.BinaryClassification.EvaluateNonCalibrated(dataWithPredictions, "IsOver50K"); + var metrics = mlContext.BinaryClassification.EvaluateNonCalibrated(dataWithPredictions); SamplesUtils.ConsoleUtils.PrintMetrics(metrics); - // Accuracy: 0.84 - // AUC: 0.88 - // F1 Score: 0.60 - // Negative Precision: 0.87 - // Negative Recall: 0.93 - // Positive Precision: 0.69 - // Positive Recall: 0.53 + + // Expected output: + // Accuracy: 0.84 + // AUC: 0.88 + // F1 Score: 0.60 + // Negative Precision: 0.87 + // Negative Recall: 0.93 + // Positive Precision: 0.69 + // Positive Recall: 0.53 } } } diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/MulticlassClassification/LightGBMMulticlassClassification.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/MulticlassClassification/LightGBMMulticlassClassification.cs index 8731c6bc50..103d9f052f 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/MulticlassClassification/LightGBMMulticlassClassification.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/MulticlassClassification/LightGBMMulticlassClassification.cs @@ -3,9 +3,9 @@ using Microsoft.ML.Data; using Microsoft.ML.SamplesUtils; -namespace Microsoft.ML.Samples.Dynamic +namespace Microsoft.ML.Samples.Dynamic.Trainers.MulticlassClassification { - class LightGbmMulticlassClassification + class LightGbm { // This example requires installation of additional nuget package Microsoft.ML.LightGBM. public static void Example() diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/MulticlassClassification/LightGBMMulticlassClassificationWithOptions.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/MulticlassClassification/LightGBMMulticlassClassificationWithOptions.cs index 7d98c9318e..36de9b8fe1 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/MulticlassClassification/LightGBMMulticlassClassificationWithOptions.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/MulticlassClassification/LightGBMMulticlassClassificationWithOptions.cs @@ -5,9 +5,9 @@ using Microsoft.ML.SamplesUtils; using static Microsoft.ML.LightGBM.Options; -namespace Microsoft.ML.Samples.Dynamic +namespace Microsoft.ML.Samples.Dynamic.Trainers.MulticlassClassification { - class LightGbmMulticlassClassificationWithOptions + class LightGbmWithOptions { // This example requires installation of additional nuget package Microsoft.ML.LightGBM. public static void Example() diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Ranking/LightGBMRanking.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Ranking/LightGBMRanking.cs index 8822a16630..b5857e4538 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Ranking/LightGBMRanking.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Ranking/LightGBMRanking.cs @@ -1,10 +1,8 @@ -using System; -using System.Collections.Generic; -using System.Text; +using Microsoft.ML; -namespace Microsoft.ML.Samples.Dynamic +namespace Microsoft.ML.Samples.Dynamic.Trainers.Ranking { - public class LightGbmRanking + public class LightGbm { // This example requires installation of additional nuget package Microsoft.ML.LightGBM. public static void Example() @@ -12,31 +10,33 @@ public static void Example() // Creating the ML.Net IHostEnvironment object, needed for the pipeline. var mlContext = new MLContext(); - // Download and featurize the train and validation datasets. - (var trainData, var validationData) = SamplesUtils.DatasetUtils.LoadFeaturizedMslrWeb10kTrainAndValidate(mlContext); + // Download and featurize the dataset. + var dataview = SamplesUtils.DatasetUtils.LoadFeaturizedMslrWeb10kDataset(mlContext); + + // Leave out 10% of the dataset for testing. Since this is a ranking problem, we must ensure that the split + // respects the GroupId column, i.e. rows with the same GroupId are either all in the train split or all in + // the test split. The samplingKeyColumn parameter in Ranking.TrainTestSplit is used for this purpose. + var split = mlContext.Ranking.TrainTestSplit(dataview, testFraction: 0.1, samplingKeyColumn: "GroupId"); // Create the Estimator pipeline. For simplicity, we will train a small tree with 4 leaves and 2 boosting iterations. var pipeline = mlContext.Ranking.Trainers.LightGbm( - labelColumn: "Label", - featureColumn: "Features", - groupIdColumn: "GroupId", numLeaves: 4, minDataPerLeaf: 10, learningRate: 0.1, numBoostRound: 2); // Fit this Pipeline to the Training Data. - var model = pipeline.Fit(trainData); + var model = pipeline.Fit(split.TrainSet); // Evaluate how the model is doing on the test data. - var dataWithPredictions = model.Transform(validationData); + var dataWithPredictions = model.Transform(split.TestSet); var metrics = mlContext.Ranking.Evaluate(dataWithPredictions, "Label", "GroupId"); SamplesUtils.ConsoleUtils.PrintMetrics(metrics); - // Output: - // DCG @N: 1.38, 3.11, 4.94 - // NDCG @N: 7.13, 10.12, 12.62 + // Expected output: + // DCG: @1:1.25, @2:2.69, @3:4.57 + // NDCG: @1:7.01, @2:9.57, @3:12.34 } } } diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Ranking/LightGBMRankingWithOptions.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Ranking/LightGBMRankingWithOptions.cs index d8f3da41ea..30087131d8 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Ranking/LightGBMRankingWithOptions.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Ranking/LightGBMRankingWithOptions.cs @@ -1,9 +1,8 @@ using Microsoft.ML.LightGBM; -using static Microsoft.ML.LightGBM.Options; -namespace Microsoft.ML.Samples.Dynamic +namespace Microsoft.ML.Samples.Dynamic.Trainers.Ranking { - public class LightGbmRankingWithOptions + public class LightGbmWithOptions { // This example requires installation of additional nuget package Microsoft.ML.LightGBM. public static void Example() @@ -12,33 +11,35 @@ public static void Example() var mlContext = new MLContext(); // Download and featurize the train and validation datasets. - (var trainData, var validationData) = SamplesUtils.DatasetUtils.LoadFeaturizedMslrWeb10kTrainAndValidate(mlContext); + var dataview = SamplesUtils.DatasetUtils.LoadFeaturizedMslrWeb10kDataset(mlContext); + + // Leave out 10% of the dataset for testing. Since this is a ranking problem, we must ensure that the split + // respects the GroupId column, i.e. rows with the same GroupId are either all in the train split or all in + // the test split. The samplingKeyColumn parameter in Ranking.TrainTestSplit is used for this purpose. + var split = mlContext.Ranking.TrainTestSplit(dataview, testFraction: 0.1, samplingKeyColumn: "GroupId"); // Create the Estimator pipeline. For simplicity, we will train a small tree with 4 leaves and 2 boosting iterations. var pipeline = mlContext.Ranking.Trainers.LightGbm( new Options { - LabelColumn = "Label", - FeatureColumn = "Features", - GroupIdColumn = "GroupId", NumLeaves = 4, MinDataPerLeaf = 10, LearningRate = 0.1, NumBoostRound = 2 }); - // Fit this Pipeline to the Training Data. - var model = pipeline.Fit(trainData); + // Fit this pipeline to the training Data. + var model = pipeline.Fit(split.TrainSet); // Evaluate how the model is doing on the test data. - var dataWithPredictions = model.Transform(validationData); + var dataWithPredictions = model.Transform(split.TestSet); var metrics = mlContext.Ranking.Evaluate(dataWithPredictions, "Label", "GroupId"); SamplesUtils.ConsoleUtils.PrintMetrics(metrics); - // Output: - // DCG @N: 1.38, 3.11, 4.94 - // NDCG @N: 7.13, 10.12, 12.62 + // Expected output: + // DCG: @1:1.25, @2:2.69, @3:4.57 + // NDCG: @1:7.01, @2:9.57, @3:12.34 } } } diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Recommendation/MatrixFactorization.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Recommendation/MatrixFactorization.cs index f630cceab9..a6d7e445fd 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Recommendation/MatrixFactorization.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Recommendation/MatrixFactorization.cs @@ -3,7 +3,7 @@ using Microsoft.ML.Data; using static Microsoft.ML.SamplesUtils.DatasetUtils; -namespace Microsoft.ML.Samples.Dynamic +namespace Microsoft.ML.Samples.Dynamic.Trainers.Recommendation { public static class MatrixFactorization { diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Recommendation/MatrixFactorizationWithOptions.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Recommendation/MatrixFactorizationWithOptions.cs index c73fd7fbcb..cbb11938a0 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Recommendation/MatrixFactorizationWithOptions.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Recommendation/MatrixFactorizationWithOptions.cs @@ -4,7 +4,7 @@ using Microsoft.ML.Trainers; using static Microsoft.ML.SamplesUtils.DatasetUtils; -namespace Microsoft.ML.Samples.Dynamic +namespace Microsoft.ML.Samples.Dynamic.Trainers.Recommendation { public static class MatrixFactorizationWithOptions { diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Regression/LightGBMRegression.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Regression/LightGBMRegression.cs index c4b6f9f68c..cb950e6832 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Regression/LightGBMRegression.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Regression/LightGBMRegression.cs @@ -2,9 +2,9 @@ using System.Linq; using Microsoft.ML.Data; -namespace Microsoft.ML.Samples.Dynamic +namespace Microsoft.ML.Samples.Dynamic.Trainers.Regression { - class LightGbmRegression + class LightGbm { // This example requires installation of additional nuget package Microsoft.ML.LightGBM. public static void Example() @@ -54,12 +54,12 @@ public static void Example() var metrics = mlContext.Regression.Evaluate(dataWithPredictions, label: labelName); SamplesUtils.ConsoleUtils.PrintMetrics(metrics); - // Output - // L1: 4.97 - // L2: 51.37 - // LossFunction: 51.37 - // RMS: 7.17 - // RSquared: 0.08 + // Expected output + // L1: 4.97 + // L2: 51.37 + // LossFunction: 51.37 + // RMS: 7.17 + // RSquared: 0.08 } } } diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Regression/LightGBMRegressionWithOptions.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Regression/LightGBMRegressionWithOptions.cs index 3f73df053e..c1c82a9735 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Regression/LightGBMRegressionWithOptions.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Regression/LightGBMRegressionWithOptions.cs @@ -4,9 +4,9 @@ using Microsoft.ML.LightGBM; using static Microsoft.ML.LightGBM.Options; -namespace Microsoft.ML.Samples.Dynamic +namespace Microsoft.ML.Samples.Dynamic.Trainers.Regression { - class LightGbmRegressionWithOptions + class LightGbmWithOptions { // This example requires installation of additional nuget package Microsoft.ML.LightGBM. public static void Example() @@ -64,12 +64,12 @@ public static void Example() var metrics = mlContext.Regression.Evaluate(dataWithPredictions, label: labelName); SamplesUtils.ConsoleUtils.PrintMetrics(metrics); - // Output - // L1: 4.97 - // L2: 51.37 - // LossFunction: 51.37 - // RMS: 7.17 - // RSquared: 0.08 + // Expected output + // L1: 4.97 + // L2: 51.37 + // LossFunction: 51.37 + // RMS: 7.17 + // RSquared: 0.08 } } } diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Regression/OrdinaryLeastSquares.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Regression/OrdinaryLeastSquares.cs index 3a8a17952b..6cf99ad8ce 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Regression/OrdinaryLeastSquares.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Regression/OrdinaryLeastSquares.cs @@ -2,7 +2,7 @@ using Microsoft.ML.Data; using Microsoft.ML.SamplesUtils; -namespace Microsoft.ML.Samples.Dynamic +namespace Microsoft.ML.Samples.Dynamic.Trainers.Regression { public static class OrdinaryLeastSquares { @@ -55,11 +55,13 @@ public static void Example() var metrics = mlContext.Regression.Evaluate(dataWithPredictions); ConsoleUtils.PrintMetrics(metrics); - // L1: 4.15 - // L2: 31.98 - // LossFunction: 31.98 - // RMS: 5.65 - // RSquared: 0.56 + + // Expected output: + // L1: 4.15 + // L2: 31.98 + // LossFunction: 31.98 + // RMS: 5.65 + // RSquared: 0.56 } } } diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Regression/OrdinaryLeastSquaresWithOptions.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Regression/OrdinaryLeastSquaresWithOptions.cs index 519a9ef683..45a9704f47 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Regression/OrdinaryLeastSquaresWithOptions.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Regression/OrdinaryLeastSquaresWithOptions.cs @@ -3,7 +3,7 @@ using Microsoft.ML.SamplesUtils; using Microsoft.ML.Trainers.HalLearners; -namespace Microsoft.ML.Samples.Dynamic +namespace Microsoft.ML.Samples.Dynamic.Trainers.Regression { public static class OrdinaryLeastSquaresWithOptions { @@ -59,11 +59,13 @@ public static void Example() var metrics = mlContext.Regression.Evaluate(dataWithPredictions); ConsoleUtils.PrintMetrics(metrics); - // L1: 4.14 - // L2: 32.35 - // LossFunction: 32.35 - // RMS: 5.69 - // RSquared: 0.56 + + // Expected output: + // L1: 4.14 + // L2: 32.35 + // LossFunction: 32.35 + // RMS: 5.69 + // RSquared: 0.56 } } } diff --git a/docs/samples/Microsoft.ML.Samples/Program.cs b/docs/samples/Microsoft.ML.Samples/Program.cs index 6fa4e40705..d28cdd4d77 100644 --- a/docs/samples/Microsoft.ML.Samples/Program.cs +++ b/docs/samples/Microsoft.ML.Samples/Program.cs @@ -6,7 +6,7 @@ internal static class Program { static void Main(string[] args) { - LightGbmRanking.Example(); + TakeRows.Example(); } } } diff --git a/src/Microsoft.ML.Data/Evaluators/Metrics/RankerMetrics.cs b/src/Microsoft.ML.Data/Evaluators/Metrics/RankerMetrics.cs index d3b9ef685f..c9e6337070 100644 --- a/src/Microsoft.ML.Data/Evaluators/Metrics/RankerMetrics.cs +++ b/src/Microsoft.ML.Data/Evaluators/Metrics/RankerMetrics.cs @@ -15,10 +15,10 @@ public sealed class RankerMetrics public double[] Ndcg { get; } /// - ///Array of discounted cumulative gains where i-th element represent DCG@i. + /// Array of discounted cumulative gains where i-th element represent DCG@i. /// Discounted Cumulative gain /// is the sum of the gains, for all the instances i, normalized by the natural logarithm of the instance + 1. - /// Note that unlike the Wikipedia article, ML.Net uses the natural logarithm. + /// Note that unlike the Wikipedia article, ML.NET uses the natural logarithm. /// /// public double[] Dcg { get; } diff --git a/src/Microsoft.ML.SamplesUtils/ConsoleUtils.cs b/src/Microsoft.ML.SamplesUtils/ConsoleUtils.cs index 7c40d9a4c8..58ec0bcb6e 100644 --- a/src/Microsoft.ML.SamplesUtils/ConsoleUtils.cs +++ b/src/Microsoft.ML.SamplesUtils/ConsoleUtils.cs @@ -43,8 +43,18 @@ public static void PrintMetrics(RegressionMetrics metrics) /// Ranker metrics. public static void PrintMetrics(RankerMetrics metrics) { - Console.WriteLine($"DCG@N: {string.Join(", ", metrics.Dcg.Select(d => Math.Round(d, 2)).ToArray())}"); - Console.WriteLine($"NDCG@N: {string.Join(", ", metrics.Ndcg.Select(d => Math.Round(d, 2)).ToArray())}"); + Console.WriteLine($"DCG: {string.Join(", ", RoundAndBeautifyRankerMetrics(metrics.Dcg))}"); + Console.WriteLine($"NDCG: {string.Join(", ", RoundAndBeautifyRankerMetrics(metrics.Ndcg))}"); + } + + private static string[] RoundAndBeautifyRankerMetrics(double[] input) + { + string[] result = input.Select(d => Math.Round(d, 2).ToString()).ToArray(); + for (int i = 0; i < result.Length; i++) + { + result[i] = $"@{(i + 1).ToString()}:{result[i]}"; + } + return result; } } } diff --git a/src/Microsoft.ML.SamplesUtils/SamplesDatasetUtils.cs b/src/Microsoft.ML.SamplesUtils/SamplesDatasetUtils.cs index a40212b0e6..dab907f32a 100644 --- a/src/Microsoft.ML.SamplesUtils/SamplesDatasetUtils.cs +++ b/src/Microsoft.ML.SamplesUtils/SamplesDatasetUtils.cs @@ -138,7 +138,7 @@ public static IDataView LoadFeaturizedAdultDataset(MLContext mlContext) .Append(mlContext.Transforms.Concatenate("Features", "workclass", "education", "marital-status", "occupation", "relationship", "ethnicity", "native-country", "age", "education-num", "capital-gain", "capital-loss", "hours-per-week")) - // Min-max normalized all the features + // Min-max normalize all the features .Append(mlContext.Transforms.Normalize("Features")); var data = reader.Read(dataFile); @@ -146,7 +146,7 @@ public static IDataView LoadFeaturizedAdultDataset(MLContext mlContext) return featurizedData; } - public static string DownloadMslrWeb10kTrain() + public static string DownloadMslrWeb10k() { var fileName = "MSLRWeb10KTrain720kRows.tsv"; if (!File.Exists(fileName)) @@ -154,19 +154,10 @@ public static string DownloadMslrWeb10kTrain() return fileName; } - public static string DownloadMslrWeb10kValidate() - { - var fileName = "MSLRWeb10KValidate240kRows.tsv"; - if (!File.Exists(fileName)) - Download("https://tlcresources.blob.core.windows.net/datasets/MSLR-WEB10K/MSLR-WEB10K_Fold1.VALIDATE.160MB_240k-rows.tsv", fileName); - return fileName; - } - - public static (IDataView, IDataView) LoadFeaturizedMslrWeb10kTrainAndValidate(MLContext mlContext) + public static IDataView LoadFeaturizedMslrWeb10kDataset(MLContext mlContext) { // Download the training and validation files. - string trainDataFile = DownloadMslrWeb10kTrain(); - string validationDataFile = DownloadMslrWeb10kValidate(); + string dataFile = DownloadMslrWeb10k(); // Create the reader to read the data. var reader = mlContext.Data.CreateTextLoader( @@ -178,23 +169,18 @@ public static (IDataView, IDataView) LoadFeaturizedMslrWeb10kTrainAndValidate(ML } ); - // Load the raw training and validation datasets. - var trainData = reader.Read(trainDataFile); - var validationData = reader.Read(validationDataFile); + // Load the raw dataset. + var data = reader.Read(dataFile); // Create the featurization pipeline. First, hash the GroupId column. var pipeline = mlContext.Transforms.Conversion.Hash("GroupId") // Replace missing values in Features column with the default replacement value for its type. .Append(mlContext.Transforms.ReplaceMissingValues("Features")); - // Fit the pipeline on the training data. - var fittedPipeline = pipeline.Fit(trainData); - - // Use the fitted pipeline to transform the training and validation datasets. - var transformedTrainData = fittedPipeline.Transform(trainData); - var transformedValidationData = fittedPipeline.Transform(validationData); + // Fit the pipeline and transform the dataset. + var transformedData = pipeline.Fit(data).Transform(data); - return (transformedTrainData, transformedValidationData); + return transformedData; } /// From ba14a9d3c5be9c4bcc8cc65446f409f4f1c02fc2 Mon Sep 17 00:00:00 2001 From: "REDMOND\\nakazmi" Date: Tue, 19 Feb 2019 23:19:02 -0800 Subject: [PATCH 03/24] Adding a sample for LightGbm Ranking --- ...LightGBMBinaryClassificationWithOptions.cs | 1 - .../Trainers/Ranking/LightGBMRanking.cs | 42 +++++++++++++++ .../Ranking/LightGBMRankingWithOptions.cs | 44 ++++++++++++++++ docs/samples/Microsoft.ML.Samples/Program.cs | 2 +- .../Evaluators/Metrics/RankerMetrics.cs | 2 +- src/Microsoft.ML.SamplesUtils/ConsoleUtils.cs | 11 ++++ .../SamplesDatasetUtils.cs | 51 +++++++++++++++++++ 7 files changed, 150 insertions(+), 3 deletions(-) create mode 100644 docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Ranking/LightGBMRanking.cs create mode 100644 docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Ranking/LightGBMRankingWithOptions.cs diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/LightGBMBinaryClassificationWithOptions.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/LightGBMBinaryClassificationWithOptions.cs index 20924bc29f..904285aaee 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/LightGBMBinaryClassificationWithOptions.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/LightGBMBinaryClassificationWithOptions.cs @@ -1,5 +1,4 @@ using Microsoft.ML.LightGBM; -using Microsoft.ML.Transforms.Categorical; using static Microsoft.ML.LightGBM.Options; namespace Microsoft.ML.Samples.Dynamic diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Ranking/LightGBMRanking.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Ranking/LightGBMRanking.cs new file mode 100644 index 0000000000..8822a16630 --- /dev/null +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Ranking/LightGBMRanking.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Microsoft.ML.Samples.Dynamic +{ + public class LightGbmRanking + { + // This example requires installation of additional nuget package Microsoft.ML.LightGBM. + public static void Example() + { + // Creating the ML.Net IHostEnvironment object, needed for the pipeline. + var mlContext = new MLContext(); + + // Download and featurize the train and validation datasets. + (var trainData, var validationData) = SamplesUtils.DatasetUtils.LoadFeaturizedMslrWeb10kTrainAndValidate(mlContext); + + // Create the Estimator pipeline. For simplicity, we will train a small tree with 4 leaves and 2 boosting iterations. + var pipeline = mlContext.Ranking.Trainers.LightGbm( + labelColumn: "Label", + featureColumn: "Features", + groupIdColumn: "GroupId", + numLeaves: 4, + minDataPerLeaf: 10, + learningRate: 0.1, + numBoostRound: 2); + + // Fit this Pipeline to the Training Data. + var model = pipeline.Fit(trainData); + + // Evaluate how the model is doing on the test data. + var dataWithPredictions = model.Transform(validationData); + + var metrics = mlContext.Ranking.Evaluate(dataWithPredictions, "Label", "GroupId"); + SamplesUtils.ConsoleUtils.PrintMetrics(metrics); + + // Output: + // DCG @N: 1.38, 3.11, 4.94 + // NDCG @N: 7.13, 10.12, 12.62 + } + } +} diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Ranking/LightGBMRankingWithOptions.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Ranking/LightGBMRankingWithOptions.cs new file mode 100644 index 0000000000..d8f3da41ea --- /dev/null +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Ranking/LightGBMRankingWithOptions.cs @@ -0,0 +1,44 @@ +using Microsoft.ML.LightGBM; +using static Microsoft.ML.LightGBM.Options; + +namespace Microsoft.ML.Samples.Dynamic +{ + public class LightGbmRankingWithOptions + { + // This example requires installation of additional nuget package Microsoft.ML.LightGBM. + public static void Example() + { + // Creating the ML.Net IHostEnvironment object, needed for the pipeline. + var mlContext = new MLContext(); + + // Download and featurize the train and validation datasets. + (var trainData, var validationData) = SamplesUtils.DatasetUtils.LoadFeaturizedMslrWeb10kTrainAndValidate(mlContext); + + // Create the Estimator pipeline. For simplicity, we will train a small tree with 4 leaves and 2 boosting iterations. + var pipeline = mlContext.Ranking.Trainers.LightGbm( + new Options + { + LabelColumn = "Label", + FeatureColumn = "Features", + GroupIdColumn = "GroupId", + NumLeaves = 4, + MinDataPerLeaf = 10, + LearningRate = 0.1, + NumBoostRound = 2 + }); + + // Fit this Pipeline to the Training Data. + var model = pipeline.Fit(trainData); + + // Evaluate how the model is doing on the test data. + var dataWithPredictions = model.Transform(validationData); + + var metrics = mlContext.Ranking.Evaluate(dataWithPredictions, "Label", "GroupId"); + SamplesUtils.ConsoleUtils.PrintMetrics(metrics); + + // Output: + // DCG @N: 1.38, 3.11, 4.94 + // NDCG @N: 7.13, 10.12, 12.62 + } + } +} diff --git a/docs/samples/Microsoft.ML.Samples/Program.cs b/docs/samples/Microsoft.ML.Samples/Program.cs index d28cdd4d77..6fa4e40705 100644 --- a/docs/samples/Microsoft.ML.Samples/Program.cs +++ b/docs/samples/Microsoft.ML.Samples/Program.cs @@ -6,7 +6,7 @@ internal static class Program { static void Main(string[] args) { - TakeRows.Example(); + LightGbmRanking.Example(); } } } diff --git a/src/Microsoft.ML.Data/Evaluators/Metrics/RankerMetrics.cs b/src/Microsoft.ML.Data/Evaluators/Metrics/RankerMetrics.cs index b9532fd31b..d3b9ef685f 100644 --- a/src/Microsoft.ML.Data/Evaluators/Metrics/RankerMetrics.cs +++ b/src/Microsoft.ML.Data/Evaluators/Metrics/RankerMetrics.cs @@ -18,7 +18,7 @@ public sealed class RankerMetrics ///Array of discounted cumulative gains where i-th element represent DCG@i. /// Discounted Cumulative gain /// is the sum of the gains, for all the instances i, normalized by the natural logarithm of the instance + 1. - /// Note that unline the Wikipedia article, ML.Net uses the natural logarithm. + /// Note that unlike the Wikipedia article, ML.Net uses the natural logarithm. /// /// public double[] Dcg { get; } diff --git a/src/Microsoft.ML.SamplesUtils/ConsoleUtils.cs b/src/Microsoft.ML.SamplesUtils/ConsoleUtils.cs index 93de658b1e..7c40d9a4c8 100644 --- a/src/Microsoft.ML.SamplesUtils/ConsoleUtils.cs +++ b/src/Microsoft.ML.SamplesUtils/ConsoleUtils.cs @@ -1,4 +1,5 @@ using System; +using System.Linq; using Microsoft.ML.Data; namespace Microsoft.ML.SamplesUtils @@ -35,5 +36,15 @@ public static void PrintMetrics(RegressionMetrics metrics) Console.WriteLine($"RMS: {metrics.Rms:F2}"); Console.WriteLine($"RSquared: {metrics.RSquared:F2}"); } + + /// + /// Pretty-print RankerMetrics objects. + /// + /// Ranker metrics. + public static void PrintMetrics(RankerMetrics metrics) + { + Console.WriteLine($"DCG@N: {string.Join(", ", metrics.Dcg.Select(d => Math.Round(d, 2)).ToArray())}"); + Console.WriteLine($"NDCG@N: {string.Join(", ", metrics.Ndcg.Select(d => Math.Round(d, 2)).ToArray())}"); + } } } diff --git a/src/Microsoft.ML.SamplesUtils/SamplesDatasetUtils.cs b/src/Microsoft.ML.SamplesUtils/SamplesDatasetUtils.cs index 203bd6e6bd..a40212b0e6 100644 --- a/src/Microsoft.ML.SamplesUtils/SamplesDatasetUtils.cs +++ b/src/Microsoft.ML.SamplesUtils/SamplesDatasetUtils.cs @@ -146,6 +146,57 @@ public static IDataView LoadFeaturizedAdultDataset(MLContext mlContext) return featurizedData; } + public static string DownloadMslrWeb10kTrain() + { + var fileName = "MSLRWeb10KTrain720kRows.tsv"; + if (!File.Exists(fileName)) + Download("https://tlcresources.blob.core.windows.net/datasets/MSLR-WEB10K/MSLR-WEB10K_Fold1.TRAIN.500MB_720k-rows.tsv", fileName); + return fileName; + } + + public static string DownloadMslrWeb10kValidate() + { + var fileName = "MSLRWeb10KValidate240kRows.tsv"; + if (!File.Exists(fileName)) + Download("https://tlcresources.blob.core.windows.net/datasets/MSLR-WEB10K/MSLR-WEB10K_Fold1.VALIDATE.160MB_240k-rows.tsv", fileName); + return fileName; + } + + public static (IDataView, IDataView) LoadFeaturizedMslrWeb10kTrainAndValidate(MLContext mlContext) + { + // Download the training and validation files. + string trainDataFile = DownloadMslrWeb10kTrain(); + string validationDataFile = DownloadMslrWeb10kValidate(); + + // Create the reader to read the data. + var reader = mlContext.Data.CreateTextLoader( + columns: new[] + { + new TextLoader.Column("Label", DataKind.R4, 0), + new TextLoader.Column("GroupId", DataKind.TX, 1), + new TextLoader.Column("Features", DataKind.R4, new[] { new TextLoader.Range(2, 138) }) + } + ); + + // Load the raw training and validation datasets. + var trainData = reader.Read(trainDataFile); + var validationData = reader.Read(validationDataFile); + + // Create the featurization pipeline. First, hash the GroupId column. + var pipeline = mlContext.Transforms.Conversion.Hash("GroupId") + // Replace missing values in Features column with the default replacement value for its type. + .Append(mlContext.Transforms.ReplaceMissingValues("Features")); + + // Fit the pipeline on the training data. + var fittedPipeline = pipeline.Fit(trainData); + + // Use the fitted pipeline to transform the training and validation datasets. + var transformedTrainData = fittedPipeline.Transform(trainData); + var transformedValidationData = fittedPipeline.Transform(validationData); + + return (transformedTrainData, transformedValidationData); + } + /// /// Downloads the breast cancer dataset from the ML.NET repo. /// From f20d7bf1b06b84b43246cde2ab3e00b9bf59904a Mon Sep 17 00:00:00 2001 From: "REDMOND\\nakazmi" Date: Fri, 22 Feb 2019 18:19:12 -0800 Subject: [PATCH 04/24] PR feedback + cleaning up namespaces in Microsoft.ML.Samples project --- .../LightGBMBinaryClassification.cs | 24 +++++++------- ...LightGBMBinaryClassificationWithOptions.cs | 24 +++++++------- .../SDCALogisticRegression.cs | 2 +- .../SDCASupportVectorMachine.cs | 2 +- .../SymbolicStochasticGradientDescent.cs | 20 ++++++------ ...licStochasticGradientDescentWithOptions.cs | 21 ++++++------ .../LightGBMMulticlassClassification.cs | 4 +-- ...tGBMMulticlassClassificationWithOptions.cs | 4 +-- .../Trainers/Ranking/LightGBMRanking.cs | 30 ++++++++--------- .../Ranking/LightGBMRankingWithOptions.cs | 27 ++++++++-------- .../Recommendation/MatrixFactorization.cs | 2 +- .../MatrixFactorizationWithOptions.cs | 2 +- .../Trainers/Regression/LightGBMRegression.cs | 16 +++++----- .../LightGBMRegressionWithOptions.cs | 16 +++++----- .../Regression/OrdinaryLeastSquares.cs | 14 ++++---- .../OrdinaryLeastSquaresWithOptions.cs | 14 ++++---- docs/samples/Microsoft.ML.Samples/Program.cs | 2 +- .../Evaluators/Metrics/RankerMetrics.cs | 4 +-- src/Microsoft.ML.SamplesUtils/ConsoleUtils.cs | 14 ++++++-- .../SamplesDatasetUtils.cs | 32 ++++++------------- 20 files changed, 138 insertions(+), 136 deletions(-) diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/LightGBMBinaryClassification.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/LightGBMBinaryClassification.cs index edd4e31504..a6834d0082 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/LightGBMBinaryClassification.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/LightGBMBinaryClassification.cs @@ -1,8 +1,8 @@ using Microsoft.ML.Transforms.Categorical; -namespace Microsoft.ML.Samples.Dynamic +namespace Microsoft.ML.Samples.Dynamic.Trainers.BinaryClassification { - public class LightGbmBinaryClassification + public class LightGbm { // This example requires installation of additional nuget package Microsoft.ML.LightGBM. public static void Example() @@ -17,7 +17,7 @@ public static void Example() var split = mlContext.BinaryClassification.TrainTestSplit(dataview, testFraction: 0.1); // Create the Estimator. - var pipeline = mlContext.BinaryClassification.Trainers.LightGbm("IsOver50K", "Features"); + var pipeline = mlContext.BinaryClassification.Trainers.LightGbm(); // Fit this Pipeline to the Training Data. var model = pipeline.Fit(split.TrainSet); @@ -25,17 +25,17 @@ public static void Example() // Evaluate how the model is doing on the test data. var dataWithPredictions = model.Transform(split.TestSet); - var metrics = mlContext.BinaryClassification.Evaluate(dataWithPredictions, "IsOver50K"); + var metrics = mlContext.BinaryClassification.Evaluate(dataWithPredictions); SamplesUtils.ConsoleUtils.PrintMetrics(metrics); - // Output: - // Accuracy: 0.88 - // AUC: 0.93 - // F1 Score: 0.71 - // Negative Precision: 0.90 - // Negative Recall: 0.94 - // Positive Precision: 0.76 - // Positive Recall: 0.66 + // Expected output: + // Accuracy: 0.88 + // AUC: 0.93 + // F1 Score: 0.71 + // Negative Precision: 0.90 + // Negative Recall: 0.94 + // Positive Precision: 0.76 + // Positive Recall: 0.66 } } } \ No newline at end of file diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/LightGBMBinaryClassificationWithOptions.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/LightGBMBinaryClassificationWithOptions.cs index 904285aaee..7b0e21fed9 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/LightGBMBinaryClassificationWithOptions.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/LightGBMBinaryClassificationWithOptions.cs @@ -1,9 +1,9 @@ using Microsoft.ML.LightGBM; using static Microsoft.ML.LightGBM.Options; -namespace Microsoft.ML.Samples.Dynamic +namespace Microsoft.ML.Samples.Dynamic.Trainers.BinaryClassification { - class LightGbmBinaryClassificationWithOptions + class LightGbmWithOptions { // This example requires installation of additional nuget package Microsoft.ML.LightGBM. public static void Example() @@ -21,8 +21,6 @@ public static void Example() var pipeline = mlContext.BinaryClassification.Trainers.LightGbm( new Options { - LabelColumn = "IsOver50K", - FeatureColumn = "Features", Booster = new GossBooster.Options { TopRate = 0.3, @@ -36,17 +34,17 @@ public static void Example() // Evaluate how the model is doing on the test data. var dataWithPredictions = model.Transform(split.TestSet); - var metrics = mlContext.BinaryClassification.Evaluate(dataWithPredictions, "IsOver50K"); + var metrics = mlContext.BinaryClassification.Evaluate(dataWithPredictions); SamplesUtils.ConsoleUtils.PrintMetrics(metrics); - // Output: - // Accuracy: 0.88 - // AUC: 0.93 - // F1 Score: 0.71 - // Negative Precision: 0.90 - // Negative Recall: 0.94 - // Positive Precision: 0.76 - // Positive Recall: 0.67 + // Expected output: + // Accuracy: 0.88 + // AUC: 0.93 + // F1 Score: 0.71 + // Negative Precision: 0.90 + // Negative Recall: 0.94 + // Positive Precision: 0.76 + // Positive Recall: 0.67 } } } diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/SDCALogisticRegression.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/SDCALogisticRegression.cs index 3ab3257638..da12242ce4 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/SDCALogisticRegression.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/SDCALogisticRegression.cs @@ -3,7 +3,7 @@ using Microsoft.ML.Data; using Microsoft.ML.Trainers; -namespace Microsoft.ML.Samples.Dynamic +namespace Microsoft.ML.Samples.Dynamic.Trainers.BinaryClassification { public static class SDCALogisticRegression { diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/SDCASupportVectorMachine.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/SDCASupportVectorMachine.cs index d37c1cec1a..0730e3daee 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/SDCASupportVectorMachine.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/SDCASupportVectorMachine.cs @@ -2,7 +2,7 @@ using System.Linq; using Microsoft.ML.Data; -namespace Microsoft.ML.Samples.Dynamic +namespace Microsoft.ML.Samples.Dynamic.Trainers.BinaryClassification { public static class SDCASupportVectorMachine { diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/SymbolicStochasticGradientDescent.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/SymbolicStochasticGradientDescent.cs index 49b31342e0..dcdd331ab5 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/SymbolicStochasticGradientDescent.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/SymbolicStochasticGradientDescent.cs @@ -1,4 +1,4 @@ -namespace Microsoft.ML.Samples.Dynamic +namespace Microsoft.ML.Samples.Dynamic.Trainers.BinaryClassification { public static class SymbolicStochasticGradientDescent { @@ -24,15 +24,17 @@ public static void Example() // Evaluate how the model is doing on the test data. var dataWithPredictions = model.Transform(split.TestSet); - var metrics = mlContext.BinaryClassification.EvaluateNonCalibrated(dataWithPredictions, "IsOver50K"); + var metrics = mlContext.BinaryClassification.EvaluateNonCalibrated(dataWithPredictions); SamplesUtils.ConsoleUtils.PrintMetrics(metrics); - // Accuracy: 0.85 - // AUC: 0.90 - // F1 Score: 0.64 - // Negative Precision: 0.88 - // Negative Recall: 0.93 - // Positive Precision: 0.72 - // Positive Recall: 0.58 + + // Expected output: + // Accuracy: 0.85 + // AUC: 0.90 + // F1 Score: 0.64 + // Negative Precision: 0.88 + // Negative Recall: 0.93 + // Positive Precision: 0.72 + // Positive Recall: 0.58 } } } diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/SymbolicStochasticGradientDescentWithOptions.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/SymbolicStochasticGradientDescentWithOptions.cs index d05d64454c..e4363f29cc 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/SymbolicStochasticGradientDescentWithOptions.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/SymbolicStochasticGradientDescentWithOptions.cs @@ -1,4 +1,4 @@ -namespace Microsoft.ML.Samples.Dynamic +namespace Microsoft.ML.Samples.Dynamic.Trainers.BinaryClassification { public static class SymbolicStochasticGradientDescentWithOptions { @@ -22,7 +22,6 @@ public static void Example() var pipeline = mlContext.BinaryClassification.Trainers.SymbolicStochasticGradientDescent( new ML.Trainers.HalLearners.SymSgdClassificationTrainer.Options() { - LabelColumn = "IsOver50K", LearningRate = 0.2f, NumberOfIterations = 10, NumberOfThreads = 1, @@ -33,15 +32,17 @@ public static void Example() // Evaluate how the model is doing on the test data. var dataWithPredictions = model.Transform(split.TestSet); - var metrics = mlContext.BinaryClassification.EvaluateNonCalibrated(dataWithPredictions, "IsOver50K"); + var metrics = mlContext.BinaryClassification.EvaluateNonCalibrated(dataWithPredictions); SamplesUtils.ConsoleUtils.PrintMetrics(metrics); - // Accuracy: 0.84 - // AUC: 0.88 - // F1 Score: 0.60 - // Negative Precision: 0.87 - // Negative Recall: 0.93 - // Positive Precision: 0.69 - // Positive Recall: 0.53 + + // Expected output: + // Accuracy: 0.84 + // AUC: 0.88 + // F1 Score: 0.60 + // Negative Precision: 0.87 + // Negative Recall: 0.93 + // Positive Precision: 0.69 + // Positive Recall: 0.53 } } } diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/MulticlassClassification/LightGBMMulticlassClassification.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/MulticlassClassification/LightGBMMulticlassClassification.cs index 8731c6bc50..103d9f052f 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/MulticlassClassification/LightGBMMulticlassClassification.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/MulticlassClassification/LightGBMMulticlassClassification.cs @@ -3,9 +3,9 @@ using Microsoft.ML.Data; using Microsoft.ML.SamplesUtils; -namespace Microsoft.ML.Samples.Dynamic +namespace Microsoft.ML.Samples.Dynamic.Trainers.MulticlassClassification { - class LightGbmMulticlassClassification + class LightGbm { // This example requires installation of additional nuget package Microsoft.ML.LightGBM. public static void Example() diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/MulticlassClassification/LightGBMMulticlassClassificationWithOptions.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/MulticlassClassification/LightGBMMulticlassClassificationWithOptions.cs index 7d98c9318e..36de9b8fe1 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/MulticlassClassification/LightGBMMulticlassClassificationWithOptions.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/MulticlassClassification/LightGBMMulticlassClassificationWithOptions.cs @@ -5,9 +5,9 @@ using Microsoft.ML.SamplesUtils; using static Microsoft.ML.LightGBM.Options; -namespace Microsoft.ML.Samples.Dynamic +namespace Microsoft.ML.Samples.Dynamic.Trainers.MulticlassClassification { - class LightGbmMulticlassClassificationWithOptions + class LightGbmWithOptions { // This example requires installation of additional nuget package Microsoft.ML.LightGBM. public static void Example() diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Ranking/LightGBMRanking.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Ranking/LightGBMRanking.cs index 8822a16630..b5857e4538 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Ranking/LightGBMRanking.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Ranking/LightGBMRanking.cs @@ -1,10 +1,8 @@ -using System; -using System.Collections.Generic; -using System.Text; +using Microsoft.ML; -namespace Microsoft.ML.Samples.Dynamic +namespace Microsoft.ML.Samples.Dynamic.Trainers.Ranking { - public class LightGbmRanking + public class LightGbm { // This example requires installation of additional nuget package Microsoft.ML.LightGBM. public static void Example() @@ -12,31 +10,33 @@ public static void Example() // Creating the ML.Net IHostEnvironment object, needed for the pipeline. var mlContext = new MLContext(); - // Download and featurize the train and validation datasets. - (var trainData, var validationData) = SamplesUtils.DatasetUtils.LoadFeaturizedMslrWeb10kTrainAndValidate(mlContext); + // Download and featurize the dataset. + var dataview = SamplesUtils.DatasetUtils.LoadFeaturizedMslrWeb10kDataset(mlContext); + + // Leave out 10% of the dataset for testing. Since this is a ranking problem, we must ensure that the split + // respects the GroupId column, i.e. rows with the same GroupId are either all in the train split or all in + // the test split. The samplingKeyColumn parameter in Ranking.TrainTestSplit is used for this purpose. + var split = mlContext.Ranking.TrainTestSplit(dataview, testFraction: 0.1, samplingKeyColumn: "GroupId"); // Create the Estimator pipeline. For simplicity, we will train a small tree with 4 leaves and 2 boosting iterations. var pipeline = mlContext.Ranking.Trainers.LightGbm( - labelColumn: "Label", - featureColumn: "Features", - groupIdColumn: "GroupId", numLeaves: 4, minDataPerLeaf: 10, learningRate: 0.1, numBoostRound: 2); // Fit this Pipeline to the Training Data. - var model = pipeline.Fit(trainData); + var model = pipeline.Fit(split.TrainSet); // Evaluate how the model is doing on the test data. - var dataWithPredictions = model.Transform(validationData); + var dataWithPredictions = model.Transform(split.TestSet); var metrics = mlContext.Ranking.Evaluate(dataWithPredictions, "Label", "GroupId"); SamplesUtils.ConsoleUtils.PrintMetrics(metrics); - // Output: - // DCG @N: 1.38, 3.11, 4.94 - // NDCG @N: 7.13, 10.12, 12.62 + // Expected output: + // DCG: @1:1.25, @2:2.69, @3:4.57 + // NDCG: @1:7.01, @2:9.57, @3:12.34 } } } diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Ranking/LightGBMRankingWithOptions.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Ranking/LightGBMRankingWithOptions.cs index d8f3da41ea..30087131d8 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Ranking/LightGBMRankingWithOptions.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Ranking/LightGBMRankingWithOptions.cs @@ -1,9 +1,8 @@ using Microsoft.ML.LightGBM; -using static Microsoft.ML.LightGBM.Options; -namespace Microsoft.ML.Samples.Dynamic +namespace Microsoft.ML.Samples.Dynamic.Trainers.Ranking { - public class LightGbmRankingWithOptions + public class LightGbmWithOptions { // This example requires installation of additional nuget package Microsoft.ML.LightGBM. public static void Example() @@ -12,33 +11,35 @@ public static void Example() var mlContext = new MLContext(); // Download and featurize the train and validation datasets. - (var trainData, var validationData) = SamplesUtils.DatasetUtils.LoadFeaturizedMslrWeb10kTrainAndValidate(mlContext); + var dataview = SamplesUtils.DatasetUtils.LoadFeaturizedMslrWeb10kDataset(mlContext); + + // Leave out 10% of the dataset for testing. Since this is a ranking problem, we must ensure that the split + // respects the GroupId column, i.e. rows with the same GroupId are either all in the train split or all in + // the test split. The samplingKeyColumn parameter in Ranking.TrainTestSplit is used for this purpose. + var split = mlContext.Ranking.TrainTestSplit(dataview, testFraction: 0.1, samplingKeyColumn: "GroupId"); // Create the Estimator pipeline. For simplicity, we will train a small tree with 4 leaves and 2 boosting iterations. var pipeline = mlContext.Ranking.Trainers.LightGbm( new Options { - LabelColumn = "Label", - FeatureColumn = "Features", - GroupIdColumn = "GroupId", NumLeaves = 4, MinDataPerLeaf = 10, LearningRate = 0.1, NumBoostRound = 2 }); - // Fit this Pipeline to the Training Data. - var model = pipeline.Fit(trainData); + // Fit this pipeline to the training Data. + var model = pipeline.Fit(split.TrainSet); // Evaluate how the model is doing on the test data. - var dataWithPredictions = model.Transform(validationData); + var dataWithPredictions = model.Transform(split.TestSet); var metrics = mlContext.Ranking.Evaluate(dataWithPredictions, "Label", "GroupId"); SamplesUtils.ConsoleUtils.PrintMetrics(metrics); - // Output: - // DCG @N: 1.38, 3.11, 4.94 - // NDCG @N: 7.13, 10.12, 12.62 + // Expected output: + // DCG: @1:1.25, @2:2.69, @3:4.57 + // NDCG: @1:7.01, @2:9.57, @3:12.34 } } } diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Recommendation/MatrixFactorization.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Recommendation/MatrixFactorization.cs index d252eb489d..3737e751d5 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Recommendation/MatrixFactorization.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Recommendation/MatrixFactorization.cs @@ -3,7 +3,7 @@ using Microsoft.ML.Data; using static Microsoft.ML.SamplesUtils.DatasetUtils; -namespace Microsoft.ML.Samples.Dynamic +namespace Microsoft.ML.Samples.Dynamic.Trainers.Recommendation { public static class MatrixFactorization { diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Recommendation/MatrixFactorizationWithOptions.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Recommendation/MatrixFactorizationWithOptions.cs index c73fd7fbcb..cbb11938a0 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Recommendation/MatrixFactorizationWithOptions.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Recommendation/MatrixFactorizationWithOptions.cs @@ -4,7 +4,7 @@ using Microsoft.ML.Trainers; using static Microsoft.ML.SamplesUtils.DatasetUtils; -namespace Microsoft.ML.Samples.Dynamic +namespace Microsoft.ML.Samples.Dynamic.Trainers.Recommendation { public static class MatrixFactorizationWithOptions { diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Regression/LightGBMRegression.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Regression/LightGBMRegression.cs index c4b6f9f68c..cb950e6832 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Regression/LightGBMRegression.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Regression/LightGBMRegression.cs @@ -2,9 +2,9 @@ using System.Linq; using Microsoft.ML.Data; -namespace Microsoft.ML.Samples.Dynamic +namespace Microsoft.ML.Samples.Dynamic.Trainers.Regression { - class LightGbmRegression + class LightGbm { // This example requires installation of additional nuget package Microsoft.ML.LightGBM. public static void Example() @@ -54,12 +54,12 @@ public static void Example() var metrics = mlContext.Regression.Evaluate(dataWithPredictions, label: labelName); SamplesUtils.ConsoleUtils.PrintMetrics(metrics); - // Output - // L1: 4.97 - // L2: 51.37 - // LossFunction: 51.37 - // RMS: 7.17 - // RSquared: 0.08 + // Expected output + // L1: 4.97 + // L2: 51.37 + // LossFunction: 51.37 + // RMS: 7.17 + // RSquared: 0.08 } } } diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Regression/LightGBMRegressionWithOptions.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Regression/LightGBMRegressionWithOptions.cs index 3f73df053e..c1c82a9735 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Regression/LightGBMRegressionWithOptions.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Regression/LightGBMRegressionWithOptions.cs @@ -4,9 +4,9 @@ using Microsoft.ML.LightGBM; using static Microsoft.ML.LightGBM.Options; -namespace Microsoft.ML.Samples.Dynamic +namespace Microsoft.ML.Samples.Dynamic.Trainers.Regression { - class LightGbmRegressionWithOptions + class LightGbmWithOptions { // This example requires installation of additional nuget package Microsoft.ML.LightGBM. public static void Example() @@ -64,12 +64,12 @@ public static void Example() var metrics = mlContext.Regression.Evaluate(dataWithPredictions, label: labelName); SamplesUtils.ConsoleUtils.PrintMetrics(metrics); - // Output - // L1: 4.97 - // L2: 51.37 - // LossFunction: 51.37 - // RMS: 7.17 - // RSquared: 0.08 + // Expected output + // L1: 4.97 + // L2: 51.37 + // LossFunction: 51.37 + // RMS: 7.17 + // RSquared: 0.08 } } } diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Regression/OrdinaryLeastSquares.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Regression/OrdinaryLeastSquares.cs index 3a8a17952b..6cf99ad8ce 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Regression/OrdinaryLeastSquares.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Regression/OrdinaryLeastSquares.cs @@ -2,7 +2,7 @@ using Microsoft.ML.Data; using Microsoft.ML.SamplesUtils; -namespace Microsoft.ML.Samples.Dynamic +namespace Microsoft.ML.Samples.Dynamic.Trainers.Regression { public static class OrdinaryLeastSquares { @@ -55,11 +55,13 @@ public static void Example() var metrics = mlContext.Regression.Evaluate(dataWithPredictions); ConsoleUtils.PrintMetrics(metrics); - // L1: 4.15 - // L2: 31.98 - // LossFunction: 31.98 - // RMS: 5.65 - // RSquared: 0.56 + + // Expected output: + // L1: 4.15 + // L2: 31.98 + // LossFunction: 31.98 + // RMS: 5.65 + // RSquared: 0.56 } } } diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Regression/OrdinaryLeastSquaresWithOptions.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Regression/OrdinaryLeastSquaresWithOptions.cs index 519a9ef683..45a9704f47 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Regression/OrdinaryLeastSquaresWithOptions.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Regression/OrdinaryLeastSquaresWithOptions.cs @@ -3,7 +3,7 @@ using Microsoft.ML.SamplesUtils; using Microsoft.ML.Trainers.HalLearners; -namespace Microsoft.ML.Samples.Dynamic +namespace Microsoft.ML.Samples.Dynamic.Trainers.Regression { public static class OrdinaryLeastSquaresWithOptions { @@ -59,11 +59,13 @@ public static void Example() var metrics = mlContext.Regression.Evaluate(dataWithPredictions); ConsoleUtils.PrintMetrics(metrics); - // L1: 4.14 - // L2: 32.35 - // LossFunction: 32.35 - // RMS: 5.69 - // RSquared: 0.56 + + // Expected output: + // L1: 4.14 + // L2: 32.35 + // LossFunction: 32.35 + // RMS: 5.69 + // RSquared: 0.56 } } } diff --git a/docs/samples/Microsoft.ML.Samples/Program.cs b/docs/samples/Microsoft.ML.Samples/Program.cs index 6fa4e40705..d28cdd4d77 100644 --- a/docs/samples/Microsoft.ML.Samples/Program.cs +++ b/docs/samples/Microsoft.ML.Samples/Program.cs @@ -6,7 +6,7 @@ internal static class Program { static void Main(string[] args) { - LightGbmRanking.Example(); + TakeRows.Example(); } } } diff --git a/src/Microsoft.ML.Data/Evaluators/Metrics/RankerMetrics.cs b/src/Microsoft.ML.Data/Evaluators/Metrics/RankerMetrics.cs index d3b9ef685f..c9e6337070 100644 --- a/src/Microsoft.ML.Data/Evaluators/Metrics/RankerMetrics.cs +++ b/src/Microsoft.ML.Data/Evaluators/Metrics/RankerMetrics.cs @@ -15,10 +15,10 @@ public sealed class RankerMetrics public double[] Ndcg { get; } /// - ///Array of discounted cumulative gains where i-th element represent DCG@i. + /// Array of discounted cumulative gains where i-th element represent DCG@i. /// Discounted Cumulative gain /// is the sum of the gains, for all the instances i, normalized by the natural logarithm of the instance + 1. - /// Note that unlike the Wikipedia article, ML.Net uses the natural logarithm. + /// Note that unlike the Wikipedia article, ML.NET uses the natural logarithm. /// /// public double[] Dcg { get; } diff --git a/src/Microsoft.ML.SamplesUtils/ConsoleUtils.cs b/src/Microsoft.ML.SamplesUtils/ConsoleUtils.cs index 7c40d9a4c8..58ec0bcb6e 100644 --- a/src/Microsoft.ML.SamplesUtils/ConsoleUtils.cs +++ b/src/Microsoft.ML.SamplesUtils/ConsoleUtils.cs @@ -43,8 +43,18 @@ public static void PrintMetrics(RegressionMetrics metrics) /// Ranker metrics. public static void PrintMetrics(RankerMetrics metrics) { - Console.WriteLine($"DCG@N: {string.Join(", ", metrics.Dcg.Select(d => Math.Round(d, 2)).ToArray())}"); - Console.WriteLine($"NDCG@N: {string.Join(", ", metrics.Ndcg.Select(d => Math.Round(d, 2)).ToArray())}"); + Console.WriteLine($"DCG: {string.Join(", ", RoundAndBeautifyRankerMetrics(metrics.Dcg))}"); + Console.WriteLine($"NDCG: {string.Join(", ", RoundAndBeautifyRankerMetrics(metrics.Ndcg))}"); + } + + private static string[] RoundAndBeautifyRankerMetrics(double[] input) + { + string[] result = input.Select(d => Math.Round(d, 2).ToString()).ToArray(); + for (int i = 0; i < result.Length; i++) + { + result[i] = $"@{(i + 1).ToString()}:{result[i]}"; + } + return result; } } } diff --git a/src/Microsoft.ML.SamplesUtils/SamplesDatasetUtils.cs b/src/Microsoft.ML.SamplesUtils/SamplesDatasetUtils.cs index a40212b0e6..dab907f32a 100644 --- a/src/Microsoft.ML.SamplesUtils/SamplesDatasetUtils.cs +++ b/src/Microsoft.ML.SamplesUtils/SamplesDatasetUtils.cs @@ -138,7 +138,7 @@ public static IDataView LoadFeaturizedAdultDataset(MLContext mlContext) .Append(mlContext.Transforms.Concatenate("Features", "workclass", "education", "marital-status", "occupation", "relationship", "ethnicity", "native-country", "age", "education-num", "capital-gain", "capital-loss", "hours-per-week")) - // Min-max normalized all the features + // Min-max normalize all the features .Append(mlContext.Transforms.Normalize("Features")); var data = reader.Read(dataFile); @@ -146,7 +146,7 @@ public static IDataView LoadFeaturizedAdultDataset(MLContext mlContext) return featurizedData; } - public static string DownloadMslrWeb10kTrain() + public static string DownloadMslrWeb10k() { var fileName = "MSLRWeb10KTrain720kRows.tsv"; if (!File.Exists(fileName)) @@ -154,19 +154,10 @@ public static string DownloadMslrWeb10kTrain() return fileName; } - public static string DownloadMslrWeb10kValidate() - { - var fileName = "MSLRWeb10KValidate240kRows.tsv"; - if (!File.Exists(fileName)) - Download("https://tlcresources.blob.core.windows.net/datasets/MSLR-WEB10K/MSLR-WEB10K_Fold1.VALIDATE.160MB_240k-rows.tsv", fileName); - return fileName; - } - - public static (IDataView, IDataView) LoadFeaturizedMslrWeb10kTrainAndValidate(MLContext mlContext) + public static IDataView LoadFeaturizedMslrWeb10kDataset(MLContext mlContext) { // Download the training and validation files. - string trainDataFile = DownloadMslrWeb10kTrain(); - string validationDataFile = DownloadMslrWeb10kValidate(); + string dataFile = DownloadMslrWeb10k(); // Create the reader to read the data. var reader = mlContext.Data.CreateTextLoader( @@ -178,23 +169,18 @@ public static (IDataView, IDataView) LoadFeaturizedMslrWeb10kTrainAndValidate(ML } ); - // Load the raw training and validation datasets. - var trainData = reader.Read(trainDataFile); - var validationData = reader.Read(validationDataFile); + // Load the raw dataset. + var data = reader.Read(dataFile); // Create the featurization pipeline. First, hash the GroupId column. var pipeline = mlContext.Transforms.Conversion.Hash("GroupId") // Replace missing values in Features column with the default replacement value for its type. .Append(mlContext.Transforms.ReplaceMissingValues("Features")); - // Fit the pipeline on the training data. - var fittedPipeline = pipeline.Fit(trainData); - - // Use the fitted pipeline to transform the training and validation datasets. - var transformedTrainData = fittedPipeline.Transform(trainData); - var transformedValidationData = fittedPipeline.Transform(validationData); + // Fit the pipeline and transform the dataset. + var transformedData = pipeline.Fit(data).Transform(data); - return (transformedTrainData, transformedValidationData); + return transformedData; } /// From d862c3bd8f53e31454d555a1ce31fa44ba15286f Mon Sep 17 00:00:00 2001 From: "REDMOND\\nakazmi" Date: Fri, 22 Feb 2019 19:32:08 -0800 Subject: [PATCH 05/24] nit --- .../Dynamic/Trainers/Ranking/LightGBMRanking.cs | 2 +- .../Dynamic/Trainers/Ranking/LightGBMRankingWithOptions.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Ranking/LightGBMRanking.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Ranking/LightGBMRanking.cs index b5857e4538..eccf87af8c 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Ranking/LightGBMRanking.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Ranking/LightGBMRanking.cs @@ -31,7 +31,7 @@ public static void Example() // Evaluate how the model is doing on the test data. var dataWithPredictions = model.Transform(split.TestSet); - var metrics = mlContext.Ranking.Evaluate(dataWithPredictions, "Label", "GroupId"); + var metrics = mlContext.Ranking.Evaluate(dataWithPredictions); SamplesUtils.ConsoleUtils.PrintMetrics(metrics); // Expected output: diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Ranking/LightGBMRankingWithOptions.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Ranking/LightGBMRankingWithOptions.cs index 30087131d8..c142881716 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Ranking/LightGBMRankingWithOptions.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Ranking/LightGBMRankingWithOptions.cs @@ -34,7 +34,7 @@ public static void Example() // Evaluate how the model is doing on the test data. var dataWithPredictions = model.Transform(split.TestSet); - var metrics = mlContext.Ranking.Evaluate(dataWithPredictions, "Label", "GroupId"); + var metrics = mlContext.Ranking.Evaluate(dataWithPredictions); SamplesUtils.ConsoleUtils.PrintMetrics(metrics); // Expected output: From 9fe82330fb5e14f94d0bf4823ef6e2212a8365b4 Mon Sep 17 00:00:00 2001 From: Scott Inglis Date: Sat, 23 Feb 2019 06:24:13 -0800 Subject: [PATCH 06/24] - Fixes the project reference path for OnnxTransformer. (#2705) Found while fixing #689, moved to separate commit. --- .../Microsoft.ML.DnnImageFeaturizer.AlexNet.nupkgproj | 2 +- .../Microsoft.ML.DnnImageFeaturizer.ResNet101.nupkgproj | 2 +- .../Microsoft.ML.DnnImageFeaturizer.ResNet18.nupkgproj | 2 +- .../Microsoft.ML.DnnImageFeaturizer.ResNet50.nupkgproj | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/Microsoft.ML.DnnImageFeaturizer.AlexNet/Microsoft.ML.DnnImageFeaturizer.AlexNet.nupkgproj b/pkg/Microsoft.ML.DnnImageFeaturizer.AlexNet/Microsoft.ML.DnnImageFeaturizer.AlexNet.nupkgproj index 32daa94431..4fb4e52d0a 100644 --- a/pkg/Microsoft.ML.DnnImageFeaturizer.AlexNet/Microsoft.ML.DnnImageFeaturizer.AlexNet.nupkgproj +++ b/pkg/Microsoft.ML.DnnImageFeaturizer.AlexNet/Microsoft.ML.DnnImageFeaturizer.AlexNet.nupkgproj @@ -6,7 +6,7 @@ - + diff --git a/pkg/Microsoft.ML.DnnImageFeaturizer.ResNet101/Microsoft.ML.DnnImageFeaturizer.ResNet101.nupkgproj b/pkg/Microsoft.ML.DnnImageFeaturizer.ResNet101/Microsoft.ML.DnnImageFeaturizer.ResNet101.nupkgproj index 2172b1e63c..3d667604cd 100644 --- a/pkg/Microsoft.ML.DnnImageFeaturizer.ResNet101/Microsoft.ML.DnnImageFeaturizer.ResNet101.nupkgproj +++ b/pkg/Microsoft.ML.DnnImageFeaturizer.ResNet101/Microsoft.ML.DnnImageFeaturizer.ResNet101.nupkgproj @@ -6,7 +6,7 @@ - + diff --git a/pkg/Microsoft.ML.DnnImageFeaturizer.ResNet18/Microsoft.ML.DnnImageFeaturizer.ResNet18.nupkgproj b/pkg/Microsoft.ML.DnnImageFeaturizer.ResNet18/Microsoft.ML.DnnImageFeaturizer.ResNet18.nupkgproj index 53768fff8b..1055b4cbbe 100644 --- a/pkg/Microsoft.ML.DnnImageFeaturizer.ResNet18/Microsoft.ML.DnnImageFeaturizer.ResNet18.nupkgproj +++ b/pkg/Microsoft.ML.DnnImageFeaturizer.ResNet18/Microsoft.ML.DnnImageFeaturizer.ResNet18.nupkgproj @@ -6,7 +6,7 @@ - + diff --git a/pkg/Microsoft.ML.DnnImageFeaturizer.ResNet50/Microsoft.ML.DnnImageFeaturizer.ResNet50.nupkgproj b/pkg/Microsoft.ML.DnnImageFeaturizer.ResNet50/Microsoft.ML.DnnImageFeaturizer.ResNet50.nupkgproj index d40f7fdc4c..2c33df9ff8 100644 --- a/pkg/Microsoft.ML.DnnImageFeaturizer.ResNet50/Microsoft.ML.DnnImageFeaturizer.ResNet50.nupkgproj +++ b/pkg/Microsoft.ML.DnnImageFeaturizer.ResNet50/Microsoft.ML.DnnImageFeaturizer.ResNet50.nupkgproj @@ -6,7 +6,7 @@ - + From 160eade3dfbda59bee2450bafb7ec877aa422dbd Mon Sep 17 00:00:00 2001 From: Scott Inglis Date: Sat, 23 Feb 2019 09:05:57 -0800 Subject: [PATCH 07/24] - Removes ResultProcessor, Maml and Sweeper from Microsoft.ML nuget. (#2690) This fixes #689 --- src/Microsoft.ML.Maml/Microsoft.ML.Maml.csproj | 3 +-- .../Microsoft.ML.ResultProcessor.csproj | 1 - src/Microsoft.ML.Sweeper/Microsoft.ML.Sweeper.csproj | 1 - 3 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/Microsoft.ML.Maml/Microsoft.ML.Maml.csproj b/src/Microsoft.ML.Maml/Microsoft.ML.Maml.csproj index a366fb6f9c..d9603a7aef 100644 --- a/src/Microsoft.ML.Maml/Microsoft.ML.Maml.csproj +++ b/src/Microsoft.ML.Maml/Microsoft.ML.Maml.csproj @@ -3,7 +3,6 @@ true CORECLR - Microsoft.ML netstandard2.0 @@ -11,4 +10,4 @@ - \ No newline at end of file + diff --git a/src/Microsoft.ML.ResultProcessor/Microsoft.ML.ResultProcessor.csproj b/src/Microsoft.ML.ResultProcessor/Microsoft.ML.ResultProcessor.csproj index e0f084d70b..158d6424c7 100644 --- a/src/Microsoft.ML.ResultProcessor/Microsoft.ML.ResultProcessor.csproj +++ b/src/Microsoft.ML.ResultProcessor/Microsoft.ML.ResultProcessor.csproj @@ -2,7 +2,6 @@ netstandard2.0 - Microsoft.ML CORECLR true diff --git a/src/Microsoft.ML.Sweeper/Microsoft.ML.Sweeper.csproj b/src/Microsoft.ML.Sweeper/Microsoft.ML.Sweeper.csproj index 9ed5d25e0e..9c08ba85af 100644 --- a/src/Microsoft.ML.Sweeper/Microsoft.ML.Sweeper.csproj +++ b/src/Microsoft.ML.Sweeper/Microsoft.ML.Sweeper.csproj @@ -2,7 +2,6 @@ netstandard2.0 - Microsoft.ML CORECLR true From eecf2727123e062f80d259ac66b68cf01c4b7078 Mon Sep 17 00:00:00 2001 From: Zeeshan Siddiqui Date: Sat, 23 Feb 2019 14:10:53 -0800 Subject: [PATCH 08/24] Remove MD5Hasher. (#2706) --- .../BinFile/IniFileParserInterface.cs | 2 - .../Dataset/DenseIntArray.cs | 27 ---- src/Microsoft.ML.FastTree/Dataset/Feature.cs | 8 +- src/Microsoft.ML.FastTree/Dataset/IntArray.cs | 2 - .../Dataset/RepeatIntArray.cs | 5 - .../Dataset/SegmentIntArray.cs | 5 - .../Dataset/SparseIntArray.cs | 5 - src/Microsoft.ML.FastTree/Utils/MD5Hasher.cs | 148 ------------------ .../Utils/ToByteArrayExtensions.cs | 39 ----- 9 files changed, 1 insertion(+), 240 deletions(-) delete mode 100644 src/Microsoft.ML.FastTree/Utils/MD5Hasher.cs diff --git a/src/Microsoft.ML.FastTree/BinFile/IniFileParserInterface.cs b/src/Microsoft.ML.FastTree/BinFile/IniFileParserInterface.cs index 257b9e83b5..5488adca16 100644 --- a/src/Microsoft.ML.FastTree/BinFile/IniFileParserInterface.cs +++ b/src/Microsoft.ML.FastTree/BinFile/IniFileParserInterface.cs @@ -254,8 +254,6 @@ public sealed class FeatureEvaluator public int Id { get; } - public MD5Hash ContentMD5Hash => MD5Hasher.Hash(Content); - // Return the name of the input public unsafe string Name => _parserInterface.GetInputName(Id); diff --git a/src/Microsoft.ML.FastTree/Dataset/DenseIntArray.cs b/src/Microsoft.ML.FastTree/Dataset/DenseIntArray.cs index 68c33a0d2d..b72d1d2604 100644 --- a/src/Microsoft.ML.FastTree/Dataset/DenseIntArray.cs +++ b/src/Microsoft.ML.FastTree/Dataset/DenseIntArray.cs @@ -155,11 +155,6 @@ public Dense0BitIntArray(byte[] buffer, ref int position) { } - public override MD5Hash MD5Hash - { - get { return MD5Hasher.Hash(Length); } - } - /// /// Returns the number of bytes written by the member ToByteArray() /// @@ -271,11 +266,6 @@ private void Set(long offset, uint mask, int value) _data[major + 1] = (_data[major + 1] & ~major1Mask) | (uint)(val >> 32); } - public override MD5Hash MD5Hash - { - get { return MD5Hasher.Hash(_data); } - } - /// /// Returns the number of bytes written by the member ToByteArray() /// @@ -414,8 +404,6 @@ public Dense8BitIntArray(int len, IEnumerable values) _data = values.Select(i => (byte)i).ToArray(len); } - public override MD5Hash MD5Hash => MD5Hasher.Hash(_data); - /// /// Returns the number of bytes written by the member ToByteArray() /// @@ -482,11 +470,6 @@ internal sealed class Dense4BitIntArray : DenseIntArray public override IntArrayBits BitsPerItem { get { return IntArrayBits.Bits4; } } - public override MD5Hash MD5Hash - { - get { return MD5Hasher.Hash(_data); } - } - public Dense4BitIntArray(int len) : base(len) { @@ -622,11 +605,6 @@ public Dense16BitIntArray(byte[] buffer, ref int position) _data = buffer.ToUShortArray(ref position); } - public override MD5Hash MD5Hash - { - get { return MD5Hasher.Hash(_data); } - } - public override unsafe void Callback(Action callback) { fixed (ushort* pData = _data) @@ -719,11 +697,6 @@ public override unsafe void Callback(Action callback) } } - public override MD5Hash MD5Hash - { - get { return MD5Hasher.Hash(_data); } - } - /// /// Returns the number of bytes written by the member ToByteArray() /// diff --git a/src/Microsoft.ML.FastTree/Dataset/Feature.cs b/src/Microsoft.ML.FastTree/Dataset/Feature.cs index d16b44d6e4..fb8ced8c5e 100644 --- a/src/Microsoft.ML.FastTree/Dataset/Feature.cs +++ b/src/Microsoft.ML.FastTree/Dataset/Feature.cs @@ -33,7 +33,7 @@ public enum FeatureType #endif public bool IsTrivialFeature { get; private set; } - public MD5Hash MD5Hash { get; private set; } + public IntArrayType BinsType { get; private set; } #if !NO_STORE public FileObjectStore BinsCache { get; set; } @@ -45,12 +45,6 @@ protected Feature(IntArray bins) BinsCache = FileObjectStore.GetDefaultInstance(); #endif IsTrivialFeature = bins.BitsPerItem == IntArrayBits.Bits0; - - if (!IsTrivialFeature && bins.Length > 0) - { - MD5Hash = bins.MD5Hash; - } - BinsType = bins.Type; } diff --git a/src/Microsoft.ML.FastTree/Dataset/IntArray.cs b/src/Microsoft.ML.FastTree/Dataset/IntArray.cs index b67bc4968a..0f22d7291d 100644 --- a/src/Microsoft.ML.FastTree/Dataset/IntArray.cs +++ b/src/Microsoft.ML.FastTree/Dataset/IntArray.cs @@ -55,8 +55,6 @@ public virtual void ToByteArray(byte[] buffer, ref int position) public abstract IntArrayType Type { get; } - public abstract MD5Hash MD5Hash { get; } - /// /// Number of bytes needed to store this number of values /// diff --git a/src/Microsoft.ML.FastTree/Dataset/RepeatIntArray.cs b/src/Microsoft.ML.FastTree/Dataset/RepeatIntArray.cs index ac176c20ec..007b56b05c 100644 --- a/src/Microsoft.ML.FastTree/Dataset/RepeatIntArray.cs +++ b/src/Microsoft.ML.FastTree/Dataset/RepeatIntArray.cs @@ -105,11 +105,6 @@ public override int SizeInBytes() return _values.SizeInBytes() + _deltas.SizeInBytes() + sizeof(int) + base.SizeInBytes(); } - public override MD5Hash MD5Hash - { - get { return MD5Hasher.Hash(_deltas) ^ _values.MD5Hash; } - } - public override int Length { get { return _length; } } public override IntArray Clone(IntArrayBits bitsPerItem, IntArrayType type) diff --git a/src/Microsoft.ML.FastTree/Dataset/SegmentIntArray.cs b/src/Microsoft.ML.FastTree/Dataset/SegmentIntArray.cs index bfeb19f2f2..f0cbddd41f 100644 --- a/src/Microsoft.ML.FastTree/Dataset/SegmentIntArray.cs +++ b/src/Microsoft.ML.FastTree/Dataset/SegmentIntArray.cs @@ -34,11 +34,6 @@ public override IntArrayBits BitsPerItem get { return _bpi; } } - public override MD5Hash MD5Hash - { - get { return MD5Hasher.Hash(_data) ^ MD5Hasher.Hash(_segLength) ^ MD5Hasher.Hash(_segType); } - } - public override IntArrayType Type { get { return IntArrayType.Segmented; } diff --git a/src/Microsoft.ML.FastTree/Dataset/SparseIntArray.cs b/src/Microsoft.ML.FastTree/Dataset/SparseIntArray.cs index b9e5cc0f28..be4f53e69e 100644 --- a/src/Microsoft.ML.FastTree/Dataset/SparseIntArray.cs +++ b/src/Microsoft.ML.FastTree/Dataset/SparseIntArray.cs @@ -251,11 +251,6 @@ public override IntArrayBits BitsPerItem public override IntArrayType Type { get { return IntArrayType.Sparse; } } - public override MD5Hash MD5Hash - { - get { return MD5Hasher.Hash(_deltas) ^ _values.MD5Hash; } - } - public override IntArray Clone(IntArrayBits bitsPerItem, IntArrayType type) { if (type == IntArrayType.Sparse || type == IntArrayType.Current) diff --git a/src/Microsoft.ML.FastTree/Utils/MD5Hasher.cs b/src/Microsoft.ML.FastTree/Utils/MD5Hasher.cs deleted file mode 100644 index fb2b1dd8b2..0000000000 --- a/src/Microsoft.ML.FastTree/Utils/MD5Hasher.cs +++ /dev/null @@ -1,148 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.IO; -using System.Security.Cryptography; -using Microsoft.ML.Internal.Utilities; - -namespace Microsoft.ML.Trainers.FastTree -{ - internal struct MD5Hash - { - public UInt64 Prefix; - public UInt64 Suffix; - - internal MD5Hash(byte[] array) - { - Contracts.Assert(Utils.Size(array) == SizeInBytes()); - Prefix = BitConverter.ToUInt64(array, 0); - Suffix = BitConverter.ToUInt64(array, 8); - } - - public static MD5Hash operator ^(MD5Hash first, MD5Hash second) - { - MD5Hash result = new MD5Hash - { - Prefix = first.Prefix ^ second.Prefix, - Suffix = first.Suffix ^ second.Suffix - }; - return result; - } - - public static int SizeInBytes() { return 16; } - - public void ToByteArray(byte[] buffer, ref int position) - { - Prefix.ToByteArray(buffer, ref position); - Suffix.ToByteArray(buffer, ref position); - } - } - - internal static class MD5Hasher - { - public static MD5Hash Hash(byte[] array) - { - // REVIEW: Consider using murmur hash for this. Or at least, make - // this more memory efficient. - var hasher = new MD5CryptoServiceProvider(); - return new MD5Hash(hasher.ComputeHash(array)); - } - - private static MD5Hash Hash(Stream stream) - { - var hasher = new MD5CryptoServiceProvider(); - return new MD5Hash(hasher.ComputeHash(stream)); - } - - private static unsafe MD5Hash Hash(byte* ptr, int length) - { - var stream = new UnmanagedMemoryStream(ptr, length); - return Hash(stream); - } - - public static MD5Hash Hash(string str) - { - MemoryStream stream = new MemoryStream(); - StreamWriter writer = new StreamWriter(stream); - writer.Write(str); - writer.Flush(); - stream.Seek(0, SeekOrigin.Begin); - return Hash(stream); - } - - public static MD5Hash Hash(int a) - { - unsafe - { - return Hash((byte*)&a, sizeof(int)); - } - } - - public static MD5Hash Hash(short[] array) - { - unsafe - { - fixed (short* pArray = array) - { - byte* bArray = (byte*)pArray; - int byteLength = array.Length * sizeof(short); - return Hash(bArray, byteLength); - } - } - } - - public static MD5Hash Hash(ushort[] array) - { - unsafe - { - fixed (ushort* pArray = array) - { - byte* bArray = (byte*)pArray; - int byteLength = array.Length * sizeof(ushort); - return Hash(bArray, byteLength); - } - } - } - - public static MD5Hash Hash(int[] array) - { - unsafe - { - fixed (int* pArray = array) - { - byte* bArray = (byte*)pArray; - int byteLength = array.Length * sizeof(int); - return Hash(bArray, byteLength); - } - } - } - - public static MD5Hash Hash(uint[] array) - { - unsafe - { - fixed (uint* pArray = array) - { - byte* bArray = (byte*)pArray; - int byteLength = array.Length * sizeof(uint); - return Hash(bArray, byteLength); - } - } - } - - public static MD5Hash Hash(double[] array) - { - unsafe - { - fixed (double* pArray = array) - { - byte* bArray = (byte*)pArray; - int byteLength = array.Length * sizeof(double); - return Hash(bArray, byteLength); - } - } - } - } -} diff --git a/src/Microsoft.ML.FastTree/Utils/ToByteArrayExtensions.cs b/src/Microsoft.ML.FastTree/Utils/ToByteArrayExtensions.cs index 64d35f86b5..3ab2433da3 100644 --- a/src/Microsoft.ML.FastTree/Utils/ToByteArrayExtensions.cs +++ b/src/Microsoft.ML.FastTree/Utils/ToByteArrayExtensions.cs @@ -194,18 +194,6 @@ public static ulong ToULong(this byte[] buffer, ref int position) return a; } - // RowId - - public static MD5Hash ToRowId(this byte[] buffer, ref int position) - { - MD5Hash a = new MD5Hash - { - Prefix = buffer.ToULong(ref position), - Suffix = buffer.ToULong(ref position) - }; - return a; - } - // float public static int SizeInBytes(this float a) @@ -550,33 +538,6 @@ public static unsafe ulong[] ToULongArray(this byte[] buffer, ref int position) return a; } - // RowId[] - - public static int SizeInBytes(this MD5Hash[] array) - { - return sizeof(int) + Utils.Size(array) * MD5Hash.SizeInBytes(); - } - - public static void ToByteArray(this MD5Hash[] a, byte[] buffer, ref int position) - { - a.Length.ToByteArray(buffer, ref position); - for (int i = 0; i < a.Length; ++i) - { - a[i].ToByteArray(buffer, ref position); - } - } - - public static unsafe MD5Hash[] ToRowIdArray(this byte[] buffer, ref int position) - { - int length = buffer.ToInt(ref position); - MD5Hash[] a = new MD5Hash[length]; - for (int i = 0; i < length; ++i) - { - a[i] = buffer.ToRowId(ref position); - } - return a; - } - // float[] public static int SizeInBytes(this float[] array) From f063510edbdfd0046c526e3a69246671a187cbea Mon Sep 17 00:00:00 2001 From: Ivan Matantsev Date: Sat, 23 Feb 2019 16:05:30 -0800 Subject: [PATCH 09/24] Hide delegates, model parameters classes, move onFit to staticPIpe, get rid of trivial transformWrapper (#2701) --- src/Microsoft.ML.Core/Data/InPredicate.cs | 3 ++- .../DataLoadSave/TransformWrapper.cs | 22 ------------------- src/Microsoft.ML.Data/Dirty/ILoss.cs | 9 ++++---- .../Transforms/ValueToKeyMappingEstimator.cs | 21 ------------------ .../GamClassification.cs | 2 +- src/Microsoft.ML.FastTree/GamRegression.cs | 2 +- src/Microsoft.ML.PCA/PcaTrainer.cs | 2 +- ...wareFactorizationMachineModelParameters.cs | 2 +- .../Standard/LinearModelParameters.cs | 8 +++---- .../MulticlassLogisticRegression.cs | 2 +- .../MultiClass/MultiClassNaiveBayesTrainer.cs | 2 +- .../CategoricalStaticExtensions.cs | 1 + .../TermStaticExtensions.cs | 22 +++++++++++++++++-- .../TermStaticExtensions.tt | 22 +++++++++++++++++-- 14 files changed, 57 insertions(+), 63 deletions(-) diff --git a/src/Microsoft.ML.Core/Data/InPredicate.cs b/src/Microsoft.ML.Core/Data/InPredicate.cs index 3c35bf600a..86d716356a 100644 --- a/src/Microsoft.ML.Core/Data/InPredicate.cs +++ b/src/Microsoft.ML.Core/Data/InPredicate.cs @@ -4,5 +4,6 @@ namespace Microsoft.ML.Data { - public delegate bool InPredicate(in T value); + [BestFriend] + internal delegate bool InPredicate(in T value); } diff --git a/src/Microsoft.ML.Data/DataLoadSave/TransformWrapper.cs b/src/Microsoft.ML.Data/DataLoadSave/TransformWrapper.cs index 0014ae638e..c822568cf1 100644 --- a/src/Microsoft.ML.Data/DataLoadSave/TransformWrapper.cs +++ b/src/Microsoft.ML.Data/DataLoadSave/TransformWrapper.cs @@ -168,26 +168,4 @@ public SchemaShape GetOutputSchema(SchemaShape inputSchema) return SchemaShape.Create(transformer.GetOutputSchema(fakeSchema)); } } - - /// - /// Estimator for untrained wrapped transformers. - /// - public abstract class TrivialWrapperEstimator : TrivialEstimator - { - protected TrivialWrapperEstimator(IHost host, TransformWrapper transformer) - : base(host, transformer) - { - } - - /// - /// Returns the of the schema which will be produced by the transformer. - /// Used for schema propagation and verification in a pipeline. - /// - public override SchemaShape GetOutputSchema(SchemaShape inputSchema) - { - Host.CheckValue(inputSchema, nameof(inputSchema)); - var fakeSchema = FakeSchemaFactory.Create(inputSchema); - return SchemaShape.Create(Transformer.GetOutputSchema(fakeSchema)); - } - } } diff --git a/src/Microsoft.ML.Data/Dirty/ILoss.cs b/src/Microsoft.ML.Data/Dirty/ILoss.cs index 1bb1350e0b..6e35c17bea 100644 --- a/src/Microsoft.ML.Data/Dirty/ILoss.cs +++ b/src/Microsoft.ML.Data/Dirty/ILoss.cs @@ -4,7 +4,6 @@ using System; using Microsoft.ML.EntryPoints; -using Float = System.Single; namespace Microsoft.ML { @@ -17,12 +16,12 @@ public interface ILossFunction Double Loss(TOutput output, TLabel label); } - public interface IScalarOutputLoss : ILossFunction + public interface IScalarOutputLoss : ILossFunction { /// /// Derivative of the loss function with respect to output /// - Float Derivative(Float output, Float label); + float Derivative(float output, float label); } [TlcModule.ComponentKind("RegressionLossFunction")] @@ -46,10 +45,10 @@ public interface IClassificationLoss : IScalarOutputLoss /// /// Delegate signature for standardized classification loss functions. /// - public delegate void SignatureClassificationLoss(); + internal delegate void SignatureClassificationLoss(); /// /// Delegate signature for standardized regression loss functions. /// - public delegate void SignatureRegressionLoss(); + internal delegate void SignatureRegressionLoss(); } diff --git a/src/Microsoft.ML.Data/Transforms/ValueToKeyMappingEstimator.cs b/src/Microsoft.ML.Data/Transforms/ValueToKeyMappingEstimator.cs index 1b2106ccaa..9521da3766 100644 --- a/src/Microsoft.ML.Data/Transforms/ValueToKeyMappingEstimator.cs +++ b/src/Microsoft.ML.Data/Transforms/ValueToKeyMappingEstimator.cs @@ -159,25 +159,4 @@ public enum KeyValueOrder : byte /// Value = ValueToKeyMappingEstimator.SortOrder.Value } - - /// - /// Information on the result of fitting a to-key transform. - /// - /// The type of the values. - public sealed class ToKeyFitResult - { - /// - /// For user defined delegates that accept instances of the containing type. - /// - /// - public delegate void OnFit(ToKeyFitResult result); - - // At the moment this is empty. Once PR #863 clears, we can change this class to hold the output - // key-values metadata. - - [BestFriend] - internal ToKeyFitResult(ValueToKeyMappingTransformer.TermMap map) - { - } - } } diff --git a/src/Microsoft.ML.FastTree/GamClassification.cs b/src/Microsoft.ML.FastTree/GamClassification.cs index fb7262ece8..92c65471c9 100644 --- a/src/Microsoft.ML.FastTree/GamClassification.cs +++ b/src/Microsoft.ML.FastTree/GamClassification.cs @@ -180,7 +180,7 @@ public sealed class BinaryClassificationGamModelParameters : GamModelParametersB /// A map from the feature shape functions (as described by the binUpperBounds and BinEffects) /// to the input feature. Used when the number of input features is different than the number of shape functions. Use default if all features have /// a shape function. - public BinaryClassificationGamModelParameters(IHostEnvironment env, + internal BinaryClassificationGamModelParameters(IHostEnvironment env, double[][] binUpperBounds, double[][] binEffects, double intercept, int inputLength, int[] featureToInputMap) : base(env, LoaderSignature, binUpperBounds, binEffects, intercept, inputLength, featureToInputMap) { } diff --git a/src/Microsoft.ML.FastTree/GamRegression.cs b/src/Microsoft.ML.FastTree/GamRegression.cs index c3defd7990..cc8a57532f 100644 --- a/src/Microsoft.ML.FastTree/GamRegression.cs +++ b/src/Microsoft.ML.FastTree/GamRegression.cs @@ -126,7 +126,7 @@ public sealed class RegressionGamModelParameters : GamModelParametersBase /// A map from the feature shape functions (as described by the binUpperBounds and BinEffects) /// to the input feature. Used when the number of input features is different than the number of shape functions. Use default if all features have /// a shape function. - public RegressionGamModelParameters(IHostEnvironment env, + internal RegressionGamModelParameters(IHostEnvironment env, double[][] binUpperBounds, double[][] binEffects, double intercept, int inputLength = -1, int[] featureToInputMap = null) : base(env, LoaderSignature, binUpperBounds, binEffects, intercept, inputLength, featureToInputMap) { } diff --git a/src/Microsoft.ML.PCA/PcaTrainer.cs b/src/Microsoft.ML.PCA/PcaTrainer.cs index abf2c8dbae..654cac0bdb 100644 --- a/src/Microsoft.ML.PCA/PcaTrainer.cs +++ b/src/Microsoft.ML.PCA/PcaTrainer.cs @@ -411,7 +411,7 @@ private static VersionInfo GetVersionInfo() /// The rank of the PCA approximation of the covariance matrix. This is the number of eigenvectors in the model. /// Array of eigenvectors. /// The mean vector of the training data. - public PcaModelParameters(IHostEnvironment env, int rank, float[][] eigenVectors, in VBuffer mean) + internal PcaModelParameters(IHostEnvironment env, int rank, float[][] eigenVectors, in VBuffer mean) : base(env, RegistrationName) { _dimension = eigenVectors[0].Length; diff --git a/src/Microsoft.ML.StandardLearners/FactorizationMachine/FieldAwareFactorizationMachineModelParameters.cs b/src/Microsoft.ML.StandardLearners/FactorizationMachine/FieldAwareFactorizationMachineModelParameters.cs index 80b7e10d35..78000c948d 100644 --- a/src/Microsoft.ML.StandardLearners/FactorizationMachine/FieldAwareFactorizationMachineModelParameters.cs +++ b/src/Microsoft.ML.StandardLearners/FactorizationMachine/FieldAwareFactorizationMachineModelParameters.cs @@ -57,7 +57,7 @@ private static VersionInfo GetVersionInfo() /// and each latent vector contains values. In the f-th field, the j-th feature's latent vector, `v_{j, f}` in the doc /// https://github.com/wschin/fast-ffm/blob/master/fast-ffm.pdf, starts at latentWeights[j * fieldCount * latentDim + f * latentDim]. /// The k-th element in v_{j, f} is latentWeights[j * fieldCount * latentDim + f * latentDim + k]. The size of the array must be featureCount x fieldCount x latentDim. - public FieldAwareFactorizationMachineModelParameters(IHostEnvironment env, bool norm, int fieldCount, int featureCount, int latentDim, + internal FieldAwareFactorizationMachineModelParameters(IHostEnvironment env, bool norm, int fieldCount, int featureCount, int latentDim, float[] linearWeights, float[] latentWeights) : base(env, LoaderSignature) { Host.Assert(fieldCount > 0); diff --git a/src/Microsoft.ML.StandardLearners/Standard/LinearModelParameters.cs b/src/Microsoft.ML.StandardLearners/Standard/LinearModelParameters.cs index 33d9823e65..e72c6c5615 100644 --- a/src/Microsoft.ML.StandardLearners/Standard/LinearModelParameters.cs +++ b/src/Microsoft.ML.StandardLearners/Standard/LinearModelParameters.cs @@ -115,7 +115,7 @@ public IEnumerator GetEnumerator() /// The weights for the linear model. The i-th element of weights is the coefficient /// of the i-th feature. Note that this will take ownership of the . /// The bias added to every output score. - public LinearModelParameters(IHostEnvironment env, string name, in VBuffer weights, float bias) + internal LinearModelParameters(IHostEnvironment env, string name, in VBuffer weights, float bias) : base(env, name) { Host.CheckParam(FloatUtils.IsFinite(weights.GetValues()), nameof(weights), "Cannot initialize linear predictor with non-finite weights"); @@ -436,7 +436,7 @@ private static VersionInfo GetVersionInfo() /// of the i-th feature. Note that this will take ownership of the . /// The bias added to every output score. /// - public LinearBinaryModelParameters(IHostEnvironment env, in VBuffer weights, float bias, LinearModelStatistics stats = null) + internal LinearBinaryModelParameters(IHostEnvironment env, in VBuffer weights, float bias, LinearModelStatistics stats = null) : base(env, RegistrationName, in weights, bias) { Contracts.AssertValueOrNull(stats); @@ -604,7 +604,7 @@ private static VersionInfo GetVersionInfo() /// The weights for the linear model. The i-th element of weights is the coefficient /// of the i-th feature. Note that this will take ownership of the . /// The bias added to every output score. - public LinearRegressionModelParameters(IHostEnvironment env, in VBuffer weights, float bias) + internal LinearRegressionModelParameters(IHostEnvironment env, in VBuffer weights, float bias) : base(env, RegistrationName, in weights, bias) { } @@ -687,7 +687,7 @@ private static VersionInfo GetVersionInfo() /// The weights for the linear model. The i-th element of weights is the coefficient /// of the i-th feature. Note that this will take ownership of the . /// The bias added to every output score. - public PoissonRegressionModelParameters(IHostEnvironment env, in VBuffer weights, float bias) + internal PoissonRegressionModelParameters(IHostEnvironment env, in VBuffer weights, float bias) : base(env, RegistrationName, in weights, bias) { } diff --git a/src/Microsoft.ML.StandardLearners/Standard/LogisticRegression/MulticlassLogisticRegression.cs b/src/Microsoft.ML.StandardLearners/Standard/LogisticRegression/MulticlassLogisticRegression.cs index 815b7b30ba..224921adc8 100644 --- a/src/Microsoft.ML.StandardLearners/Standard/LogisticRegression/MulticlassLogisticRegression.cs +++ b/src/Microsoft.ML.StandardLearners/Standard/LogisticRegression/MulticlassLogisticRegression.cs @@ -434,7 +434,7 @@ internal MulticlassLogisticRegressionModelParameters(IHostEnvironment env, in VB /// The length of the feature vector. /// The optional label names. If specified not null, it should have the same length as . /// The model statistics. - public MulticlassLogisticRegressionModelParameters(IHostEnvironment env, VBuffer[] weights, float[] bias, int numClasses, int numFeatures, string[] labelNames, LinearModelStatistics stats = null) + internal MulticlassLogisticRegressionModelParameters(IHostEnvironment env, VBuffer[] weights, float[] bias, int numClasses, int numFeatures, string[] labelNames, LinearModelStatistics stats = null) : base(env, RegistrationName) { Contracts.CheckValue(weights, nameof(weights)); diff --git a/src/Microsoft.ML.StandardLearners/Standard/MultiClass/MultiClassNaiveBayesTrainer.cs b/src/Microsoft.ML.StandardLearners/Standard/MultiClass/MultiClassNaiveBayesTrainer.cs index e3db654b18..9549e8d95f 100644 --- a/src/Microsoft.ML.StandardLearners/Standard/MultiClass/MultiClassNaiveBayesTrainer.cs +++ b/src/Microsoft.ML.StandardLearners/Standard/MultiClass/MultiClassNaiveBayesTrainer.cs @@ -254,7 +254,7 @@ public void GetFeatureHistogram(ref int[][] featureHistogram, out int labelCount /// The histogram of labels. /// The feature histogram. /// The number of features. - public MultiClassNaiveBayesModelParameters(IHostEnvironment env, int[] labelHistogram, int[][] featureHistogram, int featureCount) + internal MultiClassNaiveBayesModelParameters(IHostEnvironment env, int[] labelHistogram, int[][] featureHistogram, int featureCount) : base(env, LoaderSignature) { Host.AssertValue(labelHistogram); diff --git a/src/Microsoft.ML.StaticPipe/CategoricalStaticExtensions.cs b/src/Microsoft.ML.StaticPipe/CategoricalStaticExtensions.cs index af2e47fe66..11ccbbb6a5 100644 --- a/src/Microsoft.ML.StaticPipe/CategoricalStaticExtensions.cs +++ b/src/Microsoft.ML.StaticPipe/CategoricalStaticExtensions.cs @@ -7,6 +7,7 @@ using Microsoft.ML.StaticPipe.Runtime; using Microsoft.ML.Transforms.Categorical; using Microsoft.ML.Transforms.Conversions; +using static Microsoft.ML.StaticPipe.TermStaticExtensions; namespace Microsoft.ML.StaticPipe { diff --git a/src/Microsoft.ML.StaticPipe/TermStaticExtensions.cs b/src/Microsoft.ML.StaticPipe/TermStaticExtensions.cs index a879757239..c18d47f45a 100644 --- a/src/Microsoft.ML.StaticPipe/TermStaticExtensions.cs +++ b/src/Microsoft.ML.StaticPipe/TermStaticExtensions.cs @@ -3,8 +3,6 @@ // See the LICENSE file in the project root for more information. using System; -using Microsoft.ML; -using Microsoft.ML.StaticPipe; using Microsoft.ML.Transforms.Conversions; namespace Microsoft.ML.StaticPipe @@ -12,6 +10,26 @@ namespace Microsoft.ML.StaticPipe public static partial class TermStaticExtensions { // Do not edit this file directly. Rather, it is generated out of TermStaticExtensions.tt. + /// + /// Information on the result of fitting a to-key transform. + /// + /// The type of the values. + public sealed class ToKeyFitResult + { + /// + /// For user defined delegates that accept instances of the containing type. + /// + /// + public delegate void OnFit(ToKeyFitResult result); + + // At the moment this is empty. Once PR #863 clears, we can change this class to hold the output + // key-values metadata. + + [BestFriend] + internal ToKeyFitResult(ValueToKeyMappingTransformer.TermMap map) + { + } + } #region For string inputs. /// diff --git a/src/Microsoft.ML.StaticPipe/TermStaticExtensions.tt b/src/Microsoft.ML.StaticPipe/TermStaticExtensions.tt index fef9abf45a..a4c0409ec2 100644 --- a/src/Microsoft.ML.StaticPipe/TermStaticExtensions.tt +++ b/src/Microsoft.ML.StaticPipe/TermStaticExtensions.tt @@ -9,8 +9,6 @@ // See the LICENSE file in the project root for more information. using System; -using Microsoft.ML; -using Microsoft.ML.StaticPipe; using Microsoft.ML.Transforms.Conversions; namespace Microsoft.ML.StaticPipe @@ -18,6 +16,26 @@ namespace Microsoft.ML.StaticPipe public static partial class TermStaticExtensions { // Do not edit this file directly. Rather, it is generated out of TermStaticExtensions.tt. + /// + /// Information on the result of fitting a to-key transform. + /// + /// The type of the values. + public sealed class ToKeyFitResult + { + /// + /// For user defined delegates that accept instances of the containing type. + /// + /// + public delegate void OnFit(ToKeyFitResult result); + + // At the moment this is empty. Once PR #863 clears, we can change this class to hold the output + // key-values metadata. + + [BestFriend] + internal ToKeyFitResult(ValueToKeyMappingTransformer.TermMap map) + { + } + } <# // Let's skip the time-based types for now. foreach (string typeName in new string[] { "string", "float", "double", "sbyte", "short", "int", "long", "byte", "ushort", "uint", "ulong", "bool" }) { From 22844f676938a469286deb3f5ef6270509e43342 Mon Sep 17 00:00:00 2001 From: Eric Erhardt Date: Sat, 23 Feb 2019 20:20:08 -0600 Subject: [PATCH 10/24] Move the builder classes in DataViewSchema (#2703) * Move MetadataBuilder to be DataViewSchema.Metadata.Builder. * Move SchemaBuilder to DataViewSchema.Builder. * Rename `GetMetadata` and `GetSchema` to `ToMetadata` and `ToSchema` to follow the immutable collections pattern (and StringBuilder). Working towards #2297 --- src/Microsoft.Data.DataView/DataViewSchema.cs | 197 +++++++++++++++++- .../MetadataBuilder.cs | 133 ------------ src/Microsoft.Data.DataView/SchemaBuilder.cs | 77 ------- .../Data/MetadataBuilderExtensions.cs | 8 +- .../Data/SchemaExtensions.cs | 4 +- .../DataLoadSave/Binary/BinaryLoader.cs | 8 +- .../DataLoadSave/FakeSchema.cs | 8 +- .../DataLoadSave/Text/TextLoader.cs | 8 +- .../DataView/ArrayDataViewBuilder.cs | 8 +- .../DataView/DataViewConstructionUtils.cs | 4 +- src/Microsoft.ML.Data/DataView/Transposer.cs | 20 +- src/Microsoft.ML.Data/DataView/ZipBinding.cs | 4 +- .../Depricated/Instances/HeaderSchema.cs | 8 +- .../Dirty/ChooseColumnsByIndexTransform.cs | 4 +- .../Evaluators/BinaryClassifierEvaluator.cs | 12 +- .../Evaluators/ClusteringEvaluator.cs | 8 +- .../MultiClassClassifierEvaluator.cs | 12 +- .../MultiOutputRegressionEvaluator.cs | 8 +- .../Evaluators/QuantileRegressionEvaluator.cs | 8 +- .../Scorers/FeatureContributionCalculation.cs | 12 +- .../Scorers/MultiClassClassifierScorer.cs | 8 +- .../Scorers/PredictedLabelScorerBase.cs | 4 +- .../Scorers/ScoreSchemaFactory.cs | 32 +-- .../Transforms/ColumnBindingsBase.cs | 8 +- .../ColumnConcatenatingTransformer.cs | 4 +- ...atureContributionCalculationTransformer.cs | 4 +- src/Microsoft.ML.Data/Transforms/Hashing.cs | 6 +- .../Transforms/KeyToValue.cs | 4 +- .../Transforms/KeyToVector.cs | 6 +- .../Transforms/Normalizer.cs | 4 +- .../Transforms/SlotsDroppingTransformer.cs | 4 +- .../Transforms/TypeConverting.cs | 4 +- .../ValueToKeyMappingTransformer.cs | 4 +- .../ValueToKeyMappingTransformerImpl.cs | 8 +- src/Microsoft.ML.FastTree/FastTree.cs | 8 +- .../TreeEnsembleFeaturizer.cs | 16 +- src/Microsoft.ML.Parquet/ParquetLoader.cs | 4 +- .../PartitionedFileLoader.cs | 4 +- .../Standard/LinearModelParameters.cs | 8 +- .../Standard/ModelStatistics.cs | 12 +- .../TensorFlow/TensorflowUtils.cs | 8 +- ...SequentialAnomalyDetectionTransformBase.cs | 4 +- src/Microsoft.ML.Transforms/GcnTransform.cs | 4 +- src/Microsoft.ML.Transforms/GroupTransform.cs | 8 +- .../KeyToVectorMapping.cs | 6 +- .../MissingValueDroppingTransformer.cs | 4 +- .../MissingValueIndicatorTransformer.cs | 4 +- .../MissingValueReplacing.cs | 4 +- .../Text/NgramHashingTransformer.cs | 6 +- .../Text/NgramTransform.cs | 6 +- .../Text/TokenizingByCharacters.cs | 6 +- .../UngroupTransform.cs | 8 +- test/Microsoft.ML.Benchmarks/HashBench.cs | 4 +- .../StaticPipeTests.cs | 24 +-- test/Microsoft.ML.Tests/FakeSchemaTest.cs | 8 +- .../Transformers/HashTests.cs | 12 +- 56 files changed, 399 insertions(+), 420 deletions(-) delete mode 100644 src/Microsoft.Data.DataView/MetadataBuilder.cs delete mode 100644 src/Microsoft.Data.DataView/SchemaBuilder.cs diff --git a/src/Microsoft.Data.DataView/DataViewSchema.cs b/src/Microsoft.Data.DataView/DataViewSchema.cs index a916adb233..cc90fbe32a 100644 --- a/src/Microsoft.Data.DataView/DataViewSchema.cs +++ b/src/Microsoft.Data.DataView/DataViewSchema.cs @@ -14,7 +14,7 @@ namespace Microsoft.Data.DataView /// This class represents the of an object like, for interstance, an or an . /// On the high level, the schema is a collection of . /// - [System.Diagnostics.DebuggerTypeProxy(typeof(SchemaDebuggerProxy))] + [DebuggerTypeProxy(typeof(SchemaDebuggerProxy))] public sealed class DataViewSchema : IReadOnlyList { private readonly Column[] _columns; @@ -168,7 +168,7 @@ public DetachedColumn(Column column) /// /// The metadata of one . /// - [System.Diagnostics.DebuggerTypeProxy(typeof(MetadataDebuggerProxy))] + [DebuggerTypeProxy(typeof(MetadataDebuggerProxy))] public sealed class Metadata { /// @@ -248,13 +248,202 @@ internal Delegate GetGetterInternal(int index) Debug.Assert(0 <= index && index < Schema.Count); return _getters[index]; } + + /// + /// The class that incrementally builds a . + /// + public sealed class Builder + { + private readonly List<(string Name, DataViewType Type, Delegate Getter, Metadata Metadata)> _items; + + public Builder() + { + _items = new List<(string Name, DataViewType Type, Delegate Getter, Metadata Metadata)>(); + } + + /// + /// Add some columns from into our new metadata, by applying + /// to all the names. + /// + /// The metadata row to take values from. + /// The predicate describing which metadata columns to keep. + public void Add(Metadata metadata, Func selector) + { + if (metadata == null) + return; + + if (selector == null) + throw new ArgumentNullException(nameof(selector)); + + foreach (var column in metadata.Schema) + { + if (selector(column.Name)) + _items.Add((column.Name, column.Type, metadata.GetGetterInternal(column.Index), column.Metadata)); + } + } + + /// + /// Add one metadata column, strongly-typed version. + /// + /// The type of the value. + /// The metadata name. + /// The metadata type. + /// The getter delegate. + /// Metadata of the input column. Note that metadata on a metadata column is somewhat rare + /// except for certain types (for example, slot names for a vector, key values for something of key type). + public void Add(string name, DataViewType type, ValueGetter getter, Metadata metadata = null) + { + if (string.IsNullOrEmpty(name)) + throw new ArgumentNullException(nameof(name)); + if (type == null) + throw new ArgumentNullException(nameof(type)); + if (getter == null) + throw new ArgumentNullException(nameof(getter)); + if (type.RawType != typeof(TValue)) + throw new ArgumentException($"{nameof(type)}.{nameof(type.RawType)} must be of type '{typeof(TValue).FullName}'.", nameof(type)); + + _items.Add((name, type, getter, metadata)); + } + + /// + /// Add one metadata column, weakly-typed version. + /// + /// The metadata name. + /// The metadata type. + /// The getter delegate that provides the value. Note that the type of the getter is still checked + /// inside this method. + /// Metadata of the input column. Note that metadata on a metadata column is somewhat rare + /// except for certain types (for example, slot names for a vector, key values for something of key type). + public void Add(string name, DataViewType type, Delegate getter, Metadata metadata = null) + { + if (string.IsNullOrEmpty(name)) + throw new ArgumentNullException(nameof(name)); + if (type == null) + throw new ArgumentNullException(nameof(type)); + if (getter == null) + throw new ArgumentNullException(nameof(getter)); + + Utils.MarshalActionInvoke(AddDelegate, type.RawType, name, type, getter, metadata); + } + + /// + /// Add one metadata column for a primitive value type. + /// + /// The metadata name. + /// The metadata type. + /// The value of the metadata. + /// Metadata of the input column. Note that metadata on a metadata column is somewhat rare + /// except for certain types (for example, slot names for a vector, key values for something of key type). + public void AddPrimitiveValue(string name, PrimitiveDataViewType type, TValue value, Metadata metadata = null) + { + if (string.IsNullOrEmpty(name)) + throw new ArgumentNullException(nameof(name)); + if (type == null) + throw new ArgumentNullException(nameof(type)); + if (type.RawType != typeof(TValue)) + throw new ArgumentException($"{nameof(type)}.{nameof(type.RawType)} must be of type '{typeof(TValue).FullName}'.", nameof(type)); + + Add(name, type, (ref TValue dst) => dst = value, metadata); + } + + /// + /// Returns a row that contains the current contents of this . + /// + public Metadata ToMetadata() + { + var builder = new DataViewSchema.Builder(); + foreach (var item in _items) + builder.AddColumn(item.Name, item.Type, item.Metadata); + return new Metadata(builder.ToSchema(), _items.Select(x => x.Getter).ToArray()); + } + + private void AddDelegate(string name, DataViewType type, Delegate getter, Metadata metadata) + { + Debug.Assert(!string.IsNullOrEmpty(name)); + Debug.Assert(type != null); + Debug.Assert(getter != null); + + var typedGetter = getter as ValueGetter; + if (typedGetter == null) + throw new ArgumentException($"{nameof(getter)} must be of type '{typeof(ValueGetter).FullName}'", nameof(getter)); + _items.Add((name, type, typedGetter, metadata)); + } + } + } + + /// + /// The class that incrementally builds a . + /// + public sealed class Builder + { + private readonly List<(string Name, DataViewType Type, Metadata Metadata)> _items; + + /// + /// Create a new instance of . + /// + public Builder() + { + _items = new List<(string Name, DataViewType Type, Metadata Metadata)>(); + } + + /// + /// Add one column to the schema being built. + /// + /// The column name. + /// The column type. + /// The column metadata. + public void AddColumn(string name, DataViewType type, Metadata metadata = null) + { + if (string.IsNullOrEmpty(name)) + throw new ArgumentNullException(nameof(name)); + if (type == null) + throw new ArgumentNullException(nameof(type)); + + _items.Add((name, type, metadata)); + } + + /// + /// Add multiple existing columns to the schema being built. + /// + /// Columns to add. + public void AddColumns(IEnumerable source) + { + foreach (var column in source) + AddColumn(column.Name, column.Type, column.Metadata); + } + + /// + /// Add multiple existing columns to the schema being built. + /// + /// Columns to add. + public void AddColumns(IEnumerable source) + { + foreach (var column in source) + AddColumn(column.Name, column.Type, column.Metadata); + } + + /// + /// Returns a that contains the current contents of this . + /// + public DataViewSchema ToSchema() + { + var nameMap = new Dictionary(); + for (int i = 0; i < _items.Count; i++) + nameMap[_items[i].Name] = i; + + var columns = new Column[_items.Count]; + for (int i = 0; i < columns.Length; i++) + columns[i] = new Column(_items[i].Name, i, nameMap[_items[i].Name] != i, _items[i].Type, _items[i].Metadata); + + return new DataViewSchema(columns); + } } /// - /// This constructor should only be called by . + /// This constructor should only be called by . /// /// The input columns. The constructed instance takes ownership of the array. - internal DataViewSchema(Column[] columns) + private DataViewSchema(Column[] columns) { if (columns == null) throw new ArgumentNullException(nameof(columns)); diff --git a/src/Microsoft.Data.DataView/MetadataBuilder.cs b/src/Microsoft.Data.DataView/MetadataBuilder.cs deleted file mode 100644 index e1b6b34a17..0000000000 --- a/src/Microsoft.Data.DataView/MetadataBuilder.cs +++ /dev/null @@ -1,133 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; - -namespace Microsoft.Data.DataView -{ - /// - /// The class that incrementally builds a . - /// - public sealed class MetadataBuilder - { - private readonly List<(string Name, DataViewType Type, Delegate Getter, DataViewSchema.Metadata Metadata)> _items; - - public MetadataBuilder() - { - _items = new List<(string Name, DataViewType Type, Delegate Getter, DataViewSchema.Metadata Metadata)>(); - } - - /// - /// Add some columns from into our new metadata, by applying - /// to all the names. - /// - /// The metadata row to take values from. - /// The predicate describing which metadata columns to keep. - public void Add(DataViewSchema.Metadata metadata, Func selector) - { - if (metadata == null) - return; - - if (selector == null) - throw new ArgumentNullException(nameof(selector)); - - foreach (var column in metadata.Schema) - { - if (selector(column.Name)) - _items.Add((column.Name, column.Type, metadata.GetGetterInternal(column.Index), column.Metadata)); - } - } - - /// - /// Add one metadata column, strongly-typed version. - /// - /// The type of the value. - /// The metadata name. - /// The metadata type. - /// The getter delegate. - /// Metadata of the input column. Note that metadata on a metadata column is somewhat rare - /// except for certain types (for example, slot names for a vector, key values for something of key type). - public void Add(string name, DataViewType type, ValueGetter getter, DataViewSchema.Metadata metadata = null) - { - if (string.IsNullOrEmpty(name)) - throw new ArgumentNullException(nameof(name)); - if (type == null) - throw new ArgumentNullException(nameof(type)); - if (getter == null) - throw new ArgumentNullException(nameof(getter)); - if (type.RawType != typeof(TValue)) - throw new ArgumentException($"{nameof(type)}.{nameof(type.RawType)} must be of type '{typeof(TValue).FullName}'.", nameof(type)); - - _items.Add((name, type, getter, metadata)); - } - - /// - /// Add one metadata column, weakly-typed version. - /// - /// The metadata name. - /// The metadata type. - /// The getter delegate that provides the value. Note that the type of the getter is still checked - /// inside this method. - /// Metadata of the input column. Note that metadata on a metadata column is somewhat rare - /// except for certain types (for example, slot names for a vector, key values for something of key type). - public void Add(string name, DataViewType type, Delegate getter, DataViewSchema.Metadata metadata = null) - { - if (string.IsNullOrEmpty(name)) - throw new ArgumentNullException(nameof(name)); - if (type == null) - throw new ArgumentNullException(nameof(type)); - if (getter == null) - throw new ArgumentNullException(nameof(getter)); - - Utils.MarshalActionInvoke(AddDelegate, type.RawType, name, type, getter, metadata); - } - - /// - /// Add one metadata column for a primitive value type. - /// - /// The metadata name. - /// The metadata type. - /// The value of the metadata. - /// Metadata of the input column. Note that metadata on a metadata column is somewhat rare - /// except for certain types (for example, slot names for a vector, key values for something of key type). - public void AddPrimitiveValue(string name, PrimitiveDataViewType type, TValue value, DataViewSchema.Metadata metadata = null) - { - if (string.IsNullOrEmpty(name)) - throw new ArgumentNullException(nameof(name)); - if (type == null) - throw new ArgumentNullException(nameof(type)); - if (type.RawType != typeof(TValue)) - throw new ArgumentException($"{nameof(type)}.{nameof(type.RawType)} must be of type '{typeof(TValue).FullName}'.", nameof(type)); - - Add(name, type, (ref TValue dst) => dst = value, metadata); - } - - /// - /// Produce the metadata row that the builder has so far. - /// Can be called multiple times. - /// - public DataViewSchema.Metadata GetMetadata() - { - var builder = new SchemaBuilder(); - foreach (var item in _items) - builder.AddColumn(item.Name, item.Type, item.Metadata); - return new DataViewSchema.Metadata(builder.GetSchema(), _items.Select(x => x.Getter).ToArray()); - } - - private void AddDelegate(string name, DataViewType type, Delegate getter, DataViewSchema.Metadata metadata) - { - Debug.Assert(!string.IsNullOrEmpty(name)); - Debug.Assert(type != null); - Debug.Assert(getter != null); - - var typedGetter = getter as ValueGetter; - if (typedGetter == null) - throw new ArgumentException($"{nameof(getter)} must be of type '{typeof(ValueGetter).FullName}'", nameof(getter)); - _items.Add((name, type, typedGetter, metadata)); - } - } -} diff --git a/src/Microsoft.Data.DataView/SchemaBuilder.cs b/src/Microsoft.Data.DataView/SchemaBuilder.cs deleted file mode 100644 index 9ee7f289ce..0000000000 --- a/src/Microsoft.Data.DataView/SchemaBuilder.cs +++ /dev/null @@ -1,77 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Collections.Generic; - -namespace Microsoft.Data.DataView -{ - /// - /// A builder for . - /// - public sealed class SchemaBuilder - { - private readonly List<(string Name, DataViewType Type, DataViewSchema.Metadata Metadata)> _items; - - /// - /// Create a new instance of . - /// - public SchemaBuilder() - { - _items = new List<(string Name, DataViewType Type, DataViewSchema.Metadata Metadata)>(); - } - - /// - /// Add one column to the schema being built. - /// - /// The column name. - /// The column type. - /// The column metadata. - public void AddColumn(string name, DataViewType type, DataViewSchema.Metadata metadata = null) - { - if (string.IsNullOrEmpty(name)) - throw new ArgumentNullException(nameof(name)); - if (type == null) - throw new ArgumentNullException(nameof(type)); - - _items.Add((name, type, metadata)); - } - - /// - /// Add multiple existing columns to the schema being built. - /// - /// Columns to add. - public void AddColumns(IEnumerable source) - { - foreach (var column in source) - AddColumn(column.Name, column.Type, column.Metadata); - } - - /// - /// Add multiple existing columns to the schema being built. - /// - /// Columns to add. - public void AddColumns(IEnumerable source) - { - foreach (var column in source) - AddColumn(column.Name, column.Type, column.Metadata); - } - - /// - /// Generate the final . - /// - public DataViewSchema GetSchema() - { - var nameMap = new Dictionary(); - for (int i = 0; i < _items.Count; i++) - nameMap[_items[i].Name] = i; - - var columns = new DataViewSchema.Column[_items.Count]; - for (int i = 0; i < columns.Length; i++) - columns[i] = new DataViewSchema.Column(_items[i].Name, i, nameMap[_items[i].Name] != i, _items[i].Type, _items[i].Metadata); - - return new DataViewSchema(columns); - } - } -} diff --git a/src/Microsoft.ML.Core/Data/MetadataBuilderExtensions.cs b/src/Microsoft.ML.Core/Data/MetadataBuilderExtensions.cs index 1392df0341..23ed78cab2 100644 --- a/src/Microsoft.ML.Core/Data/MetadataBuilderExtensions.cs +++ b/src/Microsoft.ML.Core/Data/MetadataBuilderExtensions.cs @@ -13,21 +13,21 @@ internal static class MetadataBuilderExtensions /// /// Add slot names metadata. /// - /// The MetadataBuilder to which to add the slot names. + /// The to which to add the slot names. /// The size of the slot names vector. /// The getter delegate for the slot names. - public static void AddSlotNames(this MetadataBuilder builder, int size, ValueGetter>> getter) + public static void AddSlotNames(this DataViewSchema.Metadata.Builder builder, int size, ValueGetter>> getter) => builder.Add(MetadataUtils.Kinds.SlotNames, new VectorType(TextDataViewType.Instance, size), getter); /// /// Add key values metadata. /// /// The value type of key values. - /// The MetadataBuilder to which to add the key values. + /// The to which to add the key values. /// The size of key values vector. /// The value type of key values. Its raw type must match . /// The getter delegate for the key values. - public static void AddKeyValues(this MetadataBuilder builder, int size, PrimitiveDataViewType valueType, ValueGetter> getter) + public static void AddKeyValues(this DataViewSchema.Metadata.Builder builder, int size, PrimitiveDataViewType valueType, ValueGetter> getter) => builder.Add(MetadataUtils.Kinds.KeyValues, new VectorType(valueType, size), getter); } } diff --git a/src/Microsoft.ML.Core/Data/SchemaExtensions.cs b/src/Microsoft.ML.Core/Data/SchemaExtensions.cs index 9edded5d69..bfc06887b9 100644 --- a/src/Microsoft.ML.Core/Data/SchemaExtensions.cs +++ b/src/Microsoft.ML.Core/Data/SchemaExtensions.cs @@ -12,9 +12,9 @@ internal static class SchemaExtensions { public static DataViewSchema MakeSchema(IEnumerable columns) { - var builder = new SchemaBuilder(); + var builder = new DataViewSchema.Builder(); builder.AddColumns(columns); - return builder.GetSchema(); + return builder.ToSchema(); } /// diff --git a/src/Microsoft.ML.Data/DataLoadSave/Binary/BinaryLoader.cs b/src/Microsoft.ML.Data/DataLoadSave/Binary/BinaryLoader.cs index 0e9ba19ebc..26bc6dd5b6 100644 --- a/src/Microsoft.ML.Data/DataLoadSave/Binary/BinaryLoader.cs +++ b/src/Microsoft.ML.Data/DataLoadSave/Binary/BinaryLoader.cs @@ -641,7 +641,7 @@ protected void EnsureValue() /// of loaded file. private DataViewSchema ComputeOutputSchema() { - var schemaBuilder = new SchemaBuilder(); + var schemaBuilder = new DataViewSchema.Builder(); for(int i = 0; i < _aliveColumns.Length; ++i) { @@ -653,7 +653,7 @@ private DataViewSchema ComputeOutputSchema() if (Utils.Size(metadataArray) > 0) { // We got some metadata fields here. - var metadataBuilder = new MetadataBuilder(); + var metadataBuilder = new DataViewSchema.Metadata.Builder(); foreach(var loadedMetadataColumn in metadataArray) { var metadataGetter = loadedMetadataColumn.GetGetter(); @@ -661,14 +661,14 @@ private DataViewSchema ComputeOutputSchema() throw MetadataUtils.ExceptGetMetadata(); metadataBuilder.Add(loadedMetadataColumn.Kind, loadedMetadataColumn.Codec.Type, metadataGetter); } - schemaBuilder.AddColumn(loadedColumn.Name, loadedColumn.Type, metadataBuilder.GetMetadata()); + schemaBuilder.AddColumn(loadedColumn.Name, loadedColumn.Type, metadataBuilder.ToMetadata()); } else // This case has no metadata. schemaBuilder.AddColumn(loadedColumn.Name, loadedColumn.Type); } - return schemaBuilder.GetSchema(); + return schemaBuilder.ToSchema(); } private readonly Stream _stream; diff --git a/src/Microsoft.ML.Data/DataLoadSave/FakeSchema.cs b/src/Microsoft.ML.Data/DataLoadSave/FakeSchema.cs index e62f5341d5..9d5ea86d37 100644 --- a/src/Microsoft.ML.Data/DataLoadSave/FakeSchema.cs +++ b/src/Microsoft.ML.Data/DataLoadSave/FakeSchema.cs @@ -20,11 +20,11 @@ internal static class FakeSchemaFactory public static DataViewSchema Create(SchemaShape shape) { - var builder = new SchemaBuilder(); + var builder = new DataViewSchema.Builder(); for (int i = 0; i < shape.Count; ++i) { - var metaBuilder = new MetadataBuilder(); + var metaBuilder = new DataViewSchema.Metadata.Builder(); var partialMetadata = shape[i].Metadata; for (int j = 0; j < partialMetadata.Count; ++j) { @@ -36,9 +36,9 @@ public static DataViewSchema Create(SchemaShape shape) del = Utils.MarshalInvoke(GetDefaultGetter, metaColumnType.RawType); metaBuilder.Add(partialMetadata[j].Name, metaColumnType, del); } - builder.AddColumn(shape[i].Name, MakeColumnType(shape[i]), metaBuilder.GetMetadata()); + builder.AddColumn(shape[i].Name, MakeColumnType(shape[i]), metaBuilder.ToMetadata()); } - return builder.GetSchema(); + return builder.ToSchema(); } private static DataViewType MakeColumnType(SchemaShape.Column column) diff --git a/src/Microsoft.ML.Data/DataLoadSave/Text/TextLoader.cs b/src/Microsoft.ML.Data/DataLoadSave/Text/TextLoader.cs index 10e622061b..f6e84a70c1 100644 --- a/src/Microsoft.ML.Data/DataLoadSave/Text/TextLoader.cs +++ b/src/Microsoft.ML.Data/DataLoadSave/Text/TextLoader.cs @@ -970,7 +970,7 @@ internal void Save(ModelSaveContext ctx) private DataViewSchema ComputeOutputSchema() { - var schemaBuilder = new SchemaBuilder(); + var schemaBuilder = new DataViewSchema.Builder(); // Iterate through all loaded columns. The index i indicates the i-th column loaded. for (int i = 0; i < Infos.Length; ++i) @@ -981,16 +981,16 @@ private DataViewSchema ComputeOutputSchema() if (names.Length > 0) { // Slot names present! Let's add them. - var metadataBuilder = new MetadataBuilder(); + var metadataBuilder = new DataViewSchema.Metadata.Builder(); metadataBuilder.AddSlotNames(names.Length, (ref VBuffer> value) => names.CopyTo(ref value)); - schemaBuilder.AddColumn(info.Name, info.ColType, metadataBuilder.GetMetadata()); + schemaBuilder.AddColumn(info.Name, info.ColType, metadataBuilder.ToMetadata()); } else // Slot names is empty. schemaBuilder.AddColumn(info.Name, info.ColType); } - return schemaBuilder.GetSchema(); + return schemaBuilder.ToSchema(); } } diff --git a/src/Microsoft.ML.Data/DataView/ArrayDataViewBuilder.cs b/src/Microsoft.ML.Data/DataView/ArrayDataViewBuilder.cs index 7ca685c0d9..f38e427d30 100644 --- a/src/Microsoft.ML.Data/DataView/ArrayDataViewBuilder.cs +++ b/src/Microsoft.ML.Data/DataView/ArrayDataViewBuilder.cs @@ -215,20 +215,20 @@ public DataView(IHostEnvironment env, ArrayDataViewBuilder builder, int rowCount _host.Assert(builder._names.Count == builder._columns.Count); _columns = builder._columns.ToArray(); - var schemaBuilder = new SchemaBuilder(); + var schemaBuilder = new DataViewSchema.Builder(); for(int i=0; i< _columns.Length; i++) { - var meta = new MetadataBuilder(); + var meta = new DataViewSchema.Metadata.Builder(); if (builder._getSlotNames.TryGetValue(builder._names[i], out var slotNamesGetter)) meta.AddSlotNames(_columns[i].Type.GetVectorSize(), slotNamesGetter); if (builder._getKeyValues.TryGetValue(builder._names[i], out var keyValueGetter)) meta.AddKeyValues(_columns[i].Type.GetKeyCountAsInt32(_host), TextDataViewType.Instance, keyValueGetter); - schemaBuilder.AddColumn(builder._names[i], _columns[i].Type, meta.GetMetadata()); + schemaBuilder.AddColumn(builder._names[i], _columns[i].Type, meta.ToMetadata()); } - _schema = schemaBuilder.GetSchema(); + _schema = schemaBuilder.ToSchema(); _rowCount = rowCount; } diff --git a/src/Microsoft.ML.Data/DataView/DataViewConstructionUtils.cs b/src/Microsoft.ML.Data/DataView/DataViewConstructionUtils.cs index bae95f6d36..0ef79abc8c 100644 --- a/src/Microsoft.ML.Data/DataView/DataViewConstructionUtils.cs +++ b/src/Microsoft.ML.Data/DataView/DataViewConstructionUtils.cs @@ -711,10 +711,10 @@ internal static DataViewSchema.DetachedColumn[] GetSchemaColumns(InternalSchemaD for (int i = 0; i < columns.Length; i++) { var col = schemaDefn.Columns[i]; - var meta = new MetadataBuilder(); + var meta = new DataViewSchema.Metadata.Builder(); foreach (var kvp in col.Metadata) meta.Add(kvp.Value.Kind, kvp.Value.MetadataType, kvp.Value.GetGetterDelegate()); - columns[i] = new DataViewSchema.DetachedColumn(col.ColumnName, col.ColumnType, meta.GetMetadata()); + columns[i] = new DataViewSchema.DetachedColumn(col.ColumnName, col.ColumnType, meta.ToMetadata()); } return columns; diff --git a/src/Microsoft.ML.Data/DataView/Transposer.cs b/src/Microsoft.ML.Data/DataView/Transposer.cs index fc2fc62c86..623bad22be 100644 --- a/src/Microsoft.ML.Data/DataView/Transposer.cs +++ b/src/Microsoft.ML.Data/DataView/Transposer.cs @@ -781,10 +781,10 @@ public DataViewSlicer(IHost host, IDataView input, int[] toSlice) _host.Assert(outputColumnCount == _colToSplitIndex.Length); // Sequentially concatenate output columns from all splitters to form output schema. - var schemaBuilder = new SchemaBuilder(); + var schemaBuilder = new DataViewSchema.Builder(); for (int c = 0; c < _splitters.Length; ++c) schemaBuilder.AddColumns(_splitters[c].OutputSchema); - Schema = schemaBuilder.GetSchema(); + Schema = schemaBuilder.ToSchema(); } public long? GetRowCount() @@ -1004,10 +1004,10 @@ public NoSplitter(IDataView view, int col) // The column selected for splitting. var selectedColumn = _view.Schema[col]; - var schemaBuilder = new SchemaBuilder(); + var schemaBuilder = new DataViewSchema.Builder(); // Just copy the selected column to output since no splitting happens. schemaBuilder.AddColumn(selectedColumn.Name, selectedColumn.Type, selectedColumn.Metadata); - OutputSchema = schemaBuilder.GetSchema(); + OutputSchema = schemaBuilder.ToSchema(); } public override DataViewRow Bind(DataViewRow row, Func pred) @@ -1088,10 +1088,10 @@ public ColumnSplitter(IDataView view, int col, int[] lims) _types[c] = new VectorType(type.ItemType, _lims[c] - _lims[c - 1]); var selectedColumn = _view.Schema[col]; - var schemaBuilder = new SchemaBuilder(); + var schemaBuilder = new DataViewSchema.Builder(); for (int c = 0; c < _lims.Length; ++c) schemaBuilder.AddColumn(selectedColumn.Name, _types[c]); - OutputSchema = schemaBuilder.GetSchema(); + OutputSchema = schemaBuilder.ToSchema(); } public override DataViewRow Bind(DataViewRow row, Func pred) @@ -1383,9 +1383,9 @@ public SlotDataView(IHostEnvironment env, ITransposeDataView data, int col) _data = data; _col = col; - var builder = new SchemaBuilder(); + var builder = new DataViewSchema.Builder(); builder.AddColumn(_data.Schema[_col].Name, _type); - Schema = builder.GetSchema(); + Schema = builder.ToSchema(); } public long? GetRowCount() @@ -1476,9 +1476,9 @@ public SlotRowCursorShim(IChannelProvider provider, SlotCursor cursor) Contracts.AssertValue(cursor); _slotCursor = cursor; - var builder = new SchemaBuilder(); + var builder = new DataViewSchema.Builder(); builder.AddColumn("Waffles", cursor.GetSlotType()); - Schema = builder.GetSchema(); + Schema = builder.ToSchema(); } public override bool IsColumnActive(int col) diff --git a/src/Microsoft.ML.Data/DataView/ZipBinding.cs b/src/Microsoft.ML.Data/DataView/ZipBinding.cs index e23423a259..1d5492198c 100644 --- a/src/Microsoft.ML.Data/DataView/ZipBinding.cs +++ b/src/Microsoft.ML.Data/DataView/ZipBinding.cs @@ -35,10 +35,10 @@ public ZipBinding(DataViewSchema[] sources) _cumulativeColCounts[i + 1] = _cumulativeColCounts[i] + schema.Count; } - var schemaBuilder = new SchemaBuilder(); + var schemaBuilder = new DataViewSchema.Builder(); foreach (var sourceSchema in sources) schemaBuilder.AddColumns(sourceSchema); - OutputSchema = schemaBuilder.GetSchema(); + OutputSchema = schemaBuilder.ToSchema(); } public int ColumnCount => _cumulativeColCounts[_cumulativeColCounts.Length - 1]; diff --git a/src/Microsoft.ML.Data/Depricated/Instances/HeaderSchema.cs b/src/Microsoft.ML.Data/Depricated/Instances/HeaderSchema.cs index 24969f74e0..b3e71c6f54 100644 --- a/src/Microsoft.ML.Data/Depricated/Instances/HeaderSchema.cs +++ b/src/Microsoft.ML.Data/Depricated/Instances/HeaderSchema.cs @@ -34,12 +34,12 @@ public FeatureNameCollectionBinding(FeatureNameCollection collection) _colType = new VectorType(NumberDataViewType.Single, collection.Count); _slotNamesType = new VectorType(TextDataViewType.Instance, collection.Count); - var metadataBuilder = new MetadataBuilder(); + var metadataBuilder = new DataViewSchema.Metadata.Builder(); metadataBuilder.Add(MetadataUtils.Kinds.SlotNames, _slotNamesType, (ref VBuffer> slotNames) => { GetSlotNames(0, ref slotNames); } ); - var schemaBuilder = new SchemaBuilder(); - schemaBuilder.AddColumn(RoleMappedSchema.ColumnRole.Feature.Value, _colType, metadataBuilder.GetMetadata()); - FeatureNameCollectionSchema = schemaBuilder.GetSchema(); + var schemaBuilder = new DataViewSchema.Builder(); + schemaBuilder.AddColumn(RoleMappedSchema.ColumnRole.Feature.Value, _colType, metadataBuilder.ToMetadata()); + FeatureNameCollectionSchema = schemaBuilder.ToSchema(); } private void GetSlotNames(int col, ref VBuffer> dst) diff --git a/src/Microsoft.ML.Data/Dirty/ChooseColumnsByIndexTransform.cs b/src/Microsoft.ML.Data/Dirty/ChooseColumnsByIndexTransform.cs index f008d95c96..07d2a1f58f 100644 --- a/src/Microsoft.ML.Data/Dirty/ChooseColumnsByIndexTransform.cs +++ b/src/Microsoft.ML.Data/Dirty/ChooseColumnsByIndexTransform.cs @@ -102,7 +102,7 @@ private static void ComputeSources(bool drop, int[] selectedColumnIndexes, DataV /// private DataViewSchema ComputeOutputSchema() { - var schemaBuilder = new SchemaBuilder(); + var schemaBuilder = new DataViewSchema.Builder(); for (int i = 0; i < _sources.Length; ++i) { // selectedIndex is an column index of input schema. Note that the input column indexed by _sources[i] in _sourceSchema is sent @@ -117,7 +117,7 @@ private DataViewSchema ComputeOutputSchema() var selectedColumn = _sourceSchema[selectedIndex]; schemaBuilder.AddColumn(selectedColumn.Name, selectedColumn.Type, selectedColumn.Metadata); } - return schemaBuilder.GetSchema(); + return schemaBuilder.ToSchema(); } internal Bindings(ModelLoadContext ctx, DataViewSchema sourceSchema) diff --git a/src/Microsoft.ML.Data/Evaluators/BinaryClassifierEvaluator.cs b/src/Microsoft.ML.Data/Evaluators/BinaryClassifierEvaluator.cs index c6bb60c63b..e7e1e7050c 100644 --- a/src/Microsoft.ML.Data/Evaluators/BinaryClassifierEvaluator.cs +++ b/src/Microsoft.ML.Data/Evaluators/BinaryClassifierEvaluator.cs @@ -1559,9 +1559,9 @@ private static IDataView ExtractWarnings(IHost host, Dictionary> getter = GetScoreColumnKind; @@ -569,7 +569,7 @@ private void CheckInputColumnTypes(DataViewSchema schema, out VectorType labelTy builder.Add(MetadataUtils.Kinds.ScoreValueKind, TextDataViewType.Instance, getter); ValueGetter uintGetter = GetScoreColumnSetId(schema); builder.Add(MetadataUtils.Kinds.ScoreColumnSetId, MetadataUtils.ScoreColumnSetIdType, uintGetter); - scoreMetadata = builder.GetMetadata(); + scoreMetadata = builder.ToMetadata(); } private ValueGetter GetScoreColumnSetId(DataViewSchema schema) diff --git a/src/Microsoft.ML.Data/Evaluators/QuantileRegressionEvaluator.cs b/src/Microsoft.ML.Data/Evaluators/QuantileRegressionEvaluator.cs index 149d93613b..7e683c9764 100644 --- a/src/Microsoft.ML.Data/Evaluators/QuantileRegressionEvaluator.cs +++ b/src/Microsoft.ML.Data/Evaluators/QuantileRegressionEvaluator.cs @@ -354,14 +354,14 @@ private protected override DataViewSchema.DetachedColumn[] GetOutputColumnsCore( var infos = new DataViewSchema.DetachedColumn[2]; var slotNamesType = new VectorType(TextDataViewType.Instance, _scoreSize); - var l1Metadata = new MetadataBuilder(); + var l1Metadata = new DataViewSchema.Metadata.Builder(); l1Metadata.AddSlotNames(_scoreSize, CreateSlotNamesGetter(L1)); - var l2Metadata = new MetadataBuilder(); + var l2Metadata = new DataViewSchema.Metadata.Builder(); l2Metadata.AddSlotNames(_scoreSize, CreateSlotNamesGetter(L2)); - infos[L1Col] = new DataViewSchema.DetachedColumn(L1, _outputType, l1Metadata.GetMetadata()); - infos[L2Col] = new DataViewSchema.DetachedColumn(L2, _outputType, l2Metadata.GetMetadata()); + infos[L1Col] = new DataViewSchema.DetachedColumn(L1, _outputType, l1Metadata.ToMetadata()); + infos[L2Col] = new DataViewSchema.DetachedColumn(L2, _outputType, l2Metadata.ToMetadata()); return infos; } diff --git a/src/Microsoft.ML.Data/Scorers/FeatureContributionCalculation.cs b/src/Microsoft.ML.Data/Scorers/FeatureContributionCalculation.cs index ff1b1971e2..b189914d77 100644 --- a/src/Microsoft.ML.Data/Scorers/FeatureContributionCalculation.cs +++ b/src/Microsoft.ML.Data/Scorers/FeatureContributionCalculation.cs @@ -323,9 +323,9 @@ public RowMapper(IHostEnvironment env, BindableMapper parent, RoleMappedSchema s if (parent.Stringify) { - var builder = new SchemaBuilder(); + var builder = new DataViewSchema.Builder(); builder.AddColumn(DefaultColumnNames.FeatureContributions, TextDataViewType.Instance, null); - _outputSchema = builder.GetSchema(); + _outputSchema = builder.ToSchema(); if (FeatureColumn.HasSlotNames(featureSize)) FeatureColumn.Metadata.GetValue(MetadataUtils.Kinds.SlotNames, ref _slotNames); else @@ -333,15 +333,15 @@ public RowMapper(IHostEnvironment env, BindableMapper parent, RoleMappedSchema s } else { - var metadataBuilder = new MetadataBuilder(); + var metadataBuilder = new DataViewSchema.Metadata.Builder(); if (InputSchema[FeatureColumn.Index].HasSlotNames(featureSize)) metadataBuilder.AddSlotNames(featureSize, (ref VBuffer> value) => FeatureColumn.Metadata.GetValue(MetadataUtils.Kinds.SlotNames, ref value)); - var schemaBuilder = new SchemaBuilder(); + var schemaBuilder = new DataViewSchema.Builder(); var featureContributionType = new VectorType(NumberDataViewType.Single, FeatureColumn.Type as VectorType); - schemaBuilder.AddColumn(DefaultColumnNames.FeatureContributions, featureContributionType, metadataBuilder.GetMetadata()); - _outputSchema = schemaBuilder.GetSchema(); + schemaBuilder.AddColumn(DefaultColumnNames.FeatureContributions, featureContributionType, metadataBuilder.ToMetadata()); + _outputSchema = schemaBuilder.ToSchema(); } _outputGenericSchema = _genericRowMapper.OutputSchema; diff --git a/src/Microsoft.ML.Data/Scorers/MultiClassClassifierScorer.cs b/src/Microsoft.ML.Data/Scorers/MultiClassClassifierScorer.cs index 07773ce9dc..9adeaf7363 100644 --- a/src/Microsoft.ML.Data/Scorers/MultiClassClassifierScorer.cs +++ b/src/Microsoft.ML.Data/Scorers/MultiClassClassifierScorer.cs @@ -303,12 +303,12 @@ public Bound(IHostEnvironment env, ISchemaBoundRowMapper mapper, VectorType type private DataViewSchema DecorateOutputSchema(DataViewSchema partialSchema, int scoreColumnIndex, VectorType labelNameType, ValueGetter> labelNameGetter, string labelNameKind) { - var builder = new SchemaBuilder(); + var builder = new DataViewSchema.Builder(); // Sequentially add columns so that the order of them is not changed comparing with the schema in the mapper // that computes score column. for (int i = 0; i < partialSchema.Count; ++i) { - var meta = new MetadataBuilder(); + var meta = new DataViewSchema.Metadata.Builder(); if (i == scoreColumnIndex) { // Add label names for score column. @@ -322,9 +322,9 @@ private DataViewSchema DecorateOutputSchema(DataViewSchema partialSchema, int sc } // Instead of appending extra metadata to the existing score column, we create new one because // metadata is read-only. - builder.AddColumn(partialSchema[i].Name, partialSchema[i].Type, meta.GetMetadata()); + builder.AddColumn(partialSchema[i].Name, partialSchema[i].Type, meta.ToMetadata()); } - return builder.GetSchema(); + return builder.ToSchema(); } public Func GetDependencies(Func predicate) => _mapper.GetDependencies(predicate); diff --git a/src/Microsoft.ML.Data/Scorers/PredictedLabelScorerBase.cs b/src/Microsoft.ML.Data/Scorers/PredictedLabelScorerBase.cs index 5c07e232f2..f0d269eb87 100644 --- a/src/Microsoft.ML.Data/Scorers/PredictedLabelScorerBase.cs +++ b/src/Microsoft.ML.Data/Scorers/PredictedLabelScorerBase.cs @@ -90,9 +90,9 @@ private static DataViewSchema.Metadata KeyValueMetadataFromMetadata(DataViewS Contracts.Assert(0 <= metaCol.Index && metaCol.Index < meta.Schema.Count); Contracts.Assert(metaCol.Type.RawType == typeof(T)); var getter = meta.GetGetter(metaCol.Index); - var builder = new MetadataBuilder(); + var builder = new DataViewSchema.Metadata.Builder(); builder.Add(MetadataUtils.Kinds.KeyValues, metaCol.Type, meta.GetGetter(metaCol.Index)); - return builder.GetMetadata(); + return builder.ToMetadata(); } public static BindingsImpl Create(DataViewSchema input, ISchemaBoundRowMapper mapper, string suffix, diff --git a/src/Microsoft.ML.Data/Scorers/ScoreSchemaFactory.cs b/src/Microsoft.ML.Data/Scorers/ScoreSchemaFactory.cs index 5504d2235f..eac0849d1b 100644 --- a/src/Microsoft.ML.Data/Scorers/ScoreSchemaFactory.cs +++ b/src/Microsoft.ML.Data/Scorers/ScoreSchemaFactory.cs @@ -28,17 +28,17 @@ public static DataViewSchema Create(DataViewType scoreType, string scoreColumnKi Contracts.CheckNonEmpty(scoreColumnKindValue, nameof(scoreColumnKindValue)); // Two metadata fields. One can set up by caller of this function while the other one is a constant. - var metadataBuilder = new MetadataBuilder(); + var metadataBuilder = new DataViewSchema.Metadata.Builder(); metadataBuilder.Add(MetadataUtils.Kinds.ScoreColumnKind, TextDataViewType.Instance, (ref ReadOnlyMemory value) => { value = scoreColumnKindValue.AsMemory(); }); metadataBuilder.Add(MetadataUtils.Kinds.ScoreValueKind, TextDataViewType.Instance, (ref ReadOnlyMemory value) => { value = MetadataUtils.Const.ScoreValueKind.Score.AsMemory(); }); // Build a schema consisting of a single column. - var schemaBuilder = new SchemaBuilder(); - schemaBuilder.AddColumn(scoreColumnName, scoreType, metadataBuilder.GetMetadata()); + var schemaBuilder = new DataViewSchema.Builder(); + schemaBuilder.AddColumn(scoreColumnName, scoreType, metadataBuilder.ToMetadata()); - return schemaBuilder.GetSchema(); + return schemaBuilder.ToSchema(); } /// @@ -55,12 +55,12 @@ public static DataViewSchema CreateBinaryClassificationSchema(string scoreColumn // Schema of Score column. We are going to extend it by adding a Probability column. var partialSchema = Create(NumberDataViewType.Single, MetadataUtils.Const.ScoreColumnKind.BinaryClassification, scoreColumnName); - var schemaBuilder = new SchemaBuilder(); + var schemaBuilder = new DataViewSchema.Builder(); // Copy Score column from partialSchema. schemaBuilder.AddColumn(partialSchema[0].Name, partialSchema[0].Type, partialSchema[0].Metadata); // Create Probability column's metadata. - var probabilityMetadataBuilder = new MetadataBuilder(); + var probabilityMetadataBuilder = new DataViewSchema.Metadata.Builder(); probabilityMetadataBuilder.Add(MetadataUtils.Kinds.IsNormalized, BooleanDataViewType.Instance, (ref bool value) => { value = true; }); probabilityMetadataBuilder.Add(MetadataUtils.Kinds.ScoreColumnKind, TextDataViewType.Instance, (ref ReadOnlyMemory value) => { value = MetadataUtils.Const.ScoreColumnKind.BinaryClassification.AsMemory(); }); @@ -68,9 +68,9 @@ public static DataViewSchema CreateBinaryClassificationSchema(string scoreColumn (ref ReadOnlyMemory value) => { value = MetadataUtils.Const.ScoreValueKind.Probability.AsMemory(); }); // Add probability column. - schemaBuilder.AddColumn(probabilityColumnName, NumberDataViewType.Single, probabilityMetadataBuilder.GetMetadata()); + schemaBuilder.AddColumn(probabilityColumnName, NumberDataViewType.Single, probabilityMetadataBuilder.ToMetadata()); - return schemaBuilder.GetSchema(); + return schemaBuilder.ToSchema(); } /// @@ -88,7 +88,7 @@ public static DataViewSchema CreateQuantileRegressionSchema(DataViewType scoreTy // Create a schema using standard function. The produced schema will be modified by adding one metadata column. var partialSchema = Create(new VectorType(scoreType as PrimitiveDataViewType, quantiles.Length), MetadataUtils.Const.ScoreColumnKind.QuantileRegression); - var metadataBuilder = new MetadataBuilder(); + var metadataBuilder = new DataViewSchema.Metadata.Builder(); // Add the extra metadata. metadataBuilder.AddSlotNames(quantiles.Length, (ref VBuffer> value) => { @@ -101,10 +101,10 @@ public static DataViewSchema CreateQuantileRegressionSchema(DataViewType scoreTy metadataBuilder.Add(partialSchema[0].Metadata, (string kind) => true); // Build a schema consisting of a single column. Comparing with partial schema, the only difference is a metadata field. - var schemaBuilder = new SchemaBuilder(); - schemaBuilder.AddColumn(partialSchema[0].Name, partialSchema[0].Type, metadataBuilder.GetMetadata()); + var schemaBuilder = new DataViewSchema.Builder(); + schemaBuilder.AddColumn(partialSchema[0].Name, partialSchema[0].Type, metadataBuilder.ToMetadata()); - return schemaBuilder.GetSchema(); + return schemaBuilder.ToSchema(); } /// @@ -121,7 +121,7 @@ public static DataViewSchema CreateSequencePredictionSchema(DataViewType scoreTy Contracts.CheckValue(scoreType, nameof(scoreType)); Contracts.CheckValue(scoreColumnKindValue, nameof(scoreColumnKindValue)); - var metadataBuilder = new MetadataBuilder(); + var metadataBuilder = new DataViewSchema.Metadata.Builder(); // Add metadata columns including their getters. We starts with key names of predicted keys if they exist. if (keyNames.Length > 0) metadataBuilder.AddKeyValues(keyNames.Length, TextDataViewType.Instance, @@ -132,10 +132,10 @@ public static DataViewSchema CreateSequencePredictionSchema(DataViewType scoreTy (ref ReadOnlyMemory value) => value = MetadataUtils.Const.ScoreValueKind.PredictedLabel.AsMemory()); // Build a schema consisting of a single column. - var schemaBuilder = new SchemaBuilder(); - schemaBuilder.AddColumn(MetadataUtils.Const.ScoreValueKind.PredictedLabel, scoreType, metadataBuilder.GetMetadata()); + var schemaBuilder = new DataViewSchema.Builder(); + schemaBuilder.AddColumn(MetadataUtils.Const.ScoreValueKind.PredictedLabel, scoreType, metadataBuilder.ToMetadata()); - return schemaBuilder.GetSchema(); + return schemaBuilder.ToSchema(); } } } diff --git a/src/Microsoft.ML.Data/Transforms/ColumnBindingsBase.cs b/src/Microsoft.ML.Data/Transforms/ColumnBindingsBase.cs index 14ec6b8b57..3cf4925324 100644 --- a/src/Microsoft.ML.Data/Transforms/ColumnBindingsBase.cs +++ b/src/Microsoft.ML.Data/Transforms/ColumnBindingsBase.cs @@ -274,19 +274,19 @@ private static DataViewSchema CreateSchema(ColumnBindingsBase inputBindings) { Contracts.CheckValue(inputBindings, nameof(inputBindings)); - var builder = new SchemaBuilder(); + var builder = new DataViewSchema.Builder(); for (int i = 0; i < inputBindings.ColumnCount; i++) { - var meta = new MetadataBuilder(); + var meta = new DataViewSchema.Metadata.Builder(); foreach (var kvp in inputBindings.GetMetadataTypes(i)) { var getter = Utils.MarshalInvoke(GetMetadataGetterDelegate, kvp.Value.RawType, inputBindings, i, kvp.Key); meta.Add(kvp.Key, kvp.Value, getter); } - builder.AddColumn(inputBindings.GetColumnName(i), inputBindings.GetColumnType(i), meta.GetMetadata()); + builder.AddColumn(inputBindings.GetColumnName(i), inputBindings.GetColumnType(i), meta.ToMetadata()); } - return builder.GetSchema(); + return builder.ToSchema(); } private static Delegate GetMetadataGetterDelegate(ColumnBindingsBase bindings, int col, string kind) diff --git a/src/Microsoft.ML.Data/Transforms/ColumnConcatenatingTransformer.cs b/src/Microsoft.ML.Data/Transforms/ColumnConcatenatingTransformer.cs index 2609efdd19..fa37061da8 100644 --- a/src/Microsoft.ML.Data/Transforms/ColumnConcatenatingTransformer.cs +++ b/src/Microsoft.ML.Data/Transforms/ColumnConcatenatingTransformer.cs @@ -573,7 +573,7 @@ public DataViewSchema.DetachedColumn MakeSchemaColumn() return new DataViewSchema.DetachedColumn(_columnInfo.Name, inputCol.Type, inputCol.Metadata); } - var metadata = new MetadataBuilder(); + var metadata = new DataViewSchema.Metadata.Builder(); if (_isNormalized) metadata.Add(MetadataUtils.Kinds.IsNormalized, BooleanDataViewType.Instance, (ValueGetter)GetIsNormalized); if (_hasSlotNames) @@ -581,7 +581,7 @@ public DataViewSchema.DetachedColumn MakeSchemaColumn() if (_hasCategoricals) metadata.Add(MetadataUtils.Kinds.CategoricalSlotRanges, _categoricalRangeType, (ValueGetter>)GetCategoricalSlotRanges); - return new DataViewSchema.DetachedColumn(_columnInfo.Name, OutputType, metadata.GetMetadata()); + return new DataViewSchema.DetachedColumn(_columnInfo.Name, OutputType, metadata.ToMetadata()); } private void GetIsNormalized(ref bool value) => value = _isNormalized; diff --git a/src/Microsoft.ML.Data/Transforms/FeatureContributionCalculationTransformer.cs b/src/Microsoft.ML.Data/Transforms/FeatureContributionCalculationTransformer.cs index 169a0a1819..f6fb7c81d7 100644 --- a/src/Microsoft.ML.Data/Transforms/FeatureContributionCalculationTransformer.cs +++ b/src/Microsoft.ML.Data/Transforms/FeatureContributionCalculationTransformer.cs @@ -237,9 +237,9 @@ public Mapper(FeatureContributionCalculatingTransformer parent, DataViewSchema s protected override DataViewSchema.DetachedColumn[] GetOutputColumnsCore() { // Add FeatureContributions column. - var builder = new MetadataBuilder(); + var builder = new DataViewSchema.Metadata.Builder(); builder.Add(InputSchema[_featureColumnIndex].Metadata, x => x == MetadataUtils.Kinds.SlotNames); - return new[] { new DataViewSchema.DetachedColumn(DefaultColumnNames.FeatureContributions, new VectorType(NumberDataViewType.Single, _featureColumnType.Size), builder.GetMetadata()) }; + return new[] { new DataViewSchema.DetachedColumn(DefaultColumnNames.FeatureContributions, new VectorType(NumberDataViewType.Single, _featureColumnType.Size), builder.ToMetadata()) }; } protected override Delegate MakeGetter(DataViewRow input, int iinfo, Func active, out Action disposer) diff --git a/src/Microsoft.ML.Data/Transforms/Hashing.cs b/src/Microsoft.ML.Data/Transforms/Hashing.cs index 5765b6a2d0..b769cf9649 100644 --- a/src/Microsoft.ML.Data/Transforms/Hashing.cs +++ b/src/Microsoft.ML.Data/Transforms/Hashing.cs @@ -817,17 +817,17 @@ protected override DataViewSchema.DetachedColumn[] GetOutputColumnsCore() for (int i = 0; i < _parent.ColumnPairs.Length; i++) { InputSchema.TryGetColumnIndex(_parent.ColumnPairs[i].inputColumnName, out int colIndex); - var meta = new MetadataBuilder(); + var meta = new DataViewSchema.Metadata.Builder(); meta.Add(InputSchema[colIndex].Metadata, name => name == MetadataUtils.Kinds.SlotNames); if (_parent._kvTypes != null && _parent._kvTypes[i] != null) AddMetaKeyValues(i, meta); - result[i] = new DataViewSchema.DetachedColumn(_parent.ColumnPairs[i].outputColumnName, _types[i], meta.GetMetadata()); + result[i] = new DataViewSchema.DetachedColumn(_parent.ColumnPairs[i].outputColumnName, _types[i], meta.ToMetadata()); } return result; } - private void AddMetaKeyValues(int i, MetadataBuilder builder) + private void AddMetaKeyValues(int i, DataViewSchema.Metadata.Builder builder) { ValueGetter>> getter = (ref VBuffer> dst) => { diff --git a/src/Microsoft.ML.Data/Transforms/KeyToValue.cs b/src/Microsoft.ML.Data/Transforms/KeyToValue.cs index 4b15a514cc..b38648d9d4 100644 --- a/src/Microsoft.ML.Data/Transforms/KeyToValue.cs +++ b/src/Microsoft.ML.Data/Transforms/KeyToValue.cs @@ -177,9 +177,9 @@ protected override DataViewSchema.DetachedColumn[] GetOutputColumnsCore() var result = new DataViewSchema.DetachedColumn[_parent.ColumnPairs.Length]; for (int i = 0; i < _parent.ColumnPairs.Length; i++) { - var meta = new MetadataBuilder(); + var meta = new DataViewSchema.Metadata.Builder(); meta.Add(InputSchema[ColMapNewToOld[i]].Metadata, name => name == MetadataUtils.Kinds.SlotNames); - result[i] = new DataViewSchema.DetachedColumn(_parent.ColumnPairs[i].outputColumnName, _types[i], meta.GetMetadata()); + result[i] = new DataViewSchema.DetachedColumn(_parent.ColumnPairs[i].outputColumnName, _types[i], meta.ToMetadata()); } return result; } diff --git a/src/Microsoft.ML.Data/Transforms/KeyToVector.cs b/src/Microsoft.ML.Data/Transforms/KeyToVector.cs index f632edce61..c2fc950311 100644 --- a/src/Microsoft.ML.Data/Transforms/KeyToVector.cs +++ b/src/Microsoft.ML.Data/Transforms/KeyToVector.cs @@ -280,14 +280,14 @@ protected override DataViewSchema.DetachedColumn[] GetOutputColumnsCore() { InputSchema.TryGetColumnIndex(_parent.ColumnPairs[i].inputColumnName, out int colIndex); Host.Assert(colIndex >= 0); - var builder = new MetadataBuilder(); + var builder = new DataViewSchema.Metadata.Builder(); AddMetadata(i, builder); - result[i] = new DataViewSchema.DetachedColumn(_parent.ColumnPairs[i].outputColumnName, _types[i], builder.GetMetadata()); + result[i] = new DataViewSchema.DetachedColumn(_parent.ColumnPairs[i].outputColumnName, _types[i], builder.ToMetadata()); } return result; } - private void AddMetadata(int iinfo, MetadataBuilder builder) + private void AddMetadata(int iinfo, DataViewSchema.Metadata.Builder builder) { InputSchema.TryGetColumnIndex(_infos[iinfo].InputColumnName, out int srcCol); var inputMetadata = InputSchema[srcCol].Metadata; diff --git a/src/Microsoft.ML.Data/Transforms/Normalizer.cs b/src/Microsoft.ML.Data/Transforms/Normalizer.cs index ecf4b87deb..be88e2eb65 100644 --- a/src/Microsoft.ML.Data/Transforms/Normalizer.cs +++ b/src/Microsoft.ML.Data/Transforms/Normalizer.cs @@ -604,11 +604,11 @@ protected override DataViewSchema.DetachedColumn[] GetOutputColumnsCore() private DataViewSchema.Metadata MakeMetadata(int iinfo) { var colInfo = _parent.Columns[iinfo]; - var builder = new MetadataBuilder(); + var builder = new DataViewSchema.Metadata.Builder(); builder.Add(MetadataUtils.Kinds.IsNormalized, BooleanDataViewType.Instance, (ValueGetter)IsNormalizedGetter); builder.Add(InputSchema[ColMapNewToOld[iinfo]].Metadata, name => name == MetadataUtils.Kinds.SlotNames); - return builder.GetMetadata(); + return builder.ToMetadata(); } private void IsNormalizedGetter(ref bool dst) diff --git a/src/Microsoft.ML.Data/Transforms/SlotsDroppingTransformer.cs b/src/Microsoft.ML.Data/Transforms/SlotsDroppingTransformer.cs index acefc4c2b6..264cf784cd 100644 --- a/src/Microsoft.ML.Data/Transforms/SlotsDroppingTransformer.cs +++ b/src/Microsoft.ML.Data/Transforms/SlotsDroppingTransformer.cs @@ -826,7 +826,7 @@ protected override DataViewSchema.DetachedColumn[] GetOutputColumnsCore() InputSchema.TryGetColumnIndex(_parent.ColumnPairs[iinfo].inputColumnName, out int colIndex); Host.Assert(colIndex >= 0); - var builder = new MetadataBuilder(); + var builder = new DataViewSchema.Metadata.Builder(); // Add SlotNames metadata. if (_srcTypes[iinfo] is VectorType vectorType && vectorType.IsKnownSize) @@ -864,7 +864,7 @@ protected override DataViewSchema.DetachedColumn[] GetOutputColumnsCore() // Add isNormalize and KeyValues metadata. builder.Add(InputSchema[_cols[iinfo]].Metadata, x => x == MetadataUtils.Kinds.KeyValues || x == MetadataUtils.Kinds.IsNormalized); - result[iinfo] = new DataViewSchema.DetachedColumn(_parent.ColumnPairs[iinfo].outputColumnName, _dstTypes[iinfo], builder.GetMetadata()); + result[iinfo] = new DataViewSchema.DetachedColumn(_parent.ColumnPairs[iinfo].outputColumnName, _dstTypes[iinfo], builder.ToMetadata()); } return result; } diff --git a/src/Microsoft.ML.Data/Transforms/TypeConverting.cs b/src/Microsoft.ML.Data/Transforms/TypeConverting.cs index aac5115dec..01c8f2877d 100644 --- a/src/Microsoft.ML.Data/Transforms/TypeConverting.cs +++ b/src/Microsoft.ML.Data/Transforms/TypeConverting.cs @@ -437,7 +437,7 @@ protected override DataViewSchema.DetachedColumn[] GetOutputColumnsCore() var result = new DataViewSchema.DetachedColumn[_parent._columns.Length]; for (int i = 0; i < _parent._columns.Length; i++) { - var builder = new MetadataBuilder(); + var builder = new DataViewSchema.Metadata.Builder(); var srcType = InputSchema[_srcCols[i]].Type; if (_types[i].IsKnownSizeVector()) builder.Add(InputSchema[ColMapNewToOld[i]].Metadata, name => name == MetadataUtils.Kinds.SlotNames); @@ -460,7 +460,7 @@ protected override DataViewSchema.DetachedColumn[] GetOutputColumnsCore() ValueGetter getter = (ref bool dst) => dst = true; builder.Add(MetadataUtils.Kinds.IsNormalized, BooleanDataViewType.Instance, getter); } - result[i] = new DataViewSchema.DetachedColumn(_parent._columns[i].Name, _types[i], builder.GetMetadata()); + result[i] = new DataViewSchema.DetachedColumn(_parent._columns[i].Name, _types[i], builder.ToMetadata()); } return result; } diff --git a/src/Microsoft.ML.Data/Transforms/ValueToKeyMappingTransformer.cs b/src/Microsoft.ML.Data/Transforms/ValueToKeyMappingTransformer.cs index 5c820c4385..f90f6377e9 100644 --- a/src/Microsoft.ML.Data/Transforms/ValueToKeyMappingTransformer.cs +++ b/src/Microsoft.ML.Data/Transforms/ValueToKeyMappingTransformer.cs @@ -733,11 +733,11 @@ protected override DataViewSchema.DetachedColumn[] GetOutputColumnsCore() { InputSchema.TryGetColumnIndex(_parent.ColumnPairs[i].inputColumnName, out int colIndex); Host.Assert(colIndex >= 0); - var builder = new MetadataBuilder(); + var builder = new DataViewSchema.Metadata.Builder(); _termMap[i].AddMetadata(builder); builder.Add(InputSchema[colIndex].Metadata, name => name == MetadataUtils.Kinds.SlotNames); - result[i] = new DataViewSchema.DetachedColumn(_parent.ColumnPairs[i].outputColumnName, _types[i], builder.GetMetadata()); + result[i] = new DataViewSchema.DetachedColumn(_parent.ColumnPairs[i].outputColumnName, _types[i], builder.ToMetadata()); } return result; } diff --git a/src/Microsoft.ML.Data/Transforms/ValueToKeyMappingTransformerImpl.cs b/src/Microsoft.ML.Data/Transforms/ValueToKeyMappingTransformerImpl.cs index 0b70da1a35..f88c334b40 100644 --- a/src/Microsoft.ML.Data/Transforms/ValueToKeyMappingTransformerImpl.cs +++ b/src/Microsoft.ML.Data/Transforms/ValueToKeyMappingTransformerImpl.cs @@ -855,7 +855,7 @@ public static BoundTermMap CreateCore(IHostEnvironment env, DataViewSchema sc /// Allows us to optionally register metadata. It is also perfectly legal for /// this to do nothing, which corresponds to there being no metadata. /// - public abstract void AddMetadata(MetadataBuilder builder); + public abstract void AddMetadata(DataViewSchema.Metadata.Builder builder); /// /// Writes out all terms we map to a text writer, with one line per mapped term. @@ -1038,7 +1038,7 @@ public override Delegate GetMappingGetter(DataViewRow input) } } - public override void AddMetadata(MetadataBuilder builder) + public override void AddMetadata(DataViewSchema.Metadata.Builder builder) { if (TypedMap.Count == 0) return; @@ -1081,7 +1081,7 @@ public KeyImpl(IHostEnvironment env, DataViewSchema schema, TermMap map, ColI _host.Assert(TypedMap.ItemType is KeyType); } - public override void AddMetadata(MetadataBuilder builder) + public override void AddMetadata(DataViewSchema.Metadata.Builder builder) { if (TypedMap.Count == 0) return; @@ -1096,7 +1096,7 @@ public override void AddMetadata(MetadataBuilder builder) } } - private bool AddMetadataCore(DataViewType srcMetaType, MetadataBuilder builder) + private bool AddMetadataCore(DataViewType srcMetaType, DataViewSchema.Metadata.Builder builder) { _host.AssertValue(srcMetaType); _host.Assert(srcMetaType.RawType == typeof(TMeta)); diff --git a/src/Microsoft.ML.FastTree/FastTree.cs b/src/Microsoft.ML.FastTree/FastTree.cs index 6d83451324..12e62ec626 100644 --- a/src/Microsoft.ML.FastTree/FastTree.cs +++ b/src/Microsoft.ML.FastTree/FastTree.cs @@ -3279,15 +3279,15 @@ DataViewRow ICanGetSummaryAsIRow.GetSummaryIRowOrNull(RoleMappedSchema schema) { var names = default(VBuffer>); MetadataUtils.GetSlotNames(schema, RoleMappedSchema.ColumnRole.Feature, NumFeatures, ref names); - var metaBuilder = new MetadataBuilder(); + var metaBuilder = new DataViewSchema.Metadata.Builder(); metaBuilder.AddSlotNames(NumFeatures, names.CopyTo); var weights = default(VBuffer); ((IHaveFeatureWeights)this).GetFeatureWeights(ref weights); - var builder = new MetadataBuilder(); - builder.Add>("Gains", new VectorType(NumberDataViewType.Single, NumFeatures), weights.CopyTo, metaBuilder.GetMetadata()); + var builder = new DataViewSchema.Metadata.Builder(); + builder.Add>("Gains", new VectorType(NumberDataViewType.Single, NumFeatures), weights.CopyTo, metaBuilder.ToMetadata()); - return MetadataUtils.MetadataAsRow(builder.GetMetadata()); + return MetadataUtils.MetadataAsRow(builder.ToMetadata()); } DataViewRow ICanGetSummaryAsIRow.GetStatsIRowOrNull(RoleMappedSchema schema) diff --git a/src/Microsoft.ML.FastTree/TreeEnsembleFeaturizer.cs b/src/Microsoft.ML.FastTree/TreeEnsembleFeaturizer.cs index 15e7225a44..31bf3bba81 100644 --- a/src/Microsoft.ML.FastTree/TreeEnsembleFeaturizer.cs +++ b/src/Microsoft.ML.FastTree/TreeEnsembleFeaturizer.cs @@ -108,32 +108,32 @@ public BoundMapper(IExceptionContext ectx, TreeEnsembleFeaturizerBindableMapper var pathIdType = new VectorType(NumberDataViewType.Single, owner._totalLeafCount - owner._ensemble.TrainedEnsemble.NumTrees); // Start creating output schema with types derived above. - var schemaBuilder = new SchemaBuilder(); + var schemaBuilder = new DataViewSchema.Builder(); // Metadata of tree values. - var treeIdMetadataBuilder = new MetadataBuilder(); + var treeIdMetadataBuilder = new DataViewSchema.Metadata.Builder(); treeIdMetadataBuilder.Add(MetadataUtils.Kinds.SlotNames, MetadataUtils.GetNamesType(treeValueType.Size), (ValueGetter>>)owner.GetTreeSlotNames); // Add the column of trees' output values - schemaBuilder.AddColumn(OutputColumnNames.Trees, treeValueType, treeIdMetadataBuilder.GetMetadata()); + schemaBuilder.AddColumn(OutputColumnNames.Trees, treeValueType, treeIdMetadataBuilder.ToMetadata()); // Metadata of leaf IDs. - var leafIdMetadataBuilder = new MetadataBuilder(); + var leafIdMetadataBuilder = new DataViewSchema.Metadata.Builder(); leafIdMetadataBuilder.Add(MetadataUtils.Kinds.SlotNames, MetadataUtils.GetNamesType(leafIdType.Size), (ValueGetter>>)owner.GetLeafSlotNames); leafIdMetadataBuilder.Add(MetadataUtils.Kinds.IsNormalized, BooleanDataViewType.Instance, (ref bool value) => value = true); // Add the column of leaves' IDs where the input example reaches. - schemaBuilder.AddColumn(OutputColumnNames.Leaves, leafIdType, leafIdMetadataBuilder.GetMetadata()); + schemaBuilder.AddColumn(OutputColumnNames.Leaves, leafIdType, leafIdMetadataBuilder.ToMetadata()); // Metadata of path IDs. - var pathIdMetadataBuilder = new MetadataBuilder(); + var pathIdMetadataBuilder = new DataViewSchema.Metadata.Builder(); pathIdMetadataBuilder.Add(MetadataUtils.Kinds.SlotNames, MetadataUtils.GetNamesType(pathIdType.Size), (ValueGetter>>)owner.GetPathSlotNames); pathIdMetadataBuilder.Add(MetadataUtils.Kinds.IsNormalized, BooleanDataViewType.Instance, (ref bool value) => value = true); // Add the column of encoded paths which the input example passes. - schemaBuilder.AddColumn(OutputColumnNames.Paths, pathIdType, pathIdMetadataBuilder.GetMetadata()); + schemaBuilder.AddColumn(OutputColumnNames.Paths, pathIdType, pathIdMetadataBuilder.ToMetadata()); - OutputSchema = schemaBuilder.GetSchema(); + OutputSchema = schemaBuilder.ToSchema(); // Tree values must be the first output column. Contracts.Assert(OutputSchema[OutputColumnNames.Trees].Index == TreeValuesColumnId); diff --git a/src/Microsoft.ML.Parquet/ParquetLoader.cs b/src/Microsoft.ML.Parquet/ParquetLoader.cs index 1bda1fc274..fdd10d0700 100644 --- a/src/Microsoft.ML.Parquet/ParquetLoader.cs +++ b/src/Microsoft.ML.Parquet/ParquetLoader.cs @@ -317,9 +317,9 @@ private Microsoft.Data.DataView.DataViewSchema CreateSchema(IExceptionContext ec { Contracts.AssertValue(ectx); Contracts.AssertValue(cols); - var builder = new SchemaBuilder(); + var builder = new DataViewSchema.Builder(); builder.AddColumns(cols.Select(c => new Microsoft.Data.DataView.DataViewSchema.DetachedColumn(c.Name, c.ColType, null))); - return builder.GetSchema(); + return builder.ToSchema(); } /// diff --git a/src/Microsoft.ML.Parquet/PartitionedFileLoader.cs b/src/Microsoft.ML.Parquet/PartitionedFileLoader.cs index b0b37c94a4..055d34f3b9 100644 --- a/src/Microsoft.ML.Parquet/PartitionedFileLoader.cs +++ b/src/Microsoft.ML.Parquet/PartitionedFileLoader.cs @@ -317,9 +317,9 @@ private DataViewSchema CreateSchema(IExceptionContext ectx, Column[] cols, IData Contracts.AssertValue(cols); Contracts.AssertValue(subLoader); - var builder = new SchemaBuilder(); + var builder = new DataViewSchema.Builder(); builder.AddColumns(cols.Select(c => new DataViewSchema.DetachedColumn(c.Name, ColumnTypeExtensions.PrimitiveTypeFromKind(c.Type.Value), null))); - var colSchema = builder.GetSchema(); + var colSchema = builder.ToSchema(); var subSchema = subLoader.Schema; diff --git a/src/Microsoft.ML.StandardLearners/Standard/LinearModelParameters.cs b/src/Microsoft.ML.StandardLearners/Standard/LinearModelParameters.cs index e72c6c5615..c8f2601d23 100644 --- a/src/Microsoft.ML.StandardLearners/Standard/LinearModelParameters.cs +++ b/src/Microsoft.ML.StandardLearners/Standard/LinearModelParameters.cs @@ -365,13 +365,13 @@ private protected virtual DataViewRow GetSummaryIRowOrNull(RoleMappedSchema sche { var names = default(VBuffer>); MetadataUtils.GetSlotNames(schema, RoleMappedSchema.ColumnRole.Feature, Weight.Length, ref names); - var subBuilder = new MetadataBuilder(); + var subBuilder = new DataViewSchema.Metadata.Builder(); subBuilder.AddSlotNames(Weight.Length, (ref VBuffer> dst) => names.CopyTo(ref dst)); var colType = new VectorType(NumberDataViewType.Single, Weight.Length); - var builder = new MetadataBuilder(); + var builder = new DataViewSchema.Metadata.Builder(); builder.AddPrimitiveValue("Bias", NumberDataViewType.Single, Bias); - builder.Add("Weights", colType, (ref VBuffer dst) => Weight.CopyTo(ref dst), subBuilder.GetMetadata()); - return MetadataUtils.MetadataAsRow(builder.GetMetadata()); + builder.Add("Weights", colType, (ref VBuffer dst) => Weight.CopyTo(ref dst), subBuilder.ToMetadata()); + return MetadataUtils.MetadataAsRow(builder.ToMetadata()); } DataViewRow ICanGetSummaryAsIRow.GetSummaryIRowOrNull(RoleMappedSchema schema) => GetSummaryIRowOrNull(schema); diff --git a/src/Microsoft.ML.StandardLearners/Standard/ModelStatistics.cs b/src/Microsoft.ML.StandardLearners/Standard/ModelStatistics.cs index 75fca94c24..e47b9b9225 100644 --- a/src/Microsoft.ML.StandardLearners/Standard/ModelStatistics.cs +++ b/src/Microsoft.ML.StandardLearners/Standard/ModelStatistics.cs @@ -418,7 +418,7 @@ internal DataViewSchema.Metadata MakeStatisticsMetadata(LinearBinaryModelParamet _env.AssertValueOrNull(parent); _env.AssertValue(schema); - var builder = new MetadataBuilder(); + var builder = new DataViewSchema.Metadata.Builder(); builder.AddPrimitiveValue("Count of training examples", NumberDataViewType.Int64, _trainingExampleCount); builder.AddPrimitiveValue("Residual Deviance", NumberDataViewType.Single, _deviance); @@ -426,10 +426,10 @@ internal DataViewSchema.Metadata MakeStatisticsMetadata(LinearBinaryModelParamet builder.AddPrimitiveValue("AIC", NumberDataViewType.Single, 2 * _paramCount + _deviance); if (parent == null) - return builder.GetMetadata(); + return builder.ToMetadata(); if (!TryGetBiasStatistics(parent.Statistics, parent.Bias, out float biasStdErr, out float biasZScore, out float biasPValue)) - return builder.GetMetadata(); + return builder.ToMetadata(); var biasEstimate = parent.Bias; builder.AddPrimitiveValue("BiasEstimate", NumberDataViewType.Single, biasEstimate); @@ -446,9 +446,9 @@ internal DataViewSchema.Metadata MakeStatisticsMetadata(LinearBinaryModelParamet ValueGetter>> getSlotNames; GetUnorderedCoefficientStatistics(parent.Statistics, in weights, in names, ref estimate, ref stdErr, ref zScore, ref pValue, out getSlotNames); - var subMetaBuilder = new MetadataBuilder(); + var subMetaBuilder = new DataViewSchema.Metadata.Builder(); subMetaBuilder.AddSlotNames(stdErr.Length, getSlotNames); - var subMeta = subMetaBuilder.GetMetadata(); + var subMeta = subMetaBuilder.ToMetadata(); var colType = new VectorType(NumberDataViewType.Single, stdErr.Length); builder.Add("Estimate", colType, (ref VBuffer dst) => estimate.CopyTo(ref dst), subMeta); @@ -456,7 +456,7 @@ internal DataViewSchema.Metadata MakeStatisticsMetadata(LinearBinaryModelParamet builder.Add("ZScore", colType, (ref VBuffer dst) => zScore.CopyTo(ref dst), subMeta); builder.Add("PValue", colType, (ref VBuffer dst) => pValue.CopyTo(ref dst), subMeta); - return builder.GetMetadata(); + return builder.ToMetadata(); } private string DecorateProbabilityString(float probZ) diff --git a/src/Microsoft.ML.TensorFlow/TensorFlow/TensorflowUtils.cs b/src/Microsoft.ML.TensorFlow/TensorFlow/TensorflowUtils.cs index 12352885c6..7b926dc756 100644 --- a/src/Microsoft.ML.TensorFlow/TensorFlow/TensorflowUtils.cs +++ b/src/Microsoft.ML.TensorFlow/TensorFlow/TensorflowUtils.cs @@ -30,7 +30,7 @@ public static class TensorFlowUtils internal static DataViewSchema GetModelSchema(IExceptionContext ectx, TFGraph graph, string opType = null) { - var schemaBuilder = new SchemaBuilder(); + var schemaBuilder = new DataViewSchema.Builder(); foreach (var op in graph) { if (opType != null && opType != op.OpType) @@ -62,7 +62,7 @@ internal static DataViewSchema GetModelSchema(IExceptionContext ectx, TFGraph gr // these values are names of some upstream operators which should be evaluated before executing // the current operator. It's possible that one operator doesn't need any input, so this field // can be missing. - var metadataBuilder = new MetadataBuilder(); + var metadataBuilder = new DataViewSchema.Metadata.Builder(); // Create the first metadata field. metadataBuilder.Add(TensorflowOperatorTypeKind, TextDataViewType.Instance, (ref ReadOnlyMemory value) => value = op.OpType.AsMemory()); if (op.NumInputs > 0) @@ -79,9 +79,9 @@ internal static DataViewSchema GetModelSchema(IExceptionContext ectx, TFGraph gr (ref VBuffer> value) => { upstreamOperatorNames.CopyTo(ref value); }); } - schemaBuilder.AddColumn(op.Name, columnType, metadataBuilder.GetMetadata()); + schemaBuilder.AddColumn(op.Name, columnType, metadataBuilder.ToMetadata()); } - return schemaBuilder.GetSchema(); + return schemaBuilder.ToSchema(); } /// diff --git a/src/Microsoft.ML.TimeSeries/SequentialAnomalyDetectionTransformBase.cs b/src/Microsoft.ML.TimeSeries/SequentialAnomalyDetectionTransformBase.cs index 145235a1cb..5297c088c4 100644 --- a/src/Microsoft.ML.TimeSeries/SequentialAnomalyDetectionTransformBase.cs +++ b/src/Microsoft.ML.TimeSeries/SequentialAnomalyDetectionTransformBase.cs @@ -331,10 +331,10 @@ public Mapper(IHostEnvironment env, SequentialAnomalyDetectionTransformBase name == MetadataUtils.Kinds.SlotNames); ValueGetter getter = (ref bool dst) => dst = true; builder.Add(MetadataUtils.Kinds.IsNormalized, BooleanDataViewType.Instance, getter); - result[i] = new DataViewSchema.DetachedColumn(_parent.ColumnPairs[i].outputColumnName, _types[i], builder.GetMetadata()); + result[i] = new DataViewSchema.DetachedColumn(_parent.ColumnPairs[i].outputColumnName, _types[i], builder.ToMetadata()); } return result; } diff --git a/src/Microsoft.ML.Transforms/GroupTransform.cs b/src/Microsoft.ML.Transforms/GroupTransform.cs index 28eb7b4dcd..75d6d4ede0 100644 --- a/src/Microsoft.ML.Transforms/GroupTransform.cs +++ b/src/Microsoft.ML.Transforms/GroupTransform.cs @@ -278,7 +278,7 @@ public GroupBinding(DataViewSchema inputSchema, IHostEnvironment env, ModelLoadC private DataViewSchema BuildOutputSchema(DataViewSchema sourceSchema) { // Create schema build. We will sequentially add group columns and then aggregated columns. - var schemaBuilder = new SchemaBuilder(); + var schemaBuilder = new DataViewSchema.Builder(); // Handle group(-key) columns. Those columns are used as keys to partition rows in the input data; specifically, // rows with the same key value will be merged into one row in the output data. @@ -289,7 +289,7 @@ private DataViewSchema BuildOutputSchema(DataViewSchema sourceSchema) foreach (var groupValueColumnName in _keepColumns) { // Prepare column's metadata. - var metadataBuilder = new MetadataBuilder(); + var metadataBuilder = new DataViewSchema.Metadata.Builder(); metadataBuilder.Add(sourceSchema[groupValueColumnName].Metadata, s => s == MetadataUtils.Kinds.IsNormalized || s == MetadataUtils.Kinds.KeyValues); @@ -299,10 +299,10 @@ private DataViewSchema BuildOutputSchema(DataViewSchema sourceSchema) var aggregatedResultType = new VectorType(aggregatedValueType); // Add column into output schema. - schemaBuilder.AddColumn(groupValueColumnName, aggregatedResultType, metadataBuilder.GetMetadata()); + schemaBuilder.AddColumn(groupValueColumnName, aggregatedResultType, metadataBuilder.ToMetadata()); } - return schemaBuilder.GetSchema(); + return schemaBuilder.ToSchema(); } internal void Save(ModelSaveContext ctx) diff --git a/src/Microsoft.ML.Transforms/KeyToVectorMapping.cs b/src/Microsoft.ML.Transforms/KeyToVectorMapping.cs index e289b47f16..a06a098abd 100644 --- a/src/Microsoft.ML.Transforms/KeyToVectorMapping.cs +++ b/src/Microsoft.ML.Transforms/KeyToVectorMapping.cs @@ -208,15 +208,15 @@ protected override DataViewSchema.DetachedColumn[] GetOutputColumnsCore() { InputSchema.TryGetColumnIndex(_parent.ColumnPairs[i].inputColumnName, out int colIndex); Host.Assert(colIndex >= 0); - var builder = new MetadataBuilder(); + var builder = new DataViewSchema.Metadata.Builder(); AddMetadata(i, builder); - result[i] = new DataViewSchema.DetachedColumn(_parent.ColumnPairs[i].outputColumnName, _types[i], builder.GetMetadata()); + result[i] = new DataViewSchema.DetachedColumn(_parent.ColumnPairs[i].outputColumnName, _types[i], builder.ToMetadata()); } return result; } - private void AddMetadata(int iinfo, MetadataBuilder builder) + private void AddMetadata(int iinfo, DataViewSchema.Metadata.Builder builder) { InputSchema.TryGetColumnIndex(_infos[iinfo].InputColumnName, out int srcCol); var inputMetadata = InputSchema[srcCol].Metadata; diff --git a/src/Microsoft.ML.Transforms/MissingValueDroppingTransformer.cs b/src/Microsoft.ML.Transforms/MissingValueDroppingTransformer.cs index d4e854dcde..cfe3952440 100644 --- a/src/Microsoft.ML.Transforms/MissingValueDroppingTransformer.cs +++ b/src/Microsoft.ML.Transforms/MissingValueDroppingTransformer.cs @@ -187,9 +187,9 @@ protected override DataViewSchema.DetachedColumn[] GetOutputColumnsCore() var result = new DataViewSchema.DetachedColumn[_parent.ColumnPairs.Length]; for (int i = 0; i < _parent.ColumnPairs.Length; i++) { - var builder = new MetadataBuilder(); + var builder = new DataViewSchema.Metadata.Builder(); builder.Add(InputSchema[ColMapNewToOld[i]].Metadata, x => x == MetadataUtils.Kinds.KeyValues || x == MetadataUtils.Kinds.IsNormalized); - result[i] = new DataViewSchema.DetachedColumn(_parent.ColumnPairs[i].outputColumnName, _types[i], builder.GetMetadata()); + result[i] = new DataViewSchema.DetachedColumn(_parent.ColumnPairs[i].outputColumnName, _types[i], builder.ToMetadata()); } return result; } diff --git a/src/Microsoft.ML.Transforms/MissingValueIndicatorTransformer.cs b/src/Microsoft.ML.Transforms/MissingValueIndicatorTransformer.cs index 034ebb9cae..66790ee95e 100644 --- a/src/Microsoft.ML.Transforms/MissingValueIndicatorTransformer.cs +++ b/src/Microsoft.ML.Transforms/MissingValueIndicatorTransformer.cs @@ -197,14 +197,14 @@ protected override DataViewSchema.DetachedColumn[] GetOutputColumnsCore() { InputSchema.TryGetColumnIndex(_infos[iinfo].InputColumnName, out int colIndex); Host.Assert(colIndex >= 0); - var builder = new MetadataBuilder(); + var builder = new DataViewSchema.Metadata.Builder(); builder.Add(InputSchema[colIndex].Metadata, x => x == MetadataUtils.Kinds.SlotNames); ValueGetter getter = (ref bool dst) => { dst = true; }; builder.Add(MetadataUtils.Kinds.IsNormalized, BooleanDataViewType.Instance, getter); - result[iinfo] = new DataViewSchema.DetachedColumn(_infos[iinfo].Name, _infos[iinfo].OutputType, builder.GetMetadata()); + result[iinfo] = new DataViewSchema.DetachedColumn(_infos[iinfo].Name, _infos[iinfo].OutputType, builder.ToMetadata()); } return result; } diff --git a/src/Microsoft.ML.Transforms/MissingValueReplacing.cs b/src/Microsoft.ML.Transforms/MissingValueReplacing.cs index 7997566d2f..436de7ea78 100644 --- a/src/Microsoft.ML.Transforms/MissingValueReplacing.cs +++ b/src/Microsoft.ML.Transforms/MissingValueReplacing.cs @@ -605,9 +605,9 @@ protected override DataViewSchema.DetachedColumn[] GetOutputColumnsCore() { InputSchema.TryGetColumnIndex(_parent.ColumnPairs[i].inputColumnName, out int colIndex); Host.Assert(colIndex >= 0); - var builder = new MetadataBuilder(); + var builder = new DataViewSchema.Metadata.Builder(); builder.Add(InputSchema[colIndex].Metadata, x => x == MetadataUtils.Kinds.SlotNames || x == MetadataUtils.Kinds.IsNormalized); - result[i] = new DataViewSchema.DetachedColumn(_parent.ColumnPairs[i].outputColumnName, _types[i], builder.GetMetadata()); + result[i] = new DataViewSchema.DetachedColumn(_parent.ColumnPairs[i].outputColumnName, _types[i], builder.ToMetadata()); } return result; } diff --git a/src/Microsoft.ML.Transforms/Text/NgramHashingTransformer.cs b/src/Microsoft.ML.Transforms/Text/NgramHashingTransformer.cs index 1e8608567a..c570c78ad6 100644 --- a/src/Microsoft.ML.Transforms/Text/NgramHashingTransformer.cs +++ b/src/Microsoft.ML.Transforms/Text/NgramHashingTransformer.cs @@ -611,14 +611,14 @@ protected override DataViewSchema.DetachedColumn[] GetOutputColumnsCore() var result = new DataViewSchema.DetachedColumn[_parent._columns.Length]; for (int i = 0; i < _parent._columns.Length; i++) { - var builder = new MetadataBuilder(); + var builder = new DataViewSchema.Metadata.Builder(); AddMetadata(i, builder); - result[i] = new DataViewSchema.DetachedColumn(_parent._columns[i].Name, _types[i], builder.GetMetadata()); + result[i] = new DataViewSchema.DetachedColumn(_parent._columns[i].Name, _types[i], builder.ToMetadata()); } return result; } - private void AddMetadata(int i, MetadataBuilder builder) + private void AddMetadata(int i, DataViewSchema.Metadata.Builder builder) { if (_parent._slotNamesTypes != null && _parent._slotNamesTypes[i] != null) { diff --git a/src/Microsoft.ML.Transforms/Text/NgramTransform.cs b/src/Microsoft.ML.Transforms/Text/NgramTransform.cs index b9a5610d95..d8d67e7a90 100644 --- a/src/Microsoft.ML.Transforms/Text/NgramTransform.cs +++ b/src/Microsoft.ML.Transforms/Text/NgramTransform.cs @@ -499,15 +499,15 @@ protected override DataViewSchema.DetachedColumn[] GetOutputColumnsCore() var result = new DataViewSchema.DetachedColumn[_parent.ColumnPairs.Length]; for (int i = 0; i < _parent.ColumnPairs.Length; i++) { - var builder = new MetadataBuilder(); + var builder = new DataViewSchema.Metadata.Builder(); AddMetadata(i, builder); - result[i] = new DataViewSchema.DetachedColumn(_parent.ColumnPairs[i].outputColumnName, _types[i], builder.GetMetadata()); + result[i] = new DataViewSchema.DetachedColumn(_parent.ColumnPairs[i].outputColumnName, _types[i], builder.ToMetadata()); } return result; } - private void AddMetadata(int iinfo, MetadataBuilder builder) + private void AddMetadata(int iinfo, DataViewSchema.Metadata.Builder builder) { if (InputSchema[_srcCols[iinfo]].HasKeyValues()) { diff --git a/src/Microsoft.ML.Transforms/Text/TokenizingByCharacters.cs b/src/Microsoft.ML.Transforms/Text/TokenizingByCharacters.cs index 0548bf50ba..b73a8e742b 100644 --- a/src/Microsoft.ML.Transforms/Text/TokenizingByCharacters.cs +++ b/src/Microsoft.ML.Transforms/Text/TokenizingByCharacters.cs @@ -210,14 +210,14 @@ protected override DataViewSchema.DetachedColumn[] GetOutputColumnsCore() var result = new DataViewSchema.DetachedColumn[_parent.ColumnPairs.Length]; for (int i = 0; i < _parent.ColumnPairs.Length; i++) { - var builder = new MetadataBuilder(); + var builder = new DataViewSchema.Metadata.Builder(); AddMetadata(i, builder); - result[i] = new DataViewSchema.DetachedColumn(_parent.ColumnPairs[i].outputColumnName, _type, builder.GetMetadata()); + result[i] = new DataViewSchema.DetachedColumn(_parent.ColumnPairs[i].outputColumnName, _type, builder.ToMetadata()); } return result; } - private void AddMetadata(int iinfo, MetadataBuilder builder) + private void AddMetadata(int iinfo, DataViewSchema.Metadata.Builder builder) { builder.Add(InputSchema[_parent.ColumnPairs[iinfo].inputColumnName].Metadata, name => name == MetadataUtils.Kinds.SlotNames); ValueGetter>> getter = diff --git a/src/Microsoft.ML.Transforms/UngroupTransform.cs b/src/Microsoft.ML.Transforms/UngroupTransform.cs index 0714571f62..763a1f9079 100644 --- a/src/Microsoft.ML.Transforms/UngroupTransform.cs +++ b/src/Microsoft.ML.Transforms/UngroupTransform.cs @@ -288,7 +288,7 @@ public UngroupBinding(IExceptionContext ectx, DataViewSchema inputSchema, Ungrou _pivotIndex[info.Index] = i; } - var schemaBuilder = new SchemaBuilder(); + var schemaBuilder = new DataViewSchema.Builder(); // Iterate through input columns. Input columns which are not pivot columns will be copied to output schema with the same column index unchanged. // Input columns which are pivot columns would also be copied but with different data types and different metadata. for (int i = 0; i < InputColumnCount; ++i) @@ -301,7 +301,7 @@ public UngroupBinding(IExceptionContext ectx, DataViewSchema inputSchema, Ungrou else { // i-th input column is a pivot column. Let's calculate proper type and metadata for it. - var metadataBuilder = new MetadataBuilder(); + var metadataBuilder = new DataViewSchema.Metadata.Builder(); metadataBuilder.Add(inputSchema[i].Metadata, metadataName => ShouldPreserveMetadata(metadataName)); // To explain the output type of pivot columns, let's consider a row // Age UserID @@ -312,10 +312,10 @@ public UngroupBinding(IExceptionContext ectx, DataViewSchema inputSchema, Ungrou // 18 "Amy" // 18 "Willy" // One can see that "UserID" column (in output data) has a type identical to the element's type of the "UserID" column in input data. - schemaBuilder.AddColumn(inputSchema[i].Name, inputSchema[i].Type.GetItemType(), metadataBuilder.GetMetadata()); + schemaBuilder.AddColumn(inputSchema[i].Name, inputSchema[i].Type.GetItemType(), metadataBuilder.ToMetadata()); } } - OutputSchema = schemaBuilder.GetSchema(); + OutputSchema = schemaBuilder.ToSchema(); } private static void Bind(IExceptionContext ectx, DataViewSchema inputSchema, diff --git a/test/Microsoft.ML.Benchmarks/HashBench.cs b/test/Microsoft.ML.Benchmarks/HashBench.cs index f84e32c92d..570555dadf 100644 --- a/test/Microsoft.ML.Benchmarks/HashBench.cs +++ b/test/Microsoft.ML.Benchmarks/HashBench.cs @@ -52,9 +52,9 @@ public static RowImpl Create(DataViewType type, ValueGetter getter) private RowImpl(DataViewType type, Delegate getter) { - var builder = new SchemaBuilder(); + var builder = new DataViewSchema.Builder(); builder.AddColumn("Foo", type, null); - Schema = builder.GetSchema(); + Schema = builder.ToSchema(); _getter = getter; } } diff --git a/test/Microsoft.ML.StaticPipelineTesting/StaticPipeTests.cs b/test/Microsoft.ML.StaticPipelineTesting/StaticPipeTests.cs index 093bdf4dc1..310703a882 100644 --- a/test/Microsoft.ML.StaticPipelineTesting/StaticPipeTests.cs +++ b/test/Microsoft.ML.StaticPipelineTesting/StaticPipeTests.cs @@ -207,11 +207,11 @@ private static KeyValuePair P(string name, DataViewType ty public void AssertStaticSimple() { var env = new MLContext(0); - var schemaBuilder = new SchemaBuilder(); + var schemaBuilder = new DataViewSchema.Builder(); schemaBuilder.AddColumn("hello", TextDataViewType.Instance); schemaBuilder.AddColumn("my", new VectorType(NumberDataViewType.Int64, 5)); schemaBuilder.AddColumn("friend", new KeyType(typeof(uint), 3)); - var view = new EmptyDataView(env, schemaBuilder.GetSchema()); + var view = new EmptyDataView(env, schemaBuilder.ToSchema()); view.AssertStatic(env, c => new { @@ -231,12 +231,12 @@ public void AssertStaticSimple() public void AssertStaticSimpleFailure() { var env = new MLContext(0); - var schemaBuilder = new SchemaBuilder(); + var schemaBuilder = new DataViewSchema.Builder(); schemaBuilder.AddColumn("hello", TextDataViewType.Instance); schemaBuilder.AddColumn("my", new VectorType(NumberDataViewType.Int64, 5)); schemaBuilder.AddColumn("friend", new KeyType(typeof(uint), 3)); - var view = new EmptyDataView(env, schemaBuilder.GetSchema()); + var view = new EmptyDataView(env, schemaBuilder.ToSchema()); Assert.ThrowsAny(() => view.AssertStatic(env, c => new @@ -260,30 +260,30 @@ public void AssertStaticKeys() // We'll test a few things here. First, the case where the key-value metadata is text. var metaValues1 = new VBuffer>(3, new[] { "a".AsMemory(), "b".AsMemory(), "c".AsMemory() }); - var metaBuilder = new MetadataBuilder(); + var metaBuilder = new DataViewSchema.Metadata.Builder(); metaBuilder.AddKeyValues>(3, TextDataViewType.Instance, metaValues1.CopyTo); - var builder = new MetadataBuilder(); - builder.AddPrimitiveValue("stay", new KeyType(typeof(uint), 3), 2u, metaBuilder.GetMetadata()); + var builder = new DataViewSchema.Metadata.Builder(); + builder.AddPrimitiveValue("stay", new KeyType(typeof(uint), 3), 2u, metaBuilder.ToMetadata()); // Next the case where those values are ints. var metaValues2 = new VBuffer(3, new int[] { 1, 2, 3, 4 }); - metaBuilder = new MetadataBuilder(); + metaBuilder = new DataViewSchema.Metadata.Builder(); metaBuilder.AddKeyValues(3, NumberDataViewType.Int32, metaValues2.CopyTo); var value2 = new VBuffer(2, 0, null, null); - builder.Add>("awhile", new VectorType(new KeyType(typeof(byte), 3), 2), value2.CopyTo, metaBuilder.GetMetadata()); + builder.Add>("awhile", new VectorType(new KeyType(typeof(byte), 3), 2), value2.CopyTo, metaBuilder.ToMetadata()); // Then the case where a value of that kind exists, but is of not of the right kind, in which case it should not be identified as containing that metadata. - metaBuilder = new MetadataBuilder(); + metaBuilder = new DataViewSchema.Metadata.Builder(); metaBuilder.AddPrimitiveValue(MetadataUtils.Kinds.KeyValues, NumberDataViewType.Single, 2f); - builder.AddPrimitiveValue("and", new KeyType(typeof(ushort), 2), (ushort)1, metaBuilder.GetMetadata()); + builder.AddPrimitiveValue("and", new KeyType(typeof(ushort), 2), (ushort)1, metaBuilder.ToMetadata()); // Then a final case where metadata of that kind is actaully simply altogether absent. var value4 = new VBuffer(5, 0, null, null); builder.Add>("listen", new VectorType(new KeyType(typeof(uint), 2)), value4.CopyTo); // Finally compose a trivial data view out of all this. - var view = RowCursorUtils.RowAsDataView(env, MetadataUtils.MetadataAsRow(builder.GetMetadata())); + var view = RowCursorUtils.RowAsDataView(env, MetadataUtils.MetadataAsRow(builder.ToMetadata())); // Whew! I'm glad that's over with. Let us start running the test in ernest. // First let's do a direct match of the types to ensure that works. diff --git a/test/Microsoft.ML.Tests/FakeSchemaTest.cs b/test/Microsoft.ML.Tests/FakeSchemaTest.cs index cb21f037a0..208a62a796 100644 --- a/test/Microsoft.ML.Tests/FakeSchemaTest.cs +++ b/test/Microsoft.ML.Tests/FakeSchemaTest.cs @@ -21,14 +21,14 @@ public FakeSchemaTest(ITestOutputHelper output) [Fact] void SimpleTest() { - var metadataBuilder = new MetadataBuilder(); + var metadataBuilder = new DataViewSchema.Metadata.Builder(); metadataBuilder.Add("M", NumberDataViewType.Single, (ref float v) => v = 484f); - var schemaBuilder = new SchemaBuilder(); + var schemaBuilder = new DataViewSchema.Builder(); schemaBuilder.AddColumn("A", new VectorType(NumberDataViewType.Single, 94)); schemaBuilder.AddColumn("B", new KeyType(typeof(uint), 17)); - schemaBuilder.AddColumn("C", NumberDataViewType.Int32, metadataBuilder.GetMetadata()); + schemaBuilder.AddColumn("C", NumberDataViewType.Int32, metadataBuilder.ToMetadata()); - var shape = SchemaShape.Create(schemaBuilder.GetSchema()); + var shape = SchemaShape.Create(schemaBuilder.ToSchema()); var fakeSchema = FakeSchemaFactory.Create(shape); diff --git a/test/Microsoft.ML.Tests/Transformers/HashTests.cs b/test/Microsoft.ML.Tests/Transformers/HashTests.cs index f075742cb2..86251d44b5 100644 --- a/test/Microsoft.ML.Tests/Transformers/HashTests.cs +++ b/test/Microsoft.ML.Tests/Transformers/HashTests.cs @@ -128,9 +128,9 @@ private void HashTestCore(T val, PrimitiveDataViewType type, uint expected, u { const int bits = 10; - var builder = new MetadataBuilder(); + var builder = new DataViewSchema.Metadata.Builder(); builder.AddPrimitiveValue("Foo", type, val); - var inRow = MetadataUtils.MetadataAsRow(builder.GetMetadata()); + var inRow = MetadataUtils.MetadataAsRow(builder.ToMetadata()); // First do an unordered hash. var info = new HashingEstimator.ColumnInfo("Bar", "Foo", hashBits: bits); @@ -159,9 +159,9 @@ private void HashTestCore(T val, PrimitiveDataViewType type, uint expected, u // at least in the first position, and in the unordered case, the last position. const int vecLen = 5; var denseVec = new VBuffer(vecLen, Utils.CreateArray(vecLen, val)); - builder = new MetadataBuilder(); + builder = new DataViewSchema.Metadata.Builder(); builder.Add("Foo", new VectorType(type, vecLen), (ref VBuffer dst) => denseVec.CopyTo(ref dst)); - inRow = MetadataUtils.MetadataAsRow(builder.GetMetadata()); + inRow = MetadataUtils.MetadataAsRow(builder.ToMetadata()); info = new HashingEstimator.ColumnInfo("Bar", "Foo", hashBits: bits, ordered: false); xf = new HashingTransformer(Env, new[] { info }); @@ -193,9 +193,9 @@ private void HashTestCore(T val, PrimitiveDataViewType type, uint expected, u // Let's now do a sparse vector. var sparseVec = new VBuffer(10, 3, Utils.CreateArray(3, val), new[] { 0, 3, 7 }); - builder = new MetadataBuilder(); + builder = new DataViewSchema.Metadata.Builder(); builder.Add("Foo", new VectorType(type, vecLen), (ref VBuffer dst) => sparseVec.CopyTo(ref dst)); - inRow = MetadataUtils.MetadataAsRow(builder.GetMetadata()); + inRow = MetadataUtils.MetadataAsRow(builder.ToMetadata()); info = new HashingEstimator.ColumnInfo("Bar", "Foo", hashBits: bits, ordered: false); xf = new HashingTransformer(Env, new[] { info }); From 8001ccc6324cd5aad41f8d56dbf76dcdafd9e50d Mon Sep 17 00:00:00 2001 From: Rogan Carr Date: Sun, 24 Feb 2019 15:11:10 -0800 Subject: [PATCH 11/24] Adding functional tests for all training and evaluation tasks (#2646) * Adding functional tests for all training and evaluation tasks --- test/Microsoft.ML.Functional.Tests/Common.cs | 78 ++++- .../Datasets/Iris.cs | 78 +++++ .../Datasets/MnistOneClass.cs | 29 ++ .../Datasets/Sentiment.cs | 20 ++ .../Datasets/TrivialMatrixFactorization.cs | 41 +++ .../Evaluation.cs | 309 ++++++++++++++++++ .../Prediction.cs | 3 +- .../Validation.cs | 6 +- test/Microsoft.ML.TestFramework/Datasets.cs | 12 + .../Scenarios/Api/Estimators/Evaluation.cs | 39 --- 10 files changed, 570 insertions(+), 45 deletions(-) create mode 100644 test/Microsoft.ML.Functional.Tests/Datasets/Iris.cs create mode 100644 test/Microsoft.ML.Functional.Tests/Datasets/MnistOneClass.cs create mode 100644 test/Microsoft.ML.Functional.Tests/Datasets/Sentiment.cs create mode 100644 test/Microsoft.ML.Functional.Tests/Datasets/TrivialMatrixFactorization.cs create mode 100644 test/Microsoft.ML.Functional.Tests/Evaluation.cs delete mode 100644 test/Microsoft.ML.Tests/Scenarios/Api/Estimators/Evaluation.cs diff --git a/test/Microsoft.ML.Functional.Tests/Common.cs b/test/Microsoft.ML.Functional.Tests/Common.cs index 0e3e2e5c68..bcba3a8e27 100644 --- a/test/Microsoft.ML.Functional.Tests/Common.cs +++ b/test/Microsoft.ML.Functional.Tests/Common.cs @@ -7,6 +7,7 @@ using System.Linq; using Microsoft.Data.DataView; using Microsoft.ML.Data; +using Microsoft.ML.Data.Evaluators.Metrics; using Microsoft.ML.Functional.Tests.Datasets; using Xunit; @@ -160,13 +161,86 @@ public static void AssertEqual(TypeTestData testType1, TypeTestData testType2) Assert.True(testType1.Ug.Equals(testType2.Ug)); } + /// + /// Check that a object is valid. + /// + /// The metrics object. + public static void AssertMetrics(AnomalyDetectionMetrics metrics) + { + Assert.InRange(metrics.Auc, 0, 1); + Assert.InRange(metrics.DrAtK, 0, 1); + } + + /// + /// Check that a object is valid. + /// + /// The metrics object. + public static void AssertMetrics(BinaryClassificationMetrics metrics) + { + Assert.InRange(metrics.Accuracy, 0, 1); + Assert.InRange(metrics.Auc, 0, 1); + Assert.InRange(metrics.Auprc, 0, 1); + Assert.InRange(metrics.F1Score, 0, 1); + Assert.InRange(metrics.NegativePrecision, 0, 1); + Assert.InRange(metrics.NegativeRecall, 0, 1); + Assert.InRange(metrics.PositivePrecision, 0, 1); + Assert.InRange(metrics.PositiveRecall, 0, 1); + } + + /// + /// Check that a object is valid. + /// + /// The metrics object. + public static void AssertMetrics(CalibratedBinaryClassificationMetrics metrics) + { + Assert.InRange(metrics.Entropy, double.NegativeInfinity, 1); + Assert.InRange(metrics.LogLoss, double.NegativeInfinity, 1); + Assert.InRange(metrics.LogLossReduction, double.NegativeInfinity, 100); + AssertMetrics(metrics as BinaryClassificationMetrics); + } + + /// + /// Check that a object is valid. + /// + /// The metrics object. + public static void AssertMetrics(ClusteringMetrics metrics) + { + Assert.True(metrics.AvgMinScore >= 0); + Assert.True(metrics.Dbi >= 0); + if (!double.IsNaN(metrics.Nmi)) + Assert.True(metrics.Nmi >= 0 && metrics.Nmi <= 1); + } + + /// + /// Check that a object is valid. + /// + /// The metrics object. + public static void AssertMetrics(MultiClassClassifierMetrics metrics) + { + Assert.InRange(metrics.AccuracyMacro, 0, 1); + Assert.InRange(metrics.AccuracyMicro, 0, 1); + Assert.True(metrics.LogLoss >= 0); + Assert.InRange(metrics.TopKAccuracy, 0, 1); + } + + /// + /// Check that a object is valid. + /// + /// The metrics object. + public static void AssertMetrics(RankerMetrics metrics) + { + foreach (var dcg in metrics.Dcg) + Assert.True(dcg >= 0); + foreach (var ndcg in metrics.Ndcg) + Assert.InRange(ndcg, 0, 100); + } + /// /// Check that a object is valid. /// /// The metrics object. public static void AssertMetrics(RegressionMetrics metrics) { - // Perform sanity checks on the metrics. Assert.True(metrics.Rms >= 0); Assert.True(metrics.L1 >= 0); Assert.True(metrics.L2 >= 0); @@ -179,7 +253,6 @@ public static void AssertMetrics(RegressionMetrics metrics) /// The object. public static void AssertMetricStatistics(MetricStatistics metric) { - // Perform sanity checks on the metrics. Assert.True(metric.StandardDeviation >= 0); Assert.True(metric.StandardError >= 0); } @@ -190,7 +263,6 @@ public static void AssertMetricStatistics(MetricStatistics metric) /// The metrics object. public static void AssertMetricsStatistics(RegressionMetricsStatistics metrics) { - // The mean can be any float; the standard deviation and error must be >=0. AssertMetricStatistics(metrics.Rms); AssertMetricStatistics(metrics.L1); AssertMetricStatistics(metrics.L2); diff --git a/test/Microsoft.ML.Functional.Tests/Datasets/Iris.cs b/test/Microsoft.ML.Functional.Tests/Datasets/Iris.cs new file mode 100644 index 0000000000..d1cbfa3fad --- /dev/null +++ b/test/Microsoft.ML.Functional.Tests/Datasets/Iris.cs @@ -0,0 +1,78 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + + +using System; +using Microsoft.Data.DataView; +using Microsoft.ML.Data; + +namespace Microsoft.ML.Functional.Tests.Datasets +{ + /// + /// A class for the Iris test dataset. + /// + internal sealed class Iris + { + [LoadColumn(0)] + public float Label { get; set; } + + [LoadColumn(1)] + public float SepalLength { get; set; } + + [LoadColumn(2)] + public float SepalWidth { get; set; } + + [LoadColumn(4)] + public float PetalLength { get; set; } + + [LoadColumn(5)] + public float PetalWidth { get; set; } + + /// + /// The list of columns commonly used as features. + /// + public static readonly string[] Features = new string[] { "SepalLength", "SepalWidth", "PetalLength", "PetalWidth" }; + + public static IDataView LoadAsRankingProblem(MLContext mlContext, string filePath, bool hasHeader, char separatorChar, int seed = 1) + { + // Load the Iris data. + var data = mlContext.Data.ReadFromTextFile(filePath, hasHeader: hasHeader, separatorChar: separatorChar); + + // Create a function that generates a random groupId. + var rng = new Random(seed); + Action generateGroupId = (input, output) => + { + output.Label = input.Label; + // The standard set used in tests has 150 rows + output.GroupId = rng.Next(0, 30); + output.PetalLength = input.PetalLength; + output.PetalWidth = input.PetalWidth; + output.SepalLength = input.SepalLength; + output.SepalWidth = input.SepalWidth; + }; + + // Describe a pipeline that generates a groupId and converts it to a key. + var pipeline = mlContext.Transforms.CustomMapping(generateGroupId, null) + .Append(mlContext.Transforms.Conversion.MapValueToKey("GroupId")); + + // Transform the data + var transformedData = pipeline.Fit(data).Transform(data); + + return transformedData; + } + } + + /// + /// A class for the Iris dataset with a GroupId column. + /// + internal sealed class IrisWithGroup + { + public float Label { get; set; } + public int GroupId { get; set; } + public float SepalLength { get; set; } + public float SepalWidth { get; set; } + public float PetalLength { get; set; } + public float PetalWidth { get; set; } + } +} diff --git a/test/Microsoft.ML.Functional.Tests/Datasets/MnistOneClass.cs b/test/Microsoft.ML.Functional.Tests/Datasets/MnistOneClass.cs new file mode 100644 index 0000000000..07b26d3d9c --- /dev/null +++ b/test/Microsoft.ML.Functional.Tests/Datasets/MnistOneClass.cs @@ -0,0 +1,29 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Microsoft.ML.Data; + +namespace Microsoft.ML.Functional.Tests.Datasets +{ + internal sealed class MnistOneClass + { + private const int _featureLength = 783; + + public float Label { get; set; } + + public float[] Features { get; set; } + + public static TextLoader GetTextLoader(MLContext mlContext, bool hasHeader, char separatorChar) + { + return mlContext.Data.CreateTextLoader( + new[] { + new TextLoader.Column("Label", DataKind.R4, 0), + new TextLoader.Column("Features", DataKind.R4, 1, 1 + _featureLength) + }, + separatorChar: separatorChar, + hasHeader: hasHeader, + allowSparse: true); + } + } +} diff --git a/test/Microsoft.ML.Functional.Tests/Datasets/Sentiment.cs b/test/Microsoft.ML.Functional.Tests/Datasets/Sentiment.cs new file mode 100644 index 0000000000..2465e291b3 --- /dev/null +++ b/test/Microsoft.ML.Functional.Tests/Datasets/Sentiment.cs @@ -0,0 +1,20 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Microsoft.ML.Data; + +namespace Microsoft.ML.Functional.Tests.Datasets +{ + /// + /// A class for reading in the Sentiment test dataset. + /// + internal sealed class TweetSentiment + { + [LoadColumn(0), ColumnName("Label")] + public bool Sentiment { get; set; } + + [LoadColumn(1)] + public string SentimentText { get; set; } + } +} diff --git a/test/Microsoft.ML.Functional.Tests/Datasets/TrivialMatrixFactorization.cs b/test/Microsoft.ML.Functional.Tests/Datasets/TrivialMatrixFactorization.cs new file mode 100644 index 0000000000..005fc98c72 --- /dev/null +++ b/test/Microsoft.ML.Functional.Tests/Datasets/TrivialMatrixFactorization.cs @@ -0,0 +1,41 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + + +using System; +using Microsoft.Data.DataView; +using Microsoft.ML.Data; + +namespace Microsoft.ML.Functional.Tests.Datasets +{ + /// + /// A class describing the TrivialMatrixFactorization test dataset. + /// + internal sealed class TrivialMatrixFactorization + { + [LoadColumn(0)] + public float Label { get; set; } + + [LoadColumn(1)] + public uint MatrixColumnIndex { get; set; } + + [LoadColumn(2)] + public uint MatrixRowIndex { get; set; } + + public static IDataView LoadAndFeaturizeFromTextFile(MLContext mlContext, string filePath, bool hasHeader, char separatorChar) + { + // Load the data from a textfile. + var data = mlContext.Data.ReadFromTextFile(filePath, hasHeader: hasHeader, separatorChar: separatorChar); + + // Describe a pipeline to translate the uints to keys. + var pipeline = mlContext.Transforms.Conversion.MapValueToKey("MatrixColumnIndex") + .Append(mlContext.Transforms.Conversion.MapValueToKey("MatrixRowIndex")); + + // Transform the data. + var transformedData = pipeline.Fit(data).Transform(data); + + return transformedData; + } + } +} diff --git a/test/Microsoft.ML.Functional.Tests/Evaluation.cs b/test/Microsoft.ML.Functional.Tests/Evaluation.cs new file mode 100644 index 0000000000..6ffec01b32 --- /dev/null +++ b/test/Microsoft.ML.Functional.Tests/Evaluation.cs @@ -0,0 +1,309 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Microsoft.ML.Functional.Tests.Datasets; +using Microsoft.ML.RunTests; +using Microsoft.ML.TestFramework; +using Microsoft.ML.TestFramework.Attributes; +using Microsoft.ML.Trainers; +using Microsoft.ML.Trainers.FastTree; +using Microsoft.ML.Trainers.KMeans; +using Xunit; +using Xunit.Abstractions; + +namespace Microsoft.ML.Functional.Tests +{ + public class Evaluation : BaseTestClass + { + public Evaluation(ITestOutputHelper output): base(output) + { + } + + /// + /// Train and Evaluate: Anomaly Detection. + /// + [Fact] + public void TrainAndEvaluateAnomalyDetection() + { + var mlContext = new MLContext(seed: 1, conc: 1); + + var trainData = MnistOneClass.GetTextLoader(mlContext, + TestDatasets.mnistOneClass.fileHasHeader, TestDatasets.mnistOneClass.fileSeparator) + .Read(GetDataPath(TestDatasets.mnistOneClass.trainFilename)); + var testData = MnistOneClass.GetTextLoader(mlContext, + TestDatasets.mnistOneClass.fileHasHeader, TestDatasets.mnistOneClass.fileSeparator) + .Read(GetDataPath(TestDatasets.mnistOneClass.testFilename)); + + // Create a training pipeline. + var pipeline = mlContext.AnomalyDetection.Trainers.RandomizedPca(); + + // Train the model. + var model = pipeline.Fit(trainData); + + // Evaluate the model. + // TODO #2464: Using the train dataset will cause NaN metrics to be returned. + var scoredTest = model.Transform(testData); + var metrics = mlContext.AnomalyDetection.Evaluate(scoredTest); + + // Check that the metrics returned are valid. + Common.AssertMetrics(metrics); + } + + /// + /// Train and Evaluate: Binary Classification with no calibration. + /// + [Fact] + public void TrainAndEvaluateBinaryClassification() + { + var mlContext = new MLContext(seed: 1, conc: 1); + + var data = mlContext.Data.ReadFromTextFile(GetDataPath(TestDatasets.Sentiment.trainFilename), + hasHeader: TestDatasets.Sentiment.fileHasHeader, + separatorChar: TestDatasets.Sentiment.fileSeparator); + + // Create a training pipeline. + var pipeline = mlContext.Transforms.Text.FeaturizeText("Features", "SentimentText") + .AppendCacheCheckpoint(mlContext) + .Append(mlContext.BinaryClassification.Trainers.StochasticDualCoordinateAscentNonCalibrated( + new SdcaNonCalibratedBinaryTrainer.Options { NumThreads = 1 })); + + // Train the model. + var model = pipeline.Fit(data); + + // Evaluate the model. + var scoredData = model.Transform(data); + var metrics = mlContext.BinaryClassification.EvaluateNonCalibrated(scoredData); + + // Check that the metrics returned are valid. + Common.AssertMetrics(metrics); + } + + /// + /// Train and Evaluate: Binary Classification with a calibrated predictor. + /// + [Fact] + public void TrainAndEvaluateBinaryClassificationWithCalibration() + { + var mlContext = new MLContext(seed: 1, conc: 1); + + var data = mlContext.Data.ReadFromTextFile(GetDataPath(TestDatasets.Sentiment.trainFilename), + hasHeader: TestDatasets.Sentiment.fileHasHeader, + separatorChar: TestDatasets.Sentiment.fileSeparator); + + // Create a training pipeline. + var pipeline = mlContext.Transforms.Text.FeaturizeText("Features", "SentimentText") + .AppendCacheCheckpoint(mlContext) + .Append(mlContext.BinaryClassification.Trainers.LogisticRegression( + new LogisticRegression.Options { NumThreads = 1 })); + + // Train the model. + var model = pipeline.Fit(data); + + // Evaluate the model. + var scoredData = model.Transform(data); + var metrics = mlContext.BinaryClassification.Evaluate(scoredData); + + // Check that the metrics returned are valid. + Common.AssertMetrics(metrics); + } + + /// + /// Train and Evaluate: Clustering. + /// + [Fact] + public void TrainAndEvaluateClustering() + { + var mlContext = new MLContext(seed: 1, conc: 1); + + var data = mlContext.Data.ReadFromTextFile(GetDataPath(TestDatasets.iris.trainFilename), + hasHeader: TestDatasets.iris.fileHasHeader, + separatorChar: TestDatasets.iris.fileSeparator); + + // Create a training pipeline. + var pipeline = mlContext.Transforms.Concatenate("Features", Iris.Features) + .AppendCacheCheckpoint(mlContext) + .Append(mlContext.Clustering.Trainers.KMeans(new KMeansPlusPlusTrainer.Options { NumThreads = 1 })); + + // Train the model. + var model = pipeline.Fit(data); + + // Evaluate the model. + var scoredData = model.Transform(data); + var metrics = mlContext.Clustering.Evaluate(scoredData); + + // Check that the metrics returned are valid. + Common.AssertMetrics(metrics); + } + + /// + /// Train and Evaluate: Multiclass Classification. + /// + [Fact] + public void TrainAndEvaluateMulticlassClassification() + { + var mlContext = new MLContext(seed: 1, conc: 1); + + var data = mlContext.Data.ReadFromTextFile(GetDataPath(TestDatasets.iris.trainFilename), + hasHeader: TestDatasets.iris.fileHasHeader, + separatorChar: TestDatasets.iris.fileSeparator); + + // Create a training pipeline. + var pipeline = mlContext.Transforms.Concatenate("Features", Iris.Features) + .AppendCacheCheckpoint(mlContext) + .Append(mlContext.MulticlassClassification.Trainers.StochasticDualCoordinateAscent( + new SdcaMultiClassTrainer.Options { NumThreads = 1})); + + // Train the model. + var model = pipeline.Fit(data); + + // Evaluate the model. + var scoredData = model.Transform(data); + var metrics = mlContext.MulticlassClassification.Evaluate(scoredData); + + // Check that the metrics returned are valid. + Common.AssertMetrics(metrics); + } + + /// + /// Train and Evaluate: Ranking. + /// + [Fact] + public void TrainAndEvaluateRanking() + { + var mlContext = new MLContext(seed: 1, conc: 1); + + var data = Iris.LoadAsRankingProblem(mlContext, + GetDataPath(TestDatasets.iris.trainFilename), + hasHeader: TestDatasets.iris.fileHasHeader, + separatorChar: TestDatasets.iris.fileSeparator); + + // Create a training pipeline. + var pipeline = mlContext.Transforms.Concatenate("Features", Iris.Features) + .Append(mlContext.Ranking.Trainers.FastTree(new FastTreeRankingTrainer.Options { NumThreads = 1 })); + + // Train the model. + var model = pipeline.Fit(data); + + // Evaluate the model. + var scoredData = model.Transform(data); + var metrics = mlContext.Ranking.Evaluate(scoredData, label: "Label", groupId: "GroupId"); + + // Check that the metrics returned are valid. + Common.AssertMetrics(metrics); + } + + /// + /// Train and Evaluate: Recommendation. + /// + [MatrixFactorizationFact] + public void TrainAndEvaluateRecommendation() + { + var mlContext = new MLContext(seed: 1, conc: 1); + + // Get the dataset. + var data = TrivialMatrixFactorization.LoadAndFeaturizeFromTextFile( + mlContext, + GetDataPath(TestDatasets.trivialMatrixFactorization.trainFilename), + TestDatasets.trivialMatrixFactorization.fileHasHeader, + TestDatasets.trivialMatrixFactorization.fileSeparator); + + // Create a pipeline to train on the sentiment data. + var pipeline = mlContext.Recommendation().Trainers.MatrixFactorization( + new MatrixFactorizationTrainer.Options{ + MatrixColumnIndexColumnName = "MatrixColumnIndex", + MatrixRowIndexColumnName = "MatrixRowIndex", + LabelColumnName = "Label", + NumberOfIterations = 3, + NumberOfThreads = 1, + ApproximationRank = 4, + }); + + // Train the model. + var model = pipeline.Fit(data); + + // Evaluate the model. + var scoredData = model.Transform(data); + var metrics = mlContext.Recommendation().Evaluate(scoredData); + + // Check that the metrics returned are valid. + Common.AssertMetrics(metrics); + } + + /// + /// Train and Evaluate: Regression. + /// + [Fact] + public void TrainAndEvaluateRegression() + { + var mlContext = new MLContext(seed: 1, conc: 1); + + // Get the dataset. + var data = mlContext.Data.CreateTextLoader(TestDatasets.housing.GetLoaderColumns(), + hasHeader: TestDatasets.housing.fileHasHeader, separatorChar: TestDatasets.housing.fileSeparator) + .Read(GetDataPath(TestDatasets.housing.trainFilename)); + + // Create a pipeline to train on the sentiment data. + var pipeline = mlContext.Transforms.Concatenate("Features", new string[] { + "CrimesPerCapita", "PercentResidental", "PercentNonRetail", "CharlesRiver", "NitricOxides", "RoomsPerDwelling", + "PercentPre40s", "EmploymentDistance", "HighwayDistance", "TaxRate", "TeacherRatio"}) + .Append(mlContext.Transforms.CopyColumns("Label", "MedianHomeValue")) + .Append(mlContext.Regression.Trainers.FastTree(new FastTreeRegressionTrainer.Options { NumThreads = 1 })); + + // Train the model. + var model = pipeline.Fit(data); + + // Evaluate the model. + var scoredData = model.Transform(data); + var metrics = mlContext.Regression.Evaluate(scoredData); + + // Check that the metrics returned are valid. + Common.AssertMetrics(metrics); + } + + /// + /// Evaluate With Precision-Recall Curves. + /// + /// + /// This is currently not possible using the APIs. + /// + [Fact] + public void TrainAndEvaluateWithPrecisionRecallCurves() + { + var mlContext = new MLContext(seed: 1, conc: 1); + + var data = mlContext.Data.ReadFromTextFile(GetDataPath(TestDatasets.Sentiment.trainFilename), + hasHeader: TestDatasets.Sentiment.fileHasHeader, + separatorChar: TestDatasets.Sentiment.fileSeparator); + + // Create a training pipeline. + var pipeline = mlContext.Transforms.Text.FeaturizeText("Features", "SentimentText") + .AppendCacheCheckpoint(mlContext) + .Append(mlContext.BinaryClassification.Trainers.LogisticRegression( + new LogisticRegression.Options { NumThreads = 1 })); + + // Train the model. + var model = pipeline.Fit(data); + + // Evaluate the model. + var scoredData = model.Transform(data); + var metrics = mlContext.BinaryClassification.Evaluate(scoredData); + + Common.AssertMetrics(metrics); + + // This scenario is not possible with the current set of APIs. + // There could be two ways imaginable: + // 1. Getting a list of (P,R) from the Evaluator (as it calculates most of the information already). + // Not currently possible. + // 2. Manually setting the classifier threshold and calling evaluate many times: + // Not currently possible: Todo #2465: Allow the setting of threshold and thresholdColumn for scoring. + // Technically, this scenario is possible using custom mappers like so: + // 1. Get a list of all unique probability scores. + // e.g. By reading the IDataView as an IEnumerable, and keeping a hash of known probabilities up to some precision. + // 2. For each value of probability: + // a. Write a custom mapper to produce PredictedLabel at that probability threshold. + // b. Calculate Precision and Recall with these labels. + // c. Append the Precision and Recall to an IList. + } + } +} \ No newline at end of file diff --git a/test/Microsoft.ML.Functional.Tests/Prediction.cs b/test/Microsoft.ML.Functional.Tests/Prediction.cs index 661aac3fcd..74ec111c92 100644 --- a/test/Microsoft.ML.Functional.Tests/Prediction.cs +++ b/test/Microsoft.ML.Functional.Tests/Prediction.cs @@ -22,7 +22,8 @@ public void ReconfigurablePrediction() var mlContext = new MLContext(seed: 789); // Get the dataset, create a train and test - var data = mlContext.Data.CreateTextLoader(TestDatasets.housing.GetLoaderColumns(), hasHeader: true) + var data = mlContext.Data.CreateTextLoader(TestDatasets.housing.GetLoaderColumns(), + hasHeader: TestDatasets.housing.fileHasHeader, separatorChar: TestDatasets.housing.fileSeparator) .Read(BaseTestClass.GetDataPath(TestDatasets.housing.trainFilename)); var split = mlContext.BinaryClassification.TrainTestSplit(data, testFraction: 0.2); diff --git a/test/Microsoft.ML.Functional.Tests/Validation.cs b/test/Microsoft.ML.Functional.Tests/Validation.cs index eebe55b58c..ed1cccbf7c 100644 --- a/test/Microsoft.ML.Functional.Tests/Validation.cs +++ b/test/Microsoft.ML.Functional.Tests/Validation.cs @@ -27,7 +27,8 @@ void CrossValidation() var mlContext = new MLContext(seed: 1, conc: 1); // Get the dataset. - var data = mlContext.Data.CreateTextLoader(TestDatasets.housing.GetLoaderColumns(), hasHeader: true) + var data = mlContext.Data.CreateTextLoader(TestDatasets.housing.GetLoaderColumns(), + hasHeader: TestDatasets.housing.fileHasHeader, separatorChar: TestDatasets.housing.fileSeparator) .Read(BaseTestClass.GetDataPath(TestDatasets.housing.trainFilename)); // Create a pipeline to train on the sentiment data. @@ -60,7 +61,8 @@ public void TrainWithValidationSet() var mlContext = new MLContext(seed: 1, conc: 1); // Get the dataset. - var data = mlContext.Data.CreateTextLoader(TestDatasets.housing.GetLoaderColumns(), hasHeader: true) + var data = mlContext.Data.CreateTextLoader(TestDatasets.housing.GetLoaderColumns(), + hasHeader: TestDatasets.housing.fileHasHeader, separatorChar: TestDatasets.housing.fileSeparator) .Read(BaseTestClass.GetDataPath(TestDatasets.housing.trainFilename)); var dataSplit = mlContext.Regression.TrainTestSplit(data, testFraction: 0.2); var trainData = dataSplit.TrainSet; diff --git a/test/Microsoft.ML.TestFramework/Datasets.cs b/test/Microsoft.ML.TestFramework/Datasets.cs index 7197f1f64b..abc9862049 100644 --- a/test/Microsoft.ML.TestFramework/Datasets.cs +++ b/test/Microsoft.ML.TestFramework/Datasets.cs @@ -14,6 +14,8 @@ public class TestDataset public string testFilename; public string validFilename; public string labelFilename; + public char fileSeparator; + public bool fileHasHeader; // REVIEW: Replace these with appropriate SubComponents! public string settings; @@ -158,6 +160,8 @@ public static class TestDatasets name = "housing", trainFilename = "housing.txt", testFilename = "housing.txt", + fileSeparator = '\t', + fileHasHeader = true, loaderSettings = "loader=Text{col=Label:0 col=Features:~ header=+}", GetLoaderColumns = () => { @@ -206,6 +210,8 @@ public static class TestDatasets name = "sentiment", trainFilename = "wikipedia-detox-250-line-data.tsv", testFilename = "wikipedia-detox-250-line-test.tsv", + fileHasHeader = true, + fileSeparator = '\t', GetLoaderColumns = () => { return new[] @@ -447,6 +453,8 @@ public static class TestDatasets name = "iris", trainFilename = @"iris.txt", testFilename = @"iris.txt", + fileHasHeader = true, + fileSeparator = '\t' }; public static TestDataset irisMissing = new TestDataset() @@ -655,6 +663,8 @@ public static class TestDatasets name = "mnistOneClass", trainFilename = @"MNIST.Train.0-class.tiny.txt", testFilename = @"MNIST.Test.tiny.txt", + fileHasHeader = false, + fileSeparator = '\t', settings = "" }; @@ -704,6 +714,8 @@ public static class TestDatasets name = "trivialMatrixFactorization", trainFilename = @"trivial-train.tsv", testFilename = @"trivial-test.tsv", + fileHasHeader = true, + fileSeparator = '\t', loaderSettings = "loader=Text{col=Label:R4:0 col=User:U4[0-19]:1 col=Item:U4[0-39]:2 header+}" }; } diff --git a/test/Microsoft.ML.Tests/Scenarios/Api/Estimators/Evaluation.cs b/test/Microsoft.ML.Tests/Scenarios/Api/Estimators/Evaluation.cs deleted file mode 100644 index cad289872e..0000000000 --- a/test/Microsoft.ML.Tests/Scenarios/Api/Estimators/Evaluation.cs +++ /dev/null @@ -1,39 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using Microsoft.ML.Data; -using Microsoft.ML.RunTests; -using Microsoft.ML.Trainers; -using Xunit; - -namespace Microsoft.ML.Tests.Scenarios.Api -{ - public partial class ApiScenariosTests - { - /// - /// Evaluation: Similar to the simple train scenario, except instead of having some - /// predictive structure, be able to score another "test" data file, run the result - /// through an evaluator and get metrics like AUC, accuracy, PR curves, and whatnot. - /// Getting metrics out of this should be as straightforward and unannoying as possible. - /// - [Fact] - public void Evaluation() - { - var ml = new MLContext(seed: 1, conc: 1); - - // Pipeline. - var pipeline = ml.Data.CreateTextLoader(TestDatasets.Sentiment.GetLoaderColumns(), hasHeader: true) - .Append(ml.Transforms.Text.FeaturizeText("Features", "SentimentText")) - .Append(ml.BinaryClassification.Trainers.StochasticDualCoordinateAscent( - new SdcaBinaryTrainer.Options { NumThreads = 1 })); - - // Train. - var readerModel = pipeline.Fit(new MultiFileSource(GetDataPath(TestDatasets.Sentiment.trainFilename))); - - // Evaluate on the test set. - var dataEval = readerModel.Read(new MultiFileSource(GetDataPath(TestDatasets.Sentiment.testFilename))); - var metrics = ml.BinaryClassification.Evaluate(dataEval); - } - } -} From 850559f62689d6ea4d91036dfdf5a0963a74634f Mon Sep 17 00:00:00 2001 From: Ivan Matantsev Date: Mon, 25 Feb 2019 09:33:31 -0800 Subject: [PATCH 12/24] Introduce order for pixel extraction (#2602) --- .../ExtensionsCatalog.cs | 64 ++-- .../ImagePixelExtractor.cs | 282 +++++++++------- .../ImageResizer.cs | 23 +- .../VectorToImageTransform.cs | 301 +++++++++++++----- .../ImageStaticPipe.cs | 18 +- .../ImageTransformsStatic.cs | 4 +- .../Common/EntryPoints/core_manifest.json | 176 ++++++++-- .../DnnImageFeaturizerTest.cs | 2 +- .../OnnxTransformTests.cs | 2 +- test/Microsoft.ML.Tests/ImagesTests.cs | 106 ++++-- .../TensorFlowEstimatorTests.cs | 4 +- 11 files changed, 699 insertions(+), 283 deletions(-) diff --git a/src/Microsoft.ML.ImageAnalytics/ExtensionsCatalog.cs b/src/Microsoft.ML.ImageAnalytics/ExtensionsCatalog.cs index eeb8d38af5..7f1512d2f4 100644 --- a/src/Microsoft.ML.ImageAnalytics/ExtensionsCatalog.cs +++ b/src/Microsoft.ML.ImageAnalytics/ExtensionsCatalog.cs @@ -45,15 +45,16 @@ public static ImageLoadingEstimator LoadImages(this TransformsCatalog catalog, s => new ImageLoadingEstimator(CatalogUtils.GetEnvironment(catalog), imageFolder, SimpleColumnInfo.ConvertToValueTuples(columnPairs)); /// - /// The transform's catalog. - /// Name of the column resulting from the transformation of . - /// Name of column to transform. If set to , the value of the will be used as source. - /// Specifies which to extract from the image. The order of colors is: Alpha, Red, Green Blue. - /// Wheather to interleave the pixels, meaning keep them in the `ARGB ARGB` order, or leave them separated in the planar form, where the colors are outputed one by one - /// alpha, red, green, blue for all the pixels of the image. - /// Scale color pixel value by this amount. - /// Offset color pixel value by this amount. - /// Output the array as float array. If false, output as byte array. + /// The transform's catalog. + /// Name of the column resulting from the transformation of . + /// Name of column to transform. If set to , the value of the will be used as source. + /// What colors to extract. + /// In which order to extract colors from pixel. + /// Whether to interleave the pixels colors, meaning keep them in the order, or leave them in the plannar form: + /// all the values for one color for all pixels, then all the values for another color and so on. + /// Offset pixel's color value by this amount. Applied to color value first. + /// Scale pixel's color value by this amount. Applied to color value second. + /// Output array as float array. If false, output as byte array and ignores and . /// /// /// new ImagePixelExtractingEstimator(CatalogUtils.GetEnvironment(catalog), outputColumnName, inputColumnName, colors, interleave, scale, offset, asFloat); + float offset = ImagePixelExtractingEstimator.Defaults.Offset, + float scale = ImagePixelExtractingEstimator.Defaults.Scale, + bool asFloat = ImagePixelExtractingEstimator.Defaults.Convert) + => new ImagePixelExtractingEstimator(CatalogUtils.GetEnvironment(catalog), outputColumnName, inputColumnName, colors, order, interleave, offset, scale, asFloat); /// /// The transform's catalog. @@ -89,8 +91,8 @@ public static ImagePixelExtractingEstimator ExtractPixels(this TransformsCatalog /// /// /// The transform's catalog. - /// Name of the input column. - /// Name of the resulting output column. + /// Name of the column resulting from the transformation of . + /// Name of column to transform. If set to , the value of the will be used as source. /// The transformed image width. /// The transformed image height. /// The type of image resizing as specified in . @@ -150,16 +152,26 @@ public static VectorToImageConvertingEstimator ConvertToImage(this TransformsCat /// The width of the output images. /// Name of the column resulting from the transformation of . /// Name of column to transform. If set to , the value of the will be used as source. - /// Specifies which are in the input pixel vectors. The order of colors is: Alpha, Red, Green Blue. - /// Whether the pixels are interleaved, meaning whether they are in `ARGB ARGB` order, or separated in the planar form, where the colors are specified one by one - /// alpha, red, green, blue for all the pixels of the image. - /// The values are scaled by this value before being converted to pixels. - /// The offset is subtracted (before scaling) before converting the values to pixels. + /// Specifies which are in the input pixel vectors. The order of colors specified in . + /// In which order extracted colors presented in array. + /// Whether the pixels are interleaved, meaning whether they are in order, or separated in the planar form: + /// all the values for one color for all pixels, then all the values for another color and so on. + /// The values are scaled by this value before being converted to pixels. Applied to vector value first. + /// The offset is subtracted before converting the values to pixels. Applied to vector value second. + /// Default value for alpha color, would be overriden if contains . + /// Default value for red color, would be overriden if contains . + /// Default value for grenn color, would be overriden if contains . + /// Default value for blue color, would be overriden if contains . public static VectorToImageConvertingEstimator ConvertToImage(this TransformsCatalog catalog, int height, int width, string outputColumnName, string inputColumnName = null, - ImagePixelExtractingEstimator.ColorBits colors = VectorToImageConvertingTransformer.Defaults.Colors, - bool interleave = VectorToImageConvertingTransformer.Defaults.InterleaveArgb, - float scale = VectorToImageConvertingTransformer.Defaults.Scale, - float offset = VectorToImageConvertingTransformer.Defaults.Offset) - => new VectorToImageConvertingEstimator(CatalogUtils.GetEnvironment(catalog), height, width, outputColumnName, inputColumnName, colors, interleave, scale, offset); + ImagePixelExtractingEstimator.ColorBits colors = ImagePixelExtractingEstimator.Defaults.Colors, + ImagePixelExtractingEstimator.ColorsOrder order = ImagePixelExtractingEstimator.Defaults.Order, + bool interleave = ImagePixelExtractingEstimator.Defaults.Interleave, + float scale = VectorToImageConvertingEstimator.Defaults.Scale, + float offset = VectorToImageConvertingEstimator.Defaults.Offset, + int defaultAlpha = VectorToImageConvertingEstimator.Defaults.DefaultAlpha, + int defaultRed = VectorToImageConvertingEstimator.Defaults.DefaultRed, + int defaultGreen = VectorToImageConvertingEstimator.Defaults.DefaultGreen, + int defaultBlue = VectorToImageConvertingEstimator.Defaults.DefaultBlue) + => new VectorToImageConvertingEstimator(CatalogUtils.GetEnvironment(catalog), height, width, outputColumnName, inputColumnName, colors, order, interleave, scale, offset); } } diff --git a/src/Microsoft.ML.ImageAnalytics/ImagePixelExtractor.cs b/src/Microsoft.ML.ImageAnalytics/ImagePixelExtractor.cs index 8a2cf2b0ab..bc7b0c2359 100644 --- a/src/Microsoft.ML.ImageAnalytics/ImagePixelExtractor.cs +++ b/src/Microsoft.ML.ImageAnalytics/ImagePixelExtractor.cs @@ -38,7 +38,7 @@ namespace Microsoft.ML.ImageAnalytics /// During the transformation, the columns of are converted them into a vector representing the image pixels /// than can be further used as features by the algorithms added to the pipeline. /// - /// + /// /// /// public sealed class ImagePixelExtractingTransformer : OneToOneTransformerBase @@ -58,9 +58,12 @@ internal class Column : OneToOneColumn [Argument(ArgumentType.AtMostOnce, HelpText = "Whether to use blue channel", ShortName = "blue")] public bool? UseBlue; + [Argument(ArgumentType.AtMostOnce, HelpText = "Order of channels")] + public ImagePixelExtractingEstimator.ColorsOrder? Order; + // REVIEW: Consider turning this into an enum that allows for pixel, line, or planar interleaving. - [Argument(ArgumentType.AtMostOnce, HelpText = "Whether to separate each channel or interleave in ARGB order", ShortName = "interleave")] - public bool? InterleaveArgb; + [Argument(ArgumentType.AtMostOnce, HelpText = "Whether to separate each channel or interleave in specified order")] + public bool? Interleave; [Argument(ArgumentType.AtMostOnce, HelpText = "Whether to convert to floating point", ShortName = "conv")] public bool? Convert; @@ -85,7 +88,7 @@ internal bool TryUnparse(StringBuilder sb) { Contracts.AssertValue(sb); if (UseAlpha != null || UseRed != null || UseGreen != null || UseBlue != null || Convert != null || - Offset != null || Scale != null || InterleaveArgb != null) + Offset != null || Scale != null || Interleave != null || Order != null) { return false; } @@ -111,11 +114,14 @@ internal class Options : TransformInputBase [Argument(ArgumentType.AtMostOnce, HelpText = "Whether to use blue channel", ShortName = "blue")] public bool UseBlue = true; - [Argument(ArgumentType.AtMostOnce, HelpText = "Whether to separate each channel or interleave in ARGB order", ShortName = "interleave")] - public bool InterleaveArgb = Defaults.Interleave; + [Argument(ArgumentType.AtMostOnce, HelpText = "Order of colors.")] + public ImagePixelExtractingEstimator.ColorsOrder Order = ImagePixelExtractingEstimator.Defaults.Order; + + [Argument(ArgumentType.AtMostOnce, HelpText = "Whether to separate each channel or interleave in specified order")] + public bool Interleave = ImagePixelExtractingEstimator.Defaults.Interleave; [Argument(ArgumentType.AtMostOnce, HelpText = "Whether to convert to floating point", ShortName = "conv")] - public bool Convert = Defaults.Convert; + public bool Convert = ImagePixelExtractingEstimator.Defaults.Convert; [Argument(ArgumentType.AtMostOnce, HelpText = "Offset (pre-scale)")] public Single? Offset; @@ -124,25 +130,18 @@ internal class Options : TransformInputBase public Single? Scale; } - internal static class Defaults - { - public const ImagePixelExtractingEstimator.ColorBits Colors = ImagePixelExtractingEstimator.ColorBits.Rgb; - public const bool Interleave = false; - public const bool Convert = true; - public const float Scale = 1f; - public const float Offset = 0f; - } - internal const string Summary = "Extract color plane(s) from an image. Options include scaling, offset and conversion to floating point."; internal const string UserName = "Image Pixel Extractor Transform"; internal const string LoaderSignature = "ImagePixelExtractor"; + internal const uint BeforeOrderVersion = 0x00010002; private static VersionInfo GetVersionInfo() { return new VersionInfo( modelSignature: "IMGPXEXT", //verWrittenCur: 0x00010001, // Initial - verWrittenCur: 0x00010002, // Swith from OpenCV to Bitmap + //verWrittenCur: 0x00010002, // Swith from OpenCV to Bitmap + verWrittenCur: 0x00010003, // Add pixel order verReadableCur: 0x00010002, verWeCanReadBack: 0x00010002, loaderSignature: LoaderSignature, @@ -165,19 +164,22 @@ private static VersionInfo GetVersionInfo() /// Name of the column resulting from the transformation of . /// Name of column to transform. If set to , the value of the will be used as source. /// What colors to extract. - /// - /// Scale color pixel value by this amount. - /// Offset color pixel value by this amount. - /// Output array as float array. If false, output as byte array. + /// In which order to extract colors from pixel. + /// Whether to interleave the pixels colors, meaning keep them in the order, or leave them in the plannar form: + /// all the values for one color for all pixels, then all the values for another color and so on. + /// Offset pixel's color value by this amount. Applied to color value first. + /// Scale pixel's color value by this amount. Applied to color value second. + /// Output array as float array. If false, output as byte array and ignores and . internal ImagePixelExtractingTransformer(IHostEnvironment env, string outputColumnName, string inputColumnName = null, - ImagePixelExtractingEstimator.ColorBits colors = ImagePixelExtractingEstimator.ColorBits.Rgb, - bool interleave = Defaults.Interleave, - float scale = Defaults.Scale, - float offset = Defaults.Offset, - bool asFloat = Defaults.Convert) - : this(env, new ImagePixelExtractingEstimator.ColumnInfo(outputColumnName, inputColumnName, colors, interleave, scale, offset, asFloat)) + ImagePixelExtractingEstimator.ColorBits colors = ImagePixelExtractingEstimator.Defaults.Colors, + ImagePixelExtractingEstimator.ColorsOrder order = ImagePixelExtractingEstimator.Defaults.Order, + bool interleave = ImagePixelExtractingEstimator.Defaults.Interleave, + float offset = ImagePixelExtractingEstimator.Defaults.Offset, + float scale = ImagePixelExtractingEstimator.Defaults.Scale, + bool asFloat = ImagePixelExtractingEstimator.Defaults.Convert) + : this(env, new ImagePixelExtractingEstimator.ColumnInfo(outputColumnName, inputColumnName, colors, order, interleave, offset, scale, asFloat)) { } @@ -372,10 +374,7 @@ private ValueGetter> GetGetterCore(DataViewRow input, in bool needScale = offset != 0 || scale != 1; Contracts.Assert(!needScale || !vf.IsEmpty); - bool a = ex.Alpha; - bool r = ex.Red; - bool g = ex.Green; - bool b = ex.Blue; + ImagePixelExtractingEstimator.GetOrder(ex.Order, ex.Colors, out int a, out int r, out int b, out int g); int h = height; int w = width; @@ -389,25 +388,27 @@ private ValueGetter> GetGetterCore(DataViewRow input, in var pb = src.GetPixel(x, y); if (!vb.IsEmpty) { - if (a) { vb[idst++] = pb.A; } - if (r) { vb[idst++] = pb.R; } - if (g) { vb[idst++] = pb.G; } - if (b) { vb[idst++] = pb.B; } + if (a != -1) { vb[idst + a] = pb.A; } + if (r != -1) { vb[idst + r] = pb.R; } + if (g != -1) { vb[idst + g] = pb.G; } + if (b != -1) { vb[idst + b] = pb.B; } } else if (!needScale) { - if (a) { vf[idst++] = pb.A; } - if (r) { vf[idst++] = pb.R; } - if (g) { vf[idst++] = pb.G; } - if (b) { vf[idst++] = pb.B; } + if (a != -1) { vf[idst + a] = pb.A; } + if (r != -1) { vf[idst + r] = pb.R; } + if (g != -1) { vf[idst + g] = pb.G; } + if (b != -1) { vf[idst + b] = pb.B; } } else { - if (a) { vf[idst++] = (pb.A - offset) * scale; } - if (r) { vf[idst++] = (pb.R - offset) * scale; } - if (g) { vf[idst++] = (pb.G - offset) * scale; } - if (b) { vf[idst++] = (pb.B - offset) * scale; } + + if (a != -1) { vf[idst + a] = (pb.A - offset) * scale; } + if (r != -1) { vf[idst + r] = (pb.R - offset) * scale; } + if (g != -1) { vf[idst + g] = (pb.G - offset) * scale; } + if (b != -1) { vf[idst + b] = (pb.B - offset) * scale; } } + idst += ex.Planes; } Contracts.Assert(idst == size); } @@ -416,43 +417,32 @@ private ValueGetter> GetGetterCore(DataViewRow input, in int idstMin = 0; for (int y = 0; y < h; ++y) { - int idstBase = idstMin + y * w; - - // Note that the bytes are in order BGR[A]. We arrange the layers in order ARGB. - if (!vb.IsEmpty) + int idst = idstMin + y * w; + for (int x = 0; x < w; x++, idst++) { - for (int x = 0; x < w; x++, idstBase++) + if (!vb.IsEmpty) { var pb = src.GetPixel(x, y); - int idst = idstBase; - if (a) { vb[idst] = pb.A; idst += cpix; } - if (r) { vb[idst] = pb.R; idst += cpix; } - if (g) { vb[idst] = pb.G; idst += cpix; } - if (b) { vb[idst] = pb.B; idst += cpix; } + if (a != -1) vb[idst + cpix * a] = pb.A; + if (r != -1) vb[idst + cpix * r] = pb.R; + if (g != -1) vb[idst + cpix * g] = pb.G; + if (b != -1) vb[idst + cpix * b] = pb.B; } - } - else if (!needScale) - { - for (int x = 0; x < w; x++, idstBase++) + else if (!needScale) { var pb = src.GetPixel(x, y); - int idst = idstBase; - if (a) { vf[idst] = pb.A; idst += cpix; } - if (r) { vf[idst] = pb.R; idst += cpix; } - if (g) { vf[idst] = pb.G; idst += cpix; } - if (b) { vf[idst] = pb.B; idst += cpix; } + if (a != -1) vf[idst + cpix * a] = pb.A; + if (r != -1) vf[idst + cpix * r] = pb.R; + if (g != -1) vf[idst + cpix * g] = pb.G; + if (b != -1) vf[idst + cpix * b] = pb.B; } - } - else - { - for (int x = 0; x < w; x++, idstBase++) + else { var pb = src.GetPixel(x, y); - int idst = idstBase; - if (a) { vf[idst] = (pb.A - offset) * scale; idst += cpix; } - if (r) { vf[idst] = (pb.R - offset) * scale; idst += cpix; } - if (g) { vf[idst] = (pb.G - offset) * scale; idst += cpix; } - if (b) { vf[idst] = (pb.B - offset) * scale; idst += cpix; } + if (a != -1) vf[idst + cpix * a] = (pb.A - offset) * scale; + if (r != -1) vf[idst + cpix * r] = (pb.R - offset) * scale; + if (g != -1) vf[idst + cpix * g] = (pb.G - offset) * scale; + if (b != -1) vf[idst + cpix * b] = (pb.B - offset) * scale; } } } @@ -496,11 +486,21 @@ private VectorType[] ConstructTypes() /// /// Calling in this estimator, produces an . /// - /// + /// /// /// public sealed class ImagePixelExtractingEstimator : TrivialEstimator { + [BestFriend] + internal static class Defaults + { + public const ColorsOrder Order = ColorsOrder.ARGB; + public const ColorBits Colors = ColorBits.Rgb; + public const bool Interleave = false; + public const bool Convert = true; + public const float Scale = 1f; + public const float Offset = 0f; + } /// /// Which color channels are extracted. Note that these values are serialized so should not be modified. /// @@ -516,6 +516,51 @@ public enum ColorBits : byte All = Alpha | Red | Green | Blue } + public enum ColorsOrder : byte + { +#pragma warning disable MSML_GeneralName // This name should be PascalCased + ARGB = 1, + ARBG = 2, + ABRG = 3, + ABGR = 4, + AGRB = 5, + AGBR = 6 +#pragma warning restore MSML_GeneralName // This name should be PascalCased + } + + internal static void GetOrder(ColorsOrder order, ColorBits colors, out int a, out int r, out int b, out int g) + { + var str = order.ToString().ToLowerInvariant(); + a = -1; + r = -1; + b = -1; + g = -1; + int pos = 0; + for (int i = 0; i < str.Length; i++) + { + + switch (str[i]) + { + case 'a': + if ((colors & ColorBits.Alpha) != 0) + a = pos++; + break; + case 'r': + if ((colors & ColorBits.Red) != 0) + r = pos++; + break; + case 'b': + if ((colors & ColorBits.Blue) != 0) + b = pos++; + break; + case 'g': + if ((colors & ColorBits.Green) != 0) + g = pos++; + break; + } + } + } + /// /// Describes how the transformer handles one image pixel extraction column pair. /// @@ -530,24 +575,25 @@ public sealed class ColumnInfo /// What colors to extract. public readonly ColorBits Colors; - /// Offset color pixel value by this amount. + /// In which color order extract values from pixel. + public readonly ColorsOrder Order; + + /// Offset pixel's color value by this amount. Applied to color value first. public readonly float Offset; - /// Scale color pixel value by this amount. + /// Scale pixel's color value by this amount. Applied to color value second. public readonly float Scale; - /// Whether to interleave the pixels, meaning keep them in the `ARGB ARGB` order, or leave them separated in the plannar form. + /// + /// Whether to interleave the pixels colors, meaning keep them in the order, or leave them in the plannar form: + /// all the values for one color for all pixels, then all the values for another color and so on. + /// public readonly bool Interleave; - /// Output the array as float array. If false, output as byte array. + /// Output array as float array. If false, output as byte array and ignores and . public readonly bool AsFloat; internal readonly byte Planes; - internal bool Alpha => (Colors & ColorBits.Alpha) != 0; - - internal bool Red => (Colors & ColorBits.Red) != 0; - internal bool Green => (Colors & ColorBits.Green) != 0; - internal bool Blue => (Colors & ColorBits.Blue) != 0; internal ColumnInfo(ImagePixelExtractingTransformer.Column item, ImagePixelExtractingTransformer.Options options) { @@ -556,25 +602,25 @@ internal ColumnInfo(ImagePixelExtractingTransformer.Column item, ImagePixelExtra Name = item.Name; InputColumnName = item.Source ?? item.Name; - if (item.UseAlpha ?? options.UseAlpha) { Colors |= ColorBits.Alpha; Planes++; } if (item.UseRed ?? options.UseRed) { Colors |= ColorBits.Red; Planes++; } if (item.UseGreen ?? options.UseGreen) { Colors |= ColorBits.Green; Planes++; } if (item.UseBlue ?? options.UseBlue) { Colors |= ColorBits.Blue; Planes++; } Contracts.CheckUserArg(Planes > 0, nameof(item.UseRed), "Need to use at least one color plane"); - Interleave = item.InterleaveArgb ?? options.InterleaveArgb; + Order = item.Order ?? options.Order; + Interleave = item.Interleave ?? options.Interleave; AsFloat = item.Convert ?? options.Convert; if (!AsFloat) { - Offset = ImagePixelExtractingTransformer.Defaults.Offset; - Scale = ImagePixelExtractingTransformer.Defaults.Scale; + Offset = Defaults.Offset; + Scale = Defaults.Scale; } else { - Offset = item.Offset ?? options.Offset ?? ImagePixelExtractingTransformer.Defaults.Offset; - Scale = item.Scale ?? options.Scale ?? ImagePixelExtractingTransformer.Defaults.Scale; + Offset = item.Offset ?? options.Offset ?? Defaults.Offset; + Scale = item.Scale ?? options.Scale ?? Defaults.Scale; Contracts.CheckUserArg(FloatUtils.IsFinite(Offset), nameof(item.Offset)); Contracts.CheckUserArg(FloatUtils.IsFiniteNonZero(Scale), nameof(item.Scale)); } @@ -586,39 +632,40 @@ internal ColumnInfo(ImagePixelExtractingTransformer.Column item, ImagePixelExtra /// Name of the column resulting from the transformation of . /// Name of column to transform. If set to , the value of the will be used as source. /// What colors to extract. - /// Whether to interleave the pixels, meaning keep them in the `ARGB ARGB` order, or leave them in the plannar form: of all red pixels, - /// then all green, then all blue. - /// Scale color pixel value by this amount. - /// Offset color pixel value by this amount. - /// Output array as float array. If false, output as byte array. - + /// In which order to extract colors from pixel. + /// Whether to interleave the pixels, meaning keep them in the order, or leave them in the plannar form: + /// all the values for one color for all pixels, then all the values for another color and so on. + /// Offset color pixel value by this amount. Applied to color value first. + /// Scale color pixel value by this amount. Applied to color value second. + /// Output array as float array. If false, output as byte array and ignores and . public ColumnInfo(string name, string inputColumnName = null, - ColorBits colors = ImagePixelExtractingTransformer.Defaults.Colors, - bool interleave = ImagePixelExtractingTransformer.Defaults.Interleave, - float scale = ImagePixelExtractingTransformer.Defaults.Scale, - float offset = ImagePixelExtractingTransformer.Defaults.Offset, - bool asFloat = ImagePixelExtractingTransformer.Defaults.Convert) + ColorBits colors = Defaults.Colors, + ColorsOrder order = Defaults.Order, + bool interleave = Defaults.Interleave, + float offset = Defaults.Offset, + float scale = Defaults.Scale, + bool asFloat = Defaults.Convert) { Contracts.CheckNonWhiteSpace(name, nameof(name)); Name = name; InputColumnName = inputColumnName ?? name; Colors = colors; - + Order = order; if ((Colors & ColorBits.Alpha) == ColorBits.Alpha) Planes++; if ((Colors & ColorBits.Red) == ColorBits.Red) Planes++; if ((Colors & ColorBits.Green) == ColorBits.Green) Planes++; if ((Colors & ColorBits.Blue) == ColorBits.Blue) Planes++; - Contracts.CheckParam(Planes > 0, nameof(colors), "Need to use at least one color plane"); + Contracts.CheckParam(Planes > 0, nameof(colors), "Need to use at least one color plane."); Interleave = interleave; AsFloat = asFloat; if (!AsFloat) { - Offset = ImagePixelExtractingTransformer.Defaults.Offset; - Scale = ImagePixelExtractingTransformer.Defaults.Scale; + Offset = Defaults.Offset; + Scale = Defaults.Scale; } else { @@ -640,6 +687,7 @@ internal ColumnInfo(string name, string inputColumnName, ModelLoadContext ctx) // *** Binary format *** // byte: colors + // byte: order // byte: convert // Float: offset // Float: scale @@ -647,6 +695,13 @@ internal ColumnInfo(string name, string inputColumnName, ModelLoadContext ctx) Colors = (ImagePixelExtractingEstimator.ColorBits)ctx.Reader.ReadByte(); Contracts.CheckDecode(Colors != 0); Contracts.CheckDecode((Colors & ImagePixelExtractingEstimator.ColorBits.All) == Colors); + if (ctx.Header.ModelVerWritten <= ImagePixelExtractingTransformer.BeforeOrderVersion) + Order = ColorsOrder.ARGB; + else + { + Order = (ImagePixelExtractingEstimator.ColorsOrder)ctx.Reader.ReadByte(); + Contracts.CheckDecode(Order != 0); + } // Count the planes. int planes = (int)Colors; @@ -677,6 +732,7 @@ internal void Save(ModelSaveContext ctx) // *** Binary format *** // byte: colors + // byte: order // byte: convert // Float: offset // Float: scale @@ -684,6 +740,7 @@ internal void Save(ModelSaveContext ctx) Contracts.Assert(Colors != 0); Contracts.Assert((Colors & ImagePixelExtractingEstimator.ColorBits.All) == Colors); ctx.Writer.Write((byte)Colors); + ctx.Writer.Write((byte)Order); ctx.Writer.WriteBoolByte(AsFloat); Contracts.Assert(FloatUtils.IsFinite(Offset)); ctx.Writer.Write(Offset); @@ -701,19 +758,24 @@ internal void Save(ModelSaveContext ctx) /// Name of the column resulting from the transformation of . Null means is replaced. /// Name of the input column. /// What colors to extract. - /// Whether to interleave the pixels, meaning keep them in the `RGB RGB` order, or leave them in the plannar form: of all red pixels, - /// than all green, than all blue. - /// Scale color pixel value by this amount. - /// Offset color pixel value by this amount. + /// In which order to extract colors from pixel. + /// Whether to interleave the pixels, meaning keep them in the order, or leave them in the plannar form: + /// all the values for one color for all pixels, then all the values for another color and so on. + /// Offset color pixel value by this amount. Applied to color value first. + /// Scale color pixel value by this amount. Applied to color value second. /// Output array as float array. If false, output as byte array. [BestFriend] internal ImagePixelExtractingEstimator(IHostEnvironment env, string outputColumnName, string inputColumnName = null, - ColorBits colors = ImagePixelExtractingTransformer.Defaults.Colors, - bool interleave = ImagePixelExtractingTransformer.Defaults.Interleave, float scale = ImagePixelExtractingTransformer.Defaults.Scale, - float offset = ImagePixelExtractingTransformer.Defaults.Offset, bool asFloat = ImagePixelExtractingTransformer.Defaults.Convert) - : base(Contracts.CheckRef(env, nameof(env)).Register(nameof(ImagePixelExtractingEstimator)), new ImagePixelExtractingTransformer(env, outputColumnName, inputColumnName, colors, interleave, scale, offset, asFloat)) + ColorBits colors = Defaults.Colors, + ColorsOrder order = Defaults.Order, + bool interleave = Defaults.Interleave, + float offset = Defaults.Offset, + float scale = Defaults.Scale, + bool asFloat = Defaults.Convert) + : base(Contracts.CheckRef(env, nameof(env)).Register(nameof(ImagePixelExtractingEstimator)), + new ImagePixelExtractingTransformer(env, outputColumnName, inputColumnName, colors, order, interleave, offset, scale, asFloat)) { } diff --git a/src/Microsoft.ML.ImageAnalytics/ImageResizer.cs b/src/Microsoft.ML.ImageAnalytics/ImageResizer.cs index caaf20f29c..9862678eb8 100644 --- a/src/Microsoft.ML.ImageAnalytics/ImageResizer.cs +++ b/src/Microsoft.ML.ImageAnalytics/ImageResizer.cs @@ -89,15 +89,10 @@ internal class Arguments : TransformInputBase public int ImageHeight; [Argument(ArgumentType.AtMostOnce, HelpText = "Resizing method", ShortName = "scale")] - public ImageResizingEstimator.ResizingKind Resizing = ImageResizingEstimator.ResizingKind.IsoCrop; + public ImageResizingEstimator.ResizingKind Resizing = ImageResizingEstimator.Defaults.Resizing; [Argument(ArgumentType.AtMostOnce, HelpText = "Anchor for cropping", ShortName = "anchor")] - public ImageResizingEstimator.Anchor CropAnchor = ImageResizingEstimator.Anchor.Center; - } - internal static class Defaults - { - public const ImageResizingEstimator.ResizingKind Resizing = ImageResizingEstimator.ResizingKind.IsoCrop; - public const ImageResizingEstimator.Anchor CropAnchor = ImageResizingEstimator.Anchor.Center; + public ImageResizingEstimator.Anchor CropAnchor = ImageResizingEstimator.Defaults.CropAnchor; } internal const string Summary = "Scales an image to specified dimensions using one of the three scale types: isotropic with padding, " @@ -421,6 +416,12 @@ protected override Delegate MakeGetter(DataViewRow input, int iinfo, Func public sealed class ImageResizingEstimator : TrivialEstimator { + internal static class Defaults + { + public const ResizingKind Resizing = ResizingKind.IsoCrop; + public const Anchor CropAnchor = Anchor.Center; + } + /// /// Specifies how to resize the images: by croping them or padding in the direction needed to fill up. /// @@ -497,8 +498,8 @@ public ColumnInfo(string name, int width, int height, string inputColumnName = null, - ResizingKind resizing = ImageResizingTransformer.Defaults.Resizing, - Anchor anchor = ImageResizingTransformer.Defaults.CropAnchor) + ResizingKind resizing = Defaults.Resizing, + Anchor anchor = Defaults.CropAnchor) { Contracts.CheckNonEmpty(name, nameof(name)); Contracts.CheckUserArg(width > 0, nameof(width)); @@ -531,8 +532,8 @@ internal ImageResizingEstimator(IHostEnvironment env, int imageWidth, int imageHeight, string inputColumnName = null, - ResizingKind resizing = ImageResizingTransformer.Defaults.Resizing, - Anchor cropAnchor = ImageResizingTransformer.Defaults.CropAnchor) + ResizingKind resizing = Defaults.Resizing, + Anchor cropAnchor = Defaults.CropAnchor) : this(env, new ImageResizingTransformer(env, outputColumnName, imageWidth, imageHeight, inputColumnName, resizing, cropAnchor)) { } diff --git a/src/Microsoft.ML.ImageAnalytics/VectorToImageTransform.cs b/src/Microsoft.ML.ImageAnalytics/VectorToImageTransform.cs index e377513dff..c18c3c4811 100644 --- a/src/Microsoft.ML.ImageAnalytics/VectorToImageTransform.cs +++ b/src/Microsoft.ML.ImageAnalytics/VectorToImageTransform.cs @@ -35,7 +35,7 @@ namespace Microsoft.ML.ImageAnalytics /// /// /// - /// + /// /// /// public sealed class VectorToImageConvertingTransformer : OneToOneTransformerBase @@ -54,9 +54,12 @@ internal class Column : OneToOneColumn [Argument(ArgumentType.AtMostOnce, HelpText = "Whether to use blue channel", ShortName = "blue")] public bool? ContainsBlue; + [Argument(ArgumentType.AtMostOnce, HelpText = "Order of channels")] + public ImagePixelExtractingEstimator.ColorsOrder? Order; + // REVIEW: Consider turning this into an enum that allows for pixel, line, or planar interleaving. - [Argument(ArgumentType.AtMostOnce, HelpText = "Whether to separate each channel or interleave in ARGB order", ShortName = "interleave")] - public bool? InterleaveArgb; + [Argument(ArgumentType.AtMostOnce, HelpText = "Whether to separate each channel or interleave in specified order")] + public bool? Interleave; [Argument(ArgumentType.AtMostOnce, HelpText = "Width of the image", ShortName = "width")] public int? ImageWidth; @@ -70,6 +73,18 @@ internal class Column : OneToOneColumn [Argument(ArgumentType.AtMostOnce, HelpText = "Scale factor")] public Single? Scale; + [Argument(ArgumentType.AtMostOnce, HelpText = "Default value for alpha channel. Will be used if ContainsAlpha set to false")] + public int? DefaultAlpha; + + [Argument(ArgumentType.AtMostOnce, HelpText = "Default value for red channel. Will be used if ContainsRed set to false")] + public int? DefaultRed; + + [Argument(ArgumentType.AtMostOnce, HelpText = "Default value for green channel. Will be used if ContainsGreen set to false")] + public int? DefaultGreen; + + [Argument(ArgumentType.AtMostOnce, HelpText = "Default value for blue channel. Will be used if ContainsGreen set to false")] + public int? DefaultBlue; + internal static Column Parse(string str) { Contracts.AssertNonEmpty(str); @@ -84,7 +99,8 @@ internal bool TryUnparse(StringBuilder sb) { Contracts.AssertValue(sb); if (ContainsAlpha != null || ContainsRed != null || ContainsGreen != null || ContainsBlue != null || ImageWidth != null || - ImageHeight != null || Offset != null || Scale != null || InterleaveArgb != null) + ImageHeight != null || Offset != null || Scale != null || Interleave != null || Order != null || DefaultAlpha != null || + DefaultBlue != null || DefaultGreen != null || DefaultRed != null) { return false; } @@ -92,25 +108,28 @@ internal bool TryUnparse(StringBuilder sb) } } - internal class Options: TransformInputBase + internal class Options : TransformInputBase { [Argument(ArgumentType.Multiple | ArgumentType.Required, HelpText = "New column definition(s) (optional form: name:src)", Name = "Column", ShortName = "col", SortOrder = 1)] public Column[] Columns; [Argument(ArgumentType.AtMostOnce, HelpText = "Whether to use alpha channel", ShortName = "alpha")] - public bool ContainsAlpha = (Defaults.Colors & ImagePixelExtractingEstimator.ColorBits.Alpha) > 0; + public bool ContainsAlpha = (ImagePixelExtractingEstimator.Defaults.Colors & ImagePixelExtractingEstimator.ColorBits.Alpha) > 0; [Argument(ArgumentType.AtMostOnce, HelpText = "Whether to use red channel", ShortName = "red")] - public bool ContainsRed = (Defaults.Colors & ImagePixelExtractingEstimator.ColorBits.Red) > 0; + public bool ContainsRed = (ImagePixelExtractingEstimator.Defaults.Colors & ImagePixelExtractingEstimator.ColorBits.Red) > 0; [Argument(ArgumentType.AtMostOnce, HelpText = "Whether to use green channel", ShortName = "green")] - public bool ContainsGreen = (Defaults.Colors & ImagePixelExtractingEstimator.ColorBits.Green) > 0; + public bool ContainsGreen = (ImagePixelExtractingEstimator.Defaults.Colors & ImagePixelExtractingEstimator.ColorBits.Green) > 0; [Argument(ArgumentType.AtMostOnce, HelpText = "Whether to use blue channel", ShortName = "blue")] - public bool ContainsBlue = (Defaults.Colors & ImagePixelExtractingEstimator.ColorBits.Blue) > 0; + public bool ContainsBlue = (ImagePixelExtractingEstimator.Defaults.Colors & ImagePixelExtractingEstimator.ColorBits.Blue) > 0; + + [Argument(ArgumentType.AtMostOnce, HelpText = "Order of colors.")] + public ImagePixelExtractingEstimator.ColorsOrder Order = ImagePixelExtractingEstimator.Defaults.Order; - [Argument(ArgumentType.AtMostOnce, HelpText = "Whether to separate each channel or interleave in ARGB order", ShortName = "interleave")] - public bool InterleaveArgb = Defaults.InterleaveArgb; + [Argument(ArgumentType.AtMostOnce, HelpText = "Whether to separate each channel or interleave in specified order")] + public bool Interleave = ImagePixelExtractingEstimator.Defaults.Interleave; [Argument(ArgumentType.AtMostOnce, HelpText = "Width of the image", ShortName = "width")] public int ImageWidth; @@ -119,31 +138,36 @@ internal class Options: TransformInputBase public int ImageHeight; [Argument(ArgumentType.AtMostOnce, HelpText = "Offset (pre-scale)")] - public Single Offset = Defaults.Offset; + public Single Offset = VectorToImageConvertingEstimator.Defaults.Offset; [Argument(ArgumentType.AtMostOnce, HelpText = "Scale factor")] - public Single Scale = Defaults.Scale; - } + public Single Scale = VectorToImageConvertingEstimator.Defaults.Scale; - internal static class Defaults - { - public const ImagePixelExtractingEstimator.ColorBits Colors = ImagePixelExtractingEstimator.ColorBits.Rgb; - public const bool InterleaveArgb = false; - public const Single Offset = 0; - public const Single Scale = 1; + [Argument(ArgumentType.AtMostOnce, HelpText = "Default value for alpha channel. Will be used if ContainsAlpha set to false")] + public int DefaultAlpha = VectorToImageConvertingEstimator.Defaults.DefaultAlpha; + + [Argument(ArgumentType.AtMostOnce, HelpText = "Default value for red channel. Will be used if ContainsRed set to false")] + public int DefaultRed = VectorToImageConvertingEstimator.Defaults.DefaultRed; + + [Argument(ArgumentType.AtMostOnce, HelpText = "Default value for green channel. Will be used if ContainsGreen set to false")] + public int DefaultGreen = VectorToImageConvertingEstimator.Defaults.DefaultGreen; + + [Argument(ArgumentType.AtMostOnce, HelpText = "Default value for blue channel. Will be used if ContainsBlue set to false")] + public int DefaultBlue = VectorToImageConvertingEstimator.Defaults.DefaultBlue; } internal const string Summary = "Converts vector array into image type."; internal const string UserName = "Vector To Image Transform"; internal const string LoaderSignature = "VectorToImageConverter"; + internal const uint BeforeOrderVersion = 0x00010002; private static VersionInfo GetVersionInfo() { return new VersionInfo( modelSignature: "VECTOIMG", //verWrittenCur: 0x00010001, // Initial //verWrittenCur: 0x00010002, // Swith from OpenCV to Bitmap - verWrittenCur: 0x00010003, // don't serialize sizeof(Single) - verReadableCur: 0x00010003, + verWrittenCur: 0x00010003, // order for pixel colors, default colors, no size(float) + verReadableCur: 0x00010002, verWeCanReadBack: 0x00010003, loaderSignature: LoaderSignature, loaderAssemblyName: typeof(VectorToImageConvertingTransformer).Assembly.FullName); @@ -159,15 +183,41 @@ private static VersionInfo GetVersionInfo() public IReadOnlyCollection Columns => _columns.AsReadOnly(); internal VectorToImageConvertingTransformer(IHostEnvironment env, params VectorToImageConvertingEstimator.ColumnInfo[] columns) - :base(Contracts.CheckRef(env, nameof(env)).Register(RegistrationName), GetColumnPairs(columns)) + : base(Contracts.CheckRef(env, nameof(env)).Register(RegistrationName), GetColumnPairs(columns)) { Host.AssertNonEmpty(columns); _columns = columns.ToArray(); } - internal VectorToImageConvertingTransformer(IHostEnvironment env, string outputColumnName, string inputColumnName, int imageHeight, int imageWidth, ImagePixelExtractingEstimator.ColorBits colors, bool interleave, float scale, float offset) - : this(env, new VectorToImageConvertingEstimator.ColumnInfo(outputColumnName, inputColumnName, imageHeight, imageWidth, colors, interleave, scale, offset)) + /// The host environment. + /// Name of the column resulting from the transformation of . + /// The height of the output images. + /// The width of the output images. + /// Name of column to transform. If set to , the value of the will be used as source. + /// What colors to extract. + /// In which order extracted colors presented in array. + /// Whether the pixels are interleaved, meaning whether they are in order, or separated in the planar form, where the colors are specified one by one + /// for all the pixels of the image. + /// Scale color pixel value by this amount. + /// Offset color pixel value by this amount. + /// Default value for alpha color, would be overriden if contains . + /// Default value for red color, would be overriden if contains . + /// Default value for grenn color, would be overriden if contains . + /// Default value for blue color, would be overriden if contains . + internal VectorToImageConvertingTransformer(IHostEnvironment env, string outputColumnName, + int height, int width, + string inputColumnName = null, + ImagePixelExtractingEstimator.ColorBits colors = ImagePixelExtractingEstimator.Defaults.Colors, + ImagePixelExtractingEstimator.ColorsOrder order = ImagePixelExtractingEstimator.Defaults.Order, + bool interleave = ImagePixelExtractingEstimator.Defaults.Interleave, + float scale = VectorToImageConvertingEstimator.Defaults.Scale, + float offset = VectorToImageConvertingEstimator.Defaults.Offset, + int defaultAlpha = VectorToImageConvertingEstimator.Defaults.DefaultAlpha, + int defaultRed = VectorToImageConvertingEstimator.Defaults.DefaultRed, + int defaultGreen = VectorToImageConvertingEstimator.Defaults.DefaultGreen, + int defaultBlue = VectorToImageConvertingEstimator.Defaults.DefaultBlue) + : this(env, new VectorToImageConvertingEstimator.ColumnInfo(outputColumnName, height, width, inputColumnName, colors, order, interleave, scale, offset, defaultAlpha, defaultRed, defaultGreen, defaultBlue)) { } @@ -212,12 +262,13 @@ private static VectorToImageConvertingTransformer Create(IHostEnvironment env, M var h = env.Register(RegistrationName); h.CheckValue(ctx, nameof(ctx)); ctx.CheckAtModel(GetVersionInfo()); - + if (ctx.Header.ModelVerWritten <= VectorToImageConvertingTransformer.BeforeOrderVersion) + ctx.Reader.ReadFloat(); return h.Apply("Loading Model", - ch => - { - return new VectorToImageConvertingTransformer(h, ctx); - }); + ch => + { + return new VectorToImageConvertingTransformer(h, ctx); + }); } // Factory method for SignatureLoadDataTransform. @@ -325,36 +376,34 @@ private ValueGetter GetterFromType(PrimitiveDataViewType srcType dst.SetResolution(width, height); int cpix = height * width; int position = 0; + ImagePixelExtractingEstimator.GetOrder(ex.Order, ex.Colors, out int a, out int r, out int b, out int g); for (int y = 0; y < height; ++y) for (int x = 0; x < width; x++) { - float red = 0; - float green = 0; - float blue = 0; - float alpha = 0; + float red = ex.DefaultRed; + float green = ex.DefaultGreen; + float blue = ex.DefaultBlue; + float alpha = ex.DefaultAlpha; if (ex.Interleave) { if (ex.Alpha) - alpha = Convert.ToSingle(values[position++]); + alpha = Convert.ToSingle(values[position + a]); if (ex.Red) - red = Convert.ToSingle(values[position++]); + red = Convert.ToSingle(values[position + r]); if (ex.Green) - green = Convert.ToSingle(values[position++]); + green = Convert.ToSingle(values[position + g]); if (ex.Blue) - blue = Convert.ToSingle(values[position++]); + blue = Convert.ToSingle(values[position + b]); + position += ex.Planes; } else { position = y * width + x; - if (ex.Alpha) - { alpha = Convert.ToSingle(values[position]); position += cpix; } - if (ex.Red) - { red = Convert.ToSingle(values[position]); position += cpix; } - if (ex.Green) - { green = Convert.ToSingle(values[position]); position += cpix; } - if (ex.Blue) - { blue = Convert.ToSingle(values[position]); position += cpix; } + if (ex.Alpha) alpha = Convert.ToSingle(values[position + cpix * a]); + if (ex.Red) red = Convert.ToSingle(values[position + cpix * r]); + if (ex.Green) green = Convert.ToSingle(values[position + cpix * g]); + if (ex.Blue) blue = Convert.ToSingle(values[position + cpix * b]); } Color pixel; if (!needScale) @@ -362,10 +411,10 @@ private ValueGetter GetterFromType(PrimitiveDataViewType srcType else { pixel = Color.FromArgb( - ex.Alpha ? (int)Math.Round((alpha - offset) * scale) : 0, - (int)Math.Round((red - offset) * scale), - (int)Math.Round((green - offset) * scale), - (int)Math.Round((blue - offset) * scale)); + ex.Alpha ? (int)Math.Round(alpha * scale - offset) : 0, + (int)Math.Round(red * scale - offset), + (int)Math.Round(green * scale - offset), + (int)Math.Round(blue * scale - offset)); } dst.SetPixel(x, y, pixel); } @@ -385,11 +434,20 @@ private static ImageType[] ConstructTypes(VectorToImageConvertingEstimator.Colum /// /// Calling in this estimator, produces an . /// - /// + /// /// /// public sealed class VectorToImageConvertingEstimator : TrivialEstimator { + internal static class Defaults + { + public const float Scale = 1f; + public const float Offset = 0f; + public const int DefaultAlpha = 255; + public const int DefaultRed = 0; + public const int DefaultGreen = 0; + public const int DefaultBlue = 0; + } /// /// Describes how the transformer handles one image pixel extraction column pair. /// @@ -402,13 +460,19 @@ public sealed class ColumnInfo public readonly string InputColumnName; public readonly ImagePixelExtractingEstimator.ColorBits Colors; + public readonly ImagePixelExtractingEstimator.ColorsOrder Order; + public readonly bool Interleave; public readonly byte Planes; public readonly int Width; public readonly int Height; - public readonly Single Offset; - public readonly Single Scale; - public readonly bool Interleave; + public readonly float Offset; + public readonly float Scale; + + public readonly int DefaultAlpha; + public readonly int DefaultRed; + public readonly int DefaultGreen; + public readonly int DefaultBlue; public bool Alpha => (Colors & ImagePixelExtractingEstimator.ColorBits.Alpha) != 0; public bool Red => (Colors & ImagePixelExtractingEstimator.ColorBits.Red) != 0; @@ -433,7 +497,8 @@ internal ColumnInfo(VectorToImageConvertingTransformer.Column item, VectorToImag { Colors |= ImagePixelExtractingEstimator.ColorBits.Blue; Planes++; } Contracts.CheckUserArg(Planes > 0, nameof(item.ContainsRed), "Need to use at least one color plane"); - Interleave = item.InterleaveArgb ?? args.InterleaveArgb; + Order = item.Order ?? args.Order; + Interleave = item.Interleave ?? args.Interleave; Width = item.ImageWidth ?? args.ImageWidth; Height = item.ImageHeight ?? args.ImageHeight; @@ -454,11 +519,16 @@ internal ColumnInfo(string outputColumnName, string inputColumnName, ModelLoadCo // *** Binary format *** // byte: colors + // byte: order // int: widht // int: height // Float: offset // Float: scale - // byte: separateChannels + // byte: interleave + // int: defaultAlpha + // int: defaultRed + // int: defaultGreen + // int: defaultBlue Colors = (ImagePixelExtractingEstimator.ColorBits)ctx.Reader.ReadByte(); Contracts.CheckDecode(Colors != 0); Contracts.CheckDecode((Colors & ImagePixelExtractingEstimator.ColorBits.All) == Colors); @@ -470,6 +540,14 @@ internal ColumnInfo(string outputColumnName, string inputColumnName, ModelLoadCo Planes = (byte)planes; Contracts.Assert(0 < Planes & Planes <= 4); + if (ctx.Header.ModelVerWritten <= VectorToImageConvertingTransformer.BeforeOrderVersion) + Order = ImagePixelExtractingEstimator.ColorsOrder.ARGB; + else + { + Order = (ImagePixelExtractingEstimator.ColorsOrder)ctx.Reader.ReadByte(); + Contracts.CheckDecode(Order != 0); + } + Width = ctx.Reader.ReadInt32(); Contracts.CheckDecode(Width > 0); Height = ctx.Reader.ReadInt32(); @@ -479,15 +557,54 @@ internal ColumnInfo(string outputColumnName, string inputColumnName, ModelLoadCo Scale = ctx.Reader.ReadFloat(); Contracts.CheckDecode(FloatUtils.IsFiniteNonZero(Scale)); Interleave = ctx.Reader.ReadBoolByte(); + + if (ctx.Header.ModelVerWritten <= VectorToImageConvertingTransformer.BeforeOrderVersion) + { + DefaultAlpha = 0; + DefaultRed = 0; + DefaultGreen = 0; + DefaultBlue = 0; + } + else + { + DefaultAlpha = ctx.Reader.ReadInt32(); + DefaultRed = ctx.Reader.ReadInt32(); + DefaultGreen = ctx.Reader.ReadInt32(); + DefaultBlue = ctx.Reader.ReadInt32(); + } } - public ColumnInfo(string outputColumnName, string inputColumnName, - int imageHeight, int imageWidth, ImagePixelExtractingEstimator.ColorBits colors, bool interleave, float scale, float offset) + /// Name of the column resulting from the transformation of . + /// The height of the output images. + /// The width of the output images. + /// Name of column to transform. If set to , the value of the will be used as source. + /// What colors to extract. + /// In which order extracted colors presented in array. + /// Whether the pixels are interleaved, meaning whether they are in order, or separated in the planar form, where the colors are specified one by one + /// alpha, red, green, blue for all the pixels of the image. + /// Scale color pixel value by this amount. + /// Offset color pixel value by this amount. + /// Default value for alpha color, would be overriden if contains . + /// Default value for red color, would be overriden if contains . + /// Default value for grenn color, would be overriden if contains . + /// Default value for blue color, would be overriden if contains . + public ColumnInfo(string name, + int height, int width, + string inputColumnName = null, + ImagePixelExtractingEstimator.ColorBits colors = ImagePixelExtractingEstimator.Defaults.Colors, + ImagePixelExtractingEstimator.ColorsOrder order = ImagePixelExtractingEstimator.Defaults.Order, + bool interleave = ImagePixelExtractingEstimator.Defaults.Interleave, + float scale = VectorToImageConvertingEstimator.Defaults.Scale, + float offset = VectorToImageConvertingEstimator.Defaults.Offset, + int defaultAlpha = VectorToImageConvertingEstimator.Defaults.DefaultAlpha, + int defaultRed = VectorToImageConvertingEstimator.Defaults.DefaultRed, + int defaultGreen = VectorToImageConvertingEstimator.Defaults.DefaultGreen, + int defaultBlue = VectorToImageConvertingEstimator.Defaults.DefaultBlue) { - Contracts.CheckNonWhiteSpace(outputColumnName, nameof(InputColumnName)); + Contracts.CheckNonWhiteSpace(name, nameof(name)); - Name = outputColumnName; - InputColumnName = inputColumnName ?? outputColumnName; + Name = name; + InputColumnName = inputColumnName ?? name; Colors = colors; if ((byte)(Colors & ImagePixelExtractingEstimator.ColorBits.Alpha) > 0) Planes++; @@ -499,16 +616,21 @@ public ColumnInfo(string outputColumnName, string inputColumnName, Planes++; Contracts.CheckParam(Planes > 0, nameof(colors), "Need to use at least one color plane"); + Order = order; Interleave = interleave; - Contracts.CheckParam(imageWidth > 0, nameof(imageWidth), "Image width must be greater than zero"); - Contracts.CheckParam(imageHeight > 0, nameof(imageHeight), "Image height must be greater than zero"); + Contracts.CheckParam(width > 0, nameof(width), "Image width must be greater than zero"); + Contracts.CheckParam(height > 0, nameof(height), "Image height must be greater than zero"); Contracts.CheckParam(FloatUtils.IsFinite(offset), nameof(offset)); Contracts.CheckParam(FloatUtils.IsFiniteNonZero(scale), nameof(scale)); - Width = imageWidth; - Height = imageHeight; + Width = width; + Height = height; Offset = offset; Scale = scale; + DefaultAlpha = defaultAlpha; + DefaultRed = defaultRed; + DefaultGreen = defaultGreen; + DefaultBlue = defaultBlue; } internal void Save(ModelSaveContext ctx) @@ -525,13 +647,19 @@ internal void Save(ModelSaveContext ctx) // *** Binary format *** // byte: colors + // byte: order // byte: convert // Float: offset // Float: scale - // byte: separateChannels + // byte: interleave + // int: defaultAlpha + // int: defaultRed + // int: defaultGreen + // int: defaultBlue Contracts.Assert(Colors != 0); Contracts.Assert((Colors & ImagePixelExtractingEstimator.ColorBits.All) == Colors); ctx.Writer.Write((byte)Colors); + ctx.Writer.Write((byte)Order); ctx.Writer.Write(Width); ctx.Writer.Write(Height); Contracts.Assert(FloatUtils.IsFinite(Offset)); @@ -539,6 +667,10 @@ internal void Save(ModelSaveContext ctx) Contracts.Assert(FloatUtils.IsFiniteNonZero(Scale)); ctx.Writer.Write(Scale); ctx.Writer.WriteBoolByte(Interleave); + ctx.Writer.Write(DefaultAlpha); + ctx.Writer.Write(DefaultRed); + ctx.Writer.Write(DefaultGreen); + ctx.Writer.Write(DefaultBlue); } } @@ -546,26 +678,37 @@ internal void Save(ModelSaveContext ctx) /// Convert pixels values into an image. /// /// The host environment. - /// The height of the image - /// The width of the image + /// The height of the output images. + /// The width of the output images. /// Name of the column resulting from the transformation of . Null means is replaced. /// Name of the input column. /// What colors to extract. - /// Whether to interleave the pixels, meaning keep them in the `RGB RGB` order, or leave them in the plannar form: of all red pixels, - /// than all green, than all blue. - /// Scale color pixel value by this amount. - /// Offset color pixel value by this amount. + /// In which order extracted colors presented in array. + /// Whether the pixels are interleaved, meaning whether they are in order, or separated in the planar form, where the colors are specified one by one + /// alpha, red, green, blue for all the pixels of the image. + /// The values are scaled by this value before being converted to pixels. Applied to vector value first. + /// The offset is subtracted before converting the values to pixels. Applied to vector value second. + /// Default value for alpha color, would be overriden if contains . + /// Default value for red color, would be overriden if contains . + /// Default value for grenn color, would be overriden if contains . + /// Default value for blue color, would be overriden if contains . [BestFriend] internal VectorToImageConvertingEstimator(IHostEnvironment env, - int imageHeight, - int imageWidth, + int height, + int width, string outputColumnName, string inputColumnName = null, - ImagePixelExtractingEstimator.ColorBits colors = ImagePixelExtractingEstimator.ColorBits.Rgb, - bool interleave = false, - float scale = 1, - float offset = 0) - : base(Contracts.CheckRef(env, nameof(env)).Register(nameof(VectorToImageConvertingEstimator)), new VectorToImageConvertingTransformer(env, outputColumnName, inputColumnName, imageHeight, imageWidth, colors, interleave, scale, offset)) + ImagePixelExtractingEstimator.ColorBits colors = ImagePixelExtractingEstimator.Defaults.Colors, + ImagePixelExtractingEstimator.ColorsOrder order = ImagePixelExtractingEstimator.Defaults.Order, + bool interleave = ImagePixelExtractingEstimator.Defaults.Interleave, + float scale = VectorToImageConvertingEstimator.Defaults.Scale, + float offset = VectorToImageConvertingEstimator.Defaults.Offset, + int defaultAlpha = VectorToImageConvertingEstimator.Defaults.DefaultAlpha, + int defaultRed = VectorToImageConvertingEstimator.Defaults.DefaultRed, + int defaultGreen = VectorToImageConvertingEstimator.Defaults.DefaultGreen, + int defaultBlue = VectorToImageConvertingEstimator.Defaults.DefaultBlue) + : base(Contracts.CheckRef(env, nameof(env)).Register(nameof(VectorToImageConvertingEstimator)), + new VectorToImageConvertingTransformer(env, outputColumnName, height, width, inputColumnName, colors, order, interleave, scale, offset, defaultAlpha, defaultRed, defaultGreen, defaultBlue)) { } diff --git a/src/Microsoft.ML.StaticPipe/ImageStaticPipe.cs b/src/Microsoft.ML.StaticPipe/ImageStaticPipe.cs index 962eccca11..ecedb3611c 100644 --- a/src/Microsoft.ML.StaticPipe/ImageStaticPipe.cs +++ b/src/Microsoft.ML.StaticPipe/ImageStaticPipe.cs @@ -109,20 +109,21 @@ public static Custom Resize(this Custom input, int width, int he /// /// Vectorizes the image as the numeric values of its pixels converted and possibly transformed to floating point values. /// The output vector is output in height then width major order, with the channels being the most minor (if - /// is true) or major (if is false) dimension. + /// is true) or major (if is false) dimension. /// /// The input image to extract /// Whether the alpha channel should be extracted /// Whether the red channel should be extracted /// Whether the green channel should be extracted /// Whether the blue channel should be extracted - /// Whether the pixel values should be interleaved, as opposed to being separated by channel + /// In which order extract channels. + /// Whether the pixel values should be interleaved, as opposed to being separated by channel /// Scale the normally 0 through 255 pixel values by this amount /// Add this amount to the pixel values, before scaling /// The vectorized image /// public static Vector ExtractPixels(this Custom input, bool useAlpha = false, bool useRed = true, - bool useGreen = true, bool useBlue = true, bool interleaveArgb = false, float scale = 1.0f, float offset = 0.0f) + bool useGreen = true, bool useBlue = true, ImagePixelExtractingEstimator.ColorsOrder order = ImagePixelExtractingEstimator.Defaults.Order, bool interleave = false, float scale = 1.0f, float offset = 0.0f) { var colParams = new ImagePixelExtractingTransformer.Column { @@ -130,7 +131,7 @@ public static Vector ExtractPixels(this Custom input, bool useAlp UseRed = useRed, UseGreen = useGreen, UseBlue = useBlue, - InterleaveArgb = interleaveArgb, + Interleave = interleave, Scale = scale, Offset = offset, Convert = true @@ -141,18 +142,19 @@ public static Vector ExtractPixels(this Custom input, bool useAlp /// /// Vectorizes the image as the numeric byte values of its pixels. /// The output vector is output in height then width major order, with the channels being the most minor (if - /// is true) or major (if is false) dimension. + /// is true) or major (if is false) dimension. /// /// The input image to extract /// Whether the alpha channel should be extracted /// Whether the red channel should be extracted /// Whether the green channel should be extracted /// Whether the blue channel should be extracted - /// Whether the pixel values should be interleaved, as opposed to being separated by channel + /// In which order extract channels. + /// Whether the pixel values should be interleaved, as opposed to being separated by channel /// The vectorized image /// public static Vector ExtractPixelsAsBytes(this Custom input, bool useAlpha = false, bool useRed = true, - bool useGreen = true, bool useBlue = true, bool interleaveArgb = false) + bool useGreen = true, bool useBlue = true, ImagePixelExtractingEstimator.ColorsOrder order = ImagePixelExtractingEstimator.Defaults.Order, bool interleave = false) { var colParams = new ImagePixelExtractingTransformer.Column { @@ -160,7 +162,7 @@ public static Vector ExtractPixelsAsBytes(this Custom input, bool UseRed = useRed, UseGreen = useGreen, UseBlue = useBlue, - InterleaveArgb = interleaveArgb, + Interleave = interleave, Convert = false }; return new ImagePixelExtractingStaticExtensions.OutPipelineColumn(input, colParams); diff --git a/src/Microsoft.ML.StaticPipe/ImageTransformsStatic.cs b/src/Microsoft.ML.StaticPipe/ImageTransformsStatic.cs index 9475d9e967..13c9a81dc3 100644 --- a/src/Microsoft.ML.StaticPipe/ImageTransformsStatic.cs +++ b/src/Microsoft.ML.StaticPipe/ImageTransformsStatic.cs @@ -215,8 +215,8 @@ public ImagePixelExtractingEstimator.ColumnInfo MakeColumnInfo(string outputColu /// Reconciler to an for the . /// /// Because we want to use the same reconciler for - /// - /// + /// + /// private sealed class Reconciler : EstimatorReconciler { /// diff --git a/test/BaselineOutput/Common/EntryPoints/core_manifest.json b/test/BaselineOutput/Common/EntryPoints/core_manifest.json index 0e0425a8c0..b36ebd329f 100644 --- a/test/BaselineOutput/Common/EntryPoints/core_manifest.json +++ b/test/BaselineOutput/Common/EntryPoints/core_manifest.json @@ -18936,12 +18936,28 @@ "Default": null }, { - "Name": "InterleaveArgb", + "Name": "Order", + "Type": { + "Kind": "Enum", + "Values": [ + "ARGB", + "ARBG", + "ABRG", + "ABGR", + "AGRB", + "AGBR" + ] + }, + "Desc": "Order of channels", + "Required": false, + "SortOrder": 150.0, + "IsNullable": true, + "Default": null + }, + { + "Name": "Interleave", "Type": "Bool", - "Desc": "Whether to separate each channel or interleave in ARGB order", - "Aliases": [ - "interleave" - ], + "Desc": "Whether to separate each channel or interleave in specified order", "Required": false, "SortOrder": 150.0, "IsNullable": true, @@ -19069,12 +19085,28 @@ "Default": true }, { - "Name": "InterleaveArgb", + "Name": "Order", + "Type": { + "Kind": "Enum", + "Values": [ + "ARGB", + "ARBG", + "ABRG", + "ABGR", + "AGRB", + "AGBR" + ] + }, + "Desc": "Order of colors.", + "Required": false, + "SortOrder": 150.0, + "IsNullable": false, + "Default": "ARGB" + }, + { + "Name": "Interleave", "Type": "Bool", - "Desc": "Whether to separate each channel or interleave in ARGB order", - "Aliases": [ - "interleave" - ], + "Desc": "Whether to separate each channel or interleave in specified order", "Required": false, "SortOrder": 150.0, "IsNullable": false, @@ -23026,12 +23058,28 @@ "Default": null }, { - "Name": "InterleaveArgb", + "Name": "Order", + "Type": { + "Kind": "Enum", + "Values": [ + "ARGB", + "ARBG", + "ABRG", + "ABGR", + "AGRB", + "AGBR" + ] + }, + "Desc": "Order of channels", + "Required": false, + "SortOrder": 150.0, + "IsNullable": true, + "Default": null + }, + { + "Name": "Interleave", "Type": "Bool", - "Desc": "Whether to separate each channel or interleave in ARGB order", - "Aliases": [ - "interleave" - ], + "Desc": "Whether to separate each channel or interleave in specified order", "Required": false, "SortOrder": 150.0, "IsNullable": true, @@ -23079,6 +23127,42 @@ "IsNullable": true, "Default": null }, + { + "Name": "DefaultAlpha", + "Type": "Int", + "Desc": "Default value for alpha channel. Will be used if ContainsAlpha set to false", + "Required": false, + "SortOrder": 150.0, + "IsNullable": true, + "Default": null + }, + { + "Name": "DefaultRed", + "Type": "Int", + "Desc": "Default value for red channel. Will be used if ContainsRed set to false", + "Required": false, + "SortOrder": 150.0, + "IsNullable": true, + "Default": null + }, + { + "Name": "DefaultGreen", + "Type": "Int", + "Desc": "Default value for green channel. Will be used if ContainsGreen set to false", + "Required": false, + "SortOrder": 150.0, + "IsNullable": true, + "Default": null + }, + { + "Name": "DefaultBlue", + "Type": "Int", + "Desc": "Default value for blue channel. Will be used if ContainsGreen set to false", + "Required": false, + "SortOrder": 150.0, + "IsNullable": true, + "Default": null + }, { "Name": "Name", "Type": "String", @@ -23171,12 +23255,28 @@ "Default": true }, { - "Name": "InterleaveArgb", + "Name": "Order", + "Type": { + "Kind": "Enum", + "Values": [ + "ARGB", + "ARBG", + "ABRG", + "ABGR", + "AGRB", + "AGBR" + ] + }, + "Desc": "Order of colors.", + "Required": false, + "SortOrder": 150.0, + "IsNullable": false, + "Default": "ARGB" + }, + { + "Name": "Interleave", "Type": "Bool", - "Desc": "Whether to separate each channel or interleave in ARGB order", - "Aliases": [ - "interleave" - ], + "Desc": "Whether to separate each channel or interleave in specified order", "Required": false, "SortOrder": 150.0, "IsNullable": false, @@ -23223,6 +23323,42 @@ "SortOrder": 150.0, "IsNullable": false, "Default": 1.0 + }, + { + "Name": "DefaultAlpha", + "Type": "Int", + "Desc": "Default value for alpha channel. Will be used if ContainsAlpha set to false", + "Required": false, + "SortOrder": 150.0, + "IsNullable": false, + "Default": 255 + }, + { + "Name": "DefaultRed", + "Type": "Int", + "Desc": "Default value for red channel. Will be used if ContainsRed set to false", + "Required": false, + "SortOrder": 150.0, + "IsNullable": false, + "Default": 0 + }, + { + "Name": "DefaultGreen", + "Type": "Int", + "Desc": "Default value for green channel. Will be used if ContainsGreen set to false", + "Required": false, + "SortOrder": 150.0, + "IsNullable": false, + "Default": 0 + }, + { + "Name": "DefaultBlue", + "Type": "Int", + "Desc": "Default value for blue channel. Will be used if ContainsBlue set to false", + "Required": false, + "SortOrder": 150.0, + "IsNullable": false, + "Default": 0 } ], "Outputs": [ diff --git a/test/Microsoft.ML.OnnxTransformerTest/DnnImageFeaturizerTest.cs b/test/Microsoft.ML.OnnxTransformerTest/DnnImageFeaturizerTest.cs index 2fea217bc5..8a1d052f42 100644 --- a/test/Microsoft.ML.OnnxTransformerTest/DnnImageFeaturizerTest.cs +++ b/test/Microsoft.ML.OnnxTransformerTest/DnnImageFeaturizerTest.cs @@ -105,7 +105,7 @@ public void OnnxStatic() var pipe = data.MakeNewEstimator() .Append(row => ( row.name, - data_0: row.imagePath.LoadAsImage(imageFolder).Resize(imageHeight, imageWidth).ExtractPixels(interleaveArgb: true))) + data_0: row.imagePath.LoadAsImage(imageFolder).Resize(imageHeight, imageWidth).ExtractPixels(interleave: true))) .Append(row => (row.name, output_1: row.data_0.DnnImageFeaturizer(m => m.ModelSelector.ResNet18(m.Environment, m.OutputColumn, m.InputColumn)))); TestEstimatorCore(pipe.AsDynamic, data.AsDynamic); diff --git a/test/Microsoft.ML.OnnxTransformerTest/OnnxTransformTests.cs b/test/Microsoft.ML.OnnxTransformerTest/OnnxTransformTests.cs index 15185cf34f..90de1caa42 100644 --- a/test/Microsoft.ML.OnnxTransformerTest/OnnxTransformTests.cs +++ b/test/Microsoft.ML.OnnxTransformerTest/OnnxTransformTests.cs @@ -195,7 +195,7 @@ public void OnnxStatic() var pipe = data.MakeNewEstimator() .Append(row => ( row.name, - data_0: row.imagePath.LoadAsImage(imageFolder).Resize(imageHeight, imageWidth).ExtractPixels(interleaveArgb: true))) + data_0: row.imagePath.LoadAsImage(imageFolder).Resize(imageHeight, imageWidth).ExtractPixels(interleave: true))) .Append(row => (row.name, softmaxout_1: row.data_0.ApplyOnnxModel(modelFile))); TestEstimatorCore(pipe.AsDynamic, data.AsDynamic); diff --git a/test/Microsoft.ML.Tests/ImagesTests.cs b/test/Microsoft.ML.Tests/ImagesTests.cs index 9ea864024a..cc73af5d2f 100644 --- a/test/Microsoft.ML.Tests/ImagesTests.cs +++ b/test/Microsoft.ML.Tests/ImagesTests.cs @@ -200,9 +200,9 @@ public void TestBackAndForthConversionWithAlphaInterleave() var images = new ImageLoadingTransformer(env, imageFolder, ("ImageReal", "ImagePath")).Transform(data); var cropped = new ImageResizingTransformer(env, "ImageCropped", imageWidth, imageHeight, "ImageReal").Transform(images); - var pixels = new ImagePixelExtractingTransformer(env, "ImagePixels", "ImageCropped", ImagePixelExtractingEstimator.ColorBits.All, true, 2f / 255, 127.5f).Transform(cropped); - IDataView backToBitmaps = new VectorToImageConvertingTransformer(env, "ImageRestored", "ImagePixels", - imageHeight, imageWidth, ImagePixelExtractingEstimator.ColorBits.All, true, 255f / 2, -1f).Transform(pixels); + var pixels = new ImagePixelExtractingTransformer(env, "ImagePixels", "ImageCropped", ImagePixelExtractingEstimator.ColorBits.All, interleave: true, scale: 2f/19, offset: 30).Transform(cropped); + IDataView backToBitmaps = new VectorToImageConvertingTransformer(env, "ImageRestored", imageHeight, imageWidth, "ImagePixels", + ImagePixelExtractingEstimator.ColorBits.All, interleave: true, scale: 19/2f, offset: -30).Transform(pixels); var fname = nameof(TestBackAndForthConversionWithAlphaInterleave) + "_model.zip"; @@ -259,10 +259,10 @@ public void TestBackAndForthConversionWithoutAlphaInterleave() }, new MultiFileSource(dataFile)); var images = new ImageLoadingTransformer(env, imageFolder, ("ImageReal", "ImagePath")).Transform(data); var cropped = new ImageResizingTransformer(env, "ImageCropped", imageWidth, imageHeight, "ImageReal").Transform(images); - var pixels = new ImagePixelExtractingTransformer(env, "ImagePixels", "ImageCropped", ImagePixelExtractingEstimator.ColorBits.Rgb, true, 2f / 255, 127.5f).Transform(cropped); + var pixels = new ImagePixelExtractingTransformer(env, "ImagePixels", "ImageCropped", interleave: true, scale: 2f / 19, offset: 30).Transform(cropped); - IDataView backToBitmaps = new VectorToImageConvertingTransformer(env, "ImageRestored", "ImagePixels", - imageHeight, imageWidth, ImagePixelExtractingEstimator.ColorBits.Rgb, true, 255f / 2, -1f).Transform(pixels); + IDataView backToBitmaps = new VectorToImageConvertingTransformer(env, "ImageRestored", imageHeight, imageWidth, "ImagePixels", + interleave: true, scale: 19 / 2f, offset: -30).Transform(pixels); var fname = nameof(TestBackAndForthConversionWithoutAlphaInterleave) + "_model.zip"; @@ -301,6 +301,68 @@ public void TestBackAndForthConversionWithoutAlphaInterleave() Done(); } + [Fact] + public void TestBackAndForthConversionWithDifferentOrder() + { + IHostEnvironment env = new MLContext(); + const int imageHeight = 100; + const int imageWidth = 130; + var dataFile = GetDataPath("images/images.tsv"); + var imageFolder = Path.GetDirectoryName(dataFile); + var data = TextLoader.Create(env, new TextLoader.Options() + { + Columns = new[] + { + new TextLoader.Column("ImagePath", DataKind.TX, 0), + new TextLoader.Column("Name", DataKind.TX, 1), + } + }, new MultiFileSource(dataFile)); + var images = new ImageLoadingTransformer(env, imageFolder, ("ImageReal", "ImagePath")).Transform(data); + var cropped = new ImageResizingTransformer(env, "ImageCropped", imageWidth, imageHeight, "ImageReal").Transform(images); + + var pixels = new ImagePixelExtractingTransformer(env, "ImagePixels", "ImageCropped", ImagePixelExtractingEstimator.ColorBits.All, order:ImagePixelExtractingEstimator.ColorsOrder.ABRG).Transform(cropped); + IDataView backToBitmaps = new VectorToImageConvertingTransformer(env, "ImageRestored", imageHeight, imageWidth, "ImagePixels", + ImagePixelExtractingEstimator.ColorBits.All,order: ImagePixelExtractingEstimator.ColorsOrder.ABRG).Transform(pixels); + + var fname = nameof(TestBackAndForthConversionWithDifferentOrder) + "_model.zip"; + + var fh = env.CreateOutputFile(fname); + using (var ch = env.Start("save")) + TrainUtils.SaveModel(env, ch, fh, null, new RoleMappedData(backToBitmaps)); + + backToBitmaps = ModelFileUtils.LoadPipeline(env, fh.OpenReadStream(), new MultiFileSource(dataFile)); + DeleteOutputPath(fname); + + + backToBitmaps.Schema.TryGetColumnIndex("ImageRestored", out int bitmapColumn); + backToBitmaps.Schema.TryGetColumnIndex("ImageCropped", out int cropBitmapColumn); + using (var cursor = backToBitmaps.GetRowCursorForAllColumns()) + { + var bitmapGetter = cursor.GetGetter(bitmapColumn); + Bitmap restoredBitmap = default; + + var bitmapCropGetter = cursor.GetGetter(cropBitmapColumn); + Bitmap croppedBitmap = default; + while (cursor.MoveNext()) + { + bitmapGetter(ref restoredBitmap); + Assert.NotNull(restoredBitmap); + bitmapCropGetter(ref croppedBitmap); + Assert.NotNull(croppedBitmap); + for (int x = 0; x < imageWidth; x++) + for (int y = 0; y < imageHeight; y++) + { + var c = croppedBitmap.GetPixel(x, y); + var r = restoredBitmap.GetPixel(x, y); + if (c != r) + Assert.False(true); + Assert.True(c == r); + } + } + } + Done(); + } + [Fact] public void TestBackAndForthConversionWithAlphaNoInterleave() { @@ -319,10 +381,10 @@ public void TestBackAndForthConversionWithAlphaNoInterleave() }, new MultiFileSource(dataFile)); var images = new ImageLoadingTransformer(env, imageFolder, ("ImageReal", "ImagePath")).Transform(data); var cropped = new ImageResizingTransformer(env, "ImageCropped", imageWidth, imageHeight, "ImageReal").Transform(images); - var pixels = new ImagePixelExtractingTransformer(env, "ImagePixels", "ImageCropped", ImagePixelExtractingEstimator.ColorBits.All, false, 2f / 255, 127.5f).Transform(cropped); + var pixels = new ImagePixelExtractingTransformer(env, "ImagePixels", "ImageCropped", ImagePixelExtractingEstimator.ColorBits.All, scale: 2f / 19, offset: 30).Transform(cropped); - IDataView backToBitmaps = new VectorToImageConvertingTransformer(env, "ImageRestored", "ImagePixels", - imageHeight, imageWidth, ImagePixelExtractingEstimator.ColorBits.All, false, 255f / 2, -1f).Transform(pixels); + IDataView backToBitmaps = new VectorToImageConvertingTransformer(env, "ImageRestored", imageHeight, imageWidth, "ImagePixels", + ImagePixelExtractingEstimator.ColorBits.All, scale: 19 / 2f, offset: -30).Transform(pixels); var fname = nameof(TestBackAndForthConversionWithAlphaNoInterleave) + "_model.zip"; @@ -379,10 +441,10 @@ public void TestBackAndForthConversionWithoutAlphaNoInterleave() }, new MultiFileSource(dataFile)); var images = new ImageLoadingTransformer(env, imageFolder, ("ImageReal", "ImagePath")).Transform(data); var cropped = new ImageResizingTransformer(env, "ImageCropped", imageWidth, imageHeight, "ImageReal").Transform(images); - var pixels = new ImagePixelExtractingTransformer(env, "ImagePixels", "ImageCropped", ImagePixelExtractingEstimator.ColorBits.Rgb, false, 2f / 255, 127.5f).Transform(cropped); + var pixels = new ImagePixelExtractingTransformer(env, "ImagePixels", "ImageCropped", scale: 2f / 19, offset: 30).Transform(cropped); - IDataView backToBitmaps = new VectorToImageConvertingTransformer(env, "ImageRestored", "ImagePixels", - imageHeight, imageWidth, ImagePixelExtractingEstimator.ColorBits.Rgb, false, 255f / 2, -1f).Transform(pixels); + IDataView backToBitmaps = new VectorToImageConvertingTransformer(env, "ImageRestored", imageHeight, imageWidth, "ImagePixels", + scale: 19 / 2f, offset: -30).Transform(pixels); var fname = nameof(TestBackAndForthConversionWithoutAlphaNoInterleave) + "_model.zip"; @@ -440,10 +502,10 @@ public void TestBackAndForthConversionWithAlphaInterleaveNoOffset() var images = new ImageLoadingTransformer(env, imageFolder, ("ImageReal", "ImagePath")).Transform(data); var cropped = new ImageResizingTransformer(env, "ImageCropped", imageWidth, imageHeight, "ImageReal").Transform(images); - var pixels = new ImagePixelExtractingTransformer(env, "ImagePixels", "ImageCropped", ImagePixelExtractingEstimator.ColorBits.All, true).Transform(cropped); + var pixels = new ImagePixelExtractingTransformer(env, "ImagePixels", "ImageCropped", ImagePixelExtractingEstimator.ColorBits.All, interleave: true).Transform(cropped); - IDataView backToBitmaps = new VectorToImageConvertingTransformer(env, "ImageRestored", "ImagePixels", - imageHeight, imageWidth, ImagePixelExtractingEstimator.ColorBits.All, true, 1, 0).Transform(pixels); + IDataView backToBitmaps = new VectorToImageConvertingTransformer(env, "ImageRestored", imageHeight, imageWidth, "ImagePixels", + ImagePixelExtractingEstimator.ColorBits.All, interleave: true).Transform(pixels); var fname = nameof(TestBackAndForthConversionWithAlphaInterleaveNoOffset) + "_model.zip"; @@ -501,10 +563,9 @@ public void TestBackAndForthConversionWithoutAlphaInterleaveNoOffset() var images = new ImageLoadingTransformer(env, imageFolder, ("ImageReal", "ImagePath")).Transform(data); var cropped = new ImageResizingTransformer(env, "ImageCropped", imageWidth, imageHeight, "ImageReal").Transform(images); - var pixels = new ImagePixelExtractingTransformer(env, "ImagePixels", "ImageCropped", ImagePixelExtractingEstimator.ColorBits.Rgb, true).Transform(cropped); + var pixels = new ImagePixelExtractingTransformer(env, "ImagePixels", "ImageCropped", interleave: true).Transform(cropped); - IDataView backToBitmaps = new VectorToImageConvertingTransformer(env, "ImageRestored", "ImagePixels", - imageHeight, imageWidth, ImagePixelExtractingEstimator.ColorBits.Rgb, true, 1, 0).Transform(pixels); + IDataView backToBitmaps = new VectorToImageConvertingTransformer(env, "ImageRestored", imageHeight, imageWidth, "ImagePixels", interleave: true).Transform(pixels); var fname = nameof(TestBackAndForthConversionWithoutAlphaInterleaveNoOffset) + "_model.zip"; @@ -564,8 +625,8 @@ public void TestBackAndForthConversionWithAlphaNoInterleaveNoOffset() var pixels = new ImagePixelExtractingTransformer(env, "ImagePixels", "ImageCropped", ImagePixelExtractingEstimator.ColorBits.All).Transform(cropped); - IDataView backToBitmaps = new VectorToImageConvertingTransformer(env, "ImageRestored", "ImagePixels", - imageHeight, imageWidth, ImagePixelExtractingEstimator.ColorBits.All, false, 1, 0).Transform(pixels); + IDataView backToBitmaps = new VectorToImageConvertingTransformer(env, "ImageRestored", imageHeight, imageWidth, "ImagePixels", + ImagePixelExtractingEstimator.ColorBits.All).Transform(pixels); var fname = nameof(TestBackAndForthConversionWithAlphaNoInterleaveNoOffset) + "_model.zip"; @@ -624,8 +685,7 @@ public void TestBackAndForthConversionWithoutAlphaNoInterleaveNoOffset() var cropped = new ImageResizingTransformer(env, "ImageCropped", imageWidth, imageHeight, "ImageReal").Transform(images); var pixels = new ImagePixelExtractingTransformer(env, "ImagePixels", "ImageCropped").Transform(cropped); - IDataView backToBitmaps = new VectorToImageConvertingTransformer(env, "ImageRestored", "ImagePixels", - imageHeight, imageWidth, ImagePixelExtractingEstimator.ColorBits.Rgb, false, 1, 0).Transform(pixels); + IDataView backToBitmaps = new VectorToImageConvertingTransformer(env, "ImageRestored", imageHeight, imageWidth, "ImagePixels").Transform(pixels); var fname = nameof(TestBackAndForthConversionWithoutAlphaNoInterleaveNoOffset) + "_model.zip"; @@ -686,7 +746,7 @@ public void ImageResizerTransformResizingModeFill() var rowView = pipe.Preview(data).RowView; Assert.Single(rowView); - using (var bitmap = (Bitmap) rowView.First().Values.Last().Value) + using (var bitmap = (Bitmap)rowView.First().Values.Last().Value) { // these points must be white var topLeft = bitmap.GetPixel(0, 0); diff --git a/test/Microsoft.ML.Tests/TensorFlowEstimatorTests.cs b/test/Microsoft.ML.Tests/TensorFlowEstimatorTests.cs index a2e385e3d9..50b9f997d0 100644 --- a/test/Microsoft.ML.Tests/TensorFlowEstimatorTests.cs +++ b/test/Microsoft.ML.Tests/TensorFlowEstimatorTests.cs @@ -159,7 +159,7 @@ public void TestTensorFlowStatic() var pipe = data.MakeNewEstimator() .Append(row => ( row.name, - Input: row.imagePath.LoadAsImage(imageFolder).Resize(imageHeight, imageWidth).ExtractPixels(interleaveArgb: true))) + Input: row.imagePath.LoadAsImage(imageFolder).Resize(imageHeight, imageWidth).ExtractPixels(interleave: true))) .Append(row => (row.name, Output: row.Input.ApplyTensorFlowGraph(modelLocation))); TestEstimatorCore(pipe.AsDynamic, data.AsDynamic); @@ -206,7 +206,7 @@ public void TestTensorFlowStaticWithSchema() var pipe = data.MakeNewEstimator() .Append(row => ( row.name, - Input: row.imagePath.LoadAsImage(imageFolder).Resize(imageHeight, imageWidth).ExtractPixels(interleaveArgb: true))) + Input: row.imagePath.LoadAsImage(imageFolder).Resize(imageHeight, imageWidth).ExtractPixels(interleave: true))) .Append(row => (row.name, Output: row.Input.ApplyTensorFlowGraph(tensorFlowModel))); TestEstimatorCore(pipe.AsDynamic, data.AsDynamic); From 7cc208c36edec554b6353a3a268cfb5e49274d17 Mon Sep 17 00:00:00 2001 From: Abhishek Goswami Date: Mon, 25 Feb 2019 18:37:45 +0000 Subject: [PATCH 13/24] Fixing parameters in ML.NET Public API (#2665) * local tests run fine * made fixes for (feature, label) as well * update cookbook md file --- docs/code/MlNetCookBook.md | 4 +- .../Dynamic/Calibrator.cs | 4 +- .../Dynamic/FastTreeRegression.cs | 2 +- .../Dynamic/FieldAwareFactorizationMachine.cs | 2 +- .../Dynamic/GeneralizedAdditiveModels.cs | 2 +- .../PfiBinaryClassificationExample.cs | 2 +- .../SDCALogisticRegression.cs | 2 +- .../SDCASupportVectorMachine.cs | 2 +- .../LightGBMMulticlassClassification.cs | 2 +- .../Dynamic/Trainers/PriorTrainerSample.cs | 2 +- .../Trainers/Regression/LightGBMRegression.cs | 2 +- .../Dynamic/Transforms/CustomMappingSample.cs | 2 +- .../TreeTrainersCatalog.cs | 116 ++++++------ .../HalLearnersCatalog.cs | 6 +- .../KMeansCatalog.cs | 12 +- src/Microsoft.ML.LightGBM/LightGbmCatalog.cs | 60 +++--- src/Microsoft.ML.PCA/PCACatalog.cs | 16 +- .../FactorizationMachineCatalog.cs | 14 +- .../StandardLearnersCatalog.cs | 172 +++++++++--------- test/Microsoft.ML.Tests/OnnxConversionTest.cs | 6 +- .../CookbookSamplesDynamicApi.cs | 4 +- .../TrainerEstimators/SdcaTests.cs | 4 +- .../TrainerEstimators/TreeEstimators.cs | 2 +- .../Transformers/PcaTests.cs | 2 +- 24 files changed, 221 insertions(+), 221 deletions(-) diff --git a/docs/code/MlNetCookBook.md b/docs/code/MlNetCookBook.md index edfb3236e5..7bdf991a6d 100644 --- a/docs/code/MlNetCookBook.md +++ b/docs/code/MlNetCookBook.md @@ -959,7 +959,7 @@ public static ITransformer TrainModel(MLContext mlContext, IDataView trainData) // Construct the learning pipeline. var estimator = mlContext.Transforms.CustomMapping(mapping, null) .AppendCacheCheckpoint(mlContext) - .Append(mlContext.BinaryClassification.Trainers.FastTree(label: "Label")); + .Append(mlContext.BinaryClassification.Trainers.FastTree(labelColumnName: "Label")); return estimator.Fit(trainData); } @@ -998,7 +998,7 @@ public class CustomMappings : CustomMappingFactory // Construct the learning pipeline. Note that we are now providing a contract name for the custom mapping: // otherwise we will not be able to save the model. var estimator = mlContext.Transforms.CustomMapping(CustomMappings.IncomeMapping, nameof(CustomMappings.IncomeMapping)) - .Append(mlContext.BinaryClassification.Trainers.FastTree(label: "Label")); + .Append(mlContext.BinaryClassification.Trainers.FastTree(labelColumnName: "Label")); // If memory is enough, we can cache the data in-memory to avoid reading them from file // when it will be accessed multiple times. diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Calibrator.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Calibrator.cs index 77812ed9c2..dc52d0eed4 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Calibrator.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Calibrator.cs @@ -50,8 +50,8 @@ public static void Example() // the "Features" column produced by FeaturizeText as the features column. var pipeline = mlContext.Transforms.Text.FeaturizeText("SentimentText", "Features") .Append(mlContext.BinaryClassification.Trainers.StochasticDualCoordinateAscentNonCalibrated( - labelColumn: "Sentiment", - featureColumn: "Features", + labelColumnName: "Sentiment", + featureColumnName: "Features", l2Const: 0.001f, loss: new HingeLoss())); // By specifying loss: new HingeLoss(), StochasticDualCoordinateAscent will train a support vector machine (SVM). diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/FastTreeRegression.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/FastTreeRegression.cs index b2b8b3b0be..376378e355 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/FastTreeRegression.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/FastTreeRegression.cs @@ -29,7 +29,7 @@ public static void Example() // We will train a FastTreeRegression model with 1 tree on these two columns to predict Age. string outputColumnName = "Features"; var pipeline = ml.Transforms.Concatenate(outputColumnName, new[] { "Parity", "Induced" }) - .Append(ml.Regression.Trainers.FastTree(labelColumn: "Age", featureColumn: outputColumnName, numTrees: 1, numLeaves: 2, minDatapointsInLeaves: 1)); + .Append(ml.Regression.Trainers.FastTree(labelColumnName: "Age", featureColumnName: outputColumnName, numTrees: 1, numLeaves: 2, minDatapointsInLeaves: 1)); var model = pipeline.Fit(trainData); diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/FieldAwareFactorizationMachine.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/FieldAwareFactorizationMachine.cs index 0f8f3fec83..e9c54e2572 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/FieldAwareFactorizationMachine.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/FieldAwareFactorizationMachine.cs @@ -46,7 +46,7 @@ public static void Example() // the "Features" column produced by FeaturizeText as the features column. var pipeline = mlContext.Transforms.Text.FeaturizeText("SentimentText", "Features") .AppendCacheCheckpoint(mlContext) // Add a data-cache step within a pipeline. - .Append(mlContext.BinaryClassification.Trainers.FieldAwareFactorizationMachine(labelColumn: "Sentiment", featureColumns: new[] { "Features" })); + .Append(mlContext.BinaryClassification.Trainers.FieldAwareFactorizationMachine(labelColumnName: "Sentiment", featureColumnNames: new[] { "Features" })); // Fit the model. var model = pipeline.Fit(data); diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/GeneralizedAdditiveModels.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/GeneralizedAdditiveModels.cs index dd85a34d12..e3edb0813c 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/GeneralizedAdditiveModels.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/GeneralizedAdditiveModels.cs @@ -28,7 +28,7 @@ public static void Example() .ToArray(); var pipeline = mlContext.Transforms.Concatenate("Features", featureNames) .Append(mlContext.Regression.Trainers.GeneralizedAdditiveModels( - labelColumn: labelName, featureColumn: "Features", maxBins: 16)); + labelColumnName: labelName, featureColumnName: "Features", maxBins: 16)); var fitPipeline = pipeline.Fit(data); // Extract the model from the pipeline diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/PermutationFeatureImportance/PfiBinaryClassificationExample.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/PermutationFeatureImportance/PfiBinaryClassificationExample.cs index a8ebe46369..9d9b955ff6 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/PermutationFeatureImportance/PfiBinaryClassificationExample.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/PermutationFeatureImportance/PfiBinaryClassificationExample.cs @@ -23,7 +23,7 @@ public static void Example() var pipeline = mlContext.Transforms.Concatenate("Features", featureNames) .Append(mlContext.Transforms.Normalize("Features")) .Append(mlContext.BinaryClassification.Trainers.LogisticRegression( - labelColumn: labelName, featureColumn: "Features")); + labelColumnName: labelName, featureColumnName: "Features")); var model = pipeline.Fit(data); // Extract the model from the pipeline diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/SDCALogisticRegression.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/SDCALogisticRegression.cs index 3ab3257638..979976cc01 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/SDCALogisticRegression.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/SDCALogisticRegression.cs @@ -49,7 +49,7 @@ public static void Example() // the "Features" column produced by FeaturizeText as the features column. var pipeline = mlContext.Transforms.Text.FeaturizeText("SentimentText", "Features") .AppendCacheCheckpoint(mlContext) // Add a data-cache step within a pipeline. - .Append(mlContext.BinaryClassification.Trainers.StochasticDualCoordinateAscent(labelColumn: "Sentiment", featureColumn: "Features", l2Const: 0.001f)); + .Append(mlContext.BinaryClassification.Trainers.StochasticDualCoordinateAscent(labelColumnName: "Sentiment", featureColumnName: "Features", l2Const: 0.001f)); // Step 3: Run Cross-Validation on this pipeline. var cvResults = mlContext.BinaryClassification.CrossValidate(data, pipeline, labelColumn: "Sentiment"); diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/SDCASupportVectorMachine.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/SDCASupportVectorMachine.cs index d37c1cec1a..eede7b03cb 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/SDCASupportVectorMachine.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/SDCASupportVectorMachine.cs @@ -41,7 +41,7 @@ public static void Example() // Step 2: Create a binary classifier. This trainer may produce a logistic regression model. // We set the "Label" column as the label of the dataset, and the "Features" column as the features column. var pipeline = mlContext.BinaryClassification.Trainers.StochasticDualCoordinateAscentNonCalibrated( - labelColumn: "Label", featureColumn: "Features", loss: new HingeLoss(), l2Const: 0.001f); + labelColumnName: "Label", featureColumnName: "Features", loss: new HingeLoss(), l2Const: 0.001f); // Step 3: Train the pipeline created. var model = pipeline.Fit(data); diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/MulticlassClassification/LightGBMMulticlassClassification.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/MulticlassClassification/LightGBMMulticlassClassification.cs index 8731c6bc50..5c6ee5ad5f 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/MulticlassClassification/LightGBMMulticlassClassification.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/MulticlassClassification/LightGBMMulticlassClassification.cs @@ -31,7 +31,7 @@ public static void Example() // - Convert the string labels into key types. // - Apply LightGbm multiclass trainer. var pipeline = mlContext.Transforms.Conversion.MapValueToKey("LabelIndex", "Label") - .Append(mlContext.MulticlassClassification.Trainers.LightGbm(labelColumn: "LabelIndex")) + .Append(mlContext.MulticlassClassification.Trainers.LightGbm(labelColumnName: "LabelIndex")) .Append(mlContext.Transforms.Conversion.MapValueToKey("PredictedLabelIndex", "PredictedLabel")) .Append(mlContext.Transforms.CopyColumns("Scores", "Score")); diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/PriorTrainerSample.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/PriorTrainerSample.cs index f40ab22969..55aa9793c5 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/PriorTrainerSample.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/PriorTrainerSample.cs @@ -44,7 +44,7 @@ public static void Example() // the "Features" column produced by FeaturizeText as the features column. var pipeline = mlContext.Transforms.Text.FeaturizeText("Features", "SentimentText") .AppendCacheCheckpoint(mlContext) // Add a data-cache step within a pipeline. - .Append(mlContext.BinaryClassification.Trainers.Prior(labelColumn: "Sentiment")); + .Append(mlContext.BinaryClassification.Trainers.Prior(labelColumnName: "Sentiment")); // Step 3: Train the pipeline var trainedPipeline = pipeline.Fit(trainTestData.TrainSet); diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Regression/LightGBMRegression.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Regression/LightGBMRegression.cs index c4b6f9f68c..d67da241c9 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Regression/LightGBMRegression.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Regression/LightGBMRegression.cs @@ -34,7 +34,7 @@ public static void Example() .ToArray(); var pipeline = mlContext.Transforms.Concatenate("Features", featureNames) .Append(mlContext.Regression.Trainers.LightGbm( - labelColumn: labelName, + labelColumnName: labelName, numLeaves: 4, minDataPerLeaf: 6, learningRate: 0.001)); diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Transforms/CustomMappingSample.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Transforms/CustomMappingSample.cs index ce9e7d8059..f7072093e9 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Transforms/CustomMappingSample.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Transforms/CustomMappingSample.cs @@ -47,7 +47,7 @@ public static void Example() // It is useful to add a caching checkpoint before a trainer that does several passes over the data. .AppendCacheCheckpoint(mlContext) // We use binary FastTree to predict the label column that was generated by the custom mapping at the first step of the pipeline. - .Append(mlContext.BinaryClassification.Trainers.FastTree(labelColumn: "IsUnderThirty")); + .Append(mlContext.BinaryClassification.Trainers.FastTree(labelColumnName: "IsUnderThirty")); // We can train the pipeline and use it to transform data. transformedData = pipeline.Fit(trainData).Transform(trainData); diff --git a/src/Microsoft.ML.FastTree/TreeTrainersCatalog.cs b/src/Microsoft.ML.FastTree/TreeTrainersCatalog.cs index e4b116aedb..7d33a01796 100644 --- a/src/Microsoft.ML.FastTree/TreeTrainersCatalog.cs +++ b/src/Microsoft.ML.FastTree/TreeTrainersCatalog.cs @@ -17,17 +17,17 @@ public static class TreeExtensions /// Predict a target using a decision tree regression model trained with the . /// /// The . - /// The label column. - /// The feature column. - /// The optional weights column. + /// The name of the label column. + /// The name of the feature column. + /// The name of the example weight column (optional). /// Total number of decision trees to create in the ensemble. /// The maximum number of leaves per decision tree. /// The minimal number of datapoints allowed in a leaf of a regression tree, out of the subsampled data. /// The learning rate. public static FastTreeRegressionTrainer FastTree(this RegressionCatalog.RegressionTrainers catalog, - string labelColumn = DefaultColumnNames.Label, - string featureColumn = DefaultColumnNames.Features, - string weights = null, + string labelColumnName = DefaultColumnNames.Label, + string featureColumnName = DefaultColumnNames.Features, + string exampleWeightColumnName = null, int numLeaves = Defaults.NumLeaves, int numTrees = Defaults.NumTrees, int minDatapointsInLeaves = Defaults.MinDocumentsInLeaves, @@ -35,7 +35,7 @@ public static FastTreeRegressionTrainer FastTree(this RegressionCatalog.Regressi { Contracts.CheckValue(catalog, nameof(catalog)); var env = CatalogUtils.GetEnvironment(catalog); - return new FastTreeRegressionTrainer(env, labelColumn, featureColumn, weights, numLeaves, numTrees, minDatapointsInLeaves, learningRate); + return new FastTreeRegressionTrainer(env, labelColumnName, featureColumnName, exampleWeightColumnName, numLeaves, numTrees, minDatapointsInLeaves, learningRate); } /// @@ -57,17 +57,17 @@ public static FastTreeRegressionTrainer FastTree(this RegressionCatalog.Regressi /// Predict a target using a decision tree binary classification model trained with the . /// /// The . - /// The labelColumn column. - /// The featureColumn column. - /// The optional weights column. + /// The name of the label column. + /// The name of the feature column. + /// The name of the example weight column (optional). /// Total number of decision trees to create in the ensemble. /// The maximum number of leaves per decision tree. /// The minimal number of datapoints allowed in a leaf of the tree, out of the subsampled data. /// The learning rate. public static FastTreeBinaryClassificationTrainer FastTree(this BinaryClassificationCatalog.BinaryClassificationTrainers catalog, - string labelColumn = DefaultColumnNames.Label, - string featureColumn = DefaultColumnNames.Features, - string weights = null, + string labelColumnName = DefaultColumnNames.Label, + string featureColumnName = DefaultColumnNames.Features, + string exampleWeightColumnName = null, int numLeaves = Defaults.NumLeaves, int numTrees = Defaults.NumTrees, int minDatapointsInLeaves = Defaults.MinDocumentsInLeaves, @@ -75,7 +75,7 @@ public static FastTreeBinaryClassificationTrainer FastTree(this BinaryClassifica { Contracts.CheckValue(catalog, nameof(catalog)); var env = CatalogUtils.GetEnvironment(catalog); - return new FastTreeBinaryClassificationTrainer(env, labelColumn, featureColumn, weights, numLeaves, numTrees, minDatapointsInLeaves, learningRate); + return new FastTreeBinaryClassificationTrainer(env, labelColumnName, featureColumnName, exampleWeightColumnName, numLeaves, numTrees, minDatapointsInLeaves, learningRate); } /// @@ -97,19 +97,19 @@ public static FastTreeBinaryClassificationTrainer FastTree(this BinaryClassifica /// Ranks a series of inputs based on their relevance, training a decision tree ranking model through the . /// /// The . - /// The labelColumn column. - /// The featureColumn column. - /// The groupId column. - /// The optional weights column. + /// The name of the label column. + /// The name of the feature column. + /// The name of the group column. + /// The name of the example weight column (optional). /// Total number of decision trees to create in the ensemble. /// The maximum number of leaves per decision tree. /// The minimal number of datapoints allowed in a leaf of the tree, out of the subsampled data. /// The learning rate. public static FastTreeRankingTrainer FastTree(this RankingCatalog.RankingTrainers catalog, - string labelColumn = DefaultColumnNames.Label, - string featureColumn = DefaultColumnNames.Features, - string groupId = DefaultColumnNames.GroupId, - string weights = null, + string labelColumnName = DefaultColumnNames.Label, + string featureColumnName = DefaultColumnNames.Features, + string rowGroupColumnName = DefaultColumnNames.GroupId, + string exampleWeightColumnName = null, int numLeaves = Defaults.NumLeaves, int numTrees = Defaults.NumTrees, int minDatapointsInLeaves = Defaults.MinDocumentsInLeaves, @@ -117,7 +117,7 @@ public static FastTreeRankingTrainer FastTree(this RankingCatalog.RankingTrainer { Contracts.CheckValue(catalog, nameof(catalog)); var env = CatalogUtils.GetEnvironment(catalog); - return new FastTreeRankingTrainer(env, labelColumn, featureColumn, groupId, weights, numLeaves, numTrees, minDatapointsInLeaves, learningRate); + return new FastTreeRankingTrainer(env, labelColumnName, featureColumnName, rowGroupColumnName, exampleWeightColumnName, numLeaves, numTrees, minDatapointsInLeaves, learningRate); } /// @@ -139,23 +139,23 @@ public static FastTreeRankingTrainer FastTree(this RankingCatalog.RankingTrainer /// Predict a target using generalized additive models trained with the . /// /// The . - /// The labelColumn column. - /// The featureColumn column. - /// The optional weights column. + /// The name of the label column. + /// The name of the feature column. + /// The name of the example weight column (optional). /// The number of iterations to use in learning the features. /// The learning rate. GAMs work best with a small learning rate. /// The maximum number of bins to use to approximate features. public static BinaryClassificationGamTrainer GeneralizedAdditiveModels(this BinaryClassificationCatalog.BinaryClassificationTrainers catalog, - string labelColumn = DefaultColumnNames.Label, - string featureColumn = DefaultColumnNames.Features, - string weights = null, + string labelColumnName = DefaultColumnNames.Label, + string featureColumnName = DefaultColumnNames.Features, + string exampleWeightColumnName = null, int numIterations = GamDefaults.NumIterations, double learningRate = GamDefaults.LearningRates, int maxBins = GamDefaults.MaxBins) { Contracts.CheckValue(catalog, nameof(catalog)); var env = CatalogUtils.GetEnvironment(catalog); - return new BinaryClassificationGamTrainer(env, labelColumn, featureColumn, weights, numIterations, learningRate, maxBins); + return new BinaryClassificationGamTrainer(env, labelColumnName, featureColumnName, exampleWeightColumnName, numIterations, learningRate, maxBins); } /// @@ -175,23 +175,23 @@ public static BinaryClassificationGamTrainer GeneralizedAdditiveModels(this Bina /// Predict a target using generalized additive models trained with the . /// /// The . - /// The labelColumn column. - /// The featureColumn column. - /// The optional weights column. + /// The name of the label column. + /// The name of the feature column. + /// The name of the example weight column (optional). /// The number of iterations to use in learning the features. /// The learning rate. GAMs work best with a small learning rate. /// The maximum number of bins to use to approximate features. public static RegressionGamTrainer GeneralizedAdditiveModels(this RegressionCatalog.RegressionTrainers catalog, - string labelColumn = DefaultColumnNames.Label, - string featureColumn = DefaultColumnNames.Features, - string weights = null, + string labelColumnName = DefaultColumnNames.Label, + string featureColumnName = DefaultColumnNames.Features, + string exampleWeightColumnName = null, int numIterations = GamDefaults.NumIterations, double learningRate = GamDefaults.LearningRates, int maxBins = GamDefaults.MaxBins) { Contracts.CheckValue(catalog, nameof(catalog)); var env = CatalogUtils.GetEnvironment(catalog); - return new RegressionGamTrainer(env, labelColumn, featureColumn, weights, numIterations, learningRate, maxBins); + return new RegressionGamTrainer(env, labelColumnName, featureColumnName, exampleWeightColumnName, numIterations, learningRate, maxBins); } /// @@ -211,17 +211,17 @@ public static RegressionGamTrainer GeneralizedAdditiveModels(this RegressionCata /// Predict a target using a decision tree regression model trained with the . /// /// The . - /// The labelColumn column. - /// The featureColumn column. - /// The optional weights column. + /// The name of the label column. + /// The name of the feature column. + /// The name of the example weight column (optional). /// Total number of decision trees to create in the ensemble. /// The maximum number of leaves per decision tree. /// The minimal number of datapoints allowed in a leaf of the tree, out of the subsampled data. /// The learning rate. public static FastTreeTweedieTrainer FastTreeTweedie(this RegressionCatalog.RegressionTrainers catalog, - string labelColumn = DefaultColumnNames.Label, - string featureColumn = DefaultColumnNames.Features, - string weights = null, + string labelColumnName = DefaultColumnNames.Label, + string featureColumnName = DefaultColumnNames.Features, + string exampleWeightColumnName = null, int numLeaves = Defaults.NumLeaves, int numTrees = Defaults.NumTrees, int minDatapointsInLeaves = Defaults.MinDocumentsInLeaves, @@ -229,7 +229,7 @@ public static FastTreeTweedieTrainer FastTreeTweedie(this RegressionCatalog.Regr { Contracts.CheckValue(catalog, nameof(catalog)); var env = CatalogUtils.GetEnvironment(catalog); - return new FastTreeTweedieTrainer(env, labelColumn, featureColumn, weights, numLeaves, numTrees, minDatapointsInLeaves, learningRate); + return new FastTreeTweedieTrainer(env, labelColumnName, featureColumnName, exampleWeightColumnName, numLeaves, numTrees, minDatapointsInLeaves, learningRate); } /// @@ -251,23 +251,23 @@ public static FastTreeTweedieTrainer FastTreeTweedie(this RegressionCatalog.Regr /// Predict a target using a decision tree regression model trained with the . /// /// The . - /// The labelColumn column. - /// The featureColumn column. - /// The optional weights column. + /// The name of the label column. + /// The name of the feature column. + /// The name of the example weight column (optional). /// Total number of decision trees to create in the ensemble. /// The maximum number of leaves per decision tree. /// The minimal number of datapoints allowed in a leaf of the tree, out of the subsampled data. public static FastForestRegression FastForest(this RegressionCatalog.RegressionTrainers catalog, - string labelColumn = DefaultColumnNames.Label, - string featureColumn = DefaultColumnNames.Features, - string weights = null, + string labelColumnName = DefaultColumnNames.Label, + string featureColumnName = DefaultColumnNames.Features, + string exampleWeightColumnName = null, int numLeaves = Defaults.NumLeaves, int numTrees = Defaults.NumTrees, int minDatapointsInLeaves = Defaults.MinDocumentsInLeaves) { Contracts.CheckValue(catalog, nameof(catalog)); var env = CatalogUtils.GetEnvironment(catalog); - return new FastForestRegression(env, labelColumn, featureColumn, weights, numLeaves, numTrees, minDatapointsInLeaves); + return new FastForestRegression(env, labelColumnName, featureColumnName, exampleWeightColumnName, numLeaves, numTrees, minDatapointsInLeaves); } /// @@ -289,23 +289,23 @@ public static FastForestRegression FastForest(this RegressionCatalog.RegressionT /// Predict a target using a decision tree regression model trained with the . /// /// The . - /// The labelColumn column. - /// The featureColumn column. - /// The optional weights column. + /// The name of the label column. + /// The name of the feature column. + /// The name of the example weight column (optional). /// Total number of decision trees to create in the ensemble. /// The maximum number of leaves per decision tree. /// The minimal number of datapoints allowed in a leaf of the tree, out of the subsampled data. public static FastForestClassification FastForest(this BinaryClassificationCatalog.BinaryClassificationTrainers catalog, - string labelColumn = DefaultColumnNames.Label, - string featureColumn = DefaultColumnNames.Features, - string weights = null, + string labelColumnName = DefaultColumnNames.Label, + string featureColumnName = DefaultColumnNames.Features, + string exampleWeightColumnName = null, int numLeaves = Defaults.NumLeaves, int numTrees = Defaults.NumTrees, int minDatapointsInLeaves = Defaults.MinDocumentsInLeaves) { Contracts.CheckValue(catalog, nameof(catalog)); var env = CatalogUtils.GetEnvironment(catalog); - return new FastForestClassification(env, labelColumn, featureColumn, weights,numLeaves, numTrees, minDatapointsInLeaves); + return new FastForestClassification(env, labelColumnName, featureColumnName, exampleWeightColumnName, numLeaves, numTrees, minDatapointsInLeaves); } /// diff --git a/src/Microsoft.ML.HalLearners/HalLearnersCatalog.cs b/src/Microsoft.ML.HalLearners/HalLearnersCatalog.cs index 8a8c130bad..87e2851cbc 100644 --- a/src/Microsoft.ML.HalLearners/HalLearnersCatalog.cs +++ b/src/Microsoft.ML.HalLearners/HalLearnersCatalog.cs @@ -20,7 +20,7 @@ public static class HalLearnersCatalog /// The . /// The name of the label column. /// The name of the feature column. - /// The name of optional weight column. + /// The name of the example weight column (optional). /// /// /// /// The clustering catalog trainer object. - /// The features, or independent variables. - /// The optional example weights. + /// The name of the feature column. + /// The name of the example weight column (optional). /// The number of clusters to use for KMeans. /// /// @@ -28,8 +28,8 @@ public static class KMeansClusteringExtensions /// ]]> /// public static KMeansPlusPlusTrainer KMeans(this ClusteringCatalog.ClusteringTrainers catalog, - string featureColumn = DefaultColumnNames.Features, - string weights = null, + string featureColumnName = DefaultColumnNames.Features, + string exampleWeightColumnName = null, int clustersCount = KMeansPlusPlusTrainer.Defaults.ClustersCount) { Contracts.CheckValue(catalog, nameof(catalog)); @@ -37,8 +37,8 @@ public static KMeansPlusPlusTrainer KMeans(this ClusteringCatalog.ClusteringTrai var options = new KMeansPlusPlusTrainer.Options { - FeatureColumn = featureColumn, - WeightColumn = weights, + FeatureColumn = featureColumnName, + WeightColumn = exampleWeightColumnName, ClustersCount = clustersCount }; return new KMeansPlusPlusTrainer(env, options); diff --git a/src/Microsoft.ML.LightGBM/LightGbmCatalog.cs b/src/Microsoft.ML.LightGBM/LightGbmCatalog.cs index 08a968ec5d..3e38fa248a 100644 --- a/src/Microsoft.ML.LightGBM/LightGbmCatalog.cs +++ b/src/Microsoft.ML.LightGBM/LightGbmCatalog.cs @@ -17,9 +17,9 @@ public static class LightGbmExtensions /// Predict a target using a decision tree regression model trained with the . /// /// The . - /// The labelColumn column. - /// The features column. - /// The weights column. + /// The name of the label column. + /// The name of the feature column. + /// The name of the example weight column (optional). /// The number of leaves to use. /// Number of iterations. /// The minimal number of documents allowed in a leaf of the tree, out of the subsampled data. @@ -32,9 +32,9 @@ public static class LightGbmExtensions /// /// public static LightGbmRegressorTrainer LightGbm(this RegressionCatalog.RegressionTrainers catalog, - string labelColumn = DefaultColumnNames.Label, - string featureColumn = DefaultColumnNames.Features, - string weights = null, + string labelColumnName = DefaultColumnNames.Label, + string featureColumnName = DefaultColumnNames.Features, + string exampleWeightColumnName = null, int? numLeaves = null, int? minDataPerLeaf = null, double? learningRate = null, @@ -42,7 +42,7 @@ public static LightGbmRegressorTrainer LightGbm(this RegressionCatalog.Regressio { Contracts.CheckValue(catalog, nameof(catalog)); var env = CatalogUtils.GetEnvironment(catalog); - return new LightGbmRegressorTrainer(env, labelColumn, featureColumn, weights, numLeaves, minDataPerLeaf, learningRate, numBoostRound); + return new LightGbmRegressorTrainer(env, labelColumnName, featureColumnName, exampleWeightColumnName, numLeaves, minDataPerLeaf, learningRate, numBoostRound); } /// @@ -69,9 +69,9 @@ public static LightGbmRegressorTrainer LightGbm(this RegressionCatalog.Regressio /// Predict a target using a decision tree binary classification model trained with the . /// /// The . - /// The labelColumn column. - /// The features column. - /// The weights column. + /// The name of the label column. + /// The name of the feature column. + /// The name of the example weight column (optional). /// The number of leaves to use. /// Number of iterations. /// The minimal number of documents allowed in a leaf of the tree, out of the subsampled data. @@ -84,9 +84,9 @@ public static LightGbmRegressorTrainer LightGbm(this RegressionCatalog.Regressio /// /// public static LightGbmBinaryTrainer LightGbm(this BinaryClassificationCatalog.BinaryClassificationTrainers catalog, - string labelColumn = DefaultColumnNames.Label, - string featureColumn = DefaultColumnNames.Features, - string weights = null, + string labelColumnName = DefaultColumnNames.Label, + string featureColumnName = DefaultColumnNames.Features, + string exampleWeightColumnName = null, int? numLeaves = null, int? minDataPerLeaf = null, double? learningRate = null, @@ -94,7 +94,7 @@ public static LightGbmBinaryTrainer LightGbm(this BinaryClassificationCatalog.Bi { Contracts.CheckValue(catalog, nameof(catalog)); var env = CatalogUtils.GetEnvironment(catalog); - return new LightGbmBinaryTrainer(env, labelColumn, featureColumn, weights, numLeaves, minDataPerLeaf, learningRate, numBoostRound); + return new LightGbmBinaryTrainer(env, labelColumnName, featureColumnName, exampleWeightColumnName, numLeaves, minDataPerLeaf, learningRate, numBoostRound); } /// @@ -121,19 +121,19 @@ public static LightGbmBinaryTrainer LightGbm(this BinaryClassificationCatalog.Bi /// Predict a target using a decision tree ranking model trained with the . /// /// The . - /// The labelColumn column. - /// The features column. - /// The weights column. - /// The groupId column. + /// The name of the label column. + /// The name of the feature column. + /// The name of the group column. + /// The name of the example weight column (optional). /// The number of leaves to use. /// Number of iterations. /// The minimal number of documents allowed in a leaf of the tree, out of the subsampled data. /// The learning rate. public static LightGbmRankingTrainer LightGbm(this RankingCatalog.RankingTrainers catalog, - string labelColumn = DefaultColumnNames.Label, - string featureColumn = DefaultColumnNames.Features, - string groupIdColumn = DefaultColumnNames.GroupId, - string weights = null, + string labelColumnName = DefaultColumnNames.Label, + string featureColumnName = DefaultColumnNames.Features, + string rowGroupColumnName = DefaultColumnNames.GroupId, + string exampleWeightColumnName = null, int? numLeaves = null, int? minDataPerLeaf = null, double? learningRate = null, @@ -141,7 +141,7 @@ public static LightGbmRankingTrainer LightGbm(this RankingCatalog.RankingTrainer { Contracts.CheckValue(catalog, nameof(catalog)); var env = CatalogUtils.GetEnvironment(catalog); - return new LightGbmRankingTrainer(env, labelColumn, featureColumn, groupIdColumn, weights, numLeaves, minDataPerLeaf, learningRate, numBoostRound); + return new LightGbmRankingTrainer(env, labelColumnName, featureColumnName, rowGroupColumnName, exampleWeightColumnName, numLeaves, minDataPerLeaf, learningRate, numBoostRound); } /// @@ -161,9 +161,9 @@ public static LightGbmRankingTrainer LightGbm(this RankingCatalog.RankingTrainer /// Predict a target using a decision tree multiclass classification model trained with the . /// /// The . - /// The labelColumn column. - /// The features column. - /// The weights column. + /// The name of the label column. + /// The name of the feature column. + /// The name of the example weight column (optional). /// The number of leaves to use. /// Number of iterations. /// The minimal number of documents allowed in a leaf of the tree, out of the subsampled data. @@ -176,9 +176,9 @@ public static LightGbmRankingTrainer LightGbm(this RankingCatalog.RankingTrainer /// /// public static LightGbmMulticlassTrainer LightGbm(this MulticlassClassificationCatalog.MulticlassClassificationTrainers catalog, - string labelColumn = DefaultColumnNames.Label, - string featureColumn = DefaultColumnNames.Features, - string weights = null, + string labelColumnName = DefaultColumnNames.Label, + string featureColumnName = DefaultColumnNames.Features, + string exampleWeightColumnName = null, int? numLeaves = null, int? minDataPerLeaf = null, double? learningRate = null, @@ -186,7 +186,7 @@ public static LightGbmMulticlassTrainer LightGbm(this MulticlassClassificationCa { Contracts.CheckValue(catalog, nameof(catalog)); var env = CatalogUtils.GetEnvironment(catalog); - return new LightGbmMulticlassTrainer(env, labelColumn, featureColumn, weights, numLeaves, minDataPerLeaf, learningRate, numBoostRound); + return new LightGbmMulticlassTrainer(env, labelColumnName, featureColumnName, exampleWeightColumnName, numLeaves, minDataPerLeaf, learningRate, numBoostRound); } /// diff --git a/src/Microsoft.ML.PCA/PCACatalog.cs b/src/Microsoft.ML.PCA/PCACatalog.cs index 696bf1f741..ed2e9c63ef 100644 --- a/src/Microsoft.ML.PCA/PCACatalog.cs +++ b/src/Microsoft.ML.PCA/PCACatalog.cs @@ -15,7 +15,7 @@ public static class PcaCatalog /// The transform's catalog. /// Name of the column resulting from the transformation of . /// Name of column to transform. If set to , the value of the will be used as source. - /// The name of the weight column. + /// The name of the example weight column (optional). /// The number of principal components. /// Oversampling parameter for randomized PrincipalComponentAnalysis training. /// If enabled, data is centered to be zero mean. @@ -23,13 +23,13 @@ public static class PcaCatalog public static PrincipalComponentAnalysisEstimator ProjectToPrincipalComponents(this TransformsCatalog.ProjectionTransforms catalog, string outputColumnName, string inputColumnName = null, - string weightColumn = PrincipalComponentAnalysisEstimator.Defaults.WeightColumn, + string exampleWeightColumnName = null, int rank = PrincipalComponentAnalysisEstimator.Defaults.Rank, int overSampling = PrincipalComponentAnalysisEstimator.Defaults.Oversampling, bool center = PrincipalComponentAnalysisEstimator.Defaults.Center, int? seed = null) => new PrincipalComponentAnalysisEstimator(CatalogUtils.GetEnvironment(catalog), - outputColumnName, inputColumnName, weightColumn, rank, overSampling, center, seed); + outputColumnName, inputColumnName, exampleWeightColumnName, rank, overSampling, center, seed); /// Initializes a new instance of . /// The transform's catalog. @@ -41,15 +41,15 @@ public static PrincipalComponentAnalysisEstimator ProjectToPrincipalComponents(t /// Trains an approximate PCA using Randomized SVD algorithm. /// /// The anomaly detection catalog trainer object. - /// The features, or independent variables. - /// The optional example weights. + /// The name of the feature column. + /// The name of the example weight column (optional). /// The number of components in the PCA. /// Oversampling parameter for randomized PCA training. /// If enabled, data is centered to be zero mean. /// The seed for random number generation. public static RandomizedPcaTrainer RandomizedPca(this AnomalyDetectionCatalog.AnomalyDetectionTrainers catalog, - string featureColumn = DefaultColumnNames.Features, - string weights = null, + string featureColumnName = DefaultColumnNames.Features, + string exampleWeightColumnName = null, int rank = Options.Defaults.NumComponents, int oversampling = Options.Defaults.OversamplingParameters, bool center = Options.Defaults.IsCenteredZeroMean, @@ -57,7 +57,7 @@ public static RandomizedPcaTrainer RandomizedPca(this AnomalyDetectionCatalog.An { Contracts.CheckValue(catalog, nameof(catalog)); var env = CatalogUtils.GetEnvironment(catalog); - return new RandomizedPcaTrainer(env, featureColumn, weights, rank, oversampling, center, seed); + return new RandomizedPcaTrainer(env, featureColumnName, exampleWeightColumnName, rank, oversampling, center, seed); } /// diff --git a/src/Microsoft.ML.StandardLearners/FactorizationMachine/FactorizationMachineCatalog.cs b/src/Microsoft.ML.StandardLearners/FactorizationMachine/FactorizationMachineCatalog.cs index 7d085fc965..eb717898dd 100644 --- a/src/Microsoft.ML.StandardLearners/FactorizationMachine/FactorizationMachineCatalog.cs +++ b/src/Microsoft.ML.StandardLearners/FactorizationMachine/FactorizationMachineCatalog.cs @@ -17,9 +17,9 @@ public static class FactorizationMachineExtensions /// Predict a target using a field-aware factorization machine algorithm. /// /// The binary classification catalog trainer object. - /// The features, or independent variables. - /// The label, or dependent variable. - /// The optional example weights. + /// The name(s) of the feature columns. + /// The name of the label column. + /// The name of the example weight column (optional). /// /// /// /// public static FieldAwareFactorizationMachineTrainer FieldAwareFactorizationMachine(this BinaryClassificationCatalog.BinaryClassificationTrainers catalog, - string[] featureColumns, - string labelColumn = DefaultColumnNames.Label, - string weights = null) + string[] featureColumnNames, + string labelColumnName = DefaultColumnNames.Label, + string exampleWeightColumnName = null) { Contracts.CheckValue(catalog, nameof(catalog)); var env = CatalogUtils.GetEnvironment(catalog); - return new FieldAwareFactorizationMachineTrainer(env, featureColumns, labelColumn, weights); + return new FieldAwareFactorizationMachineTrainer(env, featureColumnNames, labelColumnName, exampleWeightColumnName); } /// diff --git a/src/Microsoft.ML.StandardLearners/StandardLearnersCatalog.cs b/src/Microsoft.ML.StandardLearners/StandardLearnersCatalog.cs index 30ce7e8d8c..3291aa4d83 100644 --- a/src/Microsoft.ML.StandardLearners/StandardLearnersCatalog.cs +++ b/src/Microsoft.ML.StandardLearners/StandardLearnersCatalog.cs @@ -24,21 +24,21 @@ public static class StandardLearnersCatalog /// The binary classificaiton catalog trainer object. /// The name of the label column. /// The name of the feature column. - /// The name for the example weight column. + /// The name of the example weight column (optional). /// The maximum number of iterations; set to 1 to simulate online learning. /// The initial learning rate used by SGD. /// The L2 regularization constant. public static SgdBinaryTrainer StochasticGradientDescent(this BinaryClassificationCatalog.BinaryClassificationTrainers catalog, string labelColumnName = DefaultColumnNames.Label, string featureColumnName = DefaultColumnNames.Features, - string weightColumnName = null, + string exampleWeightColumnName = null, int maxIterations = SgdBinaryTrainer.Options.Defaults.MaxIterations, double initLearningRate = SgdBinaryTrainer.Options.Defaults.InitLearningRate, float l2Weight = SgdBinaryTrainer.Options.Defaults.L2Weight) { Contracts.CheckValue(catalog, nameof(catalog)); var env = CatalogUtils.GetEnvironment(catalog); - return new SgdBinaryTrainer(env, labelColumnName, featureColumnName, weightColumnName, + return new SgdBinaryTrainer(env, labelColumnName, featureColumnName, exampleWeightColumnName, maxIterations, initLearningRate, l2Weight); } @@ -63,7 +63,7 @@ public static SgdBinaryTrainer StochasticGradientDescent(this BinaryClassificati /// The binary classificaiton catalog trainer object. /// The name of the label column. /// The name of the feature column. - /// The name for the example weight column. + /// The name of the example weight column (optional). /// The loss function minimized in the training process. Using, for example, leads to a support vector machine trainer. /// The maximum number of iterations; set to 1 to simulate online learning. /// The initial learning rate used by SGD. @@ -71,7 +71,7 @@ public static SgdBinaryTrainer StochasticGradientDescent(this BinaryClassificati public static SgdNonCalibratedBinaryTrainer StochasticGradientDescentNonCalibrated(this BinaryClassificationCatalog.BinaryClassificationTrainers catalog, string labelColumnName = DefaultColumnNames.Label, string featureColumnName = DefaultColumnNames.Features, - string weightColumnName = null, + string exampleWeightColumnName = null, IClassificationLoss loss = null, int maxIterations = SgdNonCalibratedBinaryTrainer.Options.Defaults.MaxIterations, double initLearningRate = SgdNonCalibratedBinaryTrainer.Options.Defaults.InitLearningRate, @@ -79,7 +79,7 @@ public static SgdNonCalibratedBinaryTrainer StochasticGradientDescentNonCalibrat { Contracts.CheckValue(catalog, nameof(catalog)); var env = CatalogUtils.GetEnvironment(catalog); - return new SgdNonCalibratedBinaryTrainer(env, labelColumnName, featureColumnName, weightColumnName, + return new SgdNonCalibratedBinaryTrainer(env, labelColumnName, featureColumnName, exampleWeightColumnName, maxIterations, initLearningRate, l2Weight, loss); } @@ -102,9 +102,9 @@ public static SgdNonCalibratedBinaryTrainer StochasticGradientDescentNonCalibrat /// Predict a target using a linear regression model trained with the SDCA trainer. /// /// The regression catalog trainer object. - /// The label column, or dependent variable. - /// The features, or independent variables. - /// The optional example weights. + /// The name of the label column. + /// The name of the feature column. + /// The name of the example weight column (optional). /// The L2 regularization hyperparameter. /// The L1 regularization hyperparameter. Higher values will tend to lead to more sparse model. /// The maximum number of passes to perform over the data. @@ -113,7 +113,7 @@ public static SgdNonCalibratedBinaryTrainer StochasticGradientDescentNonCalibrat public static SdcaRegressionTrainer StochasticDualCoordinateAscent(this RegressionCatalog.RegressionTrainers catalog, string labelColumnName = DefaultColumnNames.Label, string featureColumnName = DefaultColumnNames.Features, - string weightColumnName = null, + string exampleWeightColumnName = null, ISupportSdcaRegressionLoss loss = null, float? l2Const = null, float? l1Threshold = null, @@ -121,7 +121,7 @@ public static SdcaRegressionTrainer StochasticDualCoordinateAscent(this Regressi { Contracts.CheckValue(catalog, nameof(catalog)); var env = CatalogUtils.GetEnvironment(catalog); - return new SdcaRegressionTrainer(env, labelColumnName, featureColumnName, weightColumnName, loss, l2Const, l1Threshold, maxIterations); + return new SdcaRegressionTrainer(env, labelColumnName, featureColumnName, exampleWeightColumnName, loss, l2Const, l1Threshold, maxIterations); } /// @@ -145,9 +145,9 @@ public static SdcaRegressionTrainer StochasticDualCoordinateAscent(this Regressi /// function to a . /// /// The binary classification catalog trainer object. - /// The labelColumn, or dependent variable. - /// The features, or independent variables. - /// The optional example weights. + /// The name of the label column. + /// The name of the feature column. + /// The name of the example weight column (optional). /// The L2 regularization hyperparameter. /// The L1 regularization hyperparameter. Higher values will tend to lead to more sparse model. /// The maximum number of passes to perform over the data. @@ -159,16 +159,16 @@ public static SdcaRegressionTrainer StochasticDualCoordinateAscent(this Regressi /// public static SdcaBinaryTrainer StochasticDualCoordinateAscent( this BinaryClassificationCatalog.BinaryClassificationTrainers catalog, - string labelColumn = DefaultColumnNames.Label, - string featureColumn = DefaultColumnNames.Features, - string weights = null, + string labelColumnName = DefaultColumnNames.Label, + string featureColumnName = DefaultColumnNames.Features, + string exampleWeightColumnName = null, float? l2Const = null, float? l1Threshold = null, int? maxIterations = null) { Contracts.CheckValue(catalog, nameof(catalog)); var env = CatalogUtils.GetEnvironment(catalog); - return new SdcaBinaryTrainer(env, labelColumn, featureColumn, weights, l2Const, l1Threshold, maxIterations); + return new SdcaBinaryTrainer(env, labelColumnName, featureColumnName, exampleWeightColumnName, l2Const, l1Threshold, maxIterations); } /// @@ -194,9 +194,9 @@ public static SdcaBinaryTrainer StochasticDualCoordinateAscent( /// Predict a target using a linear binary classification model trained with the SDCA trainer. /// /// The binary classification catalog trainer object. - /// The labelColumn, or dependent variable. - /// The features, or independent variables. - /// The optional example weights. + /// The name of the label column. + /// The name of the feature column. + /// The name of the example weight column (optional). /// The custom loss. Defaults to log-loss if not specified. /// The L2 regularization hyperparameter. /// The L1 regularization hyperparameter. Higher values will tend to lead to more sparse model. @@ -209,9 +209,9 @@ public static SdcaBinaryTrainer StochasticDualCoordinateAscent( /// public static SdcaNonCalibratedBinaryTrainer StochasticDualCoordinateAscentNonCalibrated( this BinaryClassificationCatalog.BinaryClassificationTrainers catalog, - string labelColumn = DefaultColumnNames.Label, - string featureColumn = DefaultColumnNames.Features, - string weights = null, + string labelColumnName = DefaultColumnNames.Label, + string featureColumnName = DefaultColumnNames.Features, + string exampleWeightColumnName = null, ISupportSdcaClassificationLoss loss = null, float? l2Const = null, float? l1Threshold = null, @@ -219,7 +219,7 @@ public static SdcaNonCalibratedBinaryTrainer StochasticDualCoordinateAscentNonCa { Contracts.CheckValue(catalog, nameof(catalog)); var env = CatalogUtils.GetEnvironment(catalog); - return new SdcaNonCalibratedBinaryTrainer(env, labelColumn, featureColumn, weights, loss, l2Const, l1Threshold, maxIterations); + return new SdcaNonCalibratedBinaryTrainer(env, labelColumnName, featureColumnName, exampleWeightColumnName, loss, l2Const, l1Threshold, maxIterations); } /// @@ -242,17 +242,17 @@ public static SdcaNonCalibratedBinaryTrainer StochasticDualCoordinateAscentNonCa /// Predict a target using a linear multiclass classification model trained with the SDCA trainer. /// /// The multiclass classification catalog trainer object. - /// The labelColumn, or dependent variable. - /// The features, or independent variables. + /// The name of the label column. + /// The name of the feature column. + /// The name of the example weight column (optional). /// The optional custom loss. - /// The optional example weights. /// The L2 regularization hyperparameter. /// The L1 regularization hyperparameter. Higher values will tend to lead to more sparse model. /// The maximum number of passes to perform over the data. public static SdcaMultiClassTrainer StochasticDualCoordinateAscent(this MulticlassClassificationCatalog.MulticlassClassificationTrainers catalog, - string labelColumn = DefaultColumnNames.Label, - string featureColumn = DefaultColumnNames.Features, - string weights = null, + string labelColumnName = DefaultColumnNames.Label, + string featureColumnName = DefaultColumnNames.Features, + string exampleWeightColumnName = null, ISupportSdcaClassificationLoss loss = null, float? l2Const = null, float? l1Threshold = null, @@ -260,7 +260,7 @@ public static SdcaMultiClassTrainer StochasticDualCoordinateAscent(this Multicla { Contracts.CheckValue(catalog, nameof(catalog)); var env = CatalogUtils.GetEnvironment(catalog); - return new SdcaMultiClassTrainer(env, labelColumn, featureColumn, weights, loss, l2Const, l1Threshold, maxIterations); + return new SdcaMultiClassTrainer(env, labelColumnName, featureColumnName, exampleWeightColumnName, loss, l2Const, l1Threshold, maxIterations); } /// @@ -282,8 +282,8 @@ public static SdcaMultiClassTrainer StochasticDualCoordinateAscent(this Multicla /// Predict a target using a linear binary classification model trained with . /// /// The binary classification catalog trainer object. - /// The name of the label column, or dependent variable. - /// The features, or independent variables. + /// The name of the label column. + /// The name of the feature column. /// A custom loss. If , hinge loss will be used resulting in max-margin averaged perceptron. /// Learning rate. /// @@ -301,8 +301,8 @@ public static SdcaMultiClassTrainer StochasticDualCoordinateAscent(this Multicla /// public static AveragedPerceptronTrainer AveragedPerceptron( this BinaryClassificationCatalog.BinaryClassificationTrainers catalog, - string labelColumn = DefaultColumnNames.Label, - string featureColumn = DefaultColumnNames.Features, + string labelColumnName = DefaultColumnNames.Label, + string featureColumnName = DefaultColumnNames.Features, IClassificationLoss lossFunction = null, float learningRate = AveragedLinearOptions.AveragedDefault.LearningRate, bool decreaseLearningRate = AveragedLinearOptions.AveragedDefault.DecreaseLearningRate, @@ -312,7 +312,7 @@ public static AveragedPerceptronTrainer AveragedPerceptron( Contracts.CheckValue(catalog, nameof(catalog)); var env = CatalogUtils.GetEnvironment(catalog); - return new AveragedPerceptronTrainer(env, labelColumn, featureColumn, lossFunction ?? new LogLoss(), learningRate, decreaseLearningRate, l2RegularizerWeight, numIterations); + return new AveragedPerceptronTrainer(env, labelColumnName, featureColumnName, lossFunction ?? new LogLoss(), learningRate, decreaseLearningRate, l2RegularizerWeight, numIterations); } /// @@ -356,16 +356,16 @@ public IClassificationLoss CreateComponent(IHostEnvironment env) /// Predict a target using a linear regression model trained with the trainer. /// /// The regression catalog trainer object. - /// The name of the label, or dependent variable. - /// The features, or independent variables. + /// The name of the label column. + /// The name of the feature column. /// The custom loss. Defaults to if not provided. /// The learning Rate. /// Decrease learning rate as iterations progress. /// L2 regularization weight. /// Number of training iterations through the data. public static OnlineGradientDescentTrainer OnlineGradientDescent(this RegressionCatalog.RegressionTrainers catalog, - string labelColumn = DefaultColumnNames.Label, - string featureColumn = DefaultColumnNames.Features, + string labelColumnName = DefaultColumnNames.Label, + string featureColumnName = DefaultColumnNames.Features, IRegressionLoss lossFunction = null, float learningRate = OnlineGradientDescentTrainer.Options.OgdDefaultArgs.LearningRate, bool decreaseLearningRate = OnlineGradientDescentTrainer.Options.OgdDefaultArgs.DecreaseLearningRate, @@ -374,7 +374,7 @@ public static OnlineGradientDescentTrainer OnlineGradientDescent(this Regression { Contracts.CheckValue(catalog, nameof(catalog)); var env = CatalogUtils.GetEnvironment(catalog); - return new OnlineGradientDescentTrainer(env, labelColumn, featureColumn, learningRate, decreaseLearningRate, l2RegularizerWeight, + return new OnlineGradientDescentTrainer(env, labelColumnName, featureColumnName, learningRate, decreaseLearningRate, l2RegularizerWeight, numIterations, lossFunction); } @@ -397,9 +397,9 @@ public static OnlineGradientDescentTrainer OnlineGradientDescent(this Regression /// Predict a target using a linear binary classification model trained with the trainer. /// /// The binary classificaiton catalog trainer object. - /// The label column name, or dependent variable. - /// The features, or independent variables. - /// The optional example weights. + /// The name of the label column. + /// The name of the feature column. + /// The name of the example weight column (optional). /// Enforce non-negative weights. /// Weight of L1 regularization term. /// Weight of L2 regularization term. @@ -413,9 +413,9 @@ public static OnlineGradientDescentTrainer OnlineGradientDescent(this Regression /// /// public static LogisticRegression LogisticRegression(this BinaryClassificationCatalog.BinaryClassificationTrainers catalog, - string labelColumn = DefaultColumnNames.Label, - string featureColumn = DefaultColumnNames.Features, - string weights = null, + string labelColumnName = DefaultColumnNames.Label, + string featureColumnName = DefaultColumnNames.Features, + string exampleWeightColumnName = null, float l1Weight = LROptions.Defaults.L1Weight, float l2Weight = LROptions.Defaults.L2Weight, float optimizationTolerance = LROptions.Defaults.OptTol, @@ -424,7 +424,7 @@ public static LogisticRegression LogisticRegression(this BinaryClassificationCat { Contracts.CheckValue(catalog, nameof(catalog)); var env = CatalogUtils.GetEnvironment(catalog); - return new LogisticRegression(env, labelColumn, featureColumn, weights, l1Weight, l2Weight, optimizationTolerance, memorySize, enforceNoNegativity); + return new LogisticRegression(env, labelColumnName, featureColumnName, exampleWeightColumnName, l1Weight, l2Weight, optimizationTolerance, memorySize, enforceNoNegativity); } /// @@ -445,18 +445,18 @@ public static LogisticRegression LogisticRegression(this BinaryClassificationCat /// Predict a target using a linear regression model trained with the trainer. /// /// The regression catalog trainer object. - /// The labelColumn, or dependent variable. - /// The features, or independent variables. - /// The optional example weights. + /// The name of the label column. + /// The name of the feature column. + /// The name of the example weight column (optional). /// Weight of L1 regularization term. /// Weight of L2 regularization term. /// Threshold for optimizer convergence. /// Memory size for . Low=faster, less accurate. /// Enforce non-negative weights. public static PoissonRegression PoissonRegression(this RegressionCatalog.RegressionTrainers catalog, - string labelColumn = DefaultColumnNames.Label, - string featureColumn = DefaultColumnNames.Features, - string weights = null, + string labelColumnName = DefaultColumnNames.Label, + string featureColumnName = DefaultColumnNames.Features, + string exampleWeightColumnName = null, float l1Weight = LROptions.Defaults.L1Weight, float l2Weight = LROptions.Defaults.L2Weight, float optimizationTolerance = LROptions.Defaults.OptTol, @@ -465,7 +465,7 @@ public static PoissonRegression PoissonRegression(this RegressionCatalog.Regress { Contracts.CheckValue(catalog, nameof(catalog)); var env = CatalogUtils.GetEnvironment(catalog); - return new PoissonRegression(env, labelColumn, featureColumn, weights, l1Weight, l2Weight, optimizationTolerance, memorySize, enforceNoNegativity); + return new PoissonRegression(env, labelColumnName, featureColumnName, exampleWeightColumnName, l1Weight, l2Weight, optimizationTolerance, memorySize, enforceNoNegativity); } /// @@ -486,18 +486,18 @@ public static PoissonRegression PoissonRegression(this RegressionCatalog.Regress /// Predict a target using a linear multiclass classification model trained with the trainer. /// /// The . - /// The labelColumn, or dependent variable. - /// The features, or independent variables. - /// The optional example weights. + /// The name of the label column. + /// The name of the feature column. + /// The name of the example weight column (optional). /// Enforce non-negative weights. /// Weight of L1 regularization term. /// Weight of L2 regularization term. /// Memory size for . Low=faster, less accurate. /// Threshold for optimizer convergence. public static MulticlassLogisticRegression LogisticRegression(this MulticlassClassificationCatalog.MulticlassClassificationTrainers catalog, - string labelColumn = DefaultColumnNames.Label, - string featureColumn = DefaultColumnNames.Features, - string weights = null, + string labelColumnName = DefaultColumnNames.Label, + string featureColumnName = DefaultColumnNames.Features, + string exampleWeightColumnName = null, float l1Weight = LROptions.Defaults.L1Weight, float l2Weight = LROptions.Defaults.L2Weight, float optimizationTolerance = LROptions.Defaults.OptTol, @@ -506,7 +506,7 @@ public static MulticlassLogisticRegression LogisticRegression(this MulticlassCla { Contracts.CheckValue(catalog, nameof(catalog)); var env = CatalogUtils.GetEnvironment(catalog); - return new MulticlassLogisticRegression(env, labelColumn, featureColumn, weights, l1Weight, l2Weight, optimizationTolerance, memorySize, enforceNoNegativity); + return new MulticlassLogisticRegression(env, labelColumnName, featureColumnName, exampleWeightColumnName, l1Weight, l2Weight, optimizationTolerance, memorySize, enforceNoNegativity); } /// @@ -529,14 +529,14 @@ public static MulticlassLogisticRegression LogisticRegression(this MulticlassCla /// The trains a multiclass Naive Bayes predictor that supports binary feature values. /// /// The . - /// The name of the label column. - /// The name of the feature column. + /// The name of the label column. + /// The name of the feature column. public static MultiClassNaiveBayesTrainer NaiveBayes(this MulticlassClassificationCatalog.MulticlassClassificationTrainers catalog, - string labelColumn = DefaultColumnNames.Label, - string featureColumn = DefaultColumnNames.Features) + string labelColumnName = DefaultColumnNames.Label, + string featureColumnName = DefaultColumnNames.Features) { Contracts.CheckValue(catalog, nameof(catalog)); - return new MultiClassNaiveBayesTrainer(CatalogUtils.GetEnvironment(catalog), labelColumn, featureColumn); + return new MultiClassNaiveBayesTrainer(CatalogUtils.GetEnvironment(catalog), labelColumnName, featureColumnName); } /// @@ -572,14 +572,14 @@ private static ICalibratorTrainer GetCalibratorTrainerOrThrow(IExceptionContext /// The . /// An instance of a binary used as the base trainer. /// The calibrator. If a calibrator is not explicitely provided, it will default to - /// The name of the label colum. + /// The name of the label colum. /// Whether to treat missing labels as having negative labels, instead of keeping them missing. /// Number of instances to train the calibrator. /// Use probabilities (vs. raw outputs) to identify top-score category. /// The type of the model. This type parameter will usually be inferred automatically from . public static Ova OneVersusAll(this MulticlassClassificationCatalog.MulticlassClassificationTrainers catalog, ITrainerEstimator, TModel> binaryEstimator, - string labelColumn = DefaultColumnNames.Label, + string labelColumnName = DefaultColumnNames.Label, bool imputeMissingLabelsAsNegative = false, IEstimator> calibrator = null, int maxCalibrationExamples = 1000000000, @@ -590,7 +590,7 @@ public static Ova OneVersusAll(this MulticlassClassificationCatalog.Mult var env = CatalogUtils.GetEnvironment(catalog); if (!(binaryEstimator is ITrainerEstimator>, IPredictorProducing> est)) throw env.ExceptParam(nameof(binaryEstimator), "Trainer estimator does not appear to produce the right kind of model."); - return new Ova(env, est, labelColumn, imputeMissingLabelsAsNegative, GetCalibratorTrainerOrThrow(env, calibrator), maxCalibrationExamples, useProbabilities); + return new Ova(env, est, labelColumnName, imputeMissingLabelsAsNegative, GetCalibratorTrainerOrThrow(env, calibrator), maxCalibrationExamples, useProbabilities); } /// @@ -606,13 +606,13 @@ public static Ova OneVersusAll(this MulticlassClassificationCatalog.Mult /// The . /// An instance of a binary used as the base trainer. /// The calibrator. If a calibrator is not explicitely provided, it will default to - /// The name of the label colum. + /// The name of the label colum. /// Whether to treat missing labels as having negative labels, instead of keeping them missing. /// Number of instances to train the calibrator. /// The type of the model. This type parameter will usually be inferred automatically from . public static Pkpd PairwiseCoupling(this MulticlassClassificationCatalog.MulticlassClassificationTrainers catalog, ITrainerEstimator, TModel> binaryEstimator, - string labelColumn = DefaultColumnNames.Label, + string labelColumnName = DefaultColumnNames.Label, bool imputeMissingLabelsAsNegative = false, IEstimator> calibrator = null, int maxCalibrationExamples = 1_000_000_000) @@ -622,7 +622,7 @@ public static Pkpd PairwiseCoupling(this MulticlassClassificationCatalog var env = CatalogUtils.GetEnvironment(catalog); if (!(binaryEstimator is ITrainerEstimator>, IPredictorProducing> est)) throw env.ExceptParam(nameof(binaryEstimator), "Trainer estimator does not appear to produce the right kind of model."); - return new Pkpd(env, est, labelColumn, imputeMissingLabelsAsNegative, GetCalibratorTrainerOrThrow(env, calibrator), maxCalibrationExamples); + return new Pkpd(env, est, labelColumnName, imputeMissingLabelsAsNegative, GetCalibratorTrainerOrThrow(env, calibrator), maxCalibrationExamples); } /// @@ -640,18 +640,18 @@ public static Pkpd PairwiseCoupling(this MulticlassClassificationCatalog /// /// /// The . - /// The name of the label column. - /// The name of the feature column. - /// The optional name of the weights column. + /// The name of the label column. + /// The name of the feature column. + /// The name of the example weight column (optional). /// The number of training iteraitons. public static LinearSvmTrainer LinearSupportVectorMachines(this BinaryClassificationCatalog.BinaryClassificationTrainers catalog, - string labelColumn = DefaultColumnNames.Label, - string featureColumn = DefaultColumnNames.Features, - string weightsColumn = null, + string labelColumnName = DefaultColumnNames.Label, + string featureColumnName = DefaultColumnNames.Features, + string exampleWeightColumnName = null, int numIterations = OnlineLinearOptions.OnlineDefault.NumIterations) { Contracts.CheckValue(catalog, nameof(catalog)); - return new LinearSvmTrainer(CatalogUtils.GetEnvironment(catalog), labelColumn, featureColumn, weightsColumn, numIterations); + return new LinearSvmTrainer(CatalogUtils.GetEnvironment(catalog), labelColumnName, featureColumnName, exampleWeightColumnName, numIterations); } /// @@ -706,8 +706,8 @@ public static RandomTrainer Random(this BinaryClassificationCatalog.BinaryClassi /// This trainer is often used as a baseline for other more sophisticated mdels. /// /// The . - /// The name of the label column. - /// The optional name of the weights column. + /// The name of the label column. + /// The name of the example weight column (optional). /// /// /// /// public static PriorTrainer Prior(this BinaryClassificationCatalog.BinaryClassificationTrainers catalog, - string labelColumn = DefaultColumnNames.Label, - string weightsColumn = null) + string labelColumnName = DefaultColumnNames.Label, + string exampleWeightColumnName = null) { Contracts.CheckValue(catalog, nameof(catalog)); - return new PriorTrainer(CatalogUtils.GetEnvironment(catalog), labelColumn, weightsColumn); + return new PriorTrainer(CatalogUtils.GetEnvironment(catalog), labelColumnName, exampleWeightColumnName); } } } diff --git a/test/Microsoft.ML.Tests/OnnxConversionTest.cs b/test/Microsoft.ML.Tests/OnnxConversionTest.cs index 0142b900cd..f220e3e4fd 100644 --- a/test/Microsoft.ML.Tests/OnnxConversionTest.cs +++ b/test/Microsoft.ML.Tests/OnnxConversionTest.cs @@ -213,7 +213,7 @@ public void KeyToVectorWithBagOnnxConversionTest() var pipeline = mlContext.Transforms.Categorical.OneHotEncoding("F2", "F2", Transforms.Categorical.OneHotEncodingTransformer.OutputKind.Bag) .Append(mlContext.Transforms.ReplaceMissingValues(new MissingValueReplacingEstimator.ColumnInfo("F2"))) .Append(mlContext.Transforms.Concatenate("Features", "F1", "F2")) - .Append(mlContext.BinaryClassification.Trainers.FastTree(labelColumn: "Label", featureColumn: "Features", numLeaves: 2, numTrees: 1, minDatapointsInLeaves: 2)); + .Append(mlContext.BinaryClassification.Trainers.FastTree(labelColumnName: "Label", featureColumnName: "Features", numLeaves: 2, numTrees: 1, minDatapointsInLeaves: 2)); var model = pipeline.Fit(data); var onnxModel = mlContext.Model.ConvertToOnnxProtobuf(model, data); @@ -345,7 +345,7 @@ public void LightGbmBinaryClassificationOnnxConversionTest() var dynamicPipeline = mlContext.Transforms.Normalize("FeatureVector") .AppendCacheCheckpoint(mlContext) - .Append(mlContext.Regression.Trainers.LightGbm(labelColumn: "Target", featureColumn: "FeatureVector", numBoostRound: 3, numLeaves: 16, minDataPerLeaf: 100)); + .Append(mlContext.Regression.Trainers.LightGbm(labelColumnName: "Target", featureColumnName: "FeatureVector", numBoostRound: 3, numLeaves: 16, minDataPerLeaf: 100)); var model = dynamicPipeline.Fit(data); // Step 2: Convert ML.NET model to ONNX format and save it as a file. @@ -408,7 +408,7 @@ public void RemoveVariablesInPipelineTest() .Append(mlContext.Transforms.ReplaceMissingValues(new MissingValueReplacingEstimator.ColumnInfo("F2"))) .Append(mlContext.Transforms.Concatenate("Features", "F1", "F2")) .Append(mlContext.Transforms.Normalize("Features")) - .Append(mlContext.BinaryClassification.Trainers.FastTree(labelColumn: "Label", featureColumn: "Features", numLeaves: 2, numTrees: 1, minDatapointsInLeaves: 2)); + .Append(mlContext.BinaryClassification.Trainers.FastTree(labelColumnName: "Label", featureColumnName: "Features", numLeaves: 2, numTrees: 1, minDatapointsInLeaves: 2)); var model = pipeline.Fit(data); var transformedData = model.Transform(data); diff --git a/test/Microsoft.ML.Tests/Scenarios/Api/CookbookSamples/CookbookSamplesDynamicApi.cs b/test/Microsoft.ML.Tests/Scenarios/Api/CookbookSamples/CookbookSamplesDynamicApi.cs index 33131d2bdf..3a74d1584f 100644 --- a/test/Microsoft.ML.Tests/Scenarios/Api/CookbookSamples/CookbookSamplesDynamicApi.cs +++ b/test/Microsoft.ML.Tests/Scenarios/Api/CookbookSamples/CookbookSamplesDynamicApi.cs @@ -513,7 +513,7 @@ private static void RunEndToEnd(MLContext mlContext, IDataView trainData, string // Construct the learning pipeline. Note that we are now providing a contract name for the custom mapping: // otherwise we will not be able to save the model. var estimator = mlContext.Transforms.CustomMapping(CustomMappings.IncomeMapping, nameof(CustomMappings.IncomeMapping)) - .Append(mlContext.BinaryClassification.Trainers.FastTree(labelColumn: "Label")); + .Append(mlContext.BinaryClassification.Trainers.FastTree(labelColumnName: "Label")); // If memory is enough, we can cache the data in-memory to avoid reading them from file // when it will be accessed multiple times. @@ -555,7 +555,7 @@ public static ITransformer TrainModel(MLContext mlContext, IDataView trainData) // Construct the learning pipeline. var estimator = mlContext.Transforms.CustomMapping(mapping, null) .AppendCacheCheckpoint(mlContext) - .Append(mlContext.BinaryClassification.Trainers.FastTree(labelColumn: "Label")); + .Append(mlContext.BinaryClassification.Trainers.FastTree(labelColumnName: "Label")); return estimator.Fit(trainData); } diff --git a/test/Microsoft.ML.Tests/TrainerEstimators/SdcaTests.cs b/test/Microsoft.ML.Tests/TrainerEstimators/SdcaTests.cs index 8953fd995b..0542446d7d 100644 --- a/test/Microsoft.ML.Tests/TrainerEstimators/SdcaTests.cs +++ b/test/Microsoft.ML.Tests/TrainerEstimators/SdcaTests.cs @@ -58,7 +58,7 @@ public void SdcaLogisticRegression() // Step 2: Create a binary classifier. // We set the "Label" column as the label of the dataset, and the "Features" column as the features column. - var pipeline = mlContext.BinaryClassification.Trainers.StochasticDualCoordinateAscent(labelColumn: "Label", featureColumn: "Features", l2Const: 0.001f); + var pipeline = mlContext.BinaryClassification.Trainers.StochasticDualCoordinateAscent(labelColumnName: "Label", featureColumnName: "Features", l2Const: 0.001f); // Step 3: Train the pipeline created. var model = pipeline.Fit(data); @@ -103,7 +103,7 @@ public void SdcaSupportVectorMachine() // Step 2: Create a binary classifier. // We set the "Label" column as the label of the dataset, and the "Features" column as the features column. var pipeline = mlContext.BinaryClassification.Trainers.StochasticDualCoordinateAscentNonCalibrated( - labelColumn: "Label", featureColumn: "Features", loss: new HingeLoss(), l2Const: 0.001f); + labelColumnName: "Label", featureColumnName: "Features", loss: new HingeLoss(), l2Const: 0.001f); // Step 3: Train the pipeline created. var model = pipeline.Fit(data); diff --git a/test/Microsoft.ML.Tests/TrainerEstimators/TreeEstimators.cs b/test/Microsoft.ML.Tests/TrainerEstimators/TreeEstimators.cs index 55a4f7c9ae..d8571b6ba3 100644 --- a/test/Microsoft.ML.Tests/TrainerEstimators/TreeEstimators.cs +++ b/test/Microsoft.ML.Tests/TrainerEstimators/TreeEstimators.cs @@ -134,7 +134,7 @@ public void LightGBMRankerEstimator() { var (pipe, dataView) = GetRankingPipeline(); - var trainer = ML.Ranking.Trainers.LightGbm(labelColumn: "Label0", featureColumn: "NumericFeatures", groupIdColumn: "Group", learningRate: 0.4); + var trainer = ML.Ranking.Trainers.LightGbm(labelColumnName: "Label0", featureColumnName: "NumericFeatures", rowGroupColumnName: "Group", learningRate: 0.4); var pipeWithTrainer = pipe.Append(trainer); TestEstimatorCore(pipeWithTrainer, dataView); diff --git a/test/Microsoft.ML.Tests/Transformers/PcaTests.cs b/test/Microsoft.ML.Tests/Transformers/PcaTests.cs index 490fca5c2f..60f26176ce 100644 --- a/test/Microsoft.ML.Tests/Transformers/PcaTests.cs +++ b/test/Microsoft.ML.Tests/Transformers/PcaTests.cs @@ -40,7 +40,7 @@ public void PcaWorkout() var est = ML.Transforms.Projection.ProjectToPrincipalComponents("pca", "features", rank: 4, seed: 10); TestEstimatorCore(est, data.AsDynamic, invalidInput: invalidData.AsDynamic); - var estNonDefaultArgs = ML.Transforms.Projection.ProjectToPrincipalComponents("pca", "features", rank: 3, weightColumn: "weight", overSampling: 2, center: false); + var estNonDefaultArgs = ML.Transforms.Projection.ProjectToPrincipalComponents("pca", "features", rank: 3, exampleWeightColumnName: "weight", overSampling: 2, center: false); TestEstimatorCore(estNonDefaultArgs, data.AsDynamic, invalidInput: invalidData.AsDynamic); Done(); From 4acf5aa97ec4e55b32bf612e551e218b5af2a73a Mon Sep 17 00:00:00 2001 From: Artidoro Pagnoni Date: Mon, 25 Feb 2019 11:01:04 -0800 Subject: [PATCH 14/24] Explicit implementation for IsRowToRowMapper and GetRowToRowMapper (#2673) --- .../DataLoadSave/TransformWrapper.cs | 9 +++++---- .../DataLoadSave/TransformerChain.cs | 7 ++++--- .../Prediction/PredictionEngine.cs | 4 ++-- .../Scorers/PredictionTransformer.cs | 6 +++--- .../Transforms/ColumnSelecting.cs | 6 +++--- .../Transforms/RowToRowTransformerBase.cs | 4 ++-- .../IidAnomalyDetectionBase.cs | 18 +++++++++++------- .../IidChangePointDetector.cs | 4 ++-- .../IidSpikeDetector.cs | 4 ++-- .../SequentialAnomalyDetectionTransformBase.cs | 2 +- .../SequentialTransformerBase.cs | 2 +- .../SsaAnomalyDetectionBase.cs | 18 +++++++++++------- .../SsaChangePointDetector.cs | 4 ++-- .../SsaSpikeDetector.cs | 4 ++-- .../CustomMappingTransformer.cs | 8 ++++---- src/Microsoft.ML.Transforms/OneHotEncoding.cs | 4 ++-- .../OneHotHashEncoding.cs | 6 +++--- .../Text/TextFeaturizingEstimator.cs | 4 ++-- test/Microsoft.ML.Benchmarks/HashBench.cs | 2 +- .../Transformers/HashTests.cs | 12 ++++++------ 20 files changed, 69 insertions(+), 59 deletions(-) diff --git a/src/Microsoft.ML.Data/DataLoadSave/TransformWrapper.cs b/src/Microsoft.ML.Data/DataLoadSave/TransformWrapper.cs index c822568cf1..3992443100 100644 --- a/src/Microsoft.ML.Data/DataLoadSave/TransformWrapper.cs +++ b/src/Microsoft.ML.Data/DataLoadSave/TransformWrapper.cs @@ -25,6 +25,7 @@ public sealed class TransformWrapper : ITransformer private readonly IHost _host; private readonly IDataView _xf; private readonly bool _allowSave; + private readonly bool _isRowToRowMapper; public TransformWrapper(IHostEnvironment env, IDataView xf, bool allowSave = false) { @@ -33,7 +34,7 @@ public TransformWrapper(IHostEnvironment env, IDataView xf, bool allowSave = fal _host.CheckValue(xf, nameof(xf)); _xf = xf; _allowSave = allowSave; - IsRowToRowMapper = IsChainRowToRowMapper(_xf); + _isRowToRowMapper = IsChainRowToRowMapper(_xf); } public DataViewSchema GetOutputSchema(DataViewSchema inputSchema) @@ -108,7 +109,7 @@ private TransformWrapper(IHostEnvironment env, ModelLoadContext ctx) } _xf = data; - IsRowToRowMapper = IsChainRowToRowMapper(_xf); + _isRowToRowMapper = IsChainRowToRowMapper(_xf); } public IDataView Transform(IDataView input) => ApplyTransformUtils.ApplyAllTransformsToData(_host, _xf, input); @@ -123,9 +124,9 @@ private static bool IsChainRowToRowMapper(IDataView view) return true; } - public bool IsRowToRowMapper { get; } + bool ITransformer.IsRowToRowMapper => _isRowToRowMapper; - public IRowToRowMapper GetRowToRowMapper(DataViewSchema inputSchema) + IRowToRowMapper ITransformer.GetRowToRowMapper(DataViewSchema inputSchema) { _host.CheckValue(inputSchema, nameof(inputSchema)); var input = new EmptyDataView(_host, inputSchema); diff --git a/src/Microsoft.ML.Data/DataLoadSave/TransformerChain.cs b/src/Microsoft.ML.Data/DataLoadSave/TransformerChain.cs index 30202c0617..d776b10f19 100644 --- a/src/Microsoft.ML.Data/DataLoadSave/TransformerChain.cs +++ b/src/Microsoft.ML.Data/DataLoadSave/TransformerChain.cs @@ -59,7 +59,7 @@ public sealed class TransformerChain : ITransformer, IEnumerab private const string TransformDirTemplate = "Transform_{0:000}"; - public bool IsRowToRowMapper => _transformers.All(t => t.IsRowToRowMapper); + bool ITransformer.IsRowToRowMapper => _transformers.All(t => t.IsRowToRowMapper); ITransformer[] ITransformerChainAccessor.Transformers => _transformers; @@ -216,10 +216,11 @@ public void SaveTo(IHostEnvironment env, Stream outputStream) IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public IRowToRowMapper GetRowToRowMapper(DataViewSchema inputSchema) + IRowToRowMapper ITransformer.GetRowToRowMapper(DataViewSchema inputSchema) { Contracts.CheckValue(inputSchema, nameof(inputSchema)); - Contracts.Check(IsRowToRowMapper, nameof(GetRowToRowMapper) + " method called despite " + nameof(IsRowToRowMapper) + " being false."); + Contracts.Check(((ITransformer)this).IsRowToRowMapper, nameof(ITransformer.GetRowToRowMapper) + " method called despite " + + nameof(ITransformer.IsRowToRowMapper) + " being false."); IRowToRowMapper[] mappers = new IRowToRowMapper[_transformers.Length]; DataViewSchema schema = inputSchema; diff --git a/src/Microsoft.ML.Data/Prediction/PredictionEngine.cs b/src/Microsoft.ML.Data/Prediction/PredictionEngine.cs index 6b396180c3..2100ef3fd0 100644 --- a/src/Microsoft.ML.Data/Prediction/PredictionEngine.cs +++ b/src/Microsoft.ML.Data/Prediction/PredictionEngine.cs @@ -116,8 +116,8 @@ private static Func StreamChecker(IHostEnvironm { var pipe = DataViewConstructionUtils.LoadPipeWithPredictor(env, modelStream, new EmptyDataView(env, schema)); var transformer = new TransformWrapper(env, pipe); - env.CheckParam(transformer.IsRowToRowMapper, nameof(transformer), "Must be a row to row mapper"); - return transformer.GetRowToRowMapper(schema); + env.CheckParam(((ITransformer)transformer).IsRowToRowMapper, nameof(transformer), "Must be a row to row mapper"); + return ((ITransformer)transformer).GetRowToRowMapper(schema); }; } diff --git a/src/Microsoft.ML.Data/Scorers/PredictionTransformer.cs b/src/Microsoft.ML.Data/Scorers/PredictionTransformer.cs index 8bab13fa5d..7b94c92795 100644 --- a/src/Microsoft.ML.Data/Scorers/PredictionTransformer.cs +++ b/src/Microsoft.ML.Data/Scorers/PredictionTransformer.cs @@ -55,10 +55,10 @@ public abstract class PredictionTransformerBase : IPredictionTransformer protected DataViewSchema TrainSchema; /// - /// Whether a call to should succeed, on an + /// Whether a call to should succeed, on an /// appropriate schema. /// - public bool IsRowToRowMapper => true; + bool ITransformer.IsRowToRowMapper => true; /// /// This class is more or less a thin wrapper over the implementing @@ -132,7 +132,7 @@ public IDataView Transform(IDataView input) /// /// /// - public IRowToRowMapper GetRowToRowMapper(DataViewSchema inputSchema) + IRowToRowMapper ITransformer.GetRowToRowMapper(DataViewSchema inputSchema) { Host.CheckValue(inputSchema, nameof(inputSchema)); return (IRowToRowMapper)Scorer.ApplyToData(Host, new EmptyDataView(Host, inputSchema)); diff --git a/src/Microsoft.ML.Data/Transforms/ColumnSelecting.cs b/src/Microsoft.ML.Data/Transforms/ColumnSelecting.cs index 2a0c0686d2..2e8354e2f1 100644 --- a/src/Microsoft.ML.Data/Transforms/ColumnSelecting.cs +++ b/src/Microsoft.ML.Data/Transforms/ColumnSelecting.cs @@ -138,7 +138,7 @@ public sealed class ColumnSelectingTransformer : ITransformer private readonly IHost _host; private string[] _selectedColumns; - public bool IsRowToRowMapper => true; + bool ITransformer.IsRowToRowMapper => true; public IEnumerable SelectColumns => _selectedColumns.AsReadOnly(); @@ -458,13 +458,13 @@ public DataViewSchema GetOutputSchema(DataViewSchema inputSchema) } /// - /// Constructs a row-to-row mapper based on an input schema. If + /// Constructs a row-to-row mapper based on an input schema. If /// is false, then an exception is thrown. If the input schema is in any way /// unsuitable for constructing the mapper, an exception should likewise be thrown. /// /// The input schema for which we should get the mapper. /// The row to row mapper. - public IRowToRowMapper GetRowToRowMapper(DataViewSchema inputSchema) + IRowToRowMapper ITransformer.GetRowToRowMapper(DataViewSchema inputSchema) { _host.CheckValue(inputSchema, nameof(inputSchema)); if (!IgnoreMissing && !IsSchemaValid(inputSchema.Select(x => x.Name), diff --git a/src/Microsoft.ML.Data/Transforms/RowToRowTransformerBase.cs b/src/Microsoft.ML.Data/Transforms/RowToRowTransformerBase.cs index e3166d7407..78a34ad8bf 100644 --- a/src/Microsoft.ML.Data/Transforms/RowToRowTransformerBase.cs +++ b/src/Microsoft.ML.Data/Transforms/RowToRowTransformerBase.cs @@ -26,9 +26,9 @@ protected RowToRowTransformerBase(IHost host) private protected abstract void SaveModel(ModelSaveContext ctx); - public bool IsRowToRowMapper => true; + bool ITransformer.IsRowToRowMapper => true; - public IRowToRowMapper GetRowToRowMapper(DataViewSchema inputSchema) + IRowToRowMapper ITransformer.GetRowToRowMapper(DataViewSchema inputSchema) { Host.CheckValue(inputSchema, nameof(inputSchema)); return new RowToRowMapperTransform(Host, new EmptyDataView(Host, inputSchema), MakeRowMapper(inputSchema), MakeRowMapper); diff --git a/src/Microsoft.ML.TimeSeries/IidAnomalyDetectionBase.cs b/src/Microsoft.ML.TimeSeries/IidAnomalyDetectionBase.cs index 38cca21a49..46902ae369 100644 --- a/src/Microsoft.ML.TimeSeries/IidAnomalyDetectionBase.cs +++ b/src/Microsoft.ML.TimeSeries/IidAnomalyDetectionBase.cs @@ -18,10 +18,10 @@ namespace Microsoft.ML.Transforms.TimeSeries public class IidAnomalyDetectionBaseWrapper : IStatefulTransformer, ICanSaveModel { /// - /// Whether a call to should succeed, on an + /// Whether a call to should succeed, on an /// appropriate schema. /// - public bool IsRowToRowMapper => InternalTransform.IsRowToRowMapper; + bool ITransformer.IsRowToRowMapper => ((ITransformer)InternalTransform).IsRowToRowMapper; /// /// Creates a clone of the transfomer. Used for taking the snapshot of the state. @@ -36,20 +36,22 @@ public class IidAnomalyDetectionBaseWrapper : IStatefulTransformer, ICanSaveMode public DataViewSchema GetOutputSchema(DataViewSchema inputSchema) => InternalTransform.GetOutputSchema(inputSchema); /// - /// Constructs a row-to-row mapper based on an input schema. If + /// Constructs a row-to-row mapper based on an input schema. If /// is false, then an exception should be thrown. If the input schema is in any way /// unsuitable for constructing the mapper, an exception should likewise be thrown. /// /// The input schema for which we should get the mapper. /// The row to row mapper. - public IRowToRowMapper GetRowToRowMapper(DataViewSchema inputSchema) => InternalTransform.GetRowToRowMapper(inputSchema); + IRowToRowMapper ITransformer.GetRowToRowMapper(DataViewSchema inputSchema) + => ((ITransformer)InternalTransform).GetRowToRowMapper(inputSchema); /// /// Same as but also supports mechanism to save the state. /// /// The input schema for which we should get the mapper. /// The row to row mapper. - public IRowToRowMapper GetStatefulRowToRowMapper(DataViewSchema inputSchema) => ((IStatefulTransformer)InternalTransform).GetStatefulRowToRowMapper(inputSchema); + public IRowToRowMapper GetStatefulRowToRowMapper(DataViewSchema inputSchema) + => ((IStatefulTransformer)InternalTransform).GetStatefulRowToRowMapper(inputSchema); /// /// Take the data in, make transformations, output the data. @@ -60,7 +62,9 @@ public class IidAnomalyDetectionBaseWrapper : IStatefulTransformer, ICanSaveMode /// /// For saving a model into a repository. /// - public virtual void Save(ModelSaveContext ctx) + void ICanSaveModel.Save(ModelSaveContext ctx) => SaveModel(ctx); + + private protected virtual void SaveModel(ModelSaveContext ctx) { InternalTransform.SaveThis(ctx); } @@ -129,7 +133,7 @@ public override DataViewSchema GetOutputSchema(DataViewSchema inputSchema) private protected override void SaveModel(ModelSaveContext ctx) { - Parent.Save(ctx); + ((ICanSaveModel)Parent).Save(ctx); } internal void SaveThis(ModelSaveContext ctx) diff --git a/src/Microsoft.ML.TimeSeries/IidChangePointDetector.cs b/src/Microsoft.ML.TimeSeries/IidChangePointDetector.cs index da8749e18e..2b33c640b7 100644 --- a/src/Microsoft.ML.TimeSeries/IidChangePointDetector.cs +++ b/src/Microsoft.ML.TimeSeries/IidChangePointDetector.cs @@ -172,7 +172,7 @@ private IidChangePointDetector(IHostEnvironment env, IidChangePointDetector tran { } - public override void Save(ModelSaveContext ctx) + private protected override void SaveModel(ModelSaveContext ctx) { InternalTransform.Host.CheckValue(ctx, nameof(ctx)); ctx.CheckAtModel(); @@ -184,7 +184,7 @@ public override void Save(ModelSaveContext ctx) // *** Binary format *** // - base.Save(ctx); + base.SaveModel(ctx); } // Factory method for SignatureLoadRowMapper. diff --git a/src/Microsoft.ML.TimeSeries/IidSpikeDetector.cs b/src/Microsoft.ML.TimeSeries/IidSpikeDetector.cs index ce1091ed53..e05e990bc6 100644 --- a/src/Microsoft.ML.TimeSeries/IidSpikeDetector.cs +++ b/src/Microsoft.ML.TimeSeries/IidSpikeDetector.cs @@ -153,7 +153,7 @@ private IidSpikeDetector(IHostEnvironment env, IidSpikeDetector transform) { } - public override void Save(ModelSaveContext ctx) + private protected override void SaveModel(ModelSaveContext ctx) { InternalTransform.Host.CheckValue(ctx, nameof(ctx)); ctx.CheckAtModel(); @@ -164,7 +164,7 @@ public override void Save(ModelSaveContext ctx) // *** Binary format *** // - base.Save(ctx); + base.SaveModel(ctx); } // Factory method for SignatureLoadRowMapper. diff --git a/src/Microsoft.ML.TimeSeries/SequentialAnomalyDetectionTransformBase.cs b/src/Microsoft.ML.TimeSeries/SequentialAnomalyDetectionTransformBase.cs index 5297c088c4..dd7323fde3 100644 --- a/src/Microsoft.ML.TimeSeries/SequentialAnomalyDetectionTransformBase.cs +++ b/src/Microsoft.ML.TimeSeries/SequentialAnomalyDetectionTransformBase.cs @@ -348,7 +348,7 @@ public Func GetDependencies(Func activeOutput) return col => false; } - public void Save(ModelSaveContext ctx) => _parent.SaveModel(ctx); + void ICanSaveModel.Save(ModelSaveContext ctx) => _parent.SaveModel(ctx); public Delegate[] CreateGetters(DataViewRow input, Func activeOutput, out Action disposer) { diff --git a/src/Microsoft.ML.TimeSeries/SequentialTransformerBase.cs b/src/Microsoft.ML.TimeSeries/SequentialTransformerBase.cs index 80824a6895..0626216900 100644 --- a/src/Microsoft.ML.TimeSeries/SequentialTransformerBase.cs +++ b/src/Microsoft.ML.TimeSeries/SequentialTransformerBase.cs @@ -269,7 +269,7 @@ private protected virtual void CloneCore(TState state) internal readonly string OutputColumnName; private protected DataViewType OutputColumnType; - public bool IsRowToRowMapper => false; + bool ITransformer.IsRowToRowMapper => false; internal TState StateRef { get; set; } diff --git a/src/Microsoft.ML.TimeSeries/SsaAnomalyDetectionBase.cs b/src/Microsoft.ML.TimeSeries/SsaAnomalyDetectionBase.cs index 8241602399..704002298d 100644 --- a/src/Microsoft.ML.TimeSeries/SsaAnomalyDetectionBase.cs +++ b/src/Microsoft.ML.TimeSeries/SsaAnomalyDetectionBase.cs @@ -87,10 +87,10 @@ public static Func GetErrorFunction(ErrorFunction errorF public class SsaAnomalyDetectionBaseWrapper : IStatefulTransformer, ICanSaveModel { /// - /// Whether a call to should succeed, on an + /// Whether a call to should succeed, on an /// appropriate schema. /// - public bool IsRowToRowMapper => InternalTransform.IsRowToRowMapper; + bool ITransformer.IsRowToRowMapper => ((ITransformer)InternalTransform).IsRowToRowMapper; /// /// Creates a clone of the transfomer. Used for taking the snapshot of the state. @@ -105,20 +105,22 @@ public class SsaAnomalyDetectionBaseWrapper : IStatefulTransformer, ICanSaveMode public DataViewSchema GetOutputSchema(DataViewSchema inputSchema) => InternalTransform.GetOutputSchema(inputSchema); /// - /// Constructs a row-to-row mapper based on an input schema. If + /// Constructs a row-to-row mapper based on an input schema. If /// is false, then an exception should be thrown. If the input schema is in any way /// unsuitable for constructing the mapper, an exception should likewise be thrown. /// /// The input schema for which we should get the mapper. /// The row to row mapper. - public IRowToRowMapper GetRowToRowMapper(DataViewSchema inputSchema) => InternalTransform.GetRowToRowMapper(inputSchema); + IRowToRowMapper ITransformer.GetRowToRowMapper(DataViewSchema inputSchema) + => ((ITransformer)InternalTransform).GetRowToRowMapper(inputSchema); /// /// Same as but also supports mechanism to save the state. /// /// The input schema for which we should get the mapper. /// The row to row mapper. - public IRowToRowMapper GetStatefulRowToRowMapper(DataViewSchema inputSchema) => ((IStatefulTransformer)InternalTransform).GetStatefulRowToRowMapper(inputSchema); + public IRowToRowMapper GetStatefulRowToRowMapper(DataViewSchema inputSchema) + => ((IStatefulTransformer)InternalTransform).GetStatefulRowToRowMapper(inputSchema); /// /// Take the data in, make transformations, output the data. @@ -129,7 +131,9 @@ public class SsaAnomalyDetectionBaseWrapper : IStatefulTransformer, ICanSaveMode /// /// For saving a model into a repository. /// - public virtual void Save(ModelSaveContext ctx) => InternalTransform.SaveThis(ctx); + void ICanSaveModel.Save(ModelSaveContext ctx) => SaveModel(ctx); + + private protected virtual void SaveModel(ModelSaveContext ctx) => InternalTransform.SaveThis(ctx); /// /// Creates a row mapper from Schema. @@ -255,7 +259,7 @@ public override DataViewSchema GetOutputSchema(DataViewSchema inputSchema) private protected override void SaveModel(ModelSaveContext ctx) { - Parent.Save(ctx); + ((ICanSaveModel)Parent).Save(ctx); } internal void SaveThis(ModelSaveContext ctx) diff --git a/src/Microsoft.ML.TimeSeries/SsaChangePointDetector.cs b/src/Microsoft.ML.TimeSeries/SsaChangePointDetector.cs index 343431db74..ac7dee6bc1 100644 --- a/src/Microsoft.ML.TimeSeries/SsaChangePointDetector.cs +++ b/src/Microsoft.ML.TimeSeries/SsaChangePointDetector.cs @@ -180,7 +180,7 @@ internal SsaChangePointDetector(IHostEnvironment env, ModelLoadContext ctx) InternalTransform.Host.CheckDecode(InternalTransform.IsAdaptive == false); } - public override void Save(ModelSaveContext ctx) + private protected override void SaveModel(ModelSaveContext ctx) { InternalTransform.Host.CheckValue(ctx, nameof(ctx)); ctx.CheckAtModel(); @@ -194,7 +194,7 @@ public override void Save(ModelSaveContext ctx) // *** Binary format *** // - base.Save(ctx); + base.SaveModel(ctx); } // Factory method for SignatureLoadRowMapper. diff --git a/src/Microsoft.ML.TimeSeries/SsaSpikeDetector.cs b/src/Microsoft.ML.TimeSeries/SsaSpikeDetector.cs index a35afcb94d..1b84019385 100644 --- a/src/Microsoft.ML.TimeSeries/SsaSpikeDetector.cs +++ b/src/Microsoft.ML.TimeSeries/SsaSpikeDetector.cs @@ -162,7 +162,7 @@ internal SsaSpikeDetector(IHostEnvironment env, ModelLoadContext ctx) InternalTransform.Host.CheckDecode(InternalTransform.IsAdaptive == false); } - public override void Save(ModelSaveContext ctx) + private protected override void SaveModel(ModelSaveContext ctx) { InternalTransform.Host.CheckValue(ctx, nameof(ctx)); ctx.CheckAtModel(); @@ -175,7 +175,7 @@ public override void Save(ModelSaveContext ctx) // *** Binary format *** // - base.Save(ctx); + base.SaveModel(ctx); } // Factory method for SignatureLoadRowMapper. diff --git a/src/Microsoft.ML.Transforms/CustomMappingTransformer.cs b/src/Microsoft.ML.Transforms/CustomMappingTransformer.cs index b641ebf3e8..2ab2320334 100644 --- a/src/Microsoft.ML.Transforms/CustomMappingTransformer.cs +++ b/src/Microsoft.ML.Transforms/CustomMappingTransformer.cs @@ -30,10 +30,10 @@ public sealed class CustomMappingTransformer : ITransformer internal SchemaDefinition InputSchemaDefinition { get; } /// - /// Whether a call to should succeed, on an + /// Whether a call to should succeed, on an /// appropriate schema. /// - public bool IsRowToRowMapper => true; + bool ITransformer.IsRowToRowMapper => true; /// /// Create a custom mapping of input columns to output columns. @@ -95,11 +95,11 @@ public IDataView Transform(IDataView input) } /// - /// Constructs a row-to-row mapper based on an input schema. If + /// Constructs a row-to-row mapper based on an input schema. If /// is false, then an exception is thrown. If the is in any way /// unsuitable for constructing the mapper, an exception is likewise thrown. /// - public IRowToRowMapper GetRowToRowMapper(DataViewSchema inputSchema) + IRowToRowMapper ITransformer.GetRowToRowMapper(DataViewSchema inputSchema) { _host.CheckValue(inputSchema, nameof(inputSchema)); var simplerMapper = MakeRowMapper(inputSchema); diff --git a/src/Microsoft.ML.Transforms/OneHotEncoding.cs b/src/Microsoft.ML.Transforms/OneHotEncoding.cs index 17b54c27e6..19559d5b33 100644 --- a/src/Microsoft.ML.Transforms/OneHotEncoding.cs +++ b/src/Microsoft.ML.Transforms/OneHotEncoding.cs @@ -166,9 +166,9 @@ internal OneHotEncodingTransformer(ValueToKeyMappingEstimator term, IEstimator (_transformer as ICanSaveModel).Save(ctx); - public bool IsRowToRowMapper => _transformer.IsRowToRowMapper; + bool ITransformer.IsRowToRowMapper => ((ITransformer)_transformer).IsRowToRowMapper; - public IRowToRowMapper GetRowToRowMapper(DataViewSchema inputSchema) => _transformer.GetRowToRowMapper(inputSchema); + IRowToRowMapper ITransformer.GetRowToRowMapper(DataViewSchema inputSchema) => ((ITransformer)_transformer).GetRowToRowMapper(inputSchema); } /// /// Estimator which takes set of columns and produce for each column indicator array. diff --git a/src/Microsoft.ML.Transforms/OneHotHashEncoding.cs b/src/Microsoft.ML.Transforms/OneHotHashEncoding.cs index ee6e7a4ceb..5f2118f388 100644 --- a/src/Microsoft.ML.Transforms/OneHotHashEncoding.cs +++ b/src/Microsoft.ML.Transforms/OneHotHashEncoding.cs @@ -191,14 +191,14 @@ internal OneHotHashEncodingTransformer(HashingEstimator hash, IEstimator (_transformer as ICanSaveModel).Save(ctx); /// - /// Whether a call to should succeed, on an appropriate schema. + /// Whether a call to should succeed, on an appropriate schema. /// - public bool IsRowToRowMapper => _transformer.IsRowToRowMapper; + bool ITransformer.IsRowToRowMapper => ((ITransformer)_transformer).IsRowToRowMapper; /// /// Constructs a row-to-row mapper based on an input schema. /// - public IRowToRowMapper GetRowToRowMapper(DataViewSchema inputSchema) => _transformer.GetRowToRowMapper(inputSchema); + IRowToRowMapper ITransformer.GetRowToRowMapper(DataViewSchema inputSchema) => ((ITransformer)_transformer).GetRowToRowMapper(inputSchema); } /// diff --git a/src/Microsoft.ML.Transforms/Text/TextFeaturizingEstimator.cs b/src/Microsoft.ML.Transforms/Text/TextFeaturizingEstimator.cs index 3f91e73ebf..311a0b5f3a 100644 --- a/src/Microsoft.ML.Transforms/Text/TextFeaturizingEstimator.cs +++ b/src/Microsoft.ML.Transforms/Text/TextFeaturizingEstimator.cs @@ -586,9 +586,9 @@ public IDataView Transform(IDataView input) return ApplyTransformUtils.ApplyAllTransformsToData(_host, _xf, input); } - public bool IsRowToRowMapper => true; + bool ITransformer.IsRowToRowMapper => true; - public IRowToRowMapper GetRowToRowMapper(DataViewSchema inputSchema) + IRowToRowMapper ITransformer.GetRowToRowMapper(DataViewSchema inputSchema) { _host.CheckValue(inputSchema, nameof(inputSchema)); var input = new EmptyDataView(_host, inputSchema); diff --git a/test/Microsoft.ML.Benchmarks/HashBench.cs b/test/Microsoft.ML.Benchmarks/HashBench.cs index 570555dadf..fb36643089 100644 --- a/test/Microsoft.ML.Benchmarks/HashBench.cs +++ b/test/Microsoft.ML.Benchmarks/HashBench.cs @@ -75,7 +75,7 @@ private void InitMap(T val, DataViewType type, int hashBits = 20, ValueGetter // One million features is a nice, typical number. var info = new HashingEstimator.ColumnInfo("Bar", "Foo", hashBits: hashBits); var xf = new HashingTransformer(_env, new[] { info }); - var mapper = xf.GetRowToRowMapper(_inRow.Schema); + var mapper = ((ITransformer)xf).GetRowToRowMapper(_inRow.Schema); var column = mapper.OutputSchema["Bar"]; var outRow = mapper.GetRow(_inRow, c => c == column.Index); if (type is VectorType) diff --git a/test/Microsoft.ML.Tests/Transformers/HashTests.cs b/test/Microsoft.ML.Tests/Transformers/HashTests.cs index 86251d44b5..eac61568a1 100644 --- a/test/Microsoft.ML.Tests/Transformers/HashTests.cs +++ b/test/Microsoft.ML.Tests/Transformers/HashTests.cs @@ -135,7 +135,7 @@ private void HashTestCore(T val, PrimitiveDataViewType type, uint expected, u // First do an unordered hash. var info = new HashingEstimator.ColumnInfo("Bar", "Foo", hashBits: bits); var xf = new HashingTransformer(Env, new[] { info }); - var mapper = xf.GetRowToRowMapper(inRow.Schema); + var mapper = ((ITransformer)xf).GetRowToRowMapper(inRow.Schema); mapper.OutputSchema.TryGetColumnIndex("Bar", out int outCol); var outRow = mapper.GetRow(inRow, c => c == outCol); @@ -147,7 +147,7 @@ private void HashTestCore(T val, PrimitiveDataViewType type, uint expected, u // Next do an ordered hash. info = new HashingEstimator.ColumnInfo("Bar", "Foo", hashBits: bits, ordered: true); xf = new HashingTransformer(Env, new[] { info }); - mapper = xf.GetRowToRowMapper(inRow.Schema); + mapper = ((ITransformer)xf).GetRowToRowMapper(inRow.Schema); mapper.OutputSchema.TryGetColumnIndex("Bar", out outCol); outRow = mapper.GetRow(inRow, c => c == outCol); @@ -165,7 +165,7 @@ private void HashTestCore(T val, PrimitiveDataViewType type, uint expected, u info = new HashingEstimator.ColumnInfo("Bar", "Foo", hashBits: bits, ordered: false); xf = new HashingTransformer(Env, new[] { info }); - mapper = xf.GetRowToRowMapper(inRow.Schema); + mapper = ((ITransformer)xf).GetRowToRowMapper(inRow.Schema); mapper.OutputSchema.TryGetColumnIndex("Bar", out outCol); outRow = mapper.GetRow(inRow, c => c == outCol); @@ -180,7 +180,7 @@ private void HashTestCore(T val, PrimitiveDataViewType type, uint expected, u // Now do ordered with the dense vector. info = new HashingEstimator.ColumnInfo("Bar", "Foo", hashBits: bits, ordered: true); xf = new HashingTransformer(Env, new[] { info }); - mapper = xf.GetRowToRowMapper(inRow.Schema); + mapper = ((ITransformer)xf).GetRowToRowMapper(inRow.Schema); mapper.OutputSchema.TryGetColumnIndex("Bar", out outCol); outRow = mapper.GetRow(inRow, c => c == outCol); vecGetter = outRow.GetGetter>(outCol); @@ -199,7 +199,7 @@ private void HashTestCore(T val, PrimitiveDataViewType type, uint expected, u info = new HashingEstimator.ColumnInfo("Bar", "Foo", hashBits: bits, ordered: false); xf = new HashingTransformer(Env, new[] { info }); - mapper = xf.GetRowToRowMapper(inRow.Schema); + mapper = ((ITransformer)xf).GetRowToRowMapper(inRow.Schema); mapper.OutputSchema.TryGetColumnIndex("Bar", out outCol); outRow = mapper.GetRow(inRow, c => c == outCol); vecGetter = outRow.GetGetter>(outCol); @@ -212,7 +212,7 @@ private void HashTestCore(T val, PrimitiveDataViewType type, uint expected, u info = new HashingEstimator.ColumnInfo("Bar", "Foo", hashBits: bits, ordered: true); xf = new HashingTransformer(Env, new[] { info }); - mapper = xf.GetRowToRowMapper(inRow.Schema); + mapper = ((ITransformer)xf).GetRowToRowMapper(inRow.Schema); mapper.OutputSchema.TryGetColumnIndex("Bar", out outCol); outRow = mapper.GetRow(inRow, c => c == outCol); vecGetter = outRow.GetGetter>(outCol); From 2ef06144bc45f0c90214b3c6b534586fc0248925 Mon Sep 17 00:00:00 2001 From: Wei-Sheng Chin Date: Mon, 25 Feb 2019 13:07:36 -0800 Subject: [PATCH 15/24] Internalize DataKind (#2661) * Hide the uses of DataKind in TypeConverting * Hide DataKind used in TextLoader * Internalize-best-friend DataKind * DataKind ---> InternalDataKind * ScalarType ---> DataKind (massive renaming) * Address comments * Address comments * Address comments * Make R4 as default * Ok. I updated entry point... * Sync with new things from master * Address comments --- .../Dynamic/Calibrator.cs | 4 +- .../Dynamic/FeatureSelectionTransform.cs | 4 +- .../Dynamic/FieldAwareFactorizationMachine.cs | 4 +- .../ImageAnalytics/ConvertToGrayScale.cs | 4 +- .../Dynamic/ImageAnalytics/ExtractPixels.cs | 4 +- .../Dynamic/ImageAnalytics/LoadImages.cs | 4 +- .../Dynamic/ImageAnalytics/ResizeImages.cs | 4 +- .../Dynamic/LogisticRegression.cs | 30 +-- .../Dynamic/TensorFlow/TextClassification.cs | 4 +- .../SDCALogisticRegression.cs | 4 +- .../Dynamic/Trainers/PriorTrainerSample.cs | 4 +- .../Dynamic/Trainers/RandomTrainerSample.cs | 4 +- .../Regression/OrdinaryLeastSquares.cs | 4 +- .../OrdinaryLeastSquaresWithOptions.cs | 4 +- .../Data/ColumnTypeExtensions.cs | 48 ++-- src/Microsoft.ML.Core/Data/DataKind.cs | 241 +++++++++++------- src/Microsoft.ML.Core/Data/KeyType.cs | 2 +- .../Commands/TypeInfoCommand.cs | 24 +- .../DataLoadSave/Text/TextLoader.cs | 80 ++++-- .../DataLoadSave/Text/TextLoaderParser.cs | 14 +- .../DataLoadSave/Text/TextSaver.cs | 2 +- .../DataView/ArrayDataViewBuilder.cs | 2 +- .../ConversionsExtensionsCatalog.cs | 2 +- .../Transforms/Normalizer.cs | 8 +- .../Transforms/TypeConverting.cs | 44 ++-- .../Transforms/ValueMapping.cs | 16 +- .../ValueToKeyMappingTransformer.cs | 2 +- .../Utilities/TypeParsingUtils.cs | 8 +- .../FeatureCombiner.cs | 4 +- src/Microsoft.ML.FastTree/FastTree.cs | 2 +- src/Microsoft.ML.OnnxTransformer/OnnxUtils.cs | 24 +- .../PartitionedFileLoader.cs | 8 +- .../PartitionedPathParser.cs | 4 +- .../RecommenderUtils.cs | 2 +- .../SamplesDatasetUtils.cs | 55 ++-- .../ConvertStaticExtensions.cs | 66 ++--- .../StaticSchemaShape.cs | 2 +- .../TextLoaderStatic.cs | 36 +-- .../TransformsStatic.cs | 16 +- .../MissingValueHandlingTransformer.cs | 4 +- .../Text/StopWordsRemovingTransformer.cs | 2 +- .../Common/EntryPoints/core_manifest.json | 4 +- .../EntryPoints/ensemble-model0-stats.txt | 4 +- .../EntryPoints/ensemble-model2-stats.txt | 4 +- .../Common/EntryPoints/lr-stats.txt | 4 +- .../Common/EntryPoints/mc-lr-stats.txt | 4 +- test/BaselineOutput/Common/Text/ngrams.tsv | 4 +- .../KMeansAndLogisticRegressionBench.cs | 6 +- .../PredictionEngineBench.cs | 22 +- test/Microsoft.ML.Benchmarks/RffTransform.cs | 4 +- ...sticDualCoordinateAscentClassifierBench.cs | 35 +-- .../UnitTests/CoreBaseTestClass.cs | 64 ++--- .../UnitTests/TestEntryPoints.cs | 34 +-- .../UnitTests/TestHosts.cs | 3 +- test/Microsoft.ML.Functional.Tests/Common.cs | 1 - .../Datasets/MnistOneClass.cs | 4 +- .../Datasets/TypeTestData.cs | 39 ++- .../TestIniModels.cs | 14 +- test/Microsoft.ML.TestFramework/Datasets.cs | 38 +-- .../AnomalyDetectionTests.cs | 12 +- test/Microsoft.ML.Tests/FakeSchemaTest.cs | 2 +- test/Microsoft.ML.Tests/ImagesTests.cs | 58 ++--- .../CookbookSamplesDynamicApi.cs | 16 +- .../Scenarios/Api/TestApi.cs | 8 +- .../Scenarios/IrisPlantClassificationTests.cs | 10 +- ...PlantClassificationWithStringLabelTests.cs | 10 +- test/Microsoft.ML.Tests/Scenarios/OvaTest.cs | 16 +- .../Scenarios/TensorflowTests.cs | 4 +- .../IrisPlantClassificationTests.cs | 10 +- .../TensorflowTests.cs | 42 ++- test/Microsoft.ML.Tests/TermEstimatorTests.cs | 15 +- .../TrainerEstimators/FAFMEstimator.cs | 11 +- .../MatrixFactorizationTests.cs | 6 +- .../TrainerEstimators/PriorRandomTests.cs | 9 +- .../TrainerEstimators/TrainerEstimators.cs | 28 +- .../Transformers/ConcatTests.cs | 16 +- .../Transformers/ConvertTests.cs | 36 +-- .../Transformers/CustomMappingTests.cs | 10 +- .../Transformers/KeyToValueTests.cs | 12 +- .../Transformers/NormalizerTests.cs | 28 +- .../Transformers/TextFeaturizerTests.cs | 2 +- .../Transformers/WordEmbeddingsTests.cs | 9 +- 82 files changed, 748 insertions(+), 710 deletions(-) diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Calibrator.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Calibrator.cs index dc52d0eed4..44ddbd671c 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Calibrator.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Calibrator.cs @@ -34,8 +34,8 @@ public static void Example() HasHeader = true, Columns = new[] { - new TextLoader.Column("Sentiment", DataKind.BL, 0), - new TextLoader.Column("SentimentText", DataKind.Text, 1) + new TextLoader.Column("Sentiment", DataKind.Boolean, 0), + new TextLoader.Column("SentimentText", DataKind.String, 1) } }); diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/FeatureSelectionTransform.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/FeatureSelectionTransform.cs index 294b12f609..f9023b524e 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/FeatureSelectionTransform.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/FeatureSelectionTransform.cs @@ -33,8 +33,8 @@ public static void Example() var reader = ml.Data.CreateTextLoader( columns: new[] { - new TextLoader.Column("Label", DataKind.BL, 0), - new TextLoader.Column("Features", DataKind.Num, new [] { new TextLoader.Range(1, 9) }) + new TextLoader.Column("Label", DataKind.Boolean, 0), + new TextLoader.Column("Features", DataKind.Single, new [] { new TextLoader.Range(1, 9) }) }, hasHeader: true ); diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/FieldAwareFactorizationMachine.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/FieldAwareFactorizationMachine.cs index e9c54e2572..678796d54e 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/FieldAwareFactorizationMachine.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/FieldAwareFactorizationMachine.cs @@ -25,8 +25,8 @@ public static void Example() var reader = mlContext.Data.CreateTextLoader( columns: new[] { - new TextLoader.Column("Sentiment", DataKind.BL, 0), - new TextLoader.Column("SentimentText", DataKind.Text, 1) + new TextLoader.Column("Sentiment", DataKind.Boolean, 0), + new TextLoader.Column("SentimentText", DataKind.String, 1) }, hasHeader: true ); diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/ImageAnalytics/ConvertToGrayScale.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/ImageAnalytics/ConvertToGrayScale.cs index b168575290..3f67cbe84f 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/ImageAnalytics/ConvertToGrayScale.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/ImageAnalytics/ConvertToGrayScale.cs @@ -27,8 +27,8 @@ public static void Example() { Columns = new[] { - new TextLoader.Column("ImagePath", DataKind.TX, 0), - new TextLoader.Column("Name", DataKind.TX, 1), + new TextLoader.Column("ImagePath", DataKind.String, 0), + new TextLoader.Column("Name", DataKind.String, 1), } }).Read(imagesDataFile); diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/ImageAnalytics/ExtractPixels.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/ImageAnalytics/ExtractPixels.cs index eb7e164004..d24539a5da 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/ImageAnalytics/ExtractPixels.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/ImageAnalytics/ExtractPixels.cs @@ -28,8 +28,8 @@ public static void Example() { Columns = new[] { - new TextLoader.Column("ImagePath", DataKind.TX, 0), - new TextLoader.Column("Name", DataKind.TX, 1), + new TextLoader.Column("ImagePath", DataKind.String, 0), + new TextLoader.Column("Name", DataKind.String, 1), } }).Read(imagesDataFile); diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/ImageAnalytics/LoadImages.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/ImageAnalytics/LoadImages.cs index 541f564283..c2b1cca9c1 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/ImageAnalytics/LoadImages.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/ImageAnalytics/LoadImages.cs @@ -27,8 +27,8 @@ public static void Example() { Columns = new[] { - new TextLoader.Column("ImagePath", DataKind.TX, 0), - new TextLoader.Column("Name", DataKind.TX, 1), + new TextLoader.Column("ImagePath", DataKind.String, 0), + new TextLoader.Column("Name", DataKind.String, 1), } }).Read(imagesDataFile); diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/ImageAnalytics/ResizeImages.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/ImageAnalytics/ResizeImages.cs index 03ada5304e..2d15396dc6 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/ImageAnalytics/ResizeImages.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/ImageAnalytics/ResizeImages.cs @@ -27,8 +27,8 @@ public static void Example() { Columns = new[] { - new TextLoader.Column("ImagePath", DataKind.TX, 0), - new TextLoader.Column("Name", DataKind.TX, 1), + new TextLoader.Column("ImagePath", DataKind.String, 0), + new TextLoader.Column("Name", DataKind.String, 1), } }).Read(imagesDataFile); diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/LogisticRegression.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/LogisticRegression.cs index 1a6aacfe33..f0c9d574a7 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/LogisticRegression.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/LogisticRegression.cs @@ -37,21 +37,21 @@ public static void Example() HasHeader = true, Columns = new[] { - new TextLoader.Column("age", DataKind.R4, 0), - new TextLoader.Column("workclass", DataKind.Text, 1), - new TextLoader.Column("fnlwgt", DataKind.R4, 2), - new TextLoader.Column("education", DataKind.Text, 3), - new TextLoader.Column("education-num", DataKind.R4, 4), - new TextLoader.Column("marital-status", DataKind.Text, 5), - new TextLoader.Column("occupation", DataKind.Text, 6), - new TextLoader.Column("relationship", DataKind.Text, 7), - new TextLoader.Column("ethnicity", DataKind.Text, 8), - new TextLoader.Column("sex", DataKind.Text, 9), - new TextLoader.Column("capital-gain", DataKind.R4, 10), - new TextLoader.Column("capital-loss", DataKind.R4, 11), - new TextLoader.Column("hours-per-week", DataKind.R4, 12), - new TextLoader.Column("native-country", DataKind.Text, 13), - new TextLoader.Column("Label", DataKind.Bool, 14) + new TextLoader.Column("age", DataKind.Single, 0), + new TextLoader.Column("workclass", DataKind.String, 1), + new TextLoader.Column("fnlwgt", DataKind.Single, 2), + new TextLoader.Column("education", DataKind.String, 3), + new TextLoader.Column("education-num", DataKind.Single, 4), + new TextLoader.Column("marital-status", DataKind.String, 5), + new TextLoader.Column("occupation", DataKind.String, 6), + new TextLoader.Column("relationship", DataKind.String, 7), + new TextLoader.Column("ethnicity", DataKind.String, 8), + new TextLoader.Column("sex", DataKind.String, 9), + new TextLoader.Column("capital-gain", DataKind.Single, 10), + new TextLoader.Column("capital-loss", DataKind.Single, 11), + new TextLoader.Column("hours-per-week", DataKind.Single, 12), + new TextLoader.Column("native-country", DataKind.String, 13), + new TextLoader.Column("Label", DataKind.Boolean, 14) } }); diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/TensorFlow/TextClassification.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/TensorFlow/TextClassification.cs index 562cadbf1e..8ced00d6ec 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/TensorFlow/TextClassification.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/TensorFlow/TextClassification.cs @@ -36,8 +36,8 @@ public static void Example() var lookupMap = mlContext.Data.ReadFromTextFile(Path.Combine(modelLocation, "imdb_word_index.csv"), columns: new[] { - new TextLoader.Column("Words", DataKind.TX, 0), - new TextLoader.Column("Ids", DataKind.I4, 1), + new TextLoader.Column("Words", DataKind.String, 0), + new TextLoader.Column("Ids", DataKind.Int32, 1), }, separatorChar: ',' ); diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/SDCALogisticRegression.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/SDCALogisticRegression.cs index 979976cc01..44a7a77534 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/SDCALogisticRegression.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/SDCALogisticRegression.cs @@ -28,8 +28,8 @@ public static void Example() var reader = mlContext.Data.CreateTextLoader( columns: new[] { - new TextLoader.Column("Sentiment", DataKind.BL, 0), - new TextLoader.Column("SentimentText", DataKind.Text, 1) + new TextLoader.Column("Sentiment", DataKind.Boolean, 0), + new TextLoader.Column("SentimentText", DataKind.String, 1) }, hasHeader: true ); diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/PriorTrainerSample.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/PriorTrainerSample.cs index 55aa9793c5..142ad64362 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/PriorTrainerSample.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/PriorTrainerSample.cs @@ -26,8 +26,8 @@ public static void Example() var reader = mlContext.Data.CreateTextLoader( columns: new[] { - new TextLoader.Column("Sentiment", DataKind.R4, 0), - new TextLoader.Column("SentimentText", DataKind.Text, 1) + new TextLoader.Column("Sentiment", DataKind.Single, 0), + new TextLoader.Column("SentimentText", DataKind.String, 1) }, hasHeader: true ); diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/RandomTrainerSample.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/RandomTrainerSample.cs index ce68f88950..a58b5cf100 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/RandomTrainerSample.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/RandomTrainerSample.cs @@ -26,8 +26,8 @@ public static void Example() var reader = mlContext.Data.CreateTextLoader( columns: new[] { - new TextLoader.Column("Sentiment", DataKind.R4, 0), - new TextLoader.Column("SentimentText", DataKind.Text, 1) + new TextLoader.Column("Sentiment", DataKind.Single, 0), + new TextLoader.Column("SentimentText", DataKind.String, 1) }, hasHeader: true ); diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Regression/OrdinaryLeastSquares.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Regression/OrdinaryLeastSquares.cs index 3a8a17952b..003962c5bc 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Regression/OrdinaryLeastSquares.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Regression/OrdinaryLeastSquares.cs @@ -28,8 +28,8 @@ public static void Example() HasHeader = true, Columns = new[] { - new TextLoader.Column("Label", DataKind.R4, 0), - new TextLoader.Column("Features", DataKind.R4, 1, 6) + new TextLoader.Column("Label", DataKind.Single, 0), + new TextLoader.Column("Features", DataKind.Single, 1, 6) } }); diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Regression/OrdinaryLeastSquaresWithOptions.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Regression/OrdinaryLeastSquaresWithOptions.cs index 519a9ef683..21a6a9e1ae 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Regression/OrdinaryLeastSquaresWithOptions.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Regression/OrdinaryLeastSquaresWithOptions.cs @@ -29,8 +29,8 @@ public static void Example() HasHeader = true, Columns = new[] { - new TextLoader.Column("Label", DataKind.R4, 0), - new TextLoader.Column("Features", DataKind.R4, 1, 6) + new TextLoader.Column("Label", DataKind.Single, 0), + new TextLoader.Column("Features", DataKind.Single, 1, 6) } }); diff --git a/src/Microsoft.ML.Core/Data/ColumnTypeExtensions.cs b/src/Microsoft.ML.Core/Data/ColumnTypeExtensions.cs index df1a76f3d7..1213561385 100644 --- a/src/Microsoft.ML.Core/Data/ColumnTypeExtensions.cs +++ b/src/Microsoft.ML.Core/Data/ColumnTypeExtensions.cs @@ -61,13 +61,13 @@ public static int GetKeyCountAsInt32(this DataViewType columnType, IExceptionCon public static bool IsKnownSizeVector(this DataViewType columnType) => columnType.GetVectorSize() > 0; /// - /// Gets the equivalent for the 's RawType. - /// This can return default() if the RawType doesn't have a corresponding - /// . + /// Gets the equivalent for the 's RawType. + /// This can return default() if the RawType doesn't have a corresponding + /// . /// - public static DataKind GetRawKind(this DataViewType columnType) + public static InternalDataKind GetRawKind(this DataViewType columnType) { - columnType.RawType.TryGetDataKind(out DataKind result); + columnType.RawType.TryGetDataKind(out InternalDataKind result); return result; } @@ -106,24 +106,24 @@ public static PrimitiveDataViewType PrimitiveTypeFromType(Type type) return NumberTypeFromType(type); } - public static PrimitiveDataViewType PrimitiveTypeFromKind(DataKind kind) + public static PrimitiveDataViewType PrimitiveTypeFromKind(InternalDataKind kind) { - if (kind == DataKind.TX) + if (kind == InternalDataKind.TX) return TextDataViewType.Instance; - if (kind == DataKind.BL) + if (kind == InternalDataKind.BL) return BooleanDataViewType.Instance; - if (kind == DataKind.TS) + if (kind == InternalDataKind.TS) return TimeSpanDataViewType.Instance; - if (kind == DataKind.DT) + if (kind == InternalDataKind.DT) return DateTimeDataViewType.Instance; - if (kind == DataKind.DZ) + if (kind == InternalDataKind.DZ) return DateTimeOffsetDataViewType.Instance; return NumberTypeFromKind(kind); } public static NumberDataViewType NumberTypeFromType(Type type) { - DataKind kind; + InternalDataKind kind; if (type.TryGetDataKind(out kind)) return NumberTypeFromKind(kind); @@ -131,31 +131,31 @@ public static NumberDataViewType NumberTypeFromType(Type type) throw new InvalidOperationException($"Bad type in {nameof(ColumnTypeExtensions)}.{nameof(NumberTypeFromType)}: {type}"); } - public static NumberDataViewType NumberTypeFromKind(DataKind kind) + public static NumberDataViewType NumberTypeFromKind(InternalDataKind kind) { switch (kind) { - case DataKind.I1: + case InternalDataKind.I1: return NumberDataViewType.SByte; - case DataKind.U1: + case InternalDataKind.U1: return NumberDataViewType.Byte; - case DataKind.I2: + case InternalDataKind.I2: return NumberDataViewType.Int16; - case DataKind.U2: + case InternalDataKind.U2: return NumberDataViewType.UInt16; - case DataKind.I4: + case InternalDataKind.I4: return NumberDataViewType.Int32; - case DataKind.U4: + case InternalDataKind.U4: return NumberDataViewType.UInt32; - case DataKind.I8: + case InternalDataKind.I8: return NumberDataViewType.Int64; - case DataKind.U8: + case InternalDataKind.U8: return NumberDataViewType.UInt64; - case DataKind.R4: + case InternalDataKind.R4: return NumberDataViewType.Single; - case DataKind.R8: + case InternalDataKind.R8: return NumberDataViewType.Double; - case DataKind.UG: + case InternalDataKind.UG: return NumberDataViewType.DataViewRowId; } diff --git a/src/Microsoft.ML.Core/Data/DataKind.cs b/src/Microsoft.ML.Core/Data/DataKind.cs index b65610bacf..7830ee744a 100644 --- a/src/Microsoft.ML.Core/Data/DataKind.cs +++ b/src/Microsoft.ML.Core/Data/DataKind.cs @@ -8,40 +8,80 @@ namespace Microsoft.ML.Data { /// - /// Data type specifier. + /// Specifies a simple data type. /// + // Data type specifiers mainly used in creating text loader and type converter. public enum DataKind : byte + { + /// 1-byte integer, type of . + SByte = 1, + /// 1-byte unsigned integer, type of . + Byte = 2, + /// 2-byte integer, type of . + Int16 = 3, + /// 2-byte usigned integer, type of . + UInt16 = 4, + /// 4-byte integer, type of . + Int32 = 5, + /// 4-byte usigned integer, type of . + UInt32 = 6, + /// 8-byte integer, type of . + Int64 = 7, + /// 8-byte usigned integer, type of . + UInt64 = 8, + /// 4-byte floating-point number, type of . + Single = 9, + /// 8-byte floating-point number, type of . + Double = 10, + /// string, type of . + String = 11, + /// boolean variable type, type of . + Boolean = 12, + /// type of . + TimeSpan = 13, + /// type of . + DateTime = 14, + /// type of . + DateTimeOffset = 15, + } + + /// + /// Data type specifier used in command line. is the underlying version of + /// used for command line and entry point BC. + /// + [BestFriend] + internal enum InternalDataKind : byte { // Notes: // * These values are serialized, so changing them breaks binary formats. // * We intentionally skip zero. // * Some code depends on sizeof(DataKind) == sizeof(byte). - I1 = 1, - U1 = 2, - I2 = 3, - U2 = 4, - I4 = 5, - U4 = 6, - I8 = 7, - U8 = 8, - R4 = 9, - R8 = 10, + I1 = DataKind.SByte, + U1 = DataKind.Byte, + I2 = DataKind.Int16, + U2 = DataKind.UInt16, + I4 = DataKind.Int32, + U4 = DataKind.UInt32, + I8 = DataKind.Int64, + U8 = DataKind.UInt64, + R4 = DataKind.Single, + R8 = DataKind.Double, Num = R4, - TX = 11, + TX = DataKind.String, #pragma warning disable MSML_GeneralName // The data kind enum has its own logic, independent of C# naming conventions. TXT = TX, Text = TX, - BL = 12, + BL = DataKind.Boolean, Bool = BL, - TS = 13, + TS = DataKind.TimeSpan, TimeSpan = TS, - DT = 14, + DT = DataKind.DateTime, DateTime = DT, - DZ = 15, + DZ = DataKind.DateTimeOffset, DateTimeZone = DZ, UG = 16, // Unsigned 16-byte integer. @@ -53,16 +93,16 @@ public enum DataKind : byte /// Extension methods related to the DataKind enum. /// [BestFriend] - internal static class DataKindExtensions + internal static class InternalDataKindExtensions { - public const DataKind KindMin = DataKind.I1; - public const DataKind KindLim = DataKind.U16 + 1; + public const InternalDataKind KindMin = InternalDataKind.I1; + public const InternalDataKind KindLim = InternalDataKind.U16 + 1; public const int KindCount = KindLim - KindMin; /// /// Maps a DataKind to a value suitable for indexing into an array of size KindCount. /// - public static int ToIndex(this DataKind kind) + public static int ToIndex(this InternalDataKind kind) { return kind - KindMin; } @@ -70,35 +110,52 @@ public static int ToIndex(this DataKind kind) /// /// Maps from an index into an array of size KindCount to the corresponding DataKind /// - public static DataKind FromIndex(int index) + public static InternalDataKind FromIndex(int index) { Contracts.Check(0 <= index && index < KindCount); - return (DataKind)(index + (int)KindMin); + return (InternalDataKind)(index + (int)KindMin); + } + + /// + /// This function converts to . + /// Because is a subset of , the conversion is straightforward. + /// + public static InternalDataKind ToInternalDataKind(this DataKind dataKind) => (InternalDataKind)dataKind; + + /// + /// This function converts to . + /// Because is a subset of , we should check if + /// can be found in . + /// + public static DataKind ToDataKind(this InternalDataKind kind) + { + Contracts.Check(kind != InternalDataKind.UG); + return (DataKind)kind; } /// /// For integer DataKinds, this returns the maximum legal value. For un-supported kinds, /// it returns zero. /// - public static ulong ToMaxInt(this DataKind kind) + public static ulong ToMaxInt(this InternalDataKind kind) { switch (kind) { - case DataKind.I1: + case InternalDataKind.I1: return (ulong)sbyte.MaxValue; - case DataKind.U1: + case InternalDataKind.U1: return byte.MaxValue; - case DataKind.I2: + case InternalDataKind.I2: return (ulong)short.MaxValue; - case DataKind.U2: + case InternalDataKind.U2: return ushort.MaxValue; - case DataKind.I4: + case InternalDataKind.I4: return int.MaxValue; - case DataKind.U4: + case InternalDataKind.U4: return uint.MaxValue; - case DataKind.I8: + case InternalDataKind.I8: return long.MaxValue; - case DataKind.U8: + case InternalDataKind.U8: return ulong.MaxValue; } @@ -135,25 +192,25 @@ public static ulong ToMaxInt(this Type type) /// For integer DataKinds, this returns the minimum legal value. For un-supported kinds, /// it returns one. /// - public static long ToMinInt(this DataKind kind) + public static long ToMinInt(this InternalDataKind kind) { switch (kind) { - case DataKind.I1: + case InternalDataKind.I1: return sbyte.MinValue; - case DataKind.U1: + case InternalDataKind.U1: return byte.MinValue; - case DataKind.I2: + case InternalDataKind.I2: return short.MinValue; - case DataKind.U2: + case InternalDataKind.U2: return ushort.MinValue; - case DataKind.I4: + case InternalDataKind.I4: return int.MinValue; - case DataKind.U4: + case InternalDataKind.U4: return uint.MinValue; - case DataKind.I8: + case InternalDataKind.I8: return long.MinValue; - case DataKind.U8: + case InternalDataKind.U8: return 0; } @@ -163,41 +220,41 @@ public static long ToMinInt(this DataKind kind) /// /// Maps a DataKind to the associated .Net representation type. /// - public static Type ToType(this DataKind kind) + public static Type ToType(this InternalDataKind kind) { switch (kind) { - case DataKind.I1: + case InternalDataKind.I1: return typeof(sbyte); - case DataKind.U1: + case InternalDataKind.U1: return typeof(byte); - case DataKind.I2: + case InternalDataKind.I2: return typeof(short); - case DataKind.U2: + case InternalDataKind.U2: return typeof(ushort); - case DataKind.I4: + case InternalDataKind.I4: return typeof(int); - case DataKind.U4: + case InternalDataKind.U4: return typeof(uint); - case DataKind.I8: + case InternalDataKind.I8: return typeof(long); - case DataKind.U8: + case InternalDataKind.U8: return typeof(ulong); - case DataKind.R4: + case InternalDataKind.R4: return typeof(Single); - case DataKind.R8: + case InternalDataKind.R8: return typeof(Double); - case DataKind.TX: + case InternalDataKind.TX: return typeof(ReadOnlyMemory); - case DataKind.BL: + case InternalDataKind.BL: return typeof(bool); - case DataKind.TS: + case InternalDataKind.TS: return typeof(TimeSpan); - case DataKind.DT: + case InternalDataKind.DT: return typeof(DateTime); - case DataKind.DZ: + case InternalDataKind.DZ: return typeof(DateTimeOffset); - case DataKind.UG: + case InternalDataKind.UG: return typeof(DataViewRowId); } @@ -207,46 +264,46 @@ public static Type ToType(this DataKind kind) /// /// Try to map a System.Type to a corresponding DataKind value. /// - public static bool TryGetDataKind(this Type type, out DataKind kind) + public static bool TryGetDataKind(this Type type, out InternalDataKind kind) { Contracts.CheckValueOrNull(type); // REVIEW: Make this more efficient. Should we have a global dictionary? if (type == typeof(sbyte)) - kind = DataKind.I1; + kind = InternalDataKind.I1; else if (type == typeof(byte)) - kind = DataKind.U1; + kind = InternalDataKind.U1; else if (type == typeof(short)) - kind = DataKind.I2; + kind = InternalDataKind.I2; else if (type == typeof(ushort)) - kind = DataKind.U2; + kind = InternalDataKind.U2; else if (type == typeof(int)) - kind = DataKind.I4; + kind = InternalDataKind.I4; else if (type == typeof(uint)) - kind = DataKind.U4; + kind = InternalDataKind.U4; else if (type == typeof(long)) - kind = DataKind.I8; + kind = InternalDataKind.I8; else if (type == typeof(ulong)) - kind = DataKind.U8; + kind = InternalDataKind.U8; else if (type == typeof(Single)) - kind = DataKind.R4; + kind = InternalDataKind.R4; else if (type == typeof(Double)) - kind = DataKind.R8; + kind = InternalDataKind.R8; else if (type == typeof(ReadOnlyMemory) || type == typeof(string)) - kind = DataKind.TX; + kind = InternalDataKind.TX; else if (type == typeof(bool)) - kind = DataKind.BL; + kind = InternalDataKind.BL; else if (type == typeof(TimeSpan)) - kind = DataKind.TS; + kind = InternalDataKind.TS; else if (type == typeof(DateTime)) - kind = DataKind.DT; + kind = InternalDataKind.DT; else if (type == typeof(DateTimeOffset)) - kind = DataKind.DZ; + kind = InternalDataKind.DZ; else if (type == typeof(DataViewRowId)) - kind = DataKind.UG; + kind = InternalDataKind.UG; else { - kind = default(DataKind); + kind = default(InternalDataKind); return false; } @@ -257,41 +314,41 @@ public static bool TryGetDataKind(this Type type, out DataKind kind) /// Get the canonical string for a DataKind. Note that using DataKind.ToString() is not stable /// and is also slow, so use this instead. /// - public static string GetString(this DataKind kind) + public static string GetString(this InternalDataKind kind) { switch (kind) { - case DataKind.I1: + case InternalDataKind.I1: return "I1"; - case DataKind.I2: + case InternalDataKind.I2: return "I2"; - case DataKind.I4: + case InternalDataKind.I4: return "I4"; - case DataKind.I8: + case InternalDataKind.I8: return "I8"; - case DataKind.U1: + case InternalDataKind.U1: return "U1"; - case DataKind.U2: + case InternalDataKind.U2: return "U2"; - case DataKind.U4: + case InternalDataKind.U4: return "U4"; - case DataKind.U8: + case InternalDataKind.U8: return "U8"; - case DataKind.R4: + case InternalDataKind.R4: return "R4"; - case DataKind.R8: + case InternalDataKind.R8: return "R8"; - case DataKind.BL: + case InternalDataKind.BL: return "BL"; - case DataKind.TX: + case InternalDataKind.TX: return "TX"; - case DataKind.TS: + case InternalDataKind.TS: return "TS"; - case DataKind.DT: + case InternalDataKind.DT: return "DT"; - case DataKind.DZ: + case InternalDataKind.DZ: return "DZ"; - case DataKind.UG: + case InternalDataKind.UG: return "UG"; } return ""; diff --git a/src/Microsoft.ML.Core/Data/KeyType.cs b/src/Microsoft.ML.Core/Data/KeyType.cs index 9671b1e205..877d2900fc 100644 --- a/src/Microsoft.ML.Core/Data/KeyType.cs +++ b/src/Microsoft.ML.Core/Data/KeyType.cs @@ -85,7 +85,7 @@ public override int GetHashCode() public override string ToString() { - DataKind rawKind = this.GetRawKind(); + InternalDataKind rawKind = this.GetRawKind(); return string.Format("Key<{0}, {1}-{2}>", rawKind.GetString(), 0, Count - 1); } } diff --git a/src/Microsoft.ML.Data/Commands/TypeInfoCommand.cs b/src/Microsoft.ML.Data/Commands/TypeInfoCommand.cs index ae3364b3b4..5c22104cce 100644 --- a/src/Microsoft.ML.Data/Commands/TypeInfoCommand.cs +++ b/src/Microsoft.ML.Data/Commands/TypeInfoCommand.cs @@ -48,9 +48,9 @@ public TypeNaInfo(bool hasNa, bool defaultIsNa) } } - private sealed class SetOfKindsComparer : IEqualityComparer> + private sealed class SetOfKindsComparer : IEqualityComparer> { - public bool Equals(ISet x, ISet y) + public bool Equals(ISet x, ISet y) { Contracts.AssertValueOrNull(x); Contracts.AssertValueOrNull(y); @@ -59,7 +59,7 @@ public bool Equals(ISet x, ISet y) return x.SetEquals(y); } - public int GetHashCode(ISet obj) + public int GetHashCode(ISet obj) { Contracts.AssertValueOrNull(obj); int hash = 0; @@ -78,20 +78,20 @@ public void Run() { var conv = Conversions.Instance; var comp = new SetOfKindsComparer(); - var dstToSrcMap = new Dictionary, HashSet>(comp); - var srcToDstMap = new Dictionary>(); + var dstToSrcMap = new Dictionary, HashSet>(comp); + var srcToDstMap = new Dictionary>(); - var kinds = Enum.GetValues(typeof(DataKind)).Cast().Distinct().OrderBy(k => k).ToArray(); + var kinds = Enum.GetValues(typeof(InternalDataKind)).Cast().Distinct().OrderBy(k => k).ToArray(); var types = kinds.Select(kind => ColumnTypeExtensions.PrimitiveTypeFromKind(kind)).ToArray(); - HashSet nonIdentity = null; + HashSet nonIdentity = null; // For each kind and its associated type. for (int i = 0; i < types.Length; ++i) { ch.AssertValue(types[i]); var info = Utils.MarshalInvoke(KindReport, types[i].RawType, ch, types[i]); - var dstKinds = new HashSet(); + var dstKinds = new HashSet(); Delegate del; bool isIdentity; for (int j = 0; j < types.Length; ++j) @@ -105,9 +105,9 @@ public void Run() ch.Assert(isIdentity); srcToDstMap[types[i].GetRawKind()] = dstKinds; - HashSet srcKinds; + HashSet srcKinds; if (!dstToSrcMap.TryGetValue(dstKinds, out srcKinds)) - dstToSrcMap[dstKinds] = srcKinds = new HashSet(); + dstToSrcMap[dstKinds] = srcKinds = new HashSet(); srcKinds.Add(types[i].GetRawKind()); } @@ -115,7 +115,7 @@ public void Run() for (int i = 0; i < kinds.Length; ++i) { var dsts = srcToDstMap[kinds[i]]; - HashSet srcs; + HashSet srcs; if (!dstToSrcMap.TryGetValue(dsts, out srcs)) continue; ch.Assert(Utils.Size(dsts) >= 1); @@ -129,7 +129,7 @@ public void Run() if (Utils.Size(nonIdentity) > 0) { ch.Warning("The following kinds did not have an identity conversion: {0}", - string.Join(", ", nonIdentity.OrderBy(k => k).Select(DataKindExtensions.GetString))); + string.Join(", ", nonIdentity.OrderBy(k => k).Select(InternalDataKindExtensions.GetString))); } } } diff --git a/src/Microsoft.ML.Data/DataLoadSave/Text/TextLoader.cs b/src/Microsoft.ML.Data/DataLoadSave/Text/TextLoader.cs index f6e84a70c1..23183aab9b 100644 --- a/src/Microsoft.ML.Data/DataLoadSave/Text/TextLoader.cs +++ b/src/Microsoft.ML.Data/DataLoadSave/Text/TextLoader.cs @@ -49,20 +49,34 @@ public Column() { } /// Describes how an input column should be mapped to an column. /// /// Name of the column. - /// of the items in the column. If defaults to a float. + /// of the items in the column. /// Index of the column. - public Column(string name, DataKind? type, int index) - : this(name, type, new[] { new Range(index) }) { } + public Column(string name, DataKind dataKind, int index) + : this(name, dataKind.ToInternalDataKind(), new[] { new Range(index) }) + { + } /// /// Describes how an input column should be mapped to an column. /// /// Name of the column. - /// of the items in the column. If defaults to a float. + /// of the items in the column. /// The minimum inclusive index of the column. /// The maximum-inclusive index of the column. - public Column(string name, DataKind? type, int minIndex, int maxIndex) - : this(name, type, new[] { new Range(minIndex, maxIndex) }) + public Column(string name, DataKind dataKind, int minIndex, int maxIndex) + : this(name, dataKind.ToInternalDataKind(), new[] { new Range(minIndex, maxIndex) }) + { + } + + /// + /// Describes how an input column should be mapped to an column. + /// + /// Name of the column. + /// of the items in the column. + /// Source index range(s) of the column. + /// For a key column, this defines the range of values. + public Column(string name, DataKind dataKind, Range[] source, KeyCount keyCount = null) + : this(name, dataKind.ToInternalDataKind(), source, keyCount) { } @@ -70,16 +84,16 @@ public Column(string name, DataKind? type, int minIndex, int maxIndex) /// Describes how an input column should be mapped to an column. /// /// Name of the column. - /// of the items in the column. If defaults to a float. + /// of the items in the column. /// Source index range(s) of the column. /// For a key column, this defines the range of values. - public Column(string name, DataKind? type, Range[] source, KeyCount keyCount = null) + private Column(string name, InternalDataKind kind, Range[] source, KeyCount keyCount = null) { Contracts.CheckValue(name, nameof(name)); Contracts.CheckValue(source, nameof(source)); Name = name; - Type = type; + Type = kind; Source = source; KeyCount = keyCount; } @@ -91,10 +105,22 @@ public Column(string name, DataKind? type, Range[] source, KeyCount keyCount = n public string Name; /// - /// of the items in the column. If defaults to a float. + /// of the items in the column. It defaults to float. + /// Although is internal, 's information can be publically accessed by . /// [Argument(ArgumentType.AtMostOnce, HelpText = "Type of the items in the column")] - public DataKind? Type; + [BestFriend] + internal InternalDataKind Type = InternalDataKind.R4; + + /// + /// of the items in the column. + /// + /// It's a public interface to access the information in an internal DataKind. + public DataKind DataKind + { + get { return Type.ToDataKind(); } + set { Type = value.ToInternalDataKind(); } + } /// /// Source index range(s) of the column. @@ -132,10 +158,10 @@ private bool TryParse(string str) return false; if (rgstr.Length == 3) { - DataKind kind; + InternalDataKind kind; if (!TypeParsingUtils.TryParseDataKind(rgstr[istr++], out kind, out KeyCount)) return false; - Type = kind == default ? default(DataKind?) : kind; + Type = kind == default ? InternalDataKind.R4 : kind; } return TryParseSource(rgstr[istr++]); @@ -173,10 +199,10 @@ internal bool TryUnparse(StringBuilder sb) int ich = sb.Length; sb.Append(Name); sb.Append(':'); - if (Type != null || KeyCount != null) + if (Type != default || KeyCount != null) { - if (Type != null) - sb.Append(Type.Value.GetString()); + if (Type != default) + sb.Append(Type.GetString()); if (KeyCount != null) { sb.Append('['); @@ -536,7 +562,7 @@ internal sealed class ColInfo { public readonly string Name; // REVIEW: Fix this for keys. - public readonly DataKind Kind; + public readonly InternalDataKind Kind; public readonly DataViewType ColType; public readonly Segment[] Segments; @@ -696,15 +722,15 @@ public Bindings(TextLoader parent, Column[] cols, IMultiStreamSource headerFile, ch.Info("Duplicate name(s) specified - later columns will hide earlier ones"); PrimitiveDataViewType itemType; - DataKind kind; + InternalDataKind kind; if (col.KeyCount != null) { itemType = TypeParsingUtils.ConstructKeyType(col.Type, col.KeyCount); } else { - kind = col.Type ?? DataKind.Num; - ch.CheckUserArg(Enum.IsDefined(typeof(DataKind), kind), nameof(Column.Type), "Bad item type"); + kind = col.Type == default? InternalDataKind.R4 : col.Type; + ch.CheckUserArg(Enum.IsDefined(typeof(InternalDataKind), kind), nameof(Column.Type), "Bad item type"); itemType = ColumnTypeExtensions.PrimitiveTypeFromKind(kind); } @@ -861,8 +887,8 @@ public Bindings(ModelLoadContext ctx, TextLoader parent) string name = ctx.LoadNonEmptyString(); PrimitiveDataViewType itemType; - var kind = (DataKind)ctx.Reader.ReadByte(); - Contracts.CheckDecode(Enum.IsDefined(typeof(DataKind), kind)); + var kind = (InternalDataKind)ctx.Reader.ReadByte(); + Contracts.CheckDecode(Enum.IsDefined(typeof(InternalDataKind), kind)); bool isKey = ctx.Reader.ReadBoolByte(); if (isKey) { @@ -948,8 +974,8 @@ internal void Save(ModelSaveContext ctx) var info = Infos[iinfo]; ctx.SaveNonEmptyString(info.Name); var type = info.ColType.GetItemType(); - DataKind rawKind = type.GetRawKind(); - Contracts.Assert((DataKind)(byte)rawKind == rawKind); + InternalDataKind rawKind = type.GetRawKind(); + Contracts.Assert((InternalDataKind)(byte)rawKind == rawKind); ctx.Writer.Write((byte)rawKind); ctx.Writer.WriteBoolByte(type is KeyType); if (type is KeyType key) @@ -1465,17 +1491,17 @@ internal static TextLoader CreateTextReader(IHostEnvironment host, var column = new Column(); column.Name = mappingAttrName?.Name ?? memberInfo.Name; column.Source = mappingAttr.Sources.ToArray(); - DataKind dk; + InternalDataKind dk; switch (memberInfo) { case FieldInfo field: - if (!DataKindExtensions.TryGetDataKind(field.FieldType.IsArray ? field.FieldType.GetElementType() : field.FieldType, out dk)) + if (!InternalDataKindExtensions.TryGetDataKind(field.FieldType.IsArray ? field.FieldType.GetElementType() : field.FieldType, out dk)) throw Contracts.Except($"Field {memberInfo.Name} is of unsupported type."); break; case PropertyInfo property: - if (!DataKindExtensions.TryGetDataKind(property.PropertyType.IsArray ? property.PropertyType.GetElementType() : property.PropertyType, out dk)) + if (!InternalDataKindExtensions.TryGetDataKind(property.PropertyType.IsArray ? property.PropertyType.GetElementType() : property.PropertyType, out dk)) throw Contracts.Except($"Property {memberInfo.Name} is of unsupported type."); break; diff --git a/src/Microsoft.ML.Data/DataLoadSave/Text/TextLoaderParser.cs b/src/Microsoft.ML.Data/DataLoadSave/Text/TextLoaderParser.cs index c0ce3935d0..205a89bd6e 100644 --- a/src/Microsoft.ML.Data/DataLoadSave/Text/TextLoaderParser.cs +++ b/src/Microsoft.ML.Data/DataLoadSave/Text/TextLoaderParser.cs @@ -51,9 +51,9 @@ private ValueCreatorCache() _methVec = new Func>(GetCreatorVecCore) .GetMethodInfo().GetGenericMethodDefinition(); - _creatorsOne = new Func[DataKindExtensions.KindCount]; - _creatorsVec = new Func[DataKindExtensions.KindCount]; - for (var kind = DataKindExtensions.KindMin; kind < DataKindExtensions.KindLim; kind++) + _creatorsOne = new Func[InternalDataKindExtensions.KindCount]; + _creatorsVec = new Func[InternalDataKindExtensions.KindCount]; + for (var kind = InternalDataKindExtensions.KindMin; kind < InternalDataKindExtensions.KindLim; kind++) { var type = ColumnTypeExtensions.PrimitiveTypeFromKind(kind); _creatorsOne[kind.ToIndex()] = GetCreatorOneCore(type); @@ -103,14 +103,14 @@ public Func GetCreatorVec(KeyType key) return (Func)meth.Invoke(this, new object[] { key }); } - public Func GetCreatorOne(DataKind kind) + public Func GetCreatorOne(InternalDataKind kind) { int index = kind.ToIndex(); Contracts.Assert(0 <= index & index < _creatorsOne.Length); return _creatorsOne[index]; } - public Func GetCreatorVec(DataKind kind) + public Func GetCreatorVec(InternalDataKind kind) { int index = kind.ToIndex(); Contracts.Assert(0 <= index & index < _creatorsOne.Length); @@ -654,8 +654,8 @@ public Parser(TextLoader parent) _infos = parent._bindings.Infos; _creator = new Func[_infos.Length]; var cache = ValueCreatorCache.Instance; - var mapOne = new Dictionary>(); - var mapVec = new Dictionary>(); + var mapOne = new Dictionary>(); + var mapVec = new Dictionary>(); for (int i = 0; i < _creator.Length; i++) { var info = _infos[i]; diff --git a/src/Microsoft.ML.Data/DataLoadSave/Text/TextSaver.cs b/src/Microsoft.ML.Data/DataLoadSave/Text/TextSaver.cs index 29d7e7654a..897396328d 100644 --- a/src/Microsoft.ML.Data/DataLoadSave/Text/TextSaver.cs +++ b/src/Microsoft.ML.Data/DataLoadSave/Text/TextSaver.cs @@ -503,7 +503,7 @@ private TextLoader.Column GetColumn(string name, DataViewType type, int? start) if (itemType is KeyType key) keyCount = new KeyCount(key.Count); - DataKind kind = itemType.GetRawKind(); + InternalDataKind kind = itemType.GetRawKind(); TextLoader.Range[] source = null; TextLoader.Range range = null; diff --git a/src/Microsoft.ML.Data/DataView/ArrayDataViewBuilder.cs b/src/Microsoft.ML.Data/DataView/ArrayDataViewBuilder.cs index f38e427d30..2e7a483776 100644 --- a/src/Microsoft.ML.Data/DataView/ArrayDataViewBuilder.cs +++ b/src/Microsoft.ML.Data/DataView/ArrayDataViewBuilder.cs @@ -85,7 +85,7 @@ public void AddColumn(string name, ValueGetter> _host.CheckValue(getKeyValues, nameof(getKeyValues)); _host.CheckParam(keyCount > 0, nameof(keyCount)); CheckLength(name, values); - values.GetType().GetElementType().TryGetDataKind(out DataKind kind); + values.GetType().GetElementType().TryGetDataKind(out InternalDataKind kind); _columns.Add(new AssignmentColumn(new KeyType(kind.ToType(), keyCount), values)); _getKeyValues.Add(name, getKeyValues); _names.Add(name); diff --git a/src/Microsoft.ML.Data/Transforms/ConversionsExtensionsCatalog.cs b/src/Microsoft.ML.Data/Transforms/ConversionsExtensionsCatalog.cs index 8995e4a1d5..3b6430f2a6 100644 --- a/src/Microsoft.ML.Data/Transforms/ConversionsExtensionsCatalog.cs +++ b/src/Microsoft.ML.Data/Transforms/ConversionsExtensionsCatalog.cs @@ -46,7 +46,7 @@ public static HashingEstimator Hash(this TransformsCatalog.ConversionTransforms /// The transform's catalog. /// Name of the column resulting from the transformation of . /// Name of the column to transform. If set to , the value of the will be used as source. - /// Number of bits to hash into. Must be between 1 and 31, inclusive. + /// The expected kind of the output column. public static TypeConvertingEstimator ConvertType(this TransformsCatalog.ConversionTransforms catalog, string outputColumnName, string inputColumnName = null, DataKind outputKind = ConvertDefaults.DefaultOutputKind) => new TypeConvertingEstimator(CatalogUtils.GetEnvironment(catalog), outputColumnName, inputColumnName, outputKind); diff --git a/src/Microsoft.ML.Data/Transforms/Normalizer.cs b/src/Microsoft.ML.Data/Transforms/Normalizer.cs index be88e2eb65..9cf05dd698 100644 --- a/src/Microsoft.ML.Data/Transforms/Normalizer.cs +++ b/src/Microsoft.ML.Data/Transforms/Normalizer.cs @@ -338,8 +338,8 @@ internal static DataViewType LoadType(ModelLoadContext ctx) Contracts.CheckDecode(vectorSize >= 0); Contracts.CheckDecode(vectorSize > 0 || !isVector); - DataKind itemKind = (DataKind)ctx.Reader.ReadByte(); - Contracts.CheckDecode(itemKind == DataKind.R4 || itemKind == DataKind.R8); + InternalDataKind itemKind = (InternalDataKind)ctx.Reader.ReadByte(); + Contracts.CheckDecode(itemKind == InternalDataKind.R4 || itemKind == InternalDataKind.R8); var itemType = ColumnTypeExtensions.PrimitiveTypeFromKind(itemKind); return isVector ? (DataViewType)(new VectorType(itemType, vectorSize)) : itemType; @@ -359,8 +359,8 @@ internal static void SaveType(ModelSaveContext ctx, DataViewType type) ctx.Writer.Write(vectorType?.Size ?? 0); DataViewType itemType = vectorType?.ItemType ?? type; - itemType.RawType.TryGetDataKind(out DataKind itemKind); - Contracts.Assert(itemKind == DataKind.R4 || itemKind == DataKind.R8); + itemType.RawType.TryGetDataKind(out InternalDataKind itemKind); + Contracts.Assert(itemKind == InternalDataKind.R4 || itemKind == InternalDataKind.R8); ctx.Writer.Write((byte)itemKind); } } diff --git a/src/Microsoft.ML.Data/Transforms/TypeConverting.cs b/src/Microsoft.ML.Data/Transforms/TypeConverting.cs index 01c8f2877d..ea45b796fb 100644 --- a/src/Microsoft.ML.Data/Transforms/TypeConverting.cs +++ b/src/Microsoft.ML.Data/Transforms/TypeConverting.cs @@ -61,7 +61,7 @@ public sealed class TypeConvertingTransformer : OneToOneTransformerBase internal class Column : OneToOneColumn { [Argument(ArgumentType.AtMostOnce, HelpText = "The result type", ShortName = "type")] - public DataKind? ResultType; + public InternalDataKind? ResultType; [Argument(ArgumentType.Multiple, HelpText = "For a key column, this defines the cardinality/count of valid key values", ShortName = "key", Visibility = ArgumentAttribute.VisibilityType.CmdLineOnly)] public KeyCount KeyCount; @@ -88,9 +88,9 @@ private protected override bool TryParse(string str) if (extra == null) return true; - if (!TypeParsingUtils.TryParseDataKind(extra, out DataKind kind, out KeyCount)) + if (!TypeParsingUtils.TryParseDataKind(extra, out InternalDataKind kind, out KeyCount)) return false; - ResultType = kind == default ? default(DataKind?) : kind; + ResultType = kind == default ? default(InternalDataKind?) : kind; return true; } @@ -135,7 +135,7 @@ internal class Options : TransformInputBase public Column[] Columns; [Argument(ArgumentType.AtMostOnce, HelpText = "The result type", ShortName = "type", SortOrder = 2)] - public DataKind? ResultType; + public InternalDataKind? ResultType; [Argument(ArgumentType.Multiple, HelpText = "For a key column, this defines the range of values", ShortName = "key", Visibility = ArgumentAttribute.VisibilityType.CmdLineOnly)] public KeyCount KeyCount; @@ -221,13 +221,13 @@ private protected override void SaveModel(ModelSaveContext ctx) for (int i = 0; i < _columns.Length; i++) { - Host.Assert((DataKind)(byte)_columns[i].OutputKind == _columns[i].OutputKind); + Host.Assert((InternalDataKind)(byte)_columns[i].OutputKind.ToInternalDataKind() == _columns[i].OutputKind.ToInternalDataKind()); if (_columns[i].OutputKeyCount != null) { byte b = (byte)_columns[i].OutputKind; b |= 0x80; ctx.Writer.Write(b); - ctx.Writer.Write(_columns[i].OutputKeyCount.Count ?? _columns[i].OutputKind.ToMaxInt()); + ctx.Writer.Write(_columns[i].OutputKeyCount.Count ?? _columns[i].OutputKind.ToInternalDataKind().ToMaxInt()); } else ctx.Writer.Write((byte)_columns[i].OutputKind); @@ -264,8 +264,8 @@ private TypeConvertingTransformer(IHost host, ModelLoadContext ctx) for (int i = 0; i < columnsLength; i++) { byte b = ctx.Reader.ReadByte(); - var kind = (DataKind)(b & 0x7F); - Host.CheckDecode(Enum.IsDefined(typeof(DataKind), kind)); + var kind = (InternalDataKind)(b & 0x7F); + Host.CheckDecode(Enum.IsDefined(typeof(InternalDataKind), kind)); KeyCount keyCount = null; ulong count = 0; if ((b & 0x80) != 0) @@ -289,7 +289,7 @@ private TypeConvertingTransformer(IHost host, ModelLoadContext ctx) keyCount = new KeyCount(count); } - _columns[i] = new TypeConvertingEstimator.ColumnInfo(ColumnPairs[i].outputColumnName, kind, ColumnPairs[i].inputColumnName, keyCount); + _columns[i] = new TypeConvertingEstimator.ColumnInfo(ColumnPairs[i].outputColumnName, kind.ToDataKind(), ColumnPairs[i].inputColumnName, keyCount); } } @@ -322,22 +322,22 @@ internal static IDataTransform Create(IHostEnvironment env, Options options, IDa keyCount = KeyCount.Parse(options.Range); } - DataKind kind; + InternalDataKind kind; if (tempResultType == null) { if (keyCount == null) - kind = DataKind.Num; + kind = InternalDataKind.Num; else { var srcType = input.Schema[item.Source ?? item.Name].Type; - kind = srcType is KeyType ? srcType.GetRawKind() : DataKind.U8; + kind = srcType is KeyType ? srcType.GetRawKind() : InternalDataKind.U8; } } else { kind = tempResultType.Value; } - cols[i] = new TypeConvertingEstimator.ColumnInfo(item.Name, kind, item.Source ?? item.Name, keyCount); + cols[i] = new TypeConvertingEstimator.ColumnInfo(item.Name, kind.ToDataKind(), item.Source ?? item.Name, keyCount); }; return new TypeConvertingTransformer(env, cols).MakeDataTransform(input); } @@ -352,7 +352,7 @@ private static IRowMapper Create(IHostEnvironment env, ModelLoadContext ctx, Dat private protected override IRowMapper MakeRowMapper(DataViewSchema schema) => new Mapper(this, schema); - internal static bool GetNewType(IExceptionContext ectx, DataViewType srcType, DataKind kind, KeyCount keyCount, out PrimitiveDataViewType itemType) + internal static bool GetNewType(IExceptionContext ectx, DataViewType srcType, InternalDataKind kind, KeyCount keyCount, out PrimitiveDataViewType itemType) { if (keyCount != null) { @@ -401,7 +401,8 @@ public Mapper(TypeConvertingTransformer parent, DataViewSchema inputSchema) { inputSchema.TryGetColumnIndex(_parent.ColumnPairs[i].inputColumnName, out _srcCols[i]); var srcCol = inputSchema[_srcCols[i]]; - if (!CanConvertToType(Host, srcCol.Type, _parent._columns[i].OutputKind, _parent._columns[i].OutputKeyCount, out PrimitiveDataViewType itemType, out _types[i])) + if (!CanConvertToType(Host, srcCol.Type, _parent._columns[i].OutputKind.ToInternalDataKind(), _parent._columns[i].OutputKeyCount, + out PrimitiveDataViewType itemType, out _types[i])) { throw Host.ExceptParam(nameof(inputSchema), "source column '{0}' with item type '{1}' is not compatible with destination type '{2}'", @@ -410,11 +411,11 @@ public Mapper(TypeConvertingTransformer parent, DataViewSchema inputSchema) } } - private static bool CanConvertToType(IExceptionContext ectx, DataViewType srcType, DataKind kind, KeyCount keyCount, + private static bool CanConvertToType(IExceptionContext ectx, DataViewType srcType, InternalDataKind kind, KeyCount keyCount, out PrimitiveDataViewType itemType, out DataViewType typeDst) { ectx.AssertValue(srcType); - ectx.Assert(Enum.IsDefined(typeof(DataKind), kind)); + ectx.Assert(Enum.IsDefined(typeof(InternalDataKind), kind)); typeDst = null; if (!GetNewType(ectx, srcType, kind, keyCount, out itemType)) @@ -520,7 +521,7 @@ public sealed class TypeConvertingEstimator : TrivialEstimator @@ -571,8 +572,9 @@ public ColumnInfo(string name, Type type, string inputColumnName, KeyCount outpu { Name = name; InputColumnName = inputColumnName ?? name; - if (!type.TryGetDataKind(out OutputKind)) + if (!type.TryGetDataKind(out InternalDataKind OutputKind)) throw Contracts.ExceptUserArg(nameof(type), $"Unsupported type {type}."); + this.OutputKind = OutputKind.ToDataKind(); OutputKeyCount = outputKeyCount; } } @@ -583,7 +585,7 @@ public ColumnInfo(string name, Type type, string inputColumnName, KeyCount outpu /// Host Environment. /// Name of the column resulting from the transformation of . /// Name of the column to transform. If set to , the value of the will be used as source. - /// The expected type of the converted column. + /// The expected kind of the converted column. internal TypeConvertingEstimator(IHostEnvironment env, string outputColumnName, string inputColumnName = null, DataKind outputKind = Defaults.DefaultOutputKind) @@ -611,7 +613,7 @@ public override SchemaShape GetOutputSchema(SchemaShape inputSchema) { if (!inputSchema.TryFindColumn(colInfo.InputColumnName, out var col)) throw Host.ExceptSchemaMismatch(nameof(inputSchema), "input", colInfo.InputColumnName); - if (!TypeConvertingTransformer.GetNewType(Host, col.ItemType, colInfo.OutputKind, colInfo.OutputKeyCount, out PrimitiveDataViewType newType)) + if (!TypeConvertingTransformer.GetNewType(Host, col.ItemType, colInfo.OutputKind.ToInternalDataKind(), colInfo.OutputKeyCount, out PrimitiveDataViewType newType)) throw Host.ExceptParam(nameof(inputSchema), $"Can't convert {colInfo.InputColumnName} into {newType.ToString()}"); if (!Data.Conversion.Conversions.Instance.TryGetStandardConversion(col.ItemType, newType, out Delegate del, out bool identity)) throw Host.ExceptParam(nameof(inputSchema), $"Don't know how to convert {colInfo.InputColumnName} into {newType.ToString()}"); diff --git a/src/Microsoft.ML.Data/Transforms/ValueMapping.cs b/src/Microsoft.ML.Data/Transforms/ValueMapping.cs index 6c6b11c605..b62cd8d221 100644 --- a/src/Microsoft.ML.Data/Transforms/ValueMapping.cs +++ b/src/Microsoft.ML.Data/Transforms/ValueMapping.cs @@ -168,7 +168,7 @@ internal static PrimitiveDataViewType GetPrimitiveType(Type rawType, out bool is isVectorType = true; } - if (!type.TryGetDataKind(out DataKind kind)) + if (!type.TryGetDataKind(out InternalDataKind kind)) throw new InvalidOperationException($"Unsupported type {type} used in mapping."); return ColumnTypeExtensions.PrimitiveTypeFromKind(kind); @@ -490,14 +490,14 @@ private static TextLoader.Column GenerateValueColumn(IHostEnvironment env, } } - TextLoader.Column valueColumn = new TextLoader.Column(valueColumnName, DataKind.U4, 1); + TextLoader.Column valueColumn = new TextLoader.Column(valueColumnName, DataKind.UInt32, 1); if (keyMax < int.MaxValue) valueColumn.KeyCount = new KeyCount(keyMax + 1); else if (keyMax < uint.MaxValue) valueColumn.KeyCount = new KeyCount(); else { - valueColumn.Type = DataKind.U8; + valueColumn.Type = DataKind.UInt64.ToInternalDataKind(); valueColumn.KeyCount = new KeyCount(); } @@ -598,8 +598,8 @@ private static IDataTransform Create(IHostEnvironment env, Options options, IDat // types unless ValueAsKeyType is specified. if (options.ValuesAsKeyType) { - keyColumn = new TextLoader.Column(keyColumnName, DataKind.TXT, 0); - valueColumn = new TextLoader.Column(valueColumnName, DataKind.TXT, 1); + keyColumn = new TextLoader.Column(keyColumnName, DataKind.String, 0); + valueColumn = new TextLoader.Column(valueColumnName, DataKind.String, 1); var txtArgs = new TextLoader.Options() { Columns = new TextLoader.Column[] @@ -621,8 +621,8 @@ private static IDataTransform Create(IHostEnvironment env, Options options, IDat } else { - keyColumn = new TextLoader.Column(keyColumnName, DataKind.TXT, 0); - valueColumn = new TextLoader.Column(valueColumnName, DataKind.R4, 1); + keyColumn = new TextLoader.Column(keyColumnName, DataKind.String, 0); + valueColumn = new TextLoader.Column(valueColumnName, DataKind.Single, 1); } loader = TextLoader.Create( @@ -733,7 +733,7 @@ protected static PrimitiveDataViewType GetPrimitiveType(Type rawType, out bool i isVectorType = true; } - if (!type.TryGetDataKind(out DataKind kind)) + if (!type.TryGetDataKind(out InternalDataKind kind)) throw Contracts.Except($"Unsupported type {type} used in mapping."); return ColumnTypeExtensions.PrimitiveTypeFromKind(kind); diff --git a/src/Microsoft.ML.Data/Transforms/ValueToKeyMappingTransformer.cs b/src/Microsoft.ML.Data/Transforms/ValueToKeyMappingTransformer.cs index f90f6377e9..aaba6cdebf 100644 --- a/src/Microsoft.ML.Data/Transforms/ValueToKeyMappingTransformer.cs +++ b/src/Microsoft.ML.Data/Transforms/ValueToKeyMappingTransformer.cs @@ -440,7 +440,7 @@ internal static IDataView GetKeyDataViewOrNull(IHostEnvironment env, IChannel ch nameof(Options.TermsColumn), src); } keyData = new TextLoader(env, - columns: new[] { new TextLoader.Column("Term", DataKind.TX, 0) }, + columns: new[] { new TextLoader.Column("Term", DataKind.String, 0) }, dataSample: fileSource) .Read(fileSource); src = "Term"; diff --git a/src/Microsoft.ML.Data/Utilities/TypeParsingUtils.cs b/src/Microsoft.ML.Data/Utilities/TypeParsingUtils.cs index 7e6194f6db..c3bc1e9491 100644 --- a/src/Microsoft.ML.Data/Utilities/TypeParsingUtils.cs +++ b/src/Microsoft.ML.Data/Utilities/TypeParsingUtils.cs @@ -18,13 +18,13 @@ internal static class TypeParsingUtils { /// /// Attempt to parse the string into a data kind and (optionally) a keyCount. This method does not check whether - /// the returned can really be made into a key with the specified . + /// the returned can really be made into a key with the specified . /// /// The string to parse. /// The parsed data kind. /// The parsed key count, or null if there's no key specification. /// Whether the parsing succeeded or not. - public static bool TryParseDataKind(string str, out DataKind dataKind, out KeyCount keyCount) + public static bool TryParseDataKind(string str, out InternalDataKind dataKind, out KeyCount keyCount) { Contracts.CheckValue(str, nameof(str)); keyCount = null; @@ -52,12 +52,12 @@ public static bool TryParseDataKind(string str, out DataKind dataKind, out KeyCo /// /// Construct a out of the data kind and the keyCount. /// - public static KeyType ConstructKeyType(DataKind? type, KeyCount keyCount) + public static KeyType ConstructKeyType(InternalDataKind? type, KeyCount keyCount) { Contracts.CheckValue(keyCount, nameof(keyCount)); KeyType keyType; - Type rawType = type.HasValue ? type.Value.ToType() : DataKind.U8.ToType(); + Type rawType = type.HasValue ? type.Value.ToType() : InternalDataKind.U8.ToType(); Contracts.CheckUserArg(KeyType.IsValidDataType(rawType), nameof(TextLoader.Column.Type), "Bad item type for Key"); if (keyCount.Count == null) diff --git a/src/Microsoft.ML.EntryPoints/FeatureCombiner.cs b/src/Microsoft.ML.EntryPoints/FeatureCombiner.cs index 39d47559fc..bf0873251a 100644 --- a/src/Microsoft.ML.EntryPoints/FeatureCombiner.cs +++ b/src/Microsoft.ML.EntryPoints/FeatureCombiner.cs @@ -185,7 +185,7 @@ private static IDataView ApplyConvert(List c // This happens when the training is done on an XDF and the scoring is done on a data frame. var colName = GetUniqueName(); concatNames.Add(new KeyValuePair(col.Name, colName)); - Utils.Add(ref cvt, new TypeConvertingEstimator.ColumnInfo(colName, DataKind.R4, col.Name)); + Utils.Add(ref cvt, new TypeConvertingEstimator.ColumnInfo(colName, DataKind.Single, col.Name)); continue; } } @@ -300,7 +300,7 @@ public static CommonOutputs.TransformOutput PrepareRegressionLabel(IHostEnvironm return new CommonOutputs.TransformOutput { Model = new TransformModelImpl(env, nop, input.Data), OutputData = nop }; } - var xf = new TypeConvertingTransformer(host, new TypeConvertingEstimator.ColumnInfo(input.LabelColumn, DataKind.R4, input.LabelColumn)).Transform(input.Data); + var xf = new TypeConvertingTransformer(host, new TypeConvertingEstimator.ColumnInfo(input.LabelColumn, DataKind.Single, input.LabelColumn)).Transform(input.Data); return new CommonOutputs.TransformOutput { Model = new TransformModelImpl(env, xf, input.Data), OutputData = xf }; } } diff --git a/src/Microsoft.ML.FastTree/FastTree.cs b/src/Microsoft.ML.FastTree/FastTree.cs index 12e62ec626..e49916622a 100644 --- a/src/Microsoft.ML.FastTree/FastTree.cs +++ b/src/Microsoft.ML.FastTree/FastTree.cs @@ -1375,7 +1375,7 @@ private Dataset Construct(RoleMappedData examples, ref int numExamples, int maxB } // Convert the group column, if one exists. if (examples.Schema.Group?.Name is string groupName) - data = new TypeConvertingTransformer(Host, new TypeConvertingEstimator.ColumnInfo(groupName, DataKind.U8, groupName)).Transform(data); + data = new TypeConvertingTransformer(Host, new TypeConvertingEstimator.ColumnInfo(groupName, DataKind.UInt64, groupName)).Transform(data); // Since we've passed it through a few transforms, reconstitute the mapping on the // newly transformed data. diff --git a/src/Microsoft.ML.OnnxTransformer/OnnxUtils.cs b/src/Microsoft.ML.OnnxTransformer/OnnxUtils.cs index 241d43615b..2be81943cd 100644 --- a/src/Microsoft.ML.OnnxTransformer/OnnxUtils.cs +++ b/src/Microsoft.ML.OnnxTransformer/OnnxUtils.cs @@ -192,19 +192,19 @@ internal sealed class OnnxUtils typeof(UInt32), typeof(UInt64) }; - private static Dictionary _typeToKindMap= - new Dictionary + private static Dictionary _typeToKindMap= + new Dictionary { - { typeof(Single) , DataKind.R4}, - { typeof(Double) , DataKind.R8}, - { typeof(Int16) , DataKind.I2}, - { typeof(Int32) , DataKind.I4}, - { typeof(Int64) , DataKind.I8}, - { typeof(UInt16) , DataKind.U2}, - { typeof(UInt32) , DataKind.U4}, - { typeof(UInt64) , DataKind.U8}, - { typeof(String) , DataKind.TX}, - { typeof(Boolean) , DataKind.BL}, + { typeof(Single) , InternalDataKind.R4}, + { typeof(Double) , InternalDataKind.R8}, + { typeof(Int16) , InternalDataKind.I2}, + { typeof(Int32) , InternalDataKind.I4}, + { typeof(Int64) , InternalDataKind.I8}, + { typeof(UInt16) , InternalDataKind.U2}, + { typeof(UInt32) , InternalDataKind.U4}, + { typeof(UInt64) , InternalDataKind.U8}, + { typeof(String) , InternalDataKind.TX}, + { typeof(Boolean) , InternalDataKind.BL}, }; /// diff --git a/src/Microsoft.ML.Parquet/PartitionedFileLoader.cs b/src/Microsoft.ML.Parquet/PartitionedFileLoader.cs index 055d34f3b9..2d7c298bc4 100644 --- a/src/Microsoft.ML.Parquet/PartitionedFileLoader.cs +++ b/src/Microsoft.ML.Parquet/PartitionedFileLoader.cs @@ -87,7 +87,7 @@ public sealed class Column public string Name; [Argument(ArgumentType.AtMostOnce, HelpText = "Data type of the column.")] - public DataKind? Type; + public InternalDataKind? Type; [Argument(ArgumentType.Required, HelpText = "Index of the directory representing this column.")] public int Source; @@ -118,8 +118,8 @@ private static bool TryParse(string str, out Column column) return false; } - DataKind? kind = null; - if (kindStr != null && TypeParsingUtils.TryParseDataKind(kindStr, out DataKind parsedKind, out var keyCount)) + InternalDataKind? kind = null; + if (kindStr != null && TypeParsingUtils.TryParseDataKind(kindStr, out InternalDataKind parsedKind, out var keyCount)) { kind = parsedKind; } @@ -197,7 +197,7 @@ public PartitionedFileLoader(IHostEnvironment env, Arguments args, IMultiStreamS { Name = "Path", Source = FilePathColIndex, - Type = DataKind.Text + Type = InternalDataKind.Text }; columns = columns.Concat(new[] { pathCol }).ToArray(); diff --git a/src/Microsoft.ML.Parquet/PartitionedPathParser.cs b/src/Microsoft.ML.Parquet/PartitionedPathParser.cs index 70a01be64b..b453b99ccb 100644 --- a/src/Microsoft.ML.Parquet/PartitionedPathParser.cs +++ b/src/Microsoft.ML.Parquet/PartitionedPathParser.cs @@ -82,7 +82,7 @@ public class Arguments : IPartitionedPathParserFactory public PartitionedFileLoader.Column[] Columns; [Argument(ArgumentType.AtMostOnce, HelpText = "Data type of each column.")] - public DataKind Type = DataKind.Text; + public InternalDataKind Type = InternalDataKind.Text; public IPartitionedPathParser CreateComponent(IHostEnvironment env) => new SimplePartitionedPathParser(env, this); } @@ -294,7 +294,7 @@ void ICanSaveModel.Save(ModelSaveContext ctx) { Name = names[i], Source = i, - Type = DataKind.Text + Type = InternalDataKind.Text }; } diff --git a/src/Microsoft.ML.Recommender/RecommenderUtils.cs b/src/Microsoft.ML.Recommender/RecommenderUtils.cs index b33ef0427d..4e561f0dc4 100644 --- a/src/Microsoft.ML.Recommender/RecommenderUtils.cs +++ b/src/Microsoft.ML.Recommender/RecommenderUtils.cs @@ -38,7 +38,7 @@ private static bool TryMarshalGoodRowColumnType(DataViewType type, out KeyType k /// /// Checks whether a column kind in a is unique, and its type - /// is a key of known cardinality. + /// is a key of known cardinality. /// /// The training examples /// The column role to try to extract diff --git a/src/Microsoft.ML.SamplesUtils/SamplesDatasetUtils.cs b/src/Microsoft.ML.SamplesUtils/SamplesDatasetUtils.cs index 203bd6e6bd..79ce680470 100644 --- a/src/Microsoft.ML.SamplesUtils/SamplesDatasetUtils.cs +++ b/src/Microsoft.ML.SamplesUtils/SamplesDatasetUtils.cs @@ -7,7 +7,6 @@ using System.IO; using System.Net; using Microsoft.Data.DataView; -using Microsoft.ML; using Microsoft.ML.Data; namespace Microsoft.ML.SamplesUtils @@ -34,18 +33,18 @@ public static IDataView LoadHousingRegressionDataset(MLContext mlContext) var reader = mlContext.Data.CreateTextLoader( columns: new[] { - new TextLoader.Column("MedianHomeValue", DataKind.R4, 0), - new TextLoader.Column("CrimesPerCapita", DataKind.R4, 1), - new TextLoader.Column("PercentResidental", DataKind.R4, 2), - new TextLoader.Column("PercentNonRetail", DataKind.R4, 3), - new TextLoader.Column("CharlesRiver", DataKind.R4, 4), - new TextLoader.Column("NitricOxides", DataKind.R4, 5), - new TextLoader.Column("RoomsPerDwelling", DataKind.R4, 6), - new TextLoader.Column("PercentPre40s", DataKind.R4, 7), - new TextLoader.Column("EmploymentDistance", DataKind.R4, 8), - new TextLoader.Column("HighwayDistance", DataKind.R4, 9), - new TextLoader.Column("TaxRate", DataKind.R4, 10), - new TextLoader.Column("TeacherRatio", DataKind.R4, 11), + new TextLoader.Column("MedianHomeValue", DataKind.Single, 0), + new TextLoader.Column("CrimesPerCapita", DataKind.Single, 1), + new TextLoader.Column("PercentResidental", DataKind.Single, 2), + new TextLoader.Column("PercentNonRetail", DataKind.Single, 3), + new TextLoader.Column("CharlesRiver", DataKind.Single, 4), + new TextLoader.Column("NitricOxides", DataKind.Single, 5), + new TextLoader.Column("RoomsPerDwelling", DataKind.Single, 6), + new TextLoader.Column("PercentPre40s", DataKind.Single, 7), + new TextLoader.Column("EmploymentDistance", DataKind.Single, 8), + new TextLoader.Column("HighwayDistance", DataKind.Single, 9), + new TextLoader.Column("TaxRate", DataKind.Single, 10), + new TextLoader.Column("TeacherRatio", DataKind.Single, 11), }, hasHeader: true ); @@ -104,21 +103,21 @@ public static IDataView LoadFeaturizedAdultDataset(MLContext mlContext) var reader = mlContext.Data.CreateTextLoader( columns: new[] { - new TextLoader.Column("age", DataKind.R4, 0), - new TextLoader.Column("workclass", DataKind.TX, 1), - new TextLoader.Column("fnlwgt", DataKind.R4, 2), - new TextLoader.Column("education", DataKind.TX, 3), - new TextLoader.Column("education-num", DataKind.R4, 4), - new TextLoader.Column("marital-status", DataKind.TX, 5), - new TextLoader.Column("occupation", DataKind.TX, 6), - new TextLoader.Column("relationship", DataKind.TX, 7), - new TextLoader.Column("ethnicity", DataKind.TX, 8), - new TextLoader.Column("sex", DataKind.TX, 9), - new TextLoader.Column("capital-gain", DataKind.R4, 10), - new TextLoader.Column("capital-loss", DataKind.R4, 11), - new TextLoader.Column("hours-per-week", DataKind.R4, 12), - new TextLoader.Column("native-country", DataKind.R4, 13), - new TextLoader.Column("IsOver50K", DataKind.BL, 14), + new TextLoader.Column("age", DataKind.Single, 0), + new TextLoader.Column("workclass", DataKind.String, 1), + new TextLoader.Column("fnlwgt", DataKind.Single, 2), + new TextLoader.Column("education", DataKind.String, 3), + new TextLoader.Column("education-num", DataKind.Single, 4), + new TextLoader.Column("marital-status", DataKind.String, 5), + new TextLoader.Column("occupation", DataKind.String, 6), + new TextLoader.Column("relationship", DataKind.String, 7), + new TextLoader.Column("ethnicity", DataKind.String, 8), + new TextLoader.Column("sex", DataKind.String, 9), + new TextLoader.Column("capital-gain", DataKind.Single, 10), + new TextLoader.Column("capital-loss", DataKind.Single, 11), + new TextLoader.Column("hours-per-week", DataKind.Single, 12), + new TextLoader.Column("native-country", DataKind.Single, 13), + new TextLoader.Column("IsOver50K", DataKind.Boolean, 14), }, separatorChar: ',', hasHeader: true diff --git a/src/Microsoft.ML.StaticPipe/ConvertStaticExtensions.cs b/src/Microsoft.ML.StaticPipe/ConvertStaticExtensions.cs index 464ee1a0b2..cbb301730c 100644 --- a/src/Microsoft.ML.StaticPipe/ConvertStaticExtensions.cs +++ b/src/Microsoft.ML.StaticPipe/ConvertStaticExtensions.cs @@ -15,21 +15,21 @@ public static partial class ConvertStaticExtensions /// /// The input column. /// Float column. - public static Scalar ToFloat(this Scalar input) => new ImplScalar(Contracts.CheckRef(input, nameof(input)), DataKind.R4); + public static Scalar ToFloat(this Scalar input) => new ImplScalar(Contracts.CheckRef(input, nameof(input)), InternalDataKind.R4); /// /// Convert to array of floats. /// /// The input column. /// Column with array of floats. - public static Vector ToFloat(this Vector input) => new ImplVector(Contracts.CheckRef(input, nameof(input)), DataKind.R4); + public static Vector ToFloat(this Vector input) => new ImplVector(Contracts.CheckRef(input, nameof(input)), InternalDataKind.R4); /// /// Convert to variable array of floats. /// /// The input column. /// Column with variable array of floats. - public static VarVector ToFloat(this VarVector input) => new ImplVarVector(Contracts.CheckRef(input, nameof(input)), DataKind.R4); + public static VarVector ToFloat(this VarVector input) => new ImplVarVector(Contracts.CheckRef(input, nameof(input)), InternalDataKind.R4); #endregion #region For double inputs. @@ -38,21 +38,21 @@ public static partial class ConvertStaticExtensions /// /// The input column. /// Float column. - public static Scalar ToFloat(this Scalar input) => new ImplScalar(Contracts.CheckRef(input, nameof(input)), DataKind.R4); + public static Scalar ToFloat(this Scalar input) => new ImplScalar(Contracts.CheckRef(input, nameof(input)), InternalDataKind.R4); /// /// Convert to array of floats. /// /// The input column. /// Column with array of floats. - public static Vector ToFloat(this Vector input) => new ImplVector(Contracts.CheckRef(input, nameof(input)), DataKind.R4); + public static Vector ToFloat(this Vector input) => new ImplVector(Contracts.CheckRef(input, nameof(input)), InternalDataKind.R4); /// /// Convert to variable array of floats. /// /// The input column. /// Column with variable array of floats. - public static VarVector ToFloat(this VarVector input) => new ImplVarVector(Contracts.CheckRef(input, nameof(input)), DataKind.R4); + public static VarVector ToFloat(this VarVector input) => new ImplVarVector(Contracts.CheckRef(input, nameof(input)), InternalDataKind.R4); #endregion #region For sbyte inputs. @@ -61,21 +61,21 @@ public static partial class ConvertStaticExtensions /// /// The input column. /// Float column. - public static Scalar ToFloat(this Scalar input) => new ImplScalar(Contracts.CheckRef(input, nameof(input)), DataKind.R4); + public static Scalar ToFloat(this Scalar input) => new ImplScalar(Contracts.CheckRef(input, nameof(input)), InternalDataKind.R4); /// /// Convert to array of floats. /// /// The input column. /// Column with array of floats. - public static Vector ToFloat(this Vector input) => new ImplVector(Contracts.CheckRef(input, nameof(input)), DataKind.R4); + public static Vector ToFloat(this Vector input) => new ImplVector(Contracts.CheckRef(input, nameof(input)), InternalDataKind.R4); /// /// Convert to variable array of floats. /// /// The input column. /// Column with variable array of floats. - public static VarVector ToFloat(this VarVector input) => new ImplVarVector(Contracts.CheckRef(input, nameof(input)), DataKind.R4); + public static VarVector ToFloat(this VarVector input) => new ImplVarVector(Contracts.CheckRef(input, nameof(input)), InternalDataKind.R4); #endregion #region For short inputs. @@ -84,21 +84,21 @@ public static partial class ConvertStaticExtensions /// /// The input column. /// Float column. - public static Scalar ToFloat(this Scalar input) => new ImplScalar(Contracts.CheckRef(input, nameof(input)), DataKind.R4); + public static Scalar ToFloat(this Scalar input) => new ImplScalar(Contracts.CheckRef(input, nameof(input)), InternalDataKind.R4); /// /// Convert to array of floats. /// /// The input column. /// Column with array of floats. - public static Vector ToFloat(this Vector input) => new ImplVector(Contracts.CheckRef(input, nameof(input)), DataKind.R4); + public static Vector ToFloat(this Vector input) => new ImplVector(Contracts.CheckRef(input, nameof(input)), InternalDataKind.R4); /// /// Convert to variable array of floats. /// /// The input column. /// Column with variable array of floats. - public static VarVector ToFloat(this VarVector input) => new ImplVarVector(Contracts.CheckRef(input, nameof(input)), DataKind.R4); + public static VarVector ToFloat(this VarVector input) => new ImplVarVector(Contracts.CheckRef(input, nameof(input)), InternalDataKind.R4); #endregion #region For int inputs. @@ -107,21 +107,21 @@ public static partial class ConvertStaticExtensions /// /// The input column. /// Float column. - public static Scalar ToFloat(this Scalar input) => new ImplScalar(Contracts.CheckRef(input, nameof(input)), DataKind.R4); + public static Scalar ToFloat(this Scalar input) => new ImplScalar(Contracts.CheckRef(input, nameof(input)), InternalDataKind.R4); /// /// Convert to array of floats. /// /// The input column. /// Column with array of floats. - public static Vector ToFloat(this Vector input) => new ImplVector(Contracts.CheckRef(input, nameof(input)), DataKind.R4); + public static Vector ToFloat(this Vector input) => new ImplVector(Contracts.CheckRef(input, nameof(input)), InternalDataKind.R4); /// /// Convert to variable array of floats. /// /// The input column. /// Column with variable array of floats. - public static VarVector ToFloat(this VarVector input) => new ImplVarVector(Contracts.CheckRef(input, nameof(input)), DataKind.R4); + public static VarVector ToFloat(this VarVector input) => new ImplVarVector(Contracts.CheckRef(input, nameof(input)), InternalDataKind.R4); #endregion #region For long inputs. @@ -130,21 +130,21 @@ public static partial class ConvertStaticExtensions /// /// The input column. /// Float column. - public static Scalar ToFloat(this Scalar input) => new ImplScalar(Contracts.CheckRef(input, nameof(input)), DataKind.R4); + public static Scalar ToFloat(this Scalar input) => new ImplScalar(Contracts.CheckRef(input, nameof(input)), InternalDataKind.R4); /// /// Convert to array of floats. /// /// The input column. /// Column with array of floats. - public static Vector ToFloat(this Vector input) => new ImplVector(Contracts.CheckRef(input, nameof(input)), DataKind.R4); + public static Vector ToFloat(this Vector input) => new ImplVector(Contracts.CheckRef(input, nameof(input)), InternalDataKind.R4); /// /// Convert to variable array of floats. /// /// The input column. /// Column with variable array of floats. - public static VarVector ToFloat(this VarVector input) => new ImplVarVector(Contracts.CheckRef(input, nameof(input)), DataKind.R4); + public static VarVector ToFloat(this VarVector input) => new ImplVarVector(Contracts.CheckRef(input, nameof(input)), InternalDataKind.R4); #endregion #region For byte inputs. @@ -153,21 +153,21 @@ public static partial class ConvertStaticExtensions /// /// The input column. /// Float column. - public static Scalar ToFloat(this Scalar input) => new ImplScalar(Contracts.CheckRef(input, nameof(input)), DataKind.R4); + public static Scalar ToFloat(this Scalar input) => new ImplScalar(Contracts.CheckRef(input, nameof(input)), InternalDataKind.R4); /// /// Convert to array of floats. /// /// The input column. /// Column with array of floats. - public static Vector ToFloat(this Vector input) => new ImplVector(Contracts.CheckRef(input, nameof(input)), DataKind.R4); + public static Vector ToFloat(this Vector input) => new ImplVector(Contracts.CheckRef(input, nameof(input)), InternalDataKind.R4); /// /// Convert to variable array of floats. /// /// The input column. /// Column with variable array of floats. - public static VarVector ToFloat(this VarVector input) => new ImplVarVector(Contracts.CheckRef(input, nameof(input)), DataKind.R4); + public static VarVector ToFloat(this VarVector input) => new ImplVarVector(Contracts.CheckRef(input, nameof(input)), InternalDataKind.R4); #endregion #region For ushort inputs. @@ -176,21 +176,21 @@ public static partial class ConvertStaticExtensions /// /// The input column. /// Float column. - public static Scalar ToFloat(this Scalar input) => new ImplScalar(Contracts.CheckRef(input, nameof(input)), DataKind.R4); + public static Scalar ToFloat(this Scalar input) => new ImplScalar(Contracts.CheckRef(input, nameof(input)), InternalDataKind.R4); /// /// Convert to array of floats. /// /// The input column. /// Column with array of floats. - public static Vector ToFloat(this Vector input) => new ImplVector(Contracts.CheckRef(input, nameof(input)), DataKind.R4); + public static Vector ToFloat(this Vector input) => new ImplVector(Contracts.CheckRef(input, nameof(input)), InternalDataKind.R4); /// /// Convert to variable array of floats. /// /// The input column. /// Column with variable array of floats. - public static VarVector ToFloat(this VarVector input) => new ImplVarVector(Contracts.CheckRef(input, nameof(input)), DataKind.R4); + public static VarVector ToFloat(this VarVector input) => new ImplVarVector(Contracts.CheckRef(input, nameof(input)), InternalDataKind.R4); #endregion #region For uint inputs. @@ -199,21 +199,21 @@ public static partial class ConvertStaticExtensions /// /// The input column. /// Float column. - public static Scalar ToFloat(this Scalar input) => new ImplScalar(Contracts.CheckRef(input, nameof(input)), DataKind.R4); + public static Scalar ToFloat(this Scalar input) => new ImplScalar(Contracts.CheckRef(input, nameof(input)), InternalDataKind.R4); /// /// Convert to array of floats. /// /// The input column. /// Column with array of floats. - public static Vector ToFloat(this Vector input) => new ImplVector(Contracts.CheckRef(input, nameof(input)), DataKind.R4); + public static Vector ToFloat(this Vector input) => new ImplVector(Contracts.CheckRef(input, nameof(input)), InternalDataKind.R4); /// /// Convert to variable array of floats. /// /// The input column. /// Column with variable array of floats. - public static VarVector ToFloat(this VarVector input) => new ImplVarVector(Contracts.CheckRef(input, nameof(input)), DataKind.R4); + public static VarVector ToFloat(this VarVector input) => new ImplVarVector(Contracts.CheckRef(input, nameof(input)), InternalDataKind.R4); #endregion #region For ulong inputs. @@ -222,21 +222,21 @@ public static partial class ConvertStaticExtensions /// /// The input column. /// Float column. - public static Scalar ToFloat(this Scalar input) => new ImplScalar(Contracts.CheckRef(input, nameof(input)), DataKind.R4); + public static Scalar ToFloat(this Scalar input) => new ImplScalar(Contracts.CheckRef(input, nameof(input)), InternalDataKind.R4); /// /// Convert to array of floats. /// /// The input column. /// Column with array of floats. - public static Vector ToFloat(this Vector input) => new ImplVector(Contracts.CheckRef(input, nameof(input)), DataKind.R4); + public static Vector ToFloat(this Vector input) => new ImplVector(Contracts.CheckRef(input, nameof(input)), InternalDataKind.R4); /// /// Convert to variable array of floats. /// /// The input column. /// Column with variable array of floats. - public static VarVector ToFloat(this VarVector input) => new ImplVarVector(Contracts.CheckRef(input, nameof(input)), DataKind.R4); + public static VarVector ToFloat(this VarVector input) => new ImplVarVector(Contracts.CheckRef(input, nameof(input)), InternalDataKind.R4); #endregion #region For bool inputs. @@ -245,21 +245,21 @@ public static partial class ConvertStaticExtensions /// /// The input column. /// Float column. - public static Scalar ToFloat(this Scalar input) => new ImplScalar(Contracts.CheckRef(input, nameof(input)), DataKind.R4); + public static Scalar ToFloat(this Scalar input) => new ImplScalar(Contracts.CheckRef(input, nameof(input)), InternalDataKind.R4); /// /// Convert to array of floats. /// /// The input column. /// Column with array of floats. - public static Vector ToFloat(this Vector input) => new ImplVector(Contracts.CheckRef(input, nameof(input)), DataKind.R4); + public static Vector ToFloat(this Vector input) => new ImplVector(Contracts.CheckRef(input, nameof(input)), InternalDataKind.R4); /// /// Convert to variable array of floats. /// /// The input column. /// Column with variable array of floats. - public static VarVector ToFloat(this VarVector input) => new ImplVarVector(Contracts.CheckRef(input, nameof(input)), DataKind.R4); + public static VarVector ToFloat(this VarVector input) => new ImplVarVector(Contracts.CheckRef(input, nameof(input)), InternalDataKind.R4); #endregion } diff --git a/src/Microsoft.ML.StaticPipe/StaticSchemaShape.cs b/src/Microsoft.ML.StaticPipe/StaticSchemaShape.cs index 1f35d211a5..e830b29934 100644 --- a/src/Microsoft.ML.StaticPipe/StaticSchemaShape.cs +++ b/src/Microsoft.ML.StaticPipe/StaticSchemaShape.cs @@ -324,7 +324,7 @@ private static Type GetTypeOrNull(DataViewSchema.Column col) /// /// Note that this can return a different type than the actual physical representation type, for example, for - /// the return type is , even though we do not use that + /// the return type is , even though we do not use that /// type for communicating text. /// /// The basic type used to represent an item type in the static pipeline diff --git a/src/Microsoft.ML.StaticPipe/TextLoaderStatic.cs b/src/Microsoft.ML.StaticPipe/TextLoaderStatic.cs index e19f40cf88..b27a1ddd58 100644 --- a/src/Microsoft.ML.StaticPipe/TextLoaderStatic.cs +++ b/src/Microsoft.ML.StaticPipe/TextLoaderStatic.cs @@ -131,7 +131,7 @@ internal Context(Reconciler rec) /// /// The zero-based index of the field to read from. /// The column representation. - public Scalar LoadBool(int ordinal) => Load(DataKind.BL, ordinal); + public Scalar LoadBool(int ordinal) => Load(InternalDataKind.BL, ordinal); /// /// Reads a vector Boolean column from a range of fields in the text file. @@ -141,7 +141,7 @@ internal Context(Reconciler rec) /// Note that if this is null, it will read to the end of the line. The file(s) /// will be inspected to get the length of the type. /// The column representation. - public Vector LoadBool(int minOrdinal, int? maxOrdinal) => Load(DataKind.BL, minOrdinal, maxOrdinal); + public Vector LoadBool(int minOrdinal, int? maxOrdinal) => Load(InternalDataKind.BL, minOrdinal, maxOrdinal); /// /// Create a representation for a key loaded from TextLoader as an unsigned integer (32 bits). @@ -150,14 +150,14 @@ internal Context(Reconciler rec) /// If specified, it's the count or cardinality of valid key values. /// Using null initalizes to uint.MaxValue /// The column representation. - public Key LoadKey(int ordinal, ulong? keyCount) => Load(DataKind.U4, ordinal, keyCount); + public Key LoadKey(int ordinal, ulong? keyCount) => Load(InternalDataKind.U4, ordinal, keyCount); /// /// Reads a scalar single-precision floating point column from a single field in the text file. /// /// The zero-based index of the field to read from. /// The column representation. - public Scalar LoadFloat(int ordinal) => Load(DataKind.R4, ordinal); + public Scalar LoadFloat(int ordinal) => Load(InternalDataKind.R4, ordinal); /// /// Reads a vector single-precision column from a range of fields in the text file. @@ -167,14 +167,14 @@ internal Context(Reconciler rec) /// Note that if this is null, it will read to the end of the line. The file(s) /// will be inspected to get the length of the type. /// The column representation. - public Vector LoadFloat(int minOrdinal, int? maxOrdinal) => Load(DataKind.R4, minOrdinal, maxOrdinal); + public Vector LoadFloat(int minOrdinal, int? maxOrdinal) => Load(InternalDataKind.R4, minOrdinal, maxOrdinal); /// /// Reads a scalar double-precision floating point column from a single field in the text file. /// /// The zero-based index of the field to read from. /// The column representation. - public Scalar LoadDouble(int ordinal) => Load(DataKind.R8, ordinal); + public Scalar LoadDouble(int ordinal) => Load(InternalDataKind.R8, ordinal); /// /// Reads a vector double-precision column from a range of fields in the text file. @@ -184,14 +184,14 @@ internal Context(Reconciler rec) /// Note that if this is null, it will read to the end of the line. The file(s) /// will be inspected to get the length of the type. /// The column representation. - public Vector LoadDouble(int minOrdinal, int? maxOrdinal) => Load(DataKind.R8, minOrdinal, maxOrdinal); + public Vector LoadDouble(int minOrdinal, int? maxOrdinal) => Load(InternalDataKind.R8, minOrdinal, maxOrdinal); /// /// Reads a scalar textual column from a single field in the text file. /// /// The zero-based index of the field to read from. /// The column representation. - public Scalar LoadText(int ordinal) => Load(DataKind.TX, ordinal); + public Scalar LoadText(int ordinal) => Load(InternalDataKind.TX, ordinal); /// /// Reads a vector textual column from a range of fields in the text file. @@ -201,15 +201,15 @@ internal Context(Reconciler rec) /// Note that if this is null, it will read to the end of the line. The file(s) /// will be inspected to get the length of the type. /// The column representation. - public Vector LoadText(int minOrdinal, int? maxOrdinal) => Load(DataKind.TX, minOrdinal, maxOrdinal); + public Vector LoadText(int minOrdinal, int? maxOrdinal) => Load(InternalDataKind.TX, minOrdinal, maxOrdinal); - private Scalar Load(DataKind kind, int ordinal) + private Scalar Load(InternalDataKind kind, int ordinal) { Contracts.CheckParam(ordinal >= 0, nameof(ordinal), "Should be non-negative"); return new MyScalar(_rec, kind, ordinal); } - private Vector Load(DataKind kind, int minOrdinal, int? maxOrdinal) + private Vector Load(InternalDataKind kind, int minOrdinal, int? maxOrdinal) { Contracts.CheckParam(minOrdinal >= 0, nameof(minOrdinal), "Should be non-negative"); var v = maxOrdinal >= minOrdinal; @@ -217,7 +217,7 @@ private Vector Load(DataKind kind, int minOrdinal, int? maxOrdinal) return new MyVector(_rec, kind, minOrdinal, maxOrdinal); } - private Key Load(DataKind kind, int ordinal, ulong? keyCount) + private Key Load(InternalDataKind kind, int ordinal, ulong? keyCount) { Contracts.CheckParam(ordinal >= 0, nameof(ordinal), "Should be non-negative"); return new MyKey(_rec, kind, ordinal, keyCount); @@ -230,14 +230,14 @@ private Key Load(DataKind kind, int ordinal, ulong? keyCount) private class MyKey : Key, IPipelineArgColumn { // The storage type that the targeted content would be loaded as. - private readonly DataKind _kind; + private readonly InternalDataKind _kind; // The position where the key value gets read from. private readonly int _oridinal; // The count or cardinality of valid key values. Its value is null if unbounded. private readonly ulong? _keyCount; // Contstuct a representation for a key-typed column loaded from a text file. Key values are assumed to be contiguous. - public MyKey(Reconciler rec, DataKind kind, int oridinal, ulong? keyCount=null) + public MyKey(Reconciler rec, InternalDataKind kind, int oridinal, ulong? keyCount=null) : base(rec, null) { _kind = kind; @@ -259,10 +259,10 @@ public TextLoader.Column Create() private class MyScalar : Scalar, IPipelineArgColumn { - private readonly DataKind _kind; + private readonly InternalDataKind _kind; private readonly int _ordinal; - public MyScalar(Reconciler rec, DataKind kind, int ordinal) + public MyScalar(Reconciler rec, InternalDataKind kind, int ordinal) : base(rec, null) { _kind = kind; @@ -281,11 +281,11 @@ public TextLoader.Column Create() private class MyVector : Vector, IPipelineArgColumn { - private readonly DataKind _kind; + private readonly InternalDataKind _kind; private readonly int _min; private readonly int? _max; - public MyVector(Reconciler rec, DataKind kind, int min, int? max) + public MyVector(Reconciler rec, InternalDataKind kind, int min, int? max) : base(rec, null) { _kind = kind; diff --git a/src/Microsoft.ML.StaticPipe/TransformsStatic.cs b/src/Microsoft.ML.StaticPipe/TransformsStatic.cs index 4e42fd722c..69645722e7 100644 --- a/src/Microsoft.ML.StaticPipe/TransformsStatic.cs +++ b/src/Microsoft.ML.StaticPipe/TransformsStatic.cs @@ -889,14 +889,14 @@ public static partial class ConvertStaticExtensions private interface IConvertCol { PipelineColumn Input { get; } - DataKind Kind { get; } + InternalDataKind Kind { get; } } private sealed class ImplScalar : Scalar, IConvertCol { public PipelineColumn Input { get; } - public DataKind Kind { get; } - public ImplScalar(PipelineColumn input, DataKind kind) : base(Rec.Inst, input) + public InternalDataKind Kind { get; } + public ImplScalar(PipelineColumn input, InternalDataKind kind) : base(Rec.Inst, input) { Input = input; Kind = kind; @@ -906,8 +906,8 @@ public ImplScalar(PipelineColumn input, DataKind kind) : base(Rec.Inst, input) private sealed class ImplVector : Vector, IConvertCol { public PipelineColumn Input { get; } - public DataKind Kind { get; } - public ImplVector(PipelineColumn input, DataKind kind) : base(Rec.Inst, input) + public InternalDataKind Kind { get; } + public ImplVector(PipelineColumn input, InternalDataKind kind) : base(Rec.Inst, input) { Input = input; Kind = kind; @@ -917,8 +917,8 @@ public ImplVector(PipelineColumn input, DataKind kind) : base(Rec.Inst, input) private sealed class ImplVarVector : VarVector, IConvertCol { public PipelineColumn Input { get; } - public DataKind Kind { get; } - public ImplVarVector(PipelineColumn input, DataKind kind) : base(Rec.Inst, input) + public InternalDataKind Kind { get; } + public ImplVarVector(PipelineColumn input, InternalDataKind kind) : base(Rec.Inst, input) { Input = input; Kind = kind; @@ -936,7 +936,7 @@ public override IEstimator Reconcile(IHostEnvironment env, Pipelin for (int i = 0; i < toOutput.Length; ++i) { var tcol = (IConvertCol)toOutput[i]; - infos[i] = new TypeConvertingEstimator.ColumnInfo(outputNames[toOutput[i]], tcol.Kind, inputNames[tcol.Input]); + infos[i] = new TypeConvertingEstimator.ColumnInfo(outputNames[toOutput[i]], tcol.Kind.ToDataKind(), inputNames[tcol.Input]); } return new TypeConvertingEstimator(env, infos); } diff --git a/src/Microsoft.ML.Transforms/MissingValueHandlingTransformer.cs b/src/Microsoft.ML.Transforms/MissingValueHandlingTransformer.cs index 2663b37257..7016cb40f1 100644 --- a/src/Microsoft.ML.Transforms/MissingValueHandlingTransformer.cs +++ b/src/Microsoft.ML.Transforms/MissingValueHandlingTransformer.cs @@ -181,11 +181,11 @@ internal static IDataTransform Create(IHostEnvironment env, Options options, IDa // Add a ConvertTransform column if necessary. if (!identity) { - if (!replaceItemType.RawType.TryGetDataKind(out DataKind replaceItemTypeKind)) + if (!replaceItemType.RawType.TryGetDataKind(out InternalDataKind replaceItemTypeKind)) { throw h.Except("Cannot get a DataKind for type '{0}'", replaceItemType.RawType); } - naConvCols.Add(new TypeConvertingEstimator.ColumnInfo(tmpIsMissingColName, replaceItemTypeKind, tmpIsMissingColName)); + naConvCols.Add(new TypeConvertingEstimator.ColumnInfo(tmpIsMissingColName, replaceItemTypeKind.ToDataKind(), tmpIsMissingColName)); } // Add the NAReplaceTransform column. diff --git a/src/Microsoft.ML.Transforms/Text/StopWordsRemovingTransformer.cs b/src/Microsoft.ML.Transforms/Text/StopWordsRemovingTransformer.cs index a05255da22..9c5015722f 100644 --- a/src/Microsoft.ML.Transforms/Text/StopWordsRemovingTransformer.cs +++ b/src/Microsoft.ML.Transforms/Text/StopWordsRemovingTransformer.cs @@ -741,7 +741,7 @@ private IDataLoader GetLoaderForStopwords(IChannel ch, string dataFile, Host, columns: new[] { - new TextLoader.Column(stopwordsCol, DataKind.TX, 0) + new TextLoader.Column(stopwordsCol, DataKind.String, 0) }, dataSample: fileSource).Read(fileSource) as IDataLoader; } diff --git a/test/BaselineOutput/Common/EntryPoints/core_manifest.json b/test/BaselineOutput/Common/EntryPoints/core_manifest.json index b36ebd329f..be20dafb9c 100644 --- a/test/BaselineOutput/Common/EntryPoints/core_manifest.json +++ b/test/BaselineOutput/Common/EntryPoints/core_manifest.json @@ -191,8 +191,8 @@ "Desc": "Type of the items in the column", "Required": false, "SortOrder": 150.0, - "IsNullable": true, - "Default": null + "IsNullable": false, + "Default": "R4" }, { "Name": "Source", diff --git a/test/BaselineOutput/Common/EntryPoints/ensemble-model0-stats.txt b/test/BaselineOutput/Common/EntryPoints/ensemble-model0-stats.txt index 057ef0ff87..adf771b7f1 100644 --- a/test/BaselineOutput/Common/EntryPoints/ensemble-model0-stats.txt +++ b/test/BaselineOutput/Common/EntryPoints/ensemble-model0-stats.txt @@ -2,8 +2,8 @@ #@ header+ #@ sep=tab #@ col={name={Count of training examples} type=I8 src=0} -#@ col={name={Residual Deviance} type=R4 src=1} -#@ col={name={Null Deviance} type=R4 src=2} +#@ col={name={Residual Deviance} src=1} +#@ col={name={Null Deviance} src=2} #@ col=AIC:R4:3 #@ col=BiasEstimate:R4:4 #@ col=BiasStandardError:R4:5 diff --git a/test/BaselineOutput/Common/EntryPoints/ensemble-model2-stats.txt b/test/BaselineOutput/Common/EntryPoints/ensemble-model2-stats.txt index dbb2224574..bc4bcd28d2 100644 --- a/test/BaselineOutput/Common/EntryPoints/ensemble-model2-stats.txt +++ b/test/BaselineOutput/Common/EntryPoints/ensemble-model2-stats.txt @@ -2,8 +2,8 @@ #@ header+ #@ sep=tab #@ col={name={Count of training examples} type=I8 src=0} -#@ col={name={Residual Deviance} type=R4 src=1} -#@ col={name={Null Deviance} type=R4 src=2} +#@ col={name={Residual Deviance} src=1} +#@ col={name={Null Deviance} src=2} #@ col=AIC:R4:3 #@ col=BiasEstimate:R4:4 #@ col=BiasStandardError:R4:5 diff --git a/test/BaselineOutput/Common/EntryPoints/lr-stats.txt b/test/BaselineOutput/Common/EntryPoints/lr-stats.txt index c467f102be..3d702f31a1 100644 --- a/test/BaselineOutput/Common/EntryPoints/lr-stats.txt +++ b/test/BaselineOutput/Common/EntryPoints/lr-stats.txt @@ -2,8 +2,8 @@ #@ header+ #@ sep=tab #@ col={name={Count of training examples} type=I8 src=0} -#@ col={name={Residual Deviance} type=R4 src=1} -#@ col={name={Null Deviance} type=R4 src=2} +#@ col={name={Residual Deviance} src=1} +#@ col={name={Null Deviance} src=2} #@ col=AIC:R4:3 #@ col=BiasEstimate:R4:4 #@ col=BiasStandardError:R4:5 diff --git a/test/BaselineOutput/Common/EntryPoints/mc-lr-stats.txt b/test/BaselineOutput/Common/EntryPoints/mc-lr-stats.txt index 3f451e8f26..e8a5f9dd5e 100644 --- a/test/BaselineOutput/Common/EntryPoints/mc-lr-stats.txt +++ b/test/BaselineOutput/Common/EntryPoints/mc-lr-stats.txt @@ -2,8 +2,8 @@ #@ header+ #@ sep=tab #@ col={name={Count of training examples} type=I8 src=0} -#@ col={name={Residual Deviance} type=R4 src=1} -#@ col={name={Null Deviance} type=R4 src=2} +#@ col={name={Residual Deviance} src=1} +#@ col={name={Null Deviance} src=2} #@ col=AIC:R4:3 #@ } Count of training examples Residual Deviance Null Deviance AIC diff --git a/test/BaselineOutput/Common/Text/ngrams.tsv b/test/BaselineOutput/Common/Text/ngrams.tsv index c64bd7feaa..32e5cf0bdf 100644 --- a/test/BaselineOutput/Common/Text/ngrams.tsv +++ b/test/BaselineOutput/Common/Text/ngrams.tsv @@ -3,8 +3,8 @@ #@ sep=tab #@ col=text:TX:0-** #@ col={name=terms type=U4 src={ min=-1 var=+} key=3941} -#@ col={name=ngrams type=R4 src={ min=-1 max=13111 vector=+}} -#@ col={name=ngramshash type=R4 src={ min=-1 max=65534 vector=+}} +#@ col={name=ngrams src={ min=-1 max=13111 vector=+}} +#@ col={name=ngramshash src={ min=-1 max=65534 vector=+}} #@ } ==RUDE== ==RUDE==|Dude, Dude, Dude,|you you you|are are are|rude rude rude|upload upload upload|that that that|carl carl carl|picture picture picture|back, back, back,|or or or|else. else. == ==|OK! OK! OK!|== ==|IM IM IM|GOING GOING GOING|TO TO TO|VANDALIZE VANDALIZE VANDALIZE|WILD WILD WILD|ONES ONES ONES|WIKI WIKI WIKI|THEN!!! THEN!!! Stop Stop|trolling, trolling, trolling,|zapatancas, zapatancas, zapatancas,|calling calling calling|me me me|a a a|liar liar liar|merely merely merely|demonstartes demonstartes demonstartes|that that|you you|arer arer arer|Zapatancas. Zapatancas. Zapatancas.|You You You|may may may|choose choose choose|to to to|chase chase chase|every every every|legitimate legitimate legitimate|editor editor editor|from from from|this this this|site site site|and and and|ignore ignore ignore|me me|but but but|I I I|am am am|an an an|editor editor|with with with|a a|record record record|that that|isnt isnt isnt|99% 99% 99%|trolling trolling trolling|and and|therefore therefore therefore|my my my|wishes wishes wishes|are are|not not not|to to|be be be|completely completely completely|ignored ignored ignored|by by by|a a|sockpuppet sockpuppet sockpuppet|like like like|yourself. yourself. yourself.|The The The|consensus consensus consensus|is is is|overwhelmingly overwhelmingly overwhelmingly|against against against|you you|and and|your your your|trollin trollin trollin|g g g|lover lover lover|Zapatancas, Zapatancas, ==You're ==You're|cool== cool== cool==|You You|seem seem seem|like like|a a|really really really|cool cool cool|guy... guy... guy...|*bursts *bursts *bursts|out out out|laughing laughing laughing|at at at|sarcasm*. sarcasm*. ":::::" ":::::|Why" Why Why|are are|you you|threatening threatening threatening|me? me? me?|I'm I'm I'm|not not|being being being|disruptive, disruptive, disruptive,|its its its|you you|who who who|is is|being being|disruptive. disruptive. ==|hey hey hey|waz waz waz|up? up? up?|== hey|ummm... ummm... ummm...|the the the|fif fif fif|four four four|fifty fifty fifty|one one one|song... song... song...|was was was|the the|info info info|inacurate? inacurate? inacurate?|did did did|i i i|spell spell spell|something something something|wrong? wrong? wrong?|hmm... hmm... hmm...|cause cause cause|i i|don't don't don't|think think think|you you|have have have|a a|right right right|to to|delete delete delete|ANYTHING ANYTHING ANYTHING|that that|is is|accurate accurate accurate|and and|that that|peple peple peple|may may|want want want|to to|read read read|about about about|fool. fool. fool.|i don't|like like|being being|pushed pushed pushed|around around around|especially especially especially|by by|some some some|little little little|boy. boy. boy.|got got got|it? it? "::::::::::I'm" "::::::::::I'm|not" not|sure sure sure|either. either. either.|I I|think think|it it it|has has has|something something|to to|do do do|with with|merely merely|ahistorical ahistorical ahistorical|vs vs vs|being being|derived derived derived|from from|pagan pagan pagan|myths. myths. myths.|Price Price Price|does does does|believe believe believe|the the|latter, latter, latter,|I'm sure|about about|other other other|CMT CMT CMT|proponents. proponents. "*::Your" "*::Your|POV" POV POV|and and|propaganda propaganda propaganda|pushing pushing pushing|is is|dully dully dully|noted. noted. noted.|However However However|listing listing listing|interesting interesting interesting|facts facts facts|in in in|a a|netral netral netral|and and|unacusitory unacusitory unacusitory|tone tone tone|is is|not not|POV. POV. POV.|You seem|to be|confusing confusing confusing|Censorship Censorship Censorship|with with|POV POV|monitoring. monitoring. monitoring.|I I|see see see|nothing nothing nothing|POV POV|expressed expressed expressed|in in|the the|listing listing|of of of|intersting intersting intersting|facts. facts. facts.|If If If|you you|want to|contribute contribute contribute|more more more|facts facts|or or|edit edit edit|wording wording wording|of of|the the|cited cited cited|fact fact fact|to to|make make make|them them them|sound sound sound|more more|netral netral|then then then|go go go|ahead. ahead. ahead.|No No No|need need need|to to|CENSOR CENSOR CENSOR|interesting interesting|factual factual factual|information. information. "==|File:Hildebrandt-Greg" "File:Hildebrandt-Greg" "File:Hildebrandt-Greg|and" and|Tim.jpg Tim.jpg Tim.jpg|listed listed listed|for for for|deletion deletion deletion|== ==|An An An|image image image|or or|media media media|file file file|that you|uploaded uploaded uploaded|or or|altered, altered, "altered,|File:Hildebrandt-Greg" and|Tim.jpg, Tim.jpg, Tim.jpg,|has has|been been been|listed listed|at "at|Wikipedia:Files" "Wikipedia:Files" "Wikipedia:Files|for" for|deletion. deletion. deletion.|Please Please Please|see see|the the|discussion discussion discussion|to to|see see|why why why|this this|is is|(you (you (you|may may|have have|to to|search search search|for for|the the|title title title|of the|image image|to to|find find find|its its|entry), entry), entry),|if if if|you are|interested interested interested|in in|it it|not being|deleted. deleted. "::::::::This" "::::::::This|is" is|a a|gross gross gross|exaggeration. exaggeration. exaggeration.|Nobody Nobody Nobody|is is|setting setting setting|a a|kangaroo kangaroo kangaroo|court. court. court.|There There There|was was|a a|simple simple simple|addition addition addition|concerning concerning concerning|the the|airline. airline. airline.|It It It|is is|the the|only only only|one one|disputed disputed disputed|here. here. "::No," "::No,|I" I|won't won't won't|unrevert unrevert unrevert|your "your|edits!""" "edits!""" "edits!""|""sounds" """sounds" """sounds|more" more|like like|you're you're you're|writing writing writing|their their their|MARKETING MARKETING "MARKETING|material!!""" "material!!""" "material!!""|Don't" Don't Don't|get get get|bossy bossy bossy|with with|me. me. me.|Or Or Or|snippy snippy snippy|either, either, either,|Miss Miss Miss|religious religious religious|Bigot! Bigot! Bigot!|Kindly Kindly Kindly|leave leave leave|your your|hatred hatred hatred|for for|Christianity Christianity Christianity|at at|DailyKos DailyKos DailyKos|before before before|you you|log log log|out out|there there there|and and|log log|in in|over over over|here here here|as as as|a...er...ahem...NPOV a...er...ahem...NPOV a...er...ahem...NPOV|editor "::::I" "::::I|heard" heard heard|Mark Mark Mark|Kermode Kermode Kermode|say say say|today today today|that that|Turbo Turbo Turbo|was was|rubbish, rubbish, rubbish,|and and|he's he's he's|never never never|*cough* *cough* *cough*|wrong! wrong! wrong!|He He He|doesn't doesn't doesn't|like like|F1 F1 F1|but but|he he he|loved loved loved|Senna Senna Senna|and and|liked liked liked|Rush Rush Rush|as as|well. well. am|a a|sock sock sock|puppet? puppet? puppet?|THAT THAT THAT|is is|my my|ban ban ban|reason? reason? reason?|This This This|is my|only only|account, account, account,|and and|thanks thanks thanks|for for|ignoring ignoring ignoring|the the|bulk bulk bulk|of of|my my|text. text. text.|Wikipedia Wikipedia Wikipedia|IS IS IS|corrupt corrupt corrupt|AND AND AND|populated populated populated|by by|idiots. idiots. idiots.|I am|free free free|to to|say say|this, this, this,|so so so|please please please|refrain refrain refrain|from from|saying saying saying|anything anything anything|like like|that that|again. again. again.|I I|didn't didn't didn't|get get|banned banned banned|for for|trolling, trolling,|or or|personal personal personal|attacks, attacks, attacks,|I I|got got|banned banned|because because because|I I|changed changed changed|an an|article article article|to to|NPOV NPOV NPOV|when when when|the the|far far far|majority majority majority|of the|editors editors editors|here here|would would would|rather rather rather|the the|see the|BNP BNP BNP|article article|as as|a a|diatribe diatribe diatribe|denouncing denouncing denouncing|the the|party. party. You|twit, twit, twit,|read read|the the|article article|before you|revert revert revert|edits. edits. edits.|Power-mad Power-mad Power-mad|jerks jerks jerks|like like|you are|ruining ruining ruining|this this|place place A A|tag tag tag|has been|placed placed placed|on on on|Jerome Jerome Jerome|leung leung leung|kam, kam, kam,|requesting requesting requesting|that that|it it|be be|speedily speedily speedily|deleted deleted deleted|from from|Wikipedia. Wikipedia. Wikipedia.|This This|has been|done done done|because because|the article|appears appears appears|to be|about about|a a|person, person, person,|group group group|of of|people, people, people,|band, band, band,|club, club, club,|company, company, company,|or or|web web web|content, content, content,|but but|it it|does does|not not|indicate indicate indicate|how how how|or or|why why|the the|subject subject subject|is "is|notable:" "notable:" "notable:|that" that|is, is, is,|why why|an article|about about|that that|subject subject|should should should|be be|included included included|in in|an an|encyclopedia. encyclopedia. encyclopedia.|Under Under Under|the the|criteria criteria criteria|for for|speedy speedy speedy|deletion, deletion, deletion,|articles articles articles|that that|do do|not not|assert assert assert|the the|subject's subject's subject's|importance importance importance|or or|significance significance significance|may may|be be|deleted deleted|at at|any any any|time. time. time.|Please the|guidelines guidelines guidelines|for for|what what what|is is|generally generally generally|accepted accepted accepted|as as|notable. notable. notable.|If you|think think|that you|can can can|assert the|notability notability notability|of the|subject, subject, subject,|you you|may may|contest contest contest|the the|deletion. deletion.|To To To|do do|this, this,|add add add|on on|the the|top top top|of the|page page page|(just (just (just|below below below|the the|existing existing existing|speedy speedy|deletion deletion|or "or|""db""" """db""" """db""|tag)" tag) tag)|and and|leave leave|a a|note note note|on the|article's article's article's|talk talk talk|page page|explaining explaining explaining|your your|position. position. position.|Please Please|do not|remove remove remove|the the|speedy deletion|tag tag|yourself, yourself, yourself,|but but|don't don't|hesitate hesitate hesitate|to to|add add|information information information|to to|the article|that that|would would|confirm confirm confirm|the subject's|notability notability|under under under|Wikipedia Wikipedia|guidelines. guidelines. guidelines.|For For For|guidelines guidelines|on on|specific specific specific|types types types|of of|articles, articles, articles,|you to|check check check|out out|our our our|criteria for|biographies, biographies, biographies,|for for|web web|sites, sites, sites,|for for|bands, bands, bands,|or or|for for|companies. companies. companies.|Feel Feel Feel|free to|leave on|my my|talk page|if have|any any|questions questions questions|about about|this. this. ==READ ==READ|THIS== THIS== THIS==|This is|Wikipedia. Wikipedia.|It a|place place|where where where|people people people|come come come|for for|infomation. infomation. infomation.|So So So|tell tell tell|me me|how how|it it|is is|that that|a a|guy guy guy|wants wants wants|to check|John John John|Cena's Cena's Cena's|recent recent recent|activity activity activity|in the|WWE WWE WWE|can't can't can't|because because|SOME SOME SOME|people people|want to|keep keep keep|the page|unedited. unedited. unedited.|It not|worth worth worth|my my|time time time|to to|try try try|to to|bring bring bring|new new new|infomation infomation infomation|to to|a a|page page|every every|month month month|or or|two two two|if you|NERDS NERDS NERDS|just just just|change change change|it it|back. back. back.|THERE THERE THERE|IS IS|NO NO NO|POINT POINT POINT|WHATSOEVER! WHATSOEVER! WHATSOEVER!|If If|I I|want to|put put put|what what|happened happened happened|at at|Backlash Backlash Backlash|I I|WILL WILL WILL|BLODDY BLODDY BLODDY|WELL WELL WELL|PUT PUT PUT|WHAT WHAT WHAT|HAPPENED HAPPENED HAPPENED|AT AT AT|BACKLASH! BACKLASH! BACKLASH!|Don't Don't|any any|of of|you you|nerds nerds nerds|try try|and and|stop stop stop|me! me! ==|Administrator Administrator Administrator|Complaint Complaint Complaint|Filed Filed Filed|Against Against Against|You You|== ==|I I|requested requested requested|that you|do not|edit edit|the article|until until until|the the|editor editor|assistance assistance assistance|has been|sought. sought. sought.|But But But|you you|still still still|added added added|and and|the the|tag tag|you you|added added|is is|fault fault fault|because because|this a|professionally professionally professionally|written written written|article, article, article,|besides besides besides|the the|last last last|section section section|there there|is is|nothing nothing|about about|the article|having having having|a a|fan fan fan|flavor flavor flavor|to to|it. it. it.|Before Before Before|you you|add add|the the|add add|again again again|please please|do do|show show show|which which which|section section|besides "the|""What" """What" """What|Ram's" Ram's Ram's|Fan's Fan's Fan's|have say|about "about|him""" "him""" "him""|seems" seems seems|written written|from from|a fan|point point point|of of|view. view. view.|This This|article article|besides section|adheres adheres adheres|to the|Wikpedia Wikpedia Wikpedia|standard standard standard|of of|writing. writing. writing.|IF IF IF|not not|please please|first first first|prove prove prove|it it|in in|my my|notes. notes. notes.|As As As|for the|resource resource resource|the the|technical technical technical|person person person|on the|team team team|is is|in the|process process process|of of|adding adding adding|the the|refernce refernce refernce|link link link|to the|source source source|after after after|which which|we we we|will will will|remove remove|that that|tag tag|as well.|Once Once Once|again not|add add|false false false|tags, tags, tags,|lets lets lets|wait wait wait|for editor|and the|administrator, administrator, administrator,|I I|did did|tell tell|the the|administrator administrator administrator|to to|look look look|at at|the the|history history history|and and|have have|provided provided provided|your your|notes notes notes|to to|him. him. him.|So So|at at|this this|time, time, time,|just just|have have|patience patience patience|and and|lets lets|wait. wait. wait.|I am|also also also|forwarding forwarding forwarding|this this|to administrator|from from|whom whom whom|I I|have have|requested requested|help. help. help.|Like Like Like|I I|said said said|before, before, before,|as as|adminstrator adminstrator adminstrator|came came came|to page|and and|made made made|the the|necessary necessary necessary|changes, changes, changes,|she she she|did did|not not|find find|the article|sub-standard, sub-standard, sub-standard,|so from|adding adding|tags. tags. a|shame shame shame|what what|people people|are are|here, here, here,|I am|disgusting disgusting disgusting|of of|you. you. ":Hello" ":Hello|Cielomobile." Cielomobile. Cielomobile.|I say|that that|I I|also also|belive belive belive|that that|the the|edits edits edits|made made|recently recently recently|to the|United United United|States-Mexico States-Mexico States-Mexico|barrier barrier barrier|page page|were were were|not not|vandalism. vandalism. vandalism.|I I|understand understand understand|that the|topic topic topic|of the|border border border|can can|be be|polemic, polemic, polemic,|but I|don't "that|User:68.2.242.165" "User:68.2.242.165" "User:68.2.242.165|was" was|vandalizing vandalizing vandalizing|the the|page. page. page.|Maybe Maybe Maybe|you you|could could could|use use use|the the|talk "page|Talk:United" "Talk:United" "Talk:United|States–Mexico" States–Mexico States–Mexico|barrier barrier|to to|lay lay lay|out out|your your|objections objections objections|to to|those those those|edits edits|without without without|deleting deleting deleting|them them|entirely. entirely. entirely.|I think|they they they|were were|good-faith good-faith good-faith|efforts efforts efforts|to to|improve improve improve|the the|article, article,|and is|also also|one one|of the|guiding guiding guiding|principles principles principles|of of|Wikipedia, Wikipedia, Wikipedia,|to to|Assume Assume Assume|Good Good Good|Faith. Faith. Faith.|It It|might might might|help help help|though, though, though,|if if|the the|author author author|of of|those edits|were were|to to|register register register|with with|Wikipedia Wikipedia|so so|the edits|won't won't|appear appear appear|merely merely|with with|an an|IP IP IP|address. address. ==|my my|removal removal removal|of of|your your|content content content|on on|DNA DNA DNA|melting melting melting|== I|removed removed removed|the the|content content|you you|placed placed|when when|creating creating creating|the article|because because|it it|was was|wrong wrong wrong|and and|unreferenced. unreferenced. unreferenced.|Mutations Mutations Mutations|do not|have "have|""weird" """weird" """weird|structures""" "structures""" "structures""|a" a|point point|mutation mutation mutation|might might|start start start|with a|single single single|nucleotide nucleotide nucleotide|mismatch, mismatch, mismatch,|but but|those those|are are|rapidly rapidly rapidly|detected detected detected|and and|repaired repaired repaired|to to|form form form|a a|stable stable stable|bonded bonded bonded|double-helix double-helix double-helix|structure, structure, structure,|and and|subsequent subsequent subsequent|rounds rounds rounds|of of|DNA DNA|replication replication replication|match match match|each each each|base base base|with with|its its|complement. complement. complement.|Perhaps Perhaps Perhaps|your your|wording wording|was was|wrong, wrong, wrong,|perhaps perhaps perhaps|you you|were were|thinking thinking thinking|of of|an an|obscure obscure obscure|related related related|technology technology technology|that have|heard heard|of, of, of,|but but|you you|didn't didn't|give give give|a a|reference reference reference|and and|I'm not|going going going|to to|help help|you you|with with|this, this,|because because|you're you're|being being|rude. rude. rude.|I I|find find|it it|disturbing disturbing disturbing|that you|apparently apparently apparently|made made|this this|scientific scientific scientific|page page|on on|wikipedia wikipedia wikipedia|claiming claiming claiming|a a|statement statement statement|of of|fact fact|that that|was was|in in|merely merely|based based based|on on|your your|own own own|speculations. speculations. wiki wiki|shold shold shold|dye!they dye!they dye!they|should be|ashame!j ashame!j I|suggest suggest suggest|you you|kill kill kill|yourself. Yes, Yes,|I I|was was|blocked blocked blocked|for for|losing losing losing|patience patience|with with|you, you, you,|and and|what what|I did|then then|would would|constitute constitute constitute|personal personal|attack. attack. attack.|Honest Honest Honest|outspoken outspoken outspoken|criticism criticism criticism|that is|based on|fact fact|is is|permitted permitted permitted|though, though,|and the|shameless shameless shameless|hate hate hate|speech speech speech|expressed expressed|here here|deserves deserves deserves|more more|than than than|just just|vocal vocal vocal|criticism. criticism. criticism.|As for|you, you,|I'll I'll I'll|discuss discuss discuss|you you|elsewhere. elsewhere. elsewhere.|This This|isn't isn't isn't|the the|place place|for for|that. that. Get Get|yourself yourself yourself|some some|help. ==|regarding regarding regarding|threats threats threats|== ==|is not|revert revert|of of|person's person's person's|edits, edits, edits,|only only|unwarranted unwarranted unwarranted|edit edit|by by|bot. bot. bot.|appeal appeal appeal|has been|made made|to to|bot bot bot|but but|presumption presumption presumption|of of|guilt guilt guilt|on on|part part part|of of|administrative administrative administrative|base base|is is|sign sign sign|of of|censorship censorship censorship|so so|made made|edits edits|again again|to see|if if|reversion reversion reversion|would would|occur occur occur|second second second|time. time.|has has|not. not. not.|please please|keep keep|baseless baseless baseless|threats threats|to to|self, self, self,|vulgar vulgar vulgar|pedant. pedant. Alright, Alright,|your your|lack lack lack|of fact|checking checking checking|and and|denial denial denial|of of|truth truth truth|is is|pathetic, pathetic, pathetic,|especially by|your your|staff. staff. staff.|Stop Stop|making making making|comments, comments, comments,|just just|to to|harass harass harass|me. me.|You You|are are|assuming assuming assuming|I'm I'm|everyone everyone everyone|who who|doesn't doesn't|agree agree agree|with with|your your|wiki wiki|article. article. article.|Pathetic. Pathetic. Pathetic.|I I|will will|continue continue continue|to to|report report report|them them|until until|your your|competent competent competent|employees employees employees|do do|the the|right right|thing. thing. Telling Telling|that you|wouldn't wouldn't wouldn't|answer answer answer|my my|question. question. question.|You are|a a|hypocrit hypocrit hypocrit|as as|anyone anyone anyone|can can|see ==|YOUR YOUR YOUR|INFORMATIONS INFORMATIONS INFORMATIONS|ARE ARE ARE|MISLEADING MISLEADING MISLEADING|AND AND|FULL FULL FULL|OF OF OF|ERRORS. ERRORS. ERRORS.|== ERRORS.|IF IF|THIS THIS THIS|IS IS|THE THE THE|WAY WAY WAY|YOU YOU YOU|SERVE SERVE SERVE|PEOPLE, PEOPLE, PEOPLE,|I I|PITY PITY PITY|THEM THEM THEM|FOR FOR FOR|BEING BEING BEING|BRAINWASHED BRAINWASHED BRAINWASHED|WITH WITH WITH|LIES LIES LIES|OF OF|YOU. YOU. AND|I I|EVEN EVEN EVEN|PUT PUT|A A|LINK LINK LINK|TO TO|A A|HIGHLIGHTS HIGHLIGHTS HIGHLIGHTS|VIDEO VIDEO VIDEO|ON ON ON|YOUTUBE YOUTUBE Wind Wind|in the|Sahara Sahara Sahara|rawks, rawks, rawks,|too. too. too.|Much Much Much|more more|accessible accessible accessible|than than|7 7 7|pillars. pillars. "::Excellent," "::Excellent,|thanks" for|looking looking looking|into into into|it. it.|Some Some Some|socks socks socks|are are|quite quite quite|dumb... dumb... Hypocrit! Hypocrit!|you you|just just|cited cited|a a|newspaper newspaper newspaper|that that|claims claims claims|to be|reliable. reliable. reliable.|i i|will will|incorporate incorporate incorporate|and and|make make|a newspaper|company company company|then then|ill ill ill|site site|it. it.|its its|called called called|TEADRINKERNEWS.com TEADRINKERNEWS.com TEADRINKERNEWS.com|this site|has has|no no no|merit merit merit|and and|you have|no no|integrity! integrity! ==|Conflict Conflict Conflict|of of|interest interest interest|== ==|You a|person person|who is|doing doing doing|some some|sort sort sort|of of|harm harm harm|to to|this this|lady lady lady|Saman Saman Saman|Hasnain.. Hasnain.. Hasnain..|It is|apparent apparent apparent|that are|making making|sure sure|that that|her her her|name name name|is is|defamed.... defamed.... defamed....|Okay Okay Okay|no no|problem... problem... problem...|Will Will Will|get get|a a|better better better|source... source... source...|you are|playing playing playing|dirty... dirty... dirty...|DOG DOG DOG|Sonisona Sonisona REALLY REALLY|REALLY REALLY|ANGRY ANGRY ANGRY|NOW NOW NOW|GRRRRRRRRRRRR GRRRRRRRRRRRR "::I" "::I|also" also|found found found|use use|of the|word word "word|""humanists""" """humanists""" """humanists""|confusing." confusing. confusing.|The The|types of|people people|listed listed|preceding preceding "preceding|""humanists""" """humanists""|are" are|defined defined defined|by by|what what|they they|*do* *do* *do*|(i.e. (i.e. (i.e.|study, study, study,|teach, teach, teach,|do do|medical medical medical|research) research) research)|which which|makes makes makes|sense sense sense|in the|context context context|of of|talking talking talking|about the|commonplace commonplace commonplace|book book book|as as|one of|their their|tools. tools. "tools.|""Humanists""" """Humanists""" """Humanists""|defines" defines defines|people people|of of|a a|certain certain certain|ethical ethical ethical|ideologywhat ideologywhat ideologywhat|does does|that that|have with|the the|function function function|of a|commonplace commonplace|book? book? book?|Is Is Is|the the|use book|particularly particularly particularly|defined by|one's one's one's|world world world|perspective? perspective? perspective?|To To|me me|this this|would would|be be|akin akin akin|to to|writing "writing|""many" """many" """many|blogs" blogs blogs|are are|maintained maintained maintained|by by|writers, writers, writers,|professors, professors, professors,|lawyers, lawyers, lawyers,|editorialists, editorialists, editorialists,|and "and|Republicans/Democrats""" "Republicans/Democrats""" "Republicans/Democrats""|in" about|blogs. blogs. blogs.|True True True|though though though|it it|may may|be, be, be,|it it|confuses confuses confuses|the the|reader reader reader|into into|thinking thinking|that subject|being being|written written|about about|is is|somehow somehow somehow|ideologically ideologically ideologically|specific specific|when when|it is|not. ":the" ":the|category" category category|was was|unnecesary, unnecesary, unnecesary,|as as|explained explained explained|in my|edit edit|summary. summary. summary.|Your Your Your|threats threats|are are|disgrace disgrace disgrace|to to|wikipedia. wikipedia. I|hate hate|you. you.|== you.|I hate|you! you! ==Drovers' ==Drovers'|Award== Award== Award==|Better Better Better|you you|hear hear hear|it it|from from|me, me, me,|and and|early, early, early,|I "I|suppose:" "suppose:" "suppose:|The" The|Wikipedia Wikipedia|logo logo logo|is "is|""All" """All" """All|Rights" Rights Rights|Reserved, Reserved, Reserved,|Wikimedia Wikimedia Wikimedia|Foundation, Foundation, "Foundation,|Inc.""," "Inc.""," "Inc."",|and" and|use of|it is|governed governed governed|by by|the the|Wikimedia Wikimedia|visual visual visual|identity identity identity|guidelines, guidelines, guidelines,|which which|states states states|that "that|""no" """no" """no|derivative" derivative derivative|of Wikimedia|logo logo|can be|published published published|without without|prior prior prior|approval approval approval|from from|the "the|Foundation.""" "Foundation.""" Please|stop. stop. stop.|If you|continue to|vandalize vandalize vandalize|Wikipedia, Wikipedia,|you you|will will|be be|blocked blocked|from from|editing. editing. editing.|| | ==|removing removing removing|a a|deletion deletion|review?!? review?!? review?!?|== "==|WP:SNOW" "WP:SNOW" "WP:SNOW|doesn't" doesn't|apply apply apply|to to|my my|deletion deletion|review review review|since since since|the the|issue issue issue|is is|controversial. controversial. Oooooh Oooooh|thank thank thank|you you|Mr. Mr. Mr.|DietLimeCola. DietLimeCola. DietLimeCola.|Once Once|again, again, again,|nice nice nice|job job job|trying trying trying|to to|pretend pretend pretend|you have|some some|authority authority authority|over over|anybody anybody anybody|here. here.|You a|wannabe wannabe wannabe|admin, admin, admin,|which which|is is|even even even|sadder sadder sadder|than than|a a|real real real|admin admin Grow Grow|up up up|you you|biased biased biased|child. child. ":Saved" ":Saved|without" without|renaming; renaming; renaming;|marked marked marked|for for|rapid rapid rapid|del. del. ==Terrible== ==Terrible==|Anyone Anyone Anyone|else else else|agree agree|this this|list list list|is is|garbage? garbage? ==|DON'T DON'T DON'T|INTERFERE! INTERFERE! INTERFERE!|== ==|Look, Look, Look,|I am|telling telling "telling|you:" "you:" "you:|YOU" YOU|DON'T DON'T|INTERFERE INTERFERE INTERFERE|between between between|me me|and and|Ohnoitsjamie. Ohnoitsjamie. Ohnoitsjamie.|He He|is a|filthy filthy filthy|hog, hog, hog,|an an|oldest oldest oldest|enemy, enemy, enemy,|and and|i i|can can|go go|to to|any any|extent extent extent|to to|insult insult insult|him him him|to the|fullest fullest fullest|extent. extent. extent.|So So|be be|a a|good good good|boy, boy, boy,|and and|eat eat eat|potato potato potato|crisps crisps crisps|(Yummy... (Yummy... (Yummy...|yummy yummy yummy|... ... ...|munch munch munch|crunch. crunch. crunch.|- - ":Going" ":Going|by" by|immediate immediate immediate|place place|of of|origin origin origin|is is|much much much|more more|in in|keeping keeping keeping|with the|definition definition definition|of "of|""Hispanic" """Hispanic" """Hispanic|or" "or|Latino""." "Latino""." "Latino"".|You're" You're You're|acting acting acting|in in|good good|faith, faith, faith,|obviously, obviously, obviously,|but but|claiming claiming|every every|Hispanic/Latino Hispanic/Latino Hispanic/Latino|person person|based on|ancestry ancestry ancestry|is is|too too too|OR, OR, OR,|too too|subjective, subjective, subjective,|as as|can be|seen seen seen|from from|all all all|that that|explaining explaining|you've you've you've|had had had|to to|do. do. do.|There There|is a|way way way|to to|include include include|these these these|people people|we're we're "we're|discussing:" "discussing:" "discussing:|with" the|support support support|of of|reliable reliable reliable|sources sources sources|that that|refer refer refer|to to|them them|as as|Hispanic Hispanic Hispanic|or or|Latino, Latino, Latino,|something something|that that|ideally ideally ideally|should be|done done|for for|everyone everyone|on the|list. list. ==|Pathetic Pathetic Pathetic|== ==|This This|user user user|needs needs needs|a a|life life See See|the the|section section|below below|about the|Macedonian Macedonian Macedonian|last last|names, names, names,|and and|common common common|endings endings endings|of names,|as as|well well well|some some|common last|names names names|in the|Slavic Slavic Slavic|Languages. Languages. Hauskalainen|Tom]] Hauskalainen|Tom]]|RFC RFC RFC|Response Response Response|The "The|""criticism""" """criticism""" """criticism""|section" section|reads reads reads|like a|POV POV|essay essay essay|without without|adequate adequate adequate|references. references. references.|I have|added added|the the|appropriate appropriate appropriate|tag. tag. "tag.|[[User:" "[[User:" And, And,|frankly, frankly, frankly,|you are|just just|as as|pathetic pathetic pathetic|and and|immature, immature, immature,|clearly clearly clearly|these these|acts acts acts|of of|annoyance annoyance annoyance|are are|your your|favourite favourite favourite|past past past|time. She's She's|insane insane insane|and and|a a|zealot. zealot. ":" ":|I" I|know know know|you you|listed listed|your your|English English English|as as|on "the|""level" """level" """level|2""," "2""," "2"",|but" don't|worry, worry, worry,|you you|seem be|doing doing|nicely nicely nicely|otherwise, otherwise, otherwise,|judging judging judging|by the|same same same|page page|- -|so so|don't don't|be be|taken taken taken|aback. aback. aback.|I I|just just|wanted wanted wanted|to to|know know|if were|aware aware aware|of of|what what|you you|wrote, wrote, wrote,|and and|think think|it's it's it's|an an|interesting interesting|case. case. "case.|:" I|would would|write write write|that that|sentence sentence sentence|simply simply simply|as "as|""Theoretically" """Theoretically" """Theoretically|I" an|altruist, altruist, altruist,|but but|only only|by by|word, word, word,|not not|by by|my "my|actions.""." "actions.""." "actions."".|:" ":|PS." PS. PS.|You You|can can|reply reply reply|to to|me me|on on|this this|same same|page, page, page,|as as|I have|it it|on my|watchlist. watchlist. ==|A A|bit bit bit|of of|education education education|for for|you... you... you...|== ==|Here Here Here|is the|link to|Bay Bay Bay|Lake, Lake, Lake,|Florida. Florida. Florida.|Now, Now, Now,|what what|was was|that were|saying saying|about about|it it|NOT NOT NOT|being being|a a|city? city? city?|Educate Educate Educate|yourself yourself|a a|bit bit|before you|make make|such such such|ludicrous ludicrous ludicrous|ignorant ignorant ignorant|comments comments a|CHEATER, CHEATER, CHEATER,|and article|should should|say say|that. "::" "::|a.k.a." a.k.a. a.k.a.|(among (among (among|others) others) others)|can't can't|even even|get get|the the|air air air|dates dates dates|right, right, right,|and the|rest rest rest|is POV|that is|well-covered well-covered well-covered|in the|interesting interesting|book book|I I|cited, cited, cited,|Hollywood Hollywood Hollywood|Kryptonite. Kryptonite. "Kryptonite.|""These""" """These""" """These""|users" users users|also also|cannot cannot cannot|write write|proper proper proper|English, English, English,|which is|what what|gives gives gives|away away away|that "that|""they""" """they""" """they""|are" are|the same|user, user, user,|despite despite "despite|""their""" """their""" """their""|denials." denials. denials.|==Reply ==Reply ==Reply|to to|vandal vandal vandal|Wakkeenah== Wakkeenah== Wakkeenah==|To To|all all|the the|vandals vandals vandals|and and|so so|called called|just just|administrators, administrators, administrators,|the dates|are are|minor minor minor|problems, problems, problems,|the the|facts facts|and and|details details details|surrounding surrounding surrounding|Reeves Reeves Reeves|suicided suicided suicided|are written|well well|enough, enough, enough,|as as|everybody everybody everybody|else else|is is|reporting, reporting, reporting,|the the|fact that|Reeves Reeves|was was|to to|fight fight fight|Moore Moore Moore|next next next|day, day, day,|is also|being being|reverted, reverted, reverted,|this is|pure pure pure|vandalism. vandalism.|As As|far far|as as|spelling spelling spelling|goes goes goes|by by|Vesa Vesa Vesa|or or|Projects Projects Projects|or or|whoever, whoever, whoever,|well, well, well,|if you|keep keep|on on|repeating repeating repeating|yourself yourself|and no|time, time,|some some|spelling spelling|errors errors errors|might might|occur, occur, occur,|but but|it's it's|not not|the the|spelling spelling|that that|counts counts counts|but but|content content|which being|vandalised vandalised vandalised|by by|so just|users users|and and|administrators administrators administrators|of of|this this|so just|wikipedia. wikipedia.|And And And|it is|obvious obvious obvious|wahkeenah wahkeenah wahkeenah|has has|some some|personal personal|interest interest|in in|this, "this,|proof:" "proof:" "proof:|All" All All|over over|internet internet internet|we we|have have|Reeves' Reeves' Reeves'|death death death|explained in|detail detail detail|and and|possible possible possible|people people|involved, involved, involved,|but but|over here|he he|is is|taking taking taking|everything everything everything|down, down, down,|the the|idiotic idiotic idiotic|administratotors administratotors administratotors|are are|reversing reversing reversing|it, it, it,|thus thus thus|making making|themselves themselves themselves|look look|stupid stupid stupid|and and|ignorant ignorant|by by|not not|realizing realizing realizing|the the|historical historical historical|facts. ==|Ridiculous Ridiculous Ridiculous|== ==|It's It's It's|absolutely absolutely absolutely|RIDICULOUS RIDICULOUS RIDICULOUS|how how|long long long|and and|detailed detailed detailed|this this|article article|is. is. is.|This is|why why|Wikipedia Wikipedia|is is|laughed laughed laughed|at at|and and|why why|teachers teachers teachers|won't won't|allow allow allow|Wikipedia Wikipedia|to be|used used used|in in|schoolwork schoolwork schoolwork|1)the 1)the 1)the||diots |diots |diots|writing writing|this article|are are|trying to|demonize demonize demonize|certain certain|groups groups groups|and and|2) 2) 2)|they're they're they're|trying to|revise revise revise|the facts|of the|incident incident incident|to make|it it|seem seem|something it|wasn't. wasn't. "::I|agree." agree. agree.|Trolling Trolling Trolling|snitches snitches snitches|should be|protected. protected. protected.|Where Where Where|are are|these these|days days days|when when|crybabies crybabies crybabies|just just|haven't haven't haven't|been been|payed payed payed|attention attention attention|to to|? ? ?|Eh, Eh, Eh,|I'm I'm|waxing waxing waxing|nostalgic.... nostalgic.... ==Fixed== ==Fixed==|Hi, Hi, Hi,|I I|fixed fixed fixed|up up|the the|Religion Religion Religion|in in|Vietnam Vietnam Vietnam|lead lead lead|with with|atheism atheism atheism|as as|state state state|religion religion religion|first first|as as|per per per|your your|request, request, request,|please please|take take take|a a|look. look. look.|The The|disparity disparity disparity|in the|pie pie pie|chart chart chart|seems seems|mainly mainly mainly|caused caused caused|by by|that that|US US US|institute institute institute|counting counting counting|45% 45% 45%|ancestor ancestor ancestor|worship worship worship|and and|traditional traditional traditional|beliefs beliefs beliefs|as as|religion, religion, religion,|wheras wheras wheras|officially officially officially|that that|45% 45%|are are|non-believers. non-believers. non-believers.|It's It's|a a|grey grey grey|area... area... area...|Second Second "Second|question:" "question:" "question:|What" What What|do do|you think|is is|better better|title title|chữ chữ chữ|nho nho nho|or or|chữ chữ|Hán? Hán? Hán?|To To|my my|mind mind mind|chữ chữ|Hán Hán Hán|can can|still still|include include|Japanese Japanese Japanese|and and|Chinese, Chinese, Chinese,|but but|chữ nho|is is|clearly clearly|Vietnamese-only, Vietnamese-only, Vietnamese-only,|and and|is what|Lonely Lonely Lonely|Planet Planet Planet|uses. uses. uses.|Do Do Do|you any|view? view? view?|Cheers! Cheers! "::You" "::You|should" be|ashamed ashamed ashamed|of of|yourself yourself|for for|wasting wasting wasting|adults' adults' adults'|time, time,|you you|ridiculous ridiculous ridiculous|runt. runt. Good|god, god, god,|you you|wiped wiped wiped|out out|my my|post post post|just just|now. now. now.|You You|can't even|speak speak speak|in in|coherent coherent coherent|sentences. sentences. sentences.|Bascially, Bascially, Bascially,|you've you've|been been|busted. busted. "::::I've" "::::I've|explained" explained|beneath beneath beneath|your your|unblock unblock unblock|request request request|that I|do not|feel feel feel|comfortable comfortable comfortable|with your|proclamation. proclamation. proclamation.|You You|indicated indicated indicated|that you|did not|realize realize realize|Banglapedia Banglapedia Banglapedia|was a|copyrighted copyrighted copyrighted|source. source. source.|This This|source source|bears bears bears|copyright copyright copyright|notice notice notice|on on|every every|page. page.|How How How|can can|we we|be be|certain, certain, certain,|given given given|that, that, that,|that will|not not|copy copy copy|from from|other other|copyrighted copyrighted|sources sources|without without|noticing noticing noticing|that that|they they|cannot cannot|be be|used? used? used?|I I|myself myself myself|do comfortable|unblocking unblocking unblocking|you you|until until|you you|promise promise promise|not to|copy from|any any|source source|that you|cannot cannot|prove prove|to be|without without|copyright copyright|restriction. restriction. ":|Good" Good|grief grief grief|have have|you you|nothing nothing|useful useful useful|to your|time? time? time?|Oh Oh Oh|well, well,|I'll I'll|add add|you you|to list.|Fool Fool SOMETHING SOMETHING|AWFUL AWFUL AWFUL|IS IS|DEAD DEAD DEAD|DEAD ==|To To|the the|contributors contributors contributors|of article|== ==|Anonymiss Anonymiss Anonymiss|Madchen Madchen Madchen|has has|given given|you you|a a|cookie! cookie! cookie!|Cookies Cookies Cookies|promote promote promote|WikiLove WikiLove WikiLove|and and|hopefully hopefully hopefully|this this|one one|has has|made made|your your|day day day|better. better. better.|You can|Spread Spread Spread|the "the|""WikiLove""" """WikiLove""" """WikiLove""|by" by|giving giving giving|someone someone someone|else else|a a|cookie, cookie, cookie,|whether whether whether|it be|someone someone|you have|had had|disagreements disagreements disagreements|with with|in the|past past|or or|a good|friend. friend. friend.|To To|spread spread spread|the the|goodness goodness goodness|of of|cookies, cookies, cookies,|you can|add add|to to|someone's someone's someone's|talk page|with a|friendly friendly friendly|message, message, message,|or or|eat eat|this this|cookie cookie cookie|on the|giver's giver's giver's|talk with|! ! !|Thank Thank Thank|you you|for for|your your|hard hard hard|work, work, work,|and and|sorry sorry sorry|about about|rough rough rough|times times times|in the|past. past. past.|I'm I'm|going to|go go|edit edit|other other|articles articles|now. "now.|:" ==|get life|loser. loser. loser.|== ":::::Actually," ":::::Actually,|you" the|cockroach cockroach cockroach|that that|followed followed followed|me me|to the|notice notice|board, board, board,|and and|repeatedly repeatedly repeatedly|comes comes comes|back back back|to to|revert revert|what I|had had|written. written. written.|FYI. FYI. FYI.|206.45.24.242 206.45.24.242 206.45.24.242|(talk) (talk) I|believe believe|your your|actions actions actions|to be|pure pure|vandalism vandalism vandalism|either either either|based on|pig pig pig|ignorant, ignorant, ignorant,|racism racism racism|or or|because because|you are|being being|paid paid paid|to do|so. so. so.|But But|if if|no no|one one|else else|agrees agrees agrees|enjoy. enjoy. enjoy.|It's It's|more more|likely likely likely|no else|cares cares cares|either either|way way|you will|reduce reduce reduce|this a|stub stub stub|or or|start start|supporting supporting supporting|your own|prejudices prejudices prejudices|here. here.|It's It's|only only|wiki wiki|grow grow grow|up up|son. son. son.|This not|a a|conversation. conversation. conversation.|The The|promise promise|was a|ban ban|without without|farther farther farther|notice notice|so please|don't don't|give give|me me|any any|more more|notice notice|you you|pathetic pathetic|stooge stooge are|one the|worst worst worst|page page|vandals vandals|I have|ever ever ever|seen. seen. seen.|Your Your|repeated repeated repeated|vandalism vandalism|of a|user user|page page|shows shows shows|what what|a a|pathetically pathetically pathetically|insecure insecure insecure|individual individual individual|you you|are. are. ":::I" ":::I|think" think|the the|apple apple apple|pie pie|image image|is is|pretty pretty pretty|dated. dated. dated.|The The|expression expression "expression|""as" """as" """as|American" American American|as as|apple "apple|pie""" "pie""" "pie""|is" is|dated dated dated|and and|baseball's baseball's baseball's|no no|longer longer longer|the the|most most most|popular popular popular|sport sport sport|in the|US US|(football (football (football|is). is). is).|Plus, Plus, Plus,|it's it's|sort of|weird weird weird|having having|them them|on the|flag. flag. flag.|- ME ME|IF IF|YOU YOU|PROTECT PROTECT PROTECT|THIS THIS|PAGE PAGE PAGE|I'M I'M I'M|GONNA GONNA GONNA|KILL KILL KILL|YOUR YOUR|USER USER USER|PAGE PAGE|TOMORROW TOMORROW TOMORROW|MORNING MORNING ":::Ok," ":::Ok,|whatever," whatever, whatever,|but but|if if|this this|separate separate separate|Frankish Frankish Frankish|province province province|existed existed existed|as as|such, such, such,|then then|I I|still still|believe believe|that it|should included|as as|separate separate|entry entry entry|into into|disambiguation disambiguation disambiguation|page, page,|but I|can can|live live live|with the|current current current|version version version|of page|as threatening|me, me,|buddy? buddy? buddy?|I didn't|do do|anything anything|to to|you! you!|And And|like like|I I|care care care|about about|editing editing editing|Wikipedia. Wikipedia.|Loser. Loser. ==|April April April|2009 2009 2009|== ==|Please not|attack attack attack|other other|editors. editors. editors.|If you|continue, continue, continue,|you from|editing "Wikipedia.|:If" ":If" ":If|this" a|shared shared shared|IP IP|address, address, address,|and didn't|make make|any any|unconstructive unconstructive unconstructive|edits, edits,|consider consider consider|creating creating|an an|account account account|for for|yourself yourself|so so|you can|avoid avoid avoid|further further further|irrelevant irrelevant irrelevant|warnings. warnings. ==|HOW HOW HOW|DARE DARE DARE|YOU, YOU, YOU,|HOW DARE|YOU YOU|KUBIGULA, KUBIGULA, KUBIGULA,|HOW DARE|YOU!!!!!!!!!!!! YOU!!!!!!!!!!!! YOU!!!!!!!!!!!!|== YOU|DELETE DELETE DELETE|BRILLIANT BRILLIANT BRILLIANT|ARTICLE ARTICLE ARTICLE|ON ON|NILLIAM NILLIAM "NILLIAM|""THE" """THE" """THE|PHENOMENA""" "PHENOMENA""" "PHENOMENA""|TOWNSIRIS" TOWNSIRIS TOWNSIRIS|I I|CAN CAN CAN|SENSE SENSE SENSE|A A|PRESENCE PRESENCE PRESENCE|ABOUT ABOUT ABOUT|YOU YOU|BOY, BOY, BOY,|AN AN AN|EVIL EVIL EVIL|PRESENCE, PRESENCE, PRESENCE,|MAY MAY MAY|THE THE|FORCE FORCE FORCE|FROM FROM FROM|THE THE|SPIRIT SPIRIT SPIRIT|OF OF|A A|SEAHORSE SEAHORSE SEAHORSE|UNLEASH UNLEASH UNLEASH|THE THE|EXPECTO EXPECTO EXPECTO|PATRONUM PATRONUM PATRONUM|UPON UPON UPON|YOU, YOU,|YOU YOU|MUST MUST MUST|EXPRESS EXPRESS EXPRESS|KINDNESS KINDNESS KINDNESS|TO TO|NILLIAM NILLIAM|TOWNSIRIS, TOWNSIRIS, TOWNSIRIS,|FOR FOR|HE HE HE|IS IS|OUR OUR OUR|SAVIOUR, SAVIOUR, SAVIOUR,|THE THE|ANSWER ANSWER ANSWER|TO TO|OUR OUR|ULLILOQUITY. ULLILOQUITY. ULLILOQUITY.|IF YOU|AS AS AS|SO SO SO|MUCH MUCH MUCH|BLINK BLINK BLINK|WHEN WHEN WHEN|READING READING READING|THE THE|NEXT NEXT NEXT|ARTICLE, ARTICLE, ARTICLE,|THEN THEN THEN|YOU YOU|WILL WILL|JUST JUST JUST|MISS MISS MISS|OUT OUT OUT|THERE THERE|TIGER. TIGER. , ,|16 16 16|August August August|2008 2008 2008|(UTC) (UTC) (UTC)|*I'm *I'm *I'm|terribly terribly terribly|disappointed disappointed disappointed|by by|this. this.|There There|are are|enough enough enough|disagreeable disagreeable disagreeable|people people|on on|wikipedia. wikipedia.|I I|sincerely sincerely sincerely|hope hope hope|you you|change change|your your|mind mind|again again|and and|retire, retire, retire,|again. again.|You You|suck. suck. "suck.|14:23" "14:23" ==|Blind Blind Blind|as as|bats bats bats|== ==|Not Not Not|one you|has has|seen seen|what have|done done|to this|page. page.|Obviously Obviously Obviously|you you|rely rely rely|on on|some some|form form|of of|program program program|to revert|vandalism vandalism|and and|not not|your own|eyes. eyes. just|Jealous Jealous Jealous|== ==|that you|aren't aren't aren't|a a|part the|GAYTOURAGE... GAYTOURAGE... GAYTOURAGE...|you you|probably probably probably|don't don't|even even|now now now|how how|to to|WERQ WERQ WERQ|it! it! it!|Megna Megna Megna|James James I|hope hope|this this|helps. helps. "::I|did" did|provide provide provide|a a|notable notable notable|source source|for the|references references references|I was|providinga providinga providinga|book book|written written|by a|respected respected respected|journalist journalist journalist|from a|patient's patient's patient's|perspective. perspective. perspective.|I I|created created created|a a|separate separate|article article|for for|it, it,|with with|tons tons tons|of of|references, references, references,|and and|merely merely|put put|a reference|to to|it it|under under|See See|Also. Also. Also.|You You|deleted deleted|even even|that that|because because|it's it's|allegedly allegedly allegedly|an "an|""obscure" """obscure" """obscure|anti-psychiatry" anti-psychiatry "anti-psychiatry|book.""" "book.""" "book.""|The" The|fact are|biased biased|because have|vested vested vested|interests interests interests|to to|protect. protect. protect.|It is|people people|like who|make make|sure sure|the the|truth truth|never never|becomes becomes becomes|known known known|because it|would would|endanger endanger endanger|your your|pocketbook. pocketbook. ==Hello== ==Hello==|I to|let let let|you you|know know|how how|you a|nicer nicer nicer|person person|through through through|therapy therapy therapy|and and|talking about|your your|past past|experiences experiences experiences|that that|led led led|you be|an an|angry angry angry|antisocial antisocial antisocial|person person|today. today. Yes,|and and|this this|page page|is is|wayyyyy wayyyyy wayyyyy|too too|long long|as well.|It It|really really|needs needs|to be|condensed condensed condensed|heavily. heavily. heavily.|There are|much more|important important important|shows shows|that that|don't don't|have a|tenth tenth tenth|of what|this article|has. has. has.|Shame. Shame. ==Image ==Image|copyright copyright|problem problem problem|with "with|Image:KissBOTI.jpg==" "Image:KissBOTI.jpg==" "Image:KissBOTI.jpg==|Thank" for|uploading uploading "uploading|Image:KissBOTI.jpg." "Image:KissBOTI.jpg." "Image:KissBOTI.jpg.|However," However, However,|it it|currently currently currently|is is|missing missing missing|information information|on on|its its|copyright copyright|status. status. status.|Wikipedia Wikipedia|takes takes takes|copyright copyright|very very very|seriously. seriously. seriously.|It It|may deleted|soon, soon, soon,|unless unless unless|we we|can can|determine determine determine|the the|license license license|and source|of the|image. image. image.|If know|this this|information, information, information,|then then|you add|a a|copyright copyright|tag tag|to image|description description description|page. page.|If any|questions, questions, questions,|please please|feel feel|free to|ask ask ask|them them|at the|media media|copyright copyright|questions questions|page. page.|Thanks Thanks Thanks|again again|for your|cooperation. cooperation. Thanx Thanx|efe, efe, efe,|i i|noticed noticed noticed|you you|remove remove|800 800 800|bytes bytes bytes|of of|info info|on my|watchlist watchlist watchlist|so so|i i|went went went|into into|red red red|alert alert alert|but good|call. call. ==|Woah! Woah! Woah!|== ==|As As|someone someone|who'd who'd who'd|been been|the the|victim victim victim|of of|his his his|power power power|abuse, abuse, abuse,|this this|*really* *really* *really*|came came|as a|surprise surprise surprise|to me|when when|someone someone|e-mailed e-mailed e-mailed|this this|info info|to this|morning! morning! morning!|Sorry Sorry Sorry|he he|couldn't couldn't couldn't|be be|more more|adult adult adult|with with|his his|admin admin|powers, powers, powers,|but but|as as|Stan Stan Stan|Lee Lee Lee|said said|over over|four four|decades decades decades|ago, ago, ago,|with with|great great great|power power|comes comes|great great|responsibility. responsibility. responsibility.|Of Of Of|course, course, course,|the the|big big big|question question question|now now|is is|who who|Matthew Matthew Matthew|Fenton Fenton Fenton|will will|run run run|and and|hide hide hide|behind behind behind|when when|he he|gets gets gets|his his|head head head|handed handed handed|to to|him him|over over|his his|wanton wanton wanton|edits edits|of the|Jericho Jericho Jericho|and and|Lost Lost Lost|pages. pages. ==|Newsletter Newsletter Newsletter|== ==|Thanks Thanks|Indon. Indon. Indon.|I I|tried tried tried|to to|hide hide|it it|until the|delivery delivery delivery|day, day,|hehehhe. hehehhe. hehehhe.|Have Have Have|you you|seen seen|it it|before? before? before?|If If|not, not, not,|then done|a a|somewhat somewhat somewhat|good good|job job|of of|hiding hiding hiding|it it|P. P. P.|Cheers Cheers ==|List List List|of of|Malcolm Malcolm Malcolm|in the|Middle Middle Middle|characters characters characters|== ==|Your Your|addition addition|to to|List characters|was was|excellent. excellent. excellent.|Welcome! Welcome! OH OH|MY MY MY|just just|CALL CALL CALL|THEM THEM|ROCK ROCK ROCK|YOU YOU|IDIOTS!!!! IDIOTS!!!! ":::::::::" ":::::::::|I" am|not not|user user|168.209.97.34. 168.209.97.34. 168.209.97.34.|On On On|what what|basis basis basis|are you|acusing acusing acusing|me me|of of|being being|that that|user? user? user?|Please Please|answer answer|the the|very very|simple "simple|question:" "question:|Is" the|phrase phrase "phrase|""anti-Islamic" """anti-Islamic" """anti-Islamic|cut" cut cut|and and|past past|[sic] [sic] "[sic]|troll""" "troll""" "troll""|a" a|personal personal|attack attack|or or|is is|it personal|attack? attack? attack?|Do you|deem deem deem|this be|acceptable acceptable acceptable|language language language|on on|Wikipedia? Wikipedia? Wikipedia?|Pename Pename ":You" ":You|did" did|a a|great great|job job|in the|Bailando Bailando Bailando|por por por|un un un|sueño sueño sueño|(Argentina) (Argentina) (Argentina)|article. article.|Congratulations! Congratulations! ":|Saw" Saw Saw|your your|message message message|on my|homepage. homepage. homepage.|Is Is|there there|some some|reason reason reason|you you|don't like|my my|solution? solution? solution?|— — —|3 3 3|July July July|2005 2005 "2005|05:18" "05:18" "05:18|(UTC)" HHHHHHHHHHHHHHAAAAAAHAHA HHHHHHHHHHHHHHAAAAAAHAHA|you're you're|funny.. funny.. funny..|Na Na Na|seriously seriously seriously|dude. dude. dude.|I'm I'm|reallyyyyyyy reallyyyyyyy reallyyyyyyy|drunknnnk drunknnnk drunknnnk|but but|ya're ya're ya're|funny! funny! dont dont|u u u|speak speak|to me|like that|id id id|advise advise advise|u u|to to|watch watch watch|ur ur ur|mouth!! mouth!! ":You|call" call call|MacDonald's MacDonald's MacDonald's|a "your|""culture""?" """culture""?" """culture""?|Nonsense!" Nonsense! Nonsense!|Spend Spend Spend|some some|10 10 10|years years years|in in|France, France, France,|and and|then will|have a|hint hint hint|of what|Culture Culture Culture|is! is! "::""Somebody," "::""Somebody,|go" go|write "write|one.""" "one.""" "one.""|Do" Do|it it|yourself yourself|lazy. lazy. not|make make|personal personal|attacks. attacks. attacks.|Wikipedia Wikipedia|has has|a a|strict strict strict|policy policy policy|against against|personal attacks.|Attack Attack Attack|pages pages pages|and and|images images images|are not|tolerated tolerated tolerated|by by|Wikipedia Wikipedia|and and|are are|speedily speedily|deleted. deleted.|Users Users Users|who who|continue to|create create create|or or|repost repost repost|such such|pages and|images, images, images,|especially especially|those those|in in|violation violation violation|of of|our our|biographies biographies biographies|of of|living living living|persons persons persons|policy, policy, policy,|will Wikipedia.|Thank Thank|you. Thanks|for your|response response response|in in|this this|matter. matter. matter.|Our Our Our|plan plan plan|worke worke worke|like a|charm. charm. charm.|We We We|finally finally finally|got got|the article|negativity negativity negativity|under under|control control control|and then|got got|it it|protected! protected! "::This" "::This|is" is|ridiculous. ridiculous. "ridiculous.|::Aside" "::Aside" "::Aside|from" the|reference reference|not not|actually actually actually|calling calling|it it|a a|war war war|crime, crime, crime,|saying saying|that "that|""some""" """some""" """some""|characterize" characterize characterize|it it|as one|doesn't doesn't|make it|one. one. "one.|::War" "::War" "::War|crimes" crimes crimes|are are|serious serious serious|violations violations violations|of the|laws laws laws|of of|war. war. war.|The The|key key key|words words words|here here|are "are|""laws""" """laws""" """laws""|and" "and|""war.""" """war.""" """war.""|Unless" Unless Unless|one one|lives lives lives|in a|corrupt corrupt|town, town, town,|laws laws|are are|made made|by by|legislatures, legislatures, legislatures,|or or|in this|case case case|ratified ratified ratified|by by|them, them, them,|after after|being written|and and|argued argued argued|over over|by by|diplomats diplomats diplomats|in in|consultation consultation consultation|with with|their their|military's military's military's|generals. generals. generals.|The The|laws of|war war|were were|written written|with the|understanding understanding understanding|that that|killing killing killing|large large large|numbers numbers numbers|of people|may a|legitimate legitimate|and and|necessary necessary|part of|that that|process. process. process.|The not|written by|corrupt corrupt|and ignorant|peaceniks peaceniks peaceniks|sitting sitting sitting|around around|dreaming dreaming dreaming|up up|what they|think think|would be|moral. moral. "moral.|::I'm" "::I'm" "::I'm|deleting" deleting|this this|section. section. section.|It's It's|not not|salvageable. salvageable. "salvageable.|::" ==|Who Who Who|he he|really really|is is|== This|poor poor poor|guy guy|had had|his his|IP IP|stolen stolen stolen|by by|me. me.|Pwned! Pwned! Pwned!|Too Too Too|bad bad bad|his his|ISP ISP ISP|will will|permban permban permban|him. ==|POV POV|issue issue|== article|does not|tell tell|about laws|that that|require require require|boards boards boards|of of|directors, directors, directors,|typical typical typical|officers officers officers|on on|a a|board, board,|typical typical|educations, educations, educations,|experiences, experiences, experiences,|contacts, contacts, contacts,|etc. etc. etc.|of of|board board board|members. members. members.|There also|nothing history|of the|concept concept concept|of of|boards of|directors. directors. directors.|Almost Almost Almost|the the|entire entire entire|article article|is is|devoted devoted devoted|to to|pointing pointing pointing|out out|the the|alleged alleged alleged|shortcomings shortcomings shortcomings|of of|boards, boards, boards,|and and|none none none|of the|statements statements statements|have have|sources sources|to to|verify verify verify|them. them. them.|I'm I'm|tagging tagging tagging|this as|POV POV|until until|these these|issues issues issues|are are|resolved. resolved. I'm|Not Not|vandalizing. vandalizing. vandalizing.|You You|refuse refuse refuse|my my|evidence evidence evidence|on talk|area. area. area.|You be|blind blind blind|in in|your your|support a|Racist Racist Racist|who who|calls calls calls|for for|violence. violence. the|deranged deranged deranged|harrasser harrasser harrasser|here. You|and and|yours yours yours|are. are.|Project Project Project|your your|personality personality personality|onto onto onto|someone someone|else. Please|refrain from|making making|unconstructive unconstructive|edits edits|to to|Wikipedia, Wikipedia,|as as|you did|to to|Meat Meat Meat|grinder. grinder. grinder.|Your Your|edits edits|appear appear|to to|constitute constitute|vandalism have|been been|reverted. reverted. reverted.|If you|would would|like like|to to|experiment, experiment, experiment,|please please|use the|sandbox. sandbox. sandbox.|Thank you.|cab cab cab|(talk) "(talk)|:Don't" ":Don't" ":Don't|you" "you|mean:" "mean:" "mean:|'If" 'If 'If|you use|a a|condom. condom. condom.|Thank Thank|you.' you.' ":Nothing" ":Nothing|wrong" wrong|with with|that that|portrait, portrait, portrait,|but but|she she|was was|queen queen queen|for for|22 22 22|years, years, years,|mostly mostly mostly|as as|an an|adult. adult. adult.|It's It's|great great|for section|on on|her her|childhood. childhood. childhood.|Haven't Haven't Haven't|hade hade hade|time at|your English|yet yet yet|and and|help with|that, that,|if if|needed. needed. needed.|I don't|see why|you you|only only|took took took|this this|as as|criticism, criticism, criticism,|question question|my "my|""goal""" """goal""" """goal""|and" and|got got|so so|grumpy. grumpy. grumpy.|Of Of|course course course|all all|your your|positive positive positive|input input input|to is|appreciated appreciated appreciated|by by|everyone, everyone, everyone,|including including including|me. me.|I have|tried do|my my|bit bit|earlier. earlier. "::Thanks" "::Thanks|for" the|tip! tip! tip!|I've I've I've|been been|looking looking|at the|mediation mediation mediation|thing thing thing|a bit|already already already|- -|and and|suspect suspect suspect|you be|correct correct correct|that a|wholesale wholesale wholesale|revert revert|may be|the the|answer... answer... Only Only|a a|complete complete complete|loser loser loser|writes writes writes|a a|Wiki Wiki Wiki|profile profile profile|about about|themself! themself! themself!|5 5 5|July "2005|21:21" "21:21" "21:21|(UTC)" MY|CHANGES CHANGES CHANGES|DO DO DO|NOT NOT|AFFECT AFFECT AFFECT|ANY ANY ANY|OF OF|THE THE|CONCOCTED CONCOCTED CONCOCTED|OFFENSES OFFENSES OFFENSES|YOU YOU|HAVE HAVE HAVE|BROUGHT BROUGHT BROUGHT|UP! UP! "UP!|WP:NPOV" "WP:NPOV" "WP:NPOV|issues" issues|/ / /|synthesis synthesis "synthesis|WP:Verifiable" "WP:Verifiable" "WP:Verifiable|WP:OR" "WP:OR" "WP:OR|I" bring|your your|OWN OWN OWN|STANCE, STANCE, STANCE,|as as|being being|pro pro pro|orthodox orthodox orthodox|which which|in in|itself itself itself|is is|BIASED! BIASED! BIASED!|i i|am am|again again|going put|the the|changes changes changes|back back|on, on, on,|BECAUSE BECAUSE BECAUSE|I your|STANCE STANCE STANCE|IS IS|TO TO|PROTECT PROTECT|THE THE|CURRENT CURRENT CURRENT|SINGH SINGH SINGH|SABHA SABHA SABHA|ideological ideological ideological|stance stance stance|on on|sikhism, sikhism, sikhism,|WHICH WHICH WHICH|MEANS MEANS MEANS|that that|wikipedia wikipedia|ONLY ONLY ONLY|ACCEPTS ACCEPTS ACCEPTS|ORTHODOX ORTHODOX ORTHODOX|POV and|NOT NOT|unorthodox! unorthodox! unorthodox!|Which Which Which|means means means|going going|by OWN|judgment, judgment, judgment,|that the|CHRISTIAN CHRISTIAN CHRISTIAN|UNORTHODOX UNORTHODOX UNORTHODOX|CHURCH, CHURCH, CHURCH,|which which|exist, exist, exist,|on on|real real|life life|and and|on on|wiki, wiki, wiki,|HAS HAS HAS|NO NO|merit! merit! merit!|THAT THAT|IS IS|A A|BIASED BIASED BIASED|APPROACH! APPROACH! ==|HiDrNick HiDrNick HiDrNick|== ==|Present Present Present|for for|you you|fatty. fatty. fatty.|Relax. Relax. Relax.|don't don't|get get|too too|excited, excited, excited,|it's a|5000 5000 5000|Rhino Rhino Rhino|meal. meal. meal.|[] [] []|[] ==Unblock== ==Unblock==|Blocking Blocking Blocking|me me|will not|solve solve solve|anything. anything. anything.|I I|meant meant meant|what I|called called|that that|person person|and and|I I|shall shall shall|not not|take take|it back.|Today Today Today|he he|allows allows allows|himself himself himself|to to|deleate deleate deleate|all all|of our|images, images,|tommorow tommorow tommorow|all articles,|then then|he he|calls calls|us us us|second second|class class class|people. people. people.|Shame Shame Shame|on on|you for|giving giving|such such|users users|admin admin|rights. rights. rights.|See See|my my|messages messages messages|on "on|Wikipedia:Requests" "Wikipedia:Requests" "Wikipedia:Requests|for" for|comment/Lupo comment/Lupo ==|you you|know? know? know?|== I|already already|finish finish finish|the the|main main main|temple temple temple|structure. structure. structure.|whatever whatever whatever|you you|say, say, say,|arrogant arrogant arrogant|guy. guy. Waaaaahh Waaaaahh|erase erase erase|comments comments|on page|too, too, too,|do you|really really|think think|anybody anybody|is is|reading reading reading|this? this? this?|Are Are Are|you you|that that|insecure? insecure? "==|Wikipedia:Counter" "Wikipedia:Counter" "Wikipedia:Counter|Un-civility" Un-civility Un-civility|Unit Unit Unit|== Unit|is a|new new|wiki-project wiki-project wiki-project|I have|thought thought thought|up. up. up.|I was|wondering wondering wondering|if you|thought thought|it good|idea idea idea|and and|if you|wanted to|join join join|up. I|need need|some some|users users|backing backing backing|me me|before before|I I|construct construct construct|a a|wikiproject, wikiproject, wikiproject,|and to|share share share|my my|views views views|on on|subjects subjects subjects|such such|as as|concensus, concensus, concensus,|civilty, civilty, civilty,|etc. etc.|Reply Reply Reply|on my|talkpage talkpage talkpage|if if|you're you're|interested. interested. interested.|Thanks, Thanks, Thanks,|-MegamanZero|Talk -MegamanZero|Talk am|refering refering refering|to of|Chinese Chinese Chinese|languages languages languages|and and|dialects. dialects. A|rough rough|google google "google|tally:" "tally:" "tally:|*AIDS" *AIDS *AIDS|denialist denialist denialist|13,100 13,100 13,100|hits hits hits|*Big *Big *Big|Tobacco Tobacco Tobacco|denialist/ denialist/ denialist/|Big Big Big|Tobacco Tobacco|denialism denialism denialism|0 0 0|hits hits|*Holocaust *Holocaust *Holocaust|denialist denialist|486 486 486|hits *Holocaust|denier denier denier|306,000 306,000 306,000|hits hits|So So|there there|are are|486 hits|on on|Holocaust Holocaust Holocaust|denialists denialists denialists|who who|are are|getting getting getting|some personal|gain gain gain|from from|their their|denailism, denailism, denailism,|but but|306,000 306,000|google google|hits Holocaust|deniers deniers deniers|who not|getting getting|personal their|denialism? denialism? denialism?|Is Is|that that|what you|maintain? maintain? maintain?|And "And|""Big" """Big" """Big|Tobacco" "Tobacco|denialism""" "denialism""" "denialism""|actually" actually|gets gets|0 0|google hits|because is|so so|well well|known known|those those|denialists denialists|are are|doing doing|it it|for for|personal personal|gain? gain? gain?|And And|so so|on on|and so|forth. forth. forth.|This is|ludicrous. ludicrous. ludicrous.|Give Give Give|it it|up. ==|Taken Taken Taken|from from|Bell Bell Bell|X1 X1 X1|External External External|Links Links Links|section section|== ==|Bell X1|Flock Flock Flock|Album Album Album|Review Review Review|at at|WERS.org WERS.org WERS.org|• • ==|Goodbye Goodbye Goodbye|Cruel Cruel Cruel|World World World|== have|decided decided decided|to to|kill kill|myself. myself. myself.|My My My|Dad Dad Dad|died died died|two two|weeks weeks weeks|ago, ago,|and I|wish wish wish|to join|him. him.|I say|goodbye. goodbye. ==Kobe ==Kobe|Tai== Tai== Tai==|A A|proposed proposed proposed|deletion deletion|template template template|has been|added added|to article|Kobe Kobe Kobe|Tai, Tai, Tai,|suggesting suggesting suggesting|that deleted|according according according|to the|proposed deletion|process. process.|All All|contributions contributions contributions|are are|appreciated, appreciated, appreciated,|but but|this article|may may|not not|satisfy satisfy satisfy|Wikipedia's Wikipedia's Wikipedia's|criteria for|inclusion, inclusion, inclusion,|and the|deletion deletion|notice notice|should should|explain explain explain|why why|(see (see (see|also "also|""What" """What|Wikipedia" "is|not""" "not""" "not""|and" and|Wikipedia's Wikipedia's|deletion deletion|policy). policy). policy).|You may|prevent prevent prevent|the deletion|by by|removing removing|the the|notice, notice, notice,|but but|please please|explain you|disagree disagree disagree|with deletion|in your|edit edit|summary summary summary|or or|on its|talk talk|page. page.|Also, Also, Also,|please please|consider consider|improving improving improving|the to|address address address|the the|issues issues|raised. raised. raised.|Even Even Even|though though|removing notice|will will|prevent prevent|deletion deletion|through through|the deletion|process, process, process,|the may|still still|be deleted|if if|it it|matches matches matches|any deletion|criteria criteria|or or|it it|can be|sent sent sent|to to|Articles Articles Articles|for for|Deletion, Deletion, Deletion,|where where|it if|consensus consensus|to delete|is is|reached. reached. reached.|If you|agree deletion|of only|person who|has made|substantial substantial substantial|edits the|page, page,|please please|add of|Kobe Kobe|Tai. Tai. Tai.|'''''' '''''' ''''''|* * Yeah Yeah|thanks thanks|to to|however however however|did did|that because|now now|the the|stupid stupid|fish fish fish|guy guy|can can|get get|off off off|on on|stupid stupid|information information|Wrestlinglover420 Wrestlinglover420 Pss Pss|Rex, Rex, Rex,|be be|sure sure|to to|DOCUMENT DOCUMENT DOCUMENT|all the|things things things|you've you've|discovered discovered discovered|on the|John John|Kerry Kerry Kerry|page page|etc. etc.|It's It's|awesome awesome awesome|that I|INDEPENDENTLY INDEPENDENTLY INDEPENDENTLY|observed observed observed|(and (and (and|can can|corrorborate) corrorborate) corrorborate)|virtually virtually virtually|the the|exactsame exactsame exactsame|pattern pattern pattern|by by|these these|liberals. liberals. liberals.|Demonizing Demonizing Demonizing|conservatives; conservatives; conservatives;|lionizing lionizing lionizing|liberals. liberals.|It's It's|repeated repeated|ad ad ad|infinitum, infinitum, infinitum,|ad ad|nauseum. nauseum. nauseum.|The The|more more|proof proof proof|we we|have, have, have,|the the|easier easier easier|it it|will be|to to|persuade persuade persuade|all all|but but|their their|fellow fellow fellow|brain-dead brain-dead brain-dead|truth truth|haters haters haters|to to|give a|red red|cent cent cent|to to|Wikipedia. Wikipedia.|And, And,|until until|WHOLESALE WHOLESALE WHOLESALE|changes changes|are made|from top|down, down,|that's that's that's|exactly exactly exactly|what's what's what's|about about|to to|happen. happen. happen.|It's It's|almost almost almost|like like|this the|liberal's liberal's liberal's|religion. religion. religion.|Too bad|they're they're|gonna gonna gonna|have find|a a|church church church|other other|than than|Wikipedia to|practice practice practice|their their|faith, faith,|huh? huh? huh?|I've I've|heard heard|rumors rumors rumors|that that|my my|actions actions|are are|already already|sending sending sending|users users|Hippocrite, Hippocrite, Hippocrite,|Fred Fred Fred|Bauder, Bauder, Bauder,|WoohooKitty, WoohooKitty, WoohooKitty,|Kizzle, Kizzle, Kizzle,|FVW, FVW, FVW,|Derex Derex Derex|and and|especially especially|the the|pimply pimply pimply|faced faced faced|15 15 15|year year year|old old old|RedWolf RedWolf RedWolf|to to|become become become|so so|verklempt verklempt verklempt|they they|don't don't|know know|whether whether|to to|schedule schedule schedule|an an|appointement appointement appointement|with their|psychiatrist...or psychiatrist...or psychiatrist...or|their their|gynecologist. gynecologist. gynecologist.|Big Big|Daddy- Daddy- Daddy-|PHASE PHASE PHASE|II II II|Dry Dry Dry|up the|funding funding funding|(on (on (on|the the|road) road) Your|ignorant comments|Before Before|acting acting|as a|functional functional functional|illiterate, illiterate, illiterate,|you you|should should|have have|read the|pertinent pertinent pertinent|prior prior|discussion discussion|already already|took took|place place|in the|removed removed|content which|has no|place a|biography. biography. biography.|By By By|the the|way, way, way,|how how|is is|your your|boyfriend boyfriend boyfriend|Bertil Bertil Bertil|Videt Videt Videt|doing? doing? doing?|I I|read read|sensational sensational sensational|stuff stuff stuff|on on|his his|talk page|which which|he he|keeps keeps keeps|hiding. hiding. hiding.|Did Did Did|you you|get get|to to|meet meet meet|with his|other other|boyfriends boyfriends boyfriends|yet? yet? . .|I'm I'm|afraid afraid afraid|to that|if if|anyone anyone|agreed agreed agreed|with your|interpretation interpretation interpretation|on on|what what|denotes denotes denotes|a a|comment comment comment|or or|remark remark remark|by by|one one|to an|insult, insult, insult,|well well|I'd I'd I'd|have that|you're you're|all all|stark stark stark|raving, raving, raving,|bloody bloody bloody|mad! mad! === ===|Age Age Age|of of|Modern Modern Modern|Humans Humans Humans|=== ===|The The|article article|says says says|the the|age age age|of of|modern modern modern|humans humans humans|is is|200 200 200|thousands thousands thousands|years years|which is|unsourced unsourced unsourced|material material material|obviously obviously obviously|becausee becausee becausee|no one|knows. knows. knows.|However However|the source|provided provided|says says|130,000 130,000 130,000|years. years. years.|So So|how how|old old|are are|humans? humans? humans?|200 200|thousand thousand thousand|years years|old, old, old,|130 130 130|years old,|or or|the the|millions millions millions|of of|other other|numbers numbers|that that|science science science|has has|claimed? claimed? It|wasn't wasn't wasn't|a attack.|If If|your your|grasp grasp grasp|of of|english english english|is so|poor poor|you you|shouldn't shouldn't shouldn't|be be|attempting attempting attempting|to to|censor censor censor|people. ":::*Generic" ":::*Generic|fair" fair fair|use use|rationales rationales rationales|are, are, are,|by by|definition, definition, definition,|impossible. impossible. ":That" ":That|isnt" isnt|going to|work, you|dont dont|seem seem|stupid stupid|enough enough|to to|think it|will. will. will.|'''''' ''''''|- ":::" ":::|Get" Get|off off|your your|high high high|horse, horse, horse,|or or|block block block|me. You're|very very|unreasonable unreasonable unreasonable|and and|bored, bored, bored,|sick sick sick|person! person! person!|If no|reason reason|to delete|an article|without without|knowing knowing knowing|or or|seeing seeing seeing|the the|full full full|content. content. content.|Hold Hold Hold|your your|horses horses horses|and then|decide. decide. decide.|If have|an an|e-mail e-mail e-mail|address address|I'd I'd|like to|debate debate debate|this this|with with|you. you.|-Wikipedia -Wikipedia -Wikipedia|Supervisor! Supervisor! "::The" "::The|problem" problem|is not|only only|with the|sections sections sections|concerning "concerning|""Controversy" """Controversy" """Controversy|about" about|media "media|coverage""," "coverage""," "coverage"",|the" the|major major major|problem that|many many many|major major|points points points|about the|Greek Greek Greek|debt debt debt|crisis crisis crisis|are are|missing missing|in the|lead lead|and article,|even even|though it|consists consists consists|of of|>100 >100 >100|pages. pages.|This is|addressed addressed addressed|in "in|::*" "::*" "::*|section" section|#4 #4 #4|- "-|"">100" """>100" """>100|pages," pages, pages,|but but|still still|main main|points "points|missing?""" "missing?""" "missing?""|::*" section|#5 #5 #5|- "-|""" """" """|Why" Why|did did|Greece Greece Greece|need need|fiscal fiscal fiscal|austerity austerity austerity|in the|midst midst midst|of of|its its|crisis? crisis? "crisis?|""" """|::*" section|#6 #6 #6|- """|POV" POV|/ /|LEAD LEAD LEAD|debate "debate|""" """|::Two" "::Two" "::Two|weeks" ago,|I I|proposed proposed|in this|section #4|to to|have have|the points|at at|least least least|in in|summary summary|style style style|in lead|(as (as (as|important important|ones ones ones|are not|even even|in the|article) article) "article)|::Just" "::Just" "::Just|let's" let's let's|only only|take take|the the|first first|point point|listed listed|in in|#4, #4, #4,|being being|joining joining joining|the the|Euro Euro Euro|without without|sufficient sufficient sufficient|financial financial financial|convergence convergence convergence|and and|competitiveness competitiveness competitiveness|in the|summary summary|list list|of of|causes causes causes|for debt|crisis. crisis. crisis.|It major|single single|and and|early early early|root root root|cause cause|for crisis.|Without Without Without|this this|root cause|Greece Greece|could could|technically technically technically|not had|this this|debt crisis|because it|could could|always always always|have have|printed printed printed|itself itself|out out|of of|every every|debt debt|volume volume volume|as as|they they|did did|before before|with the|drachma. drachma. drachma.|But But|this this|cause cause|is the|100 100 100|WP WP WP|pages and|in the|WP WP|lead. lead. lead.|The The|current current|lead lead|only only|lists lists lists|normal normal normal|problems problems problems|like "like|""structural" """structural" """structural|weaknesses""" "weaknesses""" "weaknesses""|and" "and|""recessions""" """recessions""" """recessions""|(even" (even (even|though is|clear clear clear|that that|Greece Greece|faced faced|those those|normal problems|for for|decades decades|and and|always always|solved solved solved|them them|with with|high high|drachma drachma drachma|inflation inflation inflation|if if|needed) needed) needed)|- so|without without|naming naming naming|the the|root cause|there is|no no|cause "crisis.|::What" "::What" "::What|happened" happened|after after|I proposed|to points|in article|(at (at (at|least lead|as a|summary) summary) summary)|and and|also also|invited invited invited|everybody everybody|to to|add/change/delete add/change/delete add/change/delete|from from|my my|proposed proposed|the main|point point|list? list? list?|There There|were were|strong strong strong|opponents opponents opponents|working working working|in a|coordinated coordinated coordinated|action, action, action,|threatening threatening|to fight|any any|significant significant significant|change, change, change,|saying saying|one one|can can|not not|summarize summarize summarize|a a|Greek debt|crisis, crisis, crisis,|saying "saying|""Greek" """Greek" """Greek|interests" interests|[need [need [need|to to|have] have] have]|a "a|prominence"")" "prominence"")" "prominence"")|when" when|describing describing describing|the the|debt crisis|in in|WP, WP, WP,|saying saying|they they|will not|let let|other other|editors editors|summarize summarize|it, it,|and so|on. on. on.|So So|we have|almost almost|100 100|new new|pages pages|in talk|section, section, section,|and and|main the|lemma lemma lemma|not not|in article|(like (like (like|it was|during during during|the last|5 5|years) years) "years)|::" ||decline=Nobody decline=Nobody decline=Nobody|on on|Wikipedia Wikipedia|wants wants|your your|moronic moronic moronic|edits! edits! edits!|Take Take Take|a a|hike! hike! Welcome!|Hello, Hello, Hello,|, ,|and and|welcome welcome welcome|to to|Wikipedia! Wikipedia! Wikipedia!|Thank your|contributions. contributions. contributions.|I you|like like|the place|and and|decide decide decide|to to|stay. stay. stay.|Here Here|are a|few few few|good good|links links links|for "for|newcomers:" "newcomers:" "newcomers:|*The" *The *The|five five five|pillars pillars pillars|of of|Wikipedia Wikipedia|*How *How *How|to to|edit edit|a page|*Help *Help *Help|pages pages|*Tutorial *Tutorial *Tutorial|*How to|write write|a great|article article|*Manual *Manual *Manual|of of|Style Style Style|I you|enjoy enjoy enjoy|editing editing|here here|and and|being a|Wikipedian! Wikipedian! Wikipedian!|Please Please|sign sign|your your|name name|on on|talk talk|pages pages|using using using|four four|tildes tildes tildes|(~~~~); (~~~~); (~~~~);|this this|will will|automatically automatically automatically|produce produce produce|your name|and the|date. date. date.|If you|need need|help, help, help,|check "out|Wikipedia:Questions," "Wikipedia:Questions," "Wikipedia:Questions,|ask" ask|me talk|page, page,|or or|place place|{{helpme}} {{helpme}} {{helpme}}|on your|talk and|someone someone|will will|show show|up up|shortly shortly shortly|to to|answer answer|your your|questions. questions. questions.|Again, Again, Again,|welcome!  welcome!  welcome! |By way,|I I|noticed have|created created|the article|Dr. Dr. Dr.|Manfred Manfred Manfred|Gerstenfeld. Gerstenfeld. Gerstenfeld.|Some Some|of the|sentences sentences sentences|there there|seem seem|copied copied copied|directly directly directly|from from|Dr Dr Dr|Gerstenfeld’s Gerstenfeld’s Gerstenfeld’s|homepage; homepage; homepage;|this not|desirable, desirable, desirable,|because it|creates creates creates|the the|impression impression impression|that article|was was|copied copied|from the|homepage, homepage, homepage,|which which|might might|be be|be copyright|violation. violation. violation.|Perhaps Perhaps|you should|try to|rewrite rewrite rewrite|the article|a bit|to to|avoid avoid|that. that.|Also, Also,|some some|kind kind kind|of of|indication indication indication|about about|why why|Dr Dr|Gerstenfeld Gerstenfeld Gerstenfeld|is is|notable notable|would be|nice nice|to have|(cf. (cf. "(cf.|WP:BIO" "WP:BIO" "WP:BIO|and" "and|WP:PROFTEST" "WP:PROFTEST" "WP:PROFTEST|for" for|ideas ideas ideas|on on|how do|that). that). that).|— ==|i i|hate hate|your your|guts guts guts|== i|hope you|feel feel|good good|about "::|oh" oh oh|i i|bet bet bet|you are|little boy.|now now|go go|up up|stairs, stairs, stairs,|your your|mummy mummy mummy|made your|lunch lunch "PS:" "PS:|you're" all|middle-aged middle-aged middle-aged|losers losers losers|at at|home home home|in your|parents parents parents|basements basements basements|living living|off off|50 50 50|bucks bucks bucks|a a|week week Samuell, Samuell,|if not|want the|one one|dead, dead, dead,|better better|proceed proceed proceed|as as|requested. requested. requested.|Either Either Either|that that|or or|we'll we'll we'll|keep keep|beating! beating! i|dare dare dare|you you|== ==|Block Block Block|me. will|do do|it it|again, again,|i to|reply my|discussions discussions discussions|rather rather|owning owning owning|articles articles|and and|issuing issuing issuing|warnings. WELL|SAID SAID SAID|Loremaster Loremaster Loremaster|you not|own own|the article,|you you|tyrannical tyrannical tyrannical|anti-knowledge anti-knowledge anti-knowledge|hater. hater. didn't|say myself|don't don't|agree with|what what|the reference|says, says, says,|or or|I myself|know know|better better|than than|what says,|so so|I am|going to|correct correct|it it|or or|remove remove|it it|based my|own own|original original original|research. research. research.|Do Do|not not|distort distort distort|my my|words. words. words.|I said|Myanmar Myanmar Myanmar|has has|nothing nothing|to the|topic. topic. topic.|You You|have have|problems problems|with with|understanding. understanding. "::So" "::So|you" than|the the|admin! admin! admin!|Are you|excusing excusing excusing|all the|above? above? above?|Are you|ignoring ignoring|all his|breaks breaks breaks|on mediation|- -|do you|not not|remember remember remember|your your|reaction reaction reaction|when when|I changed|BOMBER BOMBER BOMBER|to to|Volunteer, Volunteer, Volunteer,|you seem|very very|quite quite|of of|this, this,|do not|think is|total total total|hypocritical? hypocritical? ==|October October October|2013 2013 2013|== You|want want|ME ME|for for|understanding? understanding? understanding?|I'll I'll|give give|you you|understanding, understanding, understanding,|you you|annoying annoying annoying|editor! editor! ,|6 6 6|January January January|2014 2014 2014|(UTC) "(UTC)|::::Ok," "::::Ok," "::::Ok,|so" so|Anon Anon Anon|IP IP|from from|Tempe, Tempe, Tempe,|Arizona Arizona Arizona|aka aka aka|174.19.166.126 174.19.166.126 174.19.166.126|aka aka|174.19.169.92, 174.19.169.92, 174.19.169.92,|who who|apparently apparently|only only|edits edits|the the|Ted Ted Ted|Cruz Cruz Cruz|article article|and and|no no|other, other, other,|now now|that have|conclusively conclusively conclusively|answered answered answered|your your|question, question, question,|please please|provide provide|me me|reasons reasons reasons|that be|edited edited edited|just just|like like|Jennifer Jennifer Jennifer|Granholm Granholm Granholm|article. article.|It It|was was|your your|suggestion suggestion suggestion|I I|assume assume assume|you some|thoughts thoughts thoughts|on this|topic, topic, topic,|right? right? "right?|22:38" "22:38" You're|a real|glutton glutton glutton|for for|punishment. punishment. punishment.|;-) ;-) I'm|the the|latest latest latest|yet, yet, yet,|but but|congratulations congratulations congratulations|on your|re-adminship. re-adminship. re-adminship.|That's That's That's|the the|third third third|time time|I've I've|voted voted voted|for you,|don't don't|make make|me me|do it|again! again! again!|-P -P -P|30 30 30|June June June|2005 "2005|17:17" "17:17" "17:17|(UTC)" ":Erm," ":Erm,|thank" thank|you. ":|LOTHAT" LOTHAT LOTHAT|VON VON VON|TROTHA TROTHA TROTHA|WAS WAS WAS|POISONED, POISONED, POISONED,|THAT'S THAT'S THAT'S|WHAT WHAT|CONTAMINATION CONTAMINATION CONTAMINATION|IS! IS! IS!|YOU YOU|GET GET GET|TYPHOID TYPHOID TYPHOID|FEVER FEVER FEVER|ONLY ONLY|THROUGH THROUGH THROUGH|POISONED POISONED POISONED|FOOD FOOD FOOD|OR OR OR|DRINK! DRINK! ==|Robbie Robbie Robbie|Hummel Hummel Hummel|== ==|Way Way Way|to to|speedy speedy|delete delete|my my|Robbie Hummel|article! article! article!|It's It's|now now|a real|article you|can't can't|do anything|about about|it. it.|I I|can't can't|believe believe|you would|do do|this to|me. You|must must must|hate hate|black black black|people. ":Merge" ":Merge|and" and|redirect redirect redirect|as per|, ,|also also|for for|Base Base Base|32 32 32|into into|Base32 Base32 Base32|(I (I (I|just just|edited edited|Base32, Base32, Base32,|and and|needed needed needed|Base64 Base64 Base64|in in|UTF-1). UTF-1). a|dumb dumb dumb|American, American, American,|right? right?|No No|degree? degree? degree?|Knows Knows Knows|nothing nothing|of of|engineering? engineering? engineering?|Thinks Thinks Thinks|mathematics mathematics mathematics|is "is|""universal""?" """universal""?" """universal""?|Played" Played Played|monopoly monopoly monopoly|in in|high high|school school school|instead instead instead|of of|learning? learning? learning?|How How|am am|I I|doing doing|so so|far? far? ":::::::::::You" ":::::::::::You|read" read|it; it; it;|your your|note note|addressed addressed|something something|else. else.|(Incidentally, (Incidentally, (Incidentally,|your your|reasoning reasoning reasoning|above above above|is is|unsound; unsound; unsound;|whether whether|or or|not not|my my|Rushdie Rushdie Rushdie|comparison comparison comparison|holds holds holds|up, up, up,|it not|fail fail fail|to to|hold hold hold|up up|because because|his his|literary literary literary|career career career|is a|failure). failure). failure).|But But|I you|understand, understand, understand,|I not|trying to|get get|any any|decision decision decision|reversed reversed reversed|(and (and|never never|was). was). was).|Rather, Rather, Rather,|I am|yelling yelling yelling|at at|you for|enforcing enforcing enforcing|a a|stupid stupid|policy. policy. policy.|- Sandifer, Sandifer,|I'm going|BUY BUY BUY|my my|way way|back back|into into|wikipedia. wikipedia.|For For|all your|puffery, puffery, puffery,|I'll I'll|bet bet|you've you've|never never|forked forked forked|over over|a a|penny penny penny|to the|cause. cause. cause.|And And|even even|you you|have, have,|I'll I'll|make make|your your|contribution contribution contribution|seem like|pennies. pennies. ==|Hello, Hello,|Nawlins Nawlins Nawlins|== ==|Why Why|do to|deflower deflower deflower|prepubescent prepubescent prepubescent|girls? girls? girls?|Don’t Don’t Don’t|you know|that’s that’s that’s|a a|felony? felony? Vinny Vinny|Burgoo Burgoo Burgoo|= = =|suspected suspected suspected|sock sock|puppet puppet puppet|Are you|ever ever|going to|withdraw withdraw withdraw|this this|accusation? accusation? accusation?|It's It's|currently currently|the the|second second|hit hit hit|with a|Google Google Google|search search|with with|'Vinny 'Vinny 'Vinny|Burgoo' Burgoo' Burgoo'|(my (my (my|one one|and and|only only|online online online|identity identity|for for|nearly nearly nearly|ten ten ten|years) years)|and and|it's it's|wholly wholly wholly|bogus. bogus. bogus.|Someone Someone Someone|posted posted posted|something something|in in|support of|something something|very very|stupid stupid|I had|done done|at at|Wiktionary Wiktionary Wiktionary|(I (I|called called|a a|serial serial serial|Wiki Wiki|tyrant tyrant tyrant|a a|'c**t' 'c**t' 'c**t'|after after|he he|had had|unambiguously unambiguously unambiguously|broken broken broken|Wiki's Wiki's Wiki's|rules, rules, rules,|then I|compounded compounded compounded|this this|by by|threatening threatening|him him|in in|what I|thought thought|at the|time a|transparently transparently transparently|jocular jocular jocular|manner, manner, manner,|but but|wasn't) wasn't) wasn't)|and this|'supporter' 'supporter' 'supporter'|was was|assumed assumed assumed|to be|me me|using using|another another another|identity identity|and and|another another|IP IP|trying get|around around|a a|temporary temporary temporary|block. block. block.|I still|use use|Wikipedia Wikipedia|a a|lot lot lot|but but|have no|interest interest|whatsoever whatsoever whatsoever|in in|editing editing|it it|ever ever|again, again,|so so|by by|all all|means means|say for|disruptive disruptive disruptive|editing "editing|(guilty:" "(guilty:" "(guilty:|I" got|fed fed fed|up up|with the|lot lot|of of|you) you) you)|or or|whatever whatever|else else|I was|accused accused accused|of of|before before|this this|puppeteer puppeteer puppeteer|nonsense nonsense nonsense|was was|settled settled settled|on on|(the (the (the|crime crime crime|kept kept kept|changing) changing) changing)|but but|I'm not|happy happy happy|with you|currently currently|show. show. show.|Take Take|it it|down down down|or else.|A A|genuine genuine genuine|threat threat threat|this this|time? time?|We'll We'll We'll|see. see. Other Other|than than|that could|see see|how how|the the|side side side|bar bar bar|looks looks looks|intergrated intergrated intergrated|into into|the top|welcome welcome|section right|and it|just just|one one|section. section.|Providing Providing Providing|you it|the same|length length length|and and|shrink shrink shrink|the the|other other|pics pics pics|down down|a a|little little|it should|fit fit fit|in the|top? top? I|reckon reckon reckon|you should|die die is|British British British|form form|and and|does not|correspond correspond correspond|to to|French French French|nobiliary nobiliary nobiliary|rules, rules,|which, which, which,|in in|any any|case, case, case,|are are|defunct, defunct, defunct,|given given|that that|French French|noble noble noble|titles titles titles|were were|rendered rendered rendered|obsolete obsolete obsolete|more a|century century century|ago. ago. ago.|I think|that, that,|technically, technically, technically,|she she|is is|merely merely|Raine Raine Raine|Spencer, Spencer, Spencer,|having having|retrieved retrieved retrieved|her her|previous previous previous|surname surname surname|upon upon upon|her her|divorce divorce divorce|from from|Chambrun. Chambrun. Chambrun.|(And (And (And|during the|French French|marriage, marriage, marriage,|she was|not not|Countess Countess Countess|of of|Chambrun, Chambrun, Chambrun,|she was|Countess Countess|Jean-Francois Jean-Francois Jean-Francois|de de de|Chambrun, Chambrun,|and, and, and,|as per|French French|usage, usage, usage,|would be|referred referred referred|to to|as as|Mme Mme Mme|de Chambrun,|with title|used used|only by|servants servants servants|and and|so-called so-called so-called|inferiors.) inferiors.) Hey Hey|jerk jerk jerk|we we|may may|do do|a "a|deal:" "deal:" "deal:|please" please|let let|in in|peace peace peace|the the|articles articles|of of|Carl Carl Carl|Grissom Grissom Grissom|and and|Bob Bob Bob|the the|goon. goon. goon.|Also Also Also|unlock unlock unlock|the the|Chase Chase Chase|Meridian Meridian Meridian|articles and|accept accept accept|that that|Jack Jack Jack|Napier Napier Napier|are are|in in|Batman Batman Batman|Forever. Forever. Forever.|In In In|change change|I I|let let|of of|vandalize vandalize|the the|user user|articles. articles. wikipedia.org wikipedia.org|for for|my my|fans fans fans|i i|leave leave|for for|one one|second second|and and|Wikipedia has|blocked blocked|my my|published published|content content|for for|racist racist racist|organizations organizations organizations|who who|spam spam spam|and/or and/or and/or|advertize advertize advertize|in the|search search|engines engines engines|under under|wikipedia.org wikipedia.org|name. name. name.|would would|you like|me to|should should|you you|the the|links links|or the|world world|the the|links? links? links?|I am|sick sick|of the|racism racism|on on|wikipedia.org. wikipedia.org. wikipedia.org.|stop stop|blocking blocking blocking|my my|publishing publishing publishing|that in|fact fact|not not|spam spam|and not|advertizing advertizing advertizing|anything. anything.|It my|life, life, life,|a real|american, american, american,|in in|america. america. again|the the|TYRANNY TYRANNY TYRANNY|of of|Liberal Liberal Liberal|opinions opinions opinions|rules rules rules|over over|all, all, all,|just the|Nazis Nazis Nazis|or or|Facists. Facists. ok ok|so so|its its|the the|currupt currupt "currupt|admin:" "admin:" "admin:|desucka,crooked" desucka,crooked desucka,crooked|bullet,and bullet,and bullet,and|krappydude. krappydude. krappydude.|made made|a a|mental mental mental|note PAGE|GO GO GO|DIE DIE DIE|YOU YOU|STUPID STUPID STUPID|ARSEWHOLE ARSEWHOLE ARSEWHOLE|AUTOMATED AUTOMATED AUTOMATED|FILTER FILTER ":::The" ":::The|article" as|it it|stands stands stands|is is|of of|almost almost|no no|use use|to the|readership readership readership|it's it's|aimed aimed aimed|at, at, at,|that's that's|the the|problem. problem. problem.|I can't|imagine imagine imagine|why why|any any|medical medical|professional professional professional|would would|choose to|use use|Wikipedia, Wikipedia,|but but|even even|if if|they they|do, do, do,|they they|have have|easy easy easy|access access access|to to|better better|source source|material. material. material.|The The|general general general|reader reader|doesn't doesn't|have have|that that|easy easy|access, access, access,|so so|it would|make make|sense sense|to to|aim aim aim|to article|at at|them. "::Dai" "::Dai|antagonized" antagonized antagonized|me me|with with|he he|comment comment|of my|'first' 'first' 'first'|page page|move. move. move.|Then Then Then|Snowded Snowded Snowded|suggested suggested suggested|I a|either either|a a|drunk drunk drunk|or or|just just|plain plain plain|stupid. stupid. stupid.|They They They|should be|attacking attacking attacking|me on|those those|public public public|talkpages talkpages talkpages|& & &|through through|their their|'edi 'edi 'edi|summaries'. summaries'. summaries'.|I I|used used|to a|happy happy|bloke, bloke, bloke,|but but|Dai Dai Dai|& &|Snowy Snowy Snowy|continue to|poke poke poke|& &|provoke provoke provoke|me, me,|via via via|stalking, stalking, stalking,|harrassment harrassment harrassment|& &|contant contant contant|ABF. ABF. ABF.|They They|treat treat treat|me like|dirt, dirt, dirt,|on on|thos thos thos|public public|pages. ==|How How|rumours rumours rumours|get get|started started started|== is|how how|rumours get|started. started. started.|Ramsquire Ramsquire Ramsquire|is is|caught caught caught|again again|starting starting starting|a a|rumour. rumour. "rumour.|*RPJ:" "*RPJ:" "*RPJ:|There" no|chain chain chain|of of|custody custody custody|on the|rifle. rifle. "rifle.|*Ramsquire:" "*Ramsquire:" "*Ramsquire:|""Yes" """Yes" """Yes|there" "there|is.""" "is.""" "is.""|*RPJ:" "*RPJ:|Where?" Where? "Where?|*Ramsquire:" "*Ramsquire:|""Its" """Its" """Its|not" "the|article.""" "article.""" "article.""|and" "and|""I'm" """I'm" """I'm|not" do|any any|research research research|for "for|you.""" "you.""" "you.""|*RPJ:" "*RPJ:|Ramsquire," Ramsquire, Ramsquire,|please, please, please,|just just|admit admit admit|you you|made the|whole whole whole|story story story|up up|about a|there there|being "being|""chain" """chain" """chain|of" "of|custody""" "custody""" "custody""|on" ":::This" ":::This|discussion" discussion|was was|dead dead dead|from from|more than|half half half|of of|month month|when I|archived archived archived|it. I|really really|want see|Heta, Heta, Heta,|Stigma Stigma Stigma|and and|Sho Sho Sho|in in|article, article,|but I|cannot cannot|add add|them them|again again|effectively, effectively, effectively,|because because|of of|threat threat|of of|edit edit|war war|triggering triggering triggering|mentioned mentioned mentioned|above above|by by|me, me,|which is|manifested manifested manifested|by by|reverts reverts reverts|made by|other editors|after after|readding readding readding|these these|letters letters letters|by "::::::::Oh" "::::::::Oh|seriously," seriously, seriously,|you're you're|definitely definitely definitely|a a|challenging challenging challenging|one. one.|As As|I I|said, said, said,|it's it's|a a|legal legal legal|matter. One One|thing thing|I hate|is people|who who|talk talk|about other|people people|behind behind|their their|backs backs backs|because because|they they|are are|too too|gutless gutless gutless|to to|confront confront confront|them them|in in|person. person. person.|You You|go go|bad bad|mouthing mouthing mouthing|people and|Slim Slim Slim|Virgin Virgin Virgin|and and|others others others|off off|behind behind|our our|backs. backs. backs.|Really Really Really|honorable honorable honorable|behaviour. behaviour. behaviour.|You a|weak weak weak|person. *Please *Please|refrain adding|nonsense nonsense|to to|WWE WWE|RAW. RAW. RAW.|It is|considered considered considered|vandalism. vandalism.|If experiment,|use ==|... ...|== ==|WHY WHY WHY|DO DO|YOU YOU|ACT ACT ACT|SO SO|HOSTILE HOSTILE HOSTILE|WHEN WHEN|YOU GET|INSULTED?!?! INSULTED?!?! INSULTED?!?!|LEARN LEARN LEARN|TO TO|FRIGGIN FRIGGIN FRIGGIN|FIND FIND FIND|SOURCES SOURCES SOURCES|BEFORE BEFORE BEFORE|YOU DELETE|THOSE THOSE THOSE|PRICING PRICING PRICING|GAME GAME GAME|ARTICLES, ARTICLES, ARTICLES,|GD GD ":::If" ":::If|you" you|two two|weren't weren't weren't|ganging ganging ganging|up up|on on|me me|I'd I'd|get report|you you|first first|and and|get get|you you|banned. banned. is|really really|world world|you you|enter enter enter|my my|yard, yard, yard,|I will|use use|my my|hunter hunter hunter|rifle rifle rifle|blow blow blow|out out|you you|head. head. head.|but but|we we|are in|wiki, wiki,|so will|flag flag flag|you you|as as|vandals. vandals. Your|break break break|== ==|Hey Hey|Mr Mr Mr|V. V. V.|I a|safe safe safe|and and|restful restful restful|break. break. break.|But But|don't be|gone gone gone|for for|too too|long! long! long!|) ) )|Best Best Best|wishes, wishes, My|edits edits|are are|fine. fine. fine.|You You|people are|on the|losing losing|side. side. side.|You no|shame. shame. ==|Dont Dont Dont|go go|on on|making making|a a|FOOL FOOL FOOL|of yourself|, ,|Paula! Paula! Paula!|The The|whole whole|school school|is is|laughing laughing|already! already! already!|== ==|Too bad|that cannot|quit quit quit|popping popping popping|that that|stuff! stuff! stuff!|Drugs Drugs Drugs|are are|gonna gonna|get you|in in|trouble trouble trouble|one one|day! day! day!|(much (much (much|more more|then then|the the|stuff stuff|you with|half half|the the|guys guys guys|in in|our our|class class|, ,|at the|movies! movies! movies!|Jonathan Jonathan Jonathan|told told told|his his|mom, mom, mom,|when when|she she|asked asked asked|what the|spots spots spots|on his|pants pants pants|were!) were!) were!)|Stop Stop|lying, lying, lying,|stop stop|accusing accusing accusing|people of|sockpuppetry sockpuppetry sockpuppetry|who who|seem seem|continents continents continents|apart, apart, apart,|stop stop|hiding hiding|exactly exactly|those those|tracks tracks tracks|about about|you you|accuse accuse accuse|others others|of. of. of.|You You|get get|yourself yourself|into into|a a|shambles, shambles, shambles,|credibility credibility credibility|wise. wise. wise.|Anyhow, Anyhow, Anyhow,|what what|business business business|of of|yours yours|is it|what people|without without|remotest remotest remotest|relation relation relation|to to|you do|on on|wikipedia? wikipedia? wikipedia?|You seem|drunk, drunk, drunk,|on on|drugs drugs drugs|and and|having having|your your|period period period|??? ??? The|place is|now now|it's it's|the the|correct correct|place. place. place.|It's It's|chronologically chronologically chronologically|and and|historically historically historically|correct correct|as is|now. now.|Otherwise Otherwise Otherwise|you to|move move move|also also|your your|data data data|as Before|I I|accuse accuse|you you|of of|cringeworthy cringeworthy cringeworthy|acts acts|with with|donkeys, donkeys, donkeys,|what what|does does|sprotected sprotected sprotected|mean? mean? the|reply reply|– – –|my my|biggest biggest biggest|issue issue|at the|moment moment moment|is is|whether "include|""sales" """sales" """sales|figures""" "figures""" "figures""|for" for|earlier earlier earlier|years... years... years...|as as|far I|know, know, know,|there there|were were|no no|published published|end end end|of of|year year|sales sales sales|figures figures figures|before before|1994, 1994, 1994,|and the|sales sales|published published|at time|for for|1994 1994 1994|to to|1996 1996 1996|have have|since since|been been|discredited discredited discredited|and and|revised, revised, revised,|so so|are are|basically basically basically|worthless. worthless. worthless.|The The|figures figures|currently currently|quoted quoted quoted|in articles|up up|to 1996|are are|usually usually "usually|""estimates""" """estimates""" """estimates""|that" been|taken taken|from from|various various various|charts charts charts|message message|boards, boards,|calculated calculated calculated|by by|enthusiasts enthusiasts enthusiasts|from from|officially officially|published published|yearly yearly yearly|sales figures|per per|artist artist artist|(i.e. (i.e.|sales sales|could could|be be|made made|up up|of of|one one|or or|more more|singles singles singles|or or|albums, albums, albums,|and and|estimating estimating estimating|what what|percentage percentage percentage|of of|sales sales|were were|assigned assigned assigned|to to|each each|record). record). record).|As As|these these|are are|completely completely|unofficial unofficial unofficial|and and|unverifiable, unverifiable, unverifiable,|I am|thinking thinking|to to|remove remove|them them|altogether altogether altogether|or or|at least|add note|that that|all all|figures figures|are are|unofficial and|estimated. estimated. estimated.|In In|any any|case case|I think|most most|people in|how how|many many|records records records|the the|37th 37th 37th|best best best|selling selling selling|album album album|of of|1987 1987 1987|sold sold sold|that that|year year|– –|it it|makes makes|more more|sense to|concentrate concentrate concentrate|efforts efforts|into into|keeping keeping|List of|best-selling best-selling best-selling|singles singles|in United|Kingdom Kingdom Kingdom|up to|date. do|have have|Welsh Welsh Welsh|friends friends friends|there there|ask them|how how|my my|Welsh Welsh|is? is? is?|I cannot|tell tell|you you|if if|I'm I'm|a a|native native native|speaker speaker speaker|or not|- -|I I|could could|be, be,|I'm a|cosmopolitan. cosmopolitan. cosmopolitan.|Personally, Personally, Personally,|my my|favorite favorite favorite|version version|was was|. ":Spot," ":Spot,|grow" grow|up! up! up!|The being|improved improved improved|with the|new new|structure. structure.|Please Please|stop stop|your your|nonsense. nonsense. SINCE SINCE|WHEN WHEN|IS IS|>>>>SOURCED<<<< >>>>SOURCED<<<< >>>>SOURCED<<<<|EDITING EDITING EDITING|VANDALISM??? VANDALISM??? VANDALISM???|READ READ READ|THE THE|CITED CITED CITED|SOURCES! SOURCES! SOURCES!|WHERE WHERE WHERE|pray pray pray|tell me|DOES DOES DOES|IT IT IT|SAY SAY SAY|THAT THAT|IRAN IRAN IRAN|EVER EVER EVER|(I (I|SAY SAY|EVER) EVER) EVER)|HAD HAD HAD|A A|DEMOCRATICAL DEMOCRATICAL DEMOCRATICAL|ELECTION ELECTION ELECTION|OF OF|ANY ANY|SORT SORT SORT|OR OR|SHAPE SHAPE SHAPE|in in|HISTORY?? HISTORY?? HISTORY??|QUIT QUIT QUIT|CONVERTING CONVERTING CONVERTING|WIKIPEDIA WIKIPEDIA WIKIPEDIA|INTO INTO INTO|A A|TRASH TRASH TRASH|BIN BIN BIN|with with|YOUR YOUR|SILLY SILLY SILLY|AND AND|INFANTILE INFANTILE INFANTILE|PRANKS! PRANKS! PRANKS!|KISSING KISSING KISSING|EACH EACH EACH|OTHER'S OTHER'S OTHER'S|REAR REAR REAR|ENDS ENDS ENDS|DOESN*T DOESN*T DOESN*T|MAKE MAKE MAKE|POV POV|less less less|POV ==|Eww, Eww, Eww,|I can|s s s|m m m|e e e|l l l|l l|something something|horrible horrible horrible|round round round|here! here! here!|== ==|Ewwww Ewwww Ewwww|is that|you? you? you?|i l|you you|from from|here, here,|man! man! man!|peee-yewww!go peee-yewww!go peee-yewww!go|take a|bath bath bath|or or|something, something, something,|fleabag! fleabag! ==|Hi Hi Hi|== How|dare dare|you? you?|try words.|Are you|Libra, Libra, Libra,|Gemini Gemini Gemini|or or|some some|haters haters|else? else? else?|The The|picture picture|on "the|""front" """front" """front|page""" "page""" "page""|was" was|so so|show-off. show-off. UKDoctor UKDoctor|responds responds responds|Shut Shut Shut|Up, Up, Up,|David David David|Ruben Ruben Ruben|- -|can't can't|you you|see see|JdWolff JdWolff JdWolff|referring referring referring|to to|others others|as as|TIGERS TIGERS TIGERS|IN IN IN|CAGES CAGES CAGES|!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!|David Ruben|is not|any any|better better|and and|should should|go go|take a|flying flying flying|leap leap leap|into the|deep deep deep|end the|Pacific Pacific Pacific|Ocean Ocean Ocean|if if|he he|wants wants|to. to. to.|. .|. .|WE WE WE|WHITE WHITE WHITE|DOCTORS DOCTORS DOCTORS|ARE ARE|TOTALLY TOTALLY TOTALLY|ASHAMED ASHAMED ASHAMED|OF THE|GENERAL GENERAL GENERAL|MEDICAL MEDICAL MEDICAL|COUNCIL COUNCIL COUNCIL|-and -and -and|we we|certainly certainly certainly|have say|our our|piece piece piece|in any|way way|fit. fit. comments|== ==|In In|response response|to to|your your|Please remove|content content|from you.|— —|@ @ @|Your Your|record record|indicates indicates indicates|that were|banned banned|as a|vandal vandal|several several several|times times|and and|asked asked|for for|a a|defense defense defense|several several|times. times. times.|Also, Also,|your your|record that|Bertil Bertil|videt videt videt|asked asked|you revert|some some|legitimate legitimate|changes changes|without without|reason reason|and did|it it|because because|he he|asked asked|you, you,|vandalazing vandalazing vandalazing|good good|content content|that that|did not|suit suit suit|him him|or or|you. you.|You You|should should|talk. talk. talk.|Also Also|please please|read read|your own|talk page|regarding regarding|many many|other other|warnings warnings warnings|given given|to you|by other|users. users. users.|Also Also|be a|man man man|(at least|try) try) try)|and and|deal deal deal|with page|rather rather|than than|begging begging begging|others others|to hold|your your|hand. hand. hand.|Before "::::Based" "::::Based|on" on|ChrisO's ChrisO's ChrisO's|behavior behavior behavior|that's that's|a a|load load load|of of|bull, bull, bull,|he's he's|just just|pretexting pretexting pretexting|to to|attack attack|me. me.|Further, Further, Further,|he he|NEVER NEVER NEVER|gave gave gave|me "a|""warning""" """warning""" """warning""|about" about|being being|blocked, blocked, blocked,|the "only|""warning""" """warning""|I" had|was was|this this|and I|RESPONDED RESPONDED RESPONDED|to the|abusive abusive abusive|jerk jerk|by by|placing placing placing|a a|question question|of his|interpretation interpretation|of the|rule rule rule|which he|flatly flatly flatly|refused refused refused|to to|respond respond respond|to. REDIRECT "REDIRECT|Talk:57th" "Talk:57th" "Talk:57th|Directors" Directors Directors|Guild Guild Guild|of of|America America America|Awards Awards "::::Ouch!" "::::Ouch!|That" That That|sounded sounded sounded|like a|threat threat|and and|since since|I didn't|actually actually|attack attack|you you|but but|instead instead|criticised criticised criticised|your your|behaviour, behaviour, behaviour,|I see|you are|again again|out of|line. line. line.|/ """he" """he|grew" grew grew|up up|in in|Russia, Russia, Russia,|he he|was was|training training training|with with|Russians, Russians, Russians,|he he|talks talks talks|Russian, Russian, Russian,|even even|Russian Russian Russian|President President President|came see|his his|fights, fights, fights,|thats thats thats|why why|he he|repeatedly repeatedly|has has|identified identified identified|himself himself|as as|Russian Russian|in "in|interviews""" "interviews""" "interviews""|And" And|that that|doesn't make|him him|Russian? Russian? Russian?|You You|really really|are are|very very|stupid, stupid, stupid,|as as|the the|banderlogs banderlogs banderlogs|are, are,|of of|course. course. course.|your your|whole whole|ideology ideology ideology|is on|stupidity stupidity stupidity|and and|ignorance, ignorance, ignorance,|after after|all. all. ":Time" ":Time|to" to|call call|in "the|""Three" """Three" """Three|Revert" Revert "Revert|Rule""," "Rule""," "Rule"",|as" see|both both both|have have|editted editted editted|it it|again? again? again?|I have|left left left|a a|message message|for for|both both|PeeJay2k3 PeeJay2k3 PeeJay2k3|and and|Oragina2 Oragina2 Oragina2|to to|not not|change change|the the|table table table|again, again,|until until|a a|consensus is|come come|to to|here here|on not,|we we|might might|need move|down down|the the|Resolving Resolving Resolving|Disputes Disputes Disputes|road. road. and|to to|suggest suggest|that is|flabbergastingly flabbergastingly flabbergastingly|arrogant ":Look," ":Look,|you" are|clearly clearly|trolling trolling|now now|and am|becoming becoming becoming|more little|fed you|wasting wasting|the time|of those|of of|us us|who are|here here|to good|encyclopaedia. encyclopaedia. encyclopaedia.|I am|of of|course course|prepared prepared prepared|to to|accept accept|your your|argument argument argument|that that|Alan Alan Alan|Whicker's Whicker's Whicker's|position position position|is is|'absolutely, 'absolutely, 'absolutely,|unequivocally, unequivocally, unequivocally,|and and|unquestionably unquestionably "unquestionably|definitive':" "definitive':" "definitive':|but" only|if are|prepared my|next-door-neighbour next-door-neighbour next-door-neighbour|Mr Mr|Osborne's Osborne's Osborne's|position position|that that|Manchester Manchester Manchester|is second|city city city|is also|'absolutely, unquestionably|definitive', definitive', definitive',|since since|there's there's there's|just as|much much|reason to|take take|his his|word word|on the|matter matter matter|as as|Mr Mr|Whicker's. Whicker's. Whicker's.|ⁿɡ͡b ⁿɡ͡b ⁿɡ͡b|\ \ ==|Respect Respect Respect|is is|earned earned earned|by by|respect respect respect|== ==|That That|user user|IS IS|a a|troll troll troll|and a|stalker. stalker. stalker.|They They|are not|respected respected|and are|close close close|to to|being being|banned. banned.|Did you|bother bother bother|to the|inflammatory inflammatory inflammatory|garbage garbage garbage|that they|write write|on wikipedia?|Or Or|are just|part troll|posse? posse? ==No ==No|Personal Personal Personal|Attacks== Attacks== Attacks==|Stop Stop|trying to|cover cover cover|up truth|about about|Wikipedia. Wikipedia.|I I|asked asked|the user|a question|about about|whether the|allegations allegations allegations|in in|that that|article article|were were|true. true. true.|I didn't|write that|article. article.|P.S. P.S. P.S.|I I|actually actually|didnt didnt didnt|need to|even even|ask ask|if were|true- true- true-|its its|obvious obvious|that they|were. were. ":|you" a|notorious notorious notorious|troll and|vandal vandal|too too|Hrafn. Hrafn. just|want to|point point|something something|out out|(and (and|I'm I'm|in in|no no|way way|a a|supporter supporter supporter|of the|strange strange strange|old old|git), git), git),|but is|referred as|Dear Dear Dear|Leader, Leader, Leader,|and and|his his|father father father|was was|referred as|Great Great Great|Leader. Leader. harmony harmony|between between|people this|village, village, village,|or or|maybe maybe maybe|vice vice vice|versa versa versa|... ...|.. .. ..|/ /|Blerim Blerim Blerim|Shabani. Shabani. Shabani.|/ ===hahahahahahaha=== ===hahahahahahaha===|Your Your|fake fake fake|information information|u u|have have|filled filled filled|wikipedia wikipedia|wont wont wont|be be|tolerated tolerated|, ,|stop stop|spread spread|propaganda propaganda|in in|wikipedia wikipedia|, ,|all all|information information|is is|fake fake|as the|fake fake|state state|of of|fyrom. fyrom. fyrom.|The The|truth truth|shall shall|prevail prevail ":I" ":I|can" can|sympathize sympathize sympathize|with your|frustration. frustration. frustration.|I know|many many|comic comic comic|book book|professionals professionals professionals|and know|a of|things things|I would|love love love|to include|in in|articles articles|but I|can't. can't. can't.|I a|linked linked linked|source that|other people|can can|double-check. double-check. double-check.|Your Your|conversation conversation conversation|with with|Heck Heck Heck|is is|useful useful|in can|let let|it it|guide guide guide|you you|look look|for for|sources can|link link|as as|references, references,|but but|in in|Wikipedia, Wikipedia,|a personal|conversation conversation|is not|an an|appropriate appropriate|source for|citation. citation. ==Reversion== ==Reversion==|Given Given Given|that that|some some|jerk jerk|vandalized vandalized vandalized|the the|characters characters|section section|by by|changing changing changing|the the|names names|to to|various various|Nintendo Nintendo Nintendo|characters, characters, characters,|I have|reverted reverted reverted|to a|much much|older older older|version. version. well|first, first, "first,|""accidental" """accidental" """accidental|suicide""" "suicide""" "suicide""|made" made|me me|laugh. laugh. laugh.|There are|accidents accidents accidents|and you|die die|and then|there are|suicides suicides suicides|and you|die. die. die.|Second Second|the the|next next|sentences sentences|hurt hurt hurt|my my|head. head.|You You|ASSUME ASSUME ASSUME|checkers? checkers? checkers?|I I|don't. don't. don't.|Some Some|writer writer writer|is "is|""theorizing""?" """theorizing""?" """theorizing""?|Well" Well Well|this this|guy guy|believed believed believed|that that|George George George|Hodel Hodel Hodel|was the|killer killer killer|of the|Black Black Black|Dahlia. Dahlia. Dahlia.|He He|has been|humiliated humiliated humiliated|for for|being being|wrong wrong|up up|and and|down the|internets. internets. internets.|So So|why why|not not|put put|down down|MY MY|theory? theory? theory?|Theone Theone Theone|in in|which which|Martians Martians Martians|killed killed killed|her? her? her?|Oh, Oh, Oh,|right, right,|because not|relevant relevant ==Cell ==Cell|(film)== (film)== (film)==|Why Why|is it|such such|a a|horrible horrible|thing thing|for for|me create|a page|for the|film? film? film?|I've I've|seen seen|pages pages|for for|other other|movies movies movies|that that|are are|currently currently|in in|production. production. production.|H-E H-E H-E|doulbe doulbe doulbe|hocky hocky hocky|sticks, sticks, sticks,|I've for|movies that|aren't aren't|even in|production production production|yet. yet. yet.|Can Can Can|I I|get get|some some|answers, answers, answers,|and and|don't don't|just just|tell read|some some|other "other|WP:BOLOGNA." "WP:BOLOGNA." So, So,|in in|other other|words, words, words,|you are|professionally professionally|on the|dole. dole. dole.|You must|live live|in parents|basement basement basement|and and|leech leech leech|off off|of of|them, them,|like a|11-year 11-year 11-year|old. old. old.|Maybe Maybe|if you|had had|a of|motivation, motivation, motivation,|you could|look real|job, job, job,|and not|play play play|your your|fantasy fantasy fantasy|as Wiki|boy. boy.|I'm I'm|sure sure|you you|couls couls couls|start start|a a|career career|as a|video video video|game game game|player. player. What|a a|joker joker joker|you are.|European European European|parliament parliament parliament|has no|power power|to do|anything. is|non non non|binding binding binding|because not|serious serious|and and|silly silly silly|reports reports reports|like not|meant meant|to be|serious. serious. serious.|what is|more important|is that|we we|ruled ruled ruled|your your|ancestors ancestors ancestors|for for|centuries centuries centuries|and and|trying put|negative negative negative|images images|of of|turks turks turks|in the|turkey turkey turkey|page to|change change|that. that.|This get|your your|'revenge'. 'revenge'. 'revenge'.|Go Go Go|and and|edit the|golden golden golden|dawn dawn dawn|wikipedia wikipedia|because because|your your|ideas ideas|will will|only only|be be|welcome welcome|there. there. ==|Ban Ban Ban|of "of|""Bryansee""" """Bryansee""" """Bryansee""|from" from|Wikipediocracy. Wikipediocracy. Wikipediocracy.|== ==|Hey, Hey, Hey,|you are|Zoloft. Zoloft. Zoloft.|The The|one one|who who|banned banned|me me|from from|Wikipediocracy Wikipediocracy Wikipediocracy|with threat|that I|die. "die.|""Well""" """Well""" """Well""|means" means|dead. dead. "dead.|""Recover""" """Recover""" """Recover""|means" "means|""die""." """die""." """die"".|You" are|wanting wanting wanting|me to|die die|by a|medication medication medication|increase increase increase|or or|meet meet|my my|maker. maker. maker.|Check Check Check|this "this|out:" "out:" MODERATORS MODERATORS|ARE ARE|SOME SOME|OF THE|MOST MOST MOST|INGORANT INGORANT INGORANT|AND AND|SELF SELF SELF|SERVING SERVING SERVING|JERKS JERKS JERKS|YOU WILL|FIND FIND|ON ON|THE THE|NET NET ":So" ":So|I" will|start a|criticism criticism|of the|quote quote quote|from from|Ollier Ollier Ollier|and and|Pain, Pain, Pain,|with with|whom have|more more|general general|issues issues|than "the|""postorogenic" """postorogenic" """postorogenic|part""." "part""." "part"".|Phrase" Phrase Phrase|by by|phrase phrase|that I|disagree "disagree|with:" "with:" "with:|:#" ":#" ":#|Only" Only|much much|later later later|was was|it it|realized realized realized|that the|two two|processes processes processes|[deformation [deformation [deformation|and the|creation creation creation|of of|topography] topography] topography]|were were|mostly mostly|not not|closely closely closely|related, related, related,|either either|in in|origin origin|or in|time. time.|Very Very Very|wrong. wrong. wrong.|Deformation Deformation Deformation|causes causes|topography, topography, topography,|and the|generation generation generation|of of|topography topography topography|is is|synchronous synchronous synchronous|with with|deformation. deformation. deformation.|I will|email email email|you a|copy copy|of of|Dahlen Dahlen Dahlen|and and|Suppe Suppe Suppe|(1988), (1988), (1988),|which which|shows that|this the|case case|- -|send send send|me message|so have|your your|address address|and and|can can|attach attach attach|a a|PDF. PDF. PDF.|They They|tackle tackle tackle|the the|large-scale large-scale large-scale|deformation deformation deformation|of of|sedimentary sedimentary sedimentary|rocks rocks rocks|via via|folding folding folding|and and|thrusting thrusting thrusting|during during|orogenesis. orogenesis. "orogenesis.|:#" ":#|...fold-belt" ...fold-belt ...fold-belt|mountainous mountainous "mountainous|areas...:" "areas...:" "areas...:|""fold-belt""" """fold-belt""" """fold-belt""|isn't" isn't|used used|professionally professionally|(AFAIK) (AFAIK) (AFAIK)|to to|refer a|collisional collisional collisional|mountain-building mountain-building mountain-building|event. event. event.|A A|minor minor|thing thing|though. though. "though.|:#" Only|in very|youngest, youngest, youngest,|late late late|Cenozoic Cenozoic Cenozoic|mountains mountains mountains|is is|there there|any any|evident evident evident|causal causal causal|relation relation|between between|rock rock rock|structure structure structure|and and|surface surface surface|landscape. landscape. landscape.|and the|following following "following|sentence:" "sentence:" "sentence:|If" I|were were|British, British, British,|I would|call call|this "this|""utter" """utter" """utter|twaddle""." "twaddle""." "twaddle"".|As" I|mentioned mentioned|above, above, above,|there way|for for|many many|of the|exposed exposed exposed|structures structures structures|to the|surface surface|without without|large large|amounts amounts amounts|of of|rock rock|uplift uplift uplift|and and|erosion. erosion. erosion.|And And|as a|matter matter|of of|fact, fact, fact,|the the|trajectory trajectory trajectory|of of|different different different|units units units|of rock|through through|an an|orogen orogen orogen|is in|part part|determined determined determined|by by|patterns patterns patterns|of of|surface surface|erosion. erosion.|To To|keep keep|it it|simple simple|and and|send send|you you|one one|paper, paper, paper,|you'll you'll you'll|find find|this this|in in|and and|at the|end the|paper paper paper|by by|Dahlen Suppe|(1988). (1988). "(1988).|:" "::::::What" "::::::What|are" you|deaf deaf deaf|can't hear|? WAS|HERE. HERE. HERE.|HE HE|POWNS POWNS POWNS|NOOBS NOOBS NOOBS|ALL ALL ALL|DAY! DAY! ":::And" ":::And|as" as|fully fully fully|expected, expected, expected,|yet yet|another another|abusive abusive|admin admin|gets gets|away away|with with|abusing abusing abusing|their ":Grow" ":Grow|up," up,|you you|immature immature immature|little little|brat. brat. brat.|This This|edit edit|warring warring warring|seems seems|to only|thing thing|you do|around around|here. not|vandalize vandalize|pages, pages,|as did|with with|this this|edit edit|to to|American American|Eagle Eagle Eagle|Outfitters. Outfitters. Outfitters.|If do|so, so, so,|you *|The "The|""bold" """bold" """bold|move""" "move""" "move""|was" was|at "at|05:48," "05:48," "05:48,|3" 3|December December December|2013‎ 2013‎ 2013‎|by by|. .|Someone Someone|listed listed|this this|move move|back back|as as|uncontroversial, uncontroversial, uncontroversial,|and have|changed changed|it it|into into|discussed, discussed, discussed,|at "at|Talk:Run" "Talk:Run" "Talk:Run|Devil" Devil Devil|Run Run Run|(Girls' (Girls' (Girls'|Generation Generation Generation|song)#Move? song)#Move? song)#Move?|(2). (2). ==THEN ==THEN|WHY WHY|IS IS|Attacking Attacking Attacking|my my|edits edits|by removing|my page|comments== comments== comments==|THAT IS|SHOWING SHOWING SHOWING|CONTEMPT CONTEMPT CONTEMPT|FOR FOR|OTHER OTHER OTHER|EDITORS EDITORS EDITORS|AND AND|IS IS|VERY VERY VERY|UNCIVIL UNCIVIL UNCIVIL|AS AS|WELL WELL|AS AS|YOU YOU|UNEVEN UNEVEN UNEVEN|AND AND|UNFAIR UNFAIR UNFAIR|LABELING LABELING LABELING|ME... ME... If|there there|was a|cure cure cure|for for|AIDs, AIDs, AIDs,|it would|probably probably|be be|bought bought bought|up up|by by|rich rich rich|jerks jerks|and and|sold sold|for for|double. double. double.|I if|u have|AIDs, AIDs,|then then|that is|sad sad sad|for you,|but but|many many|people people|have have|said said|that the|ones ones|to to|blame blame blame|are are|..... ..... .....|well, well,|I I|wont wont|go go|into into|that that|here. here.|many have|there there|own own|opinion opinion opinion|of of|who who|it it|is. is.|But But|that is|just just|my my|opinion. opinion. opinion.|It It|must must|suck suck suck|to person|with with|Aids. Aids. Aids.|I would|not not|know. know. These These|people are|INSANE. INSANE. INSANE.|== But|then I|rarely rarely rarely|get get|my my|evil evil evil|way way|with with|anything anything|these these|days, days, days,|must must|be be|getting getting|old old|or or|lazy. lazy.|Or Or|perhaps perhaps|both. both. ":I|have" have|painstakingly painstakingly painstakingly|taken taken|the to|scan scan scan|in the|CD CD CD|on my|desk desk desk|showing showing showing|that "that|""Extreme" """Extreme" """Extreme|Jaime""'s" "Jaime""'s" "Jaime""'s|name" "is|""Jaime" """Jaime" """Jaime|Guse""." "Guse""." "Guse"".|Additionally," Additionally, Additionally,|I I|continue point|out out|that that|Hiram Hiram Hiram|skits skits skits|are are|available available available|both both|at at|DaveRyanShow.com DaveRyanShow.com DaveRyanShow.com|and the|Best Best|of of|The The|Dave Dave Dave|Ryan Ryan Ryan|in the|Morning Morning Morning|Show Show Show|CDs. CDs. CDs.|The The|contents contents contents|are are|viewable viewable viewable|on on|Amazon. Amazon. Amazon.|Additionally, have|taken taken|some some|time to|review review|your your|edits edits|and and|history history|on on|Wikipedia. It|appears appears|you to|present present present|yourself yourself|as as|authoritative, authoritative, authoritative,|when when|you are|not. not.|You tried|multiple multiple multiple|times times|to become|an an|Administrator, Administrator, Administrator,|but to|act act act|in in|such a|reckless, reckless, reckless,|inconsistent inconsistent inconsistent|and and|immature immature|manner, manner,|I I|doubt doubt doubt|that will|ever ever|happen. an|encyclopedia encyclopedia encyclopedia|article, article,|especially especially|this "this|bit:" "bit:" "bit:|Armed" Armed Armed|once once once|again again|with a|song song song|that that|possesses possesses possesses|all the|classic classic classic|attributes attributes attributes|of a|successful successful successful|Eurovision Eurovision Eurovision|entry entry|- -|a a|catchy, catchy, catchy,|feel-good feel-good feel-good|melody, melody, melody,|and a|key-change key-change key-change|that that|builds builds builds|up a|big big|finish finish|- -|Chiara Chiara Chiara|is is|highly highly highly|likely likely|to to|enter enter|the the|contest contest|as the|favourites. favourites. favourites.|This newspaper|article. It|should be|removed. removed. removed.|Chiara's Chiara's Chiara's|fame fame fame|is also|not not|worthy worthy worthy|of of|mention mention mention|in encyclopedia.|We We|might might|as well|start start|writing writing|about the|grocer grocer grocer|or or|shopowner shopowner shopowner|round round|the the|corner. corner. die|from from|cancer. cancer. Hard Hard|to be|constructive constructive constructive|when other|party party party|behaves behaves behaves|like a|godking godking godking|thug. thug. ==|Librier Librier Librier|== ==|Anon Anon|raised raised raised|this this|issue issue|in in|their their|edit summary.|I I|agree agree|that this|term term term|seems seems|imprecisely imprecisely imprecisely|added not|accurate. accurate. accurate.|It not|generally generally|or or|strictly strictly strictly|associated associated associated|with the|Kelb Kelb Kelb|tal-Fenek. tal-Fenek. ==|ARRHGH! ARRHGH! ARRHGH!|== ==|Frederica Frederica Frederica|is most|annoying annoying|talking talking|head head|ever Someone|is is|threatning threatning threatning|an an|annon annon annon|and is|uncivilised uncivilised uncivilised|wiki wiki|conduct. conduct. bet|80% 80% 80%|of what|she did|was was|rubbish... rubbish... ==Hello==|Dude Dude Dude|your your|mother mother mother|is is|totally totally totally|hot. hot. doubt|this will|get get|through through|your your|thick thick thick|head head|(it's (it's (it's|not insult,|it's an|opinion opinion|based your|response) response) response)|but but|the the|problem issue|itself. itself. itself.|It's It's|that that|people to|enjoy enjoy|(whether (whether (whether|or your|side side|gets gets|it it|right) right) right)|to to|discuss, discuss, discuss,|turn, turn, turn,|twist twist twist|and and|frankly frankly frankly|abuse abuse abuse|topics topics topics|like this|which which|are are|detrimental detrimental detrimental|to the|basic basic basic|goals goals goals|of of|Wikis Wikis Wikis|in in|general general|and Wikipedia|in in|particular. particular. particular.|As As|John John|Stewart Stewart Stewart|said said|to to|two two|hacks; hacks; hacks;|You're You're|hurting hurting hurting|us. us. 2 2|words words|learn learn learn|them them|SHUT SHUT SHUT|UP UP UP|DONT DONT DONT|FOLLOW FOLLOW FOLLOW|ME ME|EVERYWHERE EVERYWHERE ":::hey" ":::hey|buddy," buddy, buddy,|hey hey|buddy, buddy,|guess guess guess|what? what? "what?|""I""" """I""" """I""|dont" dont|care care|realy realy realy|what "what|""your""" """your""" """your""|excuse" excuse excuse|is, is,|and and|couldn't couldn't|care care|less less|what what|Roaringflamer Roaringflamer Roaringflamer|says, says,|but are|obviously obviously|obsessed obsessed obsessed|with with|redirects. redirects. redirects.|If is|anybody anybody|that that|should be|banned, banned, banned,|its for|vandalism and|disruption disruption disruption|so so|there OOOOHHHH OOOOHHHH|With With With|a big|long long|Intellectually Intellectually Intellectually|Terrifying Terrifying Terrifying|and and|Superior Superior Superior|name name|like "like|""(referenced" """(referenced" """(referenced|to" to|Journal Journal Journal|of of|Labelled Labelled Labelled|Compounds Compounds Compounds|and "and|Radiopharmaceuticals)""." "Radiopharmaceuticals)""." "Radiopharmaceuticals)"".|How" How|Could Could Could|the quote|be be|wrong wrong|Hey!! Hey!! Hey!!|How dare|I I|even even|question question|it, it,|or or|possibly possibly possibly|be be|right, right,|in in|saying saying|the "the|""supposed""" """supposed""" """supposed""|quote" quote|is is|wrong. wrong.|What stupid|ignoramus ignoramus ignoramus|I I|must to|challenge challenge challenge|that. YOUR|THREATENING THREATENING THREATENING|BEHAVIOUR BEHAVIOUR BEHAVIOUR|== ==|== YOUR|CONSTANT CONSTANT CONSTANT|BLOCKING BLOCKING BLOCKING|AND AND|SABOTAGE SABOTAGE SABOTAGE|OF OF|MY MY|EDITS EDITS EDITS|IS IS|TANTAMOUNT TANTAMOUNT TANTAMOUNT|TO TO|STALIKING. STALIKING. STALIKING.|ARE ARE|YOU YOU|STALKING STALKING STALKING|ME? ME? ME?|ARE YOU|THREATENING THREATENING|ME ME|STEVE? STEVE? STEVE?|IS IS|THIS THIS|WHAT WHAT|YOURE YOURE YOURE|ABOUT, ABOUT, ABOUT,|THREATENING THREATENING|AND AND|HARRASSING HARRASSING HARRASSING|ME? ME?|WHY YOU|KEEP KEEP KEEP|STALKING STALKING|ME ME|THROUGH THROUGH|WIKIPEDIA? WIKIPEDIA? WIKIPEDIA?|ARE YOU|A A|TWISTED TWISTED TWISTED|WACKO, WACKO, WACKO,|DO YOU|WISH WISH WISH|ME ME|HARM? HARM? HARM?|WHY? WHY? WHY?|WHY WHY|ARE YOU|HARRASSING HARRASSING|ME!!!!!!!!!!! ME!!!!!!!!!!! ME!!!!!!!!!!!|LEAVE LEAVE LEAVE|ME ME|ALONE ALONE ALONE|YOU YOU|RACIST RACIST RACIST|WACKO!!!!!!!!! WACKO!!!!!!!!! WACKO!!!!!!!!!|== ":O:" ":O:|I" thought|that call|you you|such a|thing. thing.|I a|cookie cookie|so could|get get|bigger bigger bigger|and and|stronger. stronger. stronger.|Obviously Obviously|it it|wasn't wasn't|because you're|a a|fat fat fat|pig. pig. pig.|I'm I'm|sorry sorry|for the|misunderstanding. misunderstanding. It's|those those|biography biography biography|and and|political political political|articles articles|you should|watch watch|out out|for. for. FURTHERMORE.... FURTHERMORE....|I I|HAVE HAVE|JUST JUST|VISITED VISITED VISITED|RAGIB'S RAGIB'S RAGIB'S|PAGE PAGE|AND AND|STUDIED STUDIED STUDIED|THE THE|DISCUSSION DISCUSSION DISCUSSION|AREA. AREA. AREA.|RAGIB RAGIB RAGIB|IS IS|OBVIOUSLY OBVIOUSLY OBVIOUSLY|FROM FROM|BANGLADESH BANGLADESH BANGLADESH|AND AND|SEEMS SEEMS SEEMS|TO TO|BE BE BE|A A|SIMILARLY SIMILARLY SIMILARLY|PAROCHIAL PAROCHIAL PAROCHIAL|CHAUVINIST CHAUVINIST CHAUVINIST|EDITOR EDITOR EDITOR|OF OF|MANY MANY MANY|OTHER OTHER|ARTICLES, ARTICLES,|EVEN EVEN|ASKING ASKING ASKING|FOR FOR|UN-NECESSARY UN-NECESSARY UN-NECESSARY|DELETIONS DELETIONS DELETIONS|OF OF|ARTICLES ARTICLES ARTICLES|THAT THAT|HE HE|DOES DOES|NOT NOT|LIKE..... LIKE..... LIKE.....|AND AND|GETTING GETTING GETTING|SNUBBED SNUBBED SNUBBED|FOR FOR|THE THE|EFFORT!! EFFORT!! I|beg beg beg|your your|pardon? pardon? pardon?|I am|from the|region, region, region,|and and|berbers berbers berbers|are a|minority. minority. minority.|How you|presume presume presume|to know|people's people's people's|origins? origins? origins?|you your|make-belief make-belief make-belief|world, world, world,|but but|do not|post post|it as|fact fact|and don't|delete my|posts posts posts|either either|to to|further further|veil veil veil|the the|truth. truth. truth.|I am|contacting contacting contacting|Wikipedia Wikipedia|immediately immediately immediately|concerning concerning|this this|largely largely largely|fictitious, fictitious, fictitious,|vicious vicious vicious|article and|discussion. discussion. ,|as, as, as,|this my|IP IP|adress adress Would Would|you you|believe believe|it.. it.. it..|This This|frenchie frenchie frenchie|threatens threatens threatens|to to|ban ban|me me|because I|talk talk|badly badly badly|upon upon|Foie Foie Foie|Gras. Gras. Gras.|I already|said said|once once|that is|protected protected protected|by by|lobbyists. lobbyists. lobbyists.|That That|includes includes includes|frog frog frog|eaters. eaters. YOU,|TOO....... TOO....... TOO.......|== YOU|FOR FOR|ATTACKING ATTACKING ATTACKING|ME! ME! is|for for|removing post|on on|100% 100% 100%|== ==|I'm to|DDOS DDOS DDOS|your your|toaster toaster toaster|for for|this. you've|made your|point point|freakin freakin freakin|heck heck heck|what what|do want|me do|huh? I've|explained explained|why why|i i|changed changed|mold mold mold|to to|mould, mould, mould,|i've i've i've|made user|name name|now now|leave leave|me me|alone alone alone|already.... already.... already....|what your|problem. ==|Need Need Need|your your|help help|in Hi|Kansas Kansas Kansas|bear, bear, bear,|I need|your article|called "called|""Sultanate" """Sultanate" """Sultanate|of" "of|Rum""," "Rum""," "Rum"",|vandalized" vandalized|by by|Turkish Turkish Turkish|nationalist nationalist nationalist|and and|even even|including including|dubious dubious dubious|sources sources|from from|books books books|like like|lonelyplanet lonelyplanet lonelyplanet|travel travel travel|guides. guides. guides.|The The|guy guy|has a|profound profound profound|anti anti anti|neutrality neutrality neutrality|agenda, agenda, agenda,|even even|removing the|Persianate Persianate Persianate|description description|of the|state state|and and|changing changing|a a|section section|about about|Sultanate's Sultanate's Sultanate's|architecture, architecture, architecture,|by by|renaming renaming renaming|it "as|""culture""," """culture""," """culture"",|in" in|order order order|to move|around around|the the|sources sources|for Persianate|terms. terms. terms.|I it|needs be|addressed addressed|by by|more than|one one|person person|to to|kick kick kick|out the|nationalistic nationalistic nationalistic|bias bias bias|from the|article. pure|tripe tripe tripe|stolen stolen|from their|bio bio bio|on on|their their|official official official|website, website, website,|which is|outdated outdated outdated|by the|way. way. way.|That's That's|bad bad|wiki wiki|practice. practice. I|saw saw saw|it it|before before|watching watching watching|the the|episode. episode. episode.|Oh Oh|well. Stupid! Stupid!|You're You're|the who|stops stops stops|for for|massive massive massive|and and|undiscussed undiscussed undiscussed|removal removal|on article.|Also, Also,|you you|say say|you're you're|interest in|Chinese Chinese|history history|well well|then go|for for|it it|and don't|ever ever|pay pay pay|attention to|Vietnamese Vietnamese Vietnamese|history. history. Jackson Jackson|didn't didn't|perform perform perform|at the|WMA WMA WMA|because he|can't can't|sing sing sing|at at|all all|anymore. anymore. anymore.|That That|is the|real real|reason reason|he he|hasn't hasn't hasn't|toured toured toured|for a|decade, decade, decade,|along along along|with his|bankruptcy. bankruptcy. bankruptcy.|Even Even|his his|vocals vocals vocals|on "on|""We've" """We've" """We've|Had" Had "Had|Enough""" "Enough""" "Enough""|four" four|years years|ago ago ago|were were|poor poor|and and|he he|never never|had a|strong strong|voice voice voice|to to|begin begin begin|with, with, with,|certainly certainly|not not|comparable comparable comparable|with real|King, King, King,|Elvis Elvis Elvis|Presley. Presley. Presley.|Jackson Jackson|has has|had had|financial financial|problems problems|since since|at least|1998 1998 1998|due due due|to to|his his|declining declining declining|sales sales|and and|popularity, popularity, popularity,|as well|as as|his his|inactivity inactivity inactivity|and having|to to|support support|all all|his his|siblings siblings siblings|and and|parents. parents. parents.|In In|2002 2002 2002|it was|revealed revealed revealed|he in|debt debt|to various|international international international|banks banks banks|to the|tune tune tune|of of|tens tens tens|of of|millions of|dollars, dollars, dollars,|and and|after after|losing losing|those those|lawsuits lawsuits lawsuits|in in|May May May|2003 2003 2003|he was|confirmed confirmed confirmed|as the|verge verge verge|of of|bankuptcy bankuptcy bankuptcy|with with|debts debts debts|of of|$400 $400 $400|million. million. million.|Invincible Invincible Invincible|was a|flop flop flop|because it|sold sold|less less|than a|third third|of his|last last|album, album, "album,|""Dangerous""," """Dangerous""," """Dangerous"",|and" and|it was|thoroughly thoroughly thoroughly|mediocre mediocre mediocre|music. music. music.|Almost Almost|all of|Jackson's Jackson's Jackson's|remaining remaining remaining|fans fans|regard regard regard|it his|worst worst|album. album. album.|In In|1989 1989 1989|Jackson Jackson|made made|it it|known known|he addressed|as the|King King King|of of|Pop Pop Pop|- a|meaningless, meaningless, meaningless,|self-proclaimed self-proclaimed self-proclaimed|title. title. title.|He He|even even|planned planned planned|to to|buy buy buy|Graceland Graceland Graceland|so so|he he|could could|demolish demolish demolish|it, it,|which which|certainly certainly|says says|far far|more more|about about|Jackson's Jackson's|megalomania megalomania megalomania|than than|it does|about about|Presley. Presley.|Half Half Half|the the|songs songs songs|on the|Dangerous Dangerous Dangerous|album album|weren't weren't|good, good, good,|especially the|unbelievably unbelievably unbelievably|awful awful awful|Heal Heal Heal|the the|World, World, World,|and it|only only|sold sold|30 30|million million million|copies copies copies|on the|strength strength strength|of his|previous previous|three three three|albums. albums. albums.|Yeah, Yeah, Yeah,|WJ WJ WJ|was was|unique unique unique|all all|right, right,|but the|less less|said said|about the|better. must|know know|some some|very very|sad sad|20-year-olds 20-year-olds 20-year-olds|if they|still still|admire admire admire|the the|disgraced disgraced disgraced|former former former|King of|Pop. Pop. Pop.|Anyway, Anyway, Anyway,|most people|know know|him him|as as|Wacko Wacko Wacko|Jacko. Jacko. Jacko.|Justin Justin Justin|is real|King Pop|and and|like like|Eminem Eminem Eminem|he he|just just|doesn't doesn't|want to|risk risk risk|offending offending offending|WJ's WJ's WJ's|fans. fans. fans.|Justin Justin|will to|perform, perform, perform,|while while while|Jackson's Jackson's|active active active|career career|finished finished finished|a a|decade decade decade|ago. ago.|( ( (|) ==Appears ==Appears|to to|Be Be Be|Uncontructive?== Uncontructive?== Uncontructive?==|Since Since Since|when when|do do|your your|mere mere mere|feelings feelings feelings|= =|evidence? evidence? evidence?|Get Get|a a|clue clue clue|hypocrite. hypocrite. hypocrite.|You one|being being|unconstructive. unconstructive. WHy WHy|are you|ugly ugly ugly|and and|fat? fat? "::Is" "::Is|that" that|so? so? so?|Than Than Than|why why|so so|many people|questiong questiong questiong|your your|incredibly incredibly incredibly|arrogant, arrogant, arrogant,|and and|entirely entirely entirely|inappropriate inappropriate inappropriate|edit edit|actions? actions? actions?|Maybe Maybe|you're you're|such such|an an|arrogant arrogant|person, person,|you think|YOU YOU|are only|member member member|of the|community community community|that that|matters? matters? Yep, Yep,|he he|be the|mouthpiece, mouthpiece, mouthpiece,|but but|his his|law law law|still still|stands. stands. stands.|Oh, Oh,|that was|friggin' friggin' friggin'|bad. bad. **And **And|we a|winner winner winner|for the|douchiest douchiest douchiest|comment comment|award. award. 65536 0:"" ==RUDE== Dude, you are rude upload that carl picture back, or else. 0 1 2 3 4 5 6 7 8 9 10 11 78649 0:1 1:1 2:1 3:1 4:1 5:1 6:1 7:1 8:1 9:1 10:1 11:1 12:1 13:1 14:1 15:1 16:1 17:1 18:1 19:1 20:1 21:1 22:1 14281:1 15549:1 18532:1 22191:1 23536:1 23628:1 31929:1 32833:1 34566:1 35389:1 37844:1 38980:1 39602:1 44258:1 57516:1 57853:1 58814:1 58940:1 59232:1 63039:1 63431:1 77175:1 78141:1 diff --git a/test/Microsoft.ML.Benchmarks/KMeansAndLogisticRegressionBench.cs b/test/Microsoft.ML.Benchmarks/KMeansAndLogisticRegressionBench.cs index 870480ebbc..1dbc74c9d0 100644 --- a/test/Microsoft.ML.Benchmarks/KMeansAndLogisticRegressionBench.cs +++ b/test/Microsoft.ML.Benchmarks/KMeansAndLogisticRegressionBench.cs @@ -23,12 +23,12 @@ public CalibratedModelParametersBase GetColumnComparer(DataViewRow r1, DataViewRow r2, int col, switch (kind) { - case DataKind.I1: + case InternalDataKind.I1: return GetComparerVec(r1, r2, col, size, (x, y) => x == y); - case DataKind.U1: + case InternalDataKind.U1: return GetComparerVec(r1, r2, col, size, (x, y) => x == y); - case DataKind.I2: + case InternalDataKind.I2: return GetComparerVec(r1, r2, col, size, (x, y) => x == y); - case DataKind.U2: + case InternalDataKind.U2: return GetComparerVec(r1, r2, col, size, (x, y) => x == y); - case DataKind.I4: + case InternalDataKind.I4: return GetComparerVec(r1, r2, col, size, (x, y) => x == y); - case DataKind.U4: + case InternalDataKind.U4: return GetComparerVec(r1, r2, col, size, (x, y) => x == y); - case DataKind.I8: + case InternalDataKind.I8: return GetComparerVec(r1, r2, col, size, (x, y) => x == y); - case DataKind.U8: + case InternalDataKind.U8: return GetComparerVec(r1, r2, col, size, (x, y) => x == y); - case DataKind.R4: + case InternalDataKind.R4: return GetComparerVec(r1, r2, col, size, (x, y) => FloatUtils.GetBits(x) == FloatUtils.GetBits(y)); - case DataKind.R8: + case InternalDataKind.R8: if (exactDoubles) return GetComparerVec(r1, r2, col, size, (x, y) => FloatUtils.GetBits(x) == FloatUtils.GetBits(y)); else return GetComparerVec(r1, r2, col, size, EqualWithEps); - case DataKind.Text: + case InternalDataKind.Text: return GetComparerVec>(r1, r2, col, size, (a, b) => a.Span.SequenceEqual(b.Span)); - case DataKind.Bool: + case InternalDataKind.Bool: return GetComparerVec(r1, r2, col, size, (x, y) => x == y); - case DataKind.TimeSpan: + case InternalDataKind.TimeSpan: return GetComparerVec(r1, r2, col, size, (x, y) => x.Ticks == y.Ticks); - case DataKind.DT: + case InternalDataKind.DT: return GetComparerVec(r1, r2, col, size, (x, y) => x.Ticks == y.Ticks); - case DataKind.DZ: + case InternalDataKind.DZ: return GetComparerVec(r1, r2, col, size, (x, y) => x.Equals(y)); - case DataKind.UG: + case InternalDataKind.UG: return GetComparerVec(r1, r2, col, size, (x, y) => x.Equals(y)); } } @@ -208,40 +208,40 @@ protected Func GetColumnComparer(DataViewRow r1, DataViewRow r2, int col, Contracts.Assert(result); switch (kind) { - case DataKind.I1: + case InternalDataKind.I1: return GetComparerOne(r1, r2, col, (x, y) => x == y); - case DataKind.U1: + case InternalDataKind.U1: return GetComparerOne(r1, r2, col, (x, y) => x == y); - case DataKind.I2: + case InternalDataKind.I2: return GetComparerOne(r1, r2, col, (x, y) => x == y); - case DataKind.U2: + case InternalDataKind.U2: return GetComparerOne(r1, r2, col, (x, y) => x == y); - case DataKind.I4: + case InternalDataKind.I4: return GetComparerOne(r1, r2, col, (x, y) => x == y); - case DataKind.U4: + case InternalDataKind.U4: return GetComparerOne(r1, r2, col, (x, y) => x == y); - case DataKind.I8: + case InternalDataKind.I8: return GetComparerOne(r1, r2, col, (x, y) => x == y); - case DataKind.U8: + case InternalDataKind.U8: return GetComparerOne(r1, r2, col, (x, y) => x == y); - case DataKind.R4: + case InternalDataKind.R4: return GetComparerOne(r1, r2, col, (x, y) => FloatUtils.GetBits(x) == FloatUtils.GetBits(y)); - case DataKind.R8: + case InternalDataKind.R8: if (exactDoubles) return GetComparerOne(r1, r2, col, (x, y) => FloatUtils.GetBits(x) == FloatUtils.GetBits(y)); else return GetComparerOne(r1, r2, col, EqualWithEps); - case DataKind.Text: + case InternalDataKind.Text: return GetComparerOne>(r1, r2, col, (a, b) => a.Span.SequenceEqual(b.Span)); - case DataKind.Bool: + case InternalDataKind.Bool: return GetComparerOne(r1, r2, col, (x, y) => x == y); - case DataKind.TimeSpan: + case InternalDataKind.TimeSpan: return GetComparerOne(r1, r2, col, (x, y) => x.Ticks == y.Ticks); - case DataKind.DT: + case InternalDataKind.DT: return GetComparerOne(r1, r2, col, (x, y) => x.Ticks == y.Ticks); - case DataKind.DZ: + case InternalDataKind.DZ: return GetComparerOne(r1, r2, col, (x, y) => x.Equals(y)); - case DataKind.UG: + case InternalDataKind.UG: return GetComparerOne(r1, r2, col, (x, y) => x.Equals(y)); } } diff --git a/test/Microsoft.ML.Core.Tests/UnitTests/TestEntryPoints.cs b/test/Microsoft.ML.Core.Tests/UnitTests/TestEntryPoints.cs index a33d91ebda..8ad01452fb 100644 --- a/test/Microsoft.ML.Core.Tests/UnitTests/TestEntryPoints.cs +++ b/test/Microsoft.ML.Core.Tests/UnitTests/TestEntryPoints.cs @@ -56,8 +56,8 @@ private IDataView GetBreastCancerDataView() { Columns = new[] { - new TextLoader.Column("Label", DataKind.R4, 0), - new TextLoader.Column("Features", DataKind.R4, + new TextLoader.Column("Label", DataKind.Single, 0), + new TextLoader.Column("Features", DataKind.Single, new [] { new TextLoader.Range(1, 9) }) } }, @@ -77,10 +77,10 @@ private IDataView GetBreastCancerDataviewWithTextColumns() HasHeader = true, Columns = new[] { - new TextLoader.Column("Label", type: null, 0), - new TextLoader.Column("F1", DataKind.Text, 1), - new TextLoader.Column("F2", DataKind.I4, 2), - new TextLoader.Column("Rest", type: null, new [] { new TextLoader.Range(3, 9) }) + new TextLoader.Column("Label", DataKind.Single, 0), + new TextLoader.Column("F1", DataKind.String, 1), + new TextLoader.Column("F2", DataKind.Int32, 2), + new TextLoader.Column("Rest", DataKind.Single, new [] { new TextLoader.Range(3, 9) }) } }, @@ -965,8 +965,8 @@ public void EntryPointPipelineEnsembleText() HasHeader = true, Columns = new[] { - new TextLoader.Column("Label", DataKind.TX, 0), - new TextLoader.Column("Text", DataKind.TX, 3) + new TextLoader.Column("Label", DataKind.String, 0), + new TextLoader.Column("Text", DataKind.String, 3) } }, @@ -1176,8 +1176,8 @@ public void EntryPointMulticlassPipelineEnsemble() { Columns = new[] { - new TextLoader.Column("Label", DataKind.R4, 0), - new TextLoader.Column("Features", DataKind.R4, new [] { new TextLoader.Range(1, 4) }) + new TextLoader.Column("Label", DataKind.Single, 0), + new TextLoader.Column("Features", DataKind.Single, new [] { new TextLoader.Range(1, 4) }) } }, @@ -1322,9 +1322,9 @@ public void EntryPointPipelineEnsembleGetSummary() { Columns = new[] { - new TextLoader.Column("Label", DataKind.R4, 0), - new TextLoader.Column("Features", DataKind.R4, new[] { new TextLoader.Range(1, 8) }), - new TextLoader.Column("Cat", DataKind.TX, 9) + new TextLoader.Column("Label", DataKind.Single, 0), + new TextLoader.Column("Features", DataKind.Single, new[] { new TextLoader.Range(1, 8) }), + new TextLoader.Column("Cat", DataKind.String, 9) }, HasHeader = true, } @@ -3330,8 +3330,8 @@ public void EntryPointLinearPredictorSummary() HasHeader = true, Columns = new[] { - new TextLoader.Column("Label", type: null, 0), - new TextLoader.Column("Features", DataKind.Num, new [] { new TextLoader.Range(1, 9) }) + new TextLoader.Column("Label", DataKind.Single, 0), + new TextLoader.Column("Features", DataKind.Single, new [] { new TextLoader.Range(1, 9) }) } }, @@ -3405,7 +3405,7 @@ public void EntryPointPcaPredictorSummary() HasHeader = false, Columns = new[] { - new TextLoader.Column("Features", DataKind.R4, new [] { new TextLoader.Range(1, 784) }) + new TextLoader.Column("Features", DataKind.Single, new [] { new TextLoader.Range(1, 784) }) } }, @@ -3618,7 +3618,7 @@ public void EntryPointWordEmbeddings() Separators = new []{' '}, Columns = new[] { - new TextLoader.Column("Text", DataKind.Text, + new TextLoader.Column("Text", DataKind.String, new [] { new TextLoader.Range() { Min = 0, VariableEnd=true, ForceVector=true} }) } }, diff --git a/test/Microsoft.ML.Core.Tests/UnitTests/TestHosts.cs b/test/Microsoft.ML.Core.Tests/UnitTests/TestHosts.cs index fff6e594f2..5adceb7ec9 100644 --- a/test/Microsoft.ML.Core.Tests/UnitTests/TestHosts.cs +++ b/test/Microsoft.ML.Core.Tests/UnitTests/TestHosts.cs @@ -83,8 +83,7 @@ public void LogEventProcessesMessages() env.Log += (sender, e) => messages.Add(e.Message); // create a dummy text reader to trigger log messages - env.Data.CreateTextLoader( - new TextLoader.Options {Columns = new[] {new TextLoader.Column("TestColumn", null, 0)}}); + env.Data.CreateTextLoader(new TextLoader.Options { Columns = new[] { new TextLoader.Column("TestColumn", DataKind.Single, 0) } }); Assert.True(messages.Count > 0); } diff --git a/test/Microsoft.ML.Functional.Tests/Common.cs b/test/Microsoft.ML.Functional.Tests/Common.cs index bcba3a8e27..9ca819952b 100644 --- a/test/Microsoft.ML.Functional.Tests/Common.cs +++ b/test/Microsoft.ML.Functional.Tests/Common.cs @@ -158,7 +158,6 @@ public static void AssertEqual(TypeTestData testType1, TypeTestData testType2) Assert.True(testType1.Ts.Equals(testType2.Ts)); Assert.True(testType1.Dt.Equals(testType2.Dt)); Assert.True(testType1.Dz.Equals(testType2.Dz)); - Assert.True(testType1.Ug.Equals(testType2.Ug)); } /// diff --git a/test/Microsoft.ML.Functional.Tests/Datasets/MnistOneClass.cs b/test/Microsoft.ML.Functional.Tests/Datasets/MnistOneClass.cs index 07b26d3d9c..0a83091fd8 100644 --- a/test/Microsoft.ML.Functional.Tests/Datasets/MnistOneClass.cs +++ b/test/Microsoft.ML.Functional.Tests/Datasets/MnistOneClass.cs @@ -18,8 +18,8 @@ public static TextLoader GetTextLoader(MLContext mlContext, bool hasHeader, char { return mlContext.Data.CreateTextLoader( new[] { - new TextLoader.Column("Label", DataKind.R4, 0), - new TextLoader.Column("Features", DataKind.R4, 1, 1 + _featureLength) + new TextLoader.Column("Label", DataKind.Single, 0), + new TextLoader.Column("Features", DataKind.Single, 1, 1 + _featureLength) }, separatorChar: separatorChar, hasHeader: hasHeader, diff --git a/test/Microsoft.ML.Functional.Tests/Datasets/TypeTestData.cs b/test/Microsoft.ML.Functional.Tests/Datasets/TypeTestData.cs index f5524098bb..223320cb0a 100644 --- a/test/Microsoft.ML.Functional.Tests/Datasets/TypeTestData.cs +++ b/test/Microsoft.ML.Functional.Tests/Datasets/TypeTestData.cs @@ -65,10 +65,7 @@ internal sealed class TypeTestData [LoadColumn(14)] public DateTimeOffset Dz { get; set; } - [LoadColumn(15)] - public DataViewRowId Ug { get; set; } - - [LoadColumn(16, 16 + _numFeatures - 1), VectorType(_numFeatures)] + [LoadColumn(15, 15 + _numFeatures - 1), VectorType(_numFeatures)] public float[] Features { get; set; } @@ -82,23 +79,22 @@ public static TextLoader GetTextLoader(MLContext mlContext, char separator) { return mlContext.Data.CreateTextLoader( new[] { - new TextLoader.Column("Label", DataKind.Bool, 0), - new TextLoader.Column("I1", DataKind.I1, 1), - new TextLoader.Column("U1", DataKind.U1, 2), - new TextLoader.Column("I2", DataKind.I2, 3), - new TextLoader.Column("U2", DataKind.U2, 4), - new TextLoader.Column("I4", DataKind.I4, 5), - new TextLoader.Column("U4", DataKind.U4, 6), - new TextLoader.Column("I8", DataKind.I8, 7), - new TextLoader.Column("U8", DataKind.U8, 8), - new TextLoader.Column("R4", DataKind.R4, 9), - new TextLoader.Column("R8", DataKind.R8, 10), - new TextLoader.Column("Tx", DataKind.TX, 11), - new TextLoader.Column("Ts", DataKind.TS, 12), - new TextLoader.Column("Dt", DataKind.DT, 13), - new TextLoader.Column("Dz", DataKind.DZ, 14), - new TextLoader.Column("Ug", DataKind.UG, 15), - new TextLoader.Column("Features", DataKind.R4, 16, 16 + _numFeatures-1), + new TextLoader.Column("Label", DataKind.Boolean, 0), + new TextLoader.Column("I1", DataKind.SByte, 1), + new TextLoader.Column("U1", DataKind.Byte, 2), + new TextLoader.Column("I2", DataKind.Int16, 3), + new TextLoader.Column("U2", DataKind.UInt16, 4), + new TextLoader.Column("I4", DataKind.Int32, 5), + new TextLoader.Column("U4", DataKind.UInt32, 6), + new TextLoader.Column("I8", DataKind.Int64, 7), + new TextLoader.Column("U8", DataKind.UInt64, 8), + new TextLoader.Column("R4", DataKind.Single, 9), + new TextLoader.Column("R8", DataKind.Double, 10), + new TextLoader.Column("Tx", DataKind.String, 11), + new TextLoader.Column("Ts", DataKind.TimeSpan, 12), + new TextLoader.Column("Dt", DataKind.DateTime, 13), + new TextLoader.Column("Dz", DataKind.DateTimeOffset, 14), + new TextLoader.Column("Features", DataKind.Single, 15, 15 + _numFeatures - 1), }, separatorChar: separator, hasHeader: true, @@ -147,7 +143,6 @@ public static TypeTestData GetRandomInstance(Random rng) Ts = TimeSpan.FromSeconds(rng.NextDouble() * (1 + rng.Next())), Dt = DateTime.FromOADate(rng.Next(657435, 2958465)), Dz = DateTimeOffset.FromUnixTimeSeconds((long)(rng.NextDouble() * (1 + rng.Next()))), - Ug = new DataViewRowId((ulong)rng.Next(), (ulong)rng.Next()), Features = GetRandomFloatArray(rng, _numFeatures), }; } diff --git a/test/Microsoft.ML.Predictor.Tests/TestIniModels.cs b/test/Microsoft.ML.Predictor.Tests/TestIniModels.cs index 234ff0a7d5..ce4579d629 100644 --- a/test/Microsoft.ML.Predictor.Tests/TestIniModels.cs +++ b/test/Microsoft.ML.Predictor.Tests/TestIniModels.cs @@ -2,17 +2,11 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; using System.Collections.Generic; using System.IO; -using System.Threading; -using Microsoft.ML; using Microsoft.ML.Data; -using Microsoft.ML.Internal.Calibration; using Microsoft.ML.Internal.Utilities; using Microsoft.ML.Internal.Internallearn; -using Microsoft.ML.Trainers.FastTree; -using Microsoft.ML.Tools; using Xunit; using Xunit.Abstractions; @@ -527,8 +521,8 @@ public void TestGamRegressionIni() HasHeader = false, Columns = new[] { - new TextLoader.Column("Label", DataKind.R4, 0), - new TextLoader.Column("Features", DataKind.R4, 1, 9) + new TextLoader.Column("Label", DataKind.Single, 0), + new TextLoader.Column("Features", DataKind.Single, 1, 9) } }).Read(GetDataPath("breast-cancer.txt")); @@ -566,8 +560,8 @@ public void TestGamBinaryClassificationIni() HasHeader = false, Columns = new[] { - new TextLoader.Column("Label", DataKind.BL, 0), - new TextLoader.Column("Features", DataKind.R4, 1, 9) + new TextLoader.Column("Label", DataKind.Boolean, 0), + new TextLoader.Column("Features", DataKind.Single, 1, 9) } }).Read(GetDataPath("breast-cancer.txt")); diff --git a/test/Microsoft.ML.TestFramework/Datasets.cs b/test/Microsoft.ML.TestFramework/Datasets.cs index abc9862049..d279332cad 100644 --- a/test/Microsoft.ML.TestFramework/Datasets.cs +++ b/test/Microsoft.ML.TestFramework/Datasets.cs @@ -166,18 +166,18 @@ public static class TestDatasets GetLoaderColumns = () => { return new[] { - new TextLoader.Column("MedianHomeValue", DataKind.R4, 0), - new TextLoader.Column("CrimesPerCapita", DataKind.R4, 1), - new TextLoader.Column("PercentResidental", DataKind.R4, 2), - new TextLoader.Column("PercentNonRetail", DataKind.R4, 3), - new TextLoader.Column("CharlesRiver", DataKind.R4, 4), - new TextLoader.Column("NitricOxides", DataKind.R4, 5), - new TextLoader.Column("RoomsPerDwelling", DataKind.R4, 6), - new TextLoader.Column("PercentPre40s", DataKind.R4, 7), - new TextLoader.Column("EmploymentDistance", DataKind.R4, 8), - new TextLoader.Column("HighwayDistance", DataKind.R4, 9), - new TextLoader.Column("TaxRate", DataKind.R4, 10), - new TextLoader.Column("TeacherRatio", DataKind.R4, 11), + new TextLoader.Column("MedianHomeValue", DataKind.Single, 0), + new TextLoader.Column("CrimesPerCapita", DataKind.Single, 1), + new TextLoader.Column("PercentResidental", DataKind.Single, 2), + new TextLoader.Column("PercentNonRetail", DataKind.Single, 3), + new TextLoader.Column("CharlesRiver", DataKind.Single, 4), + new TextLoader.Column("NitricOxides", DataKind.Single, 5), + new TextLoader.Column("RoomsPerDwelling", DataKind.Single, 6), + new TextLoader.Column("PercentPre40s", DataKind.Single, 7), + new TextLoader.Column("EmploymentDistance", DataKind.Single, 8), + new TextLoader.Column("HighwayDistance", DataKind.Single, 9), + new TextLoader.Column("TaxRate", DataKind.Single, 10), + new TextLoader.Column("TeacherRatio", DataKind.Single, 11), }; } }; @@ -216,8 +216,8 @@ public static class TestDatasets { return new[] { - new TextLoader.Column("Label", DataKind.BL, 0), - new TextLoader.Column("SentimentText", DataKind.Text, 1) + new TextLoader.Column("Label", DataKind.Boolean, 0), + new TextLoader.Column("SentimentText", DataKind.String, 1) }; } }; @@ -404,11 +404,11 @@ public static class TestDatasets { return new[] { - new TextLoader.Column("SepalLength", DataKind.R4, 0), - new TextLoader.Column("SepalWidth", DataKind.R4, 1), - new TextLoader.Column("PetalLength", DataKind.R4, 2), - new TextLoader.Column("PetalWidth",DataKind.R4, 3), - new TextLoader.Column("Label", DataKind.Text, 4) + new TextLoader.Column("SepalLength", DataKind.Single, 0), + new TextLoader.Column("SepalWidth", DataKind.Single, 1), + new TextLoader.Column("PetalLength", DataKind.Single, 2), + new TextLoader.Column("PetalWidth",DataKind.Single, 3), + new TextLoader.Column("Label", DataKind.String, 4) }; } }; diff --git a/test/Microsoft.ML.Tests/AnomalyDetectionTests.cs b/test/Microsoft.ML.Tests/AnomalyDetectionTests.cs index 63b14132db..03fbafbf7f 100644 --- a/test/Microsoft.ML.Tests/AnomalyDetectionTests.cs +++ b/test/Microsoft.ML.Tests/AnomalyDetectionTests.cs @@ -2,15 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; -using System.Drawing; -using System.Drawing.Imaging; -using System.IO; -using System.Linq; -using Microsoft.Data.DataView; using Microsoft.ML.Data; -using Microsoft.ML.ImageAnalytics; -using Microsoft.ML.Model; using Microsoft.ML.RunTests; using Xunit; using Xunit.Abstractions; @@ -38,8 +30,8 @@ public void RandomizedPcaTrainerBaselineTest() Separator = "\t", Columns = new[] { - new TextLoader.Column("Label", DataKind.R4, 0), - new TextLoader.Column(featureColumn, DataKind.R4, new [] { new TextLoader.Range(1, 784) }) + new TextLoader.Column("Label", DataKind.Single, 0), + new TextLoader.Column(featureColumn, DataKind.Single, new [] { new TextLoader.Range(1, 784) }) }, AllowSparse = true }); diff --git a/test/Microsoft.ML.Tests/FakeSchemaTest.cs b/test/Microsoft.ML.Tests/FakeSchemaTest.cs index 208a62a796..c442bd1dbb 100644 --- a/test/Microsoft.ML.Tests/FakeSchemaTest.cs +++ b/test/Microsoft.ML.Tests/FakeSchemaTest.cs @@ -41,7 +41,7 @@ void SimpleTest() Assert.Equal(10, columnA.Type.GetValueCount()); Assert.Equal("B", columnB.Name); - Assert.Equal(DataKind.U4, columnB.Type.GetRawKind()); + Assert.Equal(InternalDataKind.U4, columnB.Type.GetRawKind()); Assert.Equal(10u, columnB.Type.GetKeyCount()); Assert.Equal("C", columnC.Name); diff --git a/test/Microsoft.ML.Tests/ImagesTests.cs b/test/Microsoft.ML.Tests/ImagesTests.cs index cc73af5d2f..37208c499d 100644 --- a/test/Microsoft.ML.Tests/ImagesTests.cs +++ b/test/Microsoft.ML.Tests/ImagesTests.cs @@ -33,15 +33,15 @@ public void TestEstimatorChain() { Columns = new[] { - new TextLoader.Column("ImagePath", DataKind.TX, 0), - new TextLoader.Column("Name", DataKind.TX, 1), + new TextLoader.Column("ImagePath", DataKind.String, 0), + new TextLoader.Column("Name", DataKind.String, 1), } }, new MultiFileSource(dataFile)); var invalidData = TextLoader.Create(env, new TextLoader.Options() { Columns = new[] { - new TextLoader.Column("ImagePath", DataKind.R4, 0), + new TextLoader.Column("ImagePath", DataKind.Single, 0), } }, new MultiFileSource(dataFile)); @@ -64,8 +64,8 @@ public void TestEstimatorSaveLoad() { Columns = new[] { - new TextLoader.Column("ImagePath", DataKind.TX, 0), - new TextLoader.Column("Name", DataKind.TX, 1), + new TextLoader.Column("ImagePath", DataKind.String, 0), + new TextLoader.Column("Name", DataKind.String, 1), } }, new MultiFileSource(dataFile)); @@ -103,8 +103,8 @@ public void TestSaveImages() { Columns = new[] { - new TextLoader.Column("ImagePath", DataKind.TX, 0), - new TextLoader.Column("Name", DataKind.TX, 1), + new TextLoader.Column("ImagePath", DataKind.String, 0), + new TextLoader.Column("Name", DataKind.String, 1), } }, new MultiFileSource(dataFile)); var images = new ImageLoadingTransformer(env, imageFolder, ("ImageReal", "ImagePath")).Transform(data); @@ -142,8 +142,8 @@ public void TestGreyscaleTransformImages() { Columns = new[] { - new TextLoader.Column("ImagePath", DataKind.TX, 0), - new TextLoader.Column("Name", DataKind.TX, 1), + new TextLoader.Column("ImagePath", DataKind.String, 0), + new TextLoader.Column("Name", DataKind.String, 1), } }, new MultiFileSource(dataFile)); var images = new ImageLoadingTransformer(env, imageFolder, ("ImageReal", "ImagePath")).Transform(data); @@ -193,8 +193,8 @@ public void TestBackAndForthConversionWithAlphaInterleave() { Columns = new[] { - new TextLoader.Column("ImagePath", DataKind.TX, 0), - new TextLoader.Column("Name", DataKind.TX, 1), + new TextLoader.Column("ImagePath", DataKind.String, 0), + new TextLoader.Column("Name", DataKind.String, 1), } }, new MultiFileSource(dataFile)); var images = new ImageLoadingTransformer(env, imageFolder, ("ImageReal", "ImagePath")).Transform(data); @@ -253,8 +253,8 @@ public void TestBackAndForthConversionWithoutAlphaInterleave() { Columns = new[] { - new TextLoader.Column("ImagePath", DataKind.TX, 0), - new TextLoader.Column("Name", DataKind.TX, 1), + new TextLoader.Column("ImagePath", DataKind.String, 0), + new TextLoader.Column("Name", DataKind.String, 1), } }, new MultiFileSource(dataFile)); var images = new ImageLoadingTransformer(env, imageFolder, ("ImageReal", "ImagePath")).Transform(data); @@ -313,8 +313,8 @@ public void TestBackAndForthConversionWithDifferentOrder() { Columns = new[] { - new TextLoader.Column("ImagePath", DataKind.TX, 0), - new TextLoader.Column("Name", DataKind.TX, 1), + new TextLoader.Column("ImagePath", DataKind.String, 0), + new TextLoader.Column("Name", DataKind.String, 1), } }, new MultiFileSource(dataFile)); var images = new ImageLoadingTransformer(env, imageFolder, ("ImageReal", "ImagePath")).Transform(data); @@ -375,8 +375,8 @@ public void TestBackAndForthConversionWithAlphaNoInterleave() { Columns = new[] { - new TextLoader.Column("ImagePath", DataKind.TX, 0), - new TextLoader.Column("Name", DataKind.TX, 1), + new TextLoader.Column("ImagePath", DataKind.String, 0), + new TextLoader.Column("Name", DataKind.String, 1), } }, new MultiFileSource(dataFile)); var images = new ImageLoadingTransformer(env, imageFolder, ("ImageReal", "ImagePath")).Transform(data); @@ -435,8 +435,8 @@ public void TestBackAndForthConversionWithoutAlphaNoInterleave() { Columns = new[] { - new TextLoader.Column("ImagePath", DataKind.TX, 0), - new TextLoader.Column("Name", DataKind.TX, 1), + new TextLoader.Column("ImagePath", DataKind.String, 0), + new TextLoader.Column("Name", DataKind.String, 1), } }, new MultiFileSource(dataFile)); var images = new ImageLoadingTransformer(env, imageFolder, ("ImageReal", "ImagePath")).Transform(data); @@ -495,8 +495,8 @@ public void TestBackAndForthConversionWithAlphaInterleaveNoOffset() { Columns = new[] { - new TextLoader.Column("ImagePath", DataKind.TX, 0), - new TextLoader.Column("Name", DataKind.TX, 1), + new TextLoader.Column("ImagePath", DataKind.String, 0), + new TextLoader.Column("Name", DataKind.String, 1), } }, new MultiFileSource(dataFile)); var images = new ImageLoadingTransformer(env, imageFolder, ("ImageReal", "ImagePath")).Transform(data); @@ -556,8 +556,8 @@ public void TestBackAndForthConversionWithoutAlphaInterleaveNoOffset() { Columns = new[] { - new TextLoader.Column("ImagePath", DataKind.TX, 0), - new TextLoader.Column("Name", DataKind.TX, 1), + new TextLoader.Column("ImagePath", DataKind.String, 0), + new TextLoader.Column("Name", DataKind.String, 1), } }, new MultiFileSource(dataFile)); var images = new ImageLoadingTransformer(env, imageFolder, ("ImageReal", "ImagePath")).Transform(data); @@ -616,8 +616,8 @@ public void TestBackAndForthConversionWithAlphaNoInterleaveNoOffset() { Columns = new[] { - new TextLoader.Column("ImagePath", DataKind.TX, 0), - new TextLoader.Column("Name", DataKind.TX, 1), + new TextLoader.Column("ImagePath", DataKind.String, 0), + new TextLoader.Column("Name", DataKind.String, 1), } }, new MultiFileSource(dataFile)); var images = new ImageLoadingTransformer(env, imageFolder, ("ImageReal", "ImagePath")).Transform(data); @@ -677,9 +677,9 @@ public void TestBackAndForthConversionWithoutAlphaNoInterleaveNoOffset() { Columns = new[] { - new TextLoader.Column("ImagePath", DataKind.TX, 0), - new TextLoader.Column("Name", DataKind.TX, 1), - } + new TextLoader.Column("ImagePath", DataKind.String, 0), + new TextLoader.Column("Name", DataKind.String, 1), + } }, new MultiFileSource(dataFile)); var images = new ImageLoadingTransformer(env, imageFolder, ("ImageReal", "ImagePath")).Transform(data); var cropped = new ImageResizingTransformer(env, "ImageCropped", imageWidth, imageHeight, "ImageReal").Transform(images); @@ -734,7 +734,7 @@ public void ImageResizerTransformResizingModeFill() { Columns = new[] { - new TextLoader.Column("ImagePath", DataKind.TX, 0) + new TextLoader.Column("ImagePath", DataKind.String, 0) } }, new MultiFileSource(dataFile)); diff --git a/test/Microsoft.ML.Tests/Scenarios/Api/CookbookSamples/CookbookSamplesDynamicApi.cs b/test/Microsoft.ML.Tests/Scenarios/Api/CookbookSamples/CookbookSamplesDynamicApi.cs index 3a74d1584f..b3e2502237 100644 --- a/test/Microsoft.ML.Tests/Scenarios/Api/CookbookSamples/CookbookSamplesDynamicApi.cs +++ b/test/Microsoft.ML.Tests/Scenarios/Api/CookbookSamples/CookbookSamplesDynamicApi.cs @@ -279,8 +279,8 @@ private void TextFeaturizationOn(string dataPath) // Define the reader: specify the data columns and where to find them in the text file. var reader = mlContext.Data.CreateTextLoader(new[] { - new TextLoader.Column("IsToxic", DataKind.BL, 0), - new TextLoader.Column("Message", DataKind.TX, 1), + new TextLoader.Column("IsToxic", DataKind.Boolean, 0), + new TextLoader.Column("Message", DataKind.String, 1), }, hasHeader: true ); @@ -346,13 +346,13 @@ private void CategoricalFeaturizationOn(params string[] dataPath) // Define the reader: specify the data columns and where to find them in the text file. var reader = mlContext.Data.CreateTextLoader(new[] { - new TextLoader.Column("Label", DataKind.BL, 0), + new TextLoader.Column("Label", DataKind.Boolean, 0), // We will load all the categorical features into one vector column of size 8. - new TextLoader.Column("CategoricalFeatures", DataKind.TX, 1, 8), + new TextLoader.Column("CategoricalFeatures", DataKind.String, 1, 8), // Similarly, load all numerical features into one vector of size 6. - new TextLoader.Column("NumericalFeatures", DataKind.R4, 9, 14), + new TextLoader.Column("NumericalFeatures", DataKind.Single, 9, 14), // Let's also separately load the 'Workclass' column. - new TextLoader.Column("Workclass", DataKind.TX, 1), + new TextLoader.Column("Workclass", DataKind.String, 1), }, hasHeader: true ); @@ -479,8 +479,8 @@ public void CustomTransformer() var mlContext = new MLContext(); var data = mlContext.Data.ReadFromTextFile(GetDataPath("adult.tiny.with-schema.txt"), new[] { - new TextLoader.Column("Income", DataKind.R4, 10), - new TextLoader.Column("Features", DataKind.R4, 12, 14) + new TextLoader.Column("Income", DataKind.Single, 10), + new TextLoader.Column("Features", DataKind.Single, 12, 14) }, hasHeader: true); PrepareData(mlContext, data); diff --git a/test/Microsoft.ML.Tests/Scenarios/Api/TestApi.cs b/test/Microsoft.ML.Tests/Scenarios/Api/TestApi.cs index 3a6c643bef..498d0a053c 100644 --- a/test/Microsoft.ML.Tests/Scenarios/Api/TestApi.cs +++ b/test/Microsoft.ML.Tests/Scenarios/Api/TestApi.cs @@ -298,10 +298,10 @@ public void TestTrainTestSplit() var dataPath = GetDataPath("adult.tiny.with-schema.txt"); // Create the reader: define the data columns and where to find them in the text file. var input = mlContext.Data.ReadFromTextFile(dataPath, new[] { - new TextLoader.Column("Label", DataKind.BL, 0), - new TextLoader.Column("Workclass", DataKind.TX, 1), - new TextLoader.Column("Education", DataKind.TX,2), - new TextLoader.Column("Age", DataKind.R4,9) + new TextLoader.Column("Label", DataKind.Boolean, 0), + new TextLoader.Column("Workclass", DataKind.String, 1), + new TextLoader.Column("Education", DataKind.String,2), + new TextLoader.Column("Age", DataKind.Single,9) }, hasHeader: true); // this function will accept dataview and return content of "Workclass" column as List of strings. Func> getWorkclass = (IDataView view) => diff --git a/test/Microsoft.ML.Tests/Scenarios/IrisPlantClassificationTests.cs b/test/Microsoft.ML.Tests/Scenarios/IrisPlantClassificationTests.cs index 537e5c787f..76c28195e7 100644 --- a/test/Microsoft.ML.Tests/Scenarios/IrisPlantClassificationTests.cs +++ b/test/Microsoft.ML.Tests/Scenarios/IrisPlantClassificationTests.cs @@ -20,11 +20,11 @@ public void TrainAndPredictIrisModelTest() var reader = mlContext.Data.CreateTextLoader(columns: new[] { - new TextLoader.Column("Label", DataKind.R4, 0), - new TextLoader.Column("SepalLength", DataKind.R4, 1), - new TextLoader.Column("SepalWidth", DataKind.R4, 2), - new TextLoader.Column("PetalLength", DataKind.R4, 3), - new TextLoader.Column("PetalWidth", DataKind.R4, 4) + new TextLoader.Column("Label", DataKind.Single, 0), + new TextLoader.Column("SepalLength", DataKind.Single, 1), + new TextLoader.Column("SepalWidth", DataKind.Single, 2), + new TextLoader.Column("PetalLength", DataKind.Single, 3), + new TextLoader.Column("PetalWidth", DataKind.Single, 4) } ); diff --git a/test/Microsoft.ML.Tests/Scenarios/IrisPlantClassificationWithStringLabelTests.cs b/test/Microsoft.ML.Tests/Scenarios/IrisPlantClassificationWithStringLabelTests.cs index f84279c32d..bdfe1b56a4 100644 --- a/test/Microsoft.ML.Tests/Scenarios/IrisPlantClassificationWithStringLabelTests.cs +++ b/test/Microsoft.ML.Tests/Scenarios/IrisPlantClassificationWithStringLabelTests.cs @@ -17,11 +17,11 @@ public void TrainAndPredictIrisModelWithStringLabelTest() var reader = mlContext.Data.CreateTextLoader(columns: new[] { - new TextLoader.Column("SepalLength", DataKind.R4, 0), - new TextLoader.Column("SepalWidth", DataKind.R4, 1), - new TextLoader.Column("PetalLength", DataKind.R4, 2), - new TextLoader.Column("PetalWidth", DataKind.R4, 3), - new TextLoader.Column("IrisPlantType", DataKind.TX, 4), + new TextLoader.Column("SepalLength", DataKind.Single, 0), + new TextLoader.Column("SepalWidth", DataKind.Single, 1), + new TextLoader.Column("PetalLength", DataKind.Single, 2), + new TextLoader.Column("PetalWidth", DataKind.Single, 3), + new TextLoader.Column("IrisPlantType", DataKind.String, 4), }, separatorChar: ',' ); diff --git a/test/Microsoft.ML.Tests/Scenarios/OvaTest.cs b/test/Microsoft.ML.Tests/Scenarios/OvaTest.cs index e13d1171cd..0a133252b7 100644 --- a/test/Microsoft.ML.Tests/Scenarios/OvaTest.cs +++ b/test/Microsoft.ML.Tests/Scenarios/OvaTest.cs @@ -23,8 +23,8 @@ public void OvaLogisticRegression() { Columns = new[] { - new TextLoader.Column("Label", DataKind.R4, 0), - new TextLoader.Column("Features", DataKind.R4, new [] { new TextLoader.Range(1, 4) }), + new TextLoader.Column("Label", DataKind.Single, 0), + new TextLoader.Column("Features", DataKind.Single, new [] { new TextLoader.Range(1, 4) }), } }); @@ -55,8 +55,8 @@ public void OvaAveragedPerceptron() { Columns = new[] { - new TextLoader.Column("Label", DataKind.R4, 0), - new TextLoader.Column("Features", DataKind.R4, new [] { new TextLoader.Range(1, 4) }), + new TextLoader.Column("Label", DataKind.Single, 0), + new TextLoader.Column("Features", DataKind.Single, new [] { new TextLoader.Range(1, 4) }), } }); @@ -88,8 +88,8 @@ public void OvaFastTree() { Columns = new[] { - new TextLoader.Column("Label", DataKind.R4, 0), - new TextLoader.Column("Features", DataKind.R4, new [] { new TextLoader.Range(1, 4) }), + new TextLoader.Column("Label", DataKind.Single, 0), + new TextLoader.Column("Features", DataKind.Single, new [] { new TextLoader.Range(1, 4) }), } }); @@ -121,8 +121,8 @@ public void OvaLinearSvm() { Columns = new[] { - new TextLoader.Column("Label", DataKind.R4, 0), - new TextLoader.Column("Features", DataKind.R4, new [] { new TextLoader.Range(1, 4) }), + new TextLoader.Column("Label", DataKind.Single, 0), + new TextLoader.Column("Features", DataKind.Single, new [] { new TextLoader.Range(1, 4) }), } }); diff --git a/test/Microsoft.ML.Tests/Scenarios/TensorflowTests.cs b/test/Microsoft.ML.Tests/Scenarios/TensorflowTests.cs index 28e6b56af7..a2116b5bb3 100644 --- a/test/Microsoft.ML.Tests/Scenarios/TensorflowTests.cs +++ b/test/Microsoft.ML.Tests/Scenarios/TensorflowTests.cs @@ -28,8 +28,8 @@ public void TensorFlowTransforCifarEndToEndTest() { Columns = new[] { - new TextLoader.Column("ImagePath", DataKind.TX, 0), - new TextLoader.Column("Label", DataKind.TX, 1), + new TextLoader.Column("ImagePath", DataKind.String, 0), + new TextLoader.Column("Label", DataKind.String, 1), } }, new MultiFileSource(dataFile)); diff --git a/test/Microsoft.ML.Tests/ScenariosWithDirectInstantiation/IrisPlantClassificationTests.cs b/test/Microsoft.ML.Tests/ScenariosWithDirectInstantiation/IrisPlantClassificationTests.cs index ebd184a717..d2f77039e8 100644 --- a/test/Microsoft.ML.Tests/ScenariosWithDirectInstantiation/IrisPlantClassificationTests.cs +++ b/test/Microsoft.ML.Tests/ScenariosWithDirectInstantiation/IrisPlantClassificationTests.cs @@ -18,11 +18,11 @@ public void TrainAndPredictIrisModelUsingDirectInstantiationTest() var reader = mlContext.Data.CreateTextLoader(columns: new[] { - new TextLoader.Column("Label", DataKind.R4, 0), - new TextLoader.Column("SepalLength", DataKind.R4, 1), - new TextLoader.Column("SepalWidth", DataKind.R4, 2), - new TextLoader.Column("PetalLength", DataKind.R4, 3), - new TextLoader.Column("PetalWidth", DataKind.R4, 4) + new TextLoader.Column("Label", DataKind.Single, 0), + new TextLoader.Column("SepalLength", DataKind.Single, 1), + new TextLoader.Column("SepalWidth", DataKind.Single, 2), + new TextLoader.Column("PetalLength", DataKind.Single, 3), + new TextLoader.Column("PetalWidth", DataKind.Single, 4) } ); diff --git a/test/Microsoft.ML.Tests/ScenariosWithDirectInstantiation/TensorflowTests.cs b/test/Microsoft.ML.Tests/ScenariosWithDirectInstantiation/TensorflowTests.cs index 085336646f..1f02337466 100644 --- a/test/Microsoft.ML.Tests/ScenariosWithDirectInstantiation/TensorflowTests.cs +++ b/test/Microsoft.ML.Tests/ScenariosWithDirectInstantiation/TensorflowTests.cs @@ -12,10 +12,8 @@ using Microsoft.ML.RunTests; using Microsoft.ML.TestFramework.Attributes; using Microsoft.ML.Transforms; -using Microsoft.ML.Transforms.Conversions; using Microsoft.ML.Transforms.Normalizers; using Microsoft.ML.Transforms.TensorFlow; -using Microsoft.ML.Transforms.Text; using Xunit; namespace Microsoft.ML.Scenarios @@ -493,8 +491,8 @@ public void TensorFlowTransformMNISTConvTest() var reader = mlContext.Data.CreateTextLoader( columns: new[] { - new TextLoader.Column("Label", DataKind.U4 , new [] { new TextLoader.Range(0) }, new KeyCount(10)), - new TextLoader.Column("Placeholder", DataKind.R4, new []{ new TextLoader.Range(1, 784) }) + new TextLoader.Column("Label", DataKind.UInt32 , new [] { new TextLoader.Range(0) }, new KeyCount(10)), + new TextLoader.Column("Placeholder", DataKind.Single, new []{ new TextLoader.Range(1, 784) }) }, hasHeader: true, @@ -535,12 +533,12 @@ public void TensorFlowTransformMNISTLRTrainingTest() { var mlContext = new MLContext(seed: 1, conc: 1); var reader = mlContext.Data.CreateTextLoader(columns: new[] - { - new TextLoader.Column("Label", DataKind.I8, 0), - new TextLoader.Column("Placeholder", DataKind.R4, new []{ new TextLoader.Range(1, 784) }) - }, + { + new TextLoader.Column("Label", DataKind.Int64, 0), + new TextLoader.Column("Placeholder", DataKind.Single, new []{ new TextLoader.Range(1, 784) }) + }, allowSparse: true - ); + ); var trainData = reader.Read(GetDataPath(TestDatasets.mnistTiny28.trainFilename)); var testData = reader.Read(GetDataPath(TestDatasets.mnistOneClass.testFilename)); @@ -630,9 +628,9 @@ private void ExecuteTFTransformMNISTConvTrainingTest(bool shuffle, int? shuffleS var reader = mlContext.Data.CreateTextLoader(new[] { - new TextLoader.Column("Label", DataKind.U4, new []{ new TextLoader.Range(0) }, new KeyCount(10)), - new TextLoader.Column("TfLabel", DataKind.I8, 0), - new TextLoader.Column("Placeholder", DataKind.R4, new []{ new TextLoader.Range(1, 784) }) + new TextLoader.Column("Label", DataKind.UInt32, new []{ new TextLoader.Range(0) }, new KeyCount(10)), + new TextLoader.Column("TfLabel", DataKind.Int64, 0), + new TextLoader.Column("Placeholder", DataKind.Single, new []{ new TextLoader.Range(1, 784) }) }, allowSparse: true ); @@ -725,8 +723,8 @@ public void TensorFlowTransformMNISTConvSavedModelTest() var mlContext = new MLContext(seed: 1, conc: 1); var reader = mlContext.Data.CreateTextLoader(columns: new[] { - new TextLoader.Column("Label", DataKind.U4 , new [] { new TextLoader.Range(0) }, new KeyCount(10)), - new TextLoader.Column("Placeholder", DataKind.R4, new []{ new TextLoader.Range(1, 784) }) + new TextLoader.Column("Label", DataKind.UInt32 , new [] { new TextLoader.Range(0) }, new KeyCount(10)), + new TextLoader.Column("Placeholder", DataKind.Single, new []{ new TextLoader.Range(1, 784) }) }, hasHeader: true, allowSparse: true @@ -857,8 +855,8 @@ public void TensorFlowTransformCifar() var data = mlContext.Data.ReadFromTextFile(dataFile, columns: new[] { - new TextLoader.Column("ImagePath", DataKind.TX, 0), - new TextLoader.Column("Name", DataKind.TX, 1), + new TextLoader.Column("ImagePath", DataKind.String, 0), + new TextLoader.Column("Name", DataKind.String, 1), } ); @@ -901,8 +899,8 @@ public void TensorFlowTransformCifarSavedModel() var imageFolder = Path.GetDirectoryName(dataFile); var data = mlContext.Data.ReadFromTextFile(dataFile, columns: new[] { - new TextLoader.Column("ImagePath", DataKind.TX, 0), - new TextLoader.Column("Name", DataKind.TX, 1), + new TextLoader.Column("ImagePath", DataKind.String, 0), + new TextLoader.Column("Name", DataKind.String, 1), } ); var images = mlContext.Transforms.LoadImages(imageFolder, ("ImageReal", "ImagePath")).Fit(data).Transform(data); @@ -953,8 +951,8 @@ public void TensorFlowTransformCifarInvalidShape() var data = mlContext.Data.ReadFromTextFile(dataFile, columns: new[] { - new TextLoader.Column("ImagePath", DataKind.TX, 0), - new TextLoader.Column("Name", DataKind.TX, 1), + new TextLoader.Column("ImagePath", DataKind.String, 0), + new TextLoader.Column("Name", DataKind.String, 1), } ); var images = new ImageLoadingTransformer(mlContext, imageFolder, ("ImageReal", "ImagePath")).Transform(data); @@ -995,8 +993,8 @@ public void TensorFlowSentimentClassificationTest() var lookupMap = mlContext.Data.ReadFromTextFile(@"sentiment_model/imdb_word_index.csv", columns: new[] { - new TextLoader.Column("Words", DataKind.TX, 0), - new TextLoader.Column("Ids", DataKind.I4, 1), + new TextLoader.Column("Words", DataKind.String, 0), + new TextLoader.Column("Ids", DataKind.Int32, 1), }, separatorChar: ',' ); diff --git a/test/Microsoft.ML.Tests/TermEstimatorTests.cs b/test/Microsoft.ML.Tests/TermEstimatorTests.cs index 4cc8f02f92..757b073b07 100644 --- a/test/Microsoft.ML.Tests/TermEstimatorTests.cs +++ b/test/Microsoft.ML.Tests/TermEstimatorTests.cs @@ -10,7 +10,6 @@ using Microsoft.ML.Model; using Microsoft.ML.RunTests; using Microsoft.ML.Tools; -using Microsoft.ML.Transforms; using Microsoft.ML.Transforms.Conversions; using Xunit; using Xunit.Abstractions; @@ -58,13 +57,13 @@ void TestDifferentTypes() var loader = new TextLoader(ML, new TextLoader.Options { Columns = new[]{ - new TextLoader.Column("float1", DataKind.R4, 9), - new TextLoader.Column("float4", DataKind.R4, new[]{new TextLoader.Range(9), new TextLoader.Range(10), new TextLoader.Range(11), new TextLoader.Range(12) }), - new TextLoader.Column("double1", DataKind.R8, 9), - new TextLoader.Column("double4", DataKind.R8, new[]{new TextLoader.Range(9), new TextLoader.Range(10), new TextLoader.Range(11), new TextLoader.Range(12) }), - new TextLoader.Column("int1", DataKind.I4, 9), - new TextLoader.Column("text1", DataKind.TX, 1), - new TextLoader.Column("text2", DataKind.TX, new[]{new TextLoader.Range(1), new TextLoader.Range(2)}), + new TextLoader.Column("float1", DataKind.Single, 9), + new TextLoader.Column("float4", DataKind.Single, new[]{new TextLoader.Range(9), new TextLoader.Range(10), new TextLoader.Range(11), new TextLoader.Range(12) }), + new TextLoader.Column("double1", DataKind.Double, 9), + new TextLoader.Column("double4", DataKind.Double, new[]{new TextLoader.Range(9), new TextLoader.Range(10), new TextLoader.Range(11), new TextLoader.Range(12) }), + new TextLoader.Column("int1", DataKind.Int32, 9), + new TextLoader.Column("text1", DataKind.String, 1), + new TextLoader.Column("text2", DataKind.String, new[]{new TextLoader.Range(1), new TextLoader.Range(2)}), }, Separator = "\t", HasHeader = true diff --git a/test/Microsoft.ML.Tests/TrainerEstimators/FAFMEstimator.cs b/test/Microsoft.ML.Tests/TrainerEstimators/FAFMEstimator.cs index 359e44b7e1..c93c4315cb 100644 --- a/test/Microsoft.ML.Tests/TrainerEstimators/FAFMEstimator.cs +++ b/test/Microsoft.ML.Tests/TrainerEstimators/FAFMEstimator.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System.Linq; using Microsoft.ML.Data; using Microsoft.ML.FactorizationMachine; using Microsoft.ML.RunTests; @@ -70,11 +69,11 @@ private TextLoader.Options GetFafmBCLoaderArgs() HasHeader = false, Columns = new[] { - new TextLoader.Column("Feature1", DataKind.R4, new [] { new TextLoader.Range(1, 2) }), - new TextLoader.Column("Feature2", DataKind.R4, new [] { new TextLoader.Range(3, 4) }), - new TextLoader.Column("Feature3", DataKind.R4, new [] { new TextLoader.Range(5, 6) }), - new TextLoader.Column("Feature4", DataKind.R4, new [] { new TextLoader.Range(7, 9) }), - new TextLoader.Column("Label", DataKind.BL, 0) + new TextLoader.Column("Feature1", DataKind.Single, new [] { new TextLoader.Range(1, 2) }), + new TextLoader.Column("Feature2", DataKind.Single, new [] { new TextLoader.Range(3, 4) }), + new TextLoader.Column("Feature3", DataKind.Single, new [] { new TextLoader.Range(5, 6) }), + new TextLoader.Column("Feature4", DataKind.Single, new [] { new TextLoader.Range(7, 9) }), + new TextLoader.Column("Label", DataKind.Boolean, 0) } }; } diff --git a/test/Microsoft.ML.Tests/TrainerEstimators/MatrixFactorizationTests.cs b/test/Microsoft.ML.Tests/TrainerEstimators/MatrixFactorizationTests.cs index 6d2243de8f..06dcec0a1a 100644 --- a/test/Microsoft.ML.Tests/TrainerEstimators/MatrixFactorizationTests.cs +++ b/test/Microsoft.ML.Tests/TrainerEstimators/MatrixFactorizationTests.cs @@ -151,9 +151,9 @@ private TextLoader.Options GetLoaderArgs(string labelColumnName, string matrixCo HasHeader = true, Columns = new[] { - new TextLoader.Column(labelColumnName, DataKind.R4, new [] { new TextLoader.Range(0) }), - new TextLoader.Column(matrixColumnIndexColumnName, DataKind.U4, new [] { new TextLoader.Range(1) }, new KeyCount(20)), - new TextLoader.Column(matrixRowIndexColumnName, DataKind.U4, new [] { new TextLoader.Range(2) }, new KeyCount(40)), + new TextLoader.Column(labelColumnName, DataKind.Single, new [] { new TextLoader.Range(0) }), + new TextLoader.Column(matrixColumnIndexColumnName, DataKind.UInt32, new [] { new TextLoader.Range(1) }, new KeyCount(20)), + new TextLoader.Column(matrixRowIndexColumnName, DataKind.UInt32, new [] { new TextLoader.Range(2) }, new KeyCount(40)), } }; } diff --git a/test/Microsoft.ML.Tests/TrainerEstimators/PriorRandomTests.cs b/test/Microsoft.ML.Tests/TrainerEstimators/PriorRandomTests.cs index 84a71dadfb..c52c4ac8f9 100644 --- a/test/Microsoft.ML.Tests/TrainerEstimators/PriorRandomTests.cs +++ b/test/Microsoft.ML.Tests/TrainerEstimators/PriorRandomTests.cs @@ -5,7 +5,6 @@ using Microsoft.Data.DataView; using Microsoft.ML.Data; using Microsoft.ML.RunTests; -using Microsoft.ML.Trainers; using Xunit; namespace Microsoft.ML.Tests.TrainerEstimators @@ -20,10 +19,10 @@ private IDataView GetBreastCancerDataviewWithTextColumns() HasHeader = true, Columns = new[] { - new TextLoader.Column("Label", type: null, 0), - new TextLoader.Column("F1", DataKind.Text, 1), - new TextLoader.Column("F2", DataKind.I4, 2), - new TextLoader.Column("Rest", type: null, new [] { new TextLoader.Range(3, 9) }) + new TextLoader.Column("Label", DataKind.Single, 0), + new TextLoader.Column("F1", DataKind.String, 1), + new TextLoader.Column("F2", DataKind.Int32, 2), + new TextLoader.Column("Rest", DataKind.Single, new [] { new TextLoader.Range(3, 9) }) } }).Read(GetDataPath(TestDatasets.breastCancer.trainFilename)); } diff --git a/test/Microsoft.ML.Tests/TrainerEstimators/TrainerEstimators.cs b/test/Microsoft.ML.Tests/TrainerEstimators/TrainerEstimators.cs index 044b1be4f0..a76e736fca 100644 --- a/test/Microsoft.ML.Tests/TrainerEstimators/TrainerEstimators.cs +++ b/test/Microsoft.ML.Tests/TrainerEstimators/TrainerEstimators.cs @@ -34,7 +34,7 @@ public void PCATrainerEstimator() Separator = "\t", Columns = new[] { - new TextLoader.Column(featureColumn, DataKind.R4, new [] { new TextLoader.Range(1, 784) }) + new TextLoader.Column(featureColumn, DataKind.Single, new [] { new TextLoader.Range(1, 784) }) }, AllowSparse = true }); @@ -63,8 +63,8 @@ public void KMeansEstimator() Separator = "\t", Columns = new[] { - new TextLoader.Column(featureColumn, DataKind.R4, new [] { new TextLoader.Range(1, 784) }), - new TextLoader.Column(weights, DataKind.R4, 0) + new TextLoader.Column(featureColumn, DataKind.Single, new [] { new TextLoader.Range(1, 784) }), + new TextLoader.Column(weights, DataKind.Single, 0), }, AllowSparse = true }); @@ -168,8 +168,8 @@ public void TestEstimatorMultiClassNaiveBayesTrainer() HasHeader = true, Columns = new[] { - new TextLoader.Column("Label", DataKind.BL, 0), - new TextLoader.Column("SentimentText", DataKind.Text, 1) + new TextLoader.Column("Label", DataKind.Boolean, 0), + new TextLoader.Column("SentimentText", DataKind.String, 1) } }).Read(GetDataPath(TestDatasets.Sentiment.trainFilename)); @@ -188,9 +188,9 @@ public void TestEstimatorMultiClassNaiveBayesTrainer() Separator = "\t", Columns = new[] { - new TextLoader.Column("Label", DataKind.R4, 0), - new TextLoader.Column("Workclass", DataKind.Text, 1), - new TextLoader.Column("NumericFeatures", DataKind.R4, new [] { new TextLoader.Range(9, 14) }) + new TextLoader.Column("Label", DataKind.Single, 0), + new TextLoader.Column("Workclass", DataKind.String, 1), + new TextLoader.Column("NumericFeatures", DataKind.Single, new [] { new TextLoader.Range(9, 14) }) } }).Read(GetDataPath(TestDatasets.adultRanking.trainFilename)); @@ -211,8 +211,8 @@ private IDataView GetRegressionPipeline() HasHeader = true, Columns = new[] { - new TextLoader.Column("Label", DataKind.R4, 11), - new TextLoader.Column("Features", DataKind.R4, new [] { new TextLoader.Range(0, 10) } ) + new TextLoader.Column("Label", DataKind.Single, 11), + new TextLoader.Column("Features", DataKind.Single, new [] { new TextLoader.Range(0, 10) } ) } }).Read(GetDataPath(TestDatasets.generatedRegressionDatasetmacro.trainFilename)); } @@ -225,8 +225,8 @@ private TextLoader.Options GetIrisLoaderArgs() HasHeader = true, Columns = new[] { - new TextLoader.Column("Features", DataKind.R4, new [] { new TextLoader.Range(0, 3) }), - new TextLoader.Column("Label", DataKind.Text, 4) + new TextLoader.Column("Features", DataKind.Single, new [] { new TextLoader.Range(0, 3) }), + new TextLoader.Column("Label", DataKind.String, 4) } }; } @@ -238,8 +238,8 @@ private TextLoader.Options GetIrisLoaderArgs() Separator = "comma", Columns = new[] { - new TextLoader.Column("Features", DataKind.R4, new [] { new TextLoader.Range(0, 3) }), - new TextLoader.Column("Label", DataKind.Text, 4) + new TextLoader.Column("Features", DataKind.Single, new [] { new TextLoader.Range(0, 3) }), + new TextLoader.Column("Label", DataKind.String, 4) } }).Read(GetDataPath(IrisDataPath)); diff --git a/test/Microsoft.ML.Tests/Transformers/ConcatTests.cs b/test/Microsoft.ML.Tests/Transformers/ConcatTests.cs index 1a3614d25b..ceaefbc8d1 100644 --- a/test/Microsoft.ML.Tests/Transformers/ConcatTests.cs +++ b/test/Microsoft.ML.Tests/Transformers/ConcatTests.cs @@ -6,9 +6,7 @@ using Microsoft.Data.DataView; using Microsoft.ML.Data; using Microsoft.ML.Data.IO; -using Microsoft.ML.Internal.Utilities; using Microsoft.ML.RunTests; -using Microsoft.ML.Transforms; using Xunit; using Xunit.Abstractions; @@ -29,10 +27,10 @@ void TestConcat() var loader = new TextLoader(ML, new TextLoader.Options { Columns = new[]{ - new TextLoader.Column("float1", DataKind.R4, 9), - new TextLoader.Column("float4", DataKind.R4, new[]{new TextLoader.Range(9), new TextLoader.Range(10), new TextLoader.Range(11), new TextLoader.Range(12) }), - new TextLoader.Column("float6", DataKind.R4, new[]{new TextLoader.Range(9), new TextLoader.Range(10), new TextLoader.Range(11), new TextLoader.Range(12, 14) }), - new TextLoader.Column("vfloat", DataKind.R4, new[]{new TextLoader.Range(14, null) { AutoEnd = false, VariableEnd = true } }) + new TextLoader.Column("float1", DataKind.Single, 9), + new TextLoader.Column("float4", DataKind.Single, new[]{new TextLoader.Range(9), new TextLoader.Range(10), new TextLoader.Range(11), new TextLoader.Range(12) }), + new TextLoader.Column("float6", DataKind.Single, new[]{new TextLoader.Range(9), new TextLoader.Range(10), new TextLoader.Range(11), new TextLoader.Range(12, 14) }), + new TextLoader.Column("vfloat", DataKind.Single, new[]{new TextLoader.Range(14, null) { AutoEnd = false, VariableEnd = true } }) }, Separator = "\t", HasHeader = true @@ -87,9 +85,9 @@ public void ConcatWithAliases() var loader = new TextLoader(ML, new TextLoader.Options { Columns = new[]{ - new TextLoader.Column("float1", DataKind.R4, 9), - new TextLoader.Column("float4", DataKind.R4, new[]{new TextLoader.Range(9), new TextLoader.Range(10), new TextLoader.Range(11), new TextLoader.Range(12) }), - new TextLoader.Column("vfloat", DataKind.R4, new[]{new TextLoader.Range(9), new TextLoader.Range(10), new TextLoader.Range(11), new TextLoader.Range(12, null) { AutoEnd = false, VariableEnd = true } }) + new TextLoader.Column("float1", DataKind.Single, 9), + new TextLoader.Column("float4", DataKind.Single, new[]{new TextLoader.Range(9), new TextLoader.Range(10), new TextLoader.Range(11), new TextLoader.Range(12) }), + new TextLoader.Column("vfloat", DataKind.Single, new[]{new TextLoader.Range(9), new TextLoader.Range(10), new TextLoader.Range(11), new TextLoader.Range(12, null) { AutoEnd = false, VariableEnd = true } }) }, Separator = "\t", HasHeader = true diff --git a/test/Microsoft.ML.Tests/Transformers/ConvertTests.cs b/test/Microsoft.ML.Tests/Transformers/ConvertTests.cs index 53be5e8d1e..17715fbe6b 100644 --- a/test/Microsoft.ML.Tests/Transformers/ConvertTests.cs +++ b/test/Microsoft.ML.Tests/Transformers/ConvertTests.cs @@ -75,8 +75,8 @@ public void TestConvertWorkout() var data = new[] { new TestClass() { A = 1, B = new int[2] { 1,4 } }, new TestClass() { A = 2, B = new int[2] { 3,4 } }}; var dataView = ML.Data.ReadFromEnumerable(data); - var pipe = ML.Transforms.Conversion.ConvertType(columns: new[] {new TypeConvertingEstimator.ColumnInfo("ConvA", DataKind.R4, "A"), - new TypeConvertingEstimator.ColumnInfo("ConvB", DataKind.R4, "B")}); + var pipe = ML.Transforms.Conversion.ConvertType(columns: new[] {new TypeConvertingEstimator.ColumnInfo("ConvA", DataKind.Single, "A"), + new TypeConvertingEstimator.ColumnInfo("ConvB", DataKind.Single, "B")}); TestEstimatorCore(pipe, dataView); var allTypesData = new[] @@ -115,18 +115,18 @@ public void TestConvertWorkout() var allTypesDataView = ML.Data.ReadFromEnumerable(allTypesData); var allTypesPipe = ML.Transforms.Conversion.ConvertType(columns: new[] { - new TypeConvertingEstimator.ColumnInfo("ConvA", DataKind.R4, "AA"), - new TypeConvertingEstimator.ColumnInfo("ConvB", DataKind.R4, "AB"), - new TypeConvertingEstimator.ColumnInfo("ConvC", DataKind.R4, "AC"), - new TypeConvertingEstimator.ColumnInfo("ConvD", DataKind.R4, "AD"), - new TypeConvertingEstimator.ColumnInfo("ConvE", DataKind.R4, "AE"), - new TypeConvertingEstimator.ColumnInfo("ConvF", DataKind.R4, "AF"), - new TypeConvertingEstimator.ColumnInfo("ConvG", DataKind.R4, "AG"), - new TypeConvertingEstimator.ColumnInfo("ConvH", DataKind.R4, "AH"), - new TypeConvertingEstimator.ColumnInfo("ConvK", DataKind.R4, "AK"), - new TypeConvertingEstimator.ColumnInfo("ConvL", DataKind.R4, "AL"), - new TypeConvertingEstimator.ColumnInfo("ConvM", DataKind.R4, "AM"), - new TypeConvertingEstimator.ColumnInfo("ConvN", DataKind.R4, "AN")} + new TypeConvertingEstimator.ColumnInfo("ConvA", DataKind.Single, "AA"), + new TypeConvertingEstimator.ColumnInfo("ConvB", DataKind.Single, "AB"), + new TypeConvertingEstimator.ColumnInfo("ConvC", DataKind.Single, "AC"), + new TypeConvertingEstimator.ColumnInfo("ConvD", DataKind.Single, "AD"), + new TypeConvertingEstimator.ColumnInfo("ConvE", DataKind.Single, "AE"), + new TypeConvertingEstimator.ColumnInfo("ConvF", DataKind.Single, "AF"), + new TypeConvertingEstimator.ColumnInfo("ConvG", DataKind.Single, "AG"), + new TypeConvertingEstimator.ColumnInfo("ConvH", DataKind.Single, "AH"), + new TypeConvertingEstimator.ColumnInfo("ConvK", DataKind.Single, "AK"), + new TypeConvertingEstimator.ColumnInfo("ConvL", DataKind.Single, "AL"), + new TypeConvertingEstimator.ColumnInfo("ConvM", DataKind.Single, "AM"), + new TypeConvertingEstimator.ColumnInfo("ConvN", DataKind.Single, "AN")} ); TestEstimatorCore(allTypesPipe, allTypesDataView); @@ -207,8 +207,8 @@ public void TestMetadata() new OneHotEncodingEstimator.ColumnInfo("CatA", "A", OneHotEncodingTransformer.OutputKind.Ind), new OneHotEncodingEstimator.ColumnInfo("CatB", "B", OneHotEncodingTransformer.OutputKind.Key) }).Append(ML.Transforms.Conversion.ConvertType(new[] { - new TypeConvertingEstimator.ColumnInfo("ConvA", DataKind.R8, "CatA"), - new TypeConvertingEstimator.ColumnInfo("ConvB", DataKind.U2, "CatB") + new TypeConvertingEstimator.ColumnInfo("ConvA", DataKind.Double, "CatA"), + new TypeConvertingEstimator.ColumnInfo("ConvB", DataKind.UInt16, "CatB") })); var dataView = ML.Data.ReadFromEnumerable(data); dataView = pipe.Fit(dataView).Transform(dataView); @@ -243,7 +243,7 @@ public void TypeConvertKeyBackCompatTest() { // Model generated using the following command before the change removing Min and Count from KeyType. // ML.Transforms.Conversion.ConvertType(new[] { new TypeConvertingEstimator.ColumnInfo("key", "convertedKey", - // DataKind.U8, new KeyCount(4)) }).Fit(dataView); + // DataKind.UInt64, new KeyCount(4)) }).Fit(dataView); var dataArray = new[] { new SimpleSchemaUIntColumn() { key = 0 }, @@ -266,7 +266,7 @@ public void TypeConvertKeyBackCompatTest() var outDataOld = modelOld.Transform(dataView); var modelNew = ML.Transforms.Conversion.ConvertType(new[] { new TypeConvertingEstimator.ColumnInfo("convertedKey", - DataKind.U8, "key", new KeyCount(4)) }).Fit(dataView); + DataKind.UInt64, "key", new KeyCount(4)) }).Fit(dataView); var outDataNew = modelNew.Transform(dataView); // Check that old and new model produce the same result. diff --git a/test/Microsoft.ML.Tests/Transformers/CustomMappingTests.cs b/test/Microsoft.ML.Tests/Transformers/CustomMappingTests.cs index be13496d59..77137f94a0 100644 --- a/test/Microsoft.ML.Tests/Transformers/CustomMappingTests.cs +++ b/test/Microsoft.ML.Tests/Transformers/CustomMappingTests.cs @@ -50,8 +50,8 @@ public void TestCustomTransformer() string dataPath = GetDataPath("adult.tiny.with-schema.txt"); var source = new MultiFileSource(dataPath); var loader = ML.Data.CreateTextLoader(new[] { - new TextLoader.Column("Float1", DataKind.R4, 9), - new TextLoader.Column("Float4", DataKind.R4, new[]{new TextLoader.Range(9), new TextLoader.Range(10), new TextLoader.Range(11), new TextLoader.Range(12) }) + new TextLoader.Column("Float1", DataKind.Single, 9), + new TextLoader.Column("Float4", DataKind.Single, new[]{new TextLoader.Range(9), new TextLoader.Range(10), new TextLoader.Range(11), new TextLoader.Range(12) }) }, hasHeader: true); var data = loader.Read(source); @@ -90,9 +90,9 @@ public void TestSchemaPropagation() string dataPath = GetDataPath("adult.test"); var source = new MultiFileSource(dataPath); var loader = ML.Data.CreateTextLoader(new[] { - new TextLoader.Column("Float1", DataKind.R4, 0), - new TextLoader.Column("Float4", DataKind.R4, new[]{new TextLoader.Range(0), new TextLoader.Range(2), new TextLoader.Range(4), new TextLoader.Range(10) }), - new TextLoader.Column("Text1", DataKind.Text, 0) + new TextLoader.Column("Float1", DataKind.Single, 0), + new TextLoader.Column("Float4", DataKind.Single, new[]{new TextLoader.Range(0), new TextLoader.Range(2), new TextLoader.Range(4), new TextLoader.Range(10) }), + new TextLoader.Column("Text1", DataKind.String, 0) }, separatorChar: ',', hasHeader: true); var data = loader.Read(source); diff --git a/test/Microsoft.ML.Tests/Transformers/KeyToValueTests.cs b/test/Microsoft.ML.Tests/Transformers/KeyToValueTests.cs index 55ccb06de1..c04f363d07 100644 --- a/test/Microsoft.ML.Tests/Transformers/KeyToValueTests.cs +++ b/test/Microsoft.ML.Tests/Transformers/KeyToValueTests.cs @@ -30,15 +30,9 @@ public void KeyToValueWorkout() { Columns = new[] { - new TextLoader.Column("ScalarString", DataKind.TX, 1), - new TextLoader.Column("VectorString", DataKind.TX, new[] {new TextLoader.Range(1, 4) }), - new TextLoader.Column - { - Name="BareKey", - Source = new[] { new TextLoader.Range(0) }, - Type = DataKind.U4, - KeyCount = new KeyCount(6), - } + new TextLoader.Column("ScalarString", DataKind.String, 1), + new TextLoader.Column("VectorString", DataKind.String, new[] {new TextLoader.Range(1, 4) }), + new TextLoader.Column("BareKey", DataKind.UInt32, new[] { new TextLoader.Range(0) }, new KeyCount(6)) } }); diff --git a/test/Microsoft.ML.Tests/Transformers/NormalizerTests.cs b/test/Microsoft.ML.Tests/Transformers/NormalizerTests.cs index 8d5fa5bd88..cd84e9a058 100644 --- a/test/Microsoft.ML.Tests/Transformers/NormalizerTests.cs +++ b/test/Microsoft.ML.Tests/Transformers/NormalizerTests.cs @@ -35,12 +35,12 @@ public void NormalizerWorkout() var loader = new TextLoader(Env, new TextLoader.Options { Columns = new[] { - new TextLoader.Column("float1", DataKind.R4, 1), - new TextLoader.Column("float4", DataKind.R4, new[]{new TextLoader.Range(1, 4) }), - new TextLoader.Column("double1", DataKind.R8, 1), - new TextLoader.Column("double4", DataKind.R8, new[]{new TextLoader.Range(1, 4) }), - new TextLoader.Column("int1", DataKind.I4, 0), - new TextLoader.Column("float0", DataKind.R4, new[]{ new TextLoader.Range { Min = 1, VariableEnd = true } }), + new TextLoader.Column("float1", DataKind.Single, 1), + new TextLoader.Column("float4", DataKind.Single, new[]{new TextLoader.Range(1, 4) }), + new TextLoader.Column("double1", DataKind.Double, 1), + new TextLoader.Column("double4", DataKind.Double, new[]{new TextLoader.Range(1, 4) }), + new TextLoader.Column("int1", DataKind.Int32, 0), + new TextLoader.Column("float0", DataKind.Single, new[]{ new TextLoader.Range { Min = 1, VariableEnd = true } }), }, HasHeader = true }, new MultiFileSource(dataPath)); @@ -100,12 +100,12 @@ public void NormalizerParameters() var loader = new TextLoader(Env, new TextLoader.Options { Columns = new[] { - new TextLoader.Column("float1", DataKind.R4, 1), - new TextLoader.Column("float4", DataKind.R4, new[]{new TextLoader.Range(1, 4) }), - new TextLoader.Column("double1", DataKind.R8, 1), - new TextLoader.Column("double4", DataKind.R8, new[]{new TextLoader.Range(1, 4) }), - new TextLoader.Column("int1", DataKind.I4, 0), - new TextLoader.Column("float0", DataKind.R4, new[]{ new TextLoader.Range { Min = 1, VariableEnd = true } }) + new TextLoader.Column("float1", DataKind.Single, 1), + new TextLoader.Column("float4", DataKind.Single, new[]{new TextLoader.Range(1, 4) }), + new TextLoader.Column("double1", DataKind.Double, 1), + new TextLoader.Column("double4", DataKind.Double, new[]{new TextLoader.Range(1, 4) }), + new TextLoader.Column("int1", DataKind.Int32, 0), + new TextLoader.Column("float0", DataKind.Single, new[]{ new TextLoader.Range { Min = 1, VariableEnd = true } }) }, HasHeader = true }, new MultiFileSource(dataPath)); @@ -217,8 +217,8 @@ public void SimpleConstructorsAndExtensions() var loader = new TextLoader(Env, new TextLoader.Options { Columns = new[] { - new TextLoader.Column("Label", DataKind.R4, 0), - new TextLoader.Column("float4", DataKind.R4, new[]{new TextLoader.Range(1, 4) }), + new TextLoader.Column("Label", DataKind.Single, 0), + new TextLoader.Column("float4", DataKind.Single, new[]{new TextLoader.Range(1, 4) }), } }); diff --git a/test/Microsoft.ML.Tests/Transformers/TextFeaturizerTests.cs b/test/Microsoft.ML.Tests/Transformers/TextFeaturizerTests.cs index aadf328c8b..2ddb8b3895 100644 --- a/test/Microsoft.ML.Tests/Transformers/TextFeaturizerTests.cs +++ b/test/Microsoft.ML.Tests/Transformers/TextFeaturizerTests.cs @@ -168,7 +168,7 @@ public void StopWordsRemoverFromFactory() { Columns = new[] { - new TextLoader.Column("Text", DataKind.TX, 1) + new TextLoader.Column("Text", DataKind.String, 1) } }, new MultiFileSource(sentimentDataPath)); diff --git a/test/Microsoft.ML.Tests/Transformers/WordEmbeddingsTests.cs b/test/Microsoft.ML.Tests/Transformers/WordEmbeddingsTests.cs index 8f877eba5d..0f6b68deb7 100644 --- a/test/Microsoft.ML.Tests/Transformers/WordEmbeddingsTests.cs +++ b/test/Microsoft.ML.Tests/Transformers/WordEmbeddingsTests.cs @@ -5,7 +5,6 @@ using System.IO; using Microsoft.ML.Data; using Microsoft.ML.RunTests; -using Microsoft.ML.Transforms; using Microsoft.ML.Transforms.Text; using Xunit; using Xunit.Abstractions; @@ -30,8 +29,8 @@ public void TestWordEmbeddings() HasHeader = true, Columns = new[] { - new TextLoader.Column("Label", DataKind.BL, 0), - new TextLoader.Column("SentimentText", DataKind.Text, 1) + new TextLoader.Column("Label", DataKind.Boolean, 0), + new TextLoader.Column("SentimentText", DataKind.String, 1) } }).Read(GetDataPath(dataPath)); @@ -65,8 +64,8 @@ public void TestCustomWordEmbeddings() HasHeader = true, Columns = new[] { - new TextLoader.Column("Label", DataKind.BL, 0), - new TextLoader.Column("SentimentText", DataKind.Text, 1) + new TextLoader.Column("Label", DataKind.Boolean, 0), + new TextLoader.Column("SentimentText", DataKind.String, 1) } }).Read(GetDataPath(dataPath)); From a16eb309820af6205d7a5e804ddbd5d995c879d2 Mon Sep 17 00:00:00 2001 From: Shahab Moradi Date: Mon, 25 Feb 2019 16:45:55 -0500 Subject: [PATCH 16/24] Added samples & docs for BinaryClassification.StochasticGradientDescent (#2688) * Added samples & docs for BinaryClassification.StochasticGradientDescent, plus a bunch of typo fixing. * Addressed PR comments. * Mentioned Hogwild * Updates to exampleWeightColumnName. * Fixed trailing whitespaces. --- .../AveragedPerceptron.cs | 2 +- .../AveragedPerceptronWithOptions.cs | 2 +- .../StochasticGradientDescent.cs | 47 ++++++++++++++ .../StochasticGradientDescentWithOptions.cs | 59 +++++++++++++++++ .../SymbolicStochasticGradientDescent.cs | 2 +- ...licStochasticGradientDescentWithOptions.cs | 2 +- .../EntryPoints/InputBase.cs | 2 +- src/Microsoft.ML.SamplesUtils/ConsoleUtils.cs | 12 ++++ .../Standard/Online/AveragedLinear.cs | 2 +- .../Standard/Online/AveragedPerceptron.cs | 2 +- .../Standard/Online/OnlineLinear.cs | 4 +- .../Standard/SdcaBinary.cs | 55 +++++++++++++++- .../StandardLearnersCatalog.cs | 64 +++++++++++-------- src/Microsoft.ML.StaticPipe/LbfgsStatic.cs | 4 +- src/Microsoft.ML.StaticPipe/SgdStatic.cs | 8 +-- .../TreeTrainersStatic.cs | 4 +- 16 files changed, 226 insertions(+), 45 deletions(-) create mode 100644 docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/StochasticGradientDescent.cs create mode 100644 docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/StochasticGradientDescentWithOptions.cs diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/AveragedPerceptron.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/AveragedPerceptron.cs index 767d398dc6..8da2982ecb 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/AveragedPerceptron.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/AveragedPerceptron.cs @@ -5,7 +5,7 @@ namespace Microsoft.ML.Samples.Dynamic.Trainers.BinaryClassification public static class AveragedPerceptron { // In this examples we will use the adult income dataset. The goal is to predict - // if a person's income is above $50K or not, based on different pieces of information about that person. + // if a person's income is above $50K or not, based on demographic information about that person. // For more details about this dataset, please see https://archive.ics.uci.edu/ml/datasets/adult. public static void Example() { diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/AveragedPerceptronWithOptions.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/AveragedPerceptronWithOptions.cs index 830b5981cc..1c58ee48aa 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/AveragedPerceptronWithOptions.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/AveragedPerceptronWithOptions.cs @@ -6,7 +6,7 @@ namespace Microsoft.ML.Samples.Dynamic.Trainers.BinaryClassification public static class AveragedPerceptronWithOptions { // In this examples we will use the adult income dataset. The goal is to predict - // if a person's income is above $50K or not, based on different pieces of information about that person. + // if a person's income is above $50K or not, based on demographic information about that person. // For more details about this dataset, please see https://archive.ics.uci.edu/ml/datasets/adult. public static void Example() { diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/StochasticGradientDescent.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/StochasticGradientDescent.cs new file mode 100644 index 0000000000..bbebc47d9a --- /dev/null +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/StochasticGradientDescent.cs @@ -0,0 +1,47 @@ +using Microsoft.ML; + +namespace Microsoft.ML.Samples.Dynamic.Trainers.BinaryClassification +{ + public static class StochasticGradientDescent + { + // In this examples we will use the adult income dataset. The goal is to predict + // if a person's income is above $50K or not, based on demographic information about that person. + // For more details about this dataset, please see https://archive.ics.uci.edu/ml/datasets/adult. + public static void Example() + { + // Create a new context for ML.NET operations. It can be used for exception tracking and logging, + // as a catalog of available operations and as the source of randomness. + // Setting the seed to a fixed number in this example to make outputs deterministic. + var mlContext = new MLContext(seed: 0); + + // Download and featurize the dataset. + var data = SamplesUtils.DatasetUtils.LoadFeaturizedAdultDataset(mlContext); + + // Leave out 10% of data for testing. + var trainTestData = mlContext.BinaryClassification.TrainTestSplit(data, testFraction: 0.1); + + // Create data training pipeline. + var pipeline = mlContext.BinaryClassification.Trainers.StochasticGradientDescent(); + + // Fit this pipeline to the training data. + var model = pipeline.Fit(trainTestData.TrainSet); + + // Evaluate how the model is doing on the test data. + var dataWithPredictions = model.Transform(trainTestData.TestSet); + var metrics = mlContext.BinaryClassification.Evaluate(dataWithPredictions); + SamplesUtils.ConsoleUtils.PrintMetrics(metrics); + + // Expected output: + // Accuracy: 0.85 + // AUC: 0.90 + // F1 Score: 0.67 + // Negative Precision: 0.90 + // Negative Recall: 0.91 + // Positive Precision: 0.68 + // Positive Recall: 0.65 + // LogLoss: 0.48 + // LogLossReduction: 38.31 + // Entropy: 0.78 + } + } +} \ No newline at end of file diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/StochasticGradientDescentWithOptions.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/StochasticGradientDescentWithOptions.cs new file mode 100644 index 0000000000..d28e0a19d1 --- /dev/null +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/StochasticGradientDescentWithOptions.cs @@ -0,0 +1,59 @@ +using Microsoft.ML; +using Microsoft.ML.Trainers; + +namespace Microsoft.ML.Samples.Dynamic.Trainers.BinaryClassification +{ + public static class StochasticGradientDescentWithOptions + { + // In this examples we will use the adult income dataset. The goal is to predict + // if a person's income is above $50K or not, based on demographic information about that person. + // For more details about this dataset, please see https://archive.ics.uci.edu/ml/datasets/adult. + public static void Example() + { + // Create a new context for ML.NET operations. It can be used for exception tracking and logging, + // as a catalog of available operations and as the source of randomness. + // Setting the seed to a fixed number in this example to make outputs deterministic. + var mlContext = new MLContext(seed: 0); + + // Download and featurize the dataset. + var data = SamplesUtils.DatasetUtils.LoadFeaturizedAdultDataset(mlContext); + + // Leave out 10% of data for testing. + var trainTestData = mlContext.BinaryClassification.TrainTestSplit(data, testFraction: 0.1); + + // Define the trainer options. + var options = new SgdBinaryTrainer.Options() + { + // Make the convergence tolerance tighter. + ConvergenceTolerance = 5e-5, + // Increase the maximum number of passes over training data. + MaxIterations = 30, + // Give the instances of the positive class slightly more weight. + PositiveInstanceWeight = 1.2f, + }; + + // Create data training pipeline. + var pipeline = mlContext.BinaryClassification.Trainers.StochasticGradientDescent(options); + + // Fit this pipeline to the training data. + var model = pipeline.Fit(trainTestData.TrainSet); + + // Evaluate how the model is doing on the test data. + var dataWithPredictions = model.Transform(trainTestData.TestSet); + var metrics = mlContext.BinaryClassification.Evaluate(dataWithPredictions); + SamplesUtils.ConsoleUtils.PrintMetrics(metrics); + + // Expected output: + // Accuracy: 0.85 + // AUC: 0.90 + // F1 Score: 0.67 + // Negative Precision: 0.91 + // Negative Recall: 0.89 + // Positive Precision: 0.65 + // Positive Recall: 0.70 + // LogLoss: 0.48 + // LogLossReduction: 37.52 + // Entropy: 0.78 + } + } +} \ No newline at end of file diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/SymbolicStochasticGradientDescent.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/SymbolicStochasticGradientDescent.cs index 49b31342e0..c0687d6ee7 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/SymbolicStochasticGradientDescent.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/SymbolicStochasticGradientDescent.cs @@ -4,7 +4,7 @@ public static class SymbolicStochasticGradientDescent { // This example requires installation of additional nuget package Microsoft.ML.HalLearners. // In this example we will use the adult income dataset. The goal is to predict - // if a person's income is above $50K or not, based on different pieces of information about that person. + // if a person's income is above $50K or not, based on demographic information about that person. // For more details about this dataset, please see https://archive.ics.uci.edu/ml/datasets/adult public static void Example() { diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/SymbolicStochasticGradientDescentWithOptions.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/SymbolicStochasticGradientDescentWithOptions.cs index d05d64454c..9dd4f50c87 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/SymbolicStochasticGradientDescentWithOptions.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/SymbolicStochasticGradientDescentWithOptions.cs @@ -4,7 +4,7 @@ public static class SymbolicStochasticGradientDescentWithOptions { // This example requires installation of additional nuget package Microsoft.ML.HalLearners. // In this example we will use the adult income dataset. The goal is to predict - // if a person's income is above $50K or not, based on different pieces of information about that person. + // if a person's income is above $50K or not, based on demographic information about that person. // For more details about this dataset, please see https://archive.ics.uci.edu/ml/datasets/adult public static void Example() { diff --git a/src/Microsoft.ML.Data/EntryPoints/InputBase.cs b/src/Microsoft.ML.Data/EntryPoints/InputBase.cs index 3e991829f4..61f9246c0f 100644 --- a/src/Microsoft.ML.Data/EntryPoints/InputBase.cs +++ b/src/Microsoft.ML.Data/EntryPoints/InputBase.cs @@ -95,7 +95,7 @@ public abstract class LearnerInputBaseWithLabel : LearnerInputBase public abstract class LearnerInputBaseWithWeight : LearnerInputBaseWithLabel { /// - /// Column to use for example weight. + /// The name of the example weight column. /// [Argument(ArgumentType.AtMostOnce, HelpText = "Column to use for example weight", ShortName = "weight", SortOrder = 4, Visibility = ArgumentAttribute.VisibilityType.EntryPointsOnly)] public string WeightColumn = null; diff --git a/src/Microsoft.ML.SamplesUtils/ConsoleUtils.cs b/src/Microsoft.ML.SamplesUtils/ConsoleUtils.cs index 93de658b1e..16f72e3392 100644 --- a/src/Microsoft.ML.SamplesUtils/ConsoleUtils.cs +++ b/src/Microsoft.ML.SamplesUtils/ConsoleUtils.cs @@ -23,6 +23,18 @@ public static void PrintMetrics(BinaryClassificationMetrics metrics) Console.WriteLine($"Positive Recall: {metrics.PositiveRecall:F2}"); } + /// + /// Pretty-print CalibratedBinaryClassificationMetrics objects. + /// + /// object. + public static void PrintMetrics(CalibratedBinaryClassificationMetrics metrics) + { + PrintMetrics(metrics as BinaryClassificationMetrics); + Console.WriteLine($"LogLoss: {metrics.LogLoss:F2}"); + Console.WriteLine($"LogLossReduction: {metrics.LogLossReduction:F2}"); + Console.WriteLine($"Entropy: {metrics.Entropy:F2}"); + } + /// /// Pretty-print RegressionMetrics objects. /// diff --git a/src/Microsoft.ML.StandardLearners/Standard/Online/AveragedLinear.cs b/src/Microsoft.ML.StandardLearners/Standard/Online/AveragedLinear.cs index 688fd872ab..37abdfd88e 100644 --- a/src/Microsoft.ML.StandardLearners/Standard/Online/AveragedLinear.cs +++ b/src/Microsoft.ML.StandardLearners/Standard/Online/AveragedLinear.cs @@ -60,7 +60,7 @@ public abstract class AveragedLinearOptions : OnlineLinearOptions public bool DoLazyUpdates = true; /// - /// L2 weight for regularization. + /// The L2 weight for regularization. /// [Argument(ArgumentType.AtMostOnce, HelpText = "L2 Regularization Weight", ShortName = "reg", SortOrder = 50)] [TGUI(Label = "L2 Regularization Weight")] diff --git a/src/Microsoft.ML.StandardLearners/Standard/Online/AveragedPerceptron.cs b/src/Microsoft.ML.StandardLearners/Standard/Online/AveragedPerceptron.cs index 5349d24fd1..5d53083992 100644 --- a/src/Microsoft.ML.StandardLearners/Standard/Online/AveragedPerceptron.cs +++ b/src/Microsoft.ML.StandardLearners/Standard/Online/AveragedPerceptron.cs @@ -54,7 +54,7 @@ public sealed class AveragedPerceptronTrainer : AveragedLinearTrainer - /// Options for the averaged perceptron trainer. + /// Options for the . /// public sealed class Options : AveragedLinearOptions { diff --git a/src/Microsoft.ML.StandardLearners/Standard/Online/OnlineLinear.cs b/src/Microsoft.ML.StandardLearners/Standard/Online/OnlineLinear.cs index 6347de391d..8848281e6f 100644 --- a/src/Microsoft.ML.StandardLearners/Standard/Online/OnlineLinear.cs +++ b/src/Microsoft.ML.StandardLearners/Standard/Online/OnlineLinear.cs @@ -24,7 +24,7 @@ public abstract class OnlineLinearOptions : LearnerInputBaseWithLabel /// /// Number of passes through the training dataset. /// - [Argument(ArgumentType.AtMostOnce, HelpText = "Number of iterations", ShortName = "iter, numIterations", SortOrder = 50)] + [Argument(ArgumentType.AtMostOnce, HelpText = "Number of iterations", ShortName = "iter,numIterations", SortOrder = 50)] [TGUI(Label = "Number of Iterations", Description = "Number of training iterations through data", SuggestedSweeps = "1,10,100")] [TlcModule.SweepableLongParamAttribute("NumIterations", 1, 100, stepSize: 10, isLogScale: true)] public int NumberOfIterations = OnlineDefault.NumIterations; @@ -43,7 +43,7 @@ public abstract class OnlineLinearOptions : LearnerInputBaseWithLabel /// This property is only used if the provided value is positive and is not specified. /// The weights and bias will be randomly selected from InitialWeights * [-0.5,0.5] interval with uniform distribution. /// - [Argument(ArgumentType.AtMostOnce, HelpText = "Init weights diameter", ShortName = "initwts, initWtsDiameter", SortOrder = 140)] + [Argument(ArgumentType.AtMostOnce, HelpText = "Init weights diameter", ShortName = "initwts,initWtsDiameter", SortOrder = 140)] [TGUI(Label = "Initial Weights Scale", SuggestedSweeps = "0,0.1,0.5,1")] [TlcModule.SweepableFloatParamAttribute("InitWtsDiameter", 0.0f, 1.0f, numSteps: 5)] public float InitialWeightsDiameter = 0; diff --git a/src/Microsoft.ML.StandardLearners/Standard/SdcaBinary.cs b/src/Microsoft.ML.StandardLearners/Standard/SdcaBinary.cs index 30f205eb93..58057b377a 100644 --- a/src/Microsoft.ML.StandardLearners/Standard/SdcaBinary.cs +++ b/src/Microsoft.ML.StandardLearners/Standard/SdcaBinary.cs @@ -1723,36 +1723,77 @@ public abstract class SgdBinaryTrainerBase : { public class OptionsBase : LearnerInputBaseWithWeight { + /// + /// The L2 weight for regularization. + /// [Argument(ArgumentType.AtMostOnce, HelpText = "L2 Regularization constant", ShortName = "l2", SortOrder = 50)] [TGUI(Label = "L2 Regularization Constant", SuggestedSweeps = "1e-7,5e-7,1e-6,5e-6,1e-5")] [TlcModule.SweepableDiscreteParam("L2Const", new object[] { 1e-7f, 5e-7f, 1e-6f, 5e-6f, 1e-5f })] public float L2Weight = Defaults.L2Weight; + /// + /// The degree of lock-free parallelism used by SGD. + /// + /// + /// Defaults to automatic depending on data sparseness. Determinism is not guaranteed. + /// [Argument(ArgumentType.AtMostOnce, HelpText = "Degree of lock-free parallelism. Defaults to automatic depending on data sparseness. Determinism not guaranteed.", ShortName = "nt,t,threads", SortOrder = 50)] [TGUI(Label = "Number of threads", SuggestedSweeps = "1,2,4")] public int? NumThreads; + /// + /// The convergence tolerance. If the exponential moving average of loss reductions falls below this tolerance, + /// the algorithm is deemed to have converged and will stop. + /// [Argument(ArgumentType.AtMostOnce, HelpText = "Exponential moving averaged improvement tolerance for convergence", ShortName = "tol")] [TGUI(SuggestedSweeps = "1e-2,1e-3,1e-4,1e-5")] [TlcModule.SweepableDiscreteParam("ConvergenceTolerance", new object[] { 1e-2f, 1e-3f, 1e-4f, 1e-5f })] public double ConvergenceTolerance = 1e-4; + /// + /// The maximum number of passes through the training dataset. + /// + /// + /// Set to 1 to simulate online learning. + /// [Argument(ArgumentType.AtMostOnce, HelpText = "Maximum number of iterations; set to 1 to simulate online learning.", ShortName = "iter")] [TGUI(Label = "Max number of iterations", SuggestedSweeps = "1,5,10,20")] [TlcModule.SweepableDiscreteParam("MaxIterations", new object[] { 1, 5, 10, 20 })] public int MaxIterations = Defaults.MaxIterations; + /// + /// The initial learning rate used by SGD. + /// [Argument(ArgumentType.AtMostOnce, HelpText = "Initial learning rate (only used by SGD)", ShortName = "ilr,lr")] [TGUI(Label = "Initial Learning Rate (for SGD)")] public double InitLearningRate = Defaults.InitLearningRate; + /// + /// Determines whether to shuffle data for each training iteration. + /// + /// + /// to shuffle data for each training iteration; otherwise, . + /// Default is . + /// [Argument(ArgumentType.AtMostOnce, HelpText = "Shuffle data every epoch?", ShortName = "shuf")] [TlcModule.SweepableDiscreteParam("Shuffle", null, isBool: true)] public bool Shuffle = true; + /// + /// The weight to be applied to the positive class. This is useful for training with imbalanced data. + /// + /// + /// Default value is 1, which means no extra weight. + /// [Argument(ArgumentType.AtMostOnce, HelpText = "Apply weight to the positive class, for imbalanced data", ShortName = "piw")] public float PositiveInstanceWeight = 1; + /// + /// Determines the frequency of checking for convergence in terms of number of iterations. + /// + /// + /// Default equals ." + /// [Argument(ArgumentType.AtMostOnce, HelpText = "Convergence check frequency (in terms of number of iterations). Default equals number of threads", ShortName = "checkFreq")] public int? CheckFrequency; @@ -1802,7 +1843,7 @@ internal static class Defaults /// The environment to use. /// The name of the feature column. /// The name of the label column. - /// The name for the example weight column. + /// The name of the example weight column. /// The maximum number of iterations; set to 1 to simulate online learning. /// The initial learning rate used by SGD. /// The L2 regularizer constant. @@ -2077,13 +2118,21 @@ private protected override void CheckLabel(RoleMappedData examples, out int weig } /// - /// Train logistic regression using a parallel stochastic gradient method. + /// The for training logistic regression using a parallel stochastic gradient method. + /// The trained model is calibrated and can produce probability by feeding the output value of the + /// linear function to a . /// + /// + /// The Stochastic Gradient Descent (SGD) is one of the popular stochastic optimization procedures that can be integrated + /// into several machine learning tasks to achieve state-of-the-art performance. This trainer implements the Hogwild SGD for binary classification + /// that supports multi-threading without any locking. If the associated optimization problem is sparse, Hogwild SGD achieves a nearly optimal + /// rate of convergence. For more details about Hogwild SGD, please refer to http://arxiv.org/pdf/1106.5730v2.pdf. + /// public sealed class SgdBinaryTrainer : SgdBinaryTrainerBase> { /// - /// Options available to training logistic regression using the implemented stochastic gradient method. + /// Options for the . /// public sealed class Options : OptionsBase { diff --git a/src/Microsoft.ML.StandardLearners/StandardLearnersCatalog.cs b/src/Microsoft.ML.StandardLearners/StandardLearnersCatalog.cs index 3291aa4d83..89e7eda99f 100644 --- a/src/Microsoft.ML.StandardLearners/StandardLearnersCatalog.cs +++ b/src/Microsoft.ML.StandardLearners/StandardLearnersCatalog.cs @@ -19,15 +19,22 @@ namespace Microsoft.ML public static class StandardLearnersCatalog { /// - /// Predict a target using logistic regression trained with the trainer. + /// Predict a target using a linear classification model trained with . /// - /// The binary classificaiton catalog trainer object. - /// The name of the label column. - /// The name of the feature column. + /// The binary classification catalog trainer object. + /// The name of the label column, or dependent variable. + /// The features, or independent variables. /// The name of the example weight column (optional). - /// The maximum number of iterations; set to 1 to simulate online learning. - /// The initial learning rate used by SGD. - /// The L2 regularization constant. + /// The maximum number of passes through the training dataset; set to 1 to simulate online learning. + /// The initial learning rate used by SGD. + /// The L2 weight for regularization. + /// + /// + /// + /// + /// public static SgdBinaryTrainer StochasticGradientDescent(this BinaryClassificationCatalog.BinaryClassificationTrainers catalog, string labelColumnName = DefaultColumnNames.Label, string featureColumnName = DefaultColumnNames.Features, @@ -43,10 +50,17 @@ public static SgdBinaryTrainer StochasticGradientDescent(this BinaryClassificati } /// - /// Predict a target using logistic regression trained with the trainer. + /// Predict a target using a linear classification model trained with and advanced options. /// - /// The binary classificaiton catalog trainer object. - /// Advanced arguments to the algorithm. + /// The binary classification catalog trainer object. + /// Trainer options. + /// + /// + /// + /// + /// public static SgdBinaryTrainer StochasticGradientDescent(this BinaryClassificationCatalog.BinaryClassificationTrainers catalog, SgdBinaryTrainer.Options options) { @@ -58,16 +72,16 @@ public static SgdBinaryTrainer StochasticGradientDescent(this BinaryClassificati } /// - /// Predict a target using a linear classification model trained with the trainer. + /// Predict a target using a linear classification model trained with . /// - /// The binary classificaiton catalog trainer object. - /// The name of the label column. - /// The name of the feature column. + /// The binary classification catalog trainer object. + /// The name of the label column, or dependent variable. + /// The features, or independent variables. /// The name of the example weight column (optional). /// The loss function minimized in the training process. Using, for example, leads to a support vector machine trainer. - /// The maximum number of iterations; set to 1 to simulate online learning. - /// The initial learning rate used by SGD. - /// The L2 regularization constant. + /// The maximum number of passes through the training dataset; set to 1 to simulate online learning. + /// The initial learning rate used by SGD. + /// The L2 weight for regularization. public static SgdNonCalibratedBinaryTrainer StochasticGradientDescentNonCalibrated(this BinaryClassificationCatalog.BinaryClassificationTrainers catalog, string labelColumnName = DefaultColumnNames.Label, string featureColumnName = DefaultColumnNames.Features, @@ -84,10 +98,10 @@ public static SgdNonCalibratedBinaryTrainer StochasticGradientDescentNonCalibrat } /// - /// Predict a target using a linear classification model trained with the trainer. + /// Predict a target using a linear classification model trained with and advanced options. /// - /// The binary classificaiton catalog trainer object. - /// Advanced arguments to the algorithm. + /// The binary classification catalog trainer object. + /// Trainer options. public static SgdNonCalibratedBinaryTrainer StochasticGradientDescentNonCalibrated(this BinaryClassificationCatalog.BinaryClassificationTrainers catalog, SgdNonCalibratedBinaryTrainer.Options options) { @@ -141,7 +155,7 @@ public static SdcaRegressionTrainer StochasticDualCoordinateAscent(this Regressi /// /// Predict a target using a logistic regression model trained with the SDCA trainer. - /// The trained model can produce probablity by feeding the output value of the linear + /// The trained model can produce probability by feeding the output value of the linear /// function to a . /// /// The binary classification catalog trainer object. @@ -173,7 +187,7 @@ public static SdcaBinaryTrainer StochasticDualCoordinateAscent( /// /// Predict a target using a logistic regression model trained with the SDCA trainer. - /// The trained model can produce probablity via feeding output value of the linear + /// The trained model can produce probability via feeding output value of the linear /// function to a . Compared with , /// this function allows more advanced settings by accepting . /// @@ -290,7 +304,7 @@ public static SdcaMultiClassTrainer StochasticDualCoordinateAscent(this Multicla /// to decrease the as iterations progress; otherwise, . /// Default is . /// - /// L2 weight for regularization. + /// The L2 weight for regularization. /// Number of passes through the training dataset. /// /// @@ -396,7 +410,7 @@ public static OnlineGradientDescentTrainer OnlineGradientDescent(this Regression /// /// Predict a target using a linear binary classification model trained with the trainer. /// - /// The binary classificaiton catalog trainer object. + /// The binary classification catalog trainer object. /// The name of the label column. /// The name of the feature column. /// The name of the example weight column (optional). @@ -430,7 +444,7 @@ public static LogisticRegression LogisticRegression(this BinaryClassificationCat /// /// Predict a target using a linear binary classification model trained with the trainer. /// - /// The binary classificaiton catalog trainer object. + /// The binary classification catalog trainer object. /// Advanced arguments to the algorithm. public static LogisticRegression LogisticRegression(this BinaryClassificationCatalog.BinaryClassificationTrainers catalog, LROptions options) { diff --git a/src/Microsoft.ML.StaticPipe/LbfgsStatic.cs b/src/Microsoft.ML.StaticPipe/LbfgsStatic.cs index 273bbc3320..82d6df6fbd 100644 --- a/src/Microsoft.ML.StaticPipe/LbfgsStatic.cs +++ b/src/Microsoft.ML.StaticPipe/LbfgsStatic.cs @@ -21,7 +21,7 @@ public static class LbfgsBinaryClassificationStaticExtensions /// /// Predict a target using a linear binary classification model trained with the trainer. /// - /// The binary classificaiton catalog trainer object. + /// The binary classification catalog trainer object. /// The label, or dependent variable. /// The features, or independent variables. /// The optional example weights. @@ -67,7 +67,7 @@ public static (Scalar score, Scalar probability, Scalar pred /// /// Predict a target using a linear binary classification model trained with the trainer. /// - /// The binary classificaiton catalog trainer object. + /// The binary classification catalog trainer object. /// The label, or dependent variable. /// The features, or independent variables. /// The optional example weights. diff --git a/src/Microsoft.ML.StaticPipe/SgdStatic.cs b/src/Microsoft.ML.StaticPipe/SgdStatic.cs index 66b342c6a3..f893320366 100644 --- a/src/Microsoft.ML.StaticPipe/SgdStatic.cs +++ b/src/Microsoft.ML.StaticPipe/SgdStatic.cs @@ -19,7 +19,7 @@ public static class SgdStaticExtensions /// /// Predict a target using logistic regression trained with the trainer. /// - /// The binary classificaiton catalog trainer object. + /// The binary classification catalog trainer object. /// The name of the label column. /// The name of the feature column. /// The name for the example weight column. @@ -59,7 +59,7 @@ public static (Scalar score, Scalar probability, Scalar pred /// /// Predict a target using logistic regression trained with the trainer. /// - /// The binary classificaiton catalog trainer object. + /// The binary classification catalog trainer object. /// The name of the label column. /// The name of the feature column. /// The name for the example weight column. @@ -99,7 +99,7 @@ public static (Scalar score, Scalar probability, Scalar pred /// /// Predict a target using a linear classification model trained with the trainer. /// - /// The binary classificaiton catalog trainer object. + /// The binary classification catalog trainer object. /// The name of the label column. /// The name of the feature column. /// The name for the example weight column. @@ -142,7 +142,7 @@ public static (Scalar score, Scalar predictedLabel) StochasticGradi /// /// Predict a target using a linear classification model trained with the trainer. /// - /// The binary classificaiton catalog trainer object. + /// The binary classification catalog trainer object. /// The name of the label column. /// The name of the feature column. /// The name for the example weight column. diff --git a/src/Microsoft.ML.StaticPipe/TreeTrainersStatic.cs b/src/Microsoft.ML.StaticPipe/TreeTrainersStatic.cs index c0bdbb2c3d..e5289e0d98 100644 --- a/src/Microsoft.ML.StaticPipe/TreeTrainersStatic.cs +++ b/src/Microsoft.ML.StaticPipe/TreeTrainersStatic.cs @@ -110,7 +110,7 @@ public static Scalar FastTree(this RegressionCatalog.RegressionTrainers c /// /// FastTree extension method. - /// Predict a target using a decision tree binary classificaiton model trained with the . + /// Predict a target using a decision tree binary classification model trained with the . /// /// The . /// The label column. @@ -160,7 +160,7 @@ public static (Scalar score, Scalar probability, Scalar pred /// /// FastTree extension method. - /// Predict a target using a decision tree binary classificaiton model trained with the . + /// Predict a target using a decision tree binary classification model trained with the . /// /// The . /// The label column. From f6d55f346702c4a3177e24e01c60cb0a11d2d1a8 Mon Sep 17 00:00:00 2001 From: Eric Erhardt Date: Mon, 25 Feb 2019 15:48:19 -0600 Subject: [PATCH 17/24] Make DataViewRowId not act like a number. (#2707) * Make DataViewRowId not act like a number. - Remove it from the NumberDataViewType. - Remove any method/operator that makes it feel like a number. Working towards #2297 --- src/Microsoft.Data.DataView/DataViewRowId.cs | 63 +----- src/Microsoft.Data.DataView/DataViewType.cs | 46 ++++- .../Data/ColumnTypeExtensions.cs | 11 +- src/Microsoft.ML.Data/Data/DataViewUtils.cs | 4 +- .../DataLoadSave/Binary/Codecs.cs | 4 +- src/Microsoft.ML.Data/Transforms/Hashing.cs | 5 +- .../Transforms/RowShufflingTransformer.cs | 2 +- src/Microsoft.ML.Parquet/ParquetLoader.cs | 2 +- .../StaticSchemaShape.cs | 4 +- .../MissingValueReplacingUtils.cs | 189 +++++++++++------- .../ProduceIdTransform.cs | 2 +- .../UnitTests/ColumnTypes.cs | 2 +- .../Transformers/HashTests.cs | 2 +- 13 files changed, 175 insertions(+), 161 deletions(-) diff --git a/src/Microsoft.Data.DataView/DataViewRowId.cs b/src/Microsoft.Data.DataView/DataViewRowId.cs index 586ad62915..87544279d5 100644 --- a/src/Microsoft.Data.DataView/DataViewRowId.cs +++ b/src/Microsoft.Data.DataView/DataViewRowId.cs @@ -9,7 +9,7 @@ namespace Microsoft.Data.DataView { /// - /// A structure serving as a sixteen-byte unsigned integer. It is used as the row id of . + /// A structure serving as the identifier of a row of . /// For datasets with millions of records, those IDs need to be unique, therefore the need for such a large structure to hold the values. /// Those Ids are derived from other Ids of the previous components of the pipelines, and dividing the structure in two: high order and low order of bits, /// and reduces the changes of those collisions even further. @@ -53,70 +53,13 @@ public bool Equals(DataViewRowId other) public override bool Equals(object obj) { - if (obj != null && obj is DataViewRowId) + if (obj is DataViewRowId other) { - var item = (DataViewRowId)obj; - return Equals(item); + return Equals(other); } return false; } - public static DataViewRowId operator +(DataViewRowId first, ulong second) - { - ulong resHi = first.High; - ulong resLo = first.Low + second; - if (resLo < second) - resHi++; - return new DataViewRowId(resLo, resHi); - } - - public static DataViewRowId operator -(DataViewRowId first, ulong second) - { - ulong resHi = first.High; - ulong resLo = first.Low - second; - if (resLo > first.Low) - resHi--; - return new DataViewRowId(resLo, resHi); - } - - public static bool operator ==(DataViewRowId first, ulong second) - { - return first.High == 0 && first.Low == second; - } - - public static bool operator !=(DataViewRowId first, ulong second) - { - return !(first == second); - } - - public static bool operator <(DataViewRowId first, ulong second) - { - return first.High == 0 && first.Low < second; - } - - public static bool operator >(DataViewRowId first, ulong second) - { - return first.High > 0 || first.Low > second; - } - - public static bool operator <=(DataViewRowId first, ulong second) - { - return first.High == 0 && first.Low <= second; - } - - public static bool operator >=(DataViewRowId first, ulong second) - { - return first.High > 0 || first.Low >= second; - } - - public static explicit operator double(DataViewRowId x) - { - // REVIEW: The 64-bit JIT has a bug where rounding might be not quite - // correct when converting a ulong to double with the high bit set. Should we - // care and compensate? See the DoubleParser code for a work-around. - return x.High * ((double)(1UL << 32) * (1UL << 32)) + x.Low; - } - public override int GetHashCode() { return (int)( diff --git a/src/Microsoft.Data.DataView/DataViewType.cs b/src/Microsoft.Data.DataView/DataViewType.cs index 98b458781e..8440ad4cef 100644 --- a/src/Microsoft.Data.DataView/DataViewType.cs +++ b/src/Microsoft.Data.DataView/DataViewType.cs @@ -199,17 +199,6 @@ public static NumberDataViewType UInt64 } } - private static volatile NumberDataViewType _instDataViewRowId; - public static NumberDataViewType DataViewRowId - { - get - { - return _instDataViewRowId ?? - Interlocked.CompareExchange(ref _instDataViewRowId, new NumberDataViewType(typeof(DataViewRowId), "UG"), null) ?? - _instDataViewRowId; - } - } - private static volatile NumberDataViewType _instSingle; public static NumberDataViewType Single { @@ -243,6 +232,41 @@ public override bool Equals(DataViewType other) public override string ToString() => _name; } + /// + /// The DataViewRowId type. + /// + public sealed class RowIdDataViewType : PrimitiveDataViewType + { + private static volatile RowIdDataViewType _instance; + public static RowIdDataViewType Instance + { + get + { + return _instance ?? + Interlocked.CompareExchange(ref _instance, new RowIdDataViewType(), null) ?? + _instance; + } + } + + private RowIdDataViewType() + : base(typeof(DataViewRowId)) + { + } + + public override bool Equals(DataViewType other) + { + if (other == this) + return true; + Debug.Assert(!(other is RowIdDataViewType)); + return false; + } + + public override string ToString() + { + return "DataViewRowId"; + } + } + /// /// The standard boolean type. /// diff --git a/src/Microsoft.ML.Core/Data/ColumnTypeExtensions.cs b/src/Microsoft.ML.Core/Data/ColumnTypeExtensions.cs index 1213561385..67e6434d82 100644 --- a/src/Microsoft.ML.Core/Data/ColumnTypeExtensions.cs +++ b/src/Microsoft.ML.Core/Data/ColumnTypeExtensions.cs @@ -19,7 +19,8 @@ internal static class ColumnTypeExtensions /// public static bool IsStandardScalar(this DataViewType columnType) => (columnType is NumberDataViewType) || (columnType is TextDataViewType) || (columnType is BooleanDataViewType) || - (columnType is TimeSpanDataViewType) || (columnType is DateTimeDataViewType) || (columnType is DateTimeOffsetDataViewType); + (columnType is RowIdDataViewType) || (columnType is TimeSpanDataViewType) || + (columnType is DateTimeDataViewType) || (columnType is DateTimeOffsetDataViewType); /// /// Zero return means it's not a key type. @@ -103,6 +104,8 @@ public static PrimitiveDataViewType PrimitiveTypeFromType(Type type) return DateTimeDataViewType.Instance; if (type == typeof(DateTimeOffset)) return DateTimeOffsetDataViewType.Instance; + if (type == typeof(DataViewRowId)) + return RowIdDataViewType.Instance; return NumberTypeFromType(type); } @@ -118,6 +121,8 @@ public static PrimitiveDataViewType PrimitiveTypeFromKind(InternalDataKind kind) return DateTimeDataViewType.Instance; if (kind == InternalDataKind.DZ) return DateTimeOffsetDataViewType.Instance; + if (kind == InternalDataKind.UG) + return RowIdDataViewType.Instance; return NumberTypeFromKind(kind); } @@ -131,7 +136,7 @@ public static NumberDataViewType NumberTypeFromType(Type type) throw new InvalidOperationException($"Bad type in {nameof(ColumnTypeExtensions)}.{nameof(NumberTypeFromType)}: {type}"); } - public static NumberDataViewType NumberTypeFromKind(InternalDataKind kind) + private static NumberDataViewType NumberTypeFromKind(InternalDataKind kind) { switch (kind) { @@ -155,8 +160,6 @@ public static NumberDataViewType NumberTypeFromKind(InternalDataKind kind) return NumberDataViewType.Single; case InternalDataKind.R8: return NumberDataViewType.Double; - case InternalDataKind.UG: - return NumberDataViewType.DataViewRowId; } Contracts.Assert(false); diff --git a/src/Microsoft.ML.Data/Data/DataViewUtils.cs b/src/Microsoft.ML.Data/Data/DataViewUtils.cs index 001fbe360f..021314c881 100644 --- a/src/Microsoft.ML.Data/Data/DataViewUtils.cs +++ b/src/Microsoft.ML.Data/Data/DataViewUtils.cs @@ -357,7 +357,7 @@ private static DataViewRowCursor ConsolidateCore(IChannelProvider provider, Data outPipes[i] = OutPipe.Create(type, pool); } int idIdx = activeToCol.Length + (int)ExtraIndex.Id; - outPipes[idIdx] = OutPipe.Create(NumberDataViewType.DataViewRowId, GetPool(NumberDataViewType.DataViewRowId, ourPools, idIdx)); + outPipes[idIdx] = OutPipe.Create(RowIdDataViewType.Instance, GetPool(RowIdDataViewType.Instance, ourPools, idIdx)); // Create the structures to synchronize between the workers and the consumer. const int toConsumeBound = 4; @@ -553,7 +553,7 @@ private DataViewRowCursor[] SplitCore(IChannelProvider ch, DataViewRowCursor inp int idIdx = activeToCol.Length + (int)ExtraIndex.Id; inPipes[idIdx] = CreateIdInPipe(input); for (int i = 0; i < cthd; ++i) - outPipes[i][idIdx] = inPipes[idIdx].CreateOutPipe(NumberDataViewType.DataViewRowId); + outPipes[i][idIdx] = inPipes[idIdx].CreateOutPipe(RowIdDataViewType.Instance); var toConsume = new BlockingCollection(toConsumeBound); var batchColumnPool = new MadeObjectPool(() => new BatchColumn[inPipes.Length]); diff --git a/src/Microsoft.ML.Data/DataLoadSave/Binary/Codecs.cs b/src/Microsoft.ML.Data/DataLoadSave/Binary/Codecs.cs index a9b61880e5..150b62caab 100644 --- a/src/Microsoft.ML.Data/DataLoadSave/Binary/Codecs.cs +++ b/src/Microsoft.ML.Data/DataLoadSave/Binary/Codecs.cs @@ -159,7 +159,9 @@ private sealed class UnsafeTypeCodec : SimpleCodec where T : struct // Throws an exception if T is neither a TimeSpan nor a NumberType. private static DataViewType UnsafeColumnType(Type type) { - return type == typeof(TimeSpan) ? (DataViewType)TimeSpanDataViewType.Instance : ColumnTypeExtensions.NumberTypeFromType(type); + return type == typeof(TimeSpan) ? TimeSpanDataViewType.Instance : + type == typeof(DataViewRowId) ? (DataViewType)RowIdDataViewType.Instance : + ColumnTypeExtensions.NumberTypeFromType(type); } public UnsafeTypeCodec(CodecFactory factory) diff --git a/src/Microsoft.ML.Data/Transforms/Hashing.cs b/src/Microsoft.ML.Data/Transforms/Hashing.cs index b769cf9649..103dada2da 100644 --- a/src/Microsoft.ML.Data/Transforms/Hashing.cs +++ b/src/Microsoft.ML.Data/Transforms/Hashing.cs @@ -1213,10 +1213,11 @@ internal void Save(ModelSaveContext ctx) internal static bool IsColumnTypeValid(DataViewType type) { var itemType = type.GetItemType(); - return itemType is TextDataViewType || itemType is KeyType || itemType is NumberDataViewType || itemType is BooleanDataViewType; + return itemType is TextDataViewType || itemType is KeyType || itemType is NumberDataViewType || + itemType is BooleanDataViewType || itemType is RowIdDataViewType; } - internal const string ExpectedColumnType = "Expected Text, Key, numeric or Boolean item type"; + internal const string ExpectedColumnType = "Expected Text, Key, numeric, Boolean or DataViewRowId item type"; /// /// Initializes a new instance of . diff --git a/src/Microsoft.ML.Data/Transforms/RowShufflingTransformer.cs b/src/Microsoft.ML.Data/Transforms/RowShufflingTransformer.cs index 70b69e574b..8dd7b7ba19 100644 --- a/src/Microsoft.ML.Data/Transforms/RowShufflingTransformer.cs +++ b/src/Microsoft.ML.Data/Transforms/RowShufflingTransformer.cs @@ -529,7 +529,7 @@ public Cursor(IChannelProvider provider, int poolRows, DataViewRowCursor input, input.Schema[c].Type, RowCursorUtils.GetGetterAsDelegate(input, c)); _getters[ia] = CreateGetterDelegate(c); } - var idPipe = _pipes[numActive + (int)ExtraIndex.Id] = ShufflePipe.Create(_pipeIndices.Length, NumberDataViewType.DataViewRowId, input.GetIdGetter()); + var idPipe = _pipes[numActive + (int)ExtraIndex.Id] = ShufflePipe.Create(_pipeIndices.Length, RowIdDataViewType.Instance, input.GetIdGetter()); _idGetter = CreateGetterDelegate(idPipe); // Initially, after the preamble to MoveNextCore, we want: // liveCount=0, deadCount=0, circularIndex=0. So we set these diff --git a/src/Microsoft.ML.Parquet/ParquetLoader.cs b/src/Microsoft.ML.Parquet/ParquetLoader.cs index fdd10d0700..85336ad6f2 100644 --- a/src/Microsoft.ML.Parquet/ParquetLoader.cs +++ b/src/Microsoft.ML.Parquet/ParquetLoader.cs @@ -350,7 +350,7 @@ private DataViewType ConvertFieldType(DataType parquetType) case DataType.Int64: return NumberDataViewType.Int64; case DataType.Int96: - return NumberDataViewType.DataViewRowId; + return RowIdDataViewType.Instance; case DataType.ByteArray: return new VectorType(NumberDataViewType.Byte); case DataType.String: diff --git a/src/Microsoft.ML.StaticPipe/StaticSchemaShape.cs b/src/Microsoft.ML.StaticPipe/StaticSchemaShape.cs index e830b29934..d251aba49c 100644 --- a/src/Microsoft.ML.StaticPipe/StaticSchemaShape.cs +++ b/src/Microsoft.ML.StaticPipe/StaticSchemaShape.cs @@ -166,7 +166,7 @@ private static Type GetTypeOrNull(SchemaShape.Column col) if (physType != null && ( pt == NumberDataViewType.SByte || pt == NumberDataViewType.Int16 || pt == NumberDataViewType.Int32 || pt == NumberDataViewType.Int32 || pt == NumberDataViewType.Byte || pt == NumberDataViewType.UInt16 || pt == NumberDataViewType.UInt32 || pt == NumberDataViewType.UInt32 || - pt == NumberDataViewType.Single || pt == NumberDataViewType.Double || pt == NumberDataViewType.DataViewRowId || pt == BooleanDataViewType.Instance || + pt == NumberDataViewType.Single || pt == NumberDataViewType.Double || pt == RowIdDataViewType.Instance || pt == BooleanDataViewType.Instance || pt == DateTimeDataViewType.Instance || pt == DateTimeOffsetDataViewType.Instance || pt == TimeSpanDataViewType.Instance || pt == TextDataViewType.Instance)) { @@ -311,7 +311,7 @@ private static Type GetTypeOrNull(DataViewSchema.Column col) if (physType != null && ( pt == NumberDataViewType.SByte || pt == NumberDataViewType.Int16 || pt == NumberDataViewType.Int32 || pt == NumberDataViewType.Int64 || pt == NumberDataViewType.Byte || pt == NumberDataViewType.UInt16 || pt == NumberDataViewType.UInt32 || pt == NumberDataViewType.UInt64 || - pt == NumberDataViewType.Single || pt == NumberDataViewType.Double || pt == NumberDataViewType.DataViewRowId || pt == BooleanDataViewType.Instance || + pt == NumberDataViewType.Single || pt == NumberDataViewType.Double || pt == RowIdDataViewType.Instance || pt == BooleanDataViewType.Instance || pt == DateTimeDataViewType.Instance || pt == DateTimeOffsetDataViewType.Instance || pt == TimeSpanDataViewType.Instance || pt == TextDataViewType.Instance)) { diff --git a/src/Microsoft.ML.Transforms/MissingValueReplacingUtils.cs b/src/Microsoft.ML.Transforms/MissingValueReplacingUtils.cs index bc6024b225..76f4552605 100644 --- a/src/Microsoft.ML.Transforms/MissingValueReplacingUtils.cs +++ b/src/Microsoft.ML.Transforms/MissingValueReplacingUtils.cs @@ -80,6 +80,47 @@ private static StatAggregator CreateStatAggregator(IChannel ch, DataViewType typ "assigned in NAReplaceTransform.", kind, type); } + private static DataViewRowId Add(DataViewRowId left, ulong right) + { + ulong resHi = left.High; + ulong resLo = left.Low + right; + if (resLo < right) + resHi++; + return new DataViewRowId(resLo, resHi); + } + + private static DataViewRowId Subtract(DataViewRowId left, ulong right) + { + ulong resHi = left.High; + ulong resLo = left.Low - right; + if (resLo > left.Low) + resHi--; + return new DataViewRowId(resLo, resHi); + } + + private static bool Equals(DataViewRowId left, ulong right) + { + return left.High == 0 && left.Low == right; + } + + private static bool GreaterThanOrEqual(DataViewRowId left, ulong right) + { + return left.High > 0 || left.Low >= right; + } + + private static bool GreaterThan(DataViewRowId left, ulong right) + { + return left.High > 0 || left.Low > right; + } + + private static double ToDouble(DataViewRowId value) + { + // REVIEW: The 64-bit JIT has a bug where rounding might be not quite + // correct when converting a ulong to double with the high bit set. Should we + // care and compensate? See the DoubleParser code for a work-around. + return value.High * ((double)(1UL << 32) * (1UL << 32)) + value.Low; + } + /// /// The base class for stat aggregators for imputing mean, min, and max for the NAReplaceTransform. /// @@ -161,7 +202,7 @@ protected sealed override void ProcessRow(in VBuffer src) for (int slot = 0; slot < srcCount; slot++) ProcessValue(in srcValues[slot]); - _valueCount = _valueCount + (ulong)src.Length; + _valueCount = Add(_valueCount, (ulong)src.Length); } protected abstract void ProcessValue(in TItem val); @@ -312,11 +353,11 @@ private struct MeanStatDouble // The number of non-zero (finite) values processed. private long _cnz; // The current mean estimate for the _cnz values we've processed. - private Double _cur; + private double _cur; - public void Update(Double val) + public void Update(double val) { - Contracts.Assert(Double.MinValue <= _cur && _cur <= Double.MaxValue); + Contracts.Assert(double.MinValue <= _cur && _cur <= double.MaxValue); if (val == 0) return; @@ -335,12 +376,12 @@ public void Update(Double val) else _cur += (val - _cur) / _cnz; - Contracts.Assert(Double.MinValue <= _cur && _cur <= Double.MaxValue); + Contracts.Assert(double.MinValue <= _cur && _cur <= double.MaxValue); } - public Double GetCurrentValue(IChannel ch, long count) + public double GetCurrentValue(IChannel ch, long count) { - Contracts.Assert(Double.MinValue <= _cur && _cur <= Double.MaxValue); + Contracts.Assert(double.MinValue <= _cur && _cur <= double.MaxValue); Contracts.Assert(_cnz >= 0 && _cna >= 0); Contracts.Assert(count >= _cna); Contracts.Assert(count - _cna >= _cnz); @@ -353,28 +394,28 @@ public Double GetCurrentValue(IChannel ch, long count) } // Fold in the zeros. - Double stat = _cur * ((Double)_cnz / (count - _cna)); - Contracts.Assert(Double.MinValue <= stat && stat <= Double.MaxValue); + double stat = _cur * ((double)_cnz / (count - _cna)); + Contracts.Assert(double.MinValue <= stat && stat <= double.MaxValue); return stat; } - public Double GetCurrentValue(IChannel ch, DataViewRowId count) + public double GetCurrentValue(IChannel ch, DataViewRowId count) { - Contracts.Assert(Double.MinValue <= _cur && _cur <= Double.MaxValue); + Contracts.Assert(double.MinValue <= _cur && _cur <= double.MaxValue); Contracts.Assert(_cnz >= 0 && _cna >= 0); Contracts.Assert(count.High != 0 || count.Low >= (ulong)_cna); // If all values in the column are NAs, emit a warning and return 0. // Is this what we want to do or should an error be thrown? - if (count == (ulong)_cna) + if (Equals(count, (ulong)_cna)) { ch.Warning("All values in this column are NAs, using default value for imputation"); return 0; } // Fold in the zeros. - Double stat = _cur * ((Double)_cnz / (Double)(count - (ulong)_cna)); - Contracts.Assert(Double.MinValue <= stat && stat <= Double.MaxValue); + double stat = _cur * ((double)_cnz / ToDouble(Subtract(count, (ulong)_cna))); + Contracts.Assert(double.MinValue <= stat && stat <= double.MaxValue); return stat; } } @@ -462,20 +503,20 @@ public long GetCurrentValue(IChannel ch, long count, long valMax) public long GetCurrentValue(IChannel ch, DataViewRowId count, long valMax) { AssertValid(valMax); - Contracts.Assert(count >= (ulong)_cna); + Contracts.Assert(GreaterThanOrEqual(count, (ulong)_cna)); // If the sum is zero, return zero. if ((_sumHi | _sumLo) == 0) { // If all values in a given column are NAs issue a warning. - if (count == (ulong)_cna) + if (Equals(count, (ulong)_cna)) ch.Warning("All values in this column are NAs, using default value for imputation"); return 0; } - Contracts.Assert(count > (ulong)_cna); - count -= (ulong)_cna; - Contracts.Assert(count > 0); + Contracts.Assert(GreaterThan(count, (ulong)_cna)); + count = Subtract(count, (ulong)_cna); + Contracts.Assert(GreaterThan(count, 0)); ulong sumHi = _sumHi; ulong sumLo = _sumLo; @@ -495,7 +536,7 @@ public long GetCurrentValue(IChannel ch, DataViewRowId count, long valMax) // a ulong, so the absolute value of the sum can't possibly be so large that sumHi // reaches or exceeds count. This assert implies that the Div part of the DivRound // call won't throw. - Contracts.Assert(count > sumHi); + Contracts.Assert(GreaterThan(count, sumHi)); ulong res = IntUtils.DivRound(sumLo, sumHi, count.Low, count.High); Contracts.Assert(0 <= res && res <= (ulong)valMax); @@ -508,54 +549,54 @@ private static class R4 // Utilizes MeanStatDouble for the mean aggregators, a struct that holds _stat as a double, despite the fact that its // value should always be within the range of a valid Single after processing each value as it is representative of the // mean of a set of Single values. Conversion to Single happens in GetStat. - public sealed class MeanAggregatorOne : StatAggregator + public sealed class MeanAggregatorOne : StatAggregator { public MeanAggregatorOne(IChannel ch, DataViewRowCursor cursor, int col) : base(ch, cursor, col) { } - protected override void ProcessRow(in Single val) + protected override void ProcessRow(in float val) { Stat.Update(val); } public override object GetStat() { - Double val = Stat.GetCurrentValue(Ch, RowCount); - Ch.Assert(Single.MinValue <= val && val <= Single.MaxValue); - return (Single)val; + double val = Stat.GetCurrentValue(Ch, RowCount); + Ch.Assert(float.MinValue <= val && val <= float.MaxValue); + return (float)val; } } - public sealed class MeanAggregatorAcrossSlots : StatAggregatorAcrossSlots + public sealed class MeanAggregatorAcrossSlots : StatAggregatorAcrossSlots { public MeanAggregatorAcrossSlots(IChannel ch, DataViewRowCursor cursor, int col) : base(ch, cursor, col) { } - protected override void ProcessValue(in Single val) + protected override void ProcessValue(in float val) { Stat.Update(val); } public override object GetStat() { - Double val = Stat.GetCurrentValue(Ch, ValueCount); - Ch.Assert(Single.MinValue <= val && val <= Single.MaxValue); - return (Single)val; + double val = Stat.GetCurrentValue(Ch, ValueCount); + Ch.Assert(float.MinValue <= val && val <= float.MaxValue); + return (float)val; } } - public sealed class MeanAggregatorBySlot : StatAggregatorBySlot + public sealed class MeanAggregatorBySlot : StatAggregatorBySlot { public MeanAggregatorBySlot(IChannel ch, VectorType type, DataViewRowCursor cursor, int col) : base(ch, type, cursor, col) { } - protected override void ProcessValue(in Single val, int slot) + protected override void ProcessValue(in float val, int slot) { Ch.Assert(0 <= slot && slot < Stat.Length); Stat[slot].Update(val); @@ -563,53 +604,53 @@ protected override void ProcessValue(in Single val, int slot) public override object GetStat() { - Single[] stat = new Single[Stat.Length]; + float[] stat = new float[Stat.Length]; for (int slot = 0; slot < stat.Length; slot++) { - Double val = Stat[slot].GetCurrentValue(Ch, RowCount); - Ch.Assert(Single.MinValue <= val && val <= Single.MaxValue); - stat[slot] = (Single)val; + double val = Stat[slot].GetCurrentValue(Ch, RowCount); + Ch.Assert(float.MinValue <= val && val <= float.MaxValue); + stat[slot] = (float)val; } return stat; } } - public sealed class MinMaxAggregatorOne : MinMaxAggregatorOne + public sealed class MinMaxAggregatorOne : MinMaxAggregatorOne { public MinMaxAggregatorOne(IChannel ch, DataViewRowCursor cursor, int col, bool returnMax) : base(ch, cursor, col, returnMax) { - Stat = ReturnMax ? Single.NegativeInfinity : Single.PositiveInfinity; + Stat = ReturnMax ? float.NegativeInfinity : float.PositiveInfinity; } - protected override void ProcessValueMin(in Single val) + protected override void ProcessValueMin(in float val) { if (val < Stat) Stat = val; } - protected override void ProcessValueMax(in Single val) + protected override void ProcessValueMax(in float val) { if (val > Stat) Stat = val; } } - public sealed class MinMaxAggregatorAcrossSlots : MinMaxAggregatorAcrossSlots + public sealed class MinMaxAggregatorAcrossSlots : MinMaxAggregatorAcrossSlots { public MinMaxAggregatorAcrossSlots(IChannel ch, DataViewRowCursor cursor, int col, bool returnMax) : base(ch, cursor, col, returnMax) { - Stat = ReturnMax ? Single.NegativeInfinity : Single.PositiveInfinity; + Stat = ReturnMax ? float.NegativeInfinity : float.PositiveInfinity; } - protected override void ProcessValueMin(in Single val) + protected override void ProcessValueMin(in float val) { if (val < Stat) Stat = val; } - protected override void ProcessValueMax(in Single val) + protected override void ProcessValueMax(in float val) { if (val > Stat) Stat = val; @@ -618,33 +659,33 @@ protected override void ProcessValueMax(in Single val) public override object GetStat() { // If sparsity occurred, fold in a zero. - if (ValueCount > (ulong)ValuesProcessed) + if (GreaterThan(ValueCount, (ulong)ValuesProcessed)) { - Single def = 0; + float def = 0; ProcValueDelegate(in def); } - return (Single)Stat; + return (float)Stat; } } - public sealed class MinMaxAggregatorBySlot : MinMaxAggregatorBySlot + public sealed class MinMaxAggregatorBySlot : MinMaxAggregatorBySlot { public MinMaxAggregatorBySlot(IChannel ch, VectorType type, DataViewRowCursor cursor, int col, bool returnMax) : base(ch, type, cursor, col, returnMax) { - Single bound = ReturnMax ? Single.NegativeInfinity : Single.PositiveInfinity; + float bound = ReturnMax ? float.NegativeInfinity : float.PositiveInfinity; for (int i = 0; i < Stat.Length; i++) Stat[i] = bound; } - protected override void ProcessValueMin(in Single val, int slot) + protected override void ProcessValueMin(in float val, int slot) { Ch.Assert(0 <= slot && slot < Stat.Length); if (val < Stat[slot]) Stat[slot] = val; } - protected override void ProcessValueMax(in Single val, int slot) + protected override void ProcessValueMax(in float val, int slot) { Ch.Assert(0 <= slot && slot < Stat.Length); if (val > Stat[slot]) @@ -658,7 +699,7 @@ public override object GetStat() { if (GetValuesProcessed(slot) < RowCount) { - Single def = 0; + float def = 0; ProcValueDelegate(in def, slot); } } @@ -669,14 +710,14 @@ public override object GetStat() private static class R8 { - public sealed class MeanAggregatorOne : StatAggregator + public sealed class MeanAggregatorOne : StatAggregator { public MeanAggregatorOne(IChannel ch, DataViewRowCursor cursor, int col) : base(ch, cursor, col) { } - protected override void ProcessRow(in Double val) + protected override void ProcessRow(in double val) { Stat.Update(val); } @@ -687,14 +728,14 @@ public override object GetStat() } } - public sealed class MeanAggregatorAcrossSlots : StatAggregatorAcrossSlots + public sealed class MeanAggregatorAcrossSlots : StatAggregatorAcrossSlots { public MeanAggregatorAcrossSlots(IChannel ch, DataViewRowCursor cursor, int col) : base(ch, cursor, col) { } - protected override void ProcessValue(in Double val) + protected override void ProcessValue(in double val) { Stat.Update(val); } @@ -705,14 +746,14 @@ public override object GetStat() } } - public sealed class MeanAggregatorBySlot : StatAggregatorBySlot + public sealed class MeanAggregatorBySlot : StatAggregatorBySlot { public MeanAggregatorBySlot(IChannel ch, VectorType type, DataViewRowCursor cursor, int col) : base(ch, type, cursor, col) { } - protected override void ProcessValue(in Double val, int slot) + protected override void ProcessValue(in double val, int slot) { Ch.Assert(0 <= slot && slot < Stat.Length); Stat[slot].Update(val); @@ -720,49 +761,49 @@ protected override void ProcessValue(in Double val, int slot) public override object GetStat() { - Double[] stat = new Double[Stat.Length]; + double[] stat = new double[Stat.Length]; for (int slot = 0; slot < stat.Length; slot++) stat[slot] = Stat[slot].GetCurrentValue(Ch, RowCount); return stat; } } - public sealed class MinMaxAggregatorOne : MinMaxAggregatorOne + public sealed class MinMaxAggregatorOne : MinMaxAggregatorOne { public MinMaxAggregatorOne(IChannel ch, DataViewRowCursor cursor, int col, bool returnMax) : base(ch, cursor, col, returnMax) { - Stat = ReturnMax ? Double.NegativeInfinity : Double.PositiveInfinity; + Stat = ReturnMax ? double.NegativeInfinity : double.PositiveInfinity; } - protected override void ProcessValueMin(in Double val) + protected override void ProcessValueMin(in double val) { if (val < Stat) Stat = val; } - protected override void ProcessValueMax(in Double val) + protected override void ProcessValueMax(in double val) { if (val > Stat) Stat = val; } } - public sealed class MinMaxAggregatorAcrossSlots : MinMaxAggregatorAcrossSlots + public sealed class MinMaxAggregatorAcrossSlots : MinMaxAggregatorAcrossSlots { public MinMaxAggregatorAcrossSlots(IChannel ch, DataViewRowCursor cursor, int col, bool returnMax) : base(ch, cursor, col, returnMax) { - Stat = ReturnMax ? Double.NegativeInfinity : Double.PositiveInfinity; + Stat = ReturnMax ? double.NegativeInfinity : double.PositiveInfinity; } - protected override void ProcessValueMin(in Double val) + protected override void ProcessValueMin(in double val) { if (val < Stat) Stat = val; } - protected override void ProcessValueMax(in Double val) + protected override void ProcessValueMax(in double val) { if (val > Stat) Stat = val; @@ -771,26 +812,26 @@ protected override void ProcessValueMax(in Double val) public override object GetStat() { // If sparsity occurred, fold in a zero. - if (ValueCount > (ulong)ValuesProcessed) + if (GreaterThan(ValueCount, (ulong)ValuesProcessed)) { - Double def = 0; + double def = 0; ProcValueDelegate(in def); } return Stat; } } - public sealed class MinMaxAggregatorBySlot : MinMaxAggregatorBySlot + public sealed class MinMaxAggregatorBySlot : MinMaxAggregatorBySlot { public MinMaxAggregatorBySlot(IChannel ch, VectorType type, DataViewRowCursor cursor, int col, bool returnMax) : base(ch, type, cursor, col, returnMax) { - Double bound = ReturnMax ? Double.MinValue : Double.MaxValue; + double bound = ReturnMax ? double.MinValue : double.MaxValue; for (int i = 0; i < Stat.Length; i++) Stat[i] = bound; } - protected override void ProcessValueMin(in Double val, int slot) + protected override void ProcessValueMin(in double val, int slot) { Ch.Assert(0 <= slot && slot < Stat.Length); if (FloatUtils.IsFinite(val)) @@ -800,7 +841,7 @@ protected override void ProcessValueMin(in Double val, int slot) } } - protected override void ProcessValueMax(in Double val, int slot) + protected override void ProcessValueMax(in double val, int slot) { Ch.Assert(0 <= slot && slot < Stat.Length); if (FloatUtils.IsFinite(val)) @@ -817,7 +858,7 @@ public override object GetStat() { if (GetValuesProcessed(slot) < RowCount) { - Double def = 0; + double def = 0; ProcValueDelegate(in def, slot); } } diff --git a/src/Microsoft.ML.Transforms/ProduceIdTransform.cs b/src/Microsoft.ML.Transforms/ProduceIdTransform.cs index 84d568b5f3..071213b212 100644 --- a/src/Microsoft.ML.Transforms/ProduceIdTransform.cs +++ b/src/Microsoft.ML.Transforms/ProduceIdTransform.cs @@ -46,7 +46,7 @@ public Bindings(DataViewSchema input, bool user, string name) protected override DataViewType GetColumnTypeCore(int iinfo) { Contracts.Assert(iinfo == 0); - return NumberDataViewType.DataViewRowId; + return RowIdDataViewType.Instance; } public static Bindings Create(ModelLoadContext ctx, DataViewSchema input) diff --git a/test/Microsoft.ML.Core.Tests/UnitTests/ColumnTypes.cs b/test/Microsoft.ML.Core.Tests/UnitTests/ColumnTypes.cs index 6f173a8c11..428657ab21 100644 --- a/test/Microsoft.ML.Core.Tests/UnitTests/ColumnTypes.cs +++ b/test/Microsoft.ML.Core.Tests/UnitTests/ColumnTypes.cs @@ -18,7 +18,7 @@ public void TestEqualAndGetHashCode() // add PrimitiveTypes, KeyType & corresponding VectorTypes VectorType tmp1, tmp2; var types = new PrimitiveDataViewType[] { NumberDataViewType.SByte, NumberDataViewType.Int16, NumberDataViewType.Int32, NumberDataViewType.Int64, - NumberDataViewType.Byte, NumberDataViewType.UInt16, NumberDataViewType.UInt32, NumberDataViewType.UInt64, NumberDataViewType.DataViewRowId, + NumberDataViewType.Byte, NumberDataViewType.UInt16, NumberDataViewType.UInt32, NumberDataViewType.UInt64, RowIdDataViewType.Instance, TextDataViewType.Instance, BooleanDataViewType.Instance, DateTimeDataViewType.Instance, DateTimeOffsetDataViewType.Instance, TimeSpanDataViewType.Instance }; foreach (var type in types) diff --git a/test/Microsoft.ML.Tests/Transformers/HashTests.cs b/test/Microsoft.ML.Tests/Transformers/HashTests.cs index eac61568a1..2d805f762d 100644 --- a/test/Microsoft.ML.Tests/Transformers/HashTests.cs +++ b/test/Microsoft.ML.Tests/Transformers/HashTests.cs @@ -247,7 +247,7 @@ private void HashTestPositiveIntegerCore(ulong value, uint expected, uint expect HashTestCore(value, NumberDataViewType.UInt64, expected, expectedOrdered, expectedOrdered3); HashTestCore((ulong)value, new KeyType(typeof(ulong), int.MaxValue - 1), eKey, eoKey, e3Key); - HashTestCore(new DataViewRowId(value, 0), NumberDataViewType.DataViewRowId, expected, expectedOrdered, expectedOrdered3); + HashTestCore(new DataViewRowId(value, 0), RowIdDataViewType.Instance, expected, expectedOrdered, expectedOrdered3); // Next let's check signed numbers. From 4420cc7b83f8d2b0e9b75dd8534caeadd2195e1f Mon Sep 17 00:00:00 2001 From: Zeeshan Ahmed <38438266+zeahmed@users.noreply.github.com> Date: Mon, 25 Feb 2019 14:02:37 -0800 Subject: [PATCH 18/24] Changed Ranker to Ranking in evaluation related files. (#2675) --- .../EntryPoints/InputBuilder.cs | 4 +- .../Evaluators/EvaluatorUtils.cs | 2 +- .../{RankerMetrics.cs => RankingMetrics.cs} | 10 +-- ...RankerEvaluator.cs => RankingEvaluator.cs} | 80 +++++++++---------- src/Microsoft.ML.Data/TrainCatalog.cs | 4 +- .../CrossValidationMacro.cs | 2 +- src/Microsoft.ML.EntryPoints/MacroUtils.cs | 4 +- .../EvaluatorStaticExtensions.cs | 6 +- .../PermutationFeatureImportanceExtensions.cs | 14 ++-- .../Common/EntryPoints/core_ep-list.tsv | 2 +- .../Common/EntryPoints/core_manifest.json | 2 +- .../Numeric/Ranking.cs | 8 +- .../UnitTests/TestEntryPoints.cs | 2 +- test/Microsoft.ML.Functional.Tests/Common.cs | 4 +- 14 files changed, 72 insertions(+), 72 deletions(-) rename src/Microsoft.ML.Data/Evaluators/Metrics/{RankerMetrics.cs => RankingMetrics.cs} (84%) rename src/Microsoft.ML.Data/Evaluators/{RankerEvaluator.cs => RankingEvaluator.cs} (92%) diff --git a/src/Microsoft.ML.Data/EntryPoints/InputBuilder.cs b/src/Microsoft.ML.Data/EntryPoints/InputBuilder.cs index c84a9a716e..893e949283 100644 --- a/src/Microsoft.ML.Data/EntryPoints/InputBuilder.cs +++ b/src/Microsoft.ML.Data/EntryPoints/InputBuilder.cs @@ -850,8 +850,8 @@ public static class PipelineSweeperSupportedMetrics public const string RSquared = RegressionLossEvaluatorBase.RSquared; public const string LogLoss = BinaryClassifierEvaluator.LogLoss; public const string LogLossReduction = BinaryClassifierEvaluator.LogLossReduction; - public const string Ndcg = RankerEvaluator.Ndcg; - public const string Dcg = RankerEvaluator.Dcg; + public const string Ndcg = RankingEvaluator.Ndcg; + public const string Dcg = RankingEvaluator.Dcg; public const string PositivePrecision = BinaryClassifierEvaluator.PosPrecName; public const string PositiveRecall = BinaryClassifierEvaluator.PosRecallName; public const string NegativePrecision = BinaryClassifierEvaluator.NegPrecName; diff --git a/src/Microsoft.ML.Data/Evaluators/EvaluatorUtils.cs b/src/Microsoft.ML.Data/Evaluators/EvaluatorUtils.cs index 9a24981697..a696966518 100644 --- a/src/Microsoft.ML.Data/Evaluators/EvaluatorUtils.cs +++ b/src/Microsoft.ML.Data/Evaluators/EvaluatorUtils.cs @@ -44,7 +44,7 @@ public static Dictionary> Instanc { MetadataUtils.Const.ScoreColumnKind.Regression, env => new RegressionMamlEvaluator(env, new RegressionMamlEvaluator.Arguments()) }, { MetadataUtils.Const.ScoreColumnKind.MultiOutputRegression, env => new MultiOutputRegressionMamlEvaluator(env, new MultiOutputRegressionMamlEvaluator.Arguments()) }, { MetadataUtils.Const.ScoreColumnKind.QuantileRegression, env => new QuantileRegressionMamlEvaluator(env, new QuantileRegressionMamlEvaluator.Arguments()) }, - { MetadataUtils.Const.ScoreColumnKind.Ranking, env => new RankerMamlEvaluator(env, new RankerMamlEvaluator.Arguments()) }, + { MetadataUtils.Const.ScoreColumnKind.Ranking, env => new RankingMamlEvaluator(env, new RankingMamlEvaluator.Arguments()) }, { MetadataUtils.Const.ScoreColumnKind.Clustering, env => new ClusteringMamlEvaluator(env, new ClusteringMamlEvaluator.Arguments()) }, { MetadataUtils.Const.ScoreColumnKind.AnomalyDetection, env => new AnomalyDetectionMamlEvaluator(env, new AnomalyDetectionMamlEvaluator.Arguments()) } }; diff --git a/src/Microsoft.ML.Data/Evaluators/Metrics/RankerMetrics.cs b/src/Microsoft.ML.Data/Evaluators/Metrics/RankingMetrics.cs similarity index 84% rename from src/Microsoft.ML.Data/Evaluators/Metrics/RankerMetrics.cs rename to src/Microsoft.ML.Data/Evaluators/Metrics/RankingMetrics.cs index b9532fd31b..f5f4b3389a 100644 --- a/src/Microsoft.ML.Data/Evaluators/Metrics/RankerMetrics.cs +++ b/src/Microsoft.ML.Data/Evaluators/Metrics/RankingMetrics.cs @@ -6,7 +6,7 @@ namespace Microsoft.ML.Data { - public sealed class RankerMetrics + public sealed class RankingMetrics { /// /// Array of normalized discounted cumulative gains where i-th element represent NDCG@i. @@ -32,15 +32,15 @@ private static T Fetch(IExceptionContext ectx, DataViewRow row, string name) return val; } - internal RankerMetrics(IExceptionContext ectx, DataViewRow overallResult) + internal RankingMetrics(IExceptionContext ectx, DataViewRow overallResult) { VBuffer Fetch(string name) => Fetch>(ectx, overallResult, name); - Dcg = Fetch(RankerEvaluator.Dcg).GetValues().ToArray(); - Ndcg = Fetch(RankerEvaluator.Ndcg).GetValues().ToArray(); + Dcg = Fetch(RankingEvaluator.Dcg).GetValues().ToArray(); + Ndcg = Fetch(RankingEvaluator.Ndcg).GetValues().ToArray(); } - internal RankerMetrics(double[] dcg, double[] ndcg) + internal RankingMetrics(double[] dcg, double[] ndcg) { Dcg = new double[dcg.Length]; dcg.CopyTo(Dcg, 0); diff --git a/src/Microsoft.ML.Data/Evaluators/RankerEvaluator.cs b/src/Microsoft.ML.Data/Evaluators/RankingEvaluator.cs similarity index 92% rename from src/Microsoft.ML.Data/Evaluators/RankerEvaluator.cs rename to src/Microsoft.ML.Data/Evaluators/RankingEvaluator.cs index b7c7dec570..f913a53ecd 100644 --- a/src/Microsoft.ML.Data/Evaluators/RankerEvaluator.cs +++ b/src/Microsoft.ML.Data/Evaluators/RankingEvaluator.cs @@ -16,19 +16,19 @@ using Microsoft.ML.Internal.Utilities; using Microsoft.ML.Model; -[assembly: LoadableClass(typeof(RankerEvaluator), typeof(RankerEvaluator), typeof(RankerEvaluator.Arguments), typeof(SignatureEvaluator), - "Ranking Evaluator", RankerEvaluator.LoadName, "Ranking", "rank")] +[assembly: LoadableClass(typeof(RankingEvaluator), typeof(RankingEvaluator), typeof(RankingEvaluator.Arguments), typeof(SignatureEvaluator), + "Ranking Evaluator", RankingEvaluator.LoadName, "Ranking", "rank")] -[assembly: LoadableClass(typeof(RankerMamlEvaluator), typeof(RankerMamlEvaluator), typeof(RankerMamlEvaluator.Arguments), typeof(SignatureMamlEvaluator), - "Ranking Evaluator", RankerEvaluator.LoadName, "Ranking", "rank")] +[assembly: LoadableClass(typeof(RankingMamlEvaluator), typeof(RankingMamlEvaluator), typeof(RankingMamlEvaluator.Arguments), typeof(SignatureMamlEvaluator), + "Ranking Evaluator", RankingEvaluator.LoadName, "Ranking", "rank")] -[assembly: LoadableClass(typeof(RankerPerInstanceTransform), null, typeof(SignatureLoadDataTransform), - "", RankerPerInstanceTransform.LoaderSignature)] +[assembly: LoadableClass(typeof(RankingPerInstanceTransform), null, typeof(SignatureLoadDataTransform), + "", RankingPerInstanceTransform.LoaderSignature)] namespace Microsoft.ML.Data { [BestFriend] - internal sealed class RankerEvaluator : EvaluatorBase + internal sealed class RankingEvaluator : EvaluatorBase { public sealed class Arguments { @@ -61,7 +61,7 @@ public sealed class Arguments private readonly bool _groupSummary; private readonly Double[] _labelGains; - public RankerEvaluator(IHostEnvironment env, Arguments args) + public RankingEvaluator(IHostEnvironment env, Arguments args) : base(env, LoadName) { // REVIEW: What kind of checking should be applied to labelGains? @@ -89,13 +89,13 @@ private protected override void CheckScoreAndLabelTypes(RoleMappedSchema schema) var t = schema.Label.Value.Type; if (t != NumberDataViewType.Single && !(t is KeyType)) { - throw Host.ExceptSchemaMismatch(nameof(RankerMamlEvaluator.Arguments.LabelColumn), + throw Host.ExceptSchemaMismatch(nameof(RankingMamlEvaluator.Arguments.LabelColumn), "label", schema.Label.Value.Name, "R4 or a key", t.ToString()); } var scoreCol = schema.GetUniqueColumn(MetadataUtils.Const.ScoreValueKind.Score); if (scoreCol.Type != NumberDataViewType.Single) { - throw Host.ExceptSchemaMismatch(nameof(RankerMamlEvaluator.Arguments.ScoreColumn), + throw Host.ExceptSchemaMismatch(nameof(RankingMamlEvaluator.Arguments.ScoreColumn), "score", scoreCol.Name, "R4", t.ToString()); } } @@ -105,7 +105,7 @@ private protected override void CheckCustomColumnTypesCore(RoleMappedSchema sche var t = schema.Group.Value.Type; if (!(t is KeyType)) { - throw Host.ExceptSchemaMismatch(nameof(RankerMamlEvaluator.Arguments.GroupIdColumn), + throw Host.ExceptSchemaMismatch(nameof(RankingMamlEvaluator.Arguments.GroupIdColumn), "group", schema.Group.Value.Name, "key", t.ToString()); } } @@ -129,7 +129,7 @@ internal override IDataTransform GetPerInstanceMetricsCore(RoleMappedData data) var scoreInfo = data.Schema.GetUniqueColumn(MetadataUtils.Const.ScoreValueKind.Score); Host.CheckParam(data.Schema.Group.HasValue, nameof(data), "Schema must contain a group column"); - return new RankerPerInstanceTransform(Host, data.Data, + return new RankingPerInstanceTransform(Host, data.Data, data.Schema.Label.Value.Name, scoreInfo.Name, data.Schema.Group.Value.Name, _truncationLevel, _labelGains); } @@ -242,7 +242,7 @@ private protected override void GetAggregatorConsolidationFuncs(Aggregator aggre /// The name of the groupId column. /// The name of the predicted score column. /// The evaluation metrics for these outputs. - public RankerMetrics Evaluate(IDataView data, string label, string groupId, string score) + public RankingMetrics Evaluate(IDataView data, string label, string groupId, string score) { Host.CheckValue(data, nameof(data)); Host.CheckNonEmpty(label, nameof(label)); @@ -256,12 +256,12 @@ public RankerMetrics Evaluate(IDataView data, string label, string groupId, stri Host.Assert(resultDict.ContainsKey(MetricKinds.OverallMetrics)); var overall = resultDict[MetricKinds.OverallMetrics]; - RankerMetrics result; + RankingMetrics result; using (var cursor = overall.GetRowCursorForAllColumns()) { var moved = cursor.MoveNext(); Host.Assert(moved); - result = new RankerMetrics(Host, cursor); + result = new RankingMetrics(Host, cursor); moved = cursor.MoveNext(); Host.Assert(!moved); } @@ -374,7 +374,7 @@ public void Update(short label, Single output) public void UpdateGroup(Single weight) { - RankerUtils.QueryMaxDcg(_labelGains, TruncationLevel, _queryLabels, _queryOutputs, _groupMaxDcgCur); + RankingUtils.QueryMaxDcg(_labelGains, TruncationLevel, _queryLabels, _queryOutputs, _groupMaxDcgCur); if (_groupMaxDcg != null) { var maxDcg = new Double[TruncationLevel]; @@ -382,7 +382,7 @@ public void UpdateGroup(Single weight) _groupMaxDcg.Add(maxDcg); } - RankerUtils.QueryDcg(_labelGains, TruncationLevel, _queryLabels, _queryOutputs, _groupDcgCur); + RankingUtils.QueryDcg(_labelGains, TruncationLevel, _queryLabels, _queryOutputs, _groupDcgCur); if (_groupDcg != null) { var groupDcg = new Double[TruncationLevel]; @@ -539,7 +539,7 @@ public void GetSlotNames(ref VBuffer> slotNames) } } - internal sealed class RankerPerInstanceTransform : IDataTransform + internal sealed class RankingPerInstanceTransform : IDataTransform { public const string LoaderSignature = "RankerPerInstTransform"; private const string RegistrationName = LoaderSignature; @@ -552,7 +552,7 @@ private static VersionInfo GetVersionInfo() verReadableCur: 0x00010001, verWeCanReadBack: 0x00010001, loaderSignature: LoaderSignature, - loaderAssemblyName: typeof(RankerPerInstanceTransform).Assembly.FullName); + loaderAssemblyName: typeof(RankingPerInstanceTransform).Assembly.FullName); } public const string Ndcg = "NDCG"; @@ -576,25 +576,25 @@ private static VersionInfo GetVersionInfo() /// public DataViewSchema OutputSchema => _transform.OutputSchema; - public RankerPerInstanceTransform(IHostEnvironment env, IDataView input, string labelCol, string scoreCol, string groupCol, + public RankingPerInstanceTransform(IHostEnvironment env, IDataView input, string labelCol, string scoreCol, string groupCol, int truncationLevel, Double[] labelGains) { _transform = new Transform(env, input, labelCol, scoreCol, groupCol, truncationLevel, labelGains); } - private RankerPerInstanceTransform(IHostEnvironment env, ModelLoadContext ctx, IDataView input) + private RankingPerInstanceTransform(IHostEnvironment env, ModelLoadContext ctx, IDataView input) { _transform = new Transform(env, ctx, input); } - public static RankerPerInstanceTransform Create(IHostEnvironment env, ModelLoadContext ctx, IDataView input) + public static RankingPerInstanceTransform Create(IHostEnvironment env, ModelLoadContext ctx, IDataView input) { Contracts.CheckValue(env, nameof(env)); var h = env.Register(RegistrationName); h.CheckValue(ctx, nameof(ctx)); ctx.CheckAtModel(GetVersionInfo()); h.CheckValue(input, nameof(input)); - return h.Apply("Loading Model", ch => new RankerPerInstanceTransform(h, ctx, input)); + return h.Apply("Loading Model", ch => new RankingPerInstanceTransform(h, ctx, input)); } void ICanSaveModel.Save(ModelSaveContext ctx) @@ -801,9 +801,9 @@ protected override void ProcessExample(RowCursorState state, short label, Single protected override void UpdateState(RowCursorState state) { // Calculate the current group DCG, NDCG and MaxDcg. - RankerUtils.QueryMaxDcg(_labelGains, _truncationLevel, state.QueryLabels, state.QueryOutputs, + RankingUtils.QueryMaxDcg(_labelGains, _truncationLevel, state.QueryLabels, state.QueryOutputs, state.MaxDcgCur); - RankerUtils.QueryDcg(_labelGains, _truncationLevel, state.QueryLabels, state.QueryOutputs, state.DcgCur); + RankingUtils.QueryDcg(_labelGains, _truncationLevel, state.QueryLabels, state.QueryOutputs, state.DcgCur); for (int t = 0; t < _truncationLevel; t++) { Double ndcg = state.MaxDcgCur[t] > 0 ? state.DcgCur[t] / state.MaxDcgCur[t] * 100 : 0; @@ -838,7 +838,7 @@ public RowCursorState(int truncationLevel) } [BestFriend] - internal sealed class RankerMamlEvaluator : MamlEvaluatorBase + internal sealed class RankingMamlEvaluator : MamlEvaluatorBase { public sealed class Arguments : ArgumentsBase { @@ -855,25 +855,25 @@ public sealed class Arguments : ArgumentsBase public string GroupSummaryFilename; } - private readonly RankerEvaluator _evaluator; + private readonly RankingEvaluator _evaluator; private readonly string _groupIdCol; private readonly string _groupSummaryFilename; private protected override IEvaluator Evaluator => _evaluator; - public RankerMamlEvaluator(IHostEnvironment env, Arguments args) + public RankingMamlEvaluator(IHostEnvironment env, Arguments args) : base(args, env, MetadataUtils.Const.ScoreColumnKind.Ranking, "RankerMamlEvaluator") { Host.CheckValue(args, nameof(args)); Utils.CheckOptionalUserDirectory(args.GroupSummaryFilename, nameof(args.GroupSummaryFilename)); - var evalArgs = new RankerEvaluator.Arguments(); + var evalArgs = new RankingEvaluator.Arguments(); evalArgs.DcgTruncationLevel = args.DcgTruncationLevel; evalArgs.LabelGains = args.LabelGains; evalArgs.OutputGroupSummary = !string.IsNullOrEmpty(args.GroupSummaryFilename); - _evaluator = new RankerEvaluator(Host, evalArgs); + _evaluator = new RankingEvaluator(Host, evalArgs); _groupSummaryFilename = args.GroupSummaryFilename; _groupIdCol = args.GroupIdColumn; } @@ -908,14 +908,14 @@ private bool TryGetGroupSummaryMetrics(Dictionary[] metrics, Host.AssertNonEmpty(metrics); if (metrics.Length == 1) - return metrics[0].TryGetValue(RankerEvaluator.GroupSummary, out gs); + return metrics[0].TryGetValue(RankingEvaluator.GroupSummary, out gs); gs = null; var gsList = new List(); for (int i = 0; i < metrics.Length; i++) { IDataView idv; - if (!metrics[i].TryGetValue(RankerEvaluator.GroupSummary, out idv)) + if (!metrics[i].TryGetValue(RankingEvaluator.GroupSummary, out idv)) return false; idv = EvaluateUtils.AddFoldIndex(Host, idv, i, metrics.Length); @@ -939,13 +939,13 @@ private protected override IEnumerable GetPerInstanceColumnsToSave(RoleM yield return scoreCol.Name; // Return the output columns. - yield return RankerPerInstanceTransform.Ndcg; - yield return RankerPerInstanceTransform.Dcg; - yield return RankerPerInstanceTransform.MaxDcg; + yield return RankingPerInstanceTransform.Ndcg; + yield return RankingPerInstanceTransform.Dcg; + yield return RankingPerInstanceTransform.MaxDcg; } } - internal static class RankerUtils + internal static class RankingUtils { private static volatile Double[] _discountMap; public static Double[] DiscountMap @@ -1054,8 +1054,8 @@ private static Comparison GetCompareItems(List queryLabels, ListThe name of the groupId column in . /// The name of the score column in . /// The evaluation results for these calibrated outputs. - public RankerMetrics Evaluate(IDataView data, + public RankingMetrics Evaluate(IDataView data, string label = DefaultColumnNames.Label, string groupId = DefaultColumnNames.GroupId, string score = DefaultColumnNames.Score) @@ -633,7 +633,7 @@ public RankerMetrics Evaluate(IDataView data, Environment.CheckNonEmpty(score, nameof(score)); Environment.CheckNonEmpty(groupId, nameof(groupId)); - var eval = new RankerEvaluator(Environment, new RankerEvaluator.Arguments() { }); + var eval = new RankingEvaluator(Environment, new RankingEvaluator.Arguments() { }); return eval.Evaluate(data, label, groupId, score); } } diff --git a/src/Microsoft.ML.EntryPoints/CrossValidationMacro.cs b/src/Microsoft.ML.EntryPoints/CrossValidationMacro.cs index df529dc1cf..fa4e4ee734 100644 --- a/src/Microsoft.ML.EntryPoints/CrossValidationMacro.cs +++ b/src/Microsoft.ML.EntryPoints/CrossValidationMacro.cs @@ -430,7 +430,7 @@ private static IMamlEvaluator GetEvaluator(IHostEnvironment env, MacroUtils.Trai case MacroUtils.TrainerKinds.SignatureRegressorTrainer: return new RegressionMamlEvaluator(env, new RegressionMamlEvaluator.Arguments()); case MacroUtils.TrainerKinds.SignatureRankerTrainer: - return new RankerMamlEvaluator(env, new RankerMamlEvaluator.Arguments()); + return new RankingMamlEvaluator(env, new RankingMamlEvaluator.Arguments()); case MacroUtils.TrainerKinds.SignatureAnomalyDetectorTrainer: return new AnomalyDetectionMamlEvaluator(env, new AnomalyDetectionMamlEvaluator.Arguments()); case MacroUtils.TrainerKinds.SignatureClusteringTrainer: diff --git a/src/Microsoft.ML.EntryPoints/MacroUtils.cs b/src/Microsoft.ML.EntryPoints/MacroUtils.cs index e81862b5c1..c2eba81c23 100644 --- a/src/Microsoft.ML.EntryPoints/MacroUtils.cs +++ b/src/Microsoft.ML.EntryPoints/MacroUtils.cs @@ -54,8 +54,8 @@ public static EvaluateInputBase GetEvaluatorArgs(TrainerKinds kind, out string e entryPointName = "Models.ClassificationEvaluator"; return new MultiClassMamlEvaluator.Arguments() { LabelColumn = settings.LabelColumn, WeightColumn = settings.WeightColumn, NameColumn = settings.NameColumn }; case TrainerKinds.SignatureRankerTrainer: - entryPointName = "Models.RankerEvaluator"; - return new RankerMamlEvaluator.Arguments() { LabelColumn = settings.LabelColumn, WeightColumn = settings.WeightColumn, NameColumn = settings.NameColumn, GroupIdColumn = settings.GroupColumn }; + entryPointName = "Models.RankingEvaluator"; + return new RankingMamlEvaluator.Arguments() { LabelColumn = settings.LabelColumn, WeightColumn = settings.WeightColumn, NameColumn = settings.NameColumn, GroupIdColumn = settings.GroupColumn }; case TrainerKinds.SignatureRegressorTrainer: entryPointName = "Models.RegressionEvaluator"; return new RegressionMamlEvaluator.Arguments() { LabelColumn = settings.LabelColumn, WeightColumn = settings.WeightColumn, NameColumn = settings.NameColumn }; diff --git a/src/Microsoft.ML.StaticPipe/EvaluatorStaticExtensions.cs b/src/Microsoft.ML.StaticPipe/EvaluatorStaticExtensions.cs index 1ba0f57416..b643d30f07 100644 --- a/src/Microsoft.ML.StaticPipe/EvaluatorStaticExtensions.cs +++ b/src/Microsoft.ML.StaticPipe/EvaluatorStaticExtensions.cs @@ -211,7 +211,7 @@ public static RegressionMetrics Evaluate( /// The index delegate for the groupId column. /// The index delegate for predicted score column. /// The evaluation metrics. - public static RankerMetrics Evaluate( + public static RankingMetrics Evaluate( this RankingCatalog catalog, DataView data, Func> label, @@ -230,9 +230,9 @@ public static RankerMetrics Evaluate( string scoreName = indexer.Get(score(indexer.Indices)); string groupIdName = indexer.Get(groupId(indexer.Indices)); - var args = new RankerEvaluator.Arguments() { }; + var args = new RankingEvaluator.Arguments() { }; - return new RankerEvaluator(env, args).Evaluate(data.AsDynamic, labelName, groupIdName, scoreName); + return new RankingEvaluator(env, args).Evaluate(data.AsDynamic, labelName, groupIdName, scoreName); } } } diff --git a/src/Microsoft.ML.Transforms/PermutationFeatureImportanceExtensions.cs b/src/Microsoft.ML.Transforms/PermutationFeatureImportanceExtensions.cs index 25df14f8dc..945cfc28ac 100644 --- a/src/Microsoft.ML.Transforms/PermutationFeatureImportanceExtensions.cs +++ b/src/Microsoft.ML.Transforms/PermutationFeatureImportanceExtensions.cs @@ -285,7 +285,7 @@ private static MultiClassClassifierMetrics MulticlassClassificationDelta( /// Limit the number of examples to evaluate on. null means examples (up to ~ 2 bln) from input will be used. /// The number of permutations to perform. /// Array of per-feature 'contributions' to the score. - public static ImmutableArray + public static ImmutableArray PermutationFeatureImportance( this RankingCatalog catalog, IPredictionTransformer model, @@ -297,7 +297,7 @@ public static ImmutableArray int? topExamples = null, int permutationCount = 1) { - return PermutationFeatureImportance.GetImportanceMetricsMatrix( + return PermutationFeatureImportance.GetImportanceMetricsMatrix( CatalogUtils.GetEnvironment(catalog), model, data, @@ -309,13 +309,13 @@ public static ImmutableArray topExamples); } - private static RankerMetrics RankingDelta( - RankerMetrics a, RankerMetrics b) + private static RankingMetrics RankingDelta( + RankingMetrics a, RankingMetrics b) { var dcg = ComputeArrayDeltas(a.Dcg, b.Dcg); var ndcg = ComputeArrayDeltas(a.Ndcg, b.Ndcg); - return new RankerMetrics(dcg: dcg, ndcg: ndcg); + return new RankingMetrics(dcg: dcg, ndcg: ndcg); } #endregion @@ -606,7 +606,7 @@ public override void Add(MultiClassClassifierMetrics metrics) /// The RankerMetricsStatistics class is computes summary /// statistics over multiple observations of regression evaluation metrics. /// - public sealed class RankerMetricsStatistics : MetricsStatisticsBase + public sealed class RankingMetricsStatistics : MetricsStatisticsBase { /// /// Summary Statistics for DCG @@ -622,7 +622,7 @@ public sealed class RankerMetricsStatistics : MetricsStatisticsBase /// The observed regression evaluation metric - public override void Add(RankerMetrics metrics) + public override void Add(RankingMetrics metrics) { if (Dcg == null) Dcg = InitializeArray(metrics.Dcg.Length); diff --git a/test/BaselineOutput/Common/EntryPoints/core_ep-list.tsv b/test/BaselineOutput/Common/EntryPoints/core_ep-list.tsv index 8141d7a6da..172d030b01 100644 --- a/test/BaselineOutput/Common/EntryPoints/core_ep-list.tsv +++ b/test/BaselineOutput/Common/EntryPoints/core_ep-list.tsv @@ -25,7 +25,7 @@ Models.OvaModelCombiner Combines a sequence of PredictorModels into a single mod Models.PAVCalibrator Apply a PAV calibrator to an input model Microsoft.ML.Internal.Calibration.Calibrate Pav Microsoft.ML.Internal.Calibration.Calibrate+NoArgumentsInput Microsoft.ML.EntryPoints.CommonOutputs+CalibratorOutput Models.PlattCalibrator Apply a Platt calibrator to an input model Microsoft.ML.Internal.Calibration.Calibrate Platt Microsoft.ML.Internal.Calibration.Calibrate+NoArgumentsInput Microsoft.ML.EntryPoints.CommonOutputs+CalibratorOutput Models.QuantileRegressionEvaluator Evaluates a quantile regression scored dataset. Microsoft.ML.Data.Evaluate QuantileRegression Microsoft.ML.Data.QuantileRegressionMamlEvaluator+Arguments Microsoft.ML.EntryPoints.CommonOutputs+CommonEvaluateOutput -Models.RankerEvaluator Evaluates a ranking scored dataset. Microsoft.ML.Data.Evaluate Ranking Microsoft.ML.Data.RankerMamlEvaluator+Arguments Microsoft.ML.EntryPoints.CommonOutputs+CommonEvaluateOutput +Models.RankingEvaluator Evaluates a ranking scored dataset. Microsoft.ML.Data.Evaluate Ranking Microsoft.ML.Data.RankingMamlEvaluator+Arguments Microsoft.ML.EntryPoints.CommonOutputs+CommonEvaluateOutput Models.RegressionEnsemble Combine regression models into an ensemble Microsoft.ML.Trainers.Ensemble.EnsembleCreator CreateRegressionEnsemble Microsoft.ML.Trainers.Ensemble.EnsembleCreator+RegressionInput Microsoft.ML.EntryPoints.CommonOutputs+RegressionOutput Models.RegressionEvaluator Evaluates a regression scored dataset. Microsoft.ML.Data.Evaluate Regression Microsoft.ML.Data.RegressionMamlEvaluator+Arguments Microsoft.ML.EntryPoints.CommonOutputs+CommonEvaluateOutput Models.RegressionPipelineEnsemble Combine regression models into an ensemble Microsoft.ML.Trainers.Ensemble.EnsembleCreator CreateRegressionPipelineEnsemble Microsoft.ML.Trainers.Ensemble.EnsembleCreator+PipelineRegressionInput Microsoft.ML.EntryPoints.CommonOutputs+RegressionOutput diff --git a/test/BaselineOutput/Common/EntryPoints/core_manifest.json b/test/BaselineOutput/Common/EntryPoints/core_manifest.json index be20dafb9c..f4d5e90e7c 100644 --- a/test/BaselineOutput/Common/EntryPoints/core_manifest.json +++ b/test/BaselineOutput/Common/EntryPoints/core_manifest.json @@ -2677,7 +2677,7 @@ ] }, { - "Name": "Models.RankerEvaluator", + "Name": "Models.RankingEvaluator", "Desc": "Evaluates a ranking scored dataset.", "FriendlyName": null, "ShortName": null, diff --git a/test/Microsoft.ML.Benchmarks/Numeric/Ranking.cs b/test/Microsoft.ML.Benchmarks/Numeric/Ranking.cs index ec4bfa9cb1..63dab27311 100644 --- a/test/Microsoft.ML.Benchmarks/Numeric/Ranking.cs +++ b/test/Microsoft.ML.Benchmarks/Numeric/Ranking.cs @@ -43,7 +43,7 @@ public void TrainTest_Ranking_MSLRWeb10K_RawNumericFeatures_FastTreeRanking() " xf=HashTransform{col=GroupId} xf=NAHandleTransform{col=Features}" + " tr=FastTreeRanking{}"; - var environment = EnvironmentFactory.CreateRankingEnvironment(); + var environment = EnvironmentFactory.CreateRankingEnvironment(); cmd.ExecuteMamlCommand(environment); } @@ -58,7 +58,7 @@ public void TrainTest_Ranking_MSLRWeb10K_RawNumericFeatures_LightGBMRanking() " xf=NAHandleTransform{col=Features}" + " tr=LightGBMRanking{}"; - var environment = EnvironmentFactory.CreateRankingEnvironment(); + var environment = EnvironmentFactory.CreateRankingEnvironment(); cmd.ExecuteMamlCommand(environment); } } @@ -97,7 +97,7 @@ public void SetupScoringSpeedTests() " tr=FastTreeRanking{}" + " out={" + _modelPath_MSLR + "}"; - var environment = EnvironmentFactory.CreateRankingEnvironment(); + var environment = EnvironmentFactory.CreateRankingEnvironment(); cmd.ExecuteMamlCommand(environment); } @@ -107,7 +107,7 @@ public void Test_Ranking_MSLRWeb10K_RawNumericFeatures_FastTreeRanking() // This benchmark is profiling bulk scoring speed and not training speed. string cmd = @"Test data=" + _mslrWeb10k_Test + " in=" + _modelPath_MSLR; - var environment = EnvironmentFactory.CreateRankingEnvironment(); + var environment = EnvironmentFactory.CreateRankingEnvironment(); cmd.ExecuteMamlCommand(environment); } } diff --git a/test/Microsoft.ML.Core.Tests/UnitTests/TestEntryPoints.cs b/test/Microsoft.ML.Core.Tests/UnitTests/TestEntryPoints.cs index 8ad01452fb..00eee9b979 100644 --- a/test/Microsoft.ML.Core.Tests/UnitTests/TestEntryPoints.cs +++ b/test/Microsoft.ML.Core.Tests/UnitTests/TestEntryPoints.cs @@ -1894,7 +1894,7 @@ public void EntryPointEvaluateRanking() } },"; - RunTrainScoreEvaluate("Trainers.FastTreeRanker", "Models.RankerEvaluator", + RunTrainScoreEvaluate("Trainers.FastTreeRanker", "Models.RankingEvaluator", dataPath, warningsPath, overallMetricsPath, instanceMetricsPath, splitterInput: "output_data3", transforms: transforms); diff --git a/test/Microsoft.ML.Functional.Tests/Common.cs b/test/Microsoft.ML.Functional.Tests/Common.cs index 9ca819952b..5d71d77ad4 100644 --- a/test/Microsoft.ML.Functional.Tests/Common.cs +++ b/test/Microsoft.ML.Functional.Tests/Common.cs @@ -223,10 +223,10 @@ public static void AssertMetrics(MultiClassClassifierMetrics metrics) } /// - /// Check that a object is valid. + /// Check that a object is valid. /// /// The metrics object. - public static void AssertMetrics(RankerMetrics metrics) + public static void AssertMetrics(RankingMetrics metrics) { foreach (var dcg in metrics.Dcg) Assert.True(dcg >= 0); From 18801ab63aaf98dc295cc701df65619a9972b01b Mon Sep 17 00:00:00 2001 From: "REDMOND\\nakazmi" Date: Tue, 19 Feb 2019 23:19:02 -0800 Subject: [PATCH 19/24] Adding a sample for LightGbm Ranking --- ...LightGBMBinaryClassificationWithOptions.cs | 1 - .../Trainers/Ranking/LightGBMRanking.cs | 42 +++++++++++++++ .../Ranking/LightGBMRankingWithOptions.cs | 44 ++++++++++++++++ docs/samples/Microsoft.ML.Samples/Program.cs | 2 +- .../Evaluators/Metrics/RankingMetrics.cs | 2 +- src/Microsoft.ML.SamplesUtils/ConsoleUtils.cs | 11 ++++ .../SamplesDatasetUtils.cs | 51 +++++++++++++++++++ 7 files changed, 150 insertions(+), 3 deletions(-) create mode 100644 docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Ranking/LightGBMRanking.cs create mode 100644 docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Ranking/LightGBMRankingWithOptions.cs diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/LightGBMBinaryClassificationWithOptions.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/LightGBMBinaryClassificationWithOptions.cs index 20924bc29f..904285aaee 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/LightGBMBinaryClassificationWithOptions.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/LightGBMBinaryClassificationWithOptions.cs @@ -1,5 +1,4 @@ using Microsoft.ML.LightGBM; -using Microsoft.ML.Transforms.Categorical; using static Microsoft.ML.LightGBM.Options; namespace Microsoft.ML.Samples.Dynamic diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Ranking/LightGBMRanking.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Ranking/LightGBMRanking.cs new file mode 100644 index 0000000000..8822a16630 --- /dev/null +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Ranking/LightGBMRanking.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Microsoft.ML.Samples.Dynamic +{ + public class LightGbmRanking + { + // This example requires installation of additional nuget package Microsoft.ML.LightGBM. + public static void Example() + { + // Creating the ML.Net IHostEnvironment object, needed for the pipeline. + var mlContext = new MLContext(); + + // Download and featurize the train and validation datasets. + (var trainData, var validationData) = SamplesUtils.DatasetUtils.LoadFeaturizedMslrWeb10kTrainAndValidate(mlContext); + + // Create the Estimator pipeline. For simplicity, we will train a small tree with 4 leaves and 2 boosting iterations. + var pipeline = mlContext.Ranking.Trainers.LightGbm( + labelColumn: "Label", + featureColumn: "Features", + groupIdColumn: "GroupId", + numLeaves: 4, + minDataPerLeaf: 10, + learningRate: 0.1, + numBoostRound: 2); + + // Fit this Pipeline to the Training Data. + var model = pipeline.Fit(trainData); + + // Evaluate how the model is doing on the test data. + var dataWithPredictions = model.Transform(validationData); + + var metrics = mlContext.Ranking.Evaluate(dataWithPredictions, "Label", "GroupId"); + SamplesUtils.ConsoleUtils.PrintMetrics(metrics); + + // Output: + // DCG @N: 1.38, 3.11, 4.94 + // NDCG @N: 7.13, 10.12, 12.62 + } + } +} diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Ranking/LightGBMRankingWithOptions.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Ranking/LightGBMRankingWithOptions.cs new file mode 100644 index 0000000000..d8f3da41ea --- /dev/null +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Ranking/LightGBMRankingWithOptions.cs @@ -0,0 +1,44 @@ +using Microsoft.ML.LightGBM; +using static Microsoft.ML.LightGBM.Options; + +namespace Microsoft.ML.Samples.Dynamic +{ + public class LightGbmRankingWithOptions + { + // This example requires installation of additional nuget package Microsoft.ML.LightGBM. + public static void Example() + { + // Creating the ML.Net IHostEnvironment object, needed for the pipeline. + var mlContext = new MLContext(); + + // Download and featurize the train and validation datasets. + (var trainData, var validationData) = SamplesUtils.DatasetUtils.LoadFeaturizedMslrWeb10kTrainAndValidate(mlContext); + + // Create the Estimator pipeline. For simplicity, we will train a small tree with 4 leaves and 2 boosting iterations. + var pipeline = mlContext.Ranking.Trainers.LightGbm( + new Options + { + LabelColumn = "Label", + FeatureColumn = "Features", + GroupIdColumn = "GroupId", + NumLeaves = 4, + MinDataPerLeaf = 10, + LearningRate = 0.1, + NumBoostRound = 2 + }); + + // Fit this Pipeline to the Training Data. + var model = pipeline.Fit(trainData); + + // Evaluate how the model is doing on the test data. + var dataWithPredictions = model.Transform(validationData); + + var metrics = mlContext.Ranking.Evaluate(dataWithPredictions, "Label", "GroupId"); + SamplesUtils.ConsoleUtils.PrintMetrics(metrics); + + // Output: + // DCG @N: 1.38, 3.11, 4.94 + // NDCG @N: 7.13, 10.12, 12.62 + } + } +} diff --git a/docs/samples/Microsoft.ML.Samples/Program.cs b/docs/samples/Microsoft.ML.Samples/Program.cs index d28cdd4d77..6fa4e40705 100644 --- a/docs/samples/Microsoft.ML.Samples/Program.cs +++ b/docs/samples/Microsoft.ML.Samples/Program.cs @@ -6,7 +6,7 @@ internal static class Program { static void Main(string[] args) { - TakeRows.Example(); + LightGbmRanking.Example(); } } } diff --git a/src/Microsoft.ML.Data/Evaluators/Metrics/RankingMetrics.cs b/src/Microsoft.ML.Data/Evaluators/Metrics/RankingMetrics.cs index f5f4b3389a..82513280da 100644 --- a/src/Microsoft.ML.Data/Evaluators/Metrics/RankingMetrics.cs +++ b/src/Microsoft.ML.Data/Evaluators/Metrics/RankingMetrics.cs @@ -18,7 +18,7 @@ public sealed class RankingMetrics ///Array of discounted cumulative gains where i-th element represent DCG@i. /// Discounted Cumulative gain /// is the sum of the gains, for all the instances i, normalized by the natural logarithm of the instance + 1. - /// Note that unline the Wikipedia article, ML.Net uses the natural logarithm. + /// Note that unlike the Wikipedia article, ML.Net uses the natural logarithm. /// /// public double[] Dcg { get; } diff --git a/src/Microsoft.ML.SamplesUtils/ConsoleUtils.cs b/src/Microsoft.ML.SamplesUtils/ConsoleUtils.cs index 16f72e3392..40407fe142 100644 --- a/src/Microsoft.ML.SamplesUtils/ConsoleUtils.cs +++ b/src/Microsoft.ML.SamplesUtils/ConsoleUtils.cs @@ -1,4 +1,5 @@ using System; +using System.Linq; using Microsoft.ML.Data; namespace Microsoft.ML.SamplesUtils @@ -47,5 +48,15 @@ public static void PrintMetrics(RegressionMetrics metrics) Console.WriteLine($"RMS: {metrics.Rms:F2}"); Console.WriteLine($"RSquared: {metrics.RSquared:F2}"); } + + /// + /// Pretty-print RankerMetrics objects. + /// + /// Ranker metrics. + public static void PrintMetrics(RankerMetrics metrics) + { + Console.WriteLine($"DCG@N: {string.Join(", ", metrics.Dcg.Select(d => Math.Round(d, 2)).ToArray())}"); + Console.WriteLine($"NDCG@N: {string.Join(", ", metrics.Ndcg.Select(d => Math.Round(d, 2)).ToArray())}"); + } } } diff --git a/src/Microsoft.ML.SamplesUtils/SamplesDatasetUtils.cs b/src/Microsoft.ML.SamplesUtils/SamplesDatasetUtils.cs index 79ce680470..b123b604f4 100644 --- a/src/Microsoft.ML.SamplesUtils/SamplesDatasetUtils.cs +++ b/src/Microsoft.ML.SamplesUtils/SamplesDatasetUtils.cs @@ -145,6 +145,57 @@ public static IDataView LoadFeaturizedAdultDataset(MLContext mlContext) return featurizedData; } + public static string DownloadMslrWeb10kTrain() + { + var fileName = "MSLRWeb10KTrain720kRows.tsv"; + if (!File.Exists(fileName)) + Download("https://tlcresources.blob.core.windows.net/datasets/MSLR-WEB10K/MSLR-WEB10K_Fold1.TRAIN.500MB_720k-rows.tsv", fileName); + return fileName; + } + + public static string DownloadMslrWeb10kValidate() + { + var fileName = "MSLRWeb10KValidate240kRows.tsv"; + if (!File.Exists(fileName)) + Download("https://tlcresources.blob.core.windows.net/datasets/MSLR-WEB10K/MSLR-WEB10K_Fold1.VALIDATE.160MB_240k-rows.tsv", fileName); + return fileName; + } + + public static (IDataView, IDataView) LoadFeaturizedMslrWeb10kTrainAndValidate(MLContext mlContext) + { + // Download the training and validation files. + string trainDataFile = DownloadMslrWeb10kTrain(); + string validationDataFile = DownloadMslrWeb10kValidate(); + + // Create the reader to read the data. + var reader = mlContext.Data.CreateTextLoader( + columns: new[] + { + new TextLoader.Column("Label", DataKind.R4, 0), + new TextLoader.Column("GroupId", DataKind.TX, 1), + new TextLoader.Column("Features", DataKind.R4, new[] { new TextLoader.Range(2, 138) }) + } + ); + + // Load the raw training and validation datasets. + var trainData = reader.Read(trainDataFile); + var validationData = reader.Read(validationDataFile); + + // Create the featurization pipeline. First, hash the GroupId column. + var pipeline = mlContext.Transforms.Conversion.Hash("GroupId") + // Replace missing values in Features column with the default replacement value for its type. + .Append(mlContext.Transforms.ReplaceMissingValues("Features")); + + // Fit the pipeline on the training data. + var fittedPipeline = pipeline.Fit(trainData); + + // Use the fitted pipeline to transform the training and validation datasets. + var transformedTrainData = fittedPipeline.Transform(trainData); + var transformedValidationData = fittedPipeline.Transform(validationData); + + return (transformedTrainData, transformedValidationData); + } + /// /// Downloads the breast cancer dataset from the ML.NET repo. /// From 1e1a80399ee5c240d00fc6f5ae53d1f111e8a30c Mon Sep 17 00:00:00 2001 From: "REDMOND\\nakazmi" Date: Fri, 22 Feb 2019 18:19:12 -0800 Subject: [PATCH 20/24] PR feedback + cleaning up namespaces in Microsoft.ML.Samples project --- .../LightGBMBinaryClassification.cs | 24 +++++++------- ...LightGBMBinaryClassificationWithOptions.cs | 24 +++++++------- .../SDCALogisticRegression.cs | 2 +- .../SDCASupportVectorMachine.cs | 2 +- .../SymbolicStochasticGradientDescent.cs | 20 ++++++------ ...licStochasticGradientDescentWithOptions.cs | 21 ++++++------ .../LightGBMMulticlassClassification.cs | 4 +-- ...tGBMMulticlassClassificationWithOptions.cs | 4 +-- .../Trainers/Ranking/LightGBMRanking.cs | 30 ++++++++--------- .../Ranking/LightGBMRankingWithOptions.cs | 27 ++++++++-------- .../Recommendation/MatrixFactorization.cs | 2 +- .../MatrixFactorizationWithOptions.cs | 2 +- .../Trainers/Regression/LightGBMRegression.cs | 16 +++++----- .../LightGBMRegressionWithOptions.cs | 16 +++++----- .../Regression/OrdinaryLeastSquares.cs | 14 ++++---- .../OrdinaryLeastSquaresWithOptions.cs | 14 ++++---- docs/samples/Microsoft.ML.Samples/Program.cs | 2 +- .../Evaluators/Metrics/RankingMetrics.cs | 4 +-- src/Microsoft.ML.SamplesUtils/ConsoleUtils.cs | 14 ++++++-- .../SamplesDatasetUtils.cs | 32 ++++++------------- 20 files changed, 138 insertions(+), 136 deletions(-) diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/LightGBMBinaryClassification.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/LightGBMBinaryClassification.cs index edd4e31504..a6834d0082 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/LightGBMBinaryClassification.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/LightGBMBinaryClassification.cs @@ -1,8 +1,8 @@ using Microsoft.ML.Transforms.Categorical; -namespace Microsoft.ML.Samples.Dynamic +namespace Microsoft.ML.Samples.Dynamic.Trainers.BinaryClassification { - public class LightGbmBinaryClassification + public class LightGbm { // This example requires installation of additional nuget package Microsoft.ML.LightGBM. public static void Example() @@ -17,7 +17,7 @@ public static void Example() var split = mlContext.BinaryClassification.TrainTestSplit(dataview, testFraction: 0.1); // Create the Estimator. - var pipeline = mlContext.BinaryClassification.Trainers.LightGbm("IsOver50K", "Features"); + var pipeline = mlContext.BinaryClassification.Trainers.LightGbm(); // Fit this Pipeline to the Training Data. var model = pipeline.Fit(split.TrainSet); @@ -25,17 +25,17 @@ public static void Example() // Evaluate how the model is doing on the test data. var dataWithPredictions = model.Transform(split.TestSet); - var metrics = mlContext.BinaryClassification.Evaluate(dataWithPredictions, "IsOver50K"); + var metrics = mlContext.BinaryClassification.Evaluate(dataWithPredictions); SamplesUtils.ConsoleUtils.PrintMetrics(metrics); - // Output: - // Accuracy: 0.88 - // AUC: 0.93 - // F1 Score: 0.71 - // Negative Precision: 0.90 - // Negative Recall: 0.94 - // Positive Precision: 0.76 - // Positive Recall: 0.66 + // Expected output: + // Accuracy: 0.88 + // AUC: 0.93 + // F1 Score: 0.71 + // Negative Precision: 0.90 + // Negative Recall: 0.94 + // Positive Precision: 0.76 + // Positive Recall: 0.66 } } } \ No newline at end of file diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/LightGBMBinaryClassificationWithOptions.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/LightGBMBinaryClassificationWithOptions.cs index 904285aaee..7b0e21fed9 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/LightGBMBinaryClassificationWithOptions.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/LightGBMBinaryClassificationWithOptions.cs @@ -1,9 +1,9 @@ using Microsoft.ML.LightGBM; using static Microsoft.ML.LightGBM.Options; -namespace Microsoft.ML.Samples.Dynamic +namespace Microsoft.ML.Samples.Dynamic.Trainers.BinaryClassification { - class LightGbmBinaryClassificationWithOptions + class LightGbmWithOptions { // This example requires installation of additional nuget package Microsoft.ML.LightGBM. public static void Example() @@ -21,8 +21,6 @@ public static void Example() var pipeline = mlContext.BinaryClassification.Trainers.LightGbm( new Options { - LabelColumn = "IsOver50K", - FeatureColumn = "Features", Booster = new GossBooster.Options { TopRate = 0.3, @@ -36,17 +34,17 @@ public static void Example() // Evaluate how the model is doing on the test data. var dataWithPredictions = model.Transform(split.TestSet); - var metrics = mlContext.BinaryClassification.Evaluate(dataWithPredictions, "IsOver50K"); + var metrics = mlContext.BinaryClassification.Evaluate(dataWithPredictions); SamplesUtils.ConsoleUtils.PrintMetrics(metrics); - // Output: - // Accuracy: 0.88 - // AUC: 0.93 - // F1 Score: 0.71 - // Negative Precision: 0.90 - // Negative Recall: 0.94 - // Positive Precision: 0.76 - // Positive Recall: 0.67 + // Expected output: + // Accuracy: 0.88 + // AUC: 0.93 + // F1 Score: 0.71 + // Negative Precision: 0.90 + // Negative Recall: 0.94 + // Positive Precision: 0.76 + // Positive Recall: 0.67 } } } diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/SDCALogisticRegression.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/SDCALogisticRegression.cs index 44a7a77534..0b5347ebc0 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/SDCALogisticRegression.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/SDCALogisticRegression.cs @@ -3,7 +3,7 @@ using Microsoft.ML.Data; using Microsoft.ML.Trainers; -namespace Microsoft.ML.Samples.Dynamic +namespace Microsoft.ML.Samples.Dynamic.Trainers.BinaryClassification { public static class SDCALogisticRegression { diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/SDCASupportVectorMachine.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/SDCASupportVectorMachine.cs index eede7b03cb..472e7390a8 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/SDCASupportVectorMachine.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/SDCASupportVectorMachine.cs @@ -2,7 +2,7 @@ using System.Linq; using Microsoft.ML.Data; -namespace Microsoft.ML.Samples.Dynamic +namespace Microsoft.ML.Samples.Dynamic.Trainers.BinaryClassification { public static class SDCASupportVectorMachine { diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/SymbolicStochasticGradientDescent.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/SymbolicStochasticGradientDescent.cs index c0687d6ee7..2b69730004 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/SymbolicStochasticGradientDescent.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/SymbolicStochasticGradientDescent.cs @@ -1,4 +1,4 @@ -namespace Microsoft.ML.Samples.Dynamic +namespace Microsoft.ML.Samples.Dynamic.Trainers.BinaryClassification { public static class SymbolicStochasticGradientDescent { @@ -24,15 +24,17 @@ public static void Example() // Evaluate how the model is doing on the test data. var dataWithPredictions = model.Transform(split.TestSet); - var metrics = mlContext.BinaryClassification.EvaluateNonCalibrated(dataWithPredictions, "IsOver50K"); + var metrics = mlContext.BinaryClassification.EvaluateNonCalibrated(dataWithPredictions); SamplesUtils.ConsoleUtils.PrintMetrics(metrics); - // Accuracy: 0.85 - // AUC: 0.90 - // F1 Score: 0.64 - // Negative Precision: 0.88 - // Negative Recall: 0.93 - // Positive Precision: 0.72 - // Positive Recall: 0.58 + + // Expected output: + // Accuracy: 0.85 + // AUC: 0.90 + // F1 Score: 0.64 + // Negative Precision: 0.88 + // Negative Recall: 0.93 + // Positive Precision: 0.72 + // Positive Recall: 0.58 } } } diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/SymbolicStochasticGradientDescentWithOptions.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/SymbolicStochasticGradientDescentWithOptions.cs index 9dd4f50c87..f547cd9712 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/SymbolicStochasticGradientDescentWithOptions.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/BinaryClassification/SymbolicStochasticGradientDescentWithOptions.cs @@ -1,4 +1,4 @@ -namespace Microsoft.ML.Samples.Dynamic +namespace Microsoft.ML.Samples.Dynamic.Trainers.BinaryClassification { public static class SymbolicStochasticGradientDescentWithOptions { @@ -22,7 +22,6 @@ public static void Example() var pipeline = mlContext.BinaryClassification.Trainers.SymbolicStochasticGradientDescent( new ML.Trainers.HalLearners.SymSgdClassificationTrainer.Options() { - LabelColumn = "IsOver50K", LearningRate = 0.2f, NumberOfIterations = 10, NumberOfThreads = 1, @@ -33,15 +32,17 @@ public static void Example() // Evaluate how the model is doing on the test data. var dataWithPredictions = model.Transform(split.TestSet); - var metrics = mlContext.BinaryClassification.EvaluateNonCalibrated(dataWithPredictions, "IsOver50K"); + var metrics = mlContext.BinaryClassification.EvaluateNonCalibrated(dataWithPredictions); SamplesUtils.ConsoleUtils.PrintMetrics(metrics); - // Accuracy: 0.84 - // AUC: 0.88 - // F1 Score: 0.60 - // Negative Precision: 0.87 - // Negative Recall: 0.93 - // Positive Precision: 0.69 - // Positive Recall: 0.53 + + // Expected output: + // Accuracy: 0.84 + // AUC: 0.88 + // F1 Score: 0.60 + // Negative Precision: 0.87 + // Negative Recall: 0.93 + // Positive Precision: 0.69 + // Positive Recall: 0.53 } } } diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/MulticlassClassification/LightGBMMulticlassClassification.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/MulticlassClassification/LightGBMMulticlassClassification.cs index 5c6ee5ad5f..f6f7b0d067 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/MulticlassClassification/LightGBMMulticlassClassification.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/MulticlassClassification/LightGBMMulticlassClassification.cs @@ -3,9 +3,9 @@ using Microsoft.ML.Data; using Microsoft.ML.SamplesUtils; -namespace Microsoft.ML.Samples.Dynamic +namespace Microsoft.ML.Samples.Dynamic.Trainers.MulticlassClassification { - class LightGbmMulticlassClassification + class LightGbm { // This example requires installation of additional nuget package Microsoft.ML.LightGBM. public static void Example() diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/MulticlassClassification/LightGBMMulticlassClassificationWithOptions.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/MulticlassClassification/LightGBMMulticlassClassificationWithOptions.cs index 7d98c9318e..36de9b8fe1 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/MulticlassClassification/LightGBMMulticlassClassificationWithOptions.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/MulticlassClassification/LightGBMMulticlassClassificationWithOptions.cs @@ -5,9 +5,9 @@ using Microsoft.ML.SamplesUtils; using static Microsoft.ML.LightGBM.Options; -namespace Microsoft.ML.Samples.Dynamic +namespace Microsoft.ML.Samples.Dynamic.Trainers.MulticlassClassification { - class LightGbmMulticlassClassificationWithOptions + class LightGbmWithOptions { // This example requires installation of additional nuget package Microsoft.ML.LightGBM. public static void Example() diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Ranking/LightGBMRanking.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Ranking/LightGBMRanking.cs index 8822a16630..b5857e4538 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Ranking/LightGBMRanking.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Ranking/LightGBMRanking.cs @@ -1,10 +1,8 @@ -using System; -using System.Collections.Generic; -using System.Text; +using Microsoft.ML; -namespace Microsoft.ML.Samples.Dynamic +namespace Microsoft.ML.Samples.Dynamic.Trainers.Ranking { - public class LightGbmRanking + public class LightGbm { // This example requires installation of additional nuget package Microsoft.ML.LightGBM. public static void Example() @@ -12,31 +10,33 @@ public static void Example() // Creating the ML.Net IHostEnvironment object, needed for the pipeline. var mlContext = new MLContext(); - // Download and featurize the train and validation datasets. - (var trainData, var validationData) = SamplesUtils.DatasetUtils.LoadFeaturizedMslrWeb10kTrainAndValidate(mlContext); + // Download and featurize the dataset. + var dataview = SamplesUtils.DatasetUtils.LoadFeaturizedMslrWeb10kDataset(mlContext); + + // Leave out 10% of the dataset for testing. Since this is a ranking problem, we must ensure that the split + // respects the GroupId column, i.e. rows with the same GroupId are either all in the train split or all in + // the test split. The samplingKeyColumn parameter in Ranking.TrainTestSplit is used for this purpose. + var split = mlContext.Ranking.TrainTestSplit(dataview, testFraction: 0.1, samplingKeyColumn: "GroupId"); // Create the Estimator pipeline. For simplicity, we will train a small tree with 4 leaves and 2 boosting iterations. var pipeline = mlContext.Ranking.Trainers.LightGbm( - labelColumn: "Label", - featureColumn: "Features", - groupIdColumn: "GroupId", numLeaves: 4, minDataPerLeaf: 10, learningRate: 0.1, numBoostRound: 2); // Fit this Pipeline to the Training Data. - var model = pipeline.Fit(trainData); + var model = pipeline.Fit(split.TrainSet); // Evaluate how the model is doing on the test data. - var dataWithPredictions = model.Transform(validationData); + var dataWithPredictions = model.Transform(split.TestSet); var metrics = mlContext.Ranking.Evaluate(dataWithPredictions, "Label", "GroupId"); SamplesUtils.ConsoleUtils.PrintMetrics(metrics); - // Output: - // DCG @N: 1.38, 3.11, 4.94 - // NDCG @N: 7.13, 10.12, 12.62 + // Expected output: + // DCG: @1:1.25, @2:2.69, @3:4.57 + // NDCG: @1:7.01, @2:9.57, @3:12.34 } } } diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Ranking/LightGBMRankingWithOptions.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Ranking/LightGBMRankingWithOptions.cs index d8f3da41ea..30087131d8 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Ranking/LightGBMRankingWithOptions.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Ranking/LightGBMRankingWithOptions.cs @@ -1,9 +1,8 @@ using Microsoft.ML.LightGBM; -using static Microsoft.ML.LightGBM.Options; -namespace Microsoft.ML.Samples.Dynamic +namespace Microsoft.ML.Samples.Dynamic.Trainers.Ranking { - public class LightGbmRankingWithOptions + public class LightGbmWithOptions { // This example requires installation of additional nuget package Microsoft.ML.LightGBM. public static void Example() @@ -12,33 +11,35 @@ public static void Example() var mlContext = new MLContext(); // Download and featurize the train and validation datasets. - (var trainData, var validationData) = SamplesUtils.DatasetUtils.LoadFeaturizedMslrWeb10kTrainAndValidate(mlContext); + var dataview = SamplesUtils.DatasetUtils.LoadFeaturizedMslrWeb10kDataset(mlContext); + + // Leave out 10% of the dataset for testing. Since this is a ranking problem, we must ensure that the split + // respects the GroupId column, i.e. rows with the same GroupId are either all in the train split or all in + // the test split. The samplingKeyColumn parameter in Ranking.TrainTestSplit is used for this purpose. + var split = mlContext.Ranking.TrainTestSplit(dataview, testFraction: 0.1, samplingKeyColumn: "GroupId"); // Create the Estimator pipeline. For simplicity, we will train a small tree with 4 leaves and 2 boosting iterations. var pipeline = mlContext.Ranking.Trainers.LightGbm( new Options { - LabelColumn = "Label", - FeatureColumn = "Features", - GroupIdColumn = "GroupId", NumLeaves = 4, MinDataPerLeaf = 10, LearningRate = 0.1, NumBoostRound = 2 }); - // Fit this Pipeline to the Training Data. - var model = pipeline.Fit(trainData); + // Fit this pipeline to the training Data. + var model = pipeline.Fit(split.TrainSet); // Evaluate how the model is doing on the test data. - var dataWithPredictions = model.Transform(validationData); + var dataWithPredictions = model.Transform(split.TestSet); var metrics = mlContext.Ranking.Evaluate(dataWithPredictions, "Label", "GroupId"); SamplesUtils.ConsoleUtils.PrintMetrics(metrics); - // Output: - // DCG @N: 1.38, 3.11, 4.94 - // NDCG @N: 7.13, 10.12, 12.62 + // Expected output: + // DCG: @1:1.25, @2:2.69, @3:4.57 + // NDCG: @1:7.01, @2:9.57, @3:12.34 } } } diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Recommendation/MatrixFactorization.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Recommendation/MatrixFactorization.cs index d252eb489d..3737e751d5 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Recommendation/MatrixFactorization.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Recommendation/MatrixFactorization.cs @@ -3,7 +3,7 @@ using Microsoft.ML.Data; using static Microsoft.ML.SamplesUtils.DatasetUtils; -namespace Microsoft.ML.Samples.Dynamic +namespace Microsoft.ML.Samples.Dynamic.Trainers.Recommendation { public static class MatrixFactorization { diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Recommendation/MatrixFactorizationWithOptions.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Recommendation/MatrixFactorizationWithOptions.cs index c73fd7fbcb..cbb11938a0 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Recommendation/MatrixFactorizationWithOptions.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Recommendation/MatrixFactorizationWithOptions.cs @@ -4,7 +4,7 @@ using Microsoft.ML.Trainers; using static Microsoft.ML.SamplesUtils.DatasetUtils; -namespace Microsoft.ML.Samples.Dynamic +namespace Microsoft.ML.Samples.Dynamic.Trainers.Recommendation { public static class MatrixFactorizationWithOptions { diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Regression/LightGBMRegression.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Regression/LightGBMRegression.cs index d67da241c9..ce9e27a0fc 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Regression/LightGBMRegression.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Regression/LightGBMRegression.cs @@ -2,9 +2,9 @@ using System.Linq; using Microsoft.ML.Data; -namespace Microsoft.ML.Samples.Dynamic +namespace Microsoft.ML.Samples.Dynamic.Trainers.Regression { - class LightGbmRegression + class LightGbm { // This example requires installation of additional nuget package Microsoft.ML.LightGBM. public static void Example() @@ -54,12 +54,12 @@ public static void Example() var metrics = mlContext.Regression.Evaluate(dataWithPredictions, label: labelName); SamplesUtils.ConsoleUtils.PrintMetrics(metrics); - // Output - // L1: 4.97 - // L2: 51.37 - // LossFunction: 51.37 - // RMS: 7.17 - // RSquared: 0.08 + // Expected output + // L1: 4.97 + // L2: 51.37 + // LossFunction: 51.37 + // RMS: 7.17 + // RSquared: 0.08 } } } diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Regression/LightGBMRegressionWithOptions.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Regression/LightGBMRegressionWithOptions.cs index 3f73df053e..c1c82a9735 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Regression/LightGBMRegressionWithOptions.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Regression/LightGBMRegressionWithOptions.cs @@ -4,9 +4,9 @@ using Microsoft.ML.LightGBM; using static Microsoft.ML.LightGBM.Options; -namespace Microsoft.ML.Samples.Dynamic +namespace Microsoft.ML.Samples.Dynamic.Trainers.Regression { - class LightGbmRegressionWithOptions + class LightGbmWithOptions { // This example requires installation of additional nuget package Microsoft.ML.LightGBM. public static void Example() @@ -64,12 +64,12 @@ public static void Example() var metrics = mlContext.Regression.Evaluate(dataWithPredictions, label: labelName); SamplesUtils.ConsoleUtils.PrintMetrics(metrics); - // Output - // L1: 4.97 - // L2: 51.37 - // LossFunction: 51.37 - // RMS: 7.17 - // RSquared: 0.08 + // Expected output + // L1: 4.97 + // L2: 51.37 + // LossFunction: 51.37 + // RMS: 7.17 + // RSquared: 0.08 } } } diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Regression/OrdinaryLeastSquares.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Regression/OrdinaryLeastSquares.cs index 003962c5bc..0e75693547 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Regression/OrdinaryLeastSquares.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Regression/OrdinaryLeastSquares.cs @@ -2,7 +2,7 @@ using Microsoft.ML.Data; using Microsoft.ML.SamplesUtils; -namespace Microsoft.ML.Samples.Dynamic +namespace Microsoft.ML.Samples.Dynamic.Trainers.Regression { public static class OrdinaryLeastSquares { @@ -55,11 +55,13 @@ public static void Example() var metrics = mlContext.Regression.Evaluate(dataWithPredictions); ConsoleUtils.PrintMetrics(metrics); - // L1: 4.15 - // L2: 31.98 - // LossFunction: 31.98 - // RMS: 5.65 - // RSquared: 0.56 + + // Expected output: + // L1: 4.15 + // L2: 31.98 + // LossFunction: 31.98 + // RMS: 5.65 + // RSquared: 0.56 } } } diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Regression/OrdinaryLeastSquaresWithOptions.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Regression/OrdinaryLeastSquaresWithOptions.cs index 21a6a9e1ae..6cc982b277 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Regression/OrdinaryLeastSquaresWithOptions.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Regression/OrdinaryLeastSquaresWithOptions.cs @@ -3,7 +3,7 @@ using Microsoft.ML.SamplesUtils; using Microsoft.ML.Trainers.HalLearners; -namespace Microsoft.ML.Samples.Dynamic +namespace Microsoft.ML.Samples.Dynamic.Trainers.Regression { public static class OrdinaryLeastSquaresWithOptions { @@ -59,11 +59,13 @@ public static void Example() var metrics = mlContext.Regression.Evaluate(dataWithPredictions); ConsoleUtils.PrintMetrics(metrics); - // L1: 4.14 - // L2: 32.35 - // LossFunction: 32.35 - // RMS: 5.69 - // RSquared: 0.56 + + // Expected output: + // L1: 4.14 + // L2: 32.35 + // LossFunction: 32.35 + // RMS: 5.69 + // RSquared: 0.56 } } } diff --git a/docs/samples/Microsoft.ML.Samples/Program.cs b/docs/samples/Microsoft.ML.Samples/Program.cs index 6fa4e40705..d28cdd4d77 100644 --- a/docs/samples/Microsoft.ML.Samples/Program.cs +++ b/docs/samples/Microsoft.ML.Samples/Program.cs @@ -6,7 +6,7 @@ internal static class Program { static void Main(string[] args) { - LightGbmRanking.Example(); + TakeRows.Example(); } } } diff --git a/src/Microsoft.ML.Data/Evaluators/Metrics/RankingMetrics.cs b/src/Microsoft.ML.Data/Evaluators/Metrics/RankingMetrics.cs index 82513280da..8c64adc842 100644 --- a/src/Microsoft.ML.Data/Evaluators/Metrics/RankingMetrics.cs +++ b/src/Microsoft.ML.Data/Evaluators/Metrics/RankingMetrics.cs @@ -15,10 +15,10 @@ public sealed class RankingMetrics public double[] Ndcg { get; } /// - ///Array of discounted cumulative gains where i-th element represent DCG@i. + /// Array of discounted cumulative gains where i-th element represent DCG@i. /// Discounted Cumulative gain /// is the sum of the gains, for all the instances i, normalized by the natural logarithm of the instance + 1. - /// Note that unlike the Wikipedia article, ML.Net uses the natural logarithm. + /// Note that unlike the Wikipedia article, ML.NET uses the natural logarithm. /// /// public double[] Dcg { get; } diff --git a/src/Microsoft.ML.SamplesUtils/ConsoleUtils.cs b/src/Microsoft.ML.SamplesUtils/ConsoleUtils.cs index 40407fe142..5c581c6856 100644 --- a/src/Microsoft.ML.SamplesUtils/ConsoleUtils.cs +++ b/src/Microsoft.ML.SamplesUtils/ConsoleUtils.cs @@ -55,8 +55,18 @@ public static void PrintMetrics(RegressionMetrics metrics) /// Ranker metrics. public static void PrintMetrics(RankerMetrics metrics) { - Console.WriteLine($"DCG@N: {string.Join(", ", metrics.Dcg.Select(d => Math.Round(d, 2)).ToArray())}"); - Console.WriteLine($"NDCG@N: {string.Join(", ", metrics.Ndcg.Select(d => Math.Round(d, 2)).ToArray())}"); + Console.WriteLine($"DCG: {string.Join(", ", RoundAndBeautifyRankerMetrics(metrics.Dcg))}"); + Console.WriteLine($"NDCG: {string.Join(", ", RoundAndBeautifyRankerMetrics(metrics.Ndcg))}"); + } + + private static string[] RoundAndBeautifyRankerMetrics(double[] input) + { + string[] result = input.Select(d => Math.Round(d, 2).ToString()).ToArray(); + for (int i = 0; i < result.Length; i++) + { + result[i] = $"@{(i + 1).ToString()}:{result[i]}"; + } + return result; } } } diff --git a/src/Microsoft.ML.SamplesUtils/SamplesDatasetUtils.cs b/src/Microsoft.ML.SamplesUtils/SamplesDatasetUtils.cs index b123b604f4..86e8b61ebe 100644 --- a/src/Microsoft.ML.SamplesUtils/SamplesDatasetUtils.cs +++ b/src/Microsoft.ML.SamplesUtils/SamplesDatasetUtils.cs @@ -137,7 +137,7 @@ public static IDataView LoadFeaturizedAdultDataset(MLContext mlContext) .Append(mlContext.Transforms.Concatenate("Features", "workclass", "education", "marital-status", "occupation", "relationship", "ethnicity", "native-country", "age", "education-num", "capital-gain", "capital-loss", "hours-per-week")) - // Min-max normalized all the features + // Min-max normalize all the features .Append(mlContext.Transforms.Normalize("Features")); var data = reader.Read(dataFile); @@ -145,7 +145,7 @@ public static IDataView LoadFeaturizedAdultDataset(MLContext mlContext) return featurizedData; } - public static string DownloadMslrWeb10kTrain() + public static string DownloadMslrWeb10k() { var fileName = "MSLRWeb10KTrain720kRows.tsv"; if (!File.Exists(fileName)) @@ -153,19 +153,10 @@ public static string DownloadMslrWeb10kTrain() return fileName; } - public static string DownloadMslrWeb10kValidate() - { - var fileName = "MSLRWeb10KValidate240kRows.tsv"; - if (!File.Exists(fileName)) - Download("https://tlcresources.blob.core.windows.net/datasets/MSLR-WEB10K/MSLR-WEB10K_Fold1.VALIDATE.160MB_240k-rows.tsv", fileName); - return fileName; - } - - public static (IDataView, IDataView) LoadFeaturizedMslrWeb10kTrainAndValidate(MLContext mlContext) + public static IDataView LoadFeaturizedMslrWeb10kDataset(MLContext mlContext) { // Download the training and validation files. - string trainDataFile = DownloadMslrWeb10kTrain(); - string validationDataFile = DownloadMslrWeb10kValidate(); + string dataFile = DownloadMslrWeb10k(); // Create the reader to read the data. var reader = mlContext.Data.CreateTextLoader( @@ -177,23 +168,18 @@ public static (IDataView, IDataView) LoadFeaturizedMslrWeb10kTrainAndValidate(ML } ); - // Load the raw training and validation datasets. - var trainData = reader.Read(trainDataFile); - var validationData = reader.Read(validationDataFile); + // Load the raw dataset. + var data = reader.Read(dataFile); // Create the featurization pipeline. First, hash the GroupId column. var pipeline = mlContext.Transforms.Conversion.Hash("GroupId") // Replace missing values in Features column with the default replacement value for its type. .Append(mlContext.Transforms.ReplaceMissingValues("Features")); - // Fit the pipeline on the training data. - var fittedPipeline = pipeline.Fit(trainData); - - // Use the fitted pipeline to transform the training and validation datasets. - var transformedTrainData = fittedPipeline.Transform(trainData); - var transformedValidationData = fittedPipeline.Transform(validationData); + // Fit the pipeline and transform the dataset. + var transformedData = pipeline.Fit(data).Transform(data); - return (transformedTrainData, transformedValidationData); + return transformedData; } /// From 345cf60448caf4f0682798dbe4318de74c489c4e Mon Sep 17 00:00:00 2001 From: "REDMOND\\nakazmi" Date: Tue, 19 Feb 2019 23:19:02 -0800 Subject: [PATCH 21/24] Adding a sample for LightGbm Ranking --- docs/samples/Microsoft.ML.Samples/Program.cs | 2 +- src/Microsoft.ML.SamplesUtils/ConsoleUtils.cs | 2 +- src/Microsoft.ML.SamplesUtils/SamplesDatasetUtils.cs | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/samples/Microsoft.ML.Samples/Program.cs b/docs/samples/Microsoft.ML.Samples/Program.cs index d28cdd4d77..6fa4e40705 100644 --- a/docs/samples/Microsoft.ML.Samples/Program.cs +++ b/docs/samples/Microsoft.ML.Samples/Program.cs @@ -6,7 +6,7 @@ internal static class Program { static void Main(string[] args) { - TakeRows.Example(); + LightGbmRanking.Example(); } } } diff --git a/src/Microsoft.ML.SamplesUtils/ConsoleUtils.cs b/src/Microsoft.ML.SamplesUtils/ConsoleUtils.cs index 5c581c6856..040d765b9b 100644 --- a/src/Microsoft.ML.SamplesUtils/ConsoleUtils.cs +++ b/src/Microsoft.ML.SamplesUtils/ConsoleUtils.cs @@ -53,7 +53,7 @@ public static void PrintMetrics(RegressionMetrics metrics) /// Pretty-print RankerMetrics objects. /// /// Ranker metrics. - public static void PrintMetrics(RankerMetrics metrics) + public static void PrintMetrics(RankingMetrics metrics) { Console.WriteLine($"DCG: {string.Join(", ", RoundAndBeautifyRankerMetrics(metrics.Dcg))}"); Console.WriteLine($"NDCG: {string.Join(", ", RoundAndBeautifyRankerMetrics(metrics.Ndcg))}"); diff --git a/src/Microsoft.ML.SamplesUtils/SamplesDatasetUtils.cs b/src/Microsoft.ML.SamplesUtils/SamplesDatasetUtils.cs index 86e8b61ebe..f09e9ad779 100644 --- a/src/Microsoft.ML.SamplesUtils/SamplesDatasetUtils.cs +++ b/src/Microsoft.ML.SamplesUtils/SamplesDatasetUtils.cs @@ -162,9 +162,9 @@ public static IDataView LoadFeaturizedMslrWeb10kDataset(MLContext mlContext) var reader = mlContext.Data.CreateTextLoader( columns: new[] { - new TextLoader.Column("Label", DataKind.R4, 0), - new TextLoader.Column("GroupId", DataKind.TX, 1), - new TextLoader.Column("Features", DataKind.R4, new[] { new TextLoader.Range(2, 138) }) + new TextLoader.Column("Label", DataKind.Single, 0), + new TextLoader.Column("GroupId", DataKind.String, 1), + new TextLoader.Column("Features", DataKind.Single, new[] { new TextLoader.Range(2, 138) }) } ); From c25a3c33869efb34236bcd65d155fc50ffc798d2 Mon Sep 17 00:00:00 2001 From: "REDMOND\\nakazmi" Date: Fri, 22 Feb 2019 18:19:12 -0800 Subject: [PATCH 22/24] PR feedback + cleaning up namespaces in Microsoft.ML.Samples project --- docs/samples/Microsoft.ML.Samples/Program.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/samples/Microsoft.ML.Samples/Program.cs b/docs/samples/Microsoft.ML.Samples/Program.cs index 6fa4e40705..d28cdd4d77 100644 --- a/docs/samples/Microsoft.ML.Samples/Program.cs +++ b/docs/samples/Microsoft.ML.Samples/Program.cs @@ -6,7 +6,7 @@ internal static class Program { static void Main(string[] args) { - LightGbmRanking.Example(); + TakeRows.Example(); } } } From 34ecd4a6dfe71b168cca8e0836afe4fe6ca8cf55 Mon Sep 17 00:00:00 2001 From: "REDMOND\\nakazmi" Date: Fri, 22 Feb 2019 19:32:08 -0800 Subject: [PATCH 23/24] nit --- .../Dynamic/Trainers/Ranking/LightGBMRanking.cs | 2 +- .../Dynamic/Trainers/Ranking/LightGBMRankingWithOptions.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Ranking/LightGBMRanking.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Ranking/LightGBMRanking.cs index b5857e4538..eccf87af8c 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Ranking/LightGBMRanking.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Ranking/LightGBMRanking.cs @@ -31,7 +31,7 @@ public static void Example() // Evaluate how the model is doing on the test data. var dataWithPredictions = model.Transform(split.TestSet); - var metrics = mlContext.Ranking.Evaluate(dataWithPredictions, "Label", "GroupId"); + var metrics = mlContext.Ranking.Evaluate(dataWithPredictions); SamplesUtils.ConsoleUtils.PrintMetrics(metrics); // Expected output: diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Ranking/LightGBMRankingWithOptions.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Ranking/LightGBMRankingWithOptions.cs index 30087131d8..c142881716 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Ranking/LightGBMRankingWithOptions.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Ranking/LightGBMRankingWithOptions.cs @@ -34,7 +34,7 @@ public static void Example() // Evaluate how the model is doing on the test data. var dataWithPredictions = model.Transform(split.TestSet); - var metrics = mlContext.Ranking.Evaluate(dataWithPredictions, "Label", "GroupId"); + var metrics = mlContext.Ranking.Evaluate(dataWithPredictions); SamplesUtils.ConsoleUtils.PrintMetrics(metrics); // Expected output: From 1c99a4f9e0df8ee2ea97a482f40c1927b9513b97 Mon Sep 17 00:00:00 2001 From: "REDMOND\\nakazmi" Date: Mon, 25 Feb 2019 17:02:38 -0800 Subject: [PATCH 24/24] Changing dataset to small sample and other feedback --- .../Dynamic/Trainers/Ranking/LightGBMRanking.cs | 4 ++-- .../Ranking/LightGBMRankingWithOptions.cs | 15 +++++++++++---- .../SamplesDatasetUtils.cs | 4 ++-- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Ranking/LightGBMRanking.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Ranking/LightGBMRanking.cs index eccf87af8c..c3bd9d604e 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Ranking/LightGBMRanking.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Ranking/LightGBMRanking.cs @@ -35,8 +35,8 @@ public static void Example() SamplesUtils.ConsoleUtils.PrintMetrics(metrics); // Expected output: - // DCG: @1:1.25, @2:2.69, @3:4.57 - // NDCG: @1:7.01, @2:9.57, @3:12.34 + // DCG: @1:1.71, @2:3.88, @3:7.93 + // NDCG: @1:7.98, @2:12.14, @3:16.62 } } } diff --git a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Ranking/LightGBMRankingWithOptions.cs b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Ranking/LightGBMRankingWithOptions.cs index c142881716..ccacec1b58 100644 --- a/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Ranking/LightGBMRankingWithOptions.cs +++ b/docs/samples/Microsoft.ML.Samples/Dynamic/Trainers/Ranking/LightGBMRankingWithOptions.cs @@ -1,4 +1,5 @@ using Microsoft.ML.LightGBM; +using static Microsoft.ML.LightGBM.Options; namespace Microsoft.ML.Samples.Dynamic.Trainers.Ranking { @@ -25,7 +26,11 @@ public static void Example() NumLeaves = 4, MinDataPerLeaf = 10, LearningRate = 0.1, - NumBoostRound = 2 + NumBoostRound = 2, + Booster = new TreeBooster.Options + { + FeatureFraction = 0.9 + } }); // Fit this pipeline to the training Data. @@ -37,9 +42,11 @@ public static void Example() var metrics = mlContext.Ranking.Evaluate(dataWithPredictions); SamplesUtils.ConsoleUtils.PrintMetrics(metrics); - // Expected output: - // DCG: @1:1.25, @2:2.69, @3:4.57 - // NDCG: @1:7.01, @2:9.57, @3:12.34 + // NOTE: + // + // This sample is currently broken due to a bug in setting the GroupId column in LightGbm when using Options. + // + // Please follow GitHub issue 2652 to be notified of a fix: https://github.com/dotnet/machinelearning/issues/2652 } } } diff --git a/src/Microsoft.ML.SamplesUtils/SamplesDatasetUtils.cs b/src/Microsoft.ML.SamplesUtils/SamplesDatasetUtils.cs index f09e9ad779..cddba0238e 100644 --- a/src/Microsoft.ML.SamplesUtils/SamplesDatasetUtils.cs +++ b/src/Microsoft.ML.SamplesUtils/SamplesDatasetUtils.cs @@ -147,9 +147,9 @@ public static IDataView LoadFeaturizedAdultDataset(MLContext mlContext) public static string DownloadMslrWeb10k() { - var fileName = "MSLRWeb10KTrain720kRows.tsv"; + var fileName = "MSLRWeb10KTrain10kRows.tsv"; if (!File.Exists(fileName)) - Download("https://tlcresources.blob.core.windows.net/datasets/MSLR-WEB10K/MSLR-WEB10K_Fold1.TRAIN.500MB_720k-rows.tsv", fileName); + Download("https://tlcresources.blob.core.windows.net/datasets/MSLR-WEB10K/MSLR-WEB10K%2BFold1.TRAIN.SMALL_10k-rows.tsv", fileName); return fileName; }