Table of Contents#
- Setting Up Your Environment
- Fundamental Text Preprocessing
- Text Representation Techniques
- Basic Text Analysis Techniques
- Advanced Text Analysis
- Best Practices and Common Pitfalls
- Real-World Example: News Article Analysis
- Conclusion
- References
Setting Up Your Environment#
Before diving into text analysis, let's set up our Python environment with the essential libraries:
pip install nltk spacy pandas numpy scikit-learn matplotlib seaborn textblob wordcloudFor spaCy, you'll also need to download a language model:
python -m spacy download en_core_web_sm# Essential imports
import nltk
import spacy
import pandas as pd
import numpy as np
from sklearn.feature_extraction.text import CountVectorizer, TfidfVectorizer
import matplotlib.pyplot as plt
import seaborn as sns
# Download NLTK resources
nltk.download('punkt')
nltk.download('stopwords')
nltk.download('wordnet')
nltk.download('averaged_perceptron_tagger')
# Load spaCy model
nlp = spacy.load('en_core_web_sm')Fundamental Text Preprocessing#
Text preprocessing is the most critical step in text analysis. Raw text data is often messy and needs to be cleaned and standardized before analysis.
1. Text Cleaning#
import re
import string
def clean_text(text):
"""
Comprehensive text cleaning function
"""
# Convert to lowercase
text = text.lower()
# Remove URLs
text = re.sub(r'http\S+', '', text)
# Remove HTML tags
text = re.sub(r'<.*?>', '', text)
# Remove punctuation
text = text.translate(str.maketrans('', '', string.punctuation))
# Remove numbers
text = re.sub(r'\d+', '', text)
# Remove extra whitespace
text = ' '.join(text.split())
return text
# Example usage
sample_text = "Check out this amazing website: https://example.com! It's the best site in 2024."
cleaned_text = clean_text(sample_text)
print(cleaned_text)
# Output: "check out this amazing website its the best site in"2. Tokenization#
from nltk.tokenize import word_tokenize, sent_tokenize
# Sentence tokenization
text = "This is the first sentence. This is the second sentence!"
sentences = sent_tokenize(text)
print(sentences)
# Output: ['This is the first sentence.', 'This is the second sentence!']
# Word tokenization
words = word_tokenize("Hello world! This is NLP.")
print(words)
# Output: ['Hello', 'world', '!', 'This', 'is', 'NLP', '.']
# Using spaCy for more advanced tokenization
doc = nlp("Apple is looking at buying U.K. startup for $1 billion")
tokens = [token.text for token in doc]
print(tokens)
# Output: ['Apple', 'is', 'looking', 'at', 'buying', 'U.K.', 'startup', 'for', '$', '1', 'billion']3. Stopword Removal#
from nltk.corpus import stopwords
stop_words = set(stopwords.words('english'))
def remove_stopwords(text):
words = word_tokenize(text)
filtered_words = [word for word in words if word.lower() not in stop_words]
return ' '.join(filtered_words)
text = "This is a sample sentence demonstrating stop words removal."
filtered_text = remove_stopwords(text)
print(filtered_text)
# Output: "sample sentence demonstrating stop words removal ."4. Stemming and Lemmatization#
from nltk.stem import PorterStemmer, WordNetLemmatizer
# Stemming
stemmer = PorterStemmer()
words = ["running", "runner", "ran", "easily", "fairly"]
stemmed_words = [stemmer.stem(word) for word in words]
print(stemmed_words)
# Output: ['run', 'runner', 'ran', 'easili', 'fairli']
# Lemmatization (more accurate than stemming)
lemmatizer = WordNetLemmatizer()
lemmatized_words = [lemmatizer.lemmatize(word, pos='v') for word in words] # 'v' for verb
print(lemmatized_words)
# Output: ['run', 'run', 'run', 'easily', 'fairly']
# spaCy lemmatization
doc = nlp("The striped bats are hanging on their feet for best")
lemmas = [token.lemma_ for token in doc]
print(lemmas)
# Output: ['the', 'striped', 'bat', 'be', 'hang', 'on', 'their', 'foot', 'for', 'good']5. Part-of-Speech Tagging#
# Using NLTK
text = "I am learning text analysis in Python"
tokens = word_tokenize(text)
pos_tags = nltk.pos_tag(tokens)
print(pos_tags)
# Output: [('I', 'PRP'), ('am', 'VBP'), ('learning', 'VBG'), ('text', 'NN'), ('analysis', 'NN'), ('in', 'IN'), ('Python', 'NNP')]
# Using spaCy
doc = nlp("Apple is looking at buying U.K. startup for $1 billion")
for token in doc:
print(token.text, token.lemma_, token.pos_, token.tag_)Text Representation Techniques#
To analyze text computationally, we need to convert it into numerical representations.
1. Bag of Words (BoW)#
from sklearn.feature_extraction.text import CountVectorizer
# Sample documents
documents = [
"I love machine learning",
"Machine learning is amazing",
"I love coding in Python"
]
# Create CountVectorizer
vectorizer = CountVectorizer()
bow_matrix = vectorizer.fit_transform(documents)
# Convert to DataFrame for better visualization
bow_df = pd.DataFrame(bow_matrix.toarray(), columns=vectorizer.get_feature_names_out())
print(bow_df)2. TF-IDF (Term Frequency-Inverse Document Frequency)#
from sklearn.feature_extraction.text import TfidfVectorizer
# Create TF-IDF Vectorizer
tfidf_vectorizer = TfidfVectorizer()
tfidf_matrix = tfidf_vectorizer.fit_transform(documents)
# Convert to DataFrame
tfidf_df = pd.DataFrame(tfidf_matrix.toarray(), columns=tfidf_vectorizer.get_feature_names_out())
print(tfidf_df)3. Word Embeddings (Word2Vec, GloVe)#
# Using Gensim for Word2Vec
from gensim.models import Word2Vec
# Sample sentences
sentences = [
["I", "love", "machine", "learning"],
["Machine", "learning", "is", "amazing"],
["I", "love", "coding", "in", "Python"]
]
# Train Word2Vec model
model = Word2Vec(sentences, vector_size=100, window=5, min_count=1, workers=4)
# Get word vector
vector = model.wv['machine']
print(f"Vector for 'machine': {vector}")
# Find similar words
similar_words = model.wv.most_similar('machine', topn=3)
print(f"Words similar to 'machine': {similar_words}")Basic Text Analysis Techniques#
1. Word Frequency Analysis#
from collections import Counter
import matplotlib.pyplot as plt
def plot_word_frequency(text, top_n=20):
# Tokenize and clean
words = word_tokenize(text.lower())
words = [word for word in words if word.isalpha() and word not in stop_words]
# Count frequencies
word_freq = Counter(words)
# Plot
plt.figure(figsize=(10, 6))
most_common = word_freq.most_common(top_n)
words, counts = zip(*most_common)
plt.bar(words, counts)
plt.xticks(rotation=45)
plt.title(f'Top {top_n} Most Frequent Words')
plt.tight_layout()
plt.show()
# Example usage
sample_text = "Python is great for text analysis. Python has many libraries for NLP. Text analysis with Python is fun."
plot_word_frequency(sample_text)2. N-gram Analysis#
from nltk.util import ngrams
from collections import Counter
def get_ngrams(text, n=2):
tokens = word_tokenize(text.lower())
tokens = [token for token in tokens if token.isalpha() and token not in stop_words]
n_grams = ngrams(tokens, n)
return Counter(n_grams)
# Example
text = "Python text analysis is very powerful for extracting insights from data."
bigrams = get_ngrams(text, 2)
print("Top 5 bigrams:", bigrams.most_common(5))3. Text Visualization with Word Clouds#
from wordcloud import WordCloud
def generate_wordcloud(text):
wordcloud = WordCloud(width=800, height=400, background_color='white').generate(text)
plt.figure(figsize=(10, 5))
plt.imshow(wordcloud, interpolation='bilinear')
plt.axis('off')
plt.show()
# Example
text = "Python is amazing for data science and machine learning. Data science with Python is popular."
generate_wordcloud(text)Advanced Text Analysis#
1. Sentiment Analysis#
from textblob import TextBlob
from vaderSentiment.vaderSentiment import SentimentIntensityAnalyzer
# Using TextBlob
def analyze_sentiment_textblob(text):
blob = TextBlob(text)
return blob.sentiment
# Using VADER (better for social media/text)
def analyze_sentiment_vader(text):
analyzer = SentimentIntensityAnalyzer()
return analyzer.polarity_scores(text)
# Examples
text1 = "I love Python programming! It's amazing."
text2 = "I hate errors and bugs in my code."
print("TextBlob Results:")
print(f"Text 1: {analyze_sentiment_textblob(text1)}")
print(f"Text 2: {analyze_sentiment_textblob(text2)}")
print("\nVADER Results:")
print(f"Text 1: {analyze_sentiment_vader(text1)}")
print(f"Text 2: {analyze_sentiment_vader(text2)}")2. Named Entity Recognition (NER)#
def extract_entities(text):
doc = nlp(text)
entities = []
for ent in doc.ents:
entities.append((ent.text, ent.label_))
return entities
# Example
text = "Apple was founded by Steve Jobs in Cupertino, California in 1976."
entities = extract_entities(text)
print("Named Entities:", entities)3. Topic Modeling with LDA#
from sklearn.decomposition import LatentDirichletAllocation
from sklearn.feature_extraction.text import CountVectorizer
# Sample documents
documents = [
"Machine learning is a subset of artificial intelligence",
"Python is popular for data science and machine learning",
"Deep learning uses neural networks with multiple layers",
"Natural language processing helps computers understand human language",
"Data science involves statistics, programming, and domain knowledge"
]
# Create document-term matrix
vectorizer = CountVectorizer(max_df=0.95, min_df=2, stop_words='english')
dtm = vectorizer.fit_transform(documents)
# Apply LDA
lda = LatentDirichletAllocation(n_components=2, random_state=42)
lda.fit(dtm)
# Display topics
def display_topics(model, feature_names, no_top_words):
for topic_idx, topic in enumerate(model.components_):
print(f"Topic {topic_idx}:")
print(" ".join([feature_names[i] for i in topic.argsort()[:-no_top_words - 1:-1]]))
display_topics(lda, vectorizer.get_feature_names_out(), 5)Best Practices and Common Pitfalls#
Best Practices:#
-
Always start with exploratory data analysis - understand your text data before applying complex algorithms.
-
Choose appropriate preprocessing steps - not all text requires the same level of cleaning.
-
Use lemmatization instead of stemming for better accuracy in most cases.
-
Experiment with different vectorization techniques - TF-IDF often works better than simple BoW.
-
Validate your results with multiple metrics and human evaluation when possible.
Common Pitfalls to Avoid:#
-
Over-cleaning text - removing too much information can reduce model performance.
-
Ignoring domain-specific stopwords - create custom stopword lists for specialized domains.
-
Not handling imbalanced datasets - common in sentiment analysis and classification tasks.
-
Using inappropriate evaluation metrics - accuracy isn't always the best metric for text classification.
-
Neglecting computational efficiency - text processing can be resource-intensive with large datasets.
Real-World Example: News Article Analysis#
Let's implement a complete text analysis pipeline for news articles:
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.naive_bayes import MultinomialNB
from sklearn.metrics import classification_report, accuracy_score
# Sample news dataset (in practice, you'd load from a file)
data = {
'text': [
"Stock markets reached record highs today as investors cheered positive economic data",
"The football team won the championship after a thrilling final match",
"New technology breakthrough promises to revolutionize renewable energy sector",
"Political leaders gathered for summit to discuss climate change policies",
"Company earnings exceeded expectations leading to surge in share prices"
],
'category': ['finance', 'sports', 'technology', 'politics', 'finance']
}
df = pd.DataFrame(data)
# Preprocessing pipeline
def preprocess_text(text):
text = text.lower()
text = re.sub(r'[^\w\s]', '', text)
return text
df['cleaned_text'] = df['text'].apply(preprocess_text)
# Feature extraction
vectorizer = TfidfVectorizer(max_features=1000, stop_words='english')
X = vectorizer.fit_transform(df['cleaned_text'])
y = df['category']
# Train-test split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
# Model training
model = MultinomialNB()
model.fit(X_train, y_train)
# Prediction and evaluation
y_pred = model.predict(X_test)
print("Accuracy:", accuracy_score(y_test, y_pred))
print("\nClassification Report:")
print(classification_report(y_test, y_pred))
# Analyze new article
new_article = "The basketball team secured victory in the national tournament"
new_article_cleaned = preprocess_text(new_article)
new_article_vectorized = vectorizer.transform([new_article_cleaned])
prediction = model.predict(new_article_vectorized)
print(f"\nPredicted category for new article: {prediction[0]}")Conclusion#
Text analysis in Python 3 offers powerful capabilities for extracting insights from unstructured text data. This guide has covered the essential techniques from basic preprocessing to advanced analysis methods. Remember that successful text analysis projects require:
- Thorough understanding of your data and domain
- Appropriate preprocessing tailored to your specific use case
- Iterative experimentation with different techniques
- Careful evaluation of results
The field of NLP is rapidly evolving, with new techniques like transformer models (BERT, GPT) pushing the boundaries of what's possible. However, the fundamental concepts covered in this guide provide a solid foundation for any text analysis project.
References#
- Bird, S., Klein, E., & Loper, E. (2009). Natural Language Processing with Python. O'Reilly Media.
- Jurafsky, D., & Martin, J. H. (2019). Speech and Language Processing. Pearson.
- McKinney, W. (2017). Python for Data Analysis. O'Reilly Media.
- Pedregosa, F., et al. (2011). Scikit-learn: Machine Learning in Python. JMLR.
- Honnibal, M., & Montani, I. (2017). spaCy: Industrial-strength Natural Language Processing in Python.
Useful Libraries Documentation:#
Further Learning:#
- Coursera: Natural Language Processing Specialization
- Hugging Face Transformers Course
- Kaggle NLP competitions and tutorials