【问题标题】:ML.Net 0.7 - Get Scores and Labels for MulticlassClassificationML.Net 0.7 - 获取多类分类的分数和标签
【发布时间】:2018-11-12 16:26:37
【问题描述】:

我正在使用 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 中找不到等价物。

这可以吗?如果有怎么办?

【问题讨论】:

    标签: c# ml.net


    【解决方案1】:

    这可能不是您要寻找的答案,但我最终从 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(Score),您可以通过以下方式获得第二名和其他候选人 排序分数

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

    【讨论】:

    • 注意 ValueCount 将在 0.8 中消失,因此您必须改用 ((VectorType)col).Size
    【解决方案2】:

    这是不久前提出的问题,但我认为这仍然是一个非常相关的问题,令人惊讶的是它没有得到很多关注,并且在任何 Microsoft ML 中都没有提及(截至撰写本文时)。网络教程。上面的示例代码需要进行一些调整才能使其与 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 的并行集合的最终结果。请记住,如果您使用模型构建器重建模型,对生成文件的更改可能会被覆盖。

    【讨论】:

    • 很惊讶这还没有收到更多的爱。很容易让我返回一个元组。再次惊讶它不是功能。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-01
    • 1970-01-01
    • 2019-04-01
    • 2019-03-25
    相关资源
    最近更新 更多