示例#1
0
        private static void inferBounds(Node node, Hyperrectangle <float> bounds)
        {
            if (node == null)
            {
                return;
            }
            node.Bounds = bounds;
            if (node.NodeType == NodeType.Leaf)
            {
                return;
            }

            Threshold test = node.Threshold;
            float     min  = bounds.MinimumBound[test.Dimension];
            float     max  = bounds.MaximumBound[test.Dimension];
            Hyperrectangle <float> leftBounds  = (Hyperrectangle <float>)bounds.Clone();
            Hyperrectangle <float> rightBounds = (Hyperrectangle <float>)bounds.Clone();

            leftBounds.MaximumBound[test.Dimension]  = test.Value;
            rightBounds.MinimumBound[test.Dimension] = test.Value;
            inferBounds(node.Left, leftBounds);
            inferBounds(node.Right, rightBounds);
        }
示例#2
0
        private static Node split(List <int> indices, int NCount, Hyperrectangle <float> bounds)
        {
            _depth++;
            int YCount = indices.Count;

            if (YCount <= MinY)
            {
                _depth--;
                return(new Node {
                    NodeType = NodeType.Leaf, Y = YCount, N = NCount, Bounds = bounds
                });
            }

            if (NCount < YCount)
            {
                NCount = YCount;
            }

            int length = _numFeatures;

            float min, max;

            Dictionary <Threshold, float> thresholds = new Dictionary <Threshold, float>();

            float[] values = new float[YCount];

            for (int i = 0; i < length; i++)
            {
                float[] featureValues = _featureValues[i];
                for (int j = 0; j < YCount; j++)
                {
                    values[j] = featureValues[indices[j]];
                }
                Array.Sort <float>(values);

                min = bounds.MinimumBound[i];
                max = bounds.MaximumBound[i];

                Threshold cut1 = findCut(new Region {
                    Min = min, Max = max, YCount = YCount, NCount = NCount
                }, values);

                if (cut1 == null)
                {
                    continue;
                }

                Region r0 = new Region {
                    Min = min, Max = cut1.Value, IncludeLeft = true, IncludeRight = cut1.IsInclusive
                };
                Region r1 = new Region {
                    Min = cut1.Value, Max = max, IncludeLeft = !cut1.IsInclusive, IncludeRight = true
                };
                r0.CalculateCounts(values, min, max, NCount);
                r1.CalculateCounts(values, min, max, NCount);

                Region  L       = r0.RelativeDensity < r1.RelativeDensity ? r0 : r1;
                float[] LValues = L.Limit(values);
                if (LValues.Length == 0)
                {
                    cut1.Dimension   = i;
                    cut1.Feature     = _buildFeatures[i];
                    thresholds[cut1] = L.RelativeDensity;
                    continue;
                }

                Threshold cut2 = findCut(L, LValues);

                if (cut2 == null)
                {
                    continue;
                }

                if (L == r0)
                {
                    r0 = new Region {
                        Min = r0.Min, Max = cut2.Value, IncludeLeft = true, IncludeRight = cut2.IsInclusive
                    };
                    r1 = new Region {
                        Min = cut2.Value, Max = cut1.Value, IncludeLeft = !cut2.IsInclusive, IncludeRight = cut1.IsInclusive
                    };
                    r0.CalculateCounts(values, min, max, NCount);
                    r1.CalculateCounts(values, min, max, NCount);
                    if (r1.RelativeDensity > r0.RelativeDensity)
                    {
                        cut2.Dimension   = i;
                        cut2.Feature     = _buildFeatures[i];
                        thresholds[cut2] = r0.RelativeDensity;
                        continue;
                    }
                }
                else
                {
                    r0 = new Region {
                        Min = cut1.Value, Max = cut2.Value, IncludeLeft = !cut1.IsInclusive, IncludeRight = cut2.IsInclusive
                    };
                    r1 = new Region {
                        Min = cut2.Value, Max = r1.Max, IncludeLeft = !cut2.IsInclusive, IncludeRight = true
                    };
                    r0.CalculateCounts(values, min, max, NCount);
                    r1.CalculateCounts(values, min, max, NCount);
                    if (r0.RelativeDensity > r1.RelativeDensity)
                    {
                        cut2.Dimension   = i;
                        cut2.Feature     = _buildFeatures[i];
                        thresholds[cut2] = r1.RelativeDensity;
                        continue;
                    }
                }

                L       = r0.RelativeDensity < r1.RelativeDensity ? r0 : r1;
                LValues = L.Limit(LValues);
                if (LValues.Length == 0)
                {
                    continue;
                }

                Threshold cut3 = findCut(L, LValues);

                if (cut3 == null)
                {
                    continue;
                }

                if (cut1.Value < cut3.Value)
                {
                    r0 = new Region {
                        Min = cut1.Value, Max = cut3.Value, IncludeLeft = !cut1.IsInclusive, IncludeRight = cut3.IsInclusive
                    }
                }
                ;
                else
                {
                    r0 = new Region {
                        Min = cut3.Value, Max = cut1.Value, IncludeLeft = !cut3.IsInclusive, IncludeRight = cut1.IsInclusive
                    }
                };
                if (cut2.Value < cut3.Value)
                {
                    r1 = new Region {
                        Min = cut2.Value, Max = cut3.Value, IncludeLeft = !cut2.IsInclusive, IncludeRight = cut3.IsInclusive
                    }
                }
                ;
                else
                {
                    r1 = new Region {
                        Min = cut3.Value, Max = cut2.Value, IncludeLeft = !cut3.IsInclusive, IncludeRight = cut2.IsInclusive
                    }
                };
                r0.CalculateCounts(values, min, max, NCount);
                r1.CalculateCounts(values, min, max, NCount);
                cut3.Feature     = _buildFeatures[i];
                cut3.Dimension   = i;
                thresholds[cut3] = Math.Min(r0.RelativeDensity, r1.RelativeDensity);
            }

            values = null;

            if (thresholds.Count() == 0)
            {
                _depth--;
                return(new Node {
                    NodeType = NodeType.Leaf, Y = YCount, N = NCount, Bounds = bounds
                });
            }

            Threshold best = thresholds.OrderBy(o => o.Value).First().Key;

            List <int> left  = new List <int>();
            List <int> right = new List <int>();

            values = _featureValues[best.Dimension];
            foreach (int index in indices)
            {
                float value = values[index];
                if (best.IsLeft(value))
                {
                    left.Add(index);
                }
                else
                {
                    right.Add(index);
                }
            }

            UpdateManager.WriteLine("Splitting at {0}: {1} {2}", best, left.Count, right.Count);

            min = bounds.MinimumBound[best.Dimension];
            max = bounds.MaximumBound[best.Dimension];
            Hyperrectangle <float> leftBounds  = (Hyperrectangle <float>)bounds.Clone();
            Hyperrectangle <float> rightBounds = (Hyperrectangle <float>)bounds.Clone();

            leftBounds.MaximumBound[best.Dimension]  = best.Value;
            rightBounds.MinimumBound[best.Dimension] = best.Value;
            int  leftNCount = (int)(((best.Value - min) * NCount) / (max - min));
            Node node       = new Node {
                Threshold = best, NodeType = NodeType.Branch, Y = YCount, N = NCount, Bounds = bounds
            };

            node.Left  = split(left, leftNCount, leftBounds);
            node.Right = split(right, NCount - leftNCount, rightBounds);
            _depth--;
            return(node);
        }
    }
}