3
\$\begingroup\$

I took the code from internet and tried to simplify it. So, what can I do?

How can I simplify my code more to make it easily understandable?

public class NaiveBayesAlgorithm
{
    private static List<Training> trainingDataSet = new List<Training>();
    private static Dictionary<string, HeightWeightSize> gaussianDataSet = new Dictionary<string, HeightWeightSize>();
    private static Dictionary<string, Gaussian> gaussianList = new Dictionary<string, Gaussian>();

    //takes a table
    public static void Train(List<Training> trainingData)
    {
        //adding the training data to the dataset
        trainingDataSet = trainingData;

        foreach(Training t in trainingDataSet)
        {
            if (!gaussianDataSet.ContainsKey(t.Class))
            {
                gaussianDataSet.Add(t.Class, new HeightWeightSize());
            }

            gaussianDataSet[t.Class].Height.Add(t.Height);
            gaussianDataSet[t.Class].Weight.Add(t.Weight);
            gaussianDataSet[t.Class].FootSize.Add(t.FootSize);
        }

        foreach(string key in gaussianDataSet.Keys)
        {
            Gaussian gaussian = new Gaussian();
            gaussian.Sex = key;
            gaussian.Count = gaussianDataSet[key].Height.Count;

            gaussian.HeightMean = Statistics.Mean(gaussianDataSet[key].Height);
            gaussian.WeightMean = Statistics.Mean(gaussianDataSet[key].Weight);
            gaussian.FootSizeMean = Statistics.Mean(gaussianDataSet[key].FootSize);

            gaussian.HeightVariance = Statistics.Variance(gaussianDataSet[key].Height);
            gaussian.WeightVariance = Statistics.Variance(gaussianDataSet[key].Weight);
            gaussian.FootSizeVariance = Statistics.Variance(gaussianDataSet[key].FootSize);

            gaussianList.Add(key, gaussian);
        }

        string str2 = string.Empty;
    }

    public static string Classify(double[] obj)
    {
        double maxScore = 0;
        string className = string.Empty;

        foreach( string key in gaussianList.Keys)
        {
            gaussianList[key].HeightNormalDist = Statistics.NormalDist(obj[0], gaussianList[key].HeightMean, gaussianList[key].HeightVariance);
            gaussianList[key].WeightNormalDist = Statistics.NormalDist(obj[1], gaussianList[key].WeightMean, gaussianList[key].WeightVariance);
            gaussianList[key].FootSizeNormalDist = Statistics.NormalDist(obj[2], gaussianList[key].FootSizeMean, gaussianList[key].FootSizeVariance);

            gaussianList[key].CombinedNormalDist = gaussianList[key].HeightNormalDist * gaussianList[key].WeightNormalDist * gaussianList[key].FootSizeNormalDist;
            gaussianList[key].UltimateScore = gaussianList[key].CombinedNormalDist * 0.5;

            if(maxScore < gaussianList[key].UltimateScore)
            {
                maxScore = gaussianList[key].UltimateScore;
                className = key;
            }
        }

        return className;
    }
}
\$\endgroup\$
2
  • \$\begingroup\$ I am not a machine learning professional but I would not call that machine learning. It is a fixed algorithmic - it is not neural. Other than that it seems like clean code to me. \$\endgroup\$
    – paparazzo
    Commented Oct 28, 2016 at 11:51
  • \$\begingroup\$ This is actually the way many machine learning classifiers work. The one caveat in this case is that the expected types are very specific but a ML library would have used a more generalized input type. \$\endgroup\$
    – Zack
    Commented Oct 28, 2016 at 12:59

1 Answer 1

1
\$\begingroup\$
HeightWeightSize

This doesn't make a good class name. What if you add another property? You'd need to change its name again.

I guess Person or something alike would be much better.


Gaussian gaussian = new Gaussian();
gaussian.Sex = key;
gaussian.Count = gaussianDataSet[key].Height.Count;

gaussian.HeightMean = Statistics.Mean(gaussianDataSet[key].Height);
gaussian.WeightMean = Statistics.Mean(gaussianDataSet[key].Weight);
gaussian.FootSizeMean = Statistics.Mean(gaussianDataSet[key].FootSize);

gaussian.HeightVariance = Statistics.Variance(gaussianDataSet[key].Height);
gaussian.WeightVariance = Statistics.Variance(gaussianDataSet[key].Weight);
gaussian.FootSizeVariance = Statistics.Variance(gaussianDataSet[key].FootSize);

You could simplify this by putting it inside the Gaussian class.

class Gaussian 
{
    public Gaussian(string sex, int count, double height, double weight, double footSize) 
    {
        HeightMean = Statistics.Mean(Height);
        // ...
    }

    public double HeightMean { get; }
    // ...
}

Adding it to a dictionary would then can be reduced to:

gaussianList.Add(key, new Gaussian(
    sex, 
    gaussianDataSet[key].Count
    gaussianDataSet[key].Height, 
    ...,
    ...)
);

There is still too much redundancy and you could improve more then the above but I don't know how the HeightWeightSize type looks like.

\$\endgroup\$
1
  • \$\begingroup\$ I'm not going to study the repository on github ;-) \$\endgroup\$
    – t3chb0t
    Commented Oct 28, 2016 at 20:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.