Не удается получить надлежащий трансформатор для PFI

#.net #ml.net

#.net #ml.net

Вопрос:

Я пытаюсь следовать примеру для PFI. Последнее преобразование моего конвейера — это ColumnCopyingTransformer , так что pipeline.Fit(trainingDataView).LastTransformer это тот тип. Однако, MLContext.MulticlassClassification.PermutationFeatureImportance ожидает IPredictionTransformer<IPredictor> . Такое ощущение, что пример был создан с учетом очень специфического конвейера.

Я получил этот совет через ML.Net канал gitter:

Вы можете выполнить итерацию по вашему конвейеру цепочки трансформаторов.Подгоняйте (trainingDataView), пока не найдете что-то, что является IPredictionTransformer

Однако я не вижу, как выполнить эту итерацию. Я попробовал следующее, но получил null для предиктора.

 var trainedModel = (TransformerChain<ITransformer>)mlContext.Model.Load(stream);
var predictor = trainedModel.OfType<IPredictionTransformer<IPredictor>>().FirstOrDefault();
  

Чего мне не хватает?

Ответ №1:

По-видимому, цепочки трансформаторов могут иметь дочерние цепочки трансформаторов, начиная с ML.Net 0.10. Следующее возвращает желаемый преобразователь:

 public static IPredictionTransformer<IPredictor> FindPredictionTransformer(this TransformerChain<ITransformer> chain)
{
    var xf = chain.OfType<IPredictionTransformer<IPredictor>>().FirstOrDefault();
    if (xf != null) return xf;

    foreach (var t in chain.OfType<TransformerChain<ITransformer>>())
    {
        var xfChild = t.OfType<IPredictionTransformer<IPredictor>>().FirstOrDefault();
        if (xfChild != null) return xfChild;
    }

    return null;
}
  

Использование:

 TransformerChain<ITransformer> trainedModel;

using (var stream = new FileStream(modelPath, FileMode.Open, FileAccess.Read, FileShare.Read))
{
    trainedModel = (TransformerChain<ITransformer>)mlContext.Model.Load(stream);
}

var predictionTransformer = trainedModel.FindPredictionTransformer();

var featureImportance = PfiHelper.CalculatePfi(mlContext, predictionTransformer, trainingDataView);
  

Мне неясно, почему было необходимо выполнить итерацию дочерних элементов TransformerChain<ITransformer> или, возможно, в некоторых случаях потребуется поиск глубже (внуки и т.д.). Я был бы признателен за комментарий или дополнительный ответ, разъясняющий эту проблему.

Комментарии:

1. Примечание: Это решение работает для ML.Net 0.10. Он прерывается из-за недокументированного изменения в 0.11. Работаю над обновлением решения.