Пример #1
0
        public void RunTest3()
        {
            // Example XOR problem
            double[][] inputs =
            {
                new double[] { 0, 0 }, // 0 xor 0: 1 (label +1)
                new double[] { 0, 1 }, // 0 xor 1: 0 (label -1)
                new double[] { 1, 0 }, // 1 xor 0: 0 (label -1)
                new double[] { 1, 1 }  // 1 xor 1: 1 (label +1)
            };

            // Dichotomy SVM outputs should be given as [-1;+1]
            int[] labels =
            {
                1, -1, -1, 1
            };

            // Create a Kernel Support Vector Machine for the given inputs
            KernelSupportVectorMachine svm = new KernelSupportVectorMachine(new Gaussian(0.1), inputs[0].Length);

            // Instantiate a new learning algorithm for SVMs
            SequentialMinimalOptimization smo = new SequentialMinimalOptimization(svm, inputs, labels);

            // Set up the learning algorithm
            smo.Complexity = 1.0;

            // Run the learning algorithm
            double error = smo.Run();

            Assert.IsFalse(svm.IsProbabilistic);

            // Instantiate the probabilistic learning calibration
            var calibration = new ProbabilisticOutputCalibration(svm, inputs, labels);

            // Run the calibration algorithm
            double loglikelihood = calibration.Run();

            Assert.IsTrue(svm.IsProbabilistic);

            // Compute the decision output for one of the input vectors,
            // while also retrieving the probability of the answer

            double probability;
            int    decision = svm.Compute(inputs[0], out probability);

            // At this point, decision is +1 with a probability of 75%

            Assert.AreEqual(1, decision);
            Assert.AreEqual(0.74999975815069375, probability, 1e-10);
        }
Пример #2
0
        private static void sparseMachineProbabilistic(Sparse <double>[] inputs, double[] doubleOutputs)
        {
            // The dataset has output labels as 4 and 2. We have to convert them
            // into negative and positive labels so they can be properly processed.
            //
            bool[] outputs = doubleOutputs.Apply(x => x == 2.0 ? false : true);

            // Create a learning algorithm for Sparse data. The first generic argument
            // of the learning algorithm below is the chosen kernel function, and the
            // second is the type of inputs the machine should accept. Note that, using
            // those interfaces, it is possible to define custom kernel functions that
            // operate directly on double[], string[], graphs, trees or any object:
            var teacher = new LinearDualCoordinateDescent <Linear, Sparse <double> >()
            {
                Loss       = Loss.L2,
                Complexity = 1000, // Create a hard-margin SVM
                Tolerance  = 1e-5
            };

            // Use the learning algorithm to Learn
            var svm = teacher.Learn(inputs, outputs);

            // Create a probabilistic calibration algorithm based on Platt's method:
            var calibration = new ProbabilisticOutputCalibration <Linear, Sparse <double> >()
            {
                Model = svm
            };

            // Let's say that instead of having our data as bool[], we would
            // have received it as double[] containing the actual probabilities
            // associated with each sample:
            doubleOutputs.Apply(x => x == 2.0 ? 0.05 : 0.87, result: doubleOutputs);

            // Calibrate the SVM using Platt's method
            svm = calibration.Learn(inputs, doubleOutputs);

            // Compute the machine's answers
            bool[] answers = svm.Decide(inputs);

            // Compute the machine's probabilities
            double[] prob = svm.Probability(inputs);

            // Create a confusion matrix to show the machine's performance
            var m = new ConfusionMatrix(predicted: answers, expected: outputs);

            // Show it onscreen
            DataGridBox.Show(new ConfusionMatrixView(m)).Hold();
        }
Пример #3
0
        public void RunTest1()
        {
            double[][] inputs =
            {
                new double[] { -1, -1 },
                new double[] { -1,  1 },
                new double[] {  1, -1 },
                new double[] {  1,  1 }
            };

            int[] outputs =
            {
                -1,
                1,
                1,
                -1
            };

            KernelSupportVectorMachine svm = new KernelSupportVectorMachine(new Gaussian(3.6), 2);

            var smo = new SequentialMinimalOptimization(svm, inputs, outputs);

            double error1 = smo.Run();

            Assert.AreEqual(0, error1);

            double[] distances = new double[outputs.Length];
            for (int i = 0; i < outputs.Length; i++)
            {
                int y = svm.Compute(inputs[i], out distances[i]);
                Assert.AreEqual(outputs[i], y);
            }


            var target = new ProbabilisticOutputCalibration(svm, inputs, outputs);

            double ll0 = target.LogLikelihood(inputs, outputs);

            double ll1 = target.Run();

            double ll2 = target.LogLikelihood(inputs, outputs);

            Assert.AreEqual(5.5451735748694571, ll1);
            Assert.AreEqual(ll1, ll2);
            Assert.IsTrue(ll1 > ll0);

            double[] newdistances = new double[outputs.Length];
            for (int i = 0; i < outputs.Length; i++)
            {
                int y = svm.Compute(inputs[i], out newdistances[i]);
                Assert.AreEqual(outputs[i], y);
            }

            double[] probs = new double[outputs.Length];
            for (int i = 0; i < outputs.Length; i++)
            {
                int y;
                probs[i] = svm.ToMulticlass().Probability(inputs[i], out y);
                Assert.AreEqual(outputs[i], y == 1 ? 1 : -1);
            }

            Assert.AreEqual(0.25, probs[0], 1e-5);
            Assert.AreEqual(0.75, probs[1], 1e-5);
            Assert.AreEqual(0.75, probs[2], 1e-5);
            Assert.AreEqual(0.25, probs[3], 1e-5);

            foreach (var p in probs)
            {
                Assert.IsFalse(Double.IsNaN(p));
            }
        }
Пример #4
0
        static void Main(string[] args)
        {
            if (args.Length != 1)
            {
                WriteLine("Usage:\n\n\ttrain.exe <folder path>");
                return;
            }

            WriteLine("Platform: " + IntPtr.Size);

            var stemmer = new SnowballStemmer();

            using (var zip = new ZipOutputStream(
                       OpenWrite(
                           Combine(
                               GetDirectoryName(args[0]),
                               GetFileName(args[0]) + ".cl"))))
            {
                WriteLine("Reading dictionary...");
                var dicPath = Combine(args[0], "dic.txt");
                var dicText = File.Exists(dicPath) ? ReadAllLines(dicPath) : new string[0];

                WriteLine("Building dictionary...");
                var text = ReadAllLines(Combine(args[0], "text.txt"));

                var dic = new Dictionary(dicText.Concat(text
                                                        .SelectMany(jd => jd.StemText(stemmer))
                                                        .ToLookup(w => w.Stemmed)
                                                        .Select(l => new { Stemmed = l.Key, Count = l.Count() })
                                                        .OrderByDescending(w => w.Count)
                                                        .Select(w => w.Stemmed))
                                         .Take(5000)
                                         .ToArray());

                zip.PutNextEntry(new ZipEntry("dic.txt"));
                using (var writer = new StreamWriter(zip, UTF8, 4096, true))
                    dic.WriteTo(writer);
                zip.CloseEntry();

                WriteLine("Vectorizing...");
                var input = new double[text.Length][];
                for (int i = 0; i < text.Length; i++)
                {
                    input[i] = dic.Vectorize(new Document(text[i], stemmer));
                }

                var classifiers = from f in GetFiles(args[0])
                                  where GetFileName(f) != "text.txt" && GetFileName(f) != "dic.txt"
                                  where GetExtension(f) == ".txt"
                                  let ll                                              = ReadAllLines(f)
                                                             let ld                   = ll.Distinct().ToArray()
                                                                               let li = ld
                                                                                        .Select((l, i) => new { l, i })
                                                                                        .ToDictionary(x => x.l, x => x.i)
                                                                                        select new
                {
                    Name   = GetFileNameWithoutExtension(f),
                    Labels = ld,
                    Output = ll.Select(l => li[l]).ToArray()
                };

                foreach (var classifier in classifiers)
                {
                    Write($"Training: {classifier.Name}");
                    IKernel kernel  = new Linear();
                    var     machine = new MulticlassSupportVectorMachine(input[0].Length, kernel, classifier.Labels.Length);
                    var     teacher = new MulticlassSupportVectorLearning(machine, input, classifier.Output);
                    teacher.Algorithm = (svm, classInputs, classOutputs, i, j) =>
                    {
                        //var sequentialMinimalOptimization = new SequentialMinimalOptimization(svm, classInputs, classOutputs);
                        //sequentialMinimalOptimization.Run();
                        var linearCoordinateDescent = new LinearCoordinateDescent(svm, classInputs, classOutputs);
                        linearCoordinateDescent.Run();

                        var probabilisticOutputLearning = new ProbabilisticOutputCalibration(svm, classInputs, classOutputs);
                        return(probabilisticOutputLearning);
                    };
                    WriteLine($", error = {teacher.Run()}");

                    zip.PutNextEntry(new ZipEntry(classifier.Name + ".svm"));
                    using (var stream = new MemoryStream())
                    {
                        machine.Save(stream);
                        stream.Position = 0;
                        stream.CopyTo(zip);
                    }
                    zip.CloseEntry();

                    zip.PutNextEntry(new ZipEntry(classifier.Name + ".txt"));
                    using (var writer = new StreamWriter(zip, UTF8, 4096, true))
                        foreach (var lable in classifier.Labels)
                        {
                            writer.WriteLine(lable);
                        }

                    zip.CloseEntry();
                }

                WriteLine("Done.");
            }
        }
Пример #5
0
        public void Train(DataPackage data, CancellationToken token)
        {
            if (data is null)
            {
                throw new ArgumentNullException(nameof(data));
            }

            log.Debug("Training with {0} records", data.Y.Length);

            standardizer = Standardizer.GetNumericStandardizer(data.X);
            var xTraining = data.X;
            var yTraining = data.Y;

            var xTesting = xTraining;
            var yTesting = yTraining;

            int testSize = 100;

            if (xTraining.Length > testSize * 4)
            {
                var training = xTraining.Length - testSize;
                xTesting  = xTraining.Skip(training).ToArray();
                yTesting  = yTraining.Skip(training).ToArray();
                xTraining = xTraining.Take(training).ToArray();
                yTraining = yTraining.Take(training).ToArray();
            }

            xTraining = standardizer.StandardizeAll(xTraining);
            // Instantiate a new Grid Search algorithm for Kernel Support Vector Machines
            var gridsearch = new GridSearch <SupportVectorMachine <Gaussian>, double[], int>()
            {
                // Here we can specify the range of the parameters to be included in the search
                ParameterRanges = new GridSearchRangeCollection
                {
                    new GridSearchRange("complexity", new [] { 0.001, 0.01, 0.1, 1, 10 }),
                    new GridSearchRange("gamma", new [] { 0.001, 0.01, 0.1, 1 })
                },

                // Indicate how learning algorithms for the models should be created
                Learner = p => new SequentialMinimalOptimization <Gaussian>
                {
                    Complexity = p["complexity"],
                    Kernel     = new Gaussian
                    {
                        Gamma = p["gamma"]
                    }
                },

                // Define how the performance of the models should be measured
                Loss = (actual, expected, m) => new ZeroOneLoss(expected).Loss(actual)
            };

            gridsearch.Token = token;

            var randomized = new Random().Shuffle(xTraining, yTraining).ToArray();

            yTraining = randomized[1].Cast <int>().ToArray();
            xTraining = randomized[0].Cast <double[]>().ToArray();

            var result = gridsearch.Learn(xTraining, yTraining);

            // Get the best SVM found during the parameter search
            SupportVectorMachine <Gaussian> svm = result.BestModel;

            // Instantiate the probabilistic calibration (using Platt's scaling)
            var calibration = new ProbabilisticOutputCalibration <Gaussian>(svm);

            // Run the calibration algorithm
            calibration.Learn(xTraining, yTraining); // returns the same machine
            model = calibration.Model;
            var predicted       = ClassifyInternal(xTraining);
            var confusionMatrix = new GeneralConfusionMatrix(classes: 2, expected: yTraining, predicted: predicted);

            log.Debug("Performance on training dataset . F1(0):{0} F1(1):{1}", confusionMatrix.PerClassMatrices[0].FScore, confusionMatrix.PerClassMatrices[1].FScore);

            predicted          = Classify(xTesting);
            confusionMatrix    = new GeneralConfusionMatrix(classes: 2, expected: yTesting, predicted: predicted);
            TestSetPerformance = confusionMatrix;
            log.Debug("Performance on testing dataset . F1(0):{0} F1(1):{1}", confusionMatrix.PerClassMatrices[0].FScore, confusionMatrix.PerClassMatrices[1].FScore);
        }
Пример #6
0
        public void learn_test()
        {
            #region doc_learn
            double[][] inputs =        // Example XOR problem
            {
                new double[] { 0, 0 }, // 0 xor 0: 1 (label +1)
                new double[] { 0, 1 }, // 0 xor 1: 0 (label -1)
                new double[] { 1, 0 }, // 1 xor 0: 0 (label -1)
                new double[] { 1, 1 }  // 1 xor 1: 1 (label +1)
            };

            int[] outputs = // XOR outputs
            {
                1, 0, 0, 1
            };

            // Instantiate a new SMO learning algorithm for SVMs
            var smo = new SequentialMinimalOptimization <Gaussian>()
            {
                Kernel     = new Gaussian(0.1),
                Complexity = 1.0
            };

            // Learn a SVM using the algorithm
            var svm = smo.Learn(inputs, outputs);

            // Predict labels for each input sample
            bool[] predicted = svm.Decide(inputs);

            // Compute classification error
            double error = new ZeroOneLoss(outputs).Loss(predicted);

            // Instantiate the probabilistic calibration (using Platt's scaling)
            var calibration = new ProbabilisticOutputCalibration <Gaussian>(svm);

            // Run the calibration algorithm
            calibration.Learn(inputs, outputs); // returns the same machine

            // Predict probabilities of each input sample
            double[] probabilities = svm.Probability(inputs);

            // Compute the error based on a hard decision
            double loss = new BinaryCrossEntropyLoss(outputs).Loss(probabilities);

            // Compute the decision output for one of the input vectors,
            // while also retrieving the probability of the answer

            bool   decision;
            double probability = svm.Probability(inputs[0], out decision);
            #endregion

            // At this point, decision is +1 with a probability of 75%

            Assert.AreEqual(true, decision);
            Assert.AreEqual(0, error);
            Assert.AreEqual(5.5451735748925355, loss);
            Assert.AreEqual(0.74999975815069375, probability, 1e-10);
            Assert.IsTrue(svm.IsProbabilistic);
            Assert.AreEqual(-1.0986109988055595, svm.Weights[0]);
            Assert.AreEqual(1.0986109988055595, svm.Weights[1]);
            Assert.AreEqual(-1.0986109988055595, svm.Weights[2]);
            Assert.AreEqual(1.0986109988055595, svm.Weights[3]);
        }