التعلم غير الخاضع للإشراف: خوارزمية K-Means لتجميع العملاء (Clustering)

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

التعلم غير الخاضع للإشراف: خوارزمية K-Means لتجميع العملاء (Clustering)

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

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

قبل بناء النموذج، من الضروري تأسيس خط معالجة بيانات نظيف يبدأ من الاستدعاء والفهم الأولي للبيانات كما شرحنا في مكتبة Pandas (1): قراءة واستدعاء البيانات من ملفات CSV و Excel برمجياً، ثم فهم بنية DataFrame عبر مكتبة Pandas (2): استكشاف هيكل البيانات وفهم DataFrame و Series، ثم المرور على مراحل التنظيف والتجهيز قبل أي تدريب.

ما هي خوارزمية K-Means؟

خوارزمية K-Means هي خوارزمية تجميع تعتمد على تقليل المسافة بين كل نقطة بيانات ومركز المجموعة الأقرب لها. كل مجموعة تمثلها نقطة مركزية تسمى centroid، ويتم تحديث هذه المراكز بشكل تكراري حتى الاستقرار.

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

آلية العمل الداخلية

  1. اختيار عدد المجموعات K.
  2. تهيئة مراكز أولية عشوائية أو باستخدام k-means++.
  3. إسناد كل عميل إلى أقرب مركز بناءً على مسافة غالباً ما تكون Euclidean distance.
  4. إعادة حساب مركز كل مجموعة من متوسط نقاطها.
  5. تكرار العمليتين السابقتين حتى لا تعود التخصيصات تتغير كثيراً أو نصل إلى حد التكرارات.

هذا الأسلوب فعال وسريع نسبياً، لكنه حساس للقيم الشاذة، ولمقياس المتغيرات، ولطريقة اختيار عدد المجموعات. لذلك لا يجوز تطبيقه مباشرة على بيانات خام دون مرحلة إعداد جيدة.

تجهيز بيانات العملاء قبل التجميع

جودة المخرجات في K-Means تعتمد بشدة على جودة المدخلات. إذا احتوت البيانات على قيم مفقودة أو سجلات مكررة أو متغيرات متباينة المقاييس، فإن التجميع قد يعكس ضوضاء البيانات بدل أن يكشف الشرائح الحقيقية.

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

أهم المتغيرات المفيدة لتجميع العملاء

  • إجمالي الإنفاق خلال فترة محددة.
  • عدد الطلبات أو الزيارات.
  • متوسط قيمة الطلب.
  • الفاصل الزمني منذ آخر عملية شراء recency.
  • تكرار الشراء frequency.
  • القيمة النقدية monetary.

في معمارية التحليلات المؤسسية، يُفضّل فصل طبقة التجميع التحليلي عن بيانات المعاملات الخام. أنشئ طبقة feature store أو جدولاً مشتقاً يحتوي على مؤشرات سلوكية محسوبة مسبقاً، لأن تشغيل التجميع مباشرة على جداول تشغيلية ضخمة يزيد الكلفة ويضعف القابلية لإعادة الإنتاج.

مثال عملي باستخدام Pandas و scikit-learn

فيما يلي مثال تطبيقي لبناء نموذج تجميع عملاء اعتماداً على متغيرات AnnualIncome و SpendingScore. وقبل ذلك، يكون من المفيد فهم إعداد البيانات للتدريب (Data Preprocessing): تحجيم البيانات (Scaling & Normalization) لأن الخوارزمية تعتمد على المسافات.

import pandas as pd
from sklearn.preprocessing import StandardScaler
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score

# قراءة البيانات
df = pd.read_csv("customers.csv")

# اختيار السمات
features = df[["AnnualIncome", "SpendingScore"]].copy()

# تحجيم البيانات
scaler = StandardScaler()
X_scaled = scaler.fit_transform(features)

# تدريب النموذج
kmeans = KMeans(n_clusters=4, init="k-means++", random_state=42, n_init=10)
clusters = kmeans.fit_predict(X_scaled)

# إسناد النتائج إلى الجدول
df["Cluster"] = clusters

# تقييم أولي
score = silhouette_score(X_scaled, df["Cluster"])
print("Silhouette Score:", score)

# استعراض متوسطات كل مجموعة
summary = df.groupby("Cluster")[["AnnualIncome", "SpendingScore"]].mean()
print(summary)

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

كيف نختار العدد المناسب للمجموعات؟

أحد أكثر الأخطاء شيوعاً هو تحديد قيمة K بشكل اعتباطي. لأن زيادة عدد المجموعات قد تحسن الملاءمة الرياضية لكنها تضعف القابلية للتفسير التجاري. لذلك نستخدم أساليب تقييم مثل Elbow Method و Silhouette Score.

inertia_values = []
silhouette_values = []

for k in range(2, 9):
    model = KMeans(n_clusters=k, random_state=42, n_init=10)
    labels = model.fit_predict(X_scaled)
    inertia_values.append(model.inertia_)
    silhouette_values.append(silhouette_score(X_scaled, labels))

print("Inertia:", inertia_values)
print("Silhouette:", silhouette_values)

قيمة inertia تقيس مجموع مربعات المسافات داخل المجموعات، وكلما انخفضت كان التقسيم أفضل رياضياً. أما silhouette score فيقيس جودة الفصل بين المجموعات، والقيم الأعلى تعني تمايزاً أفضل.

تفسير النتائج وتحويلها إلى قرار تجاري

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

يفيد هنا استخدام أدوات التصوير من مكتبة Matplotlib أو مكتبة Seaborn لرسم توزعات المجموعات، وكذلك الاستفادة من التجميع والتلخيص (Groupby & Aggregation) لبناء ملفات تعريف إحصائية واضحة لكل شريحة.

من منظور تحسين الأداء، لا تُشغّل خوارزمية K-Means على جميع السمات المتاحة لمجرد توفرها. زيادة الأبعاد ترفع الكلفة الحسابية وتضعف معنى المسافة. ابدأ بمجموعة سمات قليلة، عالية الجودة، مرتبطة مباشرة بهدف العمل، ثم اختبر أثر إضافة كل متغير بصورة منهجية.

تجميع العملاء على نطاق البيانات الضخمة باستخدام PySpark

عندما ترتفع أحجام البيانات إلى ملايين أو عشرات الملايين من العملاء، يصبح استخدام Pandas وحده محدوداً بالذاكرة. هنا يأتي دور Apache Spark لمعالجة البيانات الموزعة وبناء التجميع على مستوى عنقودي.

from pyspark.sql import SparkSession
from pyspark.ml.feature import VectorAssembler, StandardScaler
from pyspark.ml.clustering import KMeans

spark = SparkSession.builder.appName("CustomerClustering").getOrCreate()

df = spark.read.csv("customers_big.csv", header=True, inferSchema=True)

assembler = VectorAssembler(
    inputCols=["AnnualIncome", "SpendingScore", "OrderCount"],
    outputCol="features_raw"
)
assembled_df = assembler.transform(df)

scaler = StandardScaler(inputCol="features_raw", outputCol="features", withStd=True, withMean=True)
scaler_model = scaler.fit(assembled_df)
scaled_df = scaler_model.transform(assembled_df)

kmeans = KMeans(k=4, seed=42, featuresCol="features", predictionCol="cluster")
model = kmeans.fit(scaled_df)

result = model.transform(scaled_df)
result.select("CustomerID", "cluster").show(10)

هذا النهج مناسب عندما تكون المؤسسة تبني خطوط ETL أو Pipeline تحليلية تعمل فوق Data Lake أو بيئة موزعة. كما يفيد دمج هذه النتائج لاحقاً مع مستودعات SQL و NoSQL لتغذية تطبيقات التسويق والتوصية.

أشهر التحديات والأخطاء

  • استخدام بيانات غير محجمة، مما يجعل متغيراً واحداً يهيمن على المسافات.
  • إدخال قيم شاذة كثيرة تشوه مواقع centroids.
  • اختيار K بناءً على الحدس فقط.
  • تفسير المجموعات دون الرجوع إلى سياق العمل والمؤشرات الفعلية.
  • الخلط بين التجميع والتصنيف؛ فـ K-Means لا يتنبأ بفئة صحيحة مسبقاً، بل يكتشف بنية محتملة داخل البيانات.

الخلاصة

تمثل خوارزمية K-Means نقطة انطلاق قوية في عالم تجميع العملاء، لأنها تجمع بين البساطة والفعالية وقابلية التوسع. لكن قيمتها الحقيقية تظهر فقط عندما تُبنى فوق بيانات نظيفة، وميزات مدروسة، وآلية تقييم منهجية، وتفسير مرتبط بهدف تجاري واضح.

إذا أُحسن استخدامها داخل بيئة تحليلية ناضجة، فإنها تتحول من مجرد خوارزمية تجميع إلى أداة استراتيجية لتقسيم السوق، وتحسين الاستهداف، ورفع قيمة العميل على المدى الطويل. وهذا هو جوهر مدخل إلى علوم البيانات: كيف تحول الأرقام العشوائية إلى قرارات استراتيجية؟ حيث تتحول الأنماط الرقمية إلى قرارات عملية قابلة للتنفيذ.

اترك تعليقاً

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