CustomMappingCatalog.CustomMapping<TSrc,TDst> Méthode
Définition
Important
Certaines informations portent sur la préversion du produit qui est susceptible d’être en grande partie modifiée avant sa publication. Microsoft exclut toute garantie, expresse ou implicite, concernant les informations fournies ici.
Créez un CustomMappingEstimator<TSrc,TDst>mappage personnalisé des colonnes d’entrée pour générer des colonnes.
public static Microsoft.ML.Transforms.CustomMappingEstimator<TSrc,TDst> CustomMapping<TSrc,TDst> (this Microsoft.ML.TransformsCatalog catalog, Action<TSrc,TDst> mapAction, string contractName, Microsoft.ML.Data.SchemaDefinition inputSchemaDefinition = default, Microsoft.ML.Data.SchemaDefinition outputSchemaDefinition = default) where TSrc : class, new() where TDst : class, new();
static member CustomMapping : Microsoft.ML.TransformsCatalog * Action<'Src, 'Dst (requires 'Src : null and 'Src : (new : unit -> 'Src) and 'Dst : null and 'Dst : (new : unit -> 'Dst))> * string * Microsoft.ML.Data.SchemaDefinition * Microsoft.ML.Data.SchemaDefinition -> Microsoft.ML.Transforms.CustomMappingEstimator<'Src, 'Dst (requires 'Src : null and 'Src : (new : unit -> 'Src) and 'Dst : null and 'Dst : (new : unit -> 'Dst))> (requires 'Src : null and 'Src : (new : unit -> 'Src) and 'Dst : null and 'Dst : (new : unit -> 'Dst))
<Extension()>
Public Function CustomMapping(Of TSrc As {Class, New}, TDst As {Class, New}) (catalog As TransformsCatalog, mapAction As Action(Of TSrc, TDst), contractName As String, Optional inputSchemaDefinition As SchemaDefinition = Nothing, Optional outputSchemaDefinition As SchemaDefinition = Nothing) As CustomMappingEstimator(Of TSrc, TDst)
Paramètres de type
- TSrc
Classe définissant les colonnes à prendre à partir des données entrantes.
- TDst
Classe définissant les nouvelles colonnes ajoutées aux données.
Paramètres
- catalog
- TransformsCatalog
Catalogue de transformation
- mapAction
- Action<TSrc,TDst>
Action de mappage. Cela doit être thread-safe et libre des effets secondaires.
Si le transformateur résultant doit être en mesure d’enregistrer, la définition mapAction
de classe doit implémenter CustomMappingFactory<TSrc,TDst> et doit être décorée avec CustomMappingFactoryAttributeAttribute le fourni contractName
.
Dans les versions v1.5-preview2 et antérieures, l’assembly contenant la classe doit être inscrit dans l’environnement où il est chargé à l’aide RegisterAssembly(Assembly, Boolean)de .
- contractName
- String
Nom du contrat, utilisé par ML.NET pour le chargement du modèle.
S’il null
est spécifié, le transformateur résultant ne peut pas être enregistré.
- inputSchemaDefinition
- SchemaDefinition
Paramètres supplémentaires pour le mappage de schéma entre TSrc
et les données d’entrée.
Utile lors du traitement des annotations.
- outputSchemaDefinition
- SchemaDefinition
Paramètres supplémentaires pour le mappage de schéma entre TDst
et les données de sortie.
Utile lors du traitement des annotations.
Retours
Exemples
using System;
using System.Collections.Generic;
using Microsoft.ML;
namespace Samples.Dynamic
{
public static class CustomMapping
{
// This example shows how to define and apply a custom mapping of input
// columns to output columns without defining a contract. Since a contract
// is not defined, the pipeline containing this mapping cannot be saved and
// loaded back.
public static void Example()
{
// Create a new ML context, for ML.NET operations. It can be used for
// exception tracking and logging, as well as the source of randomness.
var mlContext = new MLContext();
// Get a small dataset as an IEnumerable and convert it to an IDataView.
var samples = new List<InputData>
{
new InputData { Age = 26 },
new InputData { Age = 35 },
new InputData { Age = 34 },
new InputData { Age = 28 },
};
var data = mlContext.Data.LoadFromEnumerable(samples);
// We define the custom mapping between input and output rows that will
// be applied by the transformation.
Action<InputData, CustomMappingOutput> mapping =
(input, output) => output.IsUnderThirty = input.Age < 30;
// Custom transformations can be used to transform data directly, or as
// part of a pipeline of estimators. Note: If contractName is null in
// the CustomMapping estimator, any pipeline of estimators containing
// it, cannot be saved and loaded back.
var pipeline = mlContext.Transforms.CustomMapping(mapping, contractName:
null);
// Now we can transform the data and look at the output to confirm the
// behavior of the estimator. This operation doesn't actually evaluate
// data until we read the data below.
var transformer = pipeline.Fit(data);
var transformedData = transformer.Transform(data);
var dataEnumerable = mlContext.Data.CreateEnumerable<TransformedData>(
transformedData, reuseRowObject: true);
Console.WriteLine("Age\t IsUnderThirty");
foreach (var row in dataEnumerable)
Console.WriteLine($"{row.Age}\t {row.IsUnderThirty}");
// Expected output:
// Age IsUnderThirty
// 26 True
// 35 False
// 34 False
// 28 True
}
// Defines only the column to be generated by the custom mapping
// transformation in addition to the columns already present.
private class CustomMappingOutput
{
public bool IsUnderThirty { get; set; }
}
// Defines the schema of the input data.
private class InputData
{
public float Age { get; set; }
}
// Defines the schema of the transformed data, which includes the new column
// IsUnderThirty.
private class TransformedData : InputData
{
public bool IsUnderThirty { get; set; }
}
}
}
using System;
using System.Collections.Generic;
using Microsoft.ML;
using Microsoft.ML.Transforms;
namespace Samples.Dynamic
{
public static class CustomMappingSaveAndLoad
{
// This example shows how to define and apply a custom mapping of input
// columns to output columns with a contract name. The contract name is
// used in the CustomMappingFactoryAttribute that decorates the custom
// mapping action. The pipeline containing the custom mapping can then be
// saved to disk, and it can be loaded back after the assembly containing
// the custom mapping action is registered.
public static void Example()
{
// Create a new ML context, for ML.NET operations. It can be used for
// exception tracking and logging, as well as the source of randomness.
var mlContext = new MLContext();
// Get a small dataset as an IEnumerable and convert it to an IDataView.
var samples = new List<InputData>
{
new InputData { Age = 26 },
new InputData { Age = 35 },
new InputData { Age = 34 },
new InputData { Age = 28 },
};
var data = mlContext.Data.LoadFromEnumerable(samples);
// Custom transformations can be used to transform data directly, or as
// part of a pipeline of estimators. The contractName must be provided
// in order for a pipeline containing a CustomMapping estimator to be
// saved and loaded back. The contractName must be the same as in the
// CustomMappingFactoryAttribute used to decorate the custom action
// defined by the user.
var pipeline = mlContext.Transforms.CustomMapping(new
IsUnderThirtyCustomAction().GetMapping(), contractName:
"IsUnderThirty");
var transformer = pipeline.Fit(data);
// To save and load the CustomMapping estimator, the assembly in which
// the custom action is defined needs to be registered in the
// environment. The following registers the assembly where
// IsUnderThirtyCustomAction is defined.
// This is necessary only in versions v1.5-preview2 and earlier
mlContext.ComponentCatalog.RegisterAssembly(typeof(
IsUnderThirtyCustomAction).Assembly);
// Now the transform pipeline can be saved and loaded through the usual
// MLContext method.
mlContext.Model.Save(transformer, data.Schema, "customTransform.zip");
var loadedTransform = mlContext.Model.Load("customTransform.zip", out
var inputSchema);
// Now we can transform the data and look at the output to confirm the
// behavior of the estimator. This operation doesn't actually evaluate
// data until we read the data below.
var transformedData = loadedTransform.Transform(data);
var dataEnumerable = mlContext.Data.CreateEnumerable<TransformedData>(
transformedData, reuseRowObject: true);
Console.WriteLine("Age\tIsUnderThirty");
foreach (var row in dataEnumerable)
Console.WriteLine($"{row.Age}\t {row.IsUnderThirty}");
// Expected output:
// Age IsUnderThirty
// 26 True
// 35 False
// 34 False
// 28 True
}
// The custom action needs to implement the abstract class
// CustomMappingFactory, and needs to have attribute
// CustomMappingFactoryAttribute with argument equal to the contractName
// used to define the CustomMapping estimator which uses the action.
[CustomMappingFactoryAttribute("IsUnderThirty")]
private class IsUnderThirtyCustomAction : CustomMappingFactory<InputData,
CustomMappingOutput>
{
// We define the custom mapping between input and output rows that will
// be applied by the transformation.
public static void CustomAction(InputData input, CustomMappingOutput
output) => output.IsUnderThirty = input.Age < 30;
public override Action<InputData, CustomMappingOutput> GetMapping()
=> CustomAction;
}
// Defines only the column to be generated by the custom mapping
// transformation in addition to the columns already present.
private class CustomMappingOutput
{
public bool IsUnderThirty { get; set; }
}
// Defines the schema of the input data.
private class InputData
{
public float Age { get; set; }
}
// Defines the schema of the transformed data, which includes the new column
// IsUnderThirty.
private class TransformedData : InputData
{
public bool IsUnderThirty { get; set; }
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.ML;
using Microsoft.ML.Data;
namespace Samples.Dynamic
{
class CustomMappingWithInMemoryCustomType
{
// This example shows how custom mapping actions can be performed on custom data
// types that ML.NET doesn't know yet. The example tells a story of how two alien
// bodies are merged to form a super alien with a single body.
//
// Here, the type AlienHero represents a single alien entity with a member "Name"
// of type string and members "One" and "Two" of type AlienBody. It defines a custom
// mapping action AlienFusionProcess that takes an AlienHero and "fuses" its two
// AlienBody members to produce a SuperAlienHero entity with a "Name" member of type
// string and a single "Merged" member of type AlienBody, where the merger is just
// the addition of the various members of AlienBody.
public static void Example()
{
var mlContext = new MLContext();
// Build in-memory data.
var tribe = new List<AlienHero>() { new AlienHero("ML.NET", 2, 1000,
2000, 3000, 4000, 5000, 6000, 7000) };
// Build a ML.NET pipeline and make prediction.
var tribeDataView = mlContext.Data.LoadFromEnumerable(tribe);
var pipeline = mlContext.Transforms.CustomMapping(AlienFusionProcess
.GetMapping(), contractName: null);
var model = pipeline.Fit(tribeDataView);
var tribeTransformed = model.Transform(tribeDataView);
// Print out prediction produced by the model.
var firstAlien = mlContext.Data.CreateEnumerable<SuperAlienHero>(
tribeTransformed, false).First();
Console.WriteLine("We got a super alien with name " + firstAlien.Name +
", age " + firstAlien.Merged.Age + ", " + "height " + firstAlien
.Merged.Height + ", weight " + firstAlien.Merged.Weight + ", and "
+ firstAlien.Merged.HandCount + " hands.");
// Expected output:
// We got a super alien with name Super ML.NET, age 4002, height 6000, weight 8000, and 10000 hands.
// Create a prediction engine and print out its prediction.
var engine = mlContext.Model.CreatePredictionEngine<AlienHero,
SuperAlienHero>(model);
var alien = new AlienHero("TEN.LM", 1, 2, 3, 4, 5, 6, 7, 8);
var superAlien = engine.Predict(alien);
Console.Write("We got a super alien with name " + superAlien.Name +
", age " + superAlien.Merged.Age + ", height " +
superAlien.Merged.Height + ", weight " + superAlien.Merged.Weight +
", and " + superAlien.Merged.HandCount + " hands.");
// Expected output:
// We got a super alien with name Super TEN.LM, age 6, height 8, weight 10, and 12 hands.
}
// A custom type which ML.NET doesn't know yet. Its value will be loaded as
// a DataView column in this example.
//
// The type members represent the characteristics of an alien body that will
// be merged in the AlienFusionProcess.
private class AlienBody
{
public int Age { get; set; }
public float Height { get; set; }
public float Weight { get; set; }
public int HandCount { get; set; }
public AlienBody(int age, float height, float weight, int handCount)
{
Age = age;
Height = height;
Weight = weight;
HandCount = handCount;
}
}
// DataViewTypeAttribute applied to class AlienBody members. This attribute
// defines how class AlienBody is registered in ML.NET's type system. In this
// case, AlienBody is registered as DataViewAlienBodyType in ML.NET. The RaceId
// property allows different members of type AlienBody to be registered with
// different types in ML.NEt (see usage in class AlienHero).
private sealed class AlienTypeAttributeAttribute : DataViewTypeAttribute
{
public int RaceId { get; }
// Create an DataViewTypeAttribute> from raceId to a AlienBody.
public AlienTypeAttributeAttribute(int raceId)
{
RaceId = raceId;
}
// A function implicitly invoked by ML.NET when processing a custom
// type. It binds a DataViewType to a custom type plus its attributes.
public override void Register()
{
DataViewTypeManager.Register(new DataViewAlienBodyType(RaceId),
typeof(AlienBody), this);
}
public override bool Equals(DataViewTypeAttribute other)
{
if (other is AlienTypeAttributeAttribute alienTypeAttributeAttribute)
return RaceId == alienTypeAttributeAttribute.RaceId;
return false;
}
public override int GetHashCode() => RaceId.GetHashCode();
}
// A custom class with a type which ML.NET doesn't know yet. Its value will
// be loaded as a DataView row in this example. It will be the input of
// AlienFusionProcess.MergeBody(AlienHero, SuperAlienHero).
//
// The members One and Two would be mapped to different types inside
// ML.NET type system because they have different
// AlienTypeAttributeAttribute's. For example, the column type of One would
// be DataViewAlienBodyType with RaceId=100.
//
// This type represents a "Hero" Alien that is a single entity with two bodies.
// The "Hero" undergoes a fusion process defined in AlienFusionProcess to
// become a SuperAlienHero with a single body that is a merger of the two
// bodies.
private class AlienHero
{
public string Name { get; set; }
[AlienTypeAttribute(100)]
public AlienBody One { get; set; }
[AlienTypeAttribute(200)]
public AlienBody Two { get; set; }
public AlienHero()
{
Name = "Unknown";
One = new AlienBody(0, 0, 0, 0);
Two = new AlienBody(0, 0, 0, 0);
}
public AlienHero(string name,
int age, float height, float weight, int handCount,
int anotherAge, float anotherHeight, float anotherWeight, int
anotherHandCount)
{
Name = name;
One = new AlienBody(age, height, weight, handCount);
Two = new AlienBody(anotherAge, anotherHeight, anotherWeight,
anotherHandCount);
}
}
// Type of AlienBody in ML.NET's type system. This is the data view type that
// will represent AlienBody in ML.NET's type system when it is registered as
// such in AlienTypeAttributeAttribute.
// It usually shows up as DataViewSchema.Column.Type among IDataView.Schema.
private class DataViewAlienBodyType : StructuredDataViewType
{
public int RaceId { get; }
public DataViewAlienBodyType(int id) : base(typeof(AlienBody))
{
RaceId = id;
}
public override bool Equals(DataViewType other)
{
if (other is DataViewAlienBodyType otherAlien)
return otherAlien.RaceId == RaceId;
return false;
}
public override int GetHashCode()
{
return RaceId.GetHashCode();
}
}
// The output type of processing AlienHero using AlienFusionProcess
// .MergeBody(AlienHero, SuperAlienHero).
// This is a "fused" alien whose body is a merger of the two bodies
// of AlienHero.
private class SuperAlienHero
{
public string Name { get; set; }
[AlienTypeAttribute(007)]
public AlienBody Merged { get; set; }
public SuperAlienHero()
{
Name = "Unknown";
Merged = new AlienBody(0, 0, 0, 0);
}
}
// The implementation of custom mapping is MergeBody. It accepts AlienHero
// and produces SuperAlienHero.
private class AlienFusionProcess
{
public static void MergeBody(AlienHero input, SuperAlienHero output)
{
output.Name = "Super " + input.Name;
output.Merged.Age = input.One.Age + input.Two.Age;
output.Merged.Height = input.One.Height + input.Two.Height;
output.Merged.Weight = input.One.Weight + input.Two.Weight;
output.Merged.HandCount = input.One.HandCount + input.Two.HandCount;
}
public static Action<AlienHero, SuperAlienHero> GetMapping()
{
return MergeBody;
}
}
}
}