我正在尝试在不创建作为模型输入和输出的类的情况下,通用地使用ML.NET。为此,在使用以下代码创建模型后:
public static (ITransformer model, double accuracy) TrainMultiClassModel(MulticlassExperimentSettings experimentSettings, MLContext mlContext, IDataView myview, string LabelName) { ITransformer trainedModel; MulticlassClassificationExperiment experiment = mlContext.Auto().CreateMulticlassClassificationExperiment(experimentSettings); ExperimentResult<MulticlassClassificationMetrics> experimentResult = experiment.Execute(myview, LabelName); RunDetail<MulticlassClassificationMetrics> best = experimentResult.BestRun; trainedModel = best.Model; return (trainedModel, best.ValidationMetrics.MacroAccuracy); }
其中myView包含一个CSV文件,其DataKinds设置正确。
然后我通过运行类似下面的代码来执行该模型:
MemoryStream modelStream = new MemoryStream(ModelData); ITransformer trainedModel = mlContext.Model.Load(modelStream, out var modelInputSchema); var predictions = trainedModel.Transform(myview);
同样,myView包含来自CSV文件的数据,只是预测列为空。
现在我们有了“predictions”,它是IDataView类型。
对于回归结果,这很简单。查找名为“Score”的Schema并将其加载为float:
float[] scoreColumn = predictions.GetColumn<float>("Score").ToArray();
但对于多类别实验该如何操作呢?有一个名为“PredictedLabel”的Schema,类型为“String”,但以这种方式读取时,它包含0到1之间的数字:
var labelColumn = predictions.Schema.FirstOrDefault(s => s.Name == "PredictedLabel" && s.IsHidden == false);string[] scoreColumn = predictions.GetColumn<string>(labelColumn).ToArray();
我如何获取实际的(在本例中是物种)名称?或者我必须以某种方式将数字映射到名称吗?我应该使用哪个映射表呢?
提前感谢您。
编辑:Eric的代码给出了这个列表:
1.41.90.20.4 0.30.10.50.61.51.31.61.01.11.81.21.72.52.12.22.02.42.3
这些是22个,这很奇怪:没有正确的物种有22个字符(如果那是名称的字符),而且我只输入了4行数据来解决问题。“PredictedLabel”现在输出4个值,但仍然是数字:
回答:
为完整起见,并解决最初问题的困惑,这里是答案。
首先,为什么“PredictedLabel”和“GetKeyValues”(来自Eric的答案)没有提供可用的结果?这里的问题是我使用IDataView的方式。在训练数据时,我加载了整个CSV文件,包括“ID”列,而在执行模型时我没有提供该列(因为该列对使用模型没有价值)。在训练和执行时始终省略“ID”列并保持相同的CSV布局后,Eric和我的方法都开始工作了。
所以当你想将结果解释为正确的格式时,首先看看结果DataView Schema中是否存在“PredictedLabel”。
if (predictions.Schema.Any(s => s.Name == "PredictedLabel"))
如果存在,请检查其DataType。这就是你区分多类别和二元结果的方法:
var labelColumn = predictions.Schema.FirstOrDefault(s => s.Name == "PredictedLabel" && s.IsHidden == false); if (labelColumn.Type.ToString() == "Boolean"){ bool[] binaryResults = predictions.GetColumn<bool>(labelColumn).ToArray();}
(或者)
if (labelColumn.Type.ToString() == "String"){ string[] multiclassResults = predictions.GetColumn<string>(labelColumn).ToArray();}
现在multiclassResults将包含你记录的多类别结果作为字符串。
如果没有PredictedLabel,应该有一个“Score”Schema,其中包含你的回归结果:
float[] regressionResults = predictions.GetColumn<float>("Score").ToArray();