ML.Net 0.7 - 获取多类分类的分数和标签

ML.Net 0.7 - Get Scores and Labels for MulticlassClassification

我正在使用 ML.NET 0.7 并且有一个多class分类模型,结果如下 class:

public class TestClassOut
{
  public string Id { get; set; }
  public float[] Score { get; set; }
  public string PredictedLabel { get; set; }
}

我想知道 Scores 属性 上的分数和相应的标签。感觉我应该能够使 属性 成为 Tuple<string,float> 或类似的东西以获得分数所代表的标签。

我了解到 V0.5 上有一个方法:

model.TryGetScoreLabelNames(out scoreLabels);

但似乎无法在 V0.7 中找到等效项。

这能做到吗?如果是怎么办?

这可能不是您正在寻找的答案,但我最终从 TryGetScoreLabelNames 复制了代码(自 0.7 起它位于旧命名空间中)并对其进行调整以使用我的输入数据中的模式。下面的 dataView 是我根据预测输入数据创建的 IDataView,因此我可以从中获取架构。

public bool TryGetScoreLabelNames(out string[] names, string scoreColumnName = DefaultColumnNames.Score)
{
    names = (string[])null;
    Schema outputSchema = model.GetOutputSchema(dataView.Schema);
    int col = -1;
    if (!outputSchema.TryGetColumnIndex(scoreColumnName, out col))
        return false;
    int valueCount = outputSchema.GetColumnType(col).ValueCount;
    if (!outputSchema.HasSlotNames(col, valueCount))
        return false;
    VBuffer<ReadOnlyMemory<char>> vbuffer = new VBuffer<ReadOnlyMemory<char>>();
    outputSchema.GetMetadata<VBuffer<ReadOnlyMemory<char>>>("SlotNames", col, ref vbuffer);
    if (vbuffer.Length != valueCount)
        return false;
    names = new string[valueCount];
    int num = 0;
    foreach (ReadOnlyMemory<char> denseValue in vbuffer.DenseValues())
        names[num++] = denseValue.ToString();
    return true;
}

我也在 gitter 中为 ml.net (https://gitter.im/dotnet/mlnet) 问了这个问题,并从 Zruty0

得到了这个回复

my best suggestion is to convert labels to 0..(N-1) beforehand, then train, and then inspect the resulting 'Score' column. It'll be a vector of size N, with per-class scores. PredictedLabel is actually just argmax(Score), and you can get the 2nd and other candidates by sorting Score

如果您有一组静态的 类,这可能是更好的选择,但我的情况是有一组不断增长的 类。

不久前有人问过这个问题,但我认为这仍然是一个非常相关的问题,令人惊讶的是它没有引起很大的关注,并且在任何 Microsoft ML.NET 个教程。上面的示例代码需要进行一些调整才能使其与 v1.5(预览版)一起使用,所以我想我会 post 我是如何让它为其他偶然发现它的人工作的。

ConsumeModel.cs 中(假设您在 Visual Studio 中使用模型生成器):

...
            // Use model to make prediction on input data
            ModelOutput result = predEngine.Predict(input);
            var labelNames = new List<string>();

            var column = predEngine.OutputSchema.GetColumnOrNull("label");
            if (column.HasValue)
            {
                VBuffer<ReadOnlyMemory<char>> vbuffer = new VBuffer<ReadOnlyMemory<char>>();
                column.Value.GetKeyValues(ref vbuffer);

                foreach (ReadOnlyMemory<char> denseValue in vbuffer.DenseValues())
                    labelNames.Add(denseValue.ToString());
            }
...

最终结果 labelNames 现在是 result.Score 的并行集合。请记住,如果您使用模型构建器重建模型,对生成的文件所做的更改可能会被覆盖。