تطبيق عملي: سحب تغريدات/تعليقات حول منتج معين وتحليلها هل هي إيجابية أم سلبية؟

دقائق القراءة: 6

تطبيق عملي: سحب تغريدات/تعليقات حول منتج معين وتحليلها هل هي إيجابية أم سلبية؟

يُعد تحليل آراء المستخدمين حول المنتجات من أكثر تطبيقات Data Science قيمةً للشركات، لأنه يحوّل النصوص المبعثرة إلى مؤشرات قابلة للقياس تساعد فرق التسويق والدعم وتطوير المنتج على اتخاذ قرارات دقيقة. وإذا كنت قد قرأت سابقاً مدخل إلى علوم البيانات: كيف تحول الأرقام العشوائية إلى قرارات استراتيجية؟ فستلاحظ هنا كيف ننتقل من المفهوم النظري إلى تنفيذ عملي كامل.

في هذا التطبيق سنبني مسار عمل يبدأ من جمع تعليقات أو تغريدات عن منتج محدد، ثم تنظيف النصوص، ثم تحويلها إلى بيانات قابلة للنمذجة، وأخيراً تصنيفها إلى إيجابية أو سلبية. وعندما يزداد الحجم إلى مئات الآلاف من السجلات، تصبح أدوات مثل PySpark وDataFrame أكثر ملاءمة من المعالجة التقليدية.

فهم السيناريو العملي ومصدر البيانات

الهدف هو مراقبة الانطباع العام عن منتج مثل هاتف، تطبيق، أو خدمة رقمية. يمكن سحب البيانات من منصة اجتماعية عبر API رسمي، أو من نظام مراجعات داخلي، أو من ملفات محفوظة مسبقاً. هذه المرحلة تمثل جانب Extract ضمن دورة ETL، ويمكن التوسع فيها عبر مقال استخراج البيانات (Extract): سحب ملايين السجلات من واجهات API وقواعد بيانات SQL.

من المهم حفظ حقول أساسية مع كل تعليق، مثل النص، وقت النشر، اسم المنتج، اللغة، والمنصة. هذه الحقول ليست ترفاً تنظيمياً، بل ضرورية لبناء تحليلات زمنية، واكتشاف تغير المزاج العام بعد تحديث أو حملة تسويقية أو عطل تقني.

في المشاريع الواقعية، لا تحفظ النص وحده. احتفظ أيضاً بـ source وcreated_at وproduct_id وlanguage، لأن جودة التحليل النهائي تعتمد كثيراً على جودة التصميم الأولي لمخطط البيانات.

تنظيف النصوص قبل التحليل

أي نموذج Machine Learning سيتأثر مباشرة بضوضاء النصوص. لذلك نزيل الروابط، أسماء المستخدمين، الوسوم غير المهمة، التكرارات، والرموز المربكة. وإذا كانت البيانات عربية، فستفيدك خطوات موضحة في تنظيف النصوص العربية وإزالة التشكيل وحروف الجر استعداداً لتحليلها.

كذلك يجب التخلص من السجلات المكررة أو الفارغة، وهي خطوة أساسية موازية لما تناولناه في تنظيف البيانات (Data Cleaning): اكتشاف ومعالجة القيم المفقودة (Missing Values) ومعالجة البيانات المكررة والمشوهة (Duplicates & Outliers) باستخدام بايثون. كل خطأ صغير هنا قد يسبب انحيازاً واضحاً في نسب المشاعر لاحقاً.

import re
import pandas as pd

def clean_text(text):
    if pd.isna(text):
        return ""
    text = text.lower()
    text = re.sub(r"http\S+|www\S+", "", text)
    text = re.sub(r"@\w+", "", text)
    text = re.sub(r"#", "", text)
    text = re.sub(r"[^a-zA-Z0-9\u0600-\u06FF\s]", " ", text)
    text = re.sub(r"\s+", " ", text).strip()
    return text

df = pd.read_csv("product_comments.csv")
df = df.drop_duplicates(subset=["comment_text"])
df["clean_text"] = df["comment_text"].apply(clean_text)
df = df[df["clean_text"] != ""]
print(df.head())

تحويل البيانات إلى خصائص قابلة للتعلّم

النص الخام لا يمكن إدخاله مباشرة إلى أغلب النماذج. لذلك نحوله إلى تمثيل عددي باستخدام TF-IDF أو تمثيلات أحدث مثل Word Embeddings. هذه المرحلة ترتبط بمفاهيم هندسة الميزات (Feature Engineering): كيف تستخرج بيانات جديدة من البيانات الحالية؟ لأننا نحول الكلمات إلى إشارات رقمية مفيدة.

في مشروع سريع وفعّال، يمكن البدء بنموذج تصنيف ثنائي باستخدام LogisticRegression. وقد شرحنا أساسها من قبل في الانحدار اللوجستي (Logistic Regression): التنبؤ بالنتائج الثنائية. وهو مناسب جداً لسؤالنا الحالي: هل التعليق إيجابي أم سلبي؟

from sklearn.model_selection import train_test_split
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import classification_report, accuracy_score

# يفترض وجود عمود sentiment بقيم: positive / negative
X = df["clean_text"]
y = df["sentiment"]

vectorizer = TfidfVectorizer(max_features=5000, ngram_range=(1, 2))
X_vectorized = vectorizer.fit_transform(X)

X_train, X_test, y_train, y_test = train_test_split(
    X_vectorized, y, test_size=0.2, random_state=42, stratify=y
)

model = LogisticRegression(max_iter=1000)
model.fit(X_train, y_train)

predictions = model.predict(X_test)

print("Accuracy:", accuracy_score(y_test, predictions))
print(classification_report(y_test, predictions))

متى ننتقل إلى المعالجة الموزعة باستخدام PySpark؟

إذا كان حجم البيانات عشرات الآلاف فقط، فقد تكون Pandas كافية، خاصة إذا كنت قد اطلعت على مكتبة Pandas (1): قراءة واستدعاء البيانات من ملفات CSV و Excel برمجياً ومكتبة Pandas (2): استكشاف هيكل البيانات وفهم DataFrame و Series. لكن عند التوسع إلى ملايين التعليقات اليومية، يصبح الانتقال إلى Apache Spark خياراً عملياً وليس رفاهية.

هنا تظهر قوة Spark في توزيع العمليات على عدة عقد، وقراءة الملفات الضخمة بسرعة، وتنفيذ التحويلات بشكل كسول Lazy Evaluation لتقليل الهدر في الذاكرة والوقت.

from pyspark.sql import SparkSession
from pyspark.sql.functions import col, lower, regexp_replace, trim, length

spark = SparkSession.builder \
    .appName("ProductSentimentAnalysis") \
    .getOrCreate()

comments_df = spark.read.option("header", True).csv("product_comments.csv")

clean_df = comments_df.dropDuplicates(["comment_text"]) \
    .withColumn("clean_text", lower(col("comment_text"))) \
    .withColumn("clean_text", regexp_replace(col("clean_text"), r"http\\S+|www\\S+", "")) \
    .withColumn("clean_text", regexp_replace(col("clean_text"), r"@\\w+", "")) \
    .withColumn("clean_text", regexp_replace(col("clean_text"), r"#", "")) \
    .withColumn("clean_text", regexp_replace(col("clean_text"), r"[^a-zA-Z0-9\\u0600-\\u06FF\\s]", " ")) \
    .withColumn("clean_text", trim(regexp_replace(col("clean_text"), r"\\s+", " "))) \
    .filter(length(col("clean_text")) > 0)

clean_df.select("comment_text", "clean_text").show(5, truncate=False)

في بيئات الإنتاج، يُفضّل فصل طبقات التخزين إلى raw وclean وcurated. هذا يسهّل إعادة المعالجة، والتدقيق، ومقارنة مخرجات النماذج عبر الزمن، ويقلل خطر فقدان المصدر الأصلي للبيانات.

تحليل النتائج باستخدام SQL وتجميع المؤشرات

بعد التنبؤ بالمشاعر، نحتاج إلى عرض نتائج قابلة للفهم: ما نسبة التعليقات السلبية؟ هل ارتفعت بعد تحديث جديد؟ ما أكثر المنصات انتقاداً؟ هنا يمكننا استخدام SQL فوق بيانات Spark أو حفظها في مخزن تحليلي مثل BigQuery.

clean_df.createOrReplaceTempView("product_comments")

result_df = spark.sql("""
SELECT
    product_name,
    sentiment,
    COUNT(*) AS total_comments
FROM product_comments
GROUP BY product_name, sentiment
ORDER BY product_name, total_comments DESC
""")

result_df.show()

هذا النوع من التلخيص قريب من منهجية التجميع والتلخيص (Groupby & Aggregation): إنشاء تقارير إحصائية برمجية، لكنه هنا يُنفذ على بيانات ضخمة وبطريقة قابلة للتوسع. كما يمكن حفظ النتائج في قاعدة NoSQL مثل MongoDB إذا كانت بنية التعليقات مرنة وتحتاج حقولاً متفاوتة.

أتمتة المسار وتحويله إلى نظام إنتاجي

القيمة الحقيقية لا تظهر عند تشغيل السكربت مرة واحدة، بل عند تحويله إلى عملية مجدولة تسحب البيانات باستمرار، تنظفها، تصنفها، ثم تخزن النتائج تلقائياً. هذه هي الفكرة الأساسية التي تناولناها في بناء خطوط أنابيب البيانات (ETL – Extract, Transform, Load) باستخدام بايثون، ثم في مقدمة في Apache Airflow.

  • استخراج التعليقات الجديدة كل ساعة أو يوم.
  • تنظيف النصوص وتوحيد الترميز واللغة.
  • تشغيل نموذج التصنيف وإنتاج عمود predicted_sentiment.
  • تحميل النتائج إلى مستودع بيانات ولوحة مؤشرات.
  • تفعيل تنبيه عند تجاوز نسبة السلبية حداً معيناً.

أفضل بنية إنتاجية لهذا النوع من الأنظمة هي: مصدر بيانات اجتماعي، طبقة تخزين خام، طبقة معالجة موزعة، مخزن تحليلي، ثم لوحة مراقبة. بهذه المعمارية يمكن إضافة نماذج أكثر تقدماً لاحقاً دون كسر خط البيانات الأساسي.

خاتمة عملية

تحليل تغريدات وتعليقات المستخدمين حول منتج معيّن ليس مجرد تدريب أكاديمي في NLP، بل أداة مباشرة لفهم السوق وتحديد المشكلات بسرعة وقياس أثر التحسينات. يبدأ العمل من جمع البيانات بشكل صحيح، ثم تنظيفها، ثم تحويلها إلى خصائص رقمية، ثم تصنيفها، ثم بناء تقارير تنفيذية موثوقة.

وإذا أردت التوسع أكثر، فأنصحك بالانتقال بعد هذا المقال إلى تقنيات معالجة اللغات الطبيعية (NLP): تحليل المشاعر (Sentiment Analysis) للنصوص، ثم إلى إعداد بيئة PySpark: معالجة البيانات الموزعة على عدة أجهزة في نفس الوقت، لأن الدمج بين النمذجة النصية وهندسة البيانات الضخمة هو ما يحول الحل من تجربة صغيرة إلى منصة تحليل مؤسسية متقدمة.

1 comment

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *