Индекс Accord.net NaiveBayesLearning находился за пределами массива

Я использую Accord.net 3.7.0 в dot net core 1.1.

Алгоритм, который я использую, является наивным байесовским. А исходный код механизма обучения выглядит следующим образом:

    public LearningResultViewModel NaiveBayes(int[][] inputs, int[] outputs)
    {
        // Create a new Naive Bayes learning
        var learner = new NaiveBayesLearning();

        // Learn a Naive Bayes model from the examples
        NaiveBayes nb = learner.Learn(inputs, outputs);

        #region test phase
        // Compute the machine outputs
        int[] predicted = nb.Decide(inputs);

        // Use confusion matrix to compute some statistics.
        ConfusionMatrix confusionMatrix = new ConfusionMatrix(predicted, outputs, 1, 0);
        #endregion

        LearningResultViewModel result = new LearningResultViewModel()
        {
            Distributions = nb.Distributions,
            NumberOfClasses = nb.NumberOfClasses,
            NumberOfInputs = nb.NumberOfInputs,
            NumberOfOutputs = nb.NumberOfOutputs,
            NumberOfSymbols = nb.NumberOfSymbols,
            Priors = nb.Priors,
            confusionMatrix = confusionMatrix
        };

        return result;
    }

Я протестировал этот фрагмент кода на небольшом количестве данных, но по мере роста данных

Индекс находился вне границ массива

Возникла ошибка.

Поскольку я не могу перемещаться по методу Learn, я не знаю, что делать. снимок экрана во время выполнения таков:

Снимок экрана с ошибкой во время выполнения

Никакой дополнительной информации, никакого внутреннего исключения, никакой ИДЕИ!!!

TG.

// ОБНОВЛЕНИЕ_1 ***

Входной массив представляет собой матрицу (массив) 180 на 4, как показано на изображении ниже:

Входы

который имеет 4 столбца в каждой строке. проверено вручную (если нужно, могу и видео выложить!!!)

Выходной массив равен 180, как показано здесь:

Выходы

который содержит только 0 и 1 (я также могу поделиться его видео, если нужно!!!).

А о документе NaiveBayesinLearning здесь:

NaiveBayesinLearning

Еще примеры внизу этой страницы:

Другие примеры

И документация по методу learn здесь:

документ по методу обучения


person ConductedClever    schedule 22.08.2017    source источник
comment
Я думаю, что мы можем догадываться так же, как и вы, а возможно, и больше. Ваш массив inputs прямоугольный? Какие у вас есть документы о Learn? Ожидается ли, что выходной массив имеет ту же длину, что и конкретный входной массив и т. д. Возможно, вам придется декомпилировать любые библиотечные коды для этого метода Learn, чтобы вы могли видеть, как он обращается к массивам   -  person Caius Jard    schedule 22.08.2017
comment
Мы не можем видеть код, выбрасывающий исключение, мы не знаем, что вы передаете этому методу, но мы можем догадаться, почему он терпит неудачу?   -  person oerkelens    schedule 22.08.2017
comment
@CaiusJard Может быть, кто-то сталкивался с этим раньше. Но это также нормально, что я проверяю ваши догадки. Да, в этом примере входные данные представляют собой массив 180 на 4, а выходные данные представляют собой вектор 180.   -  person ConductedClever    schedule 22.08.2017
comment
@oerkelens Я добавлю дополнительную информацию к вопросу, как вы заметили. минуточку.   -  person ConductedClever    schedule 22.08.2017
comment
Входные данные наверняка полностью заполнены 180 экземплярами массива из 4 длин?   -  person Caius Jard    schedule 22.08.2017
comment
@All Я добавил дополнительную информацию.   -  person ConductedClever    schedule 22.08.2017


Ответы (1)


По комментариям и идеям от них я заподозрил значения матрицы. Итак, я исследовал это:

проблема

Как показано на изображении выше, некоторые строки имеют значения ниже нуля. Матрица входов генерируется кодификацией, которая используется в примерах здесь:

NaiveBayes

с документами ниже:

Документы по кодификации

кодификация -1 была со значениями null. Как на снимке экрана ниже:

одна из проблемных записей

Итак, мое решение заключалось в замене значений null на "null". Но может быть есть лучшие решения.

Теперь вызывающий метод, который содержит фиксированные данные, выглядит следующим образом:

    public LearningResultViewModel Learn(EMVDBContext dBContext, string userId, LearningAlgorithm learningAlgorithm)
    {
        var learningDataRaw = dBContext.Mutants
            .Include(mu => mu.MutationOperator)
            .Where(mu => mu.Equivalecy == 0 || mu.Equivalecy == 10);

        string[] featureTitles = new string[] {
        "ChangeType",
        "OperatorName",
        "OperatorBefore",
        "OperatorAfter",
        };

        string[][] learningInputNotCodified = learningDataRaw.Select(ldr => new string[] {
            ldr.ChangeType.ToString(),
            ldr.MutationOperator.Name??"null",
            ldr.MutationOperator.Before??"null",
            ldr.MutationOperator.After??"null",
        }).ToArray();

        int[] learningOutputNotCodified = learningDataRaw.Select(ldr => ldr.Equivalecy == 0 ? 0 : 1).ToArray();

        #region Codification phase
        // Create a new codification codebook to
        // convert strings into discrete symbols
        Codification codebook = new Codification(featureTitles, learningInputNotCodified);

        // Extract input and output pairs to train
        int[][] learningInput = codebook.Transform(learningInputNotCodified);

        switch (learningAlgorithm)
        {
            case LearningAlgorithm.NaiveBayesian:
                return learningService.NaiveBayes(learningInput, learningOutputNotCodified);
                break;
            case LearningAlgorithm.SVM:
                break;
            default:
                break;
        }
        #endregion

        return null;
    }

Я хочу, чтобы это помогло другим, столкнувшимся с той же проблемой.

person ConductedClever    schedule 22.08.2017
comment
Правильное решение зависит от того, как вы хотели бы иметь дело с нулевыми значениями. Фильтр кодификации можно настроить для сопоставления нулевых значений с некоторым предварительно определенным значением через его свойство DefaultMissingValueReplacement. Однако существуют и другие возможные стратегии, такие как удаление переменных (столбцов) или экземпляров (строк), где могут встречаться нулевые значения. Это единственная причина, по которой фреймворк не обрабатывает их автоматически, но, конечно же, исключение должно было иметь лучшее сообщение! - person Cesar; 23.08.2017
comment
@Cesar, поскольку у алгоритмов обучения есть проблема с отрицательными значениями, я думаю, что лучше настроить кодировку так, чтобы не использовать -1 по умолчанию или, как вы упомянули, иметь лучшее сообщение об исключении. - person ConductedClever; 24.08.2017
comment
@Cesar Я протестировал этот фрагмент кода Codification codebook = new Codification(featureTitles, learningInputNotCodified) { DefaultMissingValueReplacement = 0 };, но он все равно генерирует -1 вместо нулевых значений. Не могли бы вы написать правильный код. Спасибо. - person ConductedClever; 24.08.2017
comment
В этом случае специфичные для столбца параметры создаются до того, как будет установлено отсутствующее значение по умолчанию... В качестве обходного пути вы можете установить их непосредственно с помощью codebook["OperatorName"].MissingValueReplacement = 0 после создания кодовой книги. Это должно заставить их заменить на нужное вам значение. - person Cesar; 24.08.2017
comment
Спасибо @Cesar, это тоже хорошее решение. Accord.net — это круто. - person ConductedClever; 24.08.2017