Ejemplo n.º 1
0
        /// <summary>
        /// This is similar logic as standard deviation, but this returns the max distance from the average
        /// NOTE: Spread is probably the wrong word, since this only returns the max distance (radius instead of diameter)
        /// </summary>
        public static double GetTotalSpread(IEnumerable <VectorND> values)
        {
            VectorND mean = MathND.GetCenter(values);

            double distancesSquared = values.
                                      Select(o => (o - mean).LengthSquared).
                                      OrderByDescending().
                                      First();

            return(Math.Sqrt(distancesSquared));
        }
Ejemplo n.º 2
0
        /// <summary>
        /// This version starts with a SOM, then potentially splits the largest node and/or gathers the smallest nodes into a single
        /// </summary>
        /// <returns></returns>
        public static SOMResult Train(ISOMInput[] inputs, SOMRules rules, bool isDisplay2D)
        {
            SOMResult result = SelfOrganizingMaps.TrainSOM(inputs, rules, isDisplay2D);

            if (result.Nodes.Length == 0)
            {
                return(result);
            }
            else if (result.Nodes.Length == 1)
            {
                #region kmeans single node

                if (inputs.Length < 20)
                {
                    return(result);
                }

                return(SelfOrganizingMaps.TrainKMeans(inputs, 5, true));

                #endregion
            }

            var categorized = GetSOM_SplitMerge_Categorize(result);

            List <SOMNode>     nodes     = new List <SOMNode>();
            List <ISOMInput[]> newInputs = new List <ISOMInput[]>();

            foreach (NodeCombo set in UtilityCore.Iterate(categorized.kmeans, categorized.keep))        // UtilityCore.Iterate gracefully skips nulls
            {
                nodes.Add(set.Node);
                newInputs.Add(set.Inputs);
            }

            if (categorized.remaining != null)
            {
                nodes.Add(new SOMNode()
                {
                    Position = MathND.GetCenter(categorized.remaining.Select(o => o.Node.Position)),
                    Weights  = MathND.GetCenter(categorized.remaining.Select(o => o.Node.Weights)),
                });

                newInputs.Add(categorized.remaining.
                              SelectMany(o => o.Inputs).
                              ToArray());
            }

            return(new SOMResult(nodes.ToArray(), newInputs.ToArray(), false));
        }
Ejemplo n.º 3
0
        private static void AdjustKMeansCenters(SOMNode[] nodes, ISOMInput[][] inputsByNode)
        {
            if (nodes.Length != inputsByNode.Length)
            {
                throw new ArgumentException("Arrays must be the same size");
            }

            for (int cntr = 0; cntr < nodes.Length; cntr++)
            {
                if (inputsByNode[cntr].Length == 0)
                {
                    // This happened when there were a bunch of identical images.  Otherwise, it should never happen
                    //throw new ArgumentException("Must have inputs for every node");
                    continue;
                }

                nodes[cntr].Weights = MathND.GetCenter(inputsByNode[cntr].Select(o => o.Weights));
            }
        }