public void Test_Vector_Conversion_Simple_Numbers_And_Chars_As_Enum()
        {
            Descriptor d = new Descriptor();

            var dictionary = StringHelpers.BuildCharDictionary(ShortStrings)
                             .Select(k => k.Key)
                             .ToArray();

            d.Features = new Property[]
            {
                new Property {
                    Name = "Age"
                },
                new Property {
                    Name = "Height"
                },
                new StringProperty {
                    Name       = "Chars",
                    Dictionary = dictionary,
                    SplitType  = StringSplitType.Character,
                    AsEnum     = true
                },
                new Property {
                    Name = "Weight"
                },
                new Property {
                    Name = "Good"
                },
            };

            // ["O",  "N",  "E", "#SYM#", "T", "W", "#NUM#", "H", "R"]
            // [  2,    1,   0,        1,   0,   0,       1,   0,   3]

            var o = new { Age = 23, Height = 6.21d, Chars = "N", Weight = 220m, Good = false, };

            // array generated by descriptor ordering
            var truths = new double[] { 23, 6.21,
                                        /* BEGIN CHARS */
                                        1,
                                        /* END CHARS */
                                        220, -1 };

            var actual = d.Convert(o);

            Assert.AreEqual(truths, actual);


            o = new { Age = 23, Height = 6.21d, Chars = "!", Weight = 220m, Good = false, };

            // array generated by descriptor ordering
            truths = new double[] { 23, 6.21,
                                    /* BEGIN CHARS */
                                    3,
                                    /* END CHARS */
                                    220, -1 };

            actual = d.Convert(o);
            Assert.AreEqual(truths, actual);
        }
        public void Test_Vector_Conversion_Simple_Numbers_And_Strings_As_Enum()
        {
            Descriptor d = new Descriptor();

            var dictionary = StringHelpers.BuildWordDictionary(WordStrings)
                             .Select(k => k.Key)
                             .ToArray();

            d.Features = new Property[]
            {
                new Property {
                    Name = "Age"
                },
                new Property {
                    Name = "Height"
                },
                new StringProperty {
                    Name = "Words", Dictionary = dictionary, AsEnum = true
                },
                new Property {
                    Name = "Weight"
                },
                new Property {
                    Name = "Good"
                },
            };

            // [THE, QUICK, BROWN, FOX, #NUM#, SUPER, BEAR, UGLY]
            // [  0,     1,     2,   3,     4,     5,    6,    7]

            var o = new { Age = 23, Height = 6.21d, Weight = 220m, Good = false, Words = "QUICK" };

            // array generated by descriptor ordering
            var truths = new double[] { 23, 6.21,
                                        /* BEGIN TEXT */
                                        1,
                                        /* END TEXT */
                                        220, -1 };
            var actual = d.Convert(o);

            Assert.AreEqual(truths, actual);


            o = new { Age = 23, Height = 6.21d, Weight = 220m, Good = false, Words = "sUpEr" };
            // array generated by descriptor ordering
            truths = new double[] { 23, 6.21,
                                    /* BEGIN TEXT */
                                    5,
                                    /* END TEXT */
                                    220, -1 };
            actual = d.Convert(o);
            Assert.AreEqual(truths, actual);
        }
Пример #3
0
        /// <summary>Generates.</summary>
        /// <exception cref="InvalidOperationException">Thrown when the requested operation is invalid.</exception>
        /// <param name="examples">The examples.</param>
        /// <param name="k">The int to process.</param>
        /// <param name="metric">(Optional) the metric.</param>
        /// <returns>An int[].</returns>
        public int[] Generate(IEnumerable <object> examples, int k, IDistance metric = null)
        {
            #region Sanity Checks

            if (examples == null)
            {
                throw new InvalidOperationException("Cannot generate a model will no data!");
            }

            if (k < 2)
            {
                throw new InvalidOperationException("Can only cluter with k > 1");
            }

            if (Descriptor == null)
            {
                throw new InvalidOperationException("Invalid Description!");
            }

            var count = examples.Count();
            if (k >= count)
            {
                throw new InvalidOperationException(
                          string.Format("Cannot cluster {0} items {1} different ways!", count, k));
            }

            #endregion

            var X    = Descriptor.Convert(examples).ToMatrix();
            var data = Generate(X, k, metric);
            return(data);
        }
Пример #4
0
        /// <summary>Generates.</summary>
        /// <param name="descriptor">The descriptor.</param>
        /// <param name="examples">The examples.</param>
        public void Generate(Descriptor descriptor, IEnumerable <object> examples)
        {
            // generate data matrix
            var x = descriptor.Convert(examples).ToMatrix();

            this.Generate(x);
        }
Пример #5
0
        /// <summary>Generate model based on a set of examples.</summary>
        /// <exception cref="InvalidOperationException">Thrown when the requested operation is invalid.</exception>
        /// <param name="description">The description.</param>
        /// <param name="examples">Example set.</param>
        /// <returns>Model.</returns>
        public IModel Generate(Descriptor description, IEnumerable <object> examples)
        {
            if (!examples.Any())
            {
                throw new InvalidOperationException("Empty example set.");
            }

            Descriptor = description;
            if (Descriptor.Features == null || Descriptor.Features.Length == 0)
            {
                throw new InvalidOperationException("Invalid descriptor: Empty feature set!");
            }
            if (Descriptor.Label == null)
            {
                throw new InvalidOperationException("Invalid descriptor: Empty label!");
            }

            var dataset = (this.PreserveOrder ? examples : examples.Shuffle());

            var doubles = Descriptor.Convert(dataset);

            var(X, Y) = doubles.ToExamples();

            return(Generate(X, Y));
        }
        public void Test_Vector_Conversion_Simple_Numbers()
        {
            Descriptor d = new Descriptor();

            d.Features = new Property[]
            {
                new Property {
                    Name = "Age", Type = typeof(int)
                },
                new Property {
                    Name = "Height", Type = typeof(double)
                },
                new Property {
                    Name = "Weight", Type = typeof(decimal)
                },
                new Property {
                    Name = "Good", Type = typeof(bool)
                },
            };

            var o = new { Age = 23, Height = 6.21d, Weight = 220m, Good = false };

            var truths = new double[] { 23, 6.21, 220, -1 };
            var actual = d.Convert(o);

            Assert.AreEqual(truths, actual);
        }
Пример #7
0
        public void Test_Vector_Conversion_Simple_Numbers_And_Dates_3()
        {
            Descriptor d = Generate();

            d.Features[2] = new DateTimeProperty(DatePortion.Date)
            {
                Name = "BirthDate"
            };

            var o = new { Age = 23, Height = 6.21d, Weight = 220m, Good = false, BirthDate = new DateTime(2012, 11, 7, 2, 3, 4) };

            // array generated by descriptor ordering
            var truths = new double[] { 23, 6.21,
                                        /* DATE */
                                        2012, 11, 7,
                                        /* END DATE */
                                        220, -1 };
            var actual = d.Convert(o);

            Assert.Equal(truths, actual);
            // offset test
            Assert.Equal(2, d.Features[2].Start);
            Assert.Equal(5, d.Features[3].Start);
            Assert.Equal(6, d.Features[4].Start);
            // proper length
            Assert.Equal(3, d.Features[2].Length);
        }
Пример #8
0
        public void Test_Vector_Conversion_Simple_Numbers_And_Enumerable_Long_By_One()
        {
            Descriptor d = Generate();

            d.Features[2] = new EnumerableProperty(10)
            {
                Name = "Stuff"
            };

            var array = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
            var o     = new { Age = 23, Height = 6.21d, Weight = 220m, Good = false, Stuff = array };

            // array generated by descriptor ordering
            var truths = new double[] { 23, 6.21,
                                        /* ARRAY */
                                        1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
                                        /* END ARRAY */
                                        220, -1 };
            var actual = d.Convert(o);

            Assert.Equal(truths, actual);
            // offset test
            Assert.Equal(2, d.Features[2].Start);
            Assert.Equal(12, d.Features[3].Start);
            Assert.Equal(13, d.Features[4].Start);
            // proper length
            Assert.Equal(10, d.Features[2].Length);
        }
        public void Test_Vector_Dictionary_Conversion_Simple_Numbers()
        {
            Descriptor d = new Descriptor();

            d.Features = new Property[]
            {
                new Property {
                    Name = "Age",
                },
                new Property {
                    Name = "Height",
                },
                new Property {
                    Name = "Weight",
                },
                new Property {
                    Name = "Good",
                },
            };

            Dictionary <string, object> item = new Dictionary <string, object>();

            item["Age"]    = 23;
            item["Height"] = 6.21;
            item["Weight"] = 220m;
            item["Good"]   = false;

            var truths = new double[] { 23, 6.21, 220, -1 };
            var actual = d.Convert(item);

            Assert.AreEqual(truths, actual);
        }
        public void Test_Vector_Expando_Conversion_Simple_Numbers()
        {
            Descriptor d = new Descriptor();

            d.Features = new Property[]
            {
                new Property {
                    Name = "Age",
                },
                new Property {
                    Name = "Height",
                },
                new Property {
                    Name = "Weight",
                },
                new Property {
                    Name = "Good",
                },
            };

            dynamic item = new ExpandoObject();

            item.Age    = 23;
            item.Height = 6.21;
            item.Weight = 220m;
            item.Good   = false;

            var truths = new double[] { 23, 6.21, 220, -1 };
            var actual = d.Convert(item);

            Assert.AreEqual(truths, actual);
        }
Пример #11
0
        /// <summary>
        /// Generates a <see cref="IReinforcementModel"/> based on a set of temporal/continuous examples.
        /// </summary>
        /// <exception cref="InvalidOperationException">Thrown when the requested operation is invalid.</exception>
        /// <param name="description">The description.</param>
        /// <param name="examples">Example set.</param>
        /// <returns>IReinforcementModel.</returns>
        public IReinforcementModel Generate(Descriptor description, IEnumerable <object> examples)
        {
            if (examples.Count() == 0)
            {
                throw new InvalidOperationException("Empty example set.");
            }

            Descriptor = description;
            if (Descriptor.Features == null || Descriptor.Features.Length == 0)
            {
                throw new InvalidOperationException("Invalid descriptor: Empty feature set!");
            }
            if (Descriptor.Label == null)
            {
                throw new InvalidOperationException("Invalid descriptor: Empty label!");
            }

            var doubles = Descriptor.Convert(examples);

            var(states, actions) = doubles.ToExamples();

            Vector rewards = Vector.Rand(actions.Length);

            var rewardProp = description.Features.GetPropertyOfType <RewardAttribute>();

            if (rewardProp != null)
            {
                for (int x = 0; x < examples.Count(); x++)
                {
                    rewards[x] = rewardProp.Convert(examples.ElementAt(x)).First();
                }
            }

            return(this.Generate(states, actions, rewards));
        }
Пример #12
0
        public void Test_Vector_Conversion_Simple_Numbers_And_Dates_6()
        {
            Descriptor d = Generate();

            d.Features[2] = new DateTimeProperty(DatePortion.DateExtended | DatePortion.TimeExtended)
            {
                Name = "BirthDate"
            };

            DateTime date = new DateTime(2012, 11, 7, 2, 3, 4, 234);
            var      o    = new { Age = 23, Height = 6.21d, Weight = 220m, Good = false, BirthDate = date };

            // array generated by descriptor ordering
            var truths = new double[] { 23, 6.21,
                                        /* DATE */
                                        date.DayOfYear, (int)date.DayOfWeek, 4, 234,
                                        /* END DATE */
                                        220, -1 };
            var actual = d.Convert(o);

            Assert.AreEqual(truths, actual);
            // offset test
            Assert.AreEqual(2, d.Features[2].Start);
            Assert.AreEqual(6, d.Features[3].Start);
            Assert.AreEqual(7, d.Features[4].Start);
            // proper length
            Assert.AreEqual(4, d.Features[2].Length);
        }
Пример #13
0
        /// <summary>Generates.</summary>
        /// <param name="desc">The description.</param>
        /// <param name="examples">The examples.</param>
        /// <param name="linker">The linker.</param>
        /// <returns>A Cluster.</returns>
        public Cluster Generate(Descriptor desc, IEnumerable<object> examples, ILinker linker)
        {
            // Load data 
            var exampleArray = examples.ToArray();
            Descriptor = desc;
            Matrix X = Descriptor.Convert(examples).ToMatrix();

            return GenerateClustering(X, linker, exampleArray);
        }
Пример #14
0
        /// <summary>Generates.</summary>
        /// <param name="desc">The description.</param>
        /// <param name="examples">The examples.</param>
        /// <param name="linker">The linker.</param>
        /// <returns>A Cluster.</returns>
        public Cluster Generate(Descriptor desc, IEnumerable <object> examples, ILinker linker)
        {
            // Load data
            var exampleArray = examples.ToArray();

            Descriptor = desc;
            var X = Descriptor.Convert(examples).ToMatrix();

            return(GenerateClustering(X, linker, exampleArray));
        }
Пример #15
0
        /// <summary>
        /// Reinforces the model from the new item and reward.
        /// </summary>
        /// <param name="state">Initial State object or features with action label.</param>
        /// <param name="stateP">New State object or features with reward label.</param>
        public void Learn(object state, object stateP)
        {
            var doubles1 = Descriptor.Convert(state, true);
            var tuple1   = new double[][] { doubles1.ToArray() }.ToExamples();

            var doubles2 = TransitionDescriptor.Convert(stateP, true);
            var tuple2   = new double[][] { doubles2.ToArray() }.ToExamples();

            this.Learn(tuple1.X[0], tuple1.Y[0], tuple2.X[0], tuple2.Y[0]);
        }
Пример #16
0
        public Cluster Generate(Descriptor descriptor, IEnumerable<object> examples, int k, IDistance metric = null)
        {
            var data = examples.ToArray();
            Descriptor = descriptor;
            Matrix X = Descriptor.Convert(examples).ToMatrix();

            var assignments = Generate(X, k, metric);

            return GenerateClustering(X, assignments, data);
        }
Пример #17
0
        /// <summary>
        ///   Reinforces the model from the new item and reward.
        /// </summary>
        /// <param name="state">Initial State object or features with action label.</param>
        /// <param name="stateP">New State object or features with reward label.</param>
        public void Learn(object state, object stateP)
        {
            var doubles1 = Descriptor.Convert(state, true);
            var tuple1   = new[] { doubles1.ToArray() }.ToExamples();

            var doubles2 = TransitionDescriptor.Convert(stateP, true);
            var tuple2   = new[] { doubles2.ToArray() }.ToExamples();

            Learn(tuple1.Item1[0], tuple1.Item2[0], tuple2.Item1[0], tuple2.Item2[0]);
        }
Пример #18
0
        /// <summary>
        ///   Predicts the raw label value
        /// </summary>
        /// <param name="o">Object to predict</param>
        /// <returns>Predicted value</returns>
        public object PredictValue(object o)
        {
            if (Descriptor.Label == null)
            {
                throw new InvalidOperationException("Empty label precludes prediction!");
            }

            var y      = Descriptor.Convert(o, false).ToVector();
            var val    = Predict(y);
            var result = Descriptor.Label.Convert(val);

            return(result);
        }
Пример #19
0
        /// <summary>Generates.</summary>
        /// <param name="descriptor">The descriptor.</param>
        /// <param name="examples">The examples.</param>
        /// <param name="k">The int to process.</param>
        /// <param name="metric">(Optional) the metric.</param>
        /// <returns>An int[].</returns>
        public Cluster Generate(Descriptor descriptor, IEnumerable <object> examples, int k, IDistance metric = null)
        {
            var data = examples.ToArray();

            Descriptor = descriptor;
            X          = Descriptor.Convert(data).ToMatrix();

            // generate assignments
            var assignments = Generate(X, k, metric);

            // begin packing objects into clusters
            var objects = new List <object> [k];

            for (var i = 0; i < assignments.Length; i++)
            {
                var a = assignments[i];
                if (objects[a] == null)
                {
                    objects[a] = new List <object>();
                }
                objects[a].Add(data[i]);
            }

            // create clusters
            var clusters = new List <Cluster>();

            for (var i = 0; i < k; i++)
            {
                if (!Centers[i].IsNaN()) // check for degenerate clusters
                {
                    clusters.Add(
                        new Cluster
                    {
                        Id       = i + 1,
                        Center   = Centers[i],
                        Members  = objects[i].ToArray(),
                        Children = new Cluster[] {}
                    });
                }
            }

            // return single cluster with K children
            return(new Cluster
            {
                Id = 0,
                Center = X.Mean(VectorType.Row),
                Children = clusters.ToArray()
            });
        }
Пример #20
0
        public void Test_Vector_Conversion_OneHot_Encoding()
        {
            Descriptor d = new Descriptor();

            d.Features = new Property[]
            {
                new OneHotProperty(4)
                {
                    Name = "SuperOneHot"
                }
            };

            var o = new[] {
                new { SuperOneHot = "One" },   // 1, 0, 0, 0
                new { SuperOneHot = "Two" },   // 0, 1, 0, 0
                new { SuperOneHot = "Three" }, // 0, 0, 1, 0
                new { SuperOneHot = "Two" },   // 0, 1, 0, 0
                new { SuperOneHot = "Three" }, // 0, 0, 1, 0
                new { SuperOneHot = "Two" },   // 0, 1, 0, 0
                new { SuperOneHot = "one" },   // 1, 0, 0, 0
                new { SuperOneHot = "Four" },  // 0, 0, 0, 1
                new { SuperOneHot = "Two" },   // 0, 1, 0, 0
                new { SuperOneHot = "one" },   // 1, 0, 0, 0
                new { SuperOneHot = "Three" }, // 0, 0, 1, 0
                new { SuperOneHot = "Four" }   // 0, 0, 0, 1
            };

            var truth = new double[, ] {
                { 1, 0, 0, 0 },
                { 0, 1, 0, 0 },
                { 0, 0, 1, 0 },
                { 0, 1, 0, 0 },
                { 0, 0, 1, 0 },
                { 0, 1, 0, 0 },
                { 1, 0, 0, 0 },
                { 0, 0, 0, 1 },
                { 0, 1, 0, 0 },
                { 1, 0, 0, 0 },
                { 0, 0, 1, 0 },
                { 0, 0, 0, 1 }
            }.ToTensor();

            var output = d.Convert(o).ToMatrix();

            Assert.Equal(truth, output);
        }
Пример #21
0
        public IModel Generate(Descriptor description, IEnumerable <object> examples)
        {
            Descriptor = description;
            if (Descriptor.Features == null || Descriptor.Features.Length == 0)
            {
                throw new InvalidOperationException("Invalid descriptor: Empty feature set!");
            }
            if (Descriptor.Label == null)
            {
                throw new InvalidOperationException("Invalid descriptor: Empty label!");
            }

            var doubles = Descriptor.Convert(examples);
            var tuple   = doubles.ToExamples();

            return(Generate(tuple.Item1, tuple.Item2));
        }
        public void Test_Vector_Conversion_Simple_Numbers_And_Strings()
        {
            Descriptor d = new Descriptor();

            var dictionary = StringHelpers.BuildWordDictionary(WordStrings)
                             .Select(k => k.Key)
                             .ToArray();

            d.Features = new Property[]
            {
                new Property {
                    Name = "Age"
                },
                new Property {
                    Name = "Height"
                },
                new StringProperty {
                    Name = "Words", Dictionary = dictionary
                },
                new Property {
                    Name = "Weight"
                },
                new Property {
                    Name = "Good"
                },
            };

            // [THE, QUICK, BROWN, FOX, #NUM#, SUPER, BEAR, UGLY]
            // [  1,     0,     1,   0,     1,     0,    0,    0]

            var o = new { Age = 23, Height = 6.21d, Weight = 220m, Good = false, Words = "the brown 432" };

            // array generated by descriptor ordering
            var truths = new double[] { 23, 6.21,
                                        /* BEGIN TEXT */
                                        1, 0, 1, 0, 1, 0, 0, 0,
                                        /* END TEXT */
                                        220, -1 };
            var actual = d.Convert(o);

            Assert.AreEqual(truths, actual);
            // offset test
            Assert.AreEqual(10, d.Features[3].Start);
            Assert.AreEqual(11, d.Features[4].Start);
        }
Пример #23
0
        public void Test_Matrix_Conversion_With_Label()
        {
            Descriptor d = new Descriptor();

            d.Features = new Property[]
            {
                new Property {
                    Name = "Age"
                },
                new Property {
                    Name = "Height"
                },
                new Property {
                    Name = "Weight"
                },
                new Property {
                    Name = "Good"
                },
            };

            d.Label = new Property {
                Name = "Nice"
            };

            var o = new[] {
                new { Age = 23, Height = 6.21d, Weight = 220m, Good = false, Nice = true },
                new { Age = 12, Height = 4.2d, Weight = 120m, Good = true, Nice = false },
                new { Age = 9, Height = 6.0d, Weight = 340m, Good = true, Nice = true },
                new { Age = 87, Height = 3.7d, Weight = 79m, Good = false, Nice = false }
            };

            // array generated by descriptor ordering
            // (returns IEnumerable, but should pass)
            var truths = new double[][] {
                new double[] { 23, 6.21, 220, -1, 1 },
                new double[] { 12, 4.2, 120, 1, -1 },
                new double[] { 9, 6.0, 340, 1, 1 },
                new double[] { 87, 3.7, 79, -1, -1 }
            };

            var actual = d.Convert(o);
            var array  = actual.Select(s => s.ToArray()).ToArray();

            Assert.Equal(truths, array);
        }
        public void Test_Vector_DataRow_Conversion_Simple_Numbers()
        {
            Descriptor d = new Descriptor();

            d.Features = new Property[]
            {
                new Property {
                    Name = "Age",
                },
                new Property {
                    Name = "Height",
                },
                new Property {
                    Name = "Weight",
                },
                new Property {
                    Name = "Good",
                },
            };

            DataTable table  = new DataTable("student");
            var       age    = table.Columns.Add("Age", typeof(int));
            var       height = table.Columns.Add("Height", typeof(double));
            var       weight = table.Columns.Add("Weight", typeof(decimal));
            var       good   = table.Columns.Add("Good", typeof(bool));

            DataRow row = table.NewRow();

            row[age]    = 23;
            row[height] = 6.21;
            row[weight] = 220m;
            row[good]   = false;

            var truths = new double[] { 23, 6.21, 220, -1 };
            var actual = d.Convert(row);

            Assert.AreEqual(truths, actual);
        }
Пример #25
0
        public Cluster Generate(Descriptor descriptor, IEnumerable<object> examples, int k, IDistance metric = null)
        {
            var data = examples.ToArray();
            Descriptor = descriptor;
            X = Descriptor.Convert(data).ToMatrix();

            // generate assignments
            var assignments = Generate(X, k, metric);

            // begin packing objects into clusters
            var objects = new List<object>[k];
            for (int i = 0; i < assignments.Length; i++)
            {
                var a = assignments[i];
                if (objects[a] == null) objects[a] = new List<object>();
                objects[a].Add(data[i]);
            }

            // create clusters
            List<Cluster> clusters = new List<Cluster>();
            for(int i = 0; i < k; i++)
                if(!Centers[i].IsNaN()) // check for degenerate clusters
                    clusters.Add(new Cluster
                    {
                        Id = i + 1,
                        Center = Centers[i],
                        Members = objects[i].ToArray(),
                        Children = new Cluster[] { }
                    });

            // return single cluster with K children
            return new Cluster
            {
                Id = 0,
                Center = X.Mean(VectorType.Row),
                Children = clusters.ToArray()
            };
        }
Пример #26
0
        /// <summary>
        /// Generate a multi-class classification model using a specialist classifier for each class label.
        /// </summary>
        /// <param name="generator">The generator to use for each individual classifier.</param>
        /// <param name="examples">Training examples of any number of classes</param>
        /// <param name="trainingPercentage">Percentage of training examples to use, i.e. 70% = 0.7</param>
        /// <param name="mixingPercentage">Percentage to mix positive and negative exmaples, i.e. 50% will add an additional 50% of
        ///   <paramref name="trainingPercentage"/> of negative examples into each classifier when training.</param>
        /// <param name="isMultiClass">Determines whether each class is mutually inclusive.
        ///   <para>For example: If True, each class takes on a number of classes and does not necessarily belong to one specific class.</para>
        ///   <para>The ouput would then be a number of predicted classes for a single prediction.  E.g. A song would be True as it may belong to classes: vocals, rock as well as bass.</para>
        /// </param>
        /// <returns></returns>
        public static ClassificationModel Learn(IGenerator generator, IEnumerable <object> examples, double trainingPercentage, double mixingPercentage = 0.5, bool isMultiClass = true)
        {
            Descriptor descriptor = generator.Descriptor;

            trainingPercentage = (trainingPercentage > 1.0 ? trainingPercentage / 100 : trainingPercentage);
            mixingPercentage   = (mixingPercentage > 1.0 ? mixingPercentage / 100 : mixingPercentage);

            var classGroups = examples.Select(s => new
            {
                Label = generator.Descriptor.GetValue(s, descriptor.Label),
                Item  = s
            })
                              .GroupBy(g => g.Label)
                              .ToDictionary(k => k.Key, v => v.Select(s => s.Item).ToArray());

            int classes = classGroups.Count();

            Dictionary <object, IClassifier> models = null;

            Score finalScore = new Score();

            if (classes > 2)
            {
                models = new Dictionary <object, IClassifier>(classes);

                Task <Tuple <IClassifier, Score, object> >[] learningTasks = new Task <Tuple <IClassifier, Score, object> > [classes];

                for (int y = 0; y < classes; y++)
                {
                    models.Add(classGroups.ElementAt(y).Key, null);

                    int      mix           = (int)System.Math.Ceiling(((classGroups.ElementAt(y).Value.Count() * trainingPercentage) * mixingPercentage) / classes);
                    object   label         = classGroups.ElementAt(y).Key;
                    object[] truthExamples = classGroups.ElementAt(y).Value;
                    object[] falseExamples = classGroups.Where(w => w.Key != classGroups.Keys.ElementAt(y))
                                             .SelectMany(s => s.Value.Take(mix).ToArray())
                                             .ToArray();

                    learningTasks[y] = Task.Factory.StartNew(
                        () => MultiClassLearner.GenerateModel(generator, truthExamples, falseExamples, label, trainingPercentage, label)
                        );
                }

                Task.WaitAll(learningTasks);

                Score[] scores = new Score[learningTasks.Count()];

                for (int c = 0; c < learningTasks.Count(); c++)
                {
                    models[learningTasks[c].Result.Item3] = learningTasks[c].Result.Item1;
                    scores[c] = learningTasks[c].Result.Item2;
                }

                finalScore = Score.CombineScores(scores);
            }
            else
            {
                // fallback to single classifier for two class classification

                var dataset   = descriptor.Convert(examples, true).ToExamples();
                var positives = examples.Slice(dataset.Y.Indices(f => f == 1d)).ToArray();
                var negatives = examples.Slice(dataset.Y.Indices(w => w != 1d)).ToArray();

                var label = generator.Descriptor.GetValue(positives.First(), descriptor.Label);

                var model = MultiClassLearner.GenerateModel(generator, positives, negatives, label, trainingPercentage, label);
                finalScore = model.Item2;

                models = new Dictionary <object, IClassifier>()
                {
                    { label, model.Item1 }
                };
            }

            ClassificationModel classificationModel = new ClassificationModel()
            {
                Generator    = generator,
                Classifiers  = models,
                IsMultiClass = isMultiClass,
                Score        = finalScore
            };

            return(classificationModel);
        }
Пример #27
0
        /// <summary>
        ///   Generate an <see cref="IReinforcementModel" /> based on a set of examples and transitions.
        /// </summary>
        /// <exception cref="InvalidOperationException">Thrown when the requested operation is invalid.</exception>
        /// <param name="descriptor">The description.</param>
        /// <param name="examples1">Example training set or state/action pairs.</param>
        /// <param name="transitionDescriptor">
        ///   (Optional) Descriptor for extracting transition state/reward information from
        ///   <paramref name="examples2" /> set.
        /// </param>
        /// <param name="examples2">
        ///   (Optional) Corresponding training set where each item represents a transition state from
        ///   <paramref name="examples1" /> and a reward label.
        /// </param>
        /// <returns>IReinforcementModel.</returns>
        public IReinforcementModel Generate(
            Descriptor descriptor,
            IEnumerable <object> examples1,
            Descriptor transitionDescriptor,
            IEnumerable <object> examples2)
        {
            if (!examples1.Any())
            {
                throw new InvalidOperationException("Empty example set.");
            }

            var hasTransitionStates = examples2 != null && examples2.Any();

            Descriptor           = descriptor;
            TransitionDescriptor = transitionDescriptor;

            if (Descriptor.Features == null || Descriptor.Features.Length == 0)
            {
                throw new InvalidOperationException("Invalid State Descriptor: Empty feature set!");
            }
            if (Descriptor.Label == null)
            {
                throw new InvalidOperationException("Invalid State Descriptor: Empty label!");
            }

            if (hasTransitionStates)
            {
                if (TransitionDescriptor?.Features == null || TransitionDescriptor.Features.Length == 0)
                {
                    throw new ArgumentNullException(
                              $"Transition Descriptor was null. A transition desciptor is required for '{nameof(examples2)}'.");
                }
                if (examples2.Count() != examples1.Count())
                {
                    throw new InvalidOperationException(
                              $"Length of '{nameof(examples1)}' must match length of '{nameof(examples2)}'.");
                }
            }

            var doubles = Descriptor.Convert(examples1);
            var tuple   = doubles.ToExamples();

            var states  = tuple.Item1.Copy();
            var actions = tuple.Item2;

            Matrix statesP;
            var    rewards = Vector.Rand(tuple.Item2.Length);

            if (hasTransitionStates)
            {
                var doubles2 = TransitionDescriptor.Convert(examples2);
                var tuple2   = doubles2.ToExamples();

                statesP = tuple2.Item1;
                rewards = tuple2.Item2;
            }
            else
            {
                statesP = new Matrix(states.Rows, states.Cols);
                // assume temporal
                for (var i = 0; i < states.Rows - 1; i++)
                {
                    statesP[i, VectorType.Row] = states[i + 1, VectorType.Row];
                }
            }

            return(Generate(states, actions, statesP, rewards));
        }
Пример #28
0
        public void Test_Vector_Conversion_Simple_Numbers()
        {
            Descriptor d = new Descriptor();
            d.Features = new Property[]
            {
                new Property { Name = "Age", Type = typeof(int) },
                new Property { Name = "Height", Type=typeof(double) },
                new Property { Name = "Weight", Type = typeof(decimal) },
                new Property { Name = "Good", Type=typeof(bool) },
            };

            var o = new { Age = 23, Height = 6.21d, Weight = 220m, Good = false };

            var truths = new double[] { 23, 6.21, 220, -1 };
            var actual = d.Convert(o);
            Assert.AreEqual(truths, actual);
        }
Пример #29
0
 /// <summary>Generates.</summary>
 /// <param name="descriptor">The descriptor.</param>
 /// <param name="examples">The examples.</param>
 public void Generate(Descriptor descriptor, IEnumerable<object> examples)
 {
     // generate data matrix
     var x = descriptor.Convert(examples).ToMatrix();
     Generate(x);
 }
Пример #30
0
        public void Test_Vector_Dictionary_Conversion_Simple_Numbers()
        {
            Descriptor d = new Descriptor();
            d.Features = new Property[]
            {
                new Property { Name = "Age", },
                new Property { Name = "Height", },
                new Property { Name = "Weight", },
                new Property { Name = "Good", },
            };

            Dictionary<string, object> item = new Dictionary<string, object>();
            item["Age"] = 23;
            item["Height"] = 6.21;
            item["Weight"] = 220m;
            item["Good"] = false;

            var truths = new double[] { 23, 6.21, 220, -1 };
            var actual = d.Convert(item);
            Assert.AreEqual(truths, actual);
        }
Пример #31
0
        public void Test_Vector_DataRow_Conversion_Simple_Numbers()
        {
            Descriptor d = new Descriptor();
            d.Features = new Property[]
            {
                new Property { Name = "Age", },
                new Property { Name = "Height", },
                new Property { Name = "Weight", },
                new Property { Name = "Good", },
            };

            DataTable table = new DataTable("student");
            var age = table.Columns.Add("Age", typeof(int));
            var height = table.Columns.Add("Height", typeof(double));
            var weight = table.Columns.Add("Weight", typeof(decimal));
            var good = table.Columns.Add("Good", typeof(bool));

            DataRow row = table.NewRow();
            row[age] = 23;
            row[height] = 6.21;
            row[weight] = 220m;
            row[good] = false;

            var truths = new double[] { 23, 6.21, 220, -1 };
            var actual = d.Convert(row);
            Assert.AreEqual(truths, actual);
        }
Пример #32
0
        public void Test_Vector_Conversion_Simple_Numbers_And_Strings_As_Enum()
        {
            Descriptor d = new Descriptor();

            var dictionary = StringHelpers.BuildWordDictionary(WordStrings)
                                          .Select(k => k.Key)
                                          .ToArray();

            d.Features = new Property[]
            {
                new Property { Name = "Age" },
                new Property { Name = "Height" },
                new StringProperty { Name = "Words", Dictionary = dictionary, AsEnum = true },
                new Property { Name = "Weight" },
                new Property { Name = "Good" },

            };

            // [THE, QUICK, BROWN, FOX, #NUM#, SUPER, BEAR, UGLY]
            // [  0,     1,     2,   3,     4,     5,    6,    7]

            var o = new { Age = 23, Height = 6.21d, Weight = 220m, Good = false, Words = "QUICK" };

            // array generated by descriptor ordering
            var truths = new double[] { 23, 6.21,
                                        /* BEGIN TEXT */
                                        1,
                                        /* END TEXT */
                                        220, -1 };
            var actual = d.Convert(o);
            Assert.AreEqual(truths, actual);

            o = new { Age = 23, Height = 6.21d, Weight = 220m, Good = false, Words = "sUpEr" };
            // array generated by descriptor ordering
            truths = new double[] { 23, 6.21,
                                        /* BEGIN TEXT */
                                        5,
                                        /* END TEXT */
                                        220, -1 };
            actual = d.Convert(o);
            Assert.AreEqual(truths, actual);
        }
Пример #33
0
        public void Test_Vector_Conversion_Simple_Numbers_And_Strings()
        {
            Descriptor d = new Descriptor();

            var dictionary = StringHelpers.BuildWordDictionary(WordStrings)
                                          .Select(k => k.Key)
                                          .ToArray();

            d.Features = new Property[]
            {
                new Property { Name = "Age" },
                new Property { Name = "Height" },
                new StringProperty { Name = "Words", Dictionary = dictionary },
                new Property { Name = "Weight" },
                new Property { Name = "Good" },

            };

            // [THE, QUICK, BROWN, FOX, #NUM#, SUPER, BEAR, UGLY]
            // [  1,     0,     1,   0,     1,     0,    0,    0]

            var o = new { Age = 23, Height = 6.21d, Weight = 220m, Good = false, Words = "the brown 432" };

            // array generated by descriptor ordering
            var truths = new double[] { 23, 6.21,
                                        /* BEGIN TEXT */
                                        1, 0, 1, 0, 1, 0, 0, 0,
                                        /* END TEXT */
                                        220, -1 };
            var actual = d.Convert(o);
            Assert.AreEqual(truths, actual);
            // offset test
            Assert.AreEqual(10, d.Features[3].Start);
            Assert.AreEqual(11, d.Features[4].Start);
        }
Пример #34
0
        public void Test_Vector_Conversion_Simple_Numbers_And_Chars_As_Enum()
        {
            Descriptor d = new Descriptor();

            var dictionary = StringHelpers.BuildCharDictionary(ShortStrings)
                                          .Select(k => k.Key)
                                          .ToArray();

            d.Features = new Property[]
            {
                new Property { Name = "Age" },
                new Property { Name = "Height" },
                new StringProperty {
                    Name = "Chars",
                    Dictionary = dictionary,
                    SplitType = StringSplitType.Character,
                    AsEnum = true
                },
                new Property { Name = "Weight" },
                new Property { Name = "Good" },

            };

            // ["O",  "N",  "E", "#SYM#", "T", "W", "#NUM#", "H", "R"]
            // [  2,    1,   0,        1,   0,   0,       1,   0,   3]

            var o = new { Age = 23, Height = 6.21d, Chars = "N", Weight = 220m, Good = false, };

            // array generated by descriptor ordering
            var truths = new double[] { 23, 6.21,
                                        /* BEGIN CHARS */
                                        1,
                                        /* END CHARS */
                                        220, -1 };

            var actual = d.Convert(o);
            Assert.AreEqual(truths, actual);

            o = new { Age = 23, Height = 6.21d, Chars = "!", Weight = 220m, Good = false, };

            // array generated by descriptor ordering
            truths = new double[] { 23, 6.21,
                                    /* BEGIN CHARS */
                                    3,
                                    /* END CHARS */
                                    220, -1 };

            actual = d.Convert(o);
            Assert.AreEqual(truths, actual);
        }
Пример #35
0
        public void Test_Vector_Expando_Conversion_Simple_Numbers()
        {
            Descriptor d = new Descriptor();
            d.Features = new Property[]
            {
                new Property { Name = "Age", },
                new Property { Name = "Height", },
                new Property { Name = "Weight", },
                new Property { Name = "Good", },
            };

            dynamic item = new ExpandoObject();
            item.Age = 23;
            item.Height = 6.21;
            item.Weight = 220m;
            item.Good = false;

            var truths = new double[] { 23, 6.21, 220, -1 };
            var actual = d.Convert(item);
            Assert.AreEqual(truths, actual);
        }
Пример #36
0
        public void Test_Matrix_Conversion_With_Label()
        {
            Descriptor d = new Descriptor();

            d.Features = new Property[]
            {
                new Property { Name = "Age" },
                new Property { Name = "Height" },
                new Property { Name = "Weight" },
                new Property { Name = "Good" },
            };

            d.Label = new Property { Name = "Nice" };

            var o = new[] {
                new { Age = 23, Height = 6.21d, Weight = 220m, Good = false, Nice = true },
                new { Age = 12, Height = 4.2d, Weight = 120m, Good = true, Nice = false },
                new { Age = 9, Height = 6.0d, Weight = 340m, Good = true, Nice = true },
                new { Age = 87, Height = 3.7d, Weight = 79m, Good = false, Nice = false }
            };

            // array generated by descriptor ordering
            // (returns IEnumerable, but should pass)
            var truths = new double[][] {
                new double[] { 23, 6.21, 220, -1, 1 },
                new double[] { 12,  4.2,  120, 1, -1 },
                new double[] { 9,  6.0,  340,  1, 1 },
                new double[] { 87,  3.7,  79,  -1, -1 }
            };

            var actual = d.Convert(o);
            Assert.AreEqual(truths, actual);
        }