【问题标题】:ML.NET Show which score relates to which labelML.NET 显示哪个分数与哪个标签相关
【发布时间】:2018-10-01 21:13:02
【问题描述】:

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

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

0.6 是我的预测标签,但我还需要查看 0.24 是哪个标签,这样我才能知道它为什么会混淆。

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

ML.Net 中有没有办法将两者联系起来?显示哪个分数与哪个标签相关?

【问题讨论】:

    标签: c# artificial-intelligence ml.net


    【解决方案1】:

    对于较新的版本,这个可以解决问题,因为 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/3762753756/

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

    【讨论】:

    • 谢谢,这很有帮助:)
    【解决方案2】:

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

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

    更多详情请见herehere

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

    【讨论】:

    【解决方案3】:

    从构建管道的角度可以避免这个问题。确保您的一个热编码或特征化列具有不同的列名。输入和输出列仍会出现在 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; }
    }
    

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

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

    【讨论】:

      【解决方案4】:

      由于@Samuel 的代码 sn-p 不适用于我得到的 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

      【讨论】:

        【解决方案5】:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-12-06
          • 1970-01-01
          • 2020-11-15
          • 2012-12-07
          相关资源
          最近更新 更多