Naive Bayes
TensorFlow
machine learning
tutorial
data science

How to use Naive Bayes in TensorFlow?

ML System Design practice on Codemia

Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.

Practice ML system design

Introduction

Naive Bayes is a simple probabilistic classifier, but TensorFlow is primarily designed for tensor computation and neural networks. That means you can implement Naive Bayes with TensorFlow operations, though for many everyday projects scikit-learn remains the more natural choice.

When TensorFlow Makes Sense for Naive Bayes

If your workflow already lives inside TensorFlow, or you want a differentiable tensor-based implementation for educational reasons, building Naive Bayes manually can be reasonable. The key pieces are:

  • class prior probabilities
  • per-class feature statistics
  • log-probability scoring for numerical stability

For continuous features, Gaussian Naive Bayes is the most straightforward variant.

A Simple Gaussian Naive Bayes Implementation

The idea is to compute a mean and variance for each feature within each class, then score new examples by summing log-likelihoods plus the log prior.

python
1import tensorflow as tf
2
3
4class GaussianNaiveBayes:
5    def fit(self, x, y):
6        x = tf.convert_to_tensor(x, dtype=tf.float32)
7        y = tf.convert_to_tensor(y, dtype=tf.int32)
8
9        classes, _ = tf.unique(y)
10        self.classes_ = classes
11
12        means = []
13        variances = []
14        priors = []
15
16        for class_id in classes:
17            mask = tf.equal(y, class_id)
18            class_x = tf.boolean_mask(x, mask)
19            means.append(tf.reduce_mean(class_x, axis=0))
20            variances.append(tf.math.reduce_variance(class_x, axis=0) + 1e-6)
21            priors.append(tf.cast(tf.shape(class_x)[0], tf.float32) / tf.cast(tf.shape(x)[0], tf.float32))
22
23        self.means_ = tf.stack(means)
24        self.variances_ = tf.stack(variances)
25        self.log_priors_ = tf.math.log(tf.stack(priors))
26        return self
27
28    def predict(self, x):
29        x = tf.convert_to_tensor(x, dtype=tf.float32)
30        x = tf.expand_dims(x, axis=1)
31
32        means = tf.expand_dims(self.means_, axis=0)
33        variances = tf.expand_dims(self.variances_, axis=0)
34
35        log_likelihood = -0.5 * tf.reduce_sum(
36            tf.math.log(2.0 * tf.constant(3.14159265) * variances)
37            + tf.square(x - means) / variances,
38            axis=2,
39        )
40
41        scores = log_likelihood + self.log_priors_
42        indices = tf.argmax(scores, axis=1)
43        return tf.gather(self.classes_, indices)
44
45
46x_train = [[1.0, 2.0], [1.2, 1.8], [4.0, 4.5], [4.2, 4.8]]
47y_train = [0, 0, 1, 1]
48
49model = GaussianNaiveBayes().fit(x_train, y_train)
50predictions = model.predict([[1.1, 2.1], [4.1, 4.6]])
51
52print(predictions.numpy())

This implementation is compact, uses TensorFlow tensors throughout, and works well for demonstration or small custom pipelines.

Why Log Probabilities Matter

Naive Bayes multiplies many probabilities together. Those values quickly become extremely small, so practical implementations work in log space. In log space, multiplication becomes addition, which is more stable numerically and easier to debug.

That is why the example above stores log_priors_ and computes log_likelihood rather than multiplying raw densities directly.

TensorFlow Versus scikit-learn

If your goal is just to train a Naive Bayes classifier quickly, scikit-learn is usually the better tool because it already provides optimized, well-tested implementations such as GaussianNB, MultinomialNB, and BernoulliNB.

TensorFlow becomes useful when:

  • you need everything in one tensor-centric runtime
  • you are teaching or learning the math behind the classifier
  • you want custom tensor operations around the classifier

For text classification with token counts, multinomial Naive Bayes is often a better fit than the Gaussian version shown here.

Common Pitfalls

  • Expecting a built-in high-level Naive Bayes API in TensorFlow leads to unnecessary searching because the library does not emphasize that family of models.
  • Using Gaussian Naive Bayes on count-based text features is usually the wrong variant.
  • Forgetting variance smoothing can cause divide-by-zero problems when a feature has no variation inside a class.
  • Multiplying raw probabilities instead of summing log-probabilities can create severe numerical underflow.
  • Reaching for TensorFlow when a simple scikit-learn model would do may add complexity without a real benefit.

Summary

  • TensorFlow can implement Naive Bayes, but it does not provide the most convenient built-in API for it.
  • Gaussian Naive Bayes is straightforward to express with TensorFlow tensor operations.
  • Use log probabilities and small variance smoothing for numerical stability.
  • Pick the Naive Bayes variant that matches your feature type, especially for text data.
  • For many practical projects, scikit-learn remains the simpler choice unless you specifically need a TensorFlow-based implementation.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

ML System Design practice on Codemia

Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.

Practice ML system design

All Rights Reserved.