public override bool Equals(object obj)
        {
            if (obj == null || GetType() != obj.GetType())
            {
                return(false);
            }

            var otherTable = obj as NaiveBayesProbabilityTable;

            if (otherTable.Rows != Rows)
            {
                return(false);
            }
            for (int i = 0; i < otherTable.Rows; i++)
            {
                List <ProbabilityTableEntry> otherRow = otherTable[i];
                List <ProbabilityTableEntry> thisRow  = this[i];
                if (otherRow.Count != thisRow.Count)
                {
                    return(false);
                }
                for (int j = 0; j < thisRow.Count; j++)
                {
                    ProbabilityTableEntry otherEntry = otherRow[j];
                    ProbabilityTableEntry thisEntry  = thisRow[j];
                    if (!otherEntry.Equals(thisEntry))
                    {
                        return(false);
                    }
                }
            }
            return(true);
        }
        public override bool Equals(object obj)
        {
            if (obj == null || GetType() != obj.GetType())
            {
                return(false);
            }

            ProbabilityTableEntry other = obj as ProbabilityTableEntry;

            return(other.Numerator == Numerator && other.Denominator == Denominator);
        }
        private List <ProbabilityStorage> PredictProbabilities(List <object> x)
        {
            var featureIndices = new List <int>();

            for (int i = 0; i < x.Count; i++)
            {
                var featureMappingDict = FeatureMappingDictionaries[i];
                int index = featureMappingDict.GetValueOrDefault(x[i], -1);
                featureIndices.Add(index);
            }
            var retPredictionProbabilites = new List <ProbabilityStorage>();

            foreach (KeyValuePair <object, int> mappedLabel in ClassMappingDictionary)
            {
                double calculatedProbability     = 1.0;
                int    labelIndex                = mappedLabel.Value;
                ProbabilityTableEntry labelEntry = ClassProbabilityTable[labelIndex];
                double labelProbability          = labelEntry.Numerator / (double)labelEntry.Denominator;
                for (int i = 0; i < featureIndices.Count; i++)
                {
                    if (featureIndices[i] == -1)
                    {
                        double toAdd = 1.0 / (FeatureProbabilityTables[i].Rows + 1);

                        double labelProbabilityPrime = (labelEntry.Numerator + toAdd) / (labelEntry.Denominator + 1);
                    }
                    else
                    {
                        int featureIndex = featureIndices[i];
                        NaiveBayesProbabilityTable currTable = FeatureProbabilityTables[i];
                        ProbabilityTableEntry      entry     = FeatureProbabilityTables[i][featureIndex][labelIndex];
                        double featureProbability            = CalculateFeatureProbability(currTable, featureIndex);
                        double divisionResult = CalculateFeatureLikelihood(currTable, entry.Numerator, labelIndex);
                        if (divisionResult == 0)
                        {
                            double toAdd = 1.0 / currTable.Rows;
                            divisionResult = (entry.Numerator + toAdd) / (entry.Denominator + 1);
                        }
                        calculatedProbability *= (divisionResult * labelProbability) / featureProbability;
                    }
                }
                retPredictionProbabilites.Add(new ProbabilityStorage(calculatedProbability, mappedLabel.Key));
            }
            retPredictionProbabilites.Sort(ProbabilityStorage.Sort);
            return(retPredictionProbabilites);
        }