ML.Net0.7-获取多类别分类的分数和标签



我使用的是ML.NET 0.7,有一个MulticlassClassification模型,其结果类如下:

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版本的Legacy命名空间中(,并对其进行了调整,以使用输入数据中的模式。下面的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 for ml.net中也问过这个问题(https://gitter.im/dotnet/mlnet)并从Zruty0 得到了这个响应

我最好的建议是事先将标签转换为0..(N-1(,然后培训,然后检查结果的"分数"栏。这将是一个大小为N的向量,每个类的分数。PredictedLabel实际上只要argmax(分数(,你就可以通过排序分数

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

这是不久前提出的问题,但我认为这仍然是一个非常相关的问题,令人惊讶的是,这个问题没有得到太多关注,(截至撰写本文时(在任何Microsoft ML.NET教程中都没有提到。上面的示例代码需要进行一些调整才能与v1.5(预览(一起使用,所以我想我应该为其他偶然发现这一点的人发布我是如何让它工作的。

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的并行集合。请记住,如果使用模型生成器重建模型,对生成的文件所做的更改可能会被覆盖。

最新更新