CI/CD لأنظمة ML

استراتيجيات اختبار ML

5 دقيقة للقراءة

اختبار ML يتجاوز اختبارات الوحدة. يتوقع المحاورون أن تعرف التحقق من البيانات والتحقق من النموذج واختبار التكامل الخاص بأنظمة ML.

هرم اختبار ML

                    /\
                   /  \
                  / E2E \          <-- اختبار الظل، اختبارات A/B
                 /________\
                /          \
               / Integration \      <-- اختبارات خط الأنابيب، اختبارات API
              /______________\
             /                \
            /    Model Tests   \    <-- الأداء، العدالة، المتانة
           /____________________\
          /                      \
         /     Data Tests         \  <-- المخطط، التوزيع، الجودة
        /__________________________\
       /                            \
      /        Unit Tests            \  <-- هندسة الميزات، المعالجة المسبقة
     /________________________________\

سؤال المقابلة: استراتيجية الاختبار

السؤال: "كيف ستعد الاختبار لخط أنابيب ML يعمل يومياً؟"

إجابة شاملة:

# فئات الاختبار لأنظمة ML
ml_test_categories = {
    "unit_tests": {
        "purpose": "اختبار الدوال الفردية",
        "examples": [
            "تحويلات هندسة الميزات",
            "منطق المعالجة المسبقة",
            "دوال الخسارة المخصصة"
        ],
        "run_frequency": "كل commit"
    },

    "data_tests": {
        "purpose": "التحقق من جودة البيانات",
        "examples": [
            "التحقق من المخطط",
            "اختبارات التوزيع (مقابل الأساس)",
            "عتبات معدل null",
            "السلامة المرجعية"
        ],
        "run_frequency": "كل تشغيل لخط الأنابيب"
    },

    "model_tests": {
        "purpose": "التحقق من جودة النموذج",
        "examples": [
            "عتبة الدقة الدنيا",
            "متطلبات زمن الاستدلال",
            "مقاييس العدالة (حسب الديموغرافية)",
            "المتانة للاضطرابات"
        ],
        "run_frequency": "قبل النشر"
    },

    "integration_tests": {
        "purpose": "اختبار تفاعلات المكونات",
        "examples": [
            "تنفيذ خط الأنابيب من البداية للنهاية",
            "اختبارات عقد API",
            "تكامل مخزن الميزات"
        ],
        "run_frequency": "يومياً / قبل الدمج"
    }
}

التحقق من البيانات مع Great Expectations

import great_expectations as gx

def create_data_expectations(context):
    """تحديد توقعات جودة البيانات"""

    suite = context.create_expectation_suite("training_data_suite")

    # توقعات المخطط
    validator.expect_column_to_exist("user_id")
    validator.expect_column_to_exist("transaction_amount")
    validator.expect_column_to_exist("timestamp")

    # توقعات النوع
    validator.expect_column_values_to_be_of_type(
        "transaction_amount", "float64"
    )

    # توقعات نطاق القيم
    validator.expect_column_values_to_be_between(
        "transaction_amount", min_value=0, max_value=1_000_000
    )

    # توقعات معدل null
    validator.expect_column_values_to_not_be_null(
        "user_id", mostly=1.0
    )
    validator.expect_column_values_to_not_be_null(
        "transaction_amount", mostly=0.99  # السماح بـ 1% nulls
    )

    # توقعات التوزيع
    validator.expect_column_mean_to_be_between(
        "transaction_amount", min_value=50, max_value=500
    )

    # توقعات التفرد
    validator.expect_column_values_to_be_unique("transaction_id")

    return suite

اختبارات أداء النموذج

import pytest

class TestModelPerformance:
    """يجب أن يجتاز النموذج هذه الاختبارات قبل النشر"""

    @pytest.fixture
    def model(self):
        return load_production_model("fraud_detector")

    @pytest.fixture
    def test_data(self):
        return load_test_dataset("fraud_test_2024")

    def test_accuracy_threshold(self, model, test_data):
        """يجب أن تتجاوز دقة النموذج 90%"""
        predictions = model.predict(test_data.features)
        accuracy = accuracy_score(test_data.labels, predictions)
        assert accuracy >= 0.90, f"الدقة {accuracy} أقل من العتبة 0.90"

    def test_precision_threshold(self, model, test_data):
        """يجب أن تتجاوز الدقة 85% لتقليل الإيجابيات الكاذبة"""
        predictions = model.predict(test_data.features)
        precision = precision_score(test_data.labels, predictions)
        assert precision >= 0.85, f"الدقة {precision} أقل من العتبة 0.85"

    def test_inference_latency(self, model):
        """يجب أن يكون زمن الاستجابة P99 أقل من 100ms"""
        latencies = []
        for _ in range(1000):
            start = time.time()
            model.predict(sample_input)
            latencies.append((time.time() - start) * 1000)

        p99_latency = np.percentile(latencies, 99)
        assert p99_latency < 100, f"زمن الاستجابة P99 {p99_latency}ms يتجاوز 100ms"

    def test_fairness_by_demographic(self, model, test_data):
        """ضمان عدم وجود تفاوت دقة >10% لأي ديموغرافية"""
        results_by_group = {}
        for group in test_data.demographic_groups:
            group_data = test_data.filter(demographic=group)
            predictions = model.predict(group_data.features)
            results_by_group[group] = accuracy_score(group_data.labels, predictions)

        max_disparity = max(results_by_group.values()) - min(results_by_group.values())
        assert max_disparity <= 0.10, f"تفاوت العدالة {max_disparity} يتجاوز 10%"

ورقة غش اختبار المقابلة

نوع الاختبار ما يلتقطه الأدوات
الوحدة أخطاء المنطق في الكود pytest، unittest
البيانات تغييرات المخطط، مشاكل الجودة Great Expectations، Pandera
النموذج تراجع الأداء pytest، مقاييس مخصصة
التكامل عدم تطابق المكونات pytest، اختبار API
العقد تغييرات API الكاسرة Pact، schemathesis

إشارة المقابلة: ذكر اختبار العدالة والتحليل الديموغرافي يُظهر نضجاً يتجاوز اختبار ML الأساسي.

في الدرس التالي، سنغطي سير عمل GitHub Actions لـ ML. :::

اختبار

الوحدة 5: CI/CD لأنظمة ML

خذ الاختبار