Separate multi-class choices from multi-label tags
classification
multi-class classification
multi-label classification
Learn the difference between multi-class and multi-label text classification using inaugural paragraphs.
Ravi is building filters for an archive search page. One control asks for a time period, where each paragraph can belong to only one period. Another asks for themes, where a paragraph can mention work, time, people, all three, or none.
Those two controls look similar on the screen, but they ask different questions. One forces a single choice. The other lets several tags sit on the same paragraph.
TipWhat you will learn
By the end of this lesson, you will be able to:
distinguish multi-class from multi-label classification;
build a four-way period label from years;
read a confusion matrix for a multi-class model;
create theme labels with a small quanteda dictionary; and
explain why label-level accuracy can mislead in multi-label work.
Load paragraphs and build periods
Multi-class classification means one document receives one label from several mutually exclusive choices. The four periods below are equal-width year bins: 1789-1847, 1848-1906, 1907-1965, and 1966-2025. They are technical bins for this lesson, not claims about political history.
Each paragraph receives exactly one period label. That single-label structure is what makes the task multi-class rather than multi-label.
Fit the four-way classifier
The split keeps whole speeches together. The seed for the split is 5201, and the seed before fitting is 5202. The model uses tf-idf features and a multinomial glmnet classifier.
Four-way model accuracy beside deployable and oracle baselines
Measure
Value
Model accuracy
0.5938
Training-majority baseline
0.3324
Test-majority oracle
0.3324
knitr::kable(as.data.frame(period_confusion$table),col.names =c("Model prediction", "Recorded period", "Paragraphs"),caption ="Confusion matrix for the four-way period classifier",row.names =FALSE)
Confusion matrix for the four-way period classifier
Model prediction
Recorded period
Paragraphs
1789-1847
1789-1847
19
1848-1906
1789-1847
23
1907-1965
1789-1847
5
1966-2025
1789-1847
1
1789-1847
1848-1906
13
1848-1906
1848-1906
63
1907-1965
1848-1906
9
1966-2025
1848-1906
3
1789-1847
1907-1965
14
1848-1906
1907-1965
30
1907-1965
1907-1965
47
1966-2025
1907-1965
8
1789-1847
1966-2025
3
1848-1906
1966-2025
2
1907-1965
1966-2025
32
1966-2025
1966-2025
80
The overall accuracy is 0.5938 on this speech-level split. A deployable baseline chooses the most common period in training, 1966-2025, then applies that rule to test; it scores 0.3324. Looking at the test labels first produces the same 0.3324 oracle value by coincidence on this split, but that is not a rule a deployed system could choose in advance. The confusion matrix shows, for example, that many 1907-1965 test paragraphs are sent to the 1966-2025 label.
Check recall by class
Recall asks, within one recorded class, how many rows returned to that class. For a multi-class task, recall by class is often more useful than one accuracy number.
The 1789-1847 period has recall of 0.396, while the 1848-1906 period has recall of 0.716. The model’s mistakes are uneven, so the confusion matrix is required.
Build several theme labels
Multi-label classification means a document may receive zero, one, or several labels at the same time. A small quanteda dictionary marks three vocabulary themes. These labels are the dictionary’s own output. Agreement with them measures agreement with the dictionary, not agreement with human themes or with the corpus itself.
A document-feature matrix stores document rows and word columns. quanteda dictionaries use glob matching by default, so a star means “starts with” here: work* matches work, working, and workforce.
theme_dictionary <-dictionary(list(work =c("work*", "labor", "employment", "industry", "business"),time =c("year*", "day*", "time*", "today", "future"),people =c("people", "citizen*", "family", "families", "children")))theme_dfm <-corpus( paragraphs,text_field ="paragraph",docid_field ="paragraph_id") |>tokens(remove_punct =TRUE) |>tokens_tolower() |>dfm() |>dfm_lookup(dictionary = theme_dictionary)theme_counts <-convert(theme_dfm, to ="data.frame") |>as_tibble() |>rename(paragraph_id = doc_id)theme_labels <- paragraphs |>select(paragraph_id) |>left_join(theme_counts, by =join_by(paragraph_id)) |>mutate(across(-paragraph_id, \(count) count >0))label_count_table <- theme_labels |>mutate(label_count =rowSums(across(-paragraph_id))) |>count(label_count, name ="paragraphs")knitr::kable( label_count_table,col.names =c("Theme labels on a paragraph", "Paragraphs"),caption ="Paragraphs can carry zero, one, or several dictionary labels",row.names =FALSE)
Paragraphs can carry zero, one, or several dictionary labels
Theme labels on a paragraph
Paragraphs
0
449
1
605
2
273
3
50
The memorable distinction is this: multi-class chooses one box from several; multi-label lets the same document carry several tags.
Accuracy can reward saying no
Most possible theme labels are absent. A do-nothing system that predicts every label as absent therefore gets many cells right while finding no present labels. That is why multi-label reporting needs per-label precision and recall.
knitr::kable( baseline_accuracy_summary |>mutate(value =round(value, 4)),col.names =c("Baseline measure", "Accuracy"),caption ="Two overall views of the always-absent baseline",row.names =FALSE)
Two overall views of the always-absent baseline
Baseline measure
Accuracy
Label-cell accuracy
0.6851
Exact empty-set accuracy
0.3261
Precision is NA because the baseline never predicts a present label, leaving zero predicted positives in the denominator. That is an undefined metric, not a display error.
The always-absent baseline gets 0.6851 label-cell accuracy because absent labels are common. The label prevalences are 0.422 for people, 0.364 for time, and 0.159 for work. Its recall is 0 for every label, so it finds none of the 219 work, 501 time, or 581 people dictionary labels. Exact empty-set accuracy is 0.3261, the share of paragraphs with no dictionary theme at all.
What to remember
Multi-class means one label from more than two choices.
Multi-label means zero, one, or several labels can apply at once.
Multi-class accuracy can hide weak classes.
Multi-label accuracy can be high when absent labels dominate.
Per-class or per-label precision and recall tell the reader where the errors are.