ML.NET是一个由Microsoft开发的开源机器学习框架,它允许开发者在.NET环境中创建和使用机器学习模型。ML.NET的目标是使机器学习技术更加易于访问,同时也为.NET开发者提供一个强大的工具集来整合机器学习功能到他们的应用程序中。



C#List<List<string>> doubles;
public FrmMain()
{
InitializeComponent();
lsvMain.FullRowSelect = true;
lsvMain.View = View.Details;
lsvMain.GridLines = true;
lsvMain.VirtualMode = true;
lsvMain.RetrieveVirtualItem += LsvMain_RetrieveVirtualItem;
lsvMain.VirtualListSize = 0; // 初始时设置为0
}
private void btnLoad_Click(object sender, EventArgs e)
{
List<string> rows = File.ReadAllLines("./data/电机状态.txt").ToList();
doubles = rows.ConvertAll(x =>
{
return x.Split(' ').ToList();
});
lsvMain.VirtualListSize = rows.Count; // 设置数据的总条数
for (int i = 0; i < doubles[0].Count; i++)
{
lsvMain.Columns.Add("col" + i.ToString());
}
}
private async void LsvMain_RetrieveVirtualItem(object? sender, RetrieveVirtualItemEventArgs e)
{
// 提供显示的数据项
if (e.ItemIndex >= 0 && e.ItemIndex < doubles.Count)
{
ListViewItem item = new ListViewItem();
item.Text = doubles[e.ItemIndex][0].ToString();
for (int j = 1; j < doubles[e.ItemIndex].Count; j++)
{
item.SubItems.Add(doubles[e.ItemIndex][j].ToString());
}
e.Item = item;
}
}
C#public class ModelInput
{
[ColumnName(@"col0"),LoadColumn(0)]
public float Col0 { get; set; }
[ColumnName(@"col1"), LoadColumn(1)]
public float Col1 { get; set; }
[ColumnName(@"col2"), LoadColumn(2)]
public float Col2 { get; set; }
[ColumnName(@"col3"), LoadColumn(3)]
public float Col3 { get; set; }
[ColumnName(@"col4"), LoadColumn(4)]
public float Col4 { get; set; }
[ColumnName(@"col5"), LoadColumn(5)]
public float Col5 { get; set; }
[ColumnName(@"col6"), LoadColumn(6)]
public float Col6 { get; set; }
[ColumnName(@"col7"), LoadColumn(7)]
public float Col7 { get; set; }
[ColumnName(@"col8"), LoadColumn(8)]
public float Col8 { get; set; }
[ColumnName(@"col9"), LoadColumn(9)]
public float Col9 { get; set; }
[ColumnName(@"col10"), LoadColumn(10)]
public float Col10 { get; set; }
[ColumnName(@"col11"), LoadColumn(11)]
public float Col11 { get; set; }
[ColumnName(@"col12"), LoadColumn(12)]
public float Col12 { get; set; }
[ColumnName(@"col13"), LoadColumn(13)]
public float Col13 { get; set; }
[ColumnName(@"col14"), LoadColumn(14)]
public float Col14 { get; set; }
[ColumnName(@"col15"), LoadColumn(15)]
public float Col15 { get; set; }
[ColumnName(@"col16"), LoadColumn(16)]
public float Col16 { get; set; }
[ColumnName(@"col17"), LoadColumn(17)]
public float Col17 { get; set; }
[ColumnName(@"col18"), LoadColumn(18)]
public float Col18 { get; set; }
[ColumnName(@"col19"), LoadColumn(19)]
public float Col19 { get; set; }
[ColumnName(@"col20"), LoadColumn(20)]
public float Col20 { get; set; }
[ColumnName(@"col21"), LoadColumn(21)]
public float Col21 { get; set; }
[ColumnName(@"col22"), LoadColumn(22)]
public float Col22 { get; set; }
[ColumnName(@"col23"), LoadColumn(23)]
public float Col23 { get; set; }
[ColumnName(@"col24"), LoadColumn(24)]
public float Col24 { get; set; }
[ColumnName(@"col25"), LoadColumn(25)]
public float Col25 { get; set; }
[ColumnName(@"col26"), LoadColumn(26)]
public float Col26 { get; set; }
[ColumnName(@"col27"), LoadColumn(27)]
public float Col27 { get; set; }
[ColumnName(@"col28"), LoadColumn(28)]
public float Col28 { get; set; }
[ColumnName(@"col29"), LoadColumn(29)]
public float Col29 { get; set; }
[ColumnName(@"col30"), LoadColumn(30)]
public float Col30 { get; set; }
[ColumnName(@"col31"), LoadColumn(31)]
public float Col31 { get; set; }
[ColumnName(@"col32"), LoadColumn(32)]
public float Col32 { get; set; }
[ColumnName(@"col33"), LoadColumn(33)]
public float Col33 { get; set; }
[ColumnName(@"col34"), LoadColumn(34)]
public float Col34 { get; set; }
[ColumnName(@"col35"), LoadColumn(35)]
public float Col35 { get; set; }
[ColumnName(@"col36"), LoadColumn(36)]
public float Col36 { get; set; }
[ColumnName(@"col37"), LoadColumn(37)]
public float Col37 { get; set; }
[ColumnName(@"col38"), LoadColumn(38)]
public float Col38 { get; set; }
[ColumnName(@"col39"), LoadColumn(39)]
public float Col39 { get; set; }
[ColumnName(@"col40"), LoadColumn(40)]
public float Col40 { get; set; }
[ColumnName(@"col41"), LoadColumn(41)]
public float Col41 { get; set; }
[ColumnName(@"col42"), LoadColumn(42)]
public float Col42 { get; set; }
[ColumnName(@"col43"), LoadColumn(43)]
public float Col43 { get; set; }
[ColumnName(@"col44"), LoadColumn(44)]
public float Col44 { get; set; }
[ColumnName(@"col45"), LoadColumn(45)]
public float Col45 { get; set; }
[ColumnName(@"col46"), LoadColumn(46)]
public float Col46 { get; set; }
[ColumnName(@"col47"), LoadColumn(47)]
public float Col47 { get; set; }
[ColumnName(@"col48"), LoadColumn(48)]
public float Col48 { get; set; }
}
C#public class ModelOutput
{
[ColumnName(@"col0")]
public float Col0 { get; set; }
[ColumnName(@"col1")]
public float Col1 { get; set; }
[ColumnName(@"col2")]
public float Col2 { get; set; }
[ColumnName(@"col3")]
public float Col3 { get; set; }
[ColumnName(@"col4")]
public float Col4 { get; set; }
[ColumnName(@"col5")]
public float Col5 { get; set; }
[ColumnName(@"col6")]
public float Col6 { get; set; }
[ColumnName(@"col7")]
public float Col7 { get; set; }
[ColumnName(@"col8")]
public float Col8 { get; set; }
[ColumnName(@"col9")]
public float Col9 { get; set; }
[ColumnName(@"col10")]
public float Col10 { get; set; }
[ColumnName(@"col11")]
public float Col11 { get; set; }
[ColumnName(@"col12")]
public float Col12 { get; set; }
[ColumnName(@"col13")]
public float Col13 { get; set; }
[ColumnName(@"col14")]
public float Col14 { get; set; }
[ColumnName(@"col15")]
public float Col15 { get; set; }
[ColumnName(@"col16")]
public float Col16 { get; set; }
[ColumnName(@"col17")]
public float Col17 { get; set; }
[ColumnName(@"col18")]
public float Col18 { get; set; }
[ColumnName(@"col19")]
public float Col19 { get; set; }
[ColumnName(@"col20")]
public float Col20 { get; set; }
[ColumnName(@"col21")]
public float Col21 { get; set; }
[ColumnName(@"col22")]
public float Col22 { get; set; }
[ColumnName(@"col23")]
public float Col23 { get; set; }
[ColumnName(@"col24")]
public float Col24 { get; set; }
[ColumnName(@"col25")]
public float Col25 { get; set; }
[ColumnName(@"col26")]
public float Col26 { get; set; }
[ColumnName(@"col27")]
public float Col27 { get; set; }
[ColumnName(@"col28")]
public float Col28 { get; set; }
[ColumnName(@"col29")]
public float Col29 { get; set; }
[ColumnName(@"col30")]
public float Col30 { get; set; }
[ColumnName(@"col31")]
public float Col31 { get; set; }
[ColumnName(@"col32")]
public float Col32 { get; set; }
[ColumnName(@"col33")]
public float Col33 { get; set; }
[ColumnName(@"col34")]
public float Col34 { get; set; }
[ColumnName(@"col35")]
public float Col35 { get; set; }
[ColumnName(@"col36")]
public float Col36 { get; set; }
[ColumnName(@"col37")]
public float Col37 { get; set; }
[ColumnName(@"col38")]
public float Col38 { get; set; }
[ColumnName(@"col39")]
public float Col39 { get; set; }
[ColumnName(@"col40")]
public float Col40 { get; set; }
[ColumnName(@"col41")]
public float Col41 { get; set; }
[ColumnName(@"col42")]
public float Col42 { get; set; }
[ColumnName(@"col43")]
public float Col43 { get; set; }
[ColumnName(@"col44")]
public float Col44 { get; set; }
[ColumnName(@"col45")]
public float Col45 { get; set; }
[ColumnName(@"col46")]
public float Col46 { get; set; }
[ColumnName(@"col47")]
public float Col47 { get; set; }
[ColumnName(@"col48")]
public uint Col48 { get; set; }
[ColumnName(@"Features")]
public float[] Features { get; set; }
[ColumnName(@"PredictedLabel")]
public float PredictedLabel { get; set; }
[ColumnName(@"Score")]
public float[] Score { get; set; }
}
加载数据,通常是从文件或数据库中。然后定义数据模型,以及如何将数据加载到模型中。
C#var mlContext = new MLContext();
IDataView dataView = mlContext.Data.LoadFromTextFile<ModelInput>(
path: "./data/电机状态.txt",
hasHeader: false,
separatorChar: ' '
);
对数据进行预处理,例如归一化、缩放、处理缺失值等。选择FastTree作为训练算法,并将其添加到数据处理管道中。
C#var pipeline = mlContext.Transforms.ReplaceMissingValues(new[] { new InputOutputColumnPair(@"col0", @"col0")
, new InputOutputColumnPair(@"col1", @"col1"), new InputOutputColumnPair(@"col2", @"col2"), new InputOutputColumnPair(@"col3", @"col3"), new InputOutputColumnPair(@"col4", @"col4"), new InputOutputColumnPair(@"col5", @"col5"), new InputOutputColumnPair(@"col6", @"col6"), new InputOutputColumnPair(@"col7", @"col7"), new InputOutputColumnPair(@"col8", @"col8"), new InputOutputColumnPair(@"col9", @"col9"), new InputOutputColumnPair(@"col10", @"col10"), new InputOutputColumnPair(@"col11", @"col11"), new InputOutputColumnPair(@"col12", @"col12")
, new InputOutputColumnPair(@"col13", @"col13"), new InputOutputColumnPair(@"col14", @"col14"), new InputOutputColumnPair(@"col15", @"col15"), new InputOutputColumnPair(@"col16", @"col16"), new InputOutputColumnPair(@"col17", @"col17"), new InputOutputColumnPair(@"col18", @"col18"), new InputOutputColumnPair(@"col19", @"col19"), new InputOutputColumnPair(@"col20", @"col20"), new InputOutputColumnPair(@"col21", @"col21"), new InputOutputColumnPair(@"col22", @"col22"), new InputOutputColumnPair(@"col23", @"col23"), new InputOutputColumnPair(@"col24", @"col24")
, new InputOutputColumnPair(@"col25", @"col25"), new InputOutputColumnPair(@"col26", @"col26"), new InputOutputColumnPair(@"col27", @"col27"), new InputOutputColumnPair(@"col28", @"col28"), new InputOutputColumnPair(@"col29", @"col29"), new InputOutputColumnPair(@"col30", @"col30")
, new InputOutputColumnPair(@"col31", @"col31"), new InputOutputColumnPair(@"col32", @"col32"), new InputOutputColumnPair(@"col33", @"col33"), new InputOutputColumnPair(@"col34", @"col34"), new InputOutputColumnPair(@"col35", @"col35"), new InputOutputColumnPair(@"col36", @"col36"), new InputOutputColumnPair(@"col37", @"col37"), new InputOutputColumnPair(@"col38", @"col38"), new InputOutputColumnPair(@"col39", @"col39"), new InputOutputColumnPair(@"col40", @"col40"), new InputOutputColumnPair(@"col41", @"col41"), new InputOutputColumnPair(@"col42", @"col42"), new InputOutputColumnPair(@"col43", @"col43"), new InputOutputColumnPair(@"col44", @"col44"), new InputOutputColumnPair(@"col45", @"col45"), new InputOutputColumnPair(@"col46", @"col46"), new InputOutputColumnPair(@"col47", @"col47") })
.Append(mlContext.Transforms.Concatenate(@"Features", new[] { @"col0", @"col1", @"col2", @"col3", @"col4", @"col5", @"col6", @"col7", @"col8", @"col9", @"col10", @"col11", @"col12", @"col13", @"col14", @"col15", @"col16", @"col17", @"col18", @"col19", @"col20", @"col21", @"col22", @"col23", @"col24", @"col25", @"col26", @"col27", @"col28", @"col29", @"col30", @"col31", @"col32", @"col33", @"col34", @"col35", @"col36", @"col37", @"col38", @"col39", @"col40", @"col41", @"col42", @"col43", @"col44", @"col45", @"col46", @"col47" }))
.Append(mlContext.Transforms.Conversion.MapValueToKey(outputColumnName: @"col48", inputColumnName: @"col48"))
.Append(mlContext.MulticlassClassification.Trainers.OneVersusAll(binaryEstimator: mlContext.BinaryClassification.Trainers.FastTree(new FastTreeBinaryTrainer.Options() { NumberOfLeaves = 4, MinimumExampleCountPerLeaf = 13, NumberOfTrees = 138, MaximumBinCountPerFeature = 374, FeatureFraction = 0.99999999, LearningRate = 0.999999776672986, LabelColumnName = @"col48", FeatureColumnName = @"Features" }), labelColumnName: @"col48"))
.Append(mlContext.Transforms.Conversion.MapKeyToValue(outputColumnName: @"PredictedLabel", inputColumnName: @"PredictedLabel"));
使用了一种称为"One Versus All"(OVA)的策略,该策略结合了一个二元分类器(在这种情况下是FastTree算法)来解决多类别分类问题。
binaryEstimator参数接收一个二元分类训练器。在这个例子中,使用了FastTree算法。
FastTree是一种基于梯度提升决策树(GBDT)的算法,它通常用于分类和回归任务。
设置FastTree算法的参数。这些参数会影响模型训练的行为和最终的性能。
NumberOfLeaves = 4, // 决策树中叶节点的最大数量。 MinimumExampleCountPerLeaf = 13, // 每个叶节点中的最小样本数。 NumberOfTrees = 138, // 要训练的树的数量。 MaximumBinCountPerFeature = 374, // 每个特征使用的最大箱数(用于分箱连续特征)。 FeatureFraction = 0.99999999, // 在训练每棵树时使用的特征比例。 LearningRate = 0.999999776672986, // 学习率,控制每棵树的影响。 LabelColumnName = @"col48", // 用于训练的标签列的名称。 FeatureColumnName = @"Features" // 用于训练的特征列的名称。
labelColumnName参数指定了数据集中包含正确标签的列的名称。
labelColumnName: @"col48"
OneVersusAll 方法用于创建一个多类别分类模型,它通过将每个类别与所有其他类别进行比较来工作。对于每个类别,它都会训练一个FastTree二元分类器。最终,对于一个给定的输入,所有的二元分类器将被评估,最终的预测将基于哪个分类器给出了最高的置信度。
这种方法适用于那些可以被分解为多个二元分类问题的多类别问题。FastTree二元分类器的参数被设置为特定的值,以优化模型性能。在实际应用中,这些参数通常需要通过交叉验证和参数调优来确定。
使用上述管道训练模型。
C#//它包含了用于训练的数据。Fit方法返回一个训练好的模型(ITransformer类型的实例)。
var model = pipeline.Fit(dataView);
// 使用训练好的模型的Transform方法对相同的数据集进行预测。Transform方法接收一个IDataView类型的实例,
// 并返回一个新的IDataView实例,其中包含了原始数据和模型的预测结果。
IDataView predictions = model.Transform(dataView);
C#var metrics = mlContext.MulticlassClassification.Evaluate(predictions, labelColumnName: "col48");
StringBuilder sb = new StringBuilder();
sb.AppendLine("MicroAccuracy:" + metrics.MicroAccuracy.ToString());
sb.AppendLine("MacroAccuracy:" + metrics.MacroAccuracy.ToString());
sb.AppendLine("LogLoss:" + metrics.LogLoss.ToString());
sb.AppendLine("LogLossReduction:" + metrics.LogLossReduction.ToString());
sb.AppendLine("TopKAccuracy:" + metrics.TopKAccuracy.ToString());
MessageBox.Show(sb.ToString());
MulticlassClassificationMetrics 对象,它包含了多个指标,用于衡量模型的准确性和其他性能特征。以下是一些主要的返回数据及其含义:
将训练好的模型保存到文件中,以便以后使用或部署。
C#mlContext.Model.Save(model, dataView.Schema, "./data/model.zip");
定义一个Predict方法,它接收一个ModelInput类型的实例作为输入参数。
C#public ModelOutput Predict(ModelInput input)
{
// 创建一个Lazy<T>对象,它将延迟创建PredictionEngine的实例。
// Lazy<T>的构造函数接收一个工厂方法(CreatePredictEngine)和一个布尔值(true)。
// 这个布尔值表示是否线程安全,true表示Lazy<T>实例是线程安全的。
Lazy<PredictionEngine<ModelInput, ModelOutput>> PredictEngine
= new Lazy<PredictionEngine<ModelInput, ModelOutput>>(() => CreatePredictEngine(), true);
// 获取Lazy<T>包装的PredictionEngine实例。如果这是首次访问,Lazy<T>会调用工厂方法创建PredictionEngine。
// 如果之前已经创建过,它将返回现有的实例。
var predEngine = PredictEngine.Value;
// 使用PredictionEngine对输入数据进行预测,并返回预测结果。
// Predict方法将ModelInput实例作为输入,并返回一个ModelOutput实例,其中包含了预测的标签和概率等信息。
return predEngine.Predict(input);
}
CreatePredictEngine是一个私有方法,用于创建和配置PredictionEngine实例。
C#// PredictionEngine是一个用于对单个数据实例进行预测的工具。
private PredictionEngine<ModelInput, ModelOutput> CreatePredictEngine()
{
// 创建一个新的MLContext实例。MLContext是ML.NET中的主要环境类,用于协调模型创建、训练、评估和预测活动。
var mlContext = new MLContext();
// 加载先前训练好的ML.NET模型。MLNetModelPath是一个字符串变量,应该包含模型文件的路径。
// Load方法返回一个ITransformer对象,它表示加载的模型。
// out var _ 是一个丢弃参数,用于忽略Load方法返回的模型架构信息。
ITransformer mlModel = mlContext.Model.Load(MLNetModelPath, out var _);
// 使用加载的模型创建一个PredictionEngine实例。
// CreatePredictionEngine方法需要模型(ITransformer)和输入输出数据模式(ModelInput和ModelOutput类)。
// 返回的PredictionEngine对象可以用来对ModelInput类型的数据进行预测,并返回ModelOutput类型的结果。
return mlContext.Model.CreatePredictionEngine<ModelInput, ModelOutput>(mlModel);
}
C#string MLNetModelPath = "./data/model.zip";
private void btnTest_Click(object sender, EventArgs e)
{
ModelInput sampleData = new ModelInput()
{
Col0 = 2.9132E-06F,
Col1 = -5.2477E-06F,
Col2 = 3.3421E-06F,
Col3 = -6.0561E-06F,
Col4 = 2.7789E-06F,
Col5 = -3.7524E-06F,
Col6 = 0.030804F,
Col7 = 0.03081F,
Col8 = 0.030806F,
Col9 = -0.03352F,
Col10 = -0.033522F,
Col11 = -0.033519F,
Col12 = 0.00076614F,
Col13 = 0.00022071F,
Col14 = 0.00048534F,
Col15 = 0.00075479F,
Col16 = 0.00025208F,
Col17 = 0.0006678F,
Col18 = 0.89583F,
Col19 = 0.89583F,
Col20 = 0.8958F,
Col21 = 0.89677F,
Col22 = 0.89677F,
Col23 = 0.89673F,
Col24 = -0.0094022F,
Col25 = -0.059481F,
Col26 = -0.29592F,
Col27 = 0.0071114F,
Col28 = 0.11911F,
Col29 = 0.31117F,
Col30 = 0.0010932F,
Col31 = 0.0010911F,
Col32 = 0.0010682F,
Col33 = -0.001344F,
Col34 = -0.0013419F,
Col35 = -0.0013755F,
Col36 = -0.65404F,
Col37 = 1.3977F,
Col38 = 3.6048F,
Col39 = -0.59314F,
Col40 = 7.6252F,
Col41 = 6.169F,
Col42 = -1.4967F,
Col43 = -1.4967F,
Col44 = -1.4967F,
Col45 = -1.5005F,
Col46 = -1.5005F,
Col47 = -1.5005F,
};
// Make a single prediction on the sample data and print results
var predictionResult = Predict(sampleData);
MessageBox.Show(predictionResult.PredictedLabel.ToString());
}

本文作者:技术老小子
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!