ML.NET 显示哪个分数与哪个标签相关
ML.NET Show which score relates to which label
对于 ML.Net 我正在使用分类器进行文本解释。预测有一个作为 float[] 的分数列和一个预测标签。这是因为最高分与预测标签相关,但其他分数只是浮点数,没有特定顺序。我怎么知道哪个分数与哪个标签相关?如何查看权重第二高的标签?
例如,我得到这个:
0.00005009
0.00893076
0.1274763
0.6209787
0.2425644
0.6 是我预测的标签,但我还需要查看 0.24 是哪个标签,以便了解它为什么会混淆。
标签是文本字符串,例如 "Greeting" 或 "Joke",它们在管道中被字典化,所以也许这就是它们顺序不正确的原因?
有什么办法可以ML.Net把两者link结合起来吗?要显示哪个分数与哪个标签相关?
您可以使用以下代码获取分数对应的标签:
string[] scoreLabels;
model.TryGetScoreLabelNames(out scoreLabels);
请注意,这可能会随着即将推出的 ML.NET 0.6 API 而改变。这些 API 将直接公开 Schema
并允许获取此信息(以及其他有用信息)。这可能类似于 TryGetScoreLabelNames
今天的工作方式。
对于较新的版本,这个可以解决问题,因为 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/)
当然这需要更多的错误处理等
这个问题从构建管道的角度是可以避免的。确保您的一个热编码或特征化列具有不同的列名称。输入和输出列仍会出现在 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 class 以接收您想要的值
public class OutputModel
{
[ColumnName("label")]
public string Label{ get; set; }
[ColumnName("Score")]
public float Score{ get; set; }
}
这样你的输出列是 human-readable,同时你输入给培训师的列是正确的格式。
注意:此技术也可用于数据中的其他列。只需确保在转换管道中的列时使用不同的列名,并在连接到“功能”时传入正确的列名。然后可以编写您的输出模型 class 以提取您想要的任何值。
由于@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
取自使用学习模型转换 training/validation 数据时获得的 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
仅供参考(至少在 ML.NET 版本 1.7 中),getslotnames 仅适用于 text/strings。如果你用 Single 尝试它,它会因 GetType 错误而崩溃。
对于 ML.Net 我正在使用分类器进行文本解释。预测有一个作为 float[] 的分数列和一个预测标签。这是因为最高分与预测标签相关,但其他分数只是浮点数,没有特定顺序。我怎么知道哪个分数与哪个标签相关?如何查看权重第二高的标签?
例如,我得到这个: 0.00005009 0.00893076 0.1274763 0.6209787 0.2425644
0.6 是我预测的标签,但我还需要查看 0.24 是哪个标签,以便了解它为什么会混淆。
标签是文本字符串,例如 "Greeting" 或 "Joke",它们在管道中被字典化,所以也许这就是它们顺序不正确的原因?
有什么办法可以ML.Net把两者link结合起来吗?要显示哪个分数与哪个标签相关?
您可以使用以下代码获取分数对应的标签:
string[] scoreLabels;
model.TryGetScoreLabelNames(out scoreLabels);
请注意,这可能会随着即将推出的 ML.NET 0.6 API 而改变。这些 API 将直接公开 Schema
并允许获取此信息(以及其他有用信息)。这可能类似于 TryGetScoreLabelNames
今天的工作方式。
对于较新的版本,这个可以解决问题,因为 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/)
当然这需要更多的错误处理等
这个问题从构建管道的角度是可以避免的。确保您的一个热编码或特征化列具有不同的列名称。输入和输出列仍会出现在 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 class 以接收您想要的值
public class OutputModel
{
[ColumnName("label")]
public string Label{ get; set; }
[ColumnName("Score")]
public float Score{ get; set; }
}
这样你的输出列是 human-readable,同时你输入给培训师的列是正确的格式。
注意:此技术也可用于数据中的其他列。只需确保在转换管道中的列时使用不同的列名,并在连接到“功能”时传入正确的列名。然后可以编写您的输出模型 class 以提取您想要的任何值。
由于@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
取自使用学习模型转换 training/validation 数据时获得的 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
仅供参考(至少在 ML.NET 版本 1.7 中),getslotnames 仅适用于 text/strings。如果你用 Single 尝试它,它会因 GetType 错误而崩溃。