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. :::