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

时间:2018-11-12 16:26:38

标签: c# ml.net

我正在使用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中的等效项。

可以做到吗?如果可以,怎么办?

2 个答案:

答案 0 :(得分: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中为ml.net(https://gitter.im/dotnet/mlnet)提出了这个问题,并得到Zruty0的答复

  

我最好的建议是事先将标签转换为0.(N-1),然后   训练,然后检查结果“得分”列。这将是   大小为N的向量,具有每班分数。 PredictedLabel实际上是   只需argmax(Score),您就可以通过   排序得分

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

答案 1 :(得分:0)

这是前一段时间提出的,但是我认为这仍然是一个非常相关的问题,令人惊讶的是,它没有受到太多关注,并且在任何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的并行集合。请记住,如果使用“模型构建器”重建模型,则对生成文件的更改可能会被覆盖。