AI Hints
Home›NLP Tutorial›Cleaning and Splitting Text
NLP · Lesson 6 of 106

Normalising Text

Treating the same thing as the same.

⏱ 2 min read▶ Video at 10:46🎓 Free
Watch this lesson in the NLP courseWatch on YouTube ↗Full NLP course

A customer writes, I LOVE this book. Another writes, i love this book!! A third writes, loved it. To you, these are close to the same message. To a simple program, they don't match at all. Normalisation brings different spellings of the same thing together.

Normalising Text
From the video: Normalising Text
  • I LOVE this book
  • i love this book!!
  • loved it

A cleaning function

Here's a reusable cleaning function. Unicode normalise fixes strange characters, like the wide letters at the end of our test sentence. Lower makes everything lower case. We swap web links for a marker, since each link is unique, but the fact that there is a link might matter. And we collapse spaces. Run it. Messy input, and neat output. A warning, though. Modern transformer models are trained on natural text, so you should do much less cleaning for those.

normalise.pypython
import re
import unicodedata

def clean(text):
    text = unicodedata.normalize("NFKC", text)
    text = text.lower()
    text = re.sub(r"https?://\S+", " [URL] ", text)
    text = re.sub(r"\s+", " ", text).strip()
    return text

print(clean("  CHECK   this: https://bit.ly/x   FULL width!  "))
Output
check this: [URL] full width!

Stemming and lemmas

Stemming chops off word endings, with crude rules. Lemmatising uses a dictionary, to find the true base form. Here we compare the two. Run it. The stemmer turns studies into studi, which isn't a word. The lemmatiser gives study, and it knows that mice is the plural of mouse, and that were goes to be. Stemming is fast and rough. Lemmatising is slower, but much more accurate.

lemmas.pypython
import spacy
from nltk.stem import PorterStemmer

nlp = spacy.load("en_core_web_sm")
stem = PorterStemmer()

words = "the mice were running and studies better than leaves"
for t in nlp(words):
    if not t.is_stop:
        print(f"{t.text:<9} stem: {stem.stem(t.text):<8} lemma: {t.lemma_}")
Output
mice      stem: mice     lemma: mouse
running   stem: run      lemma: run
studies   stem: studi    lemma: study
better    stem: better   lemma: well
leaves    stem: leav     lemma: leaf

Stop words, and a trap

Stop words are very common words, such as the, and, and is. Old systems removed them to save space, and to focus on useful words. Run it. But look at what's left of our sentences. The book was not good becomes, book good. We've just reversed the meaning! Not and never are stop words. So never remove stop words without thinking, especially for sentiment.

stopwords.pypython
import spacy

nlp = spacy.load("en_core_web_sm")
print("Stop words known:", len(nlp.Defaults.stop_words))

for text in ["The book was not good", "I would never buy this"]:
    kept = [t.text for t in nlp(text) if not t.is_stop]
    print(f"{text:<26} -> {kept}")
Output
Stop words known: 326
The book was not good      -> ['book', 'good']
I would never buy this     -> ['buy']

Summary

Normalise as much as your task needs, and no more. And beware of stop word lists. Our text is now clean and split. But it's still words, and models need numbers. Next, the simplest way to turn a document into numbers.

Key takeaways
  • Normalise consistently
  • Lemmas beat stems
  • Stop word removal can flip meaning
Next up: Bag of Words — turning documents into counts