بناء نظام توصية متقدم يعتمد على تفاعل المستخدمين (Collaborative Filtering)
بناء نظام توصية متقدم يعتمد على تفاعل المستخدمين (Collaborative Filtering)
يُعد نظام التوصية المعتمد على Collaborative Filtering من أكثر الأساليب فعالية في المنصات التي تمتلك سجلاً كثيفاً من تفاعلات المستخدمين مع المنتجات أو الأفلام أو المحتوى. الفكرة الجوهرية لا تعتمد على وصف العنصر نفسه، بل على الأنماط السلوكية المتكررة بين المستخدمين: من شاهد هذا، ماذا أحب أيضاً؟ ومن اشترى هذا، ما العناصر التي انتقل إليها لاحقاً؟
تقنياً، هذا النوع من النماذج يكتشف البنية الخفية داخل مصفوفة ضخمة تربط users وitems. ومع نمو البيانات إلى ملايين السجلات، يصبح التنفيذ التقليدي محدوداً، وهنا يظهر دور Big Data وبيئات المعالجة الموزعة مثل Apache Spark في تدريب النموذج بكفاءة وعلى نطاق إنتاجي.
ما هو Collaborative Filtering ولماذا ينجح؟
يعتمد هذا الأسلوب على فرضية عملية: المستخدمون الذين أظهروا سلوكاً متشابهاً في الماضي، غالباً سيظهرون ميولاً متقاربة في المستقبل. لذلك لا نحتاج دائماً إلى تحليل النصوص أو خصائص المنتج، بل نحتاج إلى سجل تفاعلات موثوق مثل التقييمات، النقرات، الإضافات إلى السلة، وقت المشاهدة، أو تكرار الشراء.
ويمكن بناء النظام بطريقتين شائعتين:
- الاعتماد على تشابه المستخدمين
User-Based. - الاعتماد على تشابه العناصر
Item-Based. - تفكيك المصفوفة إلى عوامل كامنة باستخدام
Matrix Factorization، وهو الأسلوب الأكثر ملاءمة للتوسع.
وعند مقارنة هذا النهج مع التوصية المعتمدة على تشابه المحتوى، سنجد أن Collaborative Filtering أقوى عندما تكون بيانات التفاعل وفيرة، لأنه يلتقط تفضيلات ضمنية قد لا تظهر في وصف المنتج نفسه.
بنية البيانات المطلوبة قبل التدريب
نجاح النموذج يبدأ من هندسة البيانات، وليس من الخوارزمية فقط. يجب أولاً بناء جدول تفاعلات منظم يحتوي على ثلاث ركائز أساسية: معرف المستخدم، معرف العنصر، وقيمة التفاعل. هذه القيم قد تكون صريحة مثل rating من 1 إلى 5، أو ضمنية مثل click_count وwatch_time.
غالباً يتم تجهيز هذه البيانات عبر مسار ETL Pipeline يمر بمراحل الاستخراج، التنظيف، التوحيد، ثم التحميل إلى طبقة تحليلية. في هذه المرحلة يصبح فهم القيم المفقودة والسجلات المكررة والمشوهة بالغ الأهمية لأن أي انحراف في التفاعلات سيؤثر مباشرة في التوصيات.
أعمدة شائعة في جدول التفاعل
user_iditem_idevent_typeevent_valueevent_timestamp
في بيئات الإنتاج الكبيرة، من الأفضل فصل بيانات التفاعل الخام عن جدول السمات النهائي المخصص للتدريب. هذا القرار في
Data Architectureيقلل من إعادة المعالجة، ويسهّل تتبع الأخطاء، ويحسّن سرعة التحديث الدوري للنموذج.
تجهيز بيانات التدريب وبناء الإشارات الضمنية
في كثير من المنصات لا توجد تقييمات مباشرة، لذلك نلجأ إلى تحويل السلوك إلى درجات ضمنية. مثلاً، يمكن إعطاء وزن أعلى لعملية الشراء، ووزن متوسط للإضافة إلى المفضلة، ووزن أقل للنقرة السريعة. هذه الفكرة تقع ضمن نطاق هندسة الميزات لأنها تحول الأحداث المتفرقة إلى تمثيل عددي صالح للتعلم.
كما يجب فلترة المستخدمين أو العناصر ذات النشاط المنخفض جداً، لأن الصفوف شديدة الندرة تزيد من هشاشة النموذج. ومن المفيد أيضاً اعتماد نافذة زمنية حديثة حتى لا تبقى التوصيات أسيرة تفضيلات قديمة لم تعد تعبّر عن السلوك الحالي.
from pyspark.sql import SparkSession
from pyspark.sql.functions import col, when, sum as spark_sum
spark = SparkSession.builder.appName("collaborative_filtering").getOrCreate()
events = spark.read.parquet("s3://bucket/user_events/")
weighted = events.withColumn(
"implicit_score",
when(col("event_type") == "purchase", 5.0)
.when(col("event_type") == "add_to_cart", 3.0)
.when(col("event_type") == "favorite", 2.0)
.when(col("event_type") == "click", 1.0)
.otherwise(0.0)
)
interactions = weighted.groupBy("user_id", "item_id").agg(
spark_sum("implicit_score").alias("rating")
)
filtered = interactions.filter(col("rating") > 0)
filtered.show(10)
تدريب نموذج ALS باستخدام PySpark
أشهر خوارزمية إنتاجية في هذا السياق هي ALS أو Alternating Least Squares. وهي تفكك مصفوفة التفاعل إلى متجهات كامنة للمستخدمين والعناصر، بحيث يمكن حساب درجة الاهتمام المتوقعة حتى للعناصر التي لم يتفاعل معها المستخدم بعد.
إذا كنت قد قرأت سابقاً لماذا تتوقف Pandas عن العمل مع البيانات الضخمة أو إعداد بيئة PySpark، فستعرف لماذا يعد Spark MLlib خياراً طبيعياً هنا.
from pyspark.ml.recommendation import ALS
from pyspark.ml.evaluation import RegressionEvaluator
train, test = filtered.randomSplit([0.8, 0.2], seed=42)
als = ALS(
userCol="user_id",
itemCol="item_id",
ratingCol="rating",
rank=30,
maxIter=15,
regParam=0.08,
implicitPrefs=True,
coldStartStrategy="drop",
nonnegative=True
)
model = als.fit(train)
predictions = model.transform(test)
evaluator = RegressionEvaluator(
metricName="rmse",
labelCol="rating",
predictionCol="prediction"
)
rmse = evaluator.evaluate(predictions)
print(f"RMSE: {rmse}")
كيف نقيم جودة التوصيات فعلياً؟
رغم أن RMSE مفيد، إلا أنه لا يكفي وحده في أنظمة التوصية. الهدف التجاري غالباً ليس فقط تقليل الخطأ العددي، بل زيادة احتمال النقر أو الشراء ضمن أول مجموعة توصيات. لذلك نستخدم مقاييس ترتيب مثل Precision@K وRecall@K.
ومن منظور علم البيانات، من المهم الفصل بين تقييم النموذج على بيانات تاريخية وبين اختباره ميدانياً عبر A/B Testing. فالنموذج قد يبدو ممتازاً على الورق لكنه ينتج توصيات متكررة أو غير متنوعة تقلل رضا المستخدم.
أفضل الممارسات هي الجمع بين مقاييس
offline evaluationومؤشرات الأعمال مثل معدل التحويل، متوسط قيمة الطلب، ومدة التفاعل. هذا الربط بين النموذج والأثر التجاري هو ما يرفع موثوقية المشروع ويعزّز قيمته الفعلية.
استعلامات تحليلية داعمة قبل وبعد التدريب
قبل تدريب أي نموذج، يفضّل دراسة كثافة التفاعلات وتوزيعها عبر SQL. هذه الخطوة تساعد على اكتشاف الانحياز نحو عناصر شديدة الشعبية أو مستخدمين غير نشطين. كما يمكن تنفيذ هذه التحليلات مباشرة داخل بيئة Spark SQL.
spark.sql("""
SELECT
item_id,
COUNT(DISTINCT user_id) AS unique_users,
SUM(rating) AS total_signal,
AVG(rating) AS avg_signal
FROM interactions_table
GROUP BY item_id
HAVING COUNT(DISTINCT user_id) >= 20
ORDER BY total_signal DESC
LIMIT 50
""").show()
هذا النوع من الاستعلامات يفيد أيضاً في بناء قوائم fallback للعناصر الشائعة عندما لا نملك بيانات كافية عن مستخدم جديد.
التحديات العملية: Cold Start والندرة والتوسع
أبرز مشكلة في Collaborative Filtering هي مشكلة البداية الباردة. المستخدم الجديد لم يترك تفاعلات بعد، والعنصر الجديد لم يحصل على إشارات كافية. هنا نحتاج إلى الدمج مع أساليب أخرى مثل البيانات الوصفية أو قواعد الأعمال أو النماذج القائمة على المحتوى.
كما أن مصفوفة التفاعل تكون شديدة الندرة Sparse Matrix في المنصات الضخمة، لذلك يفيد تقليل الضوضاء عبر الفلترة الزمنية، وعتبات النشاط، وإعادة وزن التفاعلات حسب نوعها وحداثتها.
عند العمل على نطاق كبير، يُفضّل تخزين بيانات التفاعل في بحيرة بيانات، ثم بناء طبقة سمات تدريبية مجدولة عبر Apache Airflow، مع حفظ النماذج أو المتجهات الناتجة في مخزن سريع للقراءة. هذه المعمارية تقلل زمن الاستجابة وتدعم إعادة التدريب الدوري دون التأثير على التطبيق الرئيسي.
خاتمة
بناء نظام توصية متقدم يعتمد على Collaborative Filtering ليس مجرد تطبيق خوارزمية جاهزة، بل هو مشروع متكامل يبدأ من جمع التفاعلات، ويمر عبر التنظيف والتهيئة، ثم تدريب نموذج مثل ALS، وينتهي بمراقبة الأداء التجاري والتحسين المستمر.
كلما كانت بنية البيانات أكثر نضجاً، وخطوط المعالجة أكثر استقراراً، زادت قدرة النظام على تقديم اقتراحات دقيقة وذات أثر فعلي على التفاعل والمبيعات. وهذا ما يجعل أنظمة التوصية واحدة من أوضح نقاط الالتقاء بين Data Science وBig Data Engineering في التطبيقات الواقعية.
2 comments