.. _cross_validation: ========================================= التحقق المتبادل: تقييم أداء المقدر ========================================= .. currentmodule:: sklearn.model_selection يُعد تعلم معلمات دالة التنبؤ واختبارها على نفس البيانات خطأً منهجيًا: النموذج الذي يكرر فقط تسميات العينات التي رآها للتو ستحصل على درجة مثالية لكنها ستفشل في التنبؤ بأي شيء مفيد على البيانات التي لم يتم رؤيتها بعد. تسمى هذه الحالة **الإفراط في التجهيز**. لتجنب ذلك، من الممارسات الشائعة عند إجراء تجربة تعلم آلي (خاضعة للإشراف) لإخفاء جزء من البيانات المتاحة كمجموعة **اختبار** ``X_test, y_test``. لاحظ أن كلمة "تجربة" لا يُقصد بها للدلالة على الاستخدام الأكاديمي فقط، لأنه حتى في البيئات التجارية عادة ما يبدأ التعلم الآلي بشكل تجريبي. فيما يلي مخطط انسيابي لسير عمل التحقق المتبادل النموذجي في تدريب النموذج. يمكن تحديد أفضل المعلمات بواسطة :ref:`بحث الشبكة ` التقنيات. .. image:: ../images/grid_search_workflow.png :width: 400px :height: 240px :alt: سير عمل بحث الشبكة :align: center في scikit-learn، تقسيم عشوائي إلى مجموعات التدريب والاختبار يمكن حسابها بسرعة باستخدام دالة المساعدة :func:`train_test_split`. دعنا نحمل مجموعة بيانات iris لتناسب جهاز متجه دعم خطي عليها:: >>> import numpy as np >>> from sklearn.model_selection import train_test_split >>> from sklearn import datasets >>> from sklearn import svm >>> X, y = datasets.load_iris(return_X_y=True) >>> X.shape, y.shape ((150, 4), (150,)) يمكننا الآن أخذ عينة سريعة من مجموعة التدريب مع الاحتفاظ بـ 40٪ من البيانات لاختبار (تقييم) المصنف الخاص بنا:: >>> X_train, X_test, y_train, y_test = train_test_split( ... X, y, test_size=0.4, random_state=0) >>> X_train.shape, y_train.shape ((90, 4), (90,)) >>> X_test.shape, y_test.shape ((60, 4), (60,)) >>> clf = svm.SVC(kernel='linear', C=1).fit(X_train, y_train) >>> clf.score(X_test, y_test) 0.96... عند تقييم إعدادات مختلفة ("معلمات فائقة") للمقدرات، مثل إعداد ``C`` الذي يجب تعيينه يدويًا لـ SVM، لا يزال هناك خطر الإفراط في التجهيز *على مجموعة الاختبار* لأنه يمكن تعديل المعلمات حتى يعمل المقدر على النحو الأمثل. بهذه الطريقة، يمكن أن "تتسرب" المعرفة حول مجموعة الاختبار إلى النموذج ولم تعد مقاييس التقييم تُبلغ عن أداء التعميم. لحل هذه المشكلة، يمكن الاحتفاظ بجزء آخر من مجموعة البيانات كمجموعة تسمى "مجموعة التحقق من الصحة": يستمر التدريب على مجموعة التدريب، بعد ذلك يتم التقييم على مجموعة التحقق من الصحة، وعندما تبدو التجربة ناجحة، يمكن إجراء التقييم النهائي على مجموعة الاختبار. ومع ذلك، عن طريق تقسيم البيانات المتاحة إلى ثلاث مجموعات، نحن نقلل بشكل كبير من عدد العينات التي يمكن استخدامها لتعلم النموذج، ويمكن أن تعتمد النتائج على اختيار عشوائي معين لزوج مجموعات (التدريب، التحقق من الصحة). الحل لهذه المشكلة هو إجراء يسمى `التحقق المتبادل `_ (CV للاختصار). يجب أن تظل مجموعة الاختبار محجوزة للتقييم النهائي، لكن لم تعد هناك حاجة إلى مجموعة التحقق من الصحة عند القيام بـ CV. في النهج الأساسي، يسمى *k*-fold CV، يتم تقسيم مجموعة التدريب إلى *k* مجموعات أصغر (تم وصف مناهج أخرى أدناه، لكن بشكل عام اتبع نفس المبادئ). يتم اتباع الإجراء التالي لكل من "الطيات" *k*: * يتم تدريب نموذج باستخدام :math:`k-1` من الطيات كبيانات تدريب؛ * يتم التحقق من صحة النموذج الناتج على الجزء المتبقي من البيانات (على سبيل المثال، يتم استخدامه كمجموعة اختبار لحساب مقياس أداء مثل الدقة). مقياس الأداء الذي أبلغ عنه التحقق المتبادل *k*-fold هو متوسط القيم المحسوبة في الحلقة. يمكن أن يكون هذا النهج مكلفًا من الناحية الحسابية، لكنها لا تهدر الكثير من البيانات (كما هو الحال عند إصلاح مجموعة تحقق من الصحة التعسفية)، وهي ميزة رئيسية في مشاكل مثل الاستدلال العكسي حيث يكون عدد العينات صغيرًا جدًا. .. image:: ../images/grid_search_cross_validation.png :width: 500px :height: 300px :alt: وصف للتحقق المتبادل من 5 طيات على مجموعة تدريب، مع الاحتفاظ بمجموعة اختبار. :align: center حساب المقاييس المتحقق منها ============================== أبسط طريقة لاستخدام التحقق المتبادل هي استدعاء دالة المساعدة :func:`cross_val_score` على المقدر ومجموعة البيانات. يوضح المثال التالي كيفية تقدير دقة نواة خطية دعم آلة المتجهات على مجموعة بيانات iris عن طريق تقسيم البيانات، وملاءمة نموذج وحساب النتيجة 5 مرات متتالية (مع انقسامات مختلفة في كل مرة زمن):: >>> from sklearn.model_selection import cross_val_score >>> clf = svm.SVC(kernel='linear', C=1, random_state=42) >>> scores = cross_val_score(clf, X, y, cv=5) >>> scores array([0.96..., 1. , 0.96..., 0.96..., 1. ]) ومن ثم يتم إعطاء متوسط الدرجة والانحراف المعياري بواسطة:: >>> print("%0.2f accuracy with a standard deviation of %0.2f" % (scores.mean(), scores.std())) 0.98 دقة مع انحراف معياري قدره 0.02 افتراضيًا، يتم حساب النتيجة في كل تكرار CV هي ``النتيجة`` طريقة المقدر. من الممكن تغيير هذا باستخدام معلمة التسجيل:: >>> from sklearn import metrics >>> scores = cross_val_score( ... clf, X, y, cv=5, scoring='f1_macro') >>> scores array([0.96..., 1. ..., 0.96..., 0.96..., 1. ]) انظر :ref:`scoring_parameter` للحصول على التفاصيل. في حالة مجموعة بيانات Iris، يتم موازنة العينات عبر الهدف فئات وبالتالي فإن الدقة ودرجة F1 متساويتان تقريبًا. عندما تكون وسيطة ``cv`` عددًا صحيحًا، يستخدم :func:`cross_val_score` استراتيجيات :class:`KFold` أو :class:`StratifiedKFold` افتراضيًا، والأخيرة يتم استخدامه إذا كان المقدر مشتقًا من :class:`ClassifierMixin `. من الممكن أيضًا استخدام استراتيجيات التحقق المتبادل الأخرى عن طريق تمرير تقاطع مكرر التحقق من الصحة بدلاً من ذلك، على سبيل المثال:: >>> from sklearn.model_selection import ShuffleSplit >>> n_samples = X.shape[0] >>> cv = ShuffleSplit(n_splits=5, test_size=0.3, random_state=0) >>> cross_val_score(clf, X, y, cv=cv) array([0.977..., 0.977..., 1. ..., 0.955..., 1. ]) خيار آخر هو استخدام تكرار ينتج عنه انقسامات (تدريب، اختبار) كمصفوفات المؤشرات، على سبيل المثال:: >>> def custom_cv_2folds(X): ... n = X.shape[0] ... i = 1 ... while i <= 2: ... idx = np.arange(n * (i - 1) / 2, n * i / 2, dtype=int) ... yield idx, idx ... i += 1 ... >>> custom_cv = custom_cv_2folds(X) >>> cross_val_score(clf, X, y, cv=custom_cv) array([1. , 0.973...]) .. dropdown:: تحويل البيانات مع البيانات المحجوزة تمامًا كما هو الحال من المهم اختبار متنبئ على البيانات المحجوزة من التدريب، المعالجة المسبقة (مثل التوحيد القياسي، اختيار الميزات، إلخ.) و :ref:`تحويلات البيانات ` المماثلة بالمثل يجب يتم تعلمها من مجموعة التدريب وتطبيقها على البيانات المحجوزة للتنبؤ:: >>> from sklearn import preprocessing >>> X_train, X_test, y_train, y_test = train_test_split( ... X, y, test_size=0.4, random_state=0) >>> scaler = preprocessing.StandardScaler().fit(X_train) >>> X_train_transformed = scaler.transform(X_train) >>> clf = svm.SVC(C=1).fit(X_train_transformed, y_train) >>> X_test_transformed = scaler.transform(X_test) >>> clf.score(X_test_transformed, y_test) 0.9333... :class:`Pipeline ` يجعل من السهل تكوين المقدرات، وتوفير هذا السلوك تحت التحقق المتبادل:: >>> from sklearn.pipeline import make_pipeline >>> clf = make_pipeline(preprocessing.StandardScaler(), svm.SVC(C=1)) >>> cross_val_score(clf, X, y, cv=cv) array([0.977..., 0.933..., 0.955..., 0.933..., 0.977...]) انظر :ref:`combining_estimators`. .. _multimetric_cross_validation: دالة cross_validate وتقييم المقاييس المتعددة ------------------------------------------------- تختلف دالة :func:`cross_validate` عن :func:`cross_val_score` في طريقتان: - يسمح بتحديد مقاييس متعددة للتقييم. - تُرجع dict تحتوي على أوقات الملاءمة، وأوقات النتيجة (واختياريًا درجات التدريب، والمقدرات المناسبة، ومؤشرات تقسيم القطار والاختبار) بالإضافة إلى درجة الاختبار. لتقييم مقياس واحد، حيث تكون معلمة التسجيل عبارة عن سلسلة، قابل للاستدعاء أو لا شيء، ستكون المفاتيح - ``['test_score', 'fit_time', 'score_time']`` ولتقييم المقاييس المتعددة، تكون قيمة الإرجاع dict مع المفاتيح التالية - ``['test_', 'test_', 'test_', 'fit_time', 'score_time']`` يتم تعيين ``return_train_score`` على ``False`` افتراضيًا لتوفير وقت الحساب. لتقييم الدرجات على مجموعة التدريب أيضًا، تحتاج إلى تعيينها على ``True``. يمكنك أيضًا الاحتفاظ بالمقدر المناسب في كل مجموعة تدريب بواسطة تعيين ``return_estimator=True``. وبالمثل، يمكنك تعيين `return_indices=True` للاحتفاظ بمؤشرات التدريب والاختبار المستخدمة للتقسيم مجموعة البيانات إلى مجموعات التدريب والاختبار لكل تقسيم cv. يمكن تحديد المقاييس المتعددة إما كقائمة أو مجموعة أو مجموعة أسماء المسجل المحددة مسبقًا:: >>> from sklearn.model_selection import cross_validate >>> from sklearn.metrics import recall_score >>> scoring = ['precision_macro', 'recall_macro'] >>> clf = svm.SVC(kernel='linear', C=1, random_state=0) >>> scores = cross_validate(clf, X, y, scoring=scoring) >>> sorted(scores.keys()) ['fit_time', 'score_time', 'test_precision_macro', 'test_recall_macro'] >>> scores['test_recall_macro'] array([0.96..., 1. ..., 0.96..., 0.96..., 1. ]) أو كدالة dict تعيين اسم المسجل إلى دالة تسجيل محددة مسبقًا أو مخصصة:: >>> from sklearn.metrics import make_scorer >>> scoring = {'prec_macro': 'precision_macro', ... 'rec_macro': make_scorer(recall_score, average='macro')} >>> scores = cross_validate(clf, X, y, scoring=scoring, ... cv=5, return_train_score=True) >>> sorted(scores.keys()) ['fit_time', 'score_time', 'test_prec_macro', 'test_rec_macro', 'train_prec_macro', 'train_rec_macro'] >>> scores['train_rec_macro'] array([0.97..., 0.97..., 0.99..., 0.98..., 0.98...]) فيما يلي مثال على ``cross_validate`` باستخدام مقياس واحد:: >>> scores = cross_validate(clf, X, y, ... scoring='precision_macro', cv=5, ... return_estimator=True) >>> sorted(scores.keys()) ['estimator', 'fit_time', 'score_time', 'test_score'] الحصول على التنبؤات عن طريق التحقق المتبادل ------------------------------------------------ تحتوي الدالة :func:`cross_val_predict` على واجهة مشابهة لـ :func:`cross_val_score`، ولكنها تُرجع، لكل عنصر في الإدخال، التنبؤ الذي تم الحصول عليه لهذا العنصر عندما كان في مجموعة الاختبار. فقط يمكن استخدام استراتيجيات التحقق المتبادل التي تعين جميع العناصر إلى مجموعة اختبار مرة واحدة بالضبط (خلاف ذلك، يتم طرح استثناء). .. warning:: ملاحظة حول الاستخدام غير المناسب لـ cross_val_predict قد تختلف نتيجة :func:`cross_val_predict` عن تلك تم الحصول عليها باستخدام :func:`cross_val_score` حيث يتم تجميع العناصر في طرق مختلفة. تأخذ الدالة :func:`cross_val_score` متوسطًا عبر طيات التحقق المتبادل، بينما :func:`cross_val_predict` ببساطة ترجع التسميات (أو الاحتمالات) من عدة نماذج مميزة غير مميز. وبالتالي، فإن :func:`cross_val_predict` ليس مقياسًا مناسبًا خطأ التعميم. دالة :func:`cross_val_predict` مناسبة لـ: - تصور التنبؤات التي تم الحصول عليها من نماذج مختلفة. - مزج النماذج: عند استخدام تنبؤات مقدر خاضع للإشراف واحد لـ تدريب مقدر آخر في طرق المجموعة. تم تقديم مكررات التحقق المتبادل المتاحة في ما يلي القسم. .. rubric:: أمثلة * :ref:`sphx_glr_auto_examples_model_selection/plot_roc_crossval.py`، * :ref:`sphx_glr_auto_examples_feature_selection/plot_rfe_with_cross_validation.py`، * :ref:`sphx_glr_auto_examples_model_selection/plot_grid_search_digits.py`، * :ref:`sphx_glr_auto_examples_model_selection/plot_grid_search_text_feature_extraction.py`، * :ref:`sphx_glr_auto_examples_model_selection/plot_cv_predict.py`، * :ref:`sphx_glr_auto_examples_model_selection/plot_nested_cross_validation_iris.py`. مكررات التحقق المتبادل ========================== تسرد الأقسام التالية الأدوات المساعدة لإنشاء مؤشرات التي يمكن استخدامها لإنشاء تقسيمات مجموعة البيانات وفقًا لاختلاف التقاطع استراتيجيات التحقق من الصحة. .. _iid_cv: مكررات التحقق المتبادل لبيانات i.i.d. ------------------------------------------ بافتراض أن بعض البيانات مستقلة وموزعة بشكل متماثل (i.i.d.) هو الافتراض بأن جميع العينات تنبع من نفس عملية التوليد ويفترض أن عملية التوليد ليس لها ذاكرة للعينات التي تم إنشاؤها في الماضي. يمكن استخدام أدوات التحقق المتبادل التالية في مثل هذه الحالات. .. note:: بينما تعد بيانات i.i.d. افتراضًا شائعًا في نظرية التعلم الآلي، إلا أنها نادرًا ما تحدث يصمد في الممارسة. إذا كان المرء يعرف أن العينات قد تم إنشاؤها باستخدام عملية تعتمد على الوقت، فمن الآمن استخدم :ref:`مخطط التحقق المتبادل للسلاسل الزمنية `. وبالمثل، إذا كنا نعلم أن عملية التوليد لها بنية جماعية (عينات تم جمعها من مواضيع مختلفة، تجارب، قياس الأجهزة)، فمن الآمن استخدام :ref:`التحقق المتبادل على مستوى المجموعة `. .. _k_fold: K-fold ^^^^^^ يقسم :class:`KFold` جميع العينات في :math:`k` مجموعات من العينات، تسمى الطيات (إذا كان :math:`k = n`، فهذا يعادل *Leave One Out* استراتيجية)، من أحجام متساوية (إن أمكن). وظيفة التنبؤ هي تم تعلمه باستخدام :math:`k - 1` طيات، ويتم استخدام الطية المتروكة للاختبار. مثال على التحقق المتبادل من 2-fold على مجموعة بيانات تحتوي على 4 عينات:: >>> import numpy as np >>> from sklearn.model_selection import KFold >>> X = ["a", "b", "c", "d"] >>> kf = KFold(n_splits=2) >>> for train, test in kf.split(X): ... print("%s %s" % (train, test)) [2 3] [0 1] [0 1] [2 3] فيما يلي تصور لسلوك التحقق المتبادل. لاحظ أن :class:`KFold` لا يتأثر بالفئات أو المجموعات. .. figure:: ../auto_examples/model_selection/images/sphx_glr_plot_cv_indices_006.png :target: ../auto_examples/model_selection/plot_cv_indices.html :align: center :scale: 75% تتكون كل طية من مصفوفتين: الأولى مرتبطة بـ *مجموعة التدريب*، والثانية إلى *مجموعة الاختبار*. وبالتالي، يمكن للمرء إنشاء مجموعات التدريب / الاختبار باستخدام فهرسة numpy:: >>> X = np.array([[0., 0.], [1., 1.], [-1., -1.], [2., 2.]]) >>> y = np.array([0, 1, 0, 1]) >>> X_train, X_test, y_train, y_test = X[train], X[test], y[train], y[test] .. _repeated_k_fold: Repeated K-Fold ^^^^^^^^^^^^^^^ :class:`RepeatedKFold` يكرر K-Fold n مرات. يمكن استخدامه عندما يكون المرء يتطلب تشغيل :class:`KFold` n مرات، مما ينتج عنه انقسامات مختلفة في كل تكرار. مثال على 2-fold K-Fold تم تكراره مرتين:: >>> import numpy as np >>> from sklearn.model_selection import RepeatedKFold >>> X = np.array([[1, 2], [3, 4], [1, 2], [3, 4]]) >>> random_state = 12883823 >>> rkf = RepeatedKFold(n_splits=2, n_repeats=2, random_state=random_state) >>> for train, test in rkf.split(X): ... print("%s %s" % (train, test)) ... [2 3] [0 1] [0 1] [2 3] [0 2] [1 3] [1 3] [0 2] وبالمثل، يكرر :class:`RepeatedStratifiedKFold` Stratified K-Fold n مرات مع عشوائية مختلفة في كل تكرار. .. _leave_one_out: Leave One Out (LOO) ^^^^^^^^^^^^^^^^^^^ :class:`LeaveOneOut` (أو LOO) هو تحقق متبادل بسيط. كل تعلم يتم إنشاء المجموعة عن طريق أخذ جميع العينات باستثناء واحدة، ومجموعة الاختبار هي العينة المتروكة. وبالتالي، لـ :math:`n` عينات، لدينا :math:`n` مختلف مجموعات التدريب و :math:`n` مجموعة اختبارات مختلفة. هذا الصليب- لا يهدر إجراء التحقق من الصحة الكثير من البيانات حيث تتم إزالة عينة واحدة فقط من مجموعة التدريب:: >>> from sklearn.model_selection import LeaveOneOut >>> X = [1, 2, 3, 4] >>> loo = LeaveOneOut() >>> for train, test in loo.split(X): ... print("%s %s" % (train, test)) [1 2 3] [0] [0 2 3] [1] [0 1 3] [2] [0 1 2] [3] يجب على المستخدمين المحتملين لـ LOO لاختيار النموذج أن يزنوا بعض المحاذير المعروفة. عند مقارنتها بالتحقق المتبادل :math:`k`-fold، يبني المرء :math:`n` نماذج من :math:`n` عينات بدلاً من :math:`k` نماذج، حيث :math:`n > k`. علاوة على ذلك، يتم تدريب كل منها على :math:`n - 1` عينات بدلاً من :math:`(k-1) n / k`. في كلتا الحالتين، بافتراض أن :math:`k` ليست كبيرة جدًا و :math:`k < n`، فإن LOO أكثر تكلفة من الناحية الحسابية من التحقق المتبادل :math:`k`-fold. من حيث الدقة، غالبًا ما ينتج عن LOO تباين كبير كمقدر لـ خطأ الاختبار. بشكل حدسي، منذ :math:`n - 1` من يتم استخدام :math:`n` عينات لبناء كل نموذج، النماذج التي تم إنشاؤها من الطيات متطابقة تقريبًا مع بعضها البعض ومع النموذج المبني من مجموعة التدريب بأكملها. ومع ذلك، إذا كان منحنى التعلم حادًا لحجم التدريب المعني، ثم يمكن أن يؤدي التحقق المتبادل من 5 أو 10 طيات إلى المبالغة في تقدير خطأ التعميم. كقاعدة عامة، يقترح معظم المؤلفين، والأدلة التجريبية، أن 5 أو 10 يجب تفضيل التحقق المتبادل للطي على LOO. .. dropdown:: المراجع * ``_؛ * T. Hastie، R. Tibshirani، J. Friedman، `The Elements of Statistical Learning `_، Springer 2009 * L. Breiman، P. Spector `Submodel selection and evaluation in regression: The X-random case `_، International Statistical Review 1992؛ * R. Kohavi، `A Study of Cross-Validation and Bootstrap for Accuracy Estimation and Model Selection `_، Intl. Jnt. Conf. AI * R. Bharat Rao، G. Fung، R. Rosales، `On the Dangers of Cross-Validation. An Experimental Evaluation `_، SIAM 2008؛ * G. James، D. Witten، T. Hastie، R Tibshirani، `An Introduction to Statistical Learning `_، Springer 2013. .. _leave_p_out: Leave P Out (LPO) ^^^^^^^^^^^^^^^^^ :class:`LeavePOut` يشبه جدًا :class:`LeaveOneOut` لأنه ينشئ كل أزواج التدريب / الاختبار الممكنة عن طريق إزالة :math:`p` عينات من الكاملة جلس. لـ :math:`n` عينات، ينتج عن هذا :math:`{n \choose p}` قطار-اختبار أزواج. على عكس :class:`LeaveOneOut` و :class:`KFold`، مجموعات الاختبار ستكون تتداخل لـ :math:`p > 1`. مثال على Leave-2-Out على مجموعة بيانات تحتوي على 4 عينات:: >>> from sklearn.model_selection import LeavePOut >>> X = np.ones(4) >>> lpo = LeavePOut(p=2) >>> for train, test in lpo.split(X): ... print("%s %s" % (train, test)) [2 3] [0 1] [1 3] [0 2] [1 2] [0 3] [0 3] [1 2] [0 2] [1 3] [0 1] [2 3] .. _ShuffleSplit: تباديل عشوائية للتحقق المتبادل المعروف أيضًا باسم Shuffle & Split ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ سيولد مكرر :class:`ShuffleSplit` عددًا محددًا من قبل المستخدم انقسامات مجموعة بيانات التدريب / الاختبار المستقلة. يتم خلط العينات أولاً و ثم تقسم إلى زوج من مجموعات التدريب والاختبار. من الممكن التحكم في العشوائية لإعادة إنتاج النتائج عن طريق زرع ``random_state`` بشكل صريح عشوائي زائف مولد الأرقام. فيما يلي مثال على الاستخدام:: >>> from sklearn.model_selection import ShuffleSplit >>> X = np.arange(10) >>> ss = ShuffleSplit(n_splits=5, test_size=0.25, random_state=0) >>> for train_index, test_index in ss.split(X): ... print("%s %s" % (train_index, test_index)) [9 1 6 7 3 0 5] [2 8 4] [2 9 8 0 6 7 4] [3 5 1] [4 5 1 0 6 9 7] [2 3 8] [2 7 5 8 0 3 4] [6 1 9] [4 1 0 6 8 9 3] [5 2 7] فيما يلي تصور لسلوك التحقق المتبادل. لاحظ أن :class:`ShuffleSplit` لا يتأثر بالفئات أو المجموعات. .. figure:: ../auto_examples/model_selection/images/sphx_glr_plot_cv_indices_008.png :target: ../auto_examples/model_selection/plot_cv_indices.html :align: center :scale: 75% :class:`ShuffleSplit` هو بالتالي بديل جيد لـ :class:`KFold` التقاطع التحقق من الصحة الذي يسمح بالتحكم الدقيق في عدد التكرارات ونسبة العينات على كل جانب من جوانب تقسيم القطار / الاختبار. .. _stratification: مكررات التحقق المتبادل مع التقسيم الطبقي بناءً على تسميات الفئة -------------------------------------------------------------------- يمكن أن تُظهر بعض مشكلات التصنيف خللًا كبيرًا في التوزيع من فئات الهدف: على سبيل المثال، يمكن أن يكون هناك عدة مرات سلبية عينات من العينات الإيجابية. في مثل هذه الحالات، يوصى باستخدام أخذ العينات الطبقية كما هو مطبق في :class:`StratifiedKFold` و :class:`StratifiedShuffleSplit` لضمان أن ترددات الفئة النسبية هي يتم الحفاظ عليها تقريبًا في كل طية تدريب والتحقق من الصحة. .. _stratified_k_fold: k-fold الطبقي ^^^^^^^^^^^^^^^^^ :class:`StratifiedKFold` هو نوع مختلف من *k-fold* الذي يُرجع *طبقات* الطيات: تحتوي كل مجموعة على نفس النسبة المئوية تقريبًا من عينات كل منها فئة الهدف كمجموعة كاملة. فيما يلي مثال على التحقق المتبادل الطبقي من 3 طيات على مجموعة بيانات تحتوي على 50 عينة من فئتين غير متوازنتين. نعرض عدد العينات في كل فئة ونقارنها بـ :class:`KFold`. >>> from sklearn.model_selection import StratifiedKFold, KFold >>> import numpy as np >>> X, y = np.ones((50, 1)), np.hstack(([0] * 45, [1] * 5)) >>> skf = StratifiedKFold(n_splits=3) >>> for train, test in skf.split(X, y): ... print('train - {} | test - {}'.format( ... np.bincount(y[train]), np.bincount(y[test]))) train - [30 3] | test - [15 2] train - [30 3] | test - [15 2] train - [30 4] | test - [15 1] >>> kf = KFold(n_splits=3) >>> for train, test in kf.split(X, y): ... print('train - {} | test - {}'.format( ... np.bincount(y[train]), np.bincount(y[test]))) train - [28 5] | test - [17] train - [28 5] | test - [17] train - [34] | test - [11 5] يمكننا أن نرى أن :class:`StratifiedKFold` يحافظ على نسب الفئة (حوالي 1/10) في كل من مجموعة بيانات التدريب والاختبار. فيما يلي تصور لسلوك التحقق المتبادل. .. figure:: ../auto_examples/model_selection/images/sphx_glr_plot_cv_indices_009.png :target: ../auto_examples/model_selection/plot_cv_indices.html :align: center :scale: 75% يمكن استخدام :class:`RepeatedStratifiedKFold` لتكرار Stratified K-Fold n مرات مع عشوائية مختلفة في كل تكرار. .. _stratified_shuffle_split: تقسيم خلط طبقي ^^^^^^^^^^^^^^^^ :class:`StratifiedShuffleSplit` هو نوع مختلف من *ShuffleSplit*، والذي يُرجع انقسامات طبقية، *على سبيل المثال* التي تنشئ انقسامات عن طريق الحفاظ على نفس الشيء النسبة المئوية لكل فئة هدف كما في المجموعة الكاملة. فيما يلي تصور لسلوك التحقق المتبادل. .. figure:: ../auto_examples/model_selection/images/sphx_glr_plot_cv_indices_012.png :target: ../auto_examples/model_selection/plot_cv_indices.html :align: center :scale: 75% .. _predefined_split: تقسيمات الطيات / مجموعات التحقق من الصحة المحددة مسبقًا ------------------------------------------------------------- بالنسبة لبعض مجموعات البيانات، يكون التقسيم المحدد مسبقًا للبيانات إلى تدريب- وطية التحقق من الصحة أو في عدة طيات للتحقق المتبادل بالفعل موجود. باستخدام :class:`PredefinedSplit` من الممكن استخدام هذه الطيات على سبيل المثال عند البحث عن المعلمات الفائقة. على سبيل المثال، عند استخدام مجموعة التحقق من الصحة، قم بتعيين ``test_fold`` على 0 للجميع العينات التي هي جزء من مجموعة التحقق من الصحة، وإلى -1 لجميع العينات الأخرى. .. _group_cv: مكررات التحقق المتبادل للبيانات المجمعة ------------------------------------------- يتم كسر افتراض i.i.d. إذا كانت عملية التوليد الأساسية تنتج مجموعات من العينات التابعة. مثل هذا التجميع للبيانات خاص بالمجال. سيكون أحد الأمثلة عندما يكون هناك البيانات الطبية التي تم جمعها من مرضى متعددين، مع أخذ عينات متعددة منكل مريض. ومن المرجح أن تعتمد هذه البيانات على المجموعة الفردية. في مثالنا، سيكون معرف المريض لكل عينة هو معرف مجموعته. في هذه الحالة، نود أن نعرف ما إذا كان النموذج المدرب على مجموعة معينة من المجموعات تعمم بشكل جيد على المجموعات غير المرئية. لقياس هذا، نحن بحاجة إلى تأكد من أن جميع العينات في طية التحقق من الصحة تأتي من مجموعات غير ممثلة على الإطلاق في طية التدريب المقترنة. يمكن استخدام أدوات تقسيم التحقق المتبادل التالية للقيام بذلك. يتم تحديد معرف التجميع للعينات عبر ``groups`` معامل. .. _group_k_fold: Group k-fold ^^^^^^^^^^^^ :class:`GroupKFold` هو نوع مختلف من k-fold يضمن أن نفس المجموعة هي غير ممثلة في كل من مجموعات الاختبار والتدريب. على سبيل المثال، إذا كانت البيانات تم الحصول عليها من مواضيع مختلفة مع عدة عينات لكل موضوع وإذا النموذج مرن بما يكفي للتعلم من ميزات محددة للغاية للشخص يمكن أن تفشل في التعميم على مواضيع جديدة. :class:`GroupKFold` يجعل من الممكن لاكتشاف هذا النوع من حالات الإفراط في التجهيز. تخيل أن لديك ثلاثة مواضيع، لكل منها رقم مرتبط من 1 إلى 3:: >>> from sklearn.model_selection import GroupKFold >>> X = [0.1, 0.2, 2.2, 2.4, 2.3, 4.55, 5.8, 8.8, 9, 10] >>> y = ["a", "b", "b", "b", "c", "c", "c", "d", "d", "d"] >>> groups = [1, 1, 1, 2, 2, 2, 3, 3, 3, 3] >>> gkf = GroupKFold(n_splits=3) >>> for train, test in gkf.split(X, y, groups=groups): ... print("%s %s" % (train, test)) [0 1 2 3 4 5] [6 7 8 9] [0 1 2 6 7 8 9] [3 4 5] [3 4 5 6 7 8 9] [0 1 2] كل موضوع في طية اختبار مختلفة، ونفس الموضوع ليس أبدًا في كل من الاختبار والتدريب. لاحظ أن الطيات ليس لها نفس الشيء بالضبط الحجم بسبب عدم التوازن في البيانات. إذا كان يجب موازنة نسب الفئة عبر الطيات، :class:`StratifiedGroupKFold` هو خيار أفضل. فيما يلي تصور لسلوك التحقق المتبادل. .. figure:: ../auto_examples/model_selection/images/sphx_glr_plot_cv_indices_007.png :target: ../auto_examples/model_selection/plot_cv_indices.html :align: center :scale: 75% على غرار :class:`KFold`، ستشكل مجموعات الاختبار من :class:`GroupKFold` a تقسيم كامل لجميع البيانات. على عكس :class:`KFold`، :class:`GroupKFold` غير عشوائي على الإطلاق، بينما يكون :class:`KFold` عشوائيًا عندما ``shuffle=True``. .. _stratified_group_k_fold: StratifiedGroupKFold ^^^^^^^^^^^^^^^^^^^^ :class:`StratifiedGroupKFold` هو مخطط تحقق متبادل يجمع بين كليهما :class:`StratifiedKFold` و :class:`GroupKFold`. الفكرة هي محاولة الحفاظ على توزيع الفئات في كل تقسيم مع الحفاظ على كل مجموعة ضمن تقسيم واحد. قد يكون ذلك مفيدًا عندما يكون لديك غير متوازن مجموعة بيانات بحيث يؤدي استخدام :class:`GroupKFold` فقط إلى إنتاج انقسامات منحرفة. مثال:: >>> from sklearn.model_selection import StratifiedGroupKFold >>> X = list(range(18)) >>> y = [1] * 6 + [0] * 12 >>> groups = [1, 2, 3, 3, 4, 4, 1, 1, 2, 2, 3, 4, 5, 5, 5, 6, 6, 6] >>> sgkf = StratifiedGroupKFold(n_splits=3) >>> for train, test in sgkf.split(X, y, groups=groups): ... print("%s %s" % (train, test)) [ 0 2 3 4 5 6 7 10 11 15 16 17] [ 1 8 9 12 13 14] [ 0 1 4 5 6 7 8 9 11 12 13 14] [ 2 3 10 15 16 17] [ 1 2 3 8 9 10 12 13 14 15 16 17] [ 0 4 5 6 7 11] .. dropdown:: ملاحظات التنفيذ - مع التنفيذ الحالي، لا يمكن إجراء خلط كامل في معظم السيناريوهات. عندما shuffle=True، يحدث ما يلي: 1. يتم خلط جميع المجموعات. 2. يتم فرز المجموعات حسب الانحراف المعياري للفئات باستخدام الفرز المستقر. 3. يتم تكرار المجموعات التي تم فرزها وتعيينها إلى طيات. هذا يعني أنه سيتم خلط المجموعات ذات الانحراف المعياري نفسه لتوزيع الفئة فقط، مما قد يكون مفيدًا عندما تحتوي كل مجموعة على فئة واحدة فقط. - تقوم الخوارزمية بتعيين كل مجموعة بشكل جشع إلى إحدى مجموعات اختبار n_splits، اختيار مجموعة الاختبار التي تقلل من التباين في توزيع الفئة عبر مجموعات الاختبار. يبدأ تعيين المجموعة من المجموعات ذات أعلى إلى أدنى تباين في تكرار الفئة، أي مجموعات كبيرة بلغت ذروتها في واحد أو قليل يتم تعيين الفئات أولاً. - هذا التقسيم دون المستوى الأمثل بمعنى أنه قد ينتج عنه انقسامات غير متوازنة حتى لو كان التقسيم الطبقي المثالي ممكنًا. إذا كان لديك قريب نسبيًا توزيع الفئات في كل مجموعة، فإن استخدام :class:`GroupKFold` أفضل. فيما يلي تصور لسلوك التحقق المتبادل للمجموعات غير المتساوية: .. figure:: ../auto_examples/model_selection/images/sphx_glr_plot_cv_indices_005.png :target: ../auto_examples/model_selection/plot_cv_indices.html :align: center :scale: 75% .. _leave_one_group_out: Leave One Group Out ^^^^^^^^^^^^^^^^^^^ :class:`LeaveOneGroupOut` هو مخطط للتحقق المتبادل حيث يحتفظ كل تقسيم العينات التي تنتمي إلى مجموعة معينة. معلومات المجموعة هي يتم توفيره من خلال مصفوفة تقوم بترميز مجموعة كل عينة. وبالتالي، تتكون كل مجموعة تدريب من جميع العينات باستثناء تلك المتعلقة بمجموعة محددة. هذا هو نفسه :class:`LeavePGroupsOut` مع `n_groups=1` وهو نفس :class:`GroupKFold` مع `n_splits` يساوي عدد التسميات الفريدة التي تم تمريرها إلى معلمة `groups`. على سبيل المثال، في حالات التجارب المتعددة، :class:`LeaveOneGroupOut` يمكن استخدامها لإنشاء تحقق متبادل بناءً على التجارب المختلفة: نقوم بإنشاء مجموعة تدريب باستخدام عينات جميع التجارب باستثناء واحدة:: >>> from sklearn.model_selection import LeaveOneGroupOut >>> X = [1, 5, 10, 50, 60, 70, 80] >>> y = [0, 1, 1, 2, 2, 2, 2] >>> groups = [1, 1, 2, 2, 3, 3, 3] >>> logo = LeaveOneGroupOut() >>> for train, test in logo.split(X, y, groups=groups): ... print("%s %s" % (train, test)) [2 3 4 5 6] [0 1] [0 1 4 5 6] [2 3] [0 1 2 3] [4 5 6] تطبيق شائع آخر هو استخدام معلومات الوقت: على سبيل المثال يمكن أن تكون المجموعات هي سنة جمع العينات وبالتالي تسمح للتحقق المتبادل مقابل الانقسامات القائمة على الوقت. .. _leave_p_groups_out: Leave P Groups Out ^^^^^^^^^^^^^^^^^^ :class:`LeavePGroupsOut` مشابه لـ :class:`LeaveOneGroupOut`، لكنه يزيل عينات متعلقة بـ :math:`P` مجموعات لكل مجموعة تدريب / اختبار. كل ما هو ممكن يتم استبعاد مجموعات :math:`P`، مما يعني أن مجموعات الاختبار ستتداخل لـ :math:`P>1`. مثال على Leave-2-Group Out:: >>> from sklearn.model_selection import LeavePGroupsOut >>> X = np.arange(6) >>> y = [1, 1, 1, 2, 2, 2] >>> groups = [1, 1, 2, 2, 3, 3] >>> lpgo = LeavePGroupsOut(n_groups=2) >>> for train, test in lpgo.split(X, y, groups=groups): ... print("%s %s" % (train, test)) [4 5] [0 1 2 3] [2 3] [0 1 4 5] [0 1] [2 3 4 5] .. _group_shuffle_split: Group Shuffle Split ^^^^^^^^^^^^^^^^^^^ يتصرف مكرر :class:`GroupShuffleSplit` كمزيج من :class:`ShuffleSplit` و :class:`LeavePGroupsOut`، ويولد سلسلة من الأقسام العشوائية التي تكون فيها مجموعة فرعية من المجموعات يتم الاحتفاظ بها لكل تقسيم. يتم تنفيذ كل تقسيم تدريب / اختبار بشكل مستقل بمعنى لا توجد علاقة مضمونة بين مجموعات الاختبار المتتالية. فيما يلي مثال على الاستخدام:: >>> from sklearn.model_selection import GroupShuffleSplit >>> X = [0.1, 0.2, 2.2, 2.4, 2.3, 4.55, 5.8, 0.001] >>> y = ["a", "b", "b", "b", "c", "c", "c", "a"] >>> groups = [1, 1, 2, 2, 3, 3, 4, 4] >>> gss = GroupShuffleSplit(n_splits=4, test_size=0.5, random_state=0) >>> for train, test in gss.split(X, y, groups=groups): ... print("%s %s" % (train, test)) ... [0 1 2 3] [4 5 6 7] [2 3 6 7] [0 1 4 5] [2 3 4 5] [0 1 6 7] [4 5 6 7] [0 1 2 3] فيما يلي تصور لسلوك التحقق المتبادل. .. figure:: ../auto_examples/model_selection/images/sphx_glr_plot_cv_indices_011.png :target: ../auto_examples/model_selection/plot_cv_indices.html :align: center :scale: 75% هذه الفئة مفيدة عندما يكون سلوك :class:`LeavePGroupsOut` هو المرغوب فيه، لكن عدد المجموعات كبير بما يكفي لتوليد كل ستكون الأقسام الممكنة مع حجب مجموعات :math:`P` باهظة الثمن. في مثل هذا السيناريو، يوفر :class:`GroupShuffleSplit` عينة عشوائية (مع الاستبدال) من تقسيمات القطار / الاختبار تم إنشاؤها بواسطة :class:`LeavePGroupsOut`. استخدام مكررات التحقق المتبادل لتقسيم التدريب والاختبار ------------------------------------------------------------- قد تكون وظائف التحقق المتبادل للمجموعة المذكورة أعلاه مفيدة أيضًا لتقسيم مجموعة بيانات إلى مجموعات فرعية للتدريب والاختبار. لاحظ أن الراحة الدالة :func:`train_test_split` هي غلاف حول :func:`ShuffleSplit` وبالتالي يسمح فقط بالتقسيم الطبقي (باستخدام تسميات الفئة) ولا يمكن أن تمثل المجموعات. لإجراء تقسيم التدريب والاختبار، استخدم المؤشرات للتدريب والاختبار المجموعات الفرعية التي ينتجها المولد بواسطة طريقة `split()` لـ مقسم التحقق المتبادل. فمثلا:: >>> import numpy as np >>> from sklearn.model_selection import GroupShuffleSplit >>> X = np.array([0.1, 0.2, 2.2, 2.4, 2.3, 4.55, 5.8, 0.001]) >>> y = np.array(["a", "b", "b", "b", "c", "c", "c", "a"]) >>> groups = np.array([1, 1, 2, 2, 3, 3, 4, 4]) >>> train_indx, test_indx = next( ... GroupShuffleSplit(random_state=7).split(X, y, groups) ... ) >>> X_train, X_test, y_train, y_test = \ ... X[train_indx], X[test_indx], y[train_indx], y[test_indx] >>> X_train.shape, X_test.shape ((6,), (2,)) >>> np.unique(groups[train_indx]), np.unique(groups[test_indx]) (array([1, 2, 4]), array([3])) .. _timeseries_cv: التحقق المتبادل من بيانات السلاسل الزمنية --------------------------------------------- تتميز بيانات السلاسل الزمنية بالارتباط بين الملاحظات التي هي قريبة في الوقت المناسب (*الارتباط التلقائي*). ومع ذلك، الكلاسيكية تقنيات التحقق المتبادل مثل :class:`KFold` و :class:`ShuffleSplit` تفترض أن العينات مستقلة و موزعة بشكل متماثل، وسيؤدي إلى ارتباط غير معقول بين حالات التدريب والاختبار (ينتج عنها تقديرات ضعيفة لـ خطأ التعميم) على بيانات السلاسل الزمنية. لذلك، من المهم جدًا لتقييم نموذجنا لبيانات السلاسل الزمنية على الملاحظات "المستقبلية" على الأقل مثل تلك التي تُستخدم لتدريب النموذج. لتحقيق هذا، واحد يتم توفير الحل بواسطة :class:`TimeSeriesSplit`. .. _time_series_split: تقسيم السلاسل الزمنية ^^^^^^^^^^^^^^^^^^^^^^^ :class:`TimeSeriesSplit` هو نوع مختلف من *k-fold* الذي يعيد أول :math:`k` طيات كمجموعة تدريب و :math:`(k+1)` طية كمجموعة اختبار. لاحظ أنه على عكس طرق التحقق المتبادل القياسية، مجموعات التدريب المتتالية هي مجموعات شاملة لتلك التي تأتي قبلها. أيضًا، يضيف جميع البيانات الفائضة إلى قسم التدريب الأول، والذي يتم استخدامه دائمًا لتدريب النموذج. يمكن استخدام هذه الفئة للتحقق المتبادل من عينات بيانات السلاسل الزمنية التي لوحظت على فترات زمنية ثابتة. مثال على التحقق المتبادل للسلاسل الزمنية المكونة من 3 انقسامات على مجموعة بيانات تحتوي على 6 عينات:: >>> from sklearn.model_selection import TimeSeriesSplit >>> X = np.array([[1, 2], [3, 4], [1, 2], [3, 4], [1, 2], [3, 4]]) >>> y = np.array([1, 2, 3, 4, 5, 6]) >>> tscv = TimeSeriesSplit(n_splits=3) >>> print(tscv) TimeSeriesSplit(gap=0, max_train_size=None, n_splits=3, test_size=None) >>> for train, test in tscv.split(X): ... print("%s %s" % (train, test)) [0 1 2] [3] [0 1 2 3] [4] [0 1 2 3 4] [5] فيما يلي تصور لسلوك التحقق المتبادل. .. figure:: ../auto_examples/model_selection/images/sphx_glr_plot_cv_indices_013.png :target: ../auto_examples/model_selection/plot_cv_indices.html :align: center :scale: 75% ملاحظة حول الخلط =================== إذا لم يكن ترتيب البيانات عشوائيًا (على سبيل المثال، عينات بنفس تسمية الفئة متجاورة)، قد يكون خلطها أولاً ضروريًا للحصول على تقاطع ذي مغزى- نتيجة التحقق من الصحة. ومع ذلك، قد يكون العكس صحيحًا إذا كانت العينات ليست كذلك موزعة بشكل مستقل ومتماثل. على سبيل المثال، إذا كانت العينات تتوافق لمقالات إخبارية، ومرتبة حسب وقت نشرها، ثم خلط من المرجح أن تؤدي البيانات إلى نموذج مفرط التجهيز ودرجة تحقق من الصحة متضخمة: سيتم اختباره على عينات متشابهة بشكل مصطنع (قريبة من الوقت) لعينات التدريب. تحتوي بعض مكررات التحقق المتبادل، مثل :class:`KFold`، على خيار مدمج لخلط مؤشرات البيانات قبل تقسيمها. لاحظ أن: * يستهلك هذا ذاكرة أقل من خلط البيانات مباشرة. * افتراضيًا، لا يحدث خلط، بما في ذلك (الطبقي) K fold cross- التحقق من الصحة الذي يتم إجراؤه عن طريق تحديد ``cv=some_integer`` إلى :func:`cross_val_score`، بحث الشبكة، إلخ. ضع في اعتبارك ذلك :func:`train_test_split` لا يزال يُرجع تقسيمًا عشوائيًا. * معلمة ``random_state`` افتراضية إلى ``None``، مما يعني أن سيكون الخلط مختلفًا في كل مرة ``KFold(..., shuffle=True)`` هو متكرر. ومع ذلك، سيستخدم ``GridSearchCV`` نفس الخلط لكل مجموعة من المعلمات التي تم التحقق من صحتها من خلال استدعاء واحد لطريقة ``fit``. * للحصول على نتائج متطابقة لكل تقسيم، قم بتعيين ``random_state`` إلى عدد صحيح. لمزيد من التفاصيل حول كيفية التحكم في عشوائية مقسمات السيرة الذاتية وتجنب المزالق الشائعة، انظر :ref:`randomness`. التحقق المتبادل واختيار النموذج ==================================== يمكن أيضًا استخدام مكررات التحقق المتبادل لأداء النموذج مباشرةً الاختيار باستخدام Grid Search للمعلمات الفائقة المثلى لـ النموذج. هذا هو موضوع القسم التالي: :ref:`grid_search`. .. _permutation_test_score: درجة اختبار التقليب ====================== يقدم :func:`~sklearn.model_selection.permutation_test_score` طريقة أخرى لتقييم أداء المصنفات. يوفر التقليب القائم على القيمة الاحتمالية، والتي تمثل مدى احتمالية أداء ملحوظ لـ سيتم الحصول على المصنف عن طريق الصدفة. الفرضية الصفرية في هذا الاختبار هي أن المصنف يفشل في الاستفادة من أي اعتماد إحصائي بين الميزات والتسميات لإجراء تنبؤات صحيحة على البيانات المتروكة. :func:`~sklearn.model_selection.permutation_test_score` يولد فارغًا التوزيع عن طريق حساب `n_permutations` تباديل مختلفة لـ البيانات. في كل تبديل، يتم خلط التسميات بشكل عشوائي، وبالتالي إزالة أي اعتماد بين الميزات والتسميات. إخراج القيمة الاحتمالية هو جزء التباديل الذي يكون متوسط درجة التحقق المتبادل التي تم الحصول عليها بواسطة النموذج أفضل من درجة التحقق المتبادل التي تم الحصول عليها بواسطة النموذج باستخدام البيانات الأصلية. للحصول على نتائج موثوقة ``n_permutations`` يجب أن تكون عادةً أكبر من 100 و ``cv`` بين 3-10 طيات. توفر القيمة الاحتمالية المنخفضة دليلًا على أن مجموعة البيانات تحتوي على اعتماد حقيقي بين الميزات والتسميات وكان المصنف قادرًا على استخدام هذا للحصول على نتائج جيدة. يمكن أن تكون القيمة الاحتمالية العالية بسبب نقص الاعتماد بين الميزات والتسميات (لا يوجد فرق في قيم الميزات بين الفئات) أو لأن المصنف لم يكن قادرًا على استخدام التبعية في البيانات. في الحالة الأخيرة، باستخدام مصنف أكثر ملاءمة قادر على استخدام الهيكل في البيانات، سينتج عنه أقل القيمة الاحتمالية. يوفر التحقق المتبادل معلومات حول مدى جودة تعميم المصنف، على وجه التحديد نطاق الأخطاء المتوقعة للمصنف. ومع ذلك، لا يزال من الممكن أن يؤدي المصنف المدرب على مجموعة بيانات عالية الأبعاد بدون بنية أداء أفضل من المتوقع في التحقق المتبادل، عن طريق الصدفة. يمكن أن يحدث هذا عادةً مع مجموعات البيانات الصغيرة التي تحتوي على أقل من بضع مئات عينات. :func:`~sklearn.model_selection.permutation_test_score` يوفر معلومات حول ما إذا كان المصنف قد وجد بنية فئة حقيقية ويمكن أن يساعد في تقييم أداء المصنف. من المهم ملاحظة أن هذا الاختبار قد ثبت أنه ينتج منخفضًا القيم الاحتمالية حتى لو كان هناك هيكل ضعيف فقط في البيانات لأن في مجموعات البيانات المتبادلة المقابلة لا يوجد هيكل على الإطلاق. هذا لذلك، فإن الاختبار قادر فقط على إظهار متى يتفوق النموذج بشكل موثوق التخمين العشوائي. أخيرًا، يتم حساب :func:`~sklearn.model_selection.permutation_test_score` باستخدام القوة الغاشمة وملاءمة ``(n_permutations + 1) * n_cv`` نماذج داخليًا. لذلك لا يمكن تتبعه إلا مع مجموعات البيانات الصغيرة التي تناسب نموذج فردي سريع جدًا. .. rubric:: أمثلة * :ref:`sphx_glr_auto_examples_model_selection/plot_permutation_tests_for_classification.py` .. dropdown:: المراجع * Ojala and Garriga. `Permutation Tests for Studying Classifier Performance `_. J. Mach. Learn. Res. 2010.