Beispiel #1
0
        /// <summary>
        ///   Determines whether the specified <see cref="DecisionRule"/> is equal to this instance.
        /// </summary>
        ///
        /// <param name="other">The <see cref="DecisionRule"/> to compare with this instance.</param>
        ///
        /// <returns>
        ///   <c>true</c> if the specified <see cref="DecisionRule"/>
        ///   is equal to this instance; otherwise, <c>false</c>.
        /// </returns>
        ///
        public bool Equals(DecisionRule other)
        {
            if ((object)other == null)
            {
                return(false);
            }

            return(this.Output == other.output &&
                   this.Antecedents.SetEquals(other.Antecedents));
        }
Beispiel #2
0
        /// <summary>
        ///   Compares this instance to another <see cref="DecisionRule"/>.
        /// </summary>
        ///
        public int CompareTo(DecisionRule other)
        {
            int order = this.Output.CompareTo(other.Output);

            if (order == 0)
            {
                return(this.Antecedents.Count.CompareTo(other.Antecedents.Count));
            }

            return(order);
        }
Beispiel #3
0
 /// <summary>
 ///   Gets whether this rule and another rule have
 ///   the same antecedents but different outputs.
 /// </summary>
 ///
 /// <param name="rule"></param>
 ///
 /// <returns>True if the two rules are contradictory;
 ///   false otherwise.</returns>
 ///
 public bool IsInconsistentWith(DecisionRule rule)
 {
     return(Antecedents.SetEquals(rule.Antecedents) && Output != rule.Output);
 }
Beispiel #4
0
        /// <summary>
        ///   Computes the reduction algorithm.
        /// </summary>
        ///
        /// <param name="inputs">A set of training inputs.</param>
        /// <param name="outputs">The outputs corresponding to each of the inputs.</param>
        ///
        /// <returns>The average error after the reduction.</returns>
        ///
        public double Compute(double[][] inputs, int[] outputs)
        {
            int samples = outputs.Length;

            bool[] actual   = new bool[samples];
            bool[] expected = new bool[samples];

            DecisionRule[] list = decisionList.ToArray();

            var antecedents = new HashSet <Antecedent>();


            foreach (DecisionRule rule in list)
            {
                foreach (Antecedent antecedent in rule)
                {
                    antecedents.Add(antecedent);
                }
            }



            // 1. Eliminate unnecessary antecedents
            for (int y = 0; y < decisionList.OutputClasses; y++)
            {
                for (int i = 0; i < outputs.Length; i++)
                {
                    expected[i] = outputs[i] == y;
                }

                var unnecessary = new HashSet <Antecedent>();

                /*foreach (var rule in list)
                 * {
                 *  if (rule.Output != y)
                 *      continue;
                 */
                foreach (var antecedent in antecedents)
                {
                    for (int i = 0; i < inputs.Length; i++)
                    {
                        actual[i] = antecedent.Match(inputs[i]);
                    }

                    if (CanEliminate(actual, expected))
                    {
                        unnecessary.Add(antecedent);
                    }
                }
                //}

                foreach (var antecedent in unnecessary)
                {
                    foreach (var rule in list)
                    {
                        if (rule.Output == y)
                        {
                            rule.Antecedents.Remove(antecedent);
                        }
                    }
                }
            }

            bool[][] matches = new bool[list.Length][];
            int[]    counts  = new int[list.Length];
            for (int i = 0; i < matches.Length; i++)
            {
                DecisionRule rule = list[i];

                matches[i] = new bool[outputs.Length];
                for (int j = 0; j < inputs.Length; j++)
                {
                    matches[i][j] = rule.Match(inputs[j]);

                    if (matches[i][j])
                    {
                        counts[i]++;
                    }
                }
            }

            // double start = computeError(inputs, outputs, list);

            for (int i = 0; i < list.Length; i++)
            {
                if (list[i] == null)
                {
                    continue;
                }

                for (int j = 0; j < list.Length; j++)
                {
                    if (list[i] == null)
                    {
                        break;
                    }
                    if (list[j] == null)
                    {
                        continue;
                    }

                    if (list[i].IsInconsistentWith(list[j]))
                    {
                        if (counts[i] > counts[j])
                        {
                            list[j]   = null;
                            counts[j] = 0;
                        }
                        else
                        {
                            list[i]   = null;
                            counts[i] = 0;
                        }
                    }
                }
            }

            list = list.Distinct(allowNulls: false);

            List <DecisionRule> newList = new List <DecisionRule>(list);

            // double middle = computeError(inputs, outputs, list);

            // 2. Eliminate redundant rules from the set

            for (int y = 0; y < decisionList.OutputClasses; y++)
            {
                for (int i = 0; i < outputs.Length; i++)
                {
                    expected[i] = outputs[i] == y;
                }

                var unnecessary = new HashSet <DecisionRule>();

                foreach (var rule in newList)
                {
                    if (rule.Output != y)
                    {
                        continue;
                    }

                    for (int i = 0; i < inputs.Length; i++)
                    {
                        actual[i] = rule.Match(inputs[i]);
                    }

                    if (CanEliminate(actual, expected))
                    {
                        unnecessary.Add(rule);
                    }
                }

                foreach (var rule in unnecessary)
                {
                    newList.Remove(rule);
                }
            }


            // double final = computeError(inputs, outputs, newList);

            decisionList.Clear();
            decisionList.AddRange(newList);

            // Compute new decision error
            double newError = ComputeError(inputs, outputs);

            return(newError);
        }