File-scoped namespaces in files under `Prediction` (`Microsoft.ML.Core`) (#6792)

Co-authored-by: Lehonti Ramos <john@doe>
This commit is contained in:
Lehonti Ramos 2023-09-01 05:36:33 +02:00 коммит произвёл GitHub
Родитель e6a88c440b
Коммит ccf34e370b
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
5 изменённых файлов: 401 добавлений и 406 удалений

Просмотреть файл

@ -2,62 +2,61 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace Microsoft.ML
namespace Microsoft.ML;
/// <summary>
/// Type of prediction task. Note that this is a legacy structure and usage of this should generally be
/// discouraged in future projects. Its presence suggests that there are privileged and supported
/// tasks, and anything outside of this is unsupported. This runs rather contrary to the idea of this
/// being an expandable framework, and it is inappropriately limiting. For legacy pipelines based on
/// <see cref="ITrainer"/> and <see cref="IPredictor"/> it is still useful, but for things based on
/// the <see cref="IEstimator{TTransformer}"/> idiom, it is inappropriate.
/// </summary>
[BestFriend]
internal enum PredictionKind
{
Unknown = 0,
Custom = 1,
BinaryClassification = 2,
MulticlassClassification = 3,
Regression = 4,
MultiOutputRegression = 5,
Ranking = 6,
Recommendation = 7,
AnomalyDetection = 8,
Clustering = 9,
SequenceClassification = 10,
// More to be added later.
}
/// <summary>
/// Weakly typed version of IPredictor.
/// </summary>
[BestFriend]
internal interface IPredictor
{
/// <summary>
/// Type of prediction task. Note that this is a legacy structure and usage of this should generally be
/// discouraged in future projects. Its presence suggests that there are privileged and supported
/// tasks, and anything outside of this is unsupported. This runs rather contrary to the idea of this
/// being an expandable framework, and it is inappropriately limiting. For legacy pipelines based on
/// <see cref="ITrainer"/> and <see cref="IPredictor"/> it is still useful, but for things based on
/// the <see cref="IEstimator{TTransformer}"/> idiom, it is inappropriate.
/// Return the type of prediction task.
/// </summary>
[BestFriend]
internal enum PredictionKind
{
Unknown = 0,
Custom = 1,
BinaryClassification = 2,
MulticlassClassification = 3,
Regression = 4,
MultiOutputRegression = 5,
Ranking = 6,
Recommendation = 7,
AnomalyDetection = 8,
Clustering = 9,
SequenceClassification = 10,
// More to be added later.
}
/// <summary>
/// Weakly typed version of IPredictor.
/// </summary>
[BestFriend]
internal interface IPredictor
{
/// <summary>
/// Return the type of prediction task.
/// </summary>
PredictionKind PredictionKind { get; }
}
/// <summary>
/// A predictor the produces values of the indicated type.
/// REVIEW: Determine whether this is just a temporary shim or long term solution.
/// </summary>
[BestFriend]
internal interface IPredictorProducing<out TResult> : IPredictor
{
}
/// <summary>
/// A predictor that produces values and distributions of the indicated types.
/// Note that from a public API perspective this is bad.
/// </summary>
[BestFriend]
internal interface IDistPredictorProducing<out TResult, out TResultDistribution> : IPredictorProducing<TResult>
{
}
PredictionKind PredictionKind { get; }
}
/// <summary>
/// A predictor the produces values of the indicated type.
/// REVIEW: Determine whether this is just a temporary shim or long term solution.
/// </summary>
[BestFriend]
internal interface IPredictorProducing<out TResult> : IPredictor
{
}
/// <summary>
/// A predictor that produces values and distributions of the indicated types.
/// Note that from a public API perspective this is bad.
/// </summary>
[BestFriend]
internal interface IDistPredictorProducing<out TResult, out TResultDistribution> : IPredictorProducing<TResult>
{
}

Просмотреть файл

@ -4,104 +4,103 @@
using Microsoft.ML.Data;
namespace Microsoft.ML
namespace Microsoft.ML;
// REVIEW: Would be nice if the registration under SignatureTrainer were automatic
// given registration for one of the "sub-class" signatures.
/// <summary>
/// Loadable class signatures for trainers. Typically each trainer should register with
/// both SignatureTrainer and SignatureXxxTrainer where Xxx is the prediction kind.
/// </summary>
[BestFriend]
internal delegate void SignatureTrainer();
[BestFriend]
internal delegate void SignatureBinaryClassifierTrainer();
[BestFriend]
internal delegate void SignatureMulticlassClassifierTrainer();
[BestFriend]
internal delegate void SignatureRegressorTrainer();
[BestFriend]
internal delegate void SignatureMultiOutputRegressorTrainer();
[BestFriend]
internal delegate void SignatureRankerTrainer();
[BestFriend]
internal delegate void SignatureAnomalyDetectorTrainer();
[BestFriend]
internal delegate void SignatureClusteringTrainer();
[BestFriend]
internal delegate void SignatureSequenceTrainer();
[BestFriend]
internal delegate void SignatureMatrixRecommendingTrainer();
/// <summary>
/// The base interface for a trainers. Implementors should not implement this interface directly,
/// but rather implement the more specific <see cref="ITrainer{TPredictor}"/>.
/// </summary>
[BestFriend]
internal interface ITrainer
{
// REVIEW: Would be nice if the registration under SignatureTrainer were automatic
// given registration for one of the "sub-class" signatures.
/// <summary>
/// Auxiliary information about the trainer in terms of its capabilities
/// and requirements.
/// </summary>
TrainerInfo Info { get; }
/// <summary>
/// Loadable class signatures for trainers. Typically each trainer should register with
/// both SignatureTrainer and SignatureXxxTrainer where Xxx is the prediction kind.
/// Return the type of prediction task for the produced predictor.
/// </summary>
[BestFriend]
internal delegate void SignatureTrainer();
[BestFriend]
internal delegate void SignatureBinaryClassifierTrainer();
[BestFriend]
internal delegate void SignatureMulticlassClassifierTrainer();
[BestFriend]
internal delegate void SignatureRegressorTrainer();
[BestFriend]
internal delegate void SignatureMultiOutputRegressorTrainer();
[BestFriend]
internal delegate void SignatureRankerTrainer();
[BestFriend]
internal delegate void SignatureAnomalyDetectorTrainer();
[BestFriend]
internal delegate void SignatureClusteringTrainer();
[BestFriend]
internal delegate void SignatureSequenceTrainer();
[BestFriend]
internal delegate void SignatureMatrixRecommendingTrainer();
PredictionKind PredictionKind { get; }
/// <summary>
/// The base interface for a trainers. Implementors should not implement this interface directly,
/// but rather implement the more specific <see cref="ITrainer{TPredictor}"/>.
/// Trains a predictor.
/// </summary>
[BestFriend]
internal interface ITrainer
{
/// <summary>
/// Auxiliary information about the trainer in terms of its capabilities
/// and requirements.
/// </summary>
TrainerInfo Info { get; }
/// <summary>
/// Return the type of prediction task for the produced predictor.
/// </summary>
PredictionKind PredictionKind { get; }
/// <summary>
/// Trains a predictor.
/// </summary>
/// <param name="context">A context containing at least the training data</param>
/// <returns>The trained predictor</returns>
/// <seealso cref="ITrainer{TPredictor}.Train(TrainContext)"/>
IPredictor Train(TrainContext context);
}
/// <summary>
/// Strongly typed generic interface for a trainer. A trainer object takes training data
/// and produces a predictor.
/// </summary>
/// <typeparam name="TPredictor"> Type of predictor produced</typeparam>
[BestFriend]
internal interface ITrainer<out TPredictor> : ITrainer
where TPredictor : IPredictor
{
/// <summary>
/// Trains a predictor.
/// </summary>
/// <param name="context">A context containing at least the training data</param>
/// <returns>The trained predictor</returns>
new TPredictor Train(TrainContext context);
}
[BestFriend]
internal static class TrainerExtensions
{
/// <summary>
/// Convenience train extension for the case where one has only a training set with no auxiliary information.
/// Equivalent to calling <see cref="ITrainer.Train(TrainContext)"/>
/// on a <see cref="TrainContext"/> constructed with <paramref name="trainData"/>.
/// </summary>
/// <param name="trainer">The trainer</param>
/// <param name="trainData">The training data.</param>
/// <returns>The trained predictor</returns>
public static IPredictor Train(this ITrainer trainer, RoleMappedData trainData)
=> trainer.Train(new TrainContext(trainData));
/// <summary>
/// Convenience train extension for the case where one has only a training set with no auxiliary information.
/// Equivalent to calling <see cref="ITrainer{TPredictor}.Train(TrainContext)"/>
/// on a <see cref="TrainContext"/> constructed with <paramref name="trainData"/>.
/// </summary>
/// <param name="trainer">The trainer</param>
/// <param name="trainData">The training data.</param>
/// <returns>The trained predictor</returns>
public static TPredictor Train<TPredictor>(this ITrainer<TPredictor> trainer, RoleMappedData trainData) where TPredictor : IPredictor
=> trainer.Train(new TrainContext(trainData));
}
/// <param name="context">A context containing at least the training data</param>
/// <returns>The trained predictor</returns>
/// <seealso cref="ITrainer{TPredictor}.Train(TrainContext)"/>
IPredictor Train(TrainContext context);
}
/// <summary>
/// Strongly typed generic interface for a trainer. A trainer object takes training data
/// and produces a predictor.
/// </summary>
/// <typeparam name="TPredictor"> Type of predictor produced</typeparam>
[BestFriend]
internal interface ITrainer<out TPredictor> : ITrainer
where TPredictor : IPredictor
{
/// <summary>
/// Trains a predictor.
/// </summary>
/// <param name="context">A context containing at least the training data</param>
/// <returns>The trained predictor</returns>
new TPredictor Train(TrainContext context);
}
[BestFriend]
internal static class TrainerExtensions
{
/// <summary>
/// Convenience train extension for the case where one has only a training set with no auxiliary information.
/// Equivalent to calling <see cref="ITrainer.Train(TrainContext)"/>
/// on a <see cref="TrainContext"/> constructed with <paramref name="trainData"/>.
/// </summary>
/// <param name="trainer">The trainer</param>
/// <param name="trainData">The training data.</param>
/// <returns>The trained predictor</returns>
public static IPredictor Train(this ITrainer trainer, RoleMappedData trainData)
=> trainer.Train(new TrainContext(trainData));
/// <summary>
/// Convenience train extension for the case where one has only a training set with no auxiliary information.
/// Equivalent to calling <see cref="ITrainer{TPredictor}.Train(TrainContext)"/>
/// on a <see cref="TrainContext"/> constructed with <paramref name="trainData"/>.
/// </summary>
/// <param name="trainer">The trainer</param>
/// <param name="trainData">The training data.</param>
/// <returns>The trained predictor</returns>
public static TPredictor Train<TPredictor>(this ITrainer<TPredictor> trainer, RoleMappedData trainData) where TPredictor : IPredictor
=> trainer.Train(new TrainContext(trainData));
}

Просмотреть файл

@ -4,139 +4,138 @@
using System.Collections.Generic;
namespace Microsoft.ML.TreePredictor
namespace Microsoft.ML.TreePredictor;
// The interfaces contained herein are meant to allow tree visualizer to run without an explicit dependency
// on FastTree, so as to allow it greater generality. These should probably be moved somewhere else, but where?
// FastTree itself is not a good candidate since their entire purpose was to avoid tying the tree visualizer
// to FastTree itself. They are semi-tolerable though as a set of internal types here.
/// <summary>
/// Predictor that has ensemble tree structures and returns collection of trees.
/// </summary>
[BestFriend]
internal interface ITreeEnsemble
{
// The interfaces contained herein are meant to allow tree visualizer to run without an explicit dependency
// on FastTree, so as to allow it greater generality. These should probably be moved somewhere else, but where?
// FastTree itself is not a good candidate since their entire purpose was to avoid tying the tree visualizer
// to FastTree itself. They are semi-tolerable though as a set of internal types here.
/// <summary>
/// Returns the number of trees in the ensemble.
/// </summary>
int NumTrees { get; }
/// <summary>
/// Predictor that has ensemble tree structures and returns collection of trees.
/// Returns the collection of trees.
/// </summary>
[BestFriend]
internal interface ITreeEnsemble
{
/// <summary>
/// Returns the number of trees in the ensemble.
/// </summary>
int NumTrees { get; }
/// <summary>
/// Returns the collection of trees.
/// </summary>
/// <returns>Collection of trees</returns>
ITree[] GetTrees();
}
/// <summary>
/// Type of tree used in ensemble of tree based predictors
/// </summary>
[BestFriend]
internal interface ITree
{
/// <summary>
/// Returns the array of right(Greater than) child nodes of every interior nodes
/// </summary>
int[] GtChild { get; }
/// <summary>
/// Returns the array of left(Leser than or equal to) nodes of every interior nodes
/// </summary>
int[] LteChild { get; }
/// <summary>
/// returns the number of interior nodes.
/// </summary>
int NumNodes { get; }
/// <summary>
/// Returns the number of leaf nodes.
/// </summary>
int NumLeaves { get; }
/// <summary>
/// Returns node structure for the given node
/// </summary>
/// <param name="nodeId">Node id</param>
/// <param name="isLeaf">Flag to denote whether the node is leaf or not</param>
/// <param name="featureNames">Feature names collection</param>
/// <returns>Node structure</returns>
INode GetNode(int nodeId, bool isLeaf, IEnumerable<string> featureNames);
}
/// <summary>
/// Type of tree used in ensemble of tree based predictors
/// </summary>
/// <typeparam name="TFeatures">Type of features container (instance) on which to make predictions</typeparam>
[BestFriend]
internal interface ITree<TFeatures> : ITree
{
/// <summary>
/// Returns the leaf node for the given instance.
/// </summary>
/// <param name="features">Type of features container (instance) on which to make predictions</param>
/// <returns>node id</returns>
/// <typeparamref name="TFeatures">Type of features container (instance) on which to make predictions</typeparamref>
int GetLeaf(in TFeatures features);
}
/// <summary>
/// Type to represent the structure of node
/// </summary>
[BestFriend]
internal interface INode
{
/// <summary>
/// Returns Key value pairs representing the properties of the node.
/// </summary>
Dictionary<string, object> KeyValues { get; }
}
/// <summary>
/// Keys to represent the properties of node.
/// </summary>
[BestFriend]
internal static class NodeKeys
{
/// <summary>
/// Name of the the interior node. It is Feature name if it is fasttree. Type is string for default trees.
/// </summary>
public const string SplitName = "SplitName";
/// <summary>
/// Split gain of the interior node. Type is double for default trees.
/// </summary>
public const string SplitGain = "SplitGain";
/// <summary>
/// Threshold value of the interior node. Type is string for default trees.
/// It is expected that the string has exactly two space separated components.
/// i. The first one should be the operator
/// ii. The second one should be the actual threshold
/// For ex., for a split like f1 &lt;= 10, expected Threshold is "&lt;= 10"
/// For a split like color not-in { blue, green }, expected Threshold is "not-in { blue, green }"
/// </summary>
public const string Threshold = "Threshold";
/// <summary>
/// Gain value (specific to fasttree) of the interior node. Type is double for default trees.
/// </summary>
public const string GainValue = "GainValue";
/// <summary>
/// Previous leaf value(specific to fasttree) of the interior node. Type is double for default trees.
/// </summary>
public const string PreviousLeafValue = "PreviousLeafValue";
/// <summary>
/// Leaf value of the leaf node. Type is double for default trees.
/// </summary>
public const string LeafValue = "LeafValue";
/// <summary>
/// Extra items that will be displayed in the tool-tip. Type is string for default trees.
/// </summary>
public const string Extras = "Extras";
}
/// <returns>Collection of trees</returns>
ITree[] GetTrees();
}
/// <summary>
/// Type of tree used in ensemble of tree based predictors
/// </summary>
[BestFriend]
internal interface ITree
{
/// <summary>
/// Returns the array of right(Greater than) child nodes of every interior nodes
/// </summary>
int[] GtChild { get; }
/// <summary>
/// Returns the array of left(Leser than or equal to) nodes of every interior nodes
/// </summary>
int[] LteChild { get; }
/// <summary>
/// returns the number of interior nodes.
/// </summary>
int NumNodes { get; }
/// <summary>
/// Returns the number of leaf nodes.
/// </summary>
int NumLeaves { get; }
/// <summary>
/// Returns node structure for the given node
/// </summary>
/// <param name="nodeId">Node id</param>
/// <param name="isLeaf">Flag to denote whether the node is leaf or not</param>
/// <param name="featureNames">Feature names collection</param>
/// <returns>Node structure</returns>
INode GetNode(int nodeId, bool isLeaf, IEnumerable<string> featureNames);
}
/// <summary>
/// Type of tree used in ensemble of tree based predictors
/// </summary>
/// <typeparam name="TFeatures">Type of features container (instance) on which to make predictions</typeparam>
[BestFriend]
internal interface ITree<TFeatures> : ITree
{
/// <summary>
/// Returns the leaf node for the given instance.
/// </summary>
/// <param name="features">Type of features container (instance) on which to make predictions</param>
/// <returns>node id</returns>
/// <typeparamref name="TFeatures">Type of features container (instance) on which to make predictions</typeparamref>
int GetLeaf(in TFeatures features);
}
/// <summary>
/// Type to represent the structure of node
/// </summary>
[BestFriend]
internal interface INode
{
/// <summary>
/// Returns Key value pairs representing the properties of the node.
/// </summary>
Dictionary<string, object> KeyValues { get; }
}
/// <summary>
/// Keys to represent the properties of node.
/// </summary>
[BestFriend]
internal static class NodeKeys
{
/// <summary>
/// Name of the the interior node. It is Feature name if it is fasttree. Type is string for default trees.
/// </summary>
public const string SplitName = "SplitName";
/// <summary>
/// Split gain of the interior node. Type is double for default trees.
/// </summary>
public const string SplitGain = "SplitGain";
/// <summary>
/// Threshold value of the interior node. Type is string for default trees.
/// It is expected that the string has exactly two space separated components.
/// i. The first one should be the operator
/// ii. The second one should be the actual threshold
/// For ex., for a split like f1 &lt;= 10, expected Threshold is "&lt;= 10"
/// For a split like color not-in { blue, green }, expected Threshold is "not-in { blue, green }"
/// </summary>
public const string Threshold = "Threshold";
/// <summary>
/// Gain value (specific to fasttree) of the interior node. Type is double for default trees.
/// </summary>
public const string GainValue = "GainValue";
/// <summary>
/// Previous leaf value(specific to fasttree) of the interior node. Type is double for default trees.
/// </summary>
public const string PreviousLeafValue = "PreviousLeafValue";
/// <summary>
/// Leaf value of the leaf node. Type is double for default trees.
/// </summary>
public const string LeafValue = "LeafValue";
/// <summary>
/// Extra items that will be displayed in the tool-tip. Type is string for default trees.
/// </summary>
public const string Extras = "Extras";
}

Просмотреть файл

@ -5,64 +5,63 @@
using Microsoft.ML.Data;
using Microsoft.ML.Runtime;
namespace Microsoft.ML
namespace Microsoft.ML;
/// <summary>
/// Holds information relevant to trainers. Instances of this class are meant to be constructed and passed
/// into <see cref="ITrainer{TPredictor}.Train(TrainContext)"/> or <see cref="ITrainer.Train(TrainContext)"/>.
/// This holds at least a training set, as well as optionally a predictor.
/// </summary>
[BestFriend]
internal sealed class TrainContext
{
/// <summary>
/// Holds information relevant to trainers. Instances of this class are meant to be constructed and passed
/// into <see cref="ITrainer{TPredictor}.Train(TrainContext)"/> or <see cref="ITrainer.Train(TrainContext)"/>.
/// This holds at least a training set, as well as optionally a predictor.
/// The training set. Cannot be <c>null</c>.
/// </summary>
[BestFriend]
internal sealed class TrainContext
public RoleMappedData TrainingSet { get; }
/// <summary>
/// The validation set. Can be <c>null</c>. Note that passing a non-<c>null</c> validation set into
/// a trainer that does not support validation sets should not be considered an error condition. It
/// should simply be ignored in that case.
/// </summary>
public RoleMappedData ValidationSet { get; }
/// <summary>
/// The test set, whose uses are very similar to validation set but it should not directly and indirectly
/// affect the training process. One major difference between validation set and test test is that validation
/// can affect the training process by, for example, early stopping. Note that early stopping is a technique
/// which terminates the training process once the scores computed on validation set starts getting worse.
/// </summary>
public RoleMappedData TestSet { get; }
/// <summary>
/// The initial predictor, for incremental training. Note that if a <see cref="ITrainer"/> implementor
/// does not support incremental training, then it can ignore it similarly to how one would ignore
/// <see cref="ValidationSet"/>. However, if the trainer does support incremental training and there
/// is something wrong with a non-<c>null</c> value of this, then the trainer ought to throw an exception.
/// </summary>
public IPredictor InitialPredictor { get; }
/// <summary>
/// Constructor, given a training set and optional other arguments.
/// </summary>
/// <param name="trainingSet">Will set <see cref="TrainingSet"/> to this value. This must be specified</param>
/// <param name="validationSet">Will set <see cref="ValidationSet"/> to this value if specified</param>
/// <param name="testSet">Will set <see cref="TestSet"/> to this value if specified</param>
/// <param name="initialPredictor">Will set <see cref="InitialPredictor"/> to this value if specified</param>
public TrainContext(RoleMappedData trainingSet, RoleMappedData validationSet = null, RoleMappedData testSet = null, IPredictor initialPredictor = null)
{
/// <summary>
/// The training set. Cannot be <c>null</c>.
/// </summary>
public RoleMappedData TrainingSet { get; }
Contracts.CheckValue(trainingSet, nameof(trainingSet));
Contracts.CheckValueOrNull(validationSet);
Contracts.CheckValueOrNull(initialPredictor);
/// <summary>
/// The validation set. Can be <c>null</c>. Note that passing a non-<c>null</c> validation set into
/// a trainer that does not support validation sets should not be considered an error condition. It
/// should simply be ignored in that case.
/// </summary>
public RoleMappedData ValidationSet { get; }
// REVIEW: Should there be code here to ensure that the role mappings between the two are compatible?
// That is, all the role mappings are the same and the columns between them have identical types?
/// <summary>
/// The test set, whose uses are very similar to validation set but it should not directly and indirectly
/// affect the training process. One major difference between validation set and test test is that validation
/// can affect the training process by, for example, early stopping. Note that early stopping is a technique
/// which terminates the training process once the scores computed on validation set starts getting worse.
/// </summary>
public RoleMappedData TestSet { get; }
/// <summary>
/// The initial predictor, for incremental training. Note that if a <see cref="ITrainer"/> implementor
/// does not support incremental training, then it can ignore it similarly to how one would ignore
/// <see cref="ValidationSet"/>. However, if the trainer does support incremental training and there
/// is something wrong with a non-<c>null</c> value of this, then the trainer ought to throw an exception.
/// </summary>
public IPredictor InitialPredictor { get; }
/// <summary>
/// Constructor, given a training set and optional other arguments.
/// </summary>
/// <param name="trainingSet">Will set <see cref="TrainingSet"/> to this value. This must be specified</param>
/// <param name="validationSet">Will set <see cref="ValidationSet"/> to this value if specified</param>
/// <param name="testSet">Will set <see cref="TestSet"/> to this value if specified</param>
/// <param name="initialPredictor">Will set <see cref="InitialPredictor"/> to this value if specified</param>
public TrainContext(RoleMappedData trainingSet, RoleMappedData validationSet = null, RoleMappedData testSet = null, IPredictor initialPredictor = null)
{
Contracts.CheckValue(trainingSet, nameof(trainingSet));
Contracts.CheckValueOrNull(validationSet);
Contracts.CheckValueOrNull(initialPredictor);
// REVIEW: Should there be code here to ensure that the role mappings between the two are compatible?
// That is, all the role mappings are the same and the columns between them have identical types?
TrainingSet = trainingSet;
ValidationSet = validationSet;
TestSet = testSet;
InitialPredictor = initialPredictor;
}
TrainingSet = trainingSet;
ValidationSet = validationSet;
TestSet = testSet;
InitialPredictor = initialPredictor;
}
}

Просмотреть файл

@ -2,83 +2,82 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace Microsoft.ML
namespace Microsoft.ML;
/// <summary>
/// Characteristics of a trainer. Exposed via the Info property of each trainer.
/// </summary>
public sealed class TrainerInfo
{
// REVIEW: Ideally trainers should be able to communicate
// something about the type of data they are capable of being trained
// on, for example, what ColumnKinds they want, how many of each, of what type,
// etc. This interface seems like the most natural conduit for that sort
// of extra information.
/// <summary>
/// Characteristics of a trainer. Exposed via the Info property of each trainer.
/// Whether the trainer needs to see data in normalized form. Only non-parametric trainers will tend to return
/// <see langword="false"/> here.
/// </summary>
public sealed class TrainerInfo
public bool NeedNormalization { get; }
/// <summary>
/// Whether the trainer needs calibration to produce probabilities. As a general rule only trainers that produce
/// binary classifier predictors that also do not have a natural probabilistic interpretation should have a
/// <see langword="true"/> value here.
/// </summary>
[BestFriend]
internal bool NeedCalibration { get; }
/// <summary>
/// Whether this trainer could benefit from a cached view of the data. Trainers that have few passes over the
/// data, or that need to build their own custom data structure over the data, will have a <c>false</c> here.
/// </summary>
public bool WantCaching { get; }
/// <summary>
/// Whether the trainer supports validation set via <see cref="TrainContext.ValidationSet"/>. Not implementing
/// this interface and returning <c>false</c> from this property is an indication the trainer does not support
/// that.
/// </summary>
[BestFriend]
internal bool SupportsValidation { get; }
/// <summary>
/// Whether the trainer can use test set via <see cref="TrainContext.TestSet"/>. Not implementing
/// this interface and returning <c>false</c> from this property is an indication the trainer does not support
/// that.
/// </summary>
[BestFriend]
internal bool SupportsTest { get; }
/// <summary>
/// Whether the trainer can support incremental trainers via <see cref="TrainContext.InitialPredictor"/>. Not
/// implementing this interface and returning <c>true</c> from this property is an indication the trainer does
/// not support that.
/// </summary>
[BestFriend]
internal bool SupportsIncrementalTraining { get; }
/// <summary>
/// Initializes with the given parameters. The parameters have default values for the most typical values
/// for most classical trainers.
/// </summary>
/// <param name="normalization">The value for the property <see cref="NeedNormalization"/></param>
/// <param name="calibration">The value for the property <see cref="NeedCalibration"/></param>
/// <param name="caching">The value for the property <see cref="WantCaching"/></param>
/// <param name="supportValid">The value for the property <see cref="SupportsValidation"/></param>
/// <param name="supportIncrementalTrain">The value for the property <see cref="SupportsIncrementalTraining"/></param>
/// <param name="supportTest">The value for the property <see cref="SupportsTest"/></param>
[BestFriend]
internal TrainerInfo(bool normalization = true, bool calibration = false, bool caching = true,
bool supportValid = false, bool supportIncrementalTrain = false, bool supportTest = false)
{
// REVIEW: Ideally trainers should be able to communicate
// something about the type of data they are capable of being trained
// on, for example, what ColumnKinds they want, how many of each, of what type,
// etc. This interface seems like the most natural conduit for that sort
// of extra information.
/// <summary>
/// Whether the trainer needs to see data in normalized form. Only non-parametric trainers will tend to return
/// <see langword="false"/> here.
/// </summary>
public bool NeedNormalization { get; }
/// <summary>
/// Whether the trainer needs calibration to produce probabilities. As a general rule only trainers that produce
/// binary classifier predictors that also do not have a natural probabilistic interpretation should have a
/// <see langword="true"/> value here.
/// </summary>
[BestFriend]
internal bool NeedCalibration { get; }
/// <summary>
/// Whether this trainer could benefit from a cached view of the data. Trainers that have few passes over the
/// data, or that need to build their own custom data structure over the data, will have a <c>false</c> here.
/// </summary>
public bool WantCaching { get; }
/// <summary>
/// Whether the trainer supports validation set via <see cref="TrainContext.ValidationSet"/>. Not implementing
/// this interface and returning <c>false</c> from this property is an indication the trainer does not support
/// that.
/// </summary>
[BestFriend]
internal bool SupportsValidation { get; }
/// <summary>
/// Whether the trainer can use test set via <see cref="TrainContext.TestSet"/>. Not implementing
/// this interface and returning <c>false</c> from this property is an indication the trainer does not support
/// that.
/// </summary>
[BestFriend]
internal bool SupportsTest { get; }
/// <summary>
/// Whether the trainer can support incremental trainers via <see cref="TrainContext.InitialPredictor"/>. Not
/// implementing this interface and returning <c>true</c> from this property is an indication the trainer does
/// not support that.
/// </summary>
[BestFriend]
internal bool SupportsIncrementalTraining { get; }
/// <summary>
/// Initializes with the given parameters. The parameters have default values for the most typical values
/// for most classical trainers.
/// </summary>
/// <param name="normalization">The value for the property <see cref="NeedNormalization"/></param>
/// <param name="calibration">The value for the property <see cref="NeedCalibration"/></param>
/// <param name="caching">The value for the property <see cref="WantCaching"/></param>
/// <param name="supportValid">The value for the property <see cref="SupportsValidation"/></param>
/// <param name="supportIncrementalTrain">The value for the property <see cref="SupportsIncrementalTraining"/></param>
/// <param name="supportTest">The value for the property <see cref="SupportsTest"/></param>
[BestFriend]
internal TrainerInfo(bool normalization = true, bool calibration = false, bool caching = true,
bool supportValid = false, bool supportIncrementalTrain = false, bool supportTest = false)
{
NeedNormalization = normalization;
NeedCalibration = calibration;
WantCaching = caching;
SupportsValidation = supportValid;
SupportsIncrementalTraining = supportIncrementalTrain;
SupportsTest = supportTest;
}
NeedNormalization = normalization;
NeedCalibration = calibration;
WantCaching = caching;
SupportsValidation = supportValid;
SupportsIncrementalTraining = supportIncrementalTrain;
SupportsTest = supportTest;
}
}