accord-net / framework

Machine learning, computer vision, statistics and general scientific computing for .NET
http://accord-framework.net
GNU Lesser General Public License v2.1
4.49k stars 1.99k forks source link

Strange issue: #1056

Open superbolide opened 6 years ago

superbolide commented 6 years ago

What would you like to submit? (put an 'x' inside the bracket that applies)

An unhandled exception of type 'System.IndexOutOfRangeException' occurred in Accord.Math.dll

I try this (my fist app with accord library):

        private void btTest_Click(object sender, EventArgs e)
        {
            DataTable table = new ExcelReader("g://doggy//examples.xls").GetWorksheet("Classification - Yin Yang");

            // Convert the DataTable to input and output vectors
            double[][] inputs = table.ToJagged<double>("X", "Y");
            int[] outputs = table.Columns["G"].ToArray<int>();

            // Plot the data
            ScatterplotBox.Show("Yin-Yang", inputs, outputs).Hold();

            naiveBayes(inputs, outputs);
        }
        private static void naiveBayes(double[][] inputs, int[] outputs)
        {
            // In our problem, we have 2 classes (samples can be either
            // positive or negative), and 2 inputs (x and y coordinates).

            // Create a Naive Bayes learning algorithm
            var teacher = new NaiveBayesLearning<NormalDistribution>();

            // Use the learning algorithm to learn
            var nb = teacher.Learn(inputs, outputs);  **# <<--- here come the problem**

            // At this point, the learning algorithm should have
            // figured important details about the problem itself:
            int numberOfClasses = nb.NumberOfClasses; // should be 2 (positive or negative)
            int nunmberOfInputs = nb.NumberOfInputs;  // should be 2 (x and y coordinates)

            // Classify the samples using the model
            int[] answers = nb.Decide(inputs);

            // Plot the results
            ScatterplotBox.Show("Expected results", inputs, outputs);
            ScatterplotBox.Show("Naive Bayes results", inputs, answers)
                .Hold();
        }
superbolide commented 6 years ago

This happen with Accord.NET-3.8.0 and vs2010:

using Accord.Controls;
using Accord.IO;
using Accord.MachineLearning.Bayes;
using Accord.MachineLearning.DecisionTrees;
using Accord.MachineLearning.DecisionTrees.Learning;
using Accord.MachineLearning.VectorMachines.Learning;
using Accord.Math;
using Accord.Neuro;
using Accord.Neuro.Learning;
using Accord.Statistics;
using Accord.Statistics.Analysis;
using Accord.Statistics.Distributions.Univariate;
using Accord.Statistics.Kernels;
using Accord.Statistics.Models.Regression;
using Accord.Statistics.Models.Regression.Fitting;
superbolide commented 6 years ago

If a remove using system.numerics do this:

            double[][] inputs =
            {
                /* 1.*/ new double[] { 0, 0 },
                /* 2.*/ new double[] { 1, 0 }, 
                /* 3.*/ new double[] { 0, 1 }, 
                /* 4.*/ new double[] { 1, 1 },
            };

            int[] outputs =
            { 
                /* 1. 0 xor 0 = 0: */ 0,
                /* 2. 1 xor 0 = 1: */ 1,
                /* 3. 0 xor 1 = 1: */ 1,
                /* 4. 1 xor 1 = 0: */ 0,
            };

It works!

cesarsouza commented 6 years ago

Hi @superbolide,

Many thanks for opening the issue! The problem was that the NaiveBayes learning class was not validating the inputs correctly when one is trying to learn a multi-class classifier using only two classes where those classes are being represented as -1 and +1 values.

The solution would be to change line

int[] outputs = table.Columns["G"].ToArray<int>();

to be

int[] outputs = Classes.ToZeroOne(table.Columns["G"].ToArray<int>());

to force the outputs to be represented as 0 or 1 values instead of -1 or +1.

I will also be committing a fix to improve argument validation in this case.

Regards, Cesar