التقييم المتقاطع (Cross-Validation): ضمان عدم حفظ النموذج للبيانات (Overfitting)

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

التقييم المتقاطع (Cross-Validation): ضمان عدم حفظ النموذج للبيانات (Overfitting)

في مشاريع مقدمة في تعلم الآلة (Machine Learning): الفرق بين التعلم الخاضع وغير الخاضع للإشراف، لا تكفي دقة التدريب المرتفعة للحكم على جودة النموذج. قد يحقق النموذج نتائج ممتازة على البيانات التي شاهدها مسبقاً، لكنه يفشل عند مواجهة بيانات جديدة. هنا يظهر خطر Overfitting، أي أن النموذج لا يتعلم القاعدة العامة بل يحفظ الأنماط والضجيج والتفاصيل العابرة.

لهذا السبب يُعد Cross-Validation من أهم أدوات التقييم الحديثة. فهو يختبر النموذج عدة مرات على تقسيمات مختلفة من البيانات، بدلاً من الاعتماد على تجربة واحدة فقط. هذه المنهجية تمنحنا تقديراً أكثر ثباتاً للأداء الحقيقي، وتقلل احتمال اتخاذ قرار خاطئ بسبب انحياز تقسيم واحد للبيانات.

إذا كنت قد قرأت مقال تقسيم البيانات (Train/Test Split): لماذا يجب أن نختبر النموذج على بيانات لم يرها من قبل؟، فاعتبر التقييم المتقاطع امتداداً احترافياً لذلك المفهوم. أما إذا كنت تعمل على بيانات معقدة بعد مراحل تنظيف البيانات (Data Cleaning): اكتشاف ومعالجة القيم المفقودة (Missing Values) وهندسة الميزات (Feature Engineering): كيف تستخرج بيانات جديدة من البيانات الحالية؟، فإن التقييم المتقاطع يصبح شرطاً أساسياً قبل نشر أي نموذج أو تصديره للإنتاج.

ما هو Cross-Validation؟

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

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

الفكرة الأساسية خطوة بخطوة

  • تقسيم البيانات إلى k أجزاء متقاربة الحجم.
  • تدريب النموذج k مرات.
  • في كل مرة نستخدم جزءاً مختلفاً للاختبار وبقية الأجزاء للتدريب.
  • تجميع المقاييس مثل Accuracy أو F1 أو RMSE.
  • حساب المتوسط والانحراف بين النتائج لفهم الاستقرار.

كيف يكشف التقييم المتقاطع مشكلة Overfitting؟

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

هذه النقطة مهمة خصوصاً مع النماذج القوية مثل شجرة القرارات (Decision Trees): كيف يتخذ الذكاء الاصطناعي قراراته بخطوات منطقية؟، لأنها قد تحفظ تفاصيل التدريب بسهولة. كما تظهر بوضوح عند مقارنة أكثر من خوارزمية مثل الانحدار اللوجستي (Logistic Regression) والغابات العشوائية (Random Forest) وخوارزمية KNN (أقرب الجيران).

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

أشهر أنواع Cross-Validation

K-Fold

النوع الأكثر شيوعاً. يتم تقسيم البيانات إلى عدد ثابت من الطيات مثل 5 أو 10. هذا الأسلوب مناسب عندما تكون البيانات متوازنة وتم توزيعها عشوائياً جيداً.

StratifiedKFold

مفيد جداً في التصنيف عندما تكون الفئات غير متوازنة. فهو يحافظ على النسبة التقريبية لكل فئة داخل كل طية. لهذا يرتبط مباشرة بمفاهيم مقال كيفية التعامل مع عدم توازن البيانات (Imbalanced Data) في نماذج التصنيف.

TimeSeriesSplit

في البيانات الزمنية لا يجوز خلط الماضي بالمستقبل. لذلك نستخدم تقسيمات تحترم التسلسل الزمني، وهو ما يتكامل مع التعامل مع التواريخ والوقت (Datetime): تحليل التوجهات الزمنية (Time Series).

تطبيق عملي باستخدام scikit-learn

لنأخذ مثالاً مختصراً على نموذج تصنيف بعد تنفيذ خطوات إعداد البيانات للتدريب (Data Preprocessing): تحجيم البيانات (Scaling & Normalization). سنستخدم Pipeline لدمج التحجيم مع النموذج لتجنب تسرب البيانات Data Leakage.

from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import cross_val_score, StratifiedKFold
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
import numpy as np

data = load_breast_cancer()
X = data.data
y = data.target

pipeline = Pipeline([
    ("scaler", StandardScaler()),
    ("model", LogisticRegression(max_iter=500))
])

cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)

scores = cross_val_score(
    pipeline,
    X,
    y,
    cv=cv,
    scoring="accuracy"
)

print("Fold Scores:", scores)
print("Mean Accuracy:", np.mean(scores))
print("Std Accuracy:", np.std(scores))

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

دمج التقييم المتقاطع مع تحسين المعاملات الفائقة

في المشاريع الاحترافية لا يُستخدم Cross-Validation فقط للتقييم، بل أيضاً لاختيار أفضل إعدادات النموذج. وهذا يرتبط مباشرة بمقال تحسين المعاملات الفائقة (Hyperparameter Tuning): رفع دقة النموذج إلى أقصى حد (GridSearch).

from sklearn.model_selection import GridSearchCV
from sklearn.ensemble import RandomForestClassifier

model = RandomForestClassifier(random_state=42)

param_grid = {
    "n_estimators": [100, 200],
    "max_depth": [3, 5, 10],
    "min_samples_split": [2, 5]
}

grid = GridSearchCV(
    estimator=model,
    param_grid=param_grid,
    cv=5,
    scoring="f1",
    n_jobs=-1
)

grid.fit(X, y)

print("Best Params:", grid.best_params_)
print("Best Score:", grid.best_score_)

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

أفضل ممارسة معمارية هي وضع كل خطوات التحويل مثل Scaling وEncoding وFeature Selection داخل Pipeline واحد. هذا يمنع تسرب المعرفة من بيانات الاختبار إلى التدريب، وهي مشكلة شائعة ترفع النتائج بشكل وهمي.

ماذا عن البيانات الضخمة وبيئات Spark؟

مع ازدياد حجم البيانات، قد يصبح تنفيذ التقييم المتقاطع مكلفاً زمنياً، خاصة بعد الانتقال من ما هو Apache Spark؟ ولماذا تتوقف مكتبة Pandas عن العمل مع البيانات الضخمة (Big Data)؟ إلى المعالجة الموزعة. في بيئة إعداد بيئة PySpark: معالجة البيانات الموزعة على عدة أجهزة في نفس الوقت، يمكن استخدام أدوات مدمجة لتقييم النماذج عبر أكثر من تقسيم.

from pyspark.ml.classification import LogisticRegression
from pyspark.ml.evaluation import BinaryClassificationEvaluator
from pyspark.ml.feature import VectorAssembler
from pyspark.ml.tuning import CrossValidator, ParamGridBuilder
from pyspark.ml import Pipeline

assembler = VectorAssembler(
    inputCols=["mean_radius", "mean_texture", "mean_perimeter"],
    outputCol="features"
)

lr = LogisticRegression(labelCol="label", featuresCol="features")

pipeline = Pipeline(stages=[assembler, lr])

param_grid = ParamGridBuilder() \
    .addGrid(lr.regParam, [0.01, 0.1]) \
    .addGrid(lr.elasticNetParam, [0.0, 0.5, 1.0]) \
    .build()

evaluator = BinaryClassificationEvaluator(labelCol="label")

crossval = CrossValidator(
    estimator=pipeline,
    estimatorParamMaps=param_grid,
    evaluator=evaluator,
    numFolds=5
)

cv_model = crossval.fit(spark_df)

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

أخطاء شائعة يجب تجنبها

  • تنفيذ التحجيم أو الترميز على كامل البيانات قبل تطبيق الطيات، وهذا يسبب Data Leakage.
  • استخدام K-Fold العادي مع بيانات غير متوازنة بدلاً من StratifiedKFold.
  • خلط التسلسل الزمني في بيانات السلاسل الزمنية.
  • الاعتماد على المتوسط فقط دون فحص التشتت بين الطيات.
  • اختيار المقياس الخاطئ، مثل التركيز على Accuracy في بيانات غير متوازنة بدلاً من Recall أو F1.

الخلاصة

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

كلما تقدمت في بناء النماذج، من خوارزمية الانحدار الخطي (Linear Regression) إلى المشاريع المعقدة مثل مشروع مصغر: بناء نموذج ذكاء اصطناعي يتنبأ باحتمالية إلغاء العملاء لاشتراكاتهم (Churn)، ستدرك أن النموذج الجيد ليس من يحفظ الماضي، بل من ينجح مع المستقبل. وهنا بالتحديد يثبت Cross-Validation قيمته الحقيقية.

اترك تعليقاً

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