Naive Bayes

To classify a piece of text as being either positive or negative sentiment. If the word “amazing” appears, what is the probability that that document is positive? Let’s use Bayes’ theorem.

We can work out the 3 terms on right side of the equation as follows:

  • P(positive) - count how many documents are positive and divide by the total number of documents,
  • P(“amazing”) - count how many times the word “amazing” appears in the corpus and divide by the total number of words,
  • P(“amazing”|positive) - out of all the positive documents, count how many times the word “amazing” appears and divide by the number of words in the positive documents.

So we converted the question from inferring the sentiment into a matter of working out the proportions a word appears in different documents. And this is something computers can do very quickly. But what do we do if we want to condition on a whole document and not just a single word? Let’s see below.

  • Multinomial NB: models word counts (good for typical bag-of-words).

  • Bernoulli NB: models word presence/absence (binary features).

How it works

We want to compute:

Since (P(\text{Words})) is the same for all classes, we only need:

The “Naïve” assumption: Words are conditionally independent given the class. So:

How text features fit in

Step 1: Turn text into numbers

You can use:

  • CountVectorizer: number of times each word appears.
  • TfidfVectorizer: same, but scaled by rarity (IDF).

Each document becomes a vector of word strengths.

Step 2: Compute probabilities

For each class (e.g., spam or ham):

  • Estimate how frequently each word appears in that class.
  • The classifier learns (P(w_i \mid \text{Class})) from the training data.

Then for a new document:

  • Look up each word’s probability under each class.
  • Multiply (or sum logs) to find which class is more probable.

Why IDF helps (intuition)

Let’s use a tiny example.

DocumentTextLabel
D₁“buy cheap pills now”spam
D₂“buy cheap watches”spam
D₃“meeting schedule update”ham

Vocabulary

$$buy, cheap, pills, now, watches, meeting, schedule, update$$

Case 1: Without IDF (plain counts)

Common word like “buy” appears in both spam and ham → its count will influence both equally.

But “pills” appears only in spam → it should have much higher importance.

Naïve Bayes with raw counts might under-emphasize that difference, because every word is treated equally frequent.

Case 2: With TF-IDF

IDF down-weights words that appear in many documents, and up-weights words that appear in few documents.

  • “buy” → appears in 3 docs → low IDF (common, less useful)
  • “pills” → appears in 1 doc → high IDF (rare, more discriminative)
  • “meeting” → appears in 1 doc (ham) → high IDF but used by other class

So in TF-IDF space:

buy    → small weight (common)
pills  → large weight in spam
meeting → large weight in ham

That means:

  • Spam docs will have high TF-IDF for “pills”, “cheap”, etc.
  • Ham docs will have high TF-IDF for “meeting”, “schedule”.

Now Naïve Bayes sees more distinctive numerical patterns per class, so classification becomes cleaner.

Mechanistic view

  • Input: matrix X from TfidfVectorizer

    • Each row = document
    • Each column = word’s TF-IDF
  • Model: MultinomialNB (or BernoulliNB)

    • Learns (P(w_i \mid \text{Class})) using these weighted values
  • Prediction: For new doc → compute

    → choose class with highest score.

Example

The model uses the TF-IDF matrix X (numbers) and learns how strongly each word (feature) is associated with each class.

Then, for a new document, it computes a score per class using:

Whichever class has the higher score → that’s the predicted class.

Mini example

Let’s pretend we’re classifying two types of messages:

MessageTextClass
D₁”buy pills”spam
D₂”cheap pills”spam
D₃”project meeting”ham
D₄”meeting schedule”ham

Vocabulary (from all docs)

[buy, cheap, pills, project, meeting, schedule]

So there are 6 words → 6 columns.

Step 1: TF-IDF matrix (simplified numbers)

To keep it readable, let’s assign rough TF-IDF values:

Docbuycheappillsprojectmeetingschedule
D₁ (spam)0.700.9000
D₂ (spam)00.70.9000
D₃ (ham)0000.70.90
D₄ (ham)00000.70.9

Step 2: Naïve Bayes learns ( P(w_i \mid \text{Class}) )

The model sums TF-IDF weights within each class and normalizes.

| Word | Sum in Spam | Sum in Ham | (P(w|Spam)) | (P(w|Ham)) | |------|--------------|-------------|----------------|---------------| | buy | 0.7 | 0 | 0.7 / (0.7+0.7+0.9+0.9) ≈ 0.19 | 0 | | cheap | 0.7 | 0 | 0.19 | 0 | | pills | 1.8 | 0 | 0.49 | 0 | | project | 0 | 0.7 | 0 | 0.27 | | meeting | 0 | 1.6 | 0 | 0.62 | | schedule | 0 | 0.9 | 0 | 0.35 |

(These are simplified normalized values — just to illustrate that spam words get probability mass in spam, ham words in ham.)

Step 3: Predict a new message

"cheap pills meeting"

TF-IDF (simplified) for this new doc:

WordTF-IDF
cheap0.6
pills0.8
meeting0.7

Now compute class scores.

Spam score

Since (P(meeting|Spam)) ≈ 0 (word unseen in spam), this term heavily reduces the score — but smoothing keeps it small, not infinite.

Ham score

Here, (P(cheap|Ham)) and (P(pills|Ham)) are near 0 (never seen in ham), but (P(meeting|Ham)) is large.

Step 4: Compare

  • Spam: big positive contributions from “cheap”, “pills”
  • Ham: big positive contribution from “meeting”, but zero for others

If the total spam score is higher → classified as spam.

Confusion Matrix

we used to evaluate the classifcation problem where row we have what we excepting and column is what machine predicted

Let say we have class 0 And 1

where below we have how many of 0 class are actullay predicted as 0 is 30 and how many 0 predicted as 1 was 12