📝 پردازش زبان طبیعی (NLP) با NLTK
پردازش زبان طبیعی (NLP) یکی از زیرشاخههای هوش مصنوعی است که به رایانهها امکان درک، تفسیر و تولید زبان انسانی را میدهد. کتابخانه NLTK (Natural Language Toolkit) یکی از قدیمیترین و محبوبترین کتابخانههای پایتون برای پردازش متن است که ابزارهای قدرتمندی برای توکنسازی، برچسبزنی، تحلیل احساسات و پردازش متون فراهم میکند .
پیشنیاز: آشنایی با Python و مفاهیم پایه متنکاوی.
🔹 نصب و import
# نصب (در محیط واقعی)
# pip install nltk
import nltk
import re
from nltk.tokenize import word_tokenize, sent_tokenize
from nltk.corpus import stopwords
from nltk.stem import PorterStemmer, WordNetLemmatizer
from nltk.probability import FreqDist
from nltk.sentiment import SentimentIntensityAnalyzer
import string
# دانلود منابع مورد نیاز (فقط یک بار)
nltk.download('punkt')
nltk.download('stopwords')
nltk.download('wordnet')
nltk.download('vader_lexicon')
print(f"NLTK version: {nltk.__version__}")
print("NLTK resources downloaded successfully!")
🔹 توکنسازی (Tokenization)
توکنسازی فرایند تقسیم متن به واحدهای کوچکتر (کلمات یا جملات) است .
import nltk
from nltk.tokenize import sent_tokenize, word_tokenize
text = """Natural Language Processing (NLP) is a field of artificial intelligence.
It helps computers understand human language.
NLTK is a powerful library for NLP in Python."""
# ===== توکنسازی به جملات =====
sentences = sent_tokenize(text)
print("Sentences:")
for i, sent in enumerate(sentences, 1):
print(f"{i}. {sent}")
# ===== توکنسازی به کلمات =====
words = word_tokenize(text)
print(f"\nNumber of words: {len(words)}")
print("First 10 words:", words[:10])
# ===== توکنسازی روی یک جمله =====
sample = "Hello, how are you? I'm fine, thanks!"
tokens = word_tokenize(sample)
print(f"\nTokens: {tokens}")
🔹 حذف کلمات توقف (Stopwords)
کلمات توقف کلماتی مانند "the"، "is"، "and" هستند که معمولاً اطلاعات مهمی ندارند و در تحلیل متن حذف میشوند .
import nltk
from nltk.corpus import stopwords
from nltk.tokenize import word_tokenize
import string
# دریافت کلمات توقف انگلیسی
stop_words = set(stopwords.words('english'))
print(f"Number of stopwords: {len(stop_words)}")
print("Sample stopwords:", list(stop_words)[:20])
# ===== حذف کلمات توقف =====
text = "NLTK is a powerful library for Natural Language Processing in Python."
tokens = word_tokenize(text.lower()) # تبدیل به حروف کوچک
# حذف کلمات توقف و نشانههای نگارشی
filtered_tokens = [
word for word in tokens
if word not in stop_words and word not in string.punctuation
]
print(f"\nOriginal tokens: {tokens}")
print(f"Filtered tokens: {filtered_tokens}")
🔹 Stemming و Lemmatization
Stemming و Lemmatization دو روش برای کاهش کلمات به ریشه (ریشهیابی) هستند. Stemming سریعتر اما کمتر دقیق است، در حالی که Lemmatization با در نظر گرفتن معنا، کلمات را به شکل پایه برمیگرداند .
import nltk
from nltk.stem import PorterStemmer, WordNetLemmatizer
# ===== Stemming =====
stemmer = PorterStemmer()
words = ['running', 'ran', 'runs', 'easily', 'fairly', 'flies']
stemmed_words = [stemmer.stem(word) for word in words]
print("Stemming:")
for original, stemmed in zip(words, stemmed_words):
print(f" {original} -> {stemmed}")
# ===== Lemmatization =====
lemmatizer = WordNetLemmatizer()
lemmatized_words = [lemmatizer.lemmatize(word, pos='v') for word in words]
print("\nLemmatization (as verbs):")
for original, lemmatized in zip(words, lemmatized_words):
print(f" {original} -> {lemmatized}")
# ===== مقایسه =====
print("\nComparison on sample words:")
sample_words = ['studies', 'studying', 'studied']
print("Original:", sample_words)
print("Stemmed:", [stemmer.stem(w) for w in sample_words])
print("Lemmatized:", [lemmatizer.lemmatize(w, pos='v') for w in sample_words])
🔹 توزیع فرکانس کلمات (FreqDist)
import nltk
from nltk.tokenize import word_tokenize
from nltk.probability import FreqDist
import string
text = """Natural Language Processing is fascinating.
NLP helps computers understand text.
Python is a great language for NLP.
NLTK is a library for NLP in Python."""
# توکنسازی و پاکسازی
tokens = word_tokenize(text.lower())
tokens = [word for word in tokens if word not in string.punctuation]
# محاسبه فرکانس
freq_dist = FreqDist(tokens)
# نمایش ۱۰ کلمه پرتکرار
print("Top 10 most frequent words:")
for word, freq in freq_dist.most_common(10):
print(f" {word}: {freq}")
# نمایش تعداد کل کلمات
print(f"\nTotal words: {freq_dist.N()}")
# نمایش تعداد کلمات منحصر به فرد
print(f"Unique words: {len(freq_dist)}")
# نمایش فرکانس یک کلمه خاص
print(f"Frequency of 'nlp': {freq_dist['nlp']}")
🔹 تحلیل احساسات (Sentiment Analysis) با VADER
VADER (Valence Aware Dictionary and sEntiment Reasoner) یک مدل مبتنی بر فرهنگ لغت برای تحلیل احساسات در متون کوتاه است که به طور خاص برای شبکههای اجتماعی طراحی شده است .
import nltk
from nltk.sentiment import SentimentIntensityAnalyzer
# دانلود VADER
nltk.download('vader_lexicon')
sia = SentimentIntensityAnalyzer()
# ===== تحلیل جملات نمونه =====
sentences = [
"I love this movie! It's absolutely amazing.",
"This product is terrible. I hate it.",
"The weather today is okay, nothing special.",
"I'm feeling great about this project!",
"This is the worst experience ever."
]
print("Sentiment Analysis Results:")
print("-" * 50)
for sentence in sentences:
scores = sia.polarity_scores(sentence)
sentiment = "Positive" if scores['compound'] > 0.05 else "Negative" if scores['compound'] < -0.05 else "Neutral"
print(f"Text: {sentence}")
print(f" Scores: {scores}")
print(f" Sentiment: {sentiment}\n")
# ===== تحلیل یک متن طولانیتر =====
long_text = """
The movie was really great! The acting was superb and the story was captivating.
However, the ending was a bit disappointing. Overall, I enjoyed it.
"""
scores = sia.polarity_scores(long_text)
print(f"Long text analysis: {scores}")
🔹 پیشپردازش پیشرفته متن
import nltk
import re
import string
from nltk.tokenize import word_tokenize
from nltk.corpus import stopwords
from nltk.stem import WordNetLemmatizer
def preprocess_text(text):
"""
یک تابع کامل برای پیشپردازش متن:
1. حذف لینکها و ایمیلها
2. حذف کاراکترهای غیرضروری
3. حذف کلمات توقف
4. Lemmatization
"""
# ۱. حذف لینکها و ایمیلها
text = re.sub(r'http\S+|www\S+|https\S+', '', text, flags=re.MULTILINE)
text = re.sub(r'\S+@\S+', '', text)
# ۲. تبدیل به حروف کوچک
text = text.lower()
# ۳. حذف کاراکترهای غیر کلمه (به جز فاصله)
text = re.sub(r'[^a-zA-Z\s]', '', text)
# ۴. توکنسازی
tokens = word_tokenize(text)
# ۵. حذف کلمات توقف
stop_words = set(stopwords.words('english'))
tokens = [word for word in tokens if word not in stop_words]
# ۶. Lemmatization
lemmatizer = WordNetLemmatizer()
tokens = [lemmatizer.lemmatize(word, pos='v') for word in tokens]
return tokens
# ===== نمونه =====
raw_text = """
Check out this amazing NLP tutorial: https://example.com/nlp
Contact me at [email protected] for more info.
The tutorial covers Natural Language Processing, Machine Learning, and Python programming.
It's really helpful for beginners and experts alike!
"""
processed = preprocess_text(raw_text)
print("Original text:")
print(raw_text)
print("\nProcessed tokens:")
print(processed)
print(f"Number of tokens: {len(processed)}")
🔹 مدل n-gram
n-gram دنبالهای از n کلمه متوالی در یک متن است که برای تحلیل آماری و مدلسازی زبان استفاده میشود .
import nltk
from nltk.tokenize import word_tokenize
from nltk.util import ngrams
from collections import Counter
def generate_ngrams(tokens, n):
"""تولید n-gram از توکنها"""
return list(ngrams(tokens, n))
text = "Natural Language Processing is fascinating. NLTK is a powerful library for NLP."
tokens = word_tokenize(text.lower())
# ===== تولید bigram و trigram =====
bigrams = generate_ngrams(tokens, 2)
trigrams = generate_ngrams(tokens, 3)
print("Sample tokens:", tokens[:15])
print("\nSample bigrams:", bigrams[:10])
print("\nSample trigrams:", trigrams[:10])
# ===== یافتن پرتکرارترین bigramها =====
bigram_freq = Counter(bigrams)
print("\nMost common bigrams:")
for bigram, freq in bigram_freq.most_common(5):
print(f" {bigram}: {freq}")
# ===== یافتن پرتکرارترین trigramها =====
trigram_freq = Counter(trigrams)
print("\nMost common trigrams:")
for trigram, freq in trigram_freq.most_common(5):
print(f" {trigram}: {freq}")
🔹 مثال جامع: تحلیل نظرات محصولات
import nltk
from nltk.tokenize import word_tokenize
from nltk.corpus import stopwords
from nltk.probability import FreqDist
from nltk.sentiment import SentimentIntensityAnalyzer
import re
from collections import Counter
class TextAnalyzer:
"""کلاس تحلیل متن برای بررسی نظرات"""
def __init__(self):
self.sia = SentimentIntensityAnalyzer()
self.stop_words = set(stopwords.words('english'))
def preprocess(self, text):
"""پیشپردازش متن"""
# تبدیل به حروف کوچک و حذف علائم
text = text.lower()
text = re.sub(r'[^a-zA-Z\s]', '', text)
tokens = word_tokenize(text)
# حذف کلمات توقف
tokens = [word for word in tokens if word not in self.stop_words]
return tokens
def analyze_sentiment(self, text):
"""تحلیل احساسات"""
scores = self.sia.polarity_scores(text)
if scores['compound'] > 0.05:
sentiment = 'Positive'
elif scores['compound'] < -0.05:
sentiment = 'Negative'
else:
sentiment = 'Neutral'
return sentiment, scores
def extract_keywords(self, text, top_n=5):
"""استخراج کلمات کلیدی"""
tokens = self.preprocess(text)
freq_dist = FreqDist(tokens)
return freq_dist.most_common(top_n)
def analyze_reviews(self, reviews):
"""تحلیل مجموعهای از نظرات"""
results = {
'total': len(reviews),
'sentiment_counts': {'Positive': 0, 'Negative': 0, 'Neutral': 0},
'all_keywords': Counter(),
'reviews': []
}
for review in reviews:
# تحلیل احساسات
sentiment, scores = self.analyze_sentiment(review)
results['sentiment_counts'][sentiment] += 1
# استخراج کلمات کلیدی
keywords = self.extract_keywords(review, top_n=3)
results['all_keywords'].update([word for word, _ in keywords])
results['reviews'].append({
'text': review[:100] + '...' if len(review) > 100 else review,
'sentiment': sentiment,
'score': scores['compound'],
'keywords': keywords
})
return results
# ===== داده نمونه =====
reviews = [
"I absolutely love this product! It's amazing and works perfectly.",
"Terrible experience. The product broke after 2 days.",
"This is okay, nothing special but gets the job done.",
"Best purchase ever! Highly recommend to everyone.",
"Waste of money. Very disappointing quality.",
"Good product for the price. It works well.",
"I'm so happy with this purchase. Excellent quality!",
"Not what I expected. It's decent but overpriced."
]
# ===== تحلیل =====
analyzer = TextAnalyzer()
results = analyzer.analyze_reviews(reviews)
# ===== نمایش نتایج =====
print("=" * 50)
print("REVIEW ANALYSIS REPORT")
print("=" * 50)
print(f"\nTotal Reviews: {results['total']}")
print("\nSentiment Distribution:")
for sentiment, count in results['sentiment_counts'].items():
percentage = (count / results['total']) * 100
print(f" {sentiment}: {count} ({percentage:.1f}%)")
print("\nTop Keywords:")
for word, freq in results['all_keywords'].most_common(10):
print(f" {word}: {freq}")
print("\nSample Reviews:")
for i, review in enumerate(results['reviews'][:5], 1):
print(f"\n{i}. Text: {review['text']}")
print(f" Sentiment: {review['sentiment']} (score: {review['score']:.2f})")
print(f" Keywords: {review['keywords']}")
📌 نکات کلیدی
- ✅ توکنسازی (Tokenization) اولین قدم در پردازش متن است که متن را به کلمات یا جملات تقسیم میکند.
- ✅ کلمات توقف (Stopwords) کلماتی هستند که معمولاً اطلاعات مهمی ندارند و باید حذف شوند.
- ✅ Stemming کلمات را به ریشه (حتی اگر غلط باشد) کاهش میدهد.
- ✅ Lemmatization کلمات را با در نظر گرفتن معنا، به شکل پایه برمیگرداند.
- ✅ FreqDist برای محاسبه توزیع فرکانس کلمات استفاده میشود.
- ✅ VADER یک ابزار قدرتمند برای تحلیل احساسات در متون کوتاه است.
- ✅ n-gram دنبالهای از n کلمه متوالی است که برای تحلیل الگوهای زبانی استفاده میشود.
- ✅ این تکنیکها پایه و اساس تحلیل متن، طبقهبندی اسناد و سیستمهای پرسش و پاسخ هستند.