Accord.net NaiveBayesLearning"索引超出了数组的范围"

Con*_*ver 5 c# accord.net .net-core

我在dot net core 1.1中使用Accord.net 3.7.0.

我使用的算法是朴素贝叶斯.学习机制的源代码如下:

    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;
    }
Run Code Online (Sandbox Code Playgroud)

我已经在一些小数据上测试了这段代码,但随着数据的增长

指数数组的边界之外

发生了错误.

因为我无法在Learn方法中导航所以我不知道该怎么做.运行时的屏幕截图是这样的:

运行时错误屏幕截图

没有额外的信息,没有内在的例外没有IDEA!

TG.

// UPDATE_1***

输入数组是180 x 4矩阵(数组),如下图所示:

输入

每行有4列.手动检查(如果需要,我也可以分享它的视频!)

输出数组是180,如下所示:

输出

它只包含0和1(如果需要,我也可以分享它的视频!).

关于NaiveBayesinLearning文档在这里:

NaiveBayesinLearning

本页底部有更多示例:

更多例子

learn这里的方法文档:

学习方法doc

Con*_*ver 4

根据他们的评论和想法,我怀疑矩阵的值。所以我对此进行了调查:

问题

如上图所示,某些行的值低于零。输入矩阵是由编码生成的,在此处的示例中使用:

天真的贝耶斯

与以下文档:

编码文档

编码-1 的值为空。就像下面的屏幕截图一样:

有问题的记录之一

所以我的解决方案是将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;
    }
Run Code Online (Sandbox Code Playgroud)

我希望这能帮助遇到同样问题的其他人。

  • 正确的解决方案取决于您希望如何处理空值。编码过滤器可以配置为通过其“DefaultMissingValueReplacement”属性将空值映射到某个预定值。但是,还有其他可能的策略,例如删除可能出现空值的变量(列)或实例(行)。这是框架不自动处理它们的唯一原因,但异常应该有更好的消息! (2认同)
  • 在这种情况下,将在设置默认缺失值之前创建特定于列的选项...作为解决方法,您可以在码本已构建。这应该迫使它们被您想要的值替换。 (2认同)
  • 谢谢@Cesar,这也是一个很好的解决方案。Accord.net 非常棒。 (2认同)