Exemplo n.º 1
0
        public static DecisionTree CreateTree(int[] indexes, double[,] xy, int nclasses, double pcoeff, double vcoeff)
        {
            if (xy == null)
            {
                throw new ArgumentException("xy is null", nameof(xy));
            }

            int npoints = xy.GetLength(0);
            int nvars   = xy.GetLength(1) - 1;

            int modNpoints = (int)(npoints * pcoeff); // столько значений надо нагенерировать
            int modNvars   = (int)(nvars * vcoeff);   // столько переменных используем

            if (modNvars < 1)
            {
                throw new ArgumentException("vcoeff too small", nameof(vcoeff));
            }

            int[] vidxes = Enumerable.Range(0, nvars).ToArray();
            if (modNvars < nvars)
            {
                vidxes = Enumerable.Range(0, nvars).OrderBy(c => RandomGen.GetDouble()).Take(modNvars).ToArray();
            }

            double[,] nxy = new double[modNpoints, modNvars + 1]; // сами значения

            int nk     = 0;                                       // столько нагенерировали
            var exists = new Dictionary <int, int>();

            if (indexes == null)
            {
                // basic tree
                while (nk < modNpoints)
                {
                    for (int i = 0; i < modNpoints; i++)
                    {
                        int sn = (int)(RandomGen.GetDouble() * npoints); // selection distribution
                        if (sn >= npoints)
                        {
                            continue;
                        }

                        if (exists.ContainsKey(sn))
                        {
                            continue;                         // такой ключ уже был
                        }
                        exists.Add(sn, 0);
                        for (int j = 0; j < modNvars; j++)
                        {
                            nxy[i, j] = xy[sn, vidxes[j]];
                        }
                        nxy[i, modNvars] = xy[sn, nvars];
                        nk++;

                        if (nk >= modNpoints)
                        {
                            break;
                        }
                    }

                    if (nk >= modNpoints)
                    {
                        break;
                    }
                }
            }
            else
            {
                // tree, with distribution selection

                while (nk < modNpoints)
                {
                    for (int i = 0; i < modNpoints; i++)
                    {
                        int sn = (int)(RandomGen.GetTrangle() * npoints); // selection distribution
                        if (sn >= indexes.Length)
                        {
                            continue;
                        }

                        if (exists.ContainsKey(sn))
                        {
                            continue;                         // такой ключ уже был
                        }
                        exists.Add(sn, 0);
                        int sidx = indexes[sn];
                        for (int j = 0; j < modNvars; j++)
                        {
                            nxy[i, j] = xy[sidx, vidxes[j]];
                        }
                        nxy[i, modNvars] = xy[sidx, nvars];
                        nk++;

                        if (nk >= modNpoints)
                        {
                            break;
                        }
                    }

                    if (nk >= modNpoints)
                    {
                        break;
                    }
                }
            }

            var ridxes = exists.Keys.ToArray();

            return(CreateTree(nxy, nclasses, nvars, modNpoints, modNvars, vidxes, ridxes));
        }