4

在 ML.Net 中,我使用分类器进行文本解释。预测有一个分数列作为 float[] 和一个预测标签。这是因为最高分数与预测标签相关,但其他分数只是浮动,没有特定顺序。我怎么知道哪个分数与哪个标签相关?我怎样才能看到权重第二高的标签是什么?

例如,我得到这个:0.00005009 0.00893076 0.1274763 0.6209787 0.2425644

0.6 是我的预测标签,但我还需要查看 0.24 是哪个标签,以便了解它为什么会混淆。

标签是在管道中被字典化的文本字符串,例如“Greeting”或“Joke”,所以也许这就是为什么它们的顺序不正确?

ML.Net 中有什么方法可以将两者联系在一起吗?显示哪个分数与哪个标签相关?

4

5 回答 5

6

对于较新的版本,这将完成TryGetScoreLabelNames已被删除的技巧:

    var scoreEntries = GetSlotNames(predictor.OutputSchema, "Score");

    ...

    private static List<string> GetSlotNames(DataViewSchema schema, string name)
    {
        var column = schema.GetColumnOrNull(name);

        var slotNames = new VBuffer<ReadOnlyMemory<char>>();
        column.Value.GetSlotNames(ref slotNames);
        var names = new string[slotNames.Length];
        var num = 0;
        foreach (var denseValue in slotNames.DenseValues())
        {
            names[num++] = denseValue.ToString();
        }

        return names.ToList();
    }

(来源:http ://www.programmersought.com/article/376​​2753756/ )

当然,这需要更多的错误处理等。

于 2019-07-29T18:05:47.510 回答
1

您可以使用以下代码获取与分数对应的标签:

string[] scoreLabels;
model.TryGetScoreLabelNames(out scoreLabels);

可以在此处此处找到更多详细信息。

请注意,这可能会随着即将推出的 ML.NET 0.6 API 而改变。这些 API 将Schema直接公开并启用获取此信息(以及其他有用信息)。这可能类似于TryGetScoreLabelNames今天的工作方式。

于 2018-10-01T21:34:28.807 回答
0

从构建管道的角度可以避免这个问题。确保您的一个热编码或特征化列具有不同的列名。输入和输出列仍将出现在 DataView 中,因此您只需适当地构建输出模型。

例如:

在建造管道时

var pipeline = mlContext.Transforms.Categorical.OneHotEncoding(outputColumnName: "label_hotencoded", inputColumnName: "label")
// Append other processing in the pipeline 
.Append(...)
// Ensure that you override the default name("label") for the label column in the pipeline trainer and/or calibrator to your hot encoded label column
.Append(mlContext.BinaryClassification.Trainers.FastTree(labelColumnName: "label_hotencoded"))
.Append(mlContext.BinaryClassification.Calibrators.Platt(labelColumnName: "label_hotencoded"));

您现在可以构建输出模型 POCO 类来接收您想要的值

public class OutputModel
{      
    [ColumnName("label")]
    public string Label{ get; set; }

    [ColumnName("Score")]
    public float Score{ get; set; }
}

这样,您的输出列是人类可读的,同时您对培训师的输入列的格式正确。

注意:此技术也可用于数据中的其他列。只需确保在转换管道中的列时使用不同的列名,并在连接到“功能”时传入正确的列名。然后可以编写您的输出模型类以提取您想要的任何值。

于 2020-09-23T12:56:09.643 回答
0

由于@Samuel 的代码片段不适用于MulticlassClassificatoinMetrics我得到的,这对我有用:

public static string[] GetSlotNames(this DataViewSchema schema)
{
    VBuffer<ReadOnlyMemory<char>> buf = default;
    schema["Score"].Annotations.GetValue("SlotNames", ref buf);
    return buf.DenseValues().Select(x => x.ToString()).ToArray();
}

schema取自IDataView您在使用学习模型转换训练/验证数据时获得的数据。

var dataView = _mlContext.Data.LoadFromEnumerable(validationSet.Data);
var features = _featureExtractor.Transform(dataView);
var predictions = _learnedModel.Transform(features);

var classLabels = predictions.Schema.GetSlotNames(),

我在用着Microsoft.ML 1.5.5

于 2021-07-23T06:43:02.940 回答
0

仅供参考(至少在 ML.NET 1.7 版中),getslotnames 仅适用于文本/字符串。如果你用 Single 来尝试它,它会在 GetType 上出现错误。

于 2022-01-04T16:07:26.960 回答