Gaussian Naive Bayes Classifier (Machine Learning OA)
Problem statement
Implement a Gaussian Naive Bayes classifier from scratch, without a machine-learning or numerical library. Train it on xTrain and yTrain, then return the predicted class label for each row of xTest, in the original row order.
Each row has m numeric features. yTrain[i] is the integer class label of training row xTrain[i]. The classes are the distinct values that appear in yTrain.
Training
For every class c, let n_c be the number of training rows labeled c, and let n be the total number of training rows. Compute:
- The prior
prior[c] = n_c / n. - For every feature
j, the meanmean[c][j]of featurejover the rows of classc. - For every feature
j, the variancevar[c][j] = (1 / n_c) * sum((x[j] - mean[c][j])^2) + epsilon, where the sum runs over the rowsxof classc. This divides byn_c, notn_c - 1. Addingepsilonkeeps every variance positive, even for a class with one row or a constant feature.
Prediction
Naive Bayes treats the features as independent given the class, and models each feature with a normal distribution. For a test row x, the score of class c is its log posterior up to a shared constant:
score(c) = log(prior[c]) + sum over j of ( -0.5 * log(2 * pi * var[c][j]) - (x[j] - mean[c][j])^2 / (2 * var[c][j]) )
Here log is the natural logarithm. Predict the class with the largest score.
Practice contract
Work with log scores. Multiplying the densities directly can underflow to zero. The tests guarantee that, for every test row, the best class's score is larger than every other class's score by more than 10^-3, so small floating-point differences cannot change the answer. If yTrain has only one class, every test row is predicted as that class.
Function
predictGaussianNaiveBayes(xTrain: double[][], yTrain: int[], xTest: double[][], epsilon: double) → int[]Examples
Example 1
xTrain = [[1.0],[2.0],[3.0],[6.0],[7.0],[8.0]]yTrain = [0,0,0,1,1,1]xTest = [[2.5],[6.5],[4.4]]epsilon = 0.001return = [0,1,0]Class 0 has mean 2 and class 1 has mean 7. Both have prior 0.5 and variance 2/3 + 0.001 ≈ 0.6677. With equal priors and equal variances, the class whose mean is closer wins.
2.5is closer to2, so it is class0.6.5is closer to7, so it is class1.4.4has squared distance5.76to mean2and6.76to mean7. The scores are about-5.72for class0and-6.47for class1, so it is class0.
Example 2
xTrain = [[0,0],[0.4,0.2],[-0.4,-0.2],[5,5],[1,9],[9,1]]yTrain = [2,2,2,7,7,7]xTest = [[1.5,1.5],[0,0.1],[4,4]]epsilon = 0.01return = [7,2,7]Class 2 has means [0, 0] and small variances of about [0.1167, 0.0367]. Class 7 has means [5, 5] and variances of about [10.6767, 10.6767]. Both priors are 0.5.
[1.5, 1.5]is closer to[0, 0], but class2is so tight that this point is very unlikely under it. The scores are about-40.13for class2and-6.05for class7, so it is class7.[0, 0.1]scores about0.06for class2and-7.19for class7, so it is class2. A log score can be positive because a density can be larger than1.[4, 4]scores about-286.56for class2and-4.99for class7, so it is class7.
Example 3
xTrain = [[-1],[1],[-1],[1],[3],[5]]yTrain = [0,0,0,0,5,5]xTest = [[2.2],[2.6],[0]]epsilon = 0.5return = [0,5,0]Class 0 has prior 2/3, mean 0, and variance 1 + 0.5 = 1.5. Class 5 has prior 1/3, mean 4, and the same variance 1.5. With equal variances, the score difference is log(2) ≈ 0.693 from the priors, plus the difference in (x - mean)^2 / 3.
- For
2.2:4.84 / 3 ≈ 1.613for class0and3.24 / 3 = 1.08for class5. Class5gains0.533from distance, but class0gains0.693from its prior. The scores are about-3.14and-3.30, so it is class0. - For
2.6: the distance terms are about2.253and0.653. Class5gains1.6, which beats the prior advantage. The scores are about-3.78and-2.87, so it is class5. 0is the mean of class0, so it is class0.
Constraints
- The following bounds are practice assumptions.
1 <= xTrain.length == yTrain.length <= 3001 <= xTest.length <= 3001 <= m <= 8, and every row ofxTrainandxTesthas exactlymvalues.-100 <= xTrain[i][j], xTest[i][j] <= 1000 <= yTrain[i] <= 1000.001 <= epsilon <= 10- For every test row, the largest class score exceeds every other class score by more than
10^-3.