Text Classification/Naive Bayes and Sentiment Classification

Lesson 2.12,595 words

Naive Bayes and Sentiment Classification

Text classification assigns a category to a document — positive or negative, spam or not, one topic among many. Naive Bayes is a generative solution: apply Bayes' rule, assume the words are conditionally independent given the class, and the winning class is the one maximizing the product of a prior and per-word likelihoods.

╌╌╌╌

A review says awful pizza and ridiculously overpriced; you want a machine to read it and answer negative. An email says online pharmaceutical, WITHOUT ANY COST, Dear Winner; you want spam. A research paper is about epidemiology, not embryology; you want the right subject label. These are all the same task: take one document and assign it a category from a fixed set.1 This is text classification. Its simplest and oldest solution, naive Bayes, is still a strong baseline.

Formally, supervised classification takes an input document and a fixed set of classes and returns a predicted class . Supervised means we learn the mapping from a training set of documents each hand-labeled with a class, . A probabilistic classifier goes further and reports for every class, not just the winner — useful when a later stage wants to weigh the decision rather than commit to it early.2

We focus on sentiment analysis, the extraction of the positive or negative orientation a writer expresses toward something. In its binary form the words of a review are strong cues on their own: great, richly, awesome pull positive; pathetic, awful, ridiculously pull negative. Naive Bayes formalizes this intuition.

Naive Bayes is a generative classifier: it builds a model of how each class would generate a document, then selects the class that most plausibly produced the one in hand. Its counterpart, the discriminativelogistic regression of the next lesson, skips the generative story and learns directly which features separate the classes. Discriminative models are usually more accurate, but the generative one is faster to train, needs less data, and is the right place to start.

The bag-of-words representation

Before any probability, we must decide what a document is to the classifier. Naive Bayes represents a document as a bag of words: an unordered multiset of its words, position discarded, only frequency kept. I love this movie, it's sweet and sweet, it's this movie I love are the same bag. The word love counts the same whether it is the first word or the last.

The bag-of-words view of a movie review. Word order is discarded; only the count of each word type survives, so the document becomes a table of (word, frequency) pairs.

This throws away real information — the movie was not good and the movie was good, not collapse to the same bag — yet the representation works well in practice. For topic and sentiment, the presence of the right words carries most of the signal, and discarding word order costs little. The features of naive Bayes are these word identities, written for the words at each position in .

The naive Bayes classifier

Naive Bayes returns the class with the highest posterior probability given the document:

We cannot estimate directly — there are too many possible documents — so we turn it around with Bayes' rule, , applied to and :

The denominator is the same for every class, and we are choosing the arg max over classes of the same document , so it cannot change which class wins. Drop it:

The winning class maximizes the product of two things: the prior , how common the class is, and the likelihood , how well the class explains the document. This is why naive Bayes is called generative — read as a recipe for producing a document: sample a class from the prior, then sample the words from that class.

Bayes' rule turns the hard-to-estimate posterior into a prior times a likelihood; the evidence is dropped because it is constant across classes.

The naive assumption

The likelihood is still intractable: estimating the probability of every possible combination of words would need more parameters and more data than any corpus supplies. Naive Bayes makes two simplifying assumptions to escape.

The first is the bag of words already introduced: position does not matter, so love contributes the same whether it is word 1 or word 20. The second, which gives the method its name, is the naive Bayes assumption — the words are conditionally independent given the class:

The assumption is false — fun and film are not independent, and New raises the odds of York — but pretending they are collapses a combinatorial explosion into a product of easy factors, and the resulting classifier works far better than the false premise suggests. Putting the pieces together, the class naive Bayes chooses is:

Log space

That product runs over every word position, so for a document of any length it multiplies dozens or hundreds of probabilities, each well below . The result underflows to zero in floating point. The fix is to work in log space: because is monotonic, the class that maximizes the product also maximizes the log of the product, and a log turns the product into a sum:

This is numerically safe and faster. It also exposes the shape of the model: the predicted class is a linear function of the input features (each contributes an additive log-weight). Classifiers that decide by a linear combination of their inputs — naive Bayes here, logistic regression next lesson — are called linear classifiers.

Training: counting with smoothing

Where do and come from? We estimate them from the training set by maximum likelihood — just the frequencies in the data.

For the prior, ask what fraction of the training documents belong to class . With the number of documents in class and the total:

For the likelihood , treat a document's words as a bag drawn from class . Concatenate every document of class into one large text, and estimate the probability of word as its fraction among all word tokens in that class:

Here is the vocabulary — the union of all word types across all classes, not just the words seen in class . That detail matters for the denominator below.

The zero-probability problem

Maximum likelihood fails on unseen words. Suppose the word fantastic never appears in any positive training document (perhaps it only showed up, sarcastically, in a negative review). Then

Because naive Bayes multiplies every word's likelihood, a single zero factor drags the whole product to zero: a document containing fantastic can never be classified positive, no matter how much other evidence points that way. A single unseen word overrides all the rest.

The standard fix is add-one (Laplace) smoothing: pretend every vocabulary word was seen one extra time in each class. Add to every count and, to keep the result a probability, add (one for each word type) to the denominator:

No probability is ever exactly zero, so no single word can override the rest of the evidence. Two practical points on the vocabulary. Unknown words — words in the test document that never appeared in any training class — are simply dropped from the test document; naive Bayes keeps no unknown-word model. Some systems also drop stop words (very frequent function words like the and a), though in most text classification tasks a stop list does not help and the whole vocabulary is used.

The training and testing procedures

The whole training procedure is: count documents per class for the priors, count words per class for the smoothed likelihoods, over a shared vocabulary .

Algorithm:Train-Naive-Bayes(D,C)\textsc{Train-Naive-Bayes}(D, C) — estimate logP(c)\log P(c) and logP(wc)\log P(w \mid c)
  1. 1
    input: labeled documents DD, classes CC
  2. 2
    VV \gets set of all word types in DD
  3. 3
    for each class cCc \in C do
  4. 4
    NdocN_{\text{doc}} \gets number of documents in DD
  5. 5
    NcN_c \gets number of documents in DD with class cc
  6. 6
    logprior[c]logNcNdoc\textit{logprior}[c] \gets \log \dfrac{N_c}{N_{\text{doc}}}
  7. 7
    bigdoc[c]\textit{bigdoc}[c] \gets concatenation of all documents in DD with class cc
  8. 8
    for each word wVw \in V do
  9. 9
    count(w,c)\textit{count}(w, c) \gets occurrences of ww in bigdoc[c]\textit{bigdoc}[c]
  10. 10
    loglikelihood[w,c]logcount(w,c)+1wV(count(w,c)+1)\textit{loglikelihood}[w, c] \gets \log \dfrac{\textit{count}(w, c) + 1}{\sum_{w' \in V}\bigl(\textit{count}(w', c) + 1\bigr)}
  11. 11
    return logprior\textit{logprior}, loglikelihood\textit{loglikelihood}, VV

Testing sums the log-prior and the log-likelihoods of the in-vocabulary words, then returns the highest-scoring class.

Algorithm:Test-Naive-Bayes(d,logprior,loglikelihood,C,V)\textsc{Test-Naive-Bayes}(d, \textit{logprior}, \textit{loglikelihood}, C, V) — classify document dd
  1. 1
    for each class cCc \in C do
  2. 2
    sum[c]logprior[c]\textit{sum}[c] \gets \textit{logprior}[c]
  3. 3
    for each position ii in dd do
  4. 4
    wd[i]w \gets d[i]
  5. 5
    if wVw \in V then
  6. 6
    sum[c]sum[c]+loglikelihood[w,c]\textit{sum}[c] \gets \textit{sum}[c] + \textit{loglikelihood}[w, c]
  7. 7
    return arg maxcsum[c]\argmax_c \textit{sum}[c]

A worked example

Take a two-class sentiment problem, positive () and negative (), with five tiny training reviews and one test review, simplified from real movie reviews.

SetClassDocument
Trainingjust plain boring
Trainingentirely predictable and lacks energy
Trainingno surprises and very few laughs
Trainingvery powerful
Trainingthe most fun film of the summer
Testpredictable with no fun

Priors. Three of the five training documents are negative, two positive:

Vocabulary and counts. The vocabulary has word types across both classes. The negative class holds word tokens, the positive class . The test word with never appears in training, so it is an unknown word and we drop it; the test review reduces to predictable no fun. The three surviving test words appear in the concatenated per-class text with the counts below — note that fun is unseen in the negative class and predictable and no are unseen in the positive class, exactly the zeros smoothing must repair:

Word
predictable10
no10
fun01
class tokens 149

Now apply add-one smoothing to the three surviving words, adding to each count and to each class-token denominator:

Scores. Multiply each prior by the product of its three word likelihoods:

The negative score is the larger, so the model predicts negative for predictable with no fun. The single word fun (twice as likely under positive) is outweighed by predictable and no leaning negative, and by the higher negative prior.

The worked naive-Bayes decision for "predictable with no fun." The negative class scores 6.1e-5 against the positive class's 3.2e-5, so the arg max picks negative. "with" is dropped as an unknown word; the two negative-leaning words outweigh the single positive-leaning "fun".

Working in log space gives the same winner and shows the additive structure directly. Taking base- logs, the negative score is , while the positive score is . The larger (less negative) again selects negative, and each word contributes one additive term — the linear form promised earlier, now with real numbers. Exponentiating recovers the probabilities: and , matching the products above.

Optimizing for sentiment

Standard naive Bayes works for sentiment, but three small changes reliably improve it.

Binary naive Bayes

For sentiment, whether a word occurs matters more than how often. A review that says great five times is not five times more positive than one that says it once. Binary naive Bayes clips each document's word counts to before training and testing: remove all duplicate words within a document, then concatenate. The counts across the whole class can still exceed great has a class count of if it appears in two different documents — but no single document contributes more than one.

Binary naive Bayes clips per-document counts to one. Within a document, repeated words are deduplicated before counting; the same word can still accrue count across several documents.

Handling negation

The bag of words is blind to negation: I really like this movie (positive) and I didn't like this movie (negative) share the token like, yet mean opposites. A simple, effective baseline runs during text normalization: prepend the prefix NOT_ to every word after a token of logical negation (n't, not, no, never) until the next punctuation mark. So

Now NOT_like and NOT_recommend accrue negative associations, while NOT_bored and NOT_dismiss accrue positive ones, and the classifier learns them like any other feature. It is crude — it ignores the true scope of negation — but works well in practice.

Sentiment lexicons

When labeled data is scarce, we can use sentiment lexicons — hand-built lists of words pre-annotated as positive or negative, such as the General Inquirer, LIWC, and the MPQA Subjectivity Lexicon. A lexicon supplies dense features: instead of a separate feature per word, add one feature counting occurrences of any positive-lexicon word and another for negative-lexicon words. With plentiful matched training data, individual-word features beat two lexicon features; but when data is sparse or unrepresentative, the dense lexicon features generalize better.

Evaluating the classifier

We now have a trained naive-Bayes classifier that labels documents. Before pushing on to a better model, we need a way to say how good any classifier is — and, when one model beats another, whether the win is real or luck. Those questions are general (they apply to every classifier in the module, not just naive Bayes), so they get their own lesson. This continues in Evaluating Classifiers, which builds the confusion matrix, defines precision, recall, and F1, and closes on the paired bootstrap test for statistical significance. The rest of this lesson steps back to place naive Bayes among the models that came after it.

Beyond bag-of-words: transformer text classification

The bag-of-words assumption that makes naive Bayes tractable is also its main limitation. Discarding word order collapses the movie was not good and the movie was good, not to the same input; conditional independence pretends New and York carry unrelated evidence. The NOT_ prefix and lexicon features are partial workarounds. The line of work that removed these assumptions entirely comes from named, public research past this chapter, and it changed both the representation and the training objective.

Contextual embeddings and fine-tuning (Devlin et al., 2019)

BERT — Bidirectional Encoder Representations from Transformers (Devlin, Chang, Lee, and Toutanova, NAACL 2019) — is a transformer encoder pretrained on a large unlabeled corpus with a masked language model objective: hide a fraction of the tokens and train the network to predict them from both left and right context. The result is a contextual embedding for every token — a vector that depends on the whole sentence, so bank in river bank and bank in savings bank receive different vectors. That alone breaks the two assumptions naive Bayes rests on: order is preserved through position information, and words condition on one another through self-attention rather than being treated as independent.

To classify a document, BERT prepends a special [CLS] token to the input, runs the sequence through the encoder, and treats the encoder's output vector at the [CLS] position as a representation of the whole document. A single linear layer — a classification head — maps that vector to class scores, and the whole network is fine-tuned end to end on the labeled sentiment data: the pretrained weights are nudged, and the head is learned from scratch, by gradient descent on the classification loss. Where naive Bayes estimates its parameters by counting once, the transformer adjusts hundreds of millions of pretrained weights against the task.

Transformer text classification (BERT). A [CLS] token is prepended, the sentence runs through a pretrained encoder, and the encoder output at the [CLS] position feeds a linear classification head fine-tuned on the labels. Order and word interactions are preserved by self-attention, unlike the bag of words.

When to still reach for naive Bayes

The transformer wins on accuracy across essentially every text-classification benchmark, and it captures negation, sarcasm, and word interactions that a bag of words cannot represent. The cost is orders of magnitude more computation, a large pretrained model to host, and far less interpretability — a naive-Bayes weight is a readable log-likelihood per word, while a fine-tuned attention weight is not. When labeled data is scarce, the classes are cleanly separated by a few keywords, the model must run on modest hardware, or a human needs to audit why a document was labeled, naive Bayes remains a strong, fast baseline — which is why it is the right place to start and still a standard point of comparison. The contrast is the same one drawn between generative and discriminative models above, taken to its modern extreme: counting once versus learning a deep function, interpretable versus accurate.3

Footnotes

  1. Jurafsky & Martin, Speech and Language Processing (3rd ed.), Ch. 4 — Naive Bayes and Sentiment Classification: text categorization as assigning a label to a document, with sentiment analysis, spam detection, and subject/topic labeling as the running tasks (the last being the task naive Bayes was invented for in 1961).
  2. Jurafsky & Martin, §4.1 — Naive Bayes Classifiers: supervised classification maps a document to a class learned from labeled examples; the multinomial naive Bayes model, Bayes' rule, the bag-of-words and conditional-independence assumptions, and the log-space linear form.
  3. Transformer-based text classification. Devlin, Chang, Lee, and Toutanova, BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding, NAACL-HLT (2019) — a transformer encoder pretrained with a masked-language-model objective yields contextual token embeddings; a document is classified by prepending a [CLS] token and fine-tuning a linear head on its encoder output. This drops both the bag-of-words and conditional-independence assumptions (order and word interactions are modeled by self-attention), trading naive Bayes' single counting pass and interpretability for higher accuracy at much greater computational cost. The transformer architecture it builds on is Vaswani et al., Attention Is All You Need, NeurIPS (2017).

╌╌ END ╌╌