Skip to Content
Course content

199: Practice Exercise: Building a Text Classification Model

Click on the "Edit" button in the top corner of the screen to edit your slide content.

I've spent a lot of time reviewing code from developers transitioning into data science, and there is one mistake that happens almost every single time when they hit text classification: the belief that R can "read" a sentence the way we do. They'll try to pass a column of raw character strings directly into a logistic regression or a random forest model and act surprised when R throws a non-numeric argument to mathematical function error.

Thinking the Model "Reads" Text vs. Converting Text to a Matrix

Here is the reality: machine learning models are just fancy calculators. They don't know what the word "excellent" means; they only know how to multiply numbers. If you have a dataset of 1,000 customer reviews, you can't just hand the model a column of sentences. If you try, you're essentially asking the model to do math on a paragraph, which is impossible.

To fix this, we have to transform the text into a Document-Term Matrix (DTM). Imagine a giant spreadsheet where every single unique word across all your reviews becomes its own column. If a review contains the word "broken," you put a 1 in that column; if not, a 0. Now, the model isn't "reading"β€”it's looking at a pattern of 1s and 0s. This is the fundamental shift you need to make: you aren't classifying text; you're classifying the frequency and presence of tokens.

Assuming Word Count Equals Importance vs. Using TF-IDF

Once you start building these matrices, you'll hit a second wall. You'll notice that words like "the," "and," and "is" appear in every single document. If you just count words, these "stop words" will dominate your model, making it think that the word "the" is the primary indicator of whether a review is positive or negative. It's a noisy mess.

I usually suggest moving straight to TF-IDF (Term Frequency-Inverse Document Frequency). Instead of just counting, TF-IDF penalizes words that appear everywhere and rewards words that are unique to a specific document. If the word "stunning" appears three times in one review but rarely anywhere else, TF-IDF cranks up the weight of that word. That's how the model actually learns that "stunning" is a high-signal word for a positive review, while "the" is just noise.

The "Model-First" Mindset vs. The Pre-processing Pipeline

It's tempting to spend all your time tweaking the hyperparameters of your classifier. Don't do that. In text classification, the "win" happens in the cleaning phase. If you don't handle case folding (making everything lowercase) or stemming (turning "running," "runs," and "ran" into the single root "run"), your matrix becomes bloated with redundant columns. You'll end up with a model that overfits because it treats "Amazing!" and "amazing" as two completely different features.

# A quick glimpse at the workflow I recommend:
library(tm)

# 1. Create a corpus
corpus <- VCorpus(VectorSource(text_data))

# 2. The "Cleaning" phase (Where the real work is)
corpus <- tm_map(corpus, content_transformer(tolower))
corpus <- tm_map(corpus, removePunctuation)
corpus <- tm_map(corpus, removeWords, stopwords("english"))
corpus <- tm_map(corpus, stripWhitespace)

# 3. Transform to DTM
dtm <- DocumentTermMatrix(corpus)

# 4. Convert to a frame for the model
text_matrix <- as.data.frame(as.matrix(dtm))

Once you have that text_matrix, you're finally playing the same game as the model. Now you can plug it into a glm() or a randomForest() call, and it will actually work.




πŸ“‹ Practical Task

Build a Spam Detector for Marketing Emails

You have been handed a small dataset of email subject lines, some labeled as "spam" and others as "ham" (legitimate). Your goal is to build a classification model that can predict the label of a new email based on its content.

Requirements:

  • Create a data frame with at least 10 sample subject lines (5 spam, 5 ham). Ensure the spam examples use high-signal words like "Winner," "Cash," "Urgent," or "Free."
  • Use the tm package to create a corpus and perform the following cleaning steps: lowercase conversion, punctuation removal, and stop-word removal.
  • Convert the cleaned corpus into a Document-Term Matrix (DTM) and then into a data frame.
  • Train a simple Logistic Regression model (using glm() with family = "binomial") to predict the spam label.
  • Test your model by predicting the label for a new, unseen subject line: "Claim your free cash prize now!"

Deliverable: A complete R script that prints the final prediction (spam or ham) for the test string.

Rating
0 0

There are no comments for now.

to be the first to leave a comment.