Machine Learning: أساسيات NLP
آخر تحديث: 2026-08-26
وراء كل مراجعة توجد عاطفة — NLP يتيح للآلات قراءة الغضب وخيبة الأمل والسرور المخفي في ملاحظات العملاء.
1. ما ستتعلمه
- المعالجة المسبقة للنصوص: التجزئة (Jieba/NLTK)، إزالة الكلمات الشائعة، الجذر/التصريف
- تمثيل النصوص: Bag-of-Words، TF-IDF، N-gram
- تضمينات الكلمات: مبادئ Word2Vec (Gensim) والتدريب، حساب تشابه الكلمات
- تصنيف النصوص عمليًا: تحليل مشاعر مراجعات المنتجات باستخدام TF-IDF + LogisticRegression
- رؤى مراجعات Bob: تحديد تلقائي لكلمات المشاكل الرئيسية في المراجعات السلبية لتوجيه تحسينات المنتجات
2. قصة حقيقية من مدير خدمة عملاء التجارة الإلكترونية
(1) نقطة الألم: 5 آلاف مراجعة يوميًا، من المستحيل تحليلها يدويًا
يتلقى منصة Bob 5 آلاف مراجعة منتج يوميًا — إيجابية وسلبية واقتراحات كلها مختلطة. يمكن لفريق خدمة العملاء أخذ عينة بنسبة 1% فقط، مما يفوت عددًا هائلًا من مشكلات الجودة. الشهر الماضي، تسببت دفعة معيبة في 2 ألف مراجعة سلبية، ولكن لم يتم اكتشافها إلا بعد 3 أسابيع، بحلول ذلك الوقت كانت قد تسببت بالفعل في خسائر إرجاع بقيمة 500 ألف دولار. البيانات النصية الضخمة هي منجم ذهب غير مستغل وحقل ألغام في آن واحد.
(2) حل NLP
يمكن لـ NLP تحليل مشاعر المراجعة تلقائيًا، واستخراج كلمات المشاكل الرئيسية، ومراقبة اتجاهات المراجعة السلبية في الوقت الفعلي.
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.linear_model import LogisticRegression
from sklearn.pipeline import Pipeline
pipe = Pipeline([
("tfidf", TfidfVectorizer(max_features=5000, ngram_range=(1, 2))),
("clf", LogisticRegression(max_iter=500)),
])
pipe.fit(X_train_reviews, y_train_sentiment)
print(f"Sentiment accuracy: {pipe.score(X_test, y_test):.3f}")
(3) النتيجة: المشاكل تُكتشف خلال 3 أيام، معدل الإرجاع ينخفض 40%
بعد أن بدأ Bob في استخدام NLP لتحليل المراجعات تلقائيًا، انخفض الوقت من اكتشاف مشكلة جودة المنتج إلى الاستجابة من 3 أسابيع إلى 3 أيام، وانخفض معدل الإرجاع بنسبة 40%، ويوفر ما يقرب من مليون دولار سنويًا.
3. المعالجة المسبقة للنصوص
(1) التجزئة والتنظيف
▶ مثال: خط أنابيب المعالجة المسبقة للنصوص الإنجليزية
import re
from nltk.tokenize import word_tokenize
from nltk.corpus import stopwords
from nltk.stem import PorterStemmer, WordNetLemmatizer
import nltk
nltk.download("punkt_tab", quiet=True)
nltk.download("stopwords", quiet=True)
nltk.download("wordnet", quiet=True)
def preprocess_text(text):
# تحويل إلى أحرف صغيرة
text = text.lower()
# إزالة الأحرف الخاصة والأرقام
text = re.sub(r"[^a-zA-Z\s]", "", text)
# التجزئة
tokens = word_tokenize(text)
# إزالة الكلمات الشائعة
stop_words = set(stopwords.words("english"))
tokens = [t for t in tokens if t not in stop_words and len(t) > 2]
# الجذر
stemmer = PorterStemmer()
tokens_stemmed = [stemmer.stem(t) for t in tokens]
return " ".join(tokens_stemmed)
# اختبار
reviews = [
"This product is absolutely amazing! Best purchase ever.",
"Terrible quality, broke after 2 days. Very disappointed.",
"Decent product for the price, but shipping was slow.",
]
for review in reviews:
cleaned = preprocess_text(review)
print(f"Original: {review}")
print(f"Cleaned: {cleaned}\n")
Output:
# Function defined successfully
▶ مثال: تجزئة الكلمات (NLTK)
from sklearn.feature_extraction.text import CountVectorizer
reviews = [
"Great laptop fast performance",
"Terrible screen quality",
"Good price fast delivery",
]
vectorizer = CountVectorizer()
X_bow = vectorizer.fit_transform(reviews)
print(f"Vocabulary: {vectorizer.vocabulary_}")
print(f"BoW matrix shape: {X_bow.shape}")
Output:
# Executed successfully
| خطوة المعالجة المسبقة | الإنجليزية | الصينية |
|---|---|---|
| التجزئة | NLTK/spaCy (تقسيم المسافات) | Jieba/LAC (لا مسافات) |
| الكلمات الشائعة | كلمات NLTK الشائعة | قوائم HIT/Baidu للكلمات الشائعة |
| الجذع | PorterStemmer | غير قابل للتطبيق |
| التصريف | WordNetLemmatizer | غير قابل للتطبيق |
4. طرق تمثيل النصوص
يتطلب تحويل النص من "سلسلة" إلى "متجه رقمي" خط أنابيب تحويل تمثيل:
graph LR
TEXT[نص خام] --> TOKEN[تجزئة<br/>split / jieba] --> REMOVE[إزالة الكلمات الشائعة] --> STEM[جذر/تصريف] --> BOW[Bag-of-Words<br/>متجه عدد] --> TFIDF[TF-IDF<br/>متجج موزون] --> EMBED[Word2Vec<br/>تضمين كثيف]
style BOW fill:#fff3cd
style TFIDF fill:#d1ecf1
style EMBED fill:#d4edda
(1) Bag-of-Words و TF-IDF
▶ مثال: مقارنة ثلاث تمثيلات نصية
from sklearn.feature_extraction.text import CountVectorizer, TfidfVectorizer
import numpy as np
reviews = [
"great product fast delivery happy customer",
"terrible quality broke disappointed waste money",
"great quality decent price fast shipping",
"awful product terrible experience never buy again",
"excellent quality great value fast delivery",
]
labels = [1, 0, 1, 0, 1] # 1=إيجابي، 0=سلبي
# الطريقة 1: Bag-of-Words (العدد)
bow = CountVectorizer()
X_bow = bow.fit_transform(reviews)
print(f"BoW vocabulary size: {len(bow.vocabulary_)}")
# الطريقة 2: TF-IDF
tfidf = TfidfVectorizer(max_features=1000)
X_tfidf = tfidf.fit_transform(reviews)
print(f"TF-IDF shape: {X_tfidf.shape}")
# الطريقة 3: N-gram (التقاط العبارات)
tfidf_ngram = TfidfVectorizer(ngram_range=(1, 2), max_features=1000)
X_ngram = tfidf_ngram.fit_transform(reviews)
print(f"TF-IDF with bigrams shape: {X_ngram.shape}")
print(f"Top bigrams: {[w for w in tfidf_ngram.get_feature_names_out() if ' ' in w][:10]}")
Output:
# Executed successfully
| التمثيل | المعلومات | الأبعاد | حالة الاستخدام |
|---|---|---|---|
| BoW (تردد المصطلح) | منخفضة | عالية | تصنيف بسيط |
| TF-IDF | متوسطة | عالية | معياري لتصنيف النصوص |
| N-gram | متوسطة | عالية جدًا | التقاط العبارات |
| Word2Vec | عالية | منخفضة (100-300) | مهام دلالية |
(2) بديهة TF-IDF
- TF (تردد المصطلح): عدد المرات التي تظهر فيها الكلمة في المستند
- IDF (تردد المستند المعكوس): مدى ندرة الكلمة (الكلمات الأكثر ندرة تحصل على وزن أعلى)
- TF-IDF = TF × IDF: الكلمات الشائعة في هذا المستند ولكن النادرة في غيرها تحصل على أعلى وزن
5. تضمينات الكلمات باستخدام Word2Vec
(1) كيف يعمل Word2Vec
يتعلم Word2Vec متجهات الكلمات عبر التنبؤ بكلمات السياق (CBOW) أو التنبؤ بالسياق من كلمة (Skip-gram)، بحيث تنتهي الكلمات المتشابهة دلاليًا بمتجهات متقاربة.
▶ مثال: تدريب Word2Vec وتشابه الكلمات
from gensim.models import Word2Vec
from gensim.test.utils import common_texts
import numpy as np
# تدريب Word2Vec على عينة من الجسم
# عمليًا، استخدم جسم بيانات المراجعة الحقيقي
sentences = [
["great", "product", "fast", "delivery", "happy"],
["terrible", "quality", "broke", "disappointed"],
["great", "quality", "decent", "price"],
["awful", "product", "terrible", "experience"],
["excellent", "quality", "great", "value"],
["fast", "shipping", "good", "price", "recommend"],
["poor", "quality", "slow", "delivery", "angry"],
["amazing", "product", "best", "purchase", "happy"],
]
model = Word2Vec(sentences, vector_size=50, window=3, min_count=1, workers=4, epochs=50)
# تشابه الكلمات
print("Similar to 'great':")
for word, sim in model.wv.most_similar("great", topn=5):
print(f" {word}: {sim:.3f}")
# متجه الكلمة
print(f"\nVector for 'quality': {model.wv['quality'][:5]}... (50-dim)")
Output:
Similar to
| المعامل | المعنى | القيمة الموصى بها |
|---|---|---|
| vector_size | بُعد المتجه | 100-300 |
| window | حجم نافذة السياق | 5 |
| min_count | الحد الأدنى لتكرار الكلمة | 5 |
| sg | 0=CBOW, 1=Skip-gram | 1 (بيانات صغيرة) |
▶ مثال: تصور تضمينات الكلمات
from sklearn.decomposition import PCA
import matplotlib.pyplot as plt
words = ["great", "terrible", "happy", "angry", "fast", "slow",
"quality", "price", "product", "delivery"]
vectors = [model.wv[w] for w in words]
vectors_2d = PCA(n_components=2).fit_transform(vectors)
fig, ax = plt.subplots(figsize=(10, 8))
ax.scatter(vectors_2d[:, 0], vectors_2d[:, 1], s=100)
for i, word in enumerate(words):
ax.annotate(word, (vectors_2d[i, 0], vectors_2d[i, 1]), fontsize=12)
ax.set_title("Word2Vec Embedding Visualization")
ax.grid(True, alpha=0.3)
plt.tight_layout()
plt.savefig("word2vec_vis.png", dpi=150)
Output:
# Executed successfully
6. تحليل مشاعر مراجعات المنتجات عمليًا
▶ مثال: سير عمل كامل لتصنيف المشاعر
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.pipeline import Pipeline
from sklearn.metrics import classification_report, confusion_matrix
import numpy as np
# محاكاة مراجعات المنتجات
rng = np.random.default_rng(42)
positive_templates = [
"great product love it highly recommend",
"excellent quality fast delivery satisfied",
"amazing value best purchase ever happy",
"good product decent price works well",
"love this item perfect condition great",
]
negative_templates = [
"terrible quality broke after one day",
"awful product waste money very disappointed",
"poor quality slow delivery never again",
"worst purchase defective product angry",
"bad product cheap material not recommend",
]
# توليد 2000 مراجعة
reviews = []
labels = []
for _ in range(1000):
reviews.append(rng.choice(positive_templates))
labels.append(1)
reviews.append(rng.choice(negative_templates))
labels.append(0)
X_train, X_test, y_train, y_test = train_test_split(reviews, labels, test_size=0.2, random_state=42)
# خط أنابيب TF-IDF + الانحدار اللوجستي
pipe = Pipeline([
("tfidf", TfidfVectorizer(max_features=5000, ngram_range=(1, 2), min_df=2)),
("clf", LogisticRegression(max_iter=500, C=1.0)),
])
pipe.fit(X_train, y_train)
y_pred = pipe.predict(X_test)
print(f"Accuracy: {pipe.score(X_test, y_test):.4f}")
print(f"\nClassification Report:\n{classification_report(y_test, y_pred, target_names=['Negative', 'Positive'])}")
# استخراج الكلمات الأكثر أهمية لكل عاطفة
feature_names = pipe.named_steps["tfidf"].get_feature_names_out()
coefs = pipe.named_steps["clf"].coef_[0]
top_positive = np.argsort(coefs)[-10:][::-1]
top_negative = np.argsort(coefs)[:10]
print("\nTop positive words:")
for idx in top_positive:
print(f" {feature_names[idx]:20s}: {coefs[idx]:.3f}")
print("\nTop negative words:")
for idx in top_negative:
print(f" {feature_names[idx]:20s}: {coefs[idx]:.3f}")
Output:
Top positive words:
Top negative words:
❓ أسئلة شائعة
📖 ملخص
- خط أنابيب المعالجة المسبقة للنصوص: أحرف صغيرة → إزالة الأحرف الخاصة → تجزئة → إزالة الكلمات الشائعة → جذر/تصريف
- TF-IDF هو التمثيل القياسي لتصنيف النصوص: تردد المصطلح × تردد المستند المعكوس، مما يعطي أعلى وزن للكلمات النادرة ولكن المهمة
- تلتقط N-grams معلومات العبارات (مثل "not good")، لكن الأبعاد تنفجر، لذلك تحكم في max_features
- يتعلم Word2Vec متجهات الكلمات من خلال التنبؤ بالسياق؛ الكلمات المتشابهة دلاليًا لها متجهات متقاربة
- خط أنابيب تصنيف النصوص: TfidfVectorizer + LogisticRegression — بسيط وفعال
- تتيح معاملات النموذج استخراج الكلمات الرئيسية — كلمات مؤشر إيجابي/سلبي توجه مباشرة تحسينات العمل
📝 تمارين
- أساسي (الصعوبة ⭐): استخدم TfidfVectorizer لتمشيد 5 مراجعات منتجات، ثم اطبع المفردات ومصفوفة TF-IDF. تلميح: راجع المثال في القسم 4.
- متوسط (الصعوبة ⭐⭐): أنشئ خط أنابيب تصنيف مشاعر TF-IDF + LogisticRegression وقارن فرق درجة F1 بين الكلمات المفردة فقط و (1,2)-gram. تلميح: ngram_range=(1,1) مقابل (1,2).
- تحدي (الصعوبة ⭐⭐⭐): نفّذ نظام رؤى مراجعات Bob — بعد تدريب مصنف المشاعر، استخرج الكلمات الرئيسية السلبية العشرين الأولى، ورتبها حسب التكرار، وأخرج لوحة "أكثر القضايا إلحاحًا للإصلاح". تلميح: رتب coef_ + اربط بأسماء الميزات + احسب التكرارات.
← الدرس السابق: تقليل الأبعاد | الدرس التالي: مقدمة في التعلم العميق →