CountVectorizer and the Bag-of-Words Representation
A pre-defined stopwords list, such as scikit-learn's ENGLISH_STOP_WORDS with 318 entries, is a library-supplied collection of common words that text processing usually ignores.
Try it: Text Vectorization: Tokens to Vectors
The text-to-tensor pipeline: standardize, split into tokens, build a frequency-ranked vocabulary with padding and [UNK], map tokens to integer ids, pad or truncate, then one-hot or multi-hot encode and look the ids up in an embedding table.
How it works
- Standardize: lowercase and delete punctuation.
- Split on whitespace into tokens.
- Build the vocabulary: 0 = padding, 1 = [UNK], then words by frequency (ties: first appearance), capped at max tokens.
- Map each token to its id (1 if it did not make the vocabulary), then pad with 0 or truncate to the sequence length.
- Encode: one-hot rows per position or one multi-hot row per text; embed: id k selects row k of the embedding table.
Default run (18 steps): Raw text (59 characters): "The movie was great. The plot was great, the acting wasn't!". A model cannot read strings, so it is turned into numbers step by step. … Embedding lookup: id k selects row k of a fixed 8 x 3 table, giving a (8, 3) dense matrix instead of (8, 8) sparse one-hots. Row 0 (padding) is looked up too; a trained Embedding layer would learn these rows.
Simplified: Bounded ASCII text (up to 200 characters, 40 tokens), whitespace splitting only, and a small FIXED embedding table (a real Embedding layer learns its rows). The multi-hot vector keeps the padding slot (always 0) so its positions line up with the ids.
Loading the simulation…
Ordinary Words That Crowd the Feature Matrix
Read any English paragraph and count the words that show up everywhere: 'the', 'and', 'is', 'of'. These words appear in almost every English document, so they tell a model very little about what any single document is about. Yet when a computer turns a document into numbers, every distinct word it sees can become a feature, and each feature takes up a column. Common words therefore keep a seat in the representation even though they contribute almost no information.
This article looks at one practical response: a pre-defined stopwords list. You will see what such a list contains, how it is handed to CountVectorizer, and what changes in the resulting features. Before reading each explanation, try to trace the code in your head and decide what you expect each stage to produce. Then compare your expectation with what the code actually does.
What a Stopwords List Contains
A pre-defined stopwords list, such as scikit-learn's ENGLISH_STOP_WORDS with 318 entries, is a library-supplied collection of common words that text processing usually ignores.
The scikit-learn library provides this list under the name ENGLISH_STOP_WORDS in its feature extraction text module. You can import it directly and ask how many entries it holds. The source reports that the list contains 318 stopwords. The list is a set-like collection rather than an ordered sequence, so the source converts it to a list before slicing it. The slice in the source takes every tenth entry, which is a quick way to sample the contents without printing all 318 words.
- The import brings in the built-in list of English stopwords.
len()reports how many entries the list holds; the source reports 318.- Converting to a list lets us slice it, and [::10] keeps every tenth entry as a sample.
The sampled words look ordinary. The source's sample includes pronouns such as 'he' and 'me', the determiner 'the', and connecting words such as 'although' and 'into'. Notice that the sample contains no subject-specific vocabulary. The list is built around words that carry grammatical function rather than meaning about a particular topic, which is why it is a generic starting point for English text. A movie review, a news article, and a recipe all tend to contain these same function words.
Bag of Words: Where Each Word Gets a Column
CountVectorizer transforms text into a matrix of token counts. Think of the result as a grid. Each row is one document, and each column is one vocabulary word. The vocabulary is the set of distinct words the vectorizer has decided to keep, and every word in it owns exactly one column. The number stored where a row and a column meet is how often that word appears in that document. Because word order is not recorded in these counts, the representation is often called a bag of words.
Trace one row through this map. The document in this illustration contains 'movie' twice, 'fun' once, and 'long' once. Its row therefore holds 2 in the column for 'movie', 1 in the column for 'fun', and 1 in the column for 'long'. Change the vocabulary and the column for each word changes with it, but the rule stays the same: a word's column is fixed by its place in the vocabulary, and its cell records its count in that document.
Passing stop_words to CountVectorizer
CountVectorizer accepts a stop_words parameter. When you set that parameter to the string 'english', the vectorizer uses the built-in ENGLISH_STOP_WORDS list. The setting is chosen when the object is created, and the vocabulary is learned later, when fit is called on the training text. The source also notes that you can augment the built-in list and pass your own, but it mentions that option without a worked example, so treat it as a direction for further study rather than a tested procedure.
- The
stop_wordsargument is supplied in the constructor, so the choice is fixed before any text is seen. fit()reads the documents, applies the stopword filter, and learns the vocabulary.get_feature_names_out()lists the words that survived as features.
Where the Stopword Step Sits in the Workflow
It helps to see the stopword step as one stage in a sequence rather than as a standalone operation. Text is first split into tokens. The stopword filter then removes the tokens that appear in the list. The remaining tokens form the vocabulary, and the count matrix records how often each vocabulary item appears in each document. This is a simplified conceptual model. It shows where the stopword decision sits, not every internal detail of the library.
Predicting the Effect on the Feature Count
What do you think happens?
Applying ENGLISH_STOP_WORDS to a text can make the number of features do which of these?
Reveal answer
Only decrease, or stay the same
Removing stopwords is a filter applied to candidate words, so the feature count can only shrink or stay the same. The list is not added to the features; it only removes words from consideration. The size of the reduction depends on which of the list's words actually appear in your text, and it can never exceed the length of the list.
The reasoning behind the answer is what matters. Each stopword that appears in the text is one candidate word that no longer becomes a feature. Words not on the list are untouched. Because the filter only removes candidates, the vocabulary after filtering is never larger than the vocabulary before. The source adds a more hopeful claim: although the count can only fall, the performance of a downstream model might improve. Whether it does is an empirical question, and the source frames it as something to test by trying the change and measuring the result.
Removing stopwords from one small document
A document contains the words 'the', 'movie', 'was', and 'fun'. Suppose the stopwords list contains 'the' and 'was'. How many features does this document contribute before and after filtering?
- 1Count candidates before filtering
The document offers four distinct candidate words: 'the', 'movie', 'was', and 'fun'. Before any filtering, that is four potential features.
- 2Check each candidate against the list
'the' appears in the list, so it is removed. 'movie' does not appear in the list, so it stays. 'was' appears in the list, so it is removed. 'fun' does not appear in the list, so it stays.
- 3Count what remains
Two words survive, 'movie' and 'fun'. The document is now represented only by the words that remain, and the removal was applied to the words of the text, not to the document itself.
- 4Compare the two counts
The count fell from four to two. This matches the rule that filtering can only decrease the number of features.
The document contributes two features, 'movie' and 'fun', down from four.
Mistakes That Produce Unexpected Counts
When a stopwords experiment gives a surprising feature count, the cause is usually at one of a few specific points. Because the stopword setting is supplied at construction and used during fitting, the most informative first question is which stage produced the result you are looking at. The points below are the ones to check first.
Common mistake Expecting stopword removal to increase the number of features
What it looks likeApplying the list and seeing fewer columns, then assuming the filter is broken.
Why it failsThe filter only removes candidate words, so the count can only shrink or stay the same.
Do this insteadExpect a count that is equal to or lower than the unfiltered count, then check how many listed words actually occur in the text.
Common mistake Passing the setting at the wrong stage
What it looks likeExpecting an already fitted vectorizer to change behavior after its stop_words value is altered.
Why it failsThe setting is chosen when the vectorizer is constructed and applied during fitting, so the earlier result still reflects the old setting.
Do this insteadConstruct a new vectorizer with the desired stop_words value and call fit again.
Common mistake Assuming a smaller feature count means a better model
What it looks likeDropping stopwords and concluding the model must now perform better.
Why it failsThe source states that any gain in model performance must be measured rather than assumed.
Do this insteadTrain the model with and without the change and compare the results on held-out data.
Common mistake Looking only at the final matrix and not at the vocabulary that produced its columns
Practice: Tracing a Stopwords Experiment
A colleague fits CountVectorizer(stop_words='english') on a set of documents and reports a vocabulary size that is larger than the one they got from the same documents last week. Before any code is changed, which stage of the workflow would you check first, and what would you compare?
Hints
- Think about the order of the workflow: tokenize, filter stopwords, build vocabulary, count.
- Ask whether the two runs used the same
stop_wordssetting and the same documents. - Remember that filtering can only remove candidates, so a larger vocabulary points to a difference in input or setting.
Key Takeaways
- A pre-defined stopwords list, such as ENGLISH_STOP_WORDS with 318 entries, is a library-supplied set of common words that text processing usually ignores because they carry little information about a document's topic.
- CountVectorizer builds a bag-of-words matrix in which each vocabulary word owns one column and each cell holds that word's count in one document.
- Passing
stop_words='english' at construction makes the vectorizer filter the built-in list during fitting, and this filter can only decrease or leave unchanged the number of features. - The stopword decision sits between tokenization and vocabulary building, so unexpected counts are usually traced to that stage or to the
stop_wordssetting used when the vectorizer was constructed. - Whether removing stopwords improves a downstream model is an empirical question that must be answered by measuring results, not assumed.