ML.Net 0.7 - 获取多类分类的分数和标签
ML.Net 0.7 - Get Scores and Labels for MulticlassClassification
我正在使用 ML.NET 0.7 并且有一个多class分类模型,结果如下 class:
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 中找到等效项。
这能做到吗?如果是怎么办?
这可能不是您正在寻找的答案,但我最终从 TryGetScoreLabelNames 复制了代码(自 0.7 起它位于旧命名空间中)并对其进行调整以使用我的输入数据中的模式。下面的 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
得到了这个回复
my best suggestion is to convert labels to 0..(N-1) beforehand, then
train, and then inspect the resulting 'Score' column. It'll be a
vector of size N, with per-class scores. PredictedLabel is actually
just argmax(Score), and you can get the 2nd and other candidates by
sorting Score
如果您有一组静态的 类,这可能是更好的选择,但我的情况是有一组不断增长的 类。
不久前有人问过这个问题,但我认为这仍然是一个非常相关的问题,令人惊讶的是它没有引起很大的关注,并且在任何 Microsoft ML.NET 个教程。上面的示例代码需要进行一些调整才能使其与 v1.5(预览版)一起使用,所以我想我会 post 我是如何让它为其他偶然发现它的人工作的。
在 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
的并行集合。请记住,如果您使用模型构建器重建模型,对生成的文件所做的更改可能会被覆盖。
我正在使用 ML.NET 0.7 并且有一个多class分类模型,结果如下 class:
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 中找到等效项。
这能做到吗?如果是怎么办?
这可能不是您正在寻找的答案,但我最终从 TryGetScoreLabelNames 复制了代码(自 0.7 起它位于旧命名空间中)并对其进行调整以使用我的输入数据中的模式。下面的 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
得到了这个回复my best suggestion is to convert labels to 0..(N-1) beforehand, then train, and then inspect the resulting 'Score' column. It'll be a vector of size N, with per-class scores. PredictedLabel is actually just argmax(Score), and you can get the 2nd and other candidates by sorting Score
如果您有一组静态的 类,这可能是更好的选择,但我的情况是有一组不断增长的 类。
不久前有人问过这个问题,但我认为这仍然是一个非常相关的问题,令人惊讶的是它没有引起很大的关注,并且在任何 Microsoft ML.NET 个教程。上面的示例代码需要进行一些调整才能使其与 v1.5(预览版)一起使用,所以我想我会 post 我是如何让它为其他偶然发现它的人工作的。
在 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
的并行集合。请记住,如果您使用模型构建器重建模型,对生成的文件所做的更改可能会被覆盖。