مراقبة ML والخطوات التالية

حوكمة ML والامتثال

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

مع اتخاذ أنظمة ML قرارات أعلى مخاطرة، تنمو المتطلبات التنظيمية. المنظمات تحتاج أطر حوكمة لضمان نشر AI مسؤول.

لماذا حوكمة ML مهمة

المخاطرة التأثير مثال
التحيز دعاوى تمييز نموذج توظيف يفضل ديموغرافيات
الخصوصية غرامات GDPR نموذج يحفظ PII
السلامة مسؤولية المنتج فشل الأنظمة المستقلة
الشفافية عقوبات تنظيمية قرارات قروض "صندوق أسود"

المشهد التنظيمي (2025)

قانون AI الأوروبي

أول تنظيم شامل لـ AI في العالم، مع بدء التنفيذ في 2025-2026:

فئة المخاطرة المتطلبات أمثلة
غير مقبول محظور التقييم الاجتماعي، AI التلاعبي
عالي المخاطر امتثال صارم الرعاية الصحية، التوظيف، الائتمان
محدود الشفافية روبوتات الدردشة، اكتشاف المشاعر
أدنى تنظيم ذاتي مرشحات البريد المزعج، الألعاب

متطلبات عالي المخاطر

# مطلوب لأنظمة AI عالية المخاطر
documentation:
  - توثيق تقني للتصميم
  - نظام إدارة المخاطر
  - ممارسات حوكمة البيانات
  - تدابير الإشراف البشري
  - مقاييس الدقة/المتانة

capabilities:
  - تسجيل التدقيق
  - قابلية التتبع
  - اختبار التحيز
  - التجاوز البشري

الإطار التنظيمي الأمريكي

  • NIST AI RMF: إطار إدارة مخاطر طوعي
  • قوانين الولايات: تنظيمات AI في كاليفورنيا، كولورادو، إلينوي
  • خاصة بالقطاع: FDA (الرعاية الصحية)، SEC (المالية)، FTC (حماية المستهلك)

بطاقات النماذج

الصيغة المعيارية

# model_card.yaml
model_details:
  name: "fraud-detector-v3"
  version: "3.2.1"
  type: "تصنيف ثنائي"
  framework: "scikit-learn 1.4.0"
  owner: "risk-team@company.com"
  created: "2025-01-15"

intended_use:
  primary: "اكتشاف معاملات الدفع الاحتيالية"
  out_of_scope:
    - "اكتشاف احتيال على مستوى الحساب"
    - "التحقق من الهوية"
  users: "خط أنابيب معالجة المدفوعات (آلي)"

training_data:
  source: "قاعدة بيانات المعاملات الداخلية"
  size: "5.2M معاملة"
  date_range: "2024-01-01 إلى 2024-12-31"
  preprocessing: "انظر data_pipeline.md"

evaluation:
  metrics:
    accuracy: 0.94
    precision: 0.91
    recall: 0.87
    f1: 0.89
    auc_roc: 0.96
  test_set: "500K معاملة (holdout)"
  slices:
    - name: "عالية القيمة (>$10K)"
      accuracy: 0.92
    - name: "دولي"
      accuracy: 0.89
    - name: "عملاء جدد (<30 يوم)"
      accuracy: 0.85

ethical_considerations:
  bias_analysis:
    performed: true
    method: "تحليل التكافؤ الديموغرافي"
    findings: "لم يُكتشف تأثير متفاوت ذو دلالة"
  fairness_constraints:
    - "فرصة متساوية عبر فئات التجار"
  limitations:
    - "دقة أقل على شرائح العملاء الجديدة"
    - "قد لا يكتشف أنماط احتيال جديدة"

caveats:
  - "يتطلب 3 معاملات سابقة على الأقل للدقة"
  - "الأداء يتدهور على المعاملات الدولية"
  - "يُوصى بإعادة التدريب كل 90 يوم"

توليد بطاقات النماذج

# model_card_generator.py
from dataclasses import dataclass
from typing import Optional
import yaml
import json

@dataclass
class ModelCard:
    name: str
    version: str
    owner: str
    description: str
    metrics: dict
    training_data_info: dict
    ethical_considerations: dict
    limitations: list[str]

    def to_yaml(self) -> str:
        return yaml.dump(self.__dict__, default_flow_style=False)

    def to_markdown(self) -> str:
        md = f"# بطاقة النموذج: {self.name} v{self.version}\n\n"
        md += f"**المالك**: {self.owner}\n\n"
        md += f"## الوصف\n{self.description}\n\n"
        md += "## المقاييس\n"
        for k, v in self.metrics.items():
            md += f"- **{k}**: {v}\n"
        md += "\n## القيود\n"
        for lim in self.limitations:
            md += f"- {lim}\n"
        return md

def generate_model_card(
    model,
    test_data,
    test_labels,
    metadata: dict
) -> ModelCard:
    """ولّد بطاقة نموذج من نموذج مُدرب."""
    from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score

    predictions = model.predict(test_data)

    metrics = {
        "accuracy": round(accuracy_score(test_labels, predictions), 4),
        "precision": round(precision_score(test_labels, predictions), 4),
        "recall": round(recall_score(test_labels, predictions), 4),
        "f1": round(f1_score(test_labels, predictions), 4)
    }

    return ModelCard(
        name=metadata["name"],
        version=metadata["version"],
        owner=metadata["owner"],
        description=metadata.get("description", ""),
        metrics=metrics,
        training_data_info=metadata.get("training_data", {}),
        ethical_considerations=metadata.get("ethics", {}),
        limitations=metadata.get("limitations", [])
    )

تسجيل التدقيق

تسجيل شامل

# audit_logger.py
import json
import logging
from datetime import datetime
from typing import Any

class AuditLogger:
    def __init__(self, model_name: str, version: str):
        self.model_name = model_name
        self.version = version
        self.logger = logging.getLogger("ml_audit")

    def log_prediction(
        self,
        prediction_id: str,
        input_features: dict,
        output: Any,
        confidence: float,
        user_id: str | None = None,
        metadata: dict | None = None
    ):
        """سجّل التنبؤ لمسار التدقيق."""
        record = {
            "timestamp": datetime.utcnow().isoformat(),
            "event_type": "prediction",
            "model_name": self.model_name,
            "model_version": self.version,
            "prediction_id": prediction_id,
            "input_hash": self._hash_input(input_features),
            "output": output,
            "confidence": confidence,
            "user_id": user_id,
            "metadata": metadata or {}
        }
        self.logger.info(json.dumps(record))

    def log_model_deployment(
        self,
        previous_version: str | None,
        deployment_type: str,
        approver: str
    ):
        """سجّل حدث نشر النموذج."""
        record = {
            "timestamp": datetime.utcnow().isoformat(),
            "event_type": "deployment",
            "model_name": self.model_name,
            "model_version": self.version,
            "previous_version": previous_version,
            "deployment_type": deployment_type,
            "approver": approver
        }
        self.logger.info(json.dumps(record))

    def log_override(
        self,
        prediction_id: str,
        original_output: Any,
        overridden_output: Any,
        reason: str,
        operator: str
    ):
        """سجّل التجاوز البشري لتنبؤ النموذج."""
        record = {
            "timestamp": datetime.utcnow().isoformat(),
            "event_type": "human_override",
            "model_name": self.model_name,
            "prediction_id": prediction_id,
            "original_output": original_output,
            "overridden_output": overridden_output,
            "reason": reason,
            "operator": operator
        }
        self.logger.info(json.dumps(record))

    def _hash_input(self, features: dict) -> str:
        import hashlib
        return hashlib.sha256(
            json.dumps(features, sort_keys=True).encode()
        ).hexdigest()[:16]

اختبار التحيز

مقاييس العدالة

# bias_testing.py
import pandas as pd
import numpy as np

def demographic_parity(
    predictions: np.ndarray,
    protected_attribute: np.ndarray
) -> dict:
    """احسب فرق التكافؤ الديموغرافي."""
    groups = np.unique(protected_attribute)
    positive_rates = {}

    for group in groups:
        mask = protected_attribute == group
        positive_rates[group] = predictions[mask].mean()

    max_rate = max(positive_rates.values())
    min_rate = min(positive_rates.values())

    return {
        "positive_rates": positive_rates,
        "demographic_parity_difference": max_rate - min_rate,
        "demographic_parity_ratio": min_rate / max_rate if max_rate > 0 else 0
    }

def equal_opportunity(
    predictions: np.ndarray,
    labels: np.ndarray,
    protected_attribute: np.ndarray
) -> dict:
    """احسب فرق الفرصة المتساوية (تكافؤ TPR)."""
    groups = np.unique(protected_attribute)
    tpr_by_group = {}

    for group in groups:
        mask = (protected_attribute == group) & (labels == 1)
        if mask.sum() > 0:
            tpr_by_group[group] = predictions[mask].mean()
        else:
            tpr_by_group[group] = None

    valid_tprs = [v for v in tpr_by_group.values() if v is not None]

    return {
        "tpr_by_group": tpr_by_group,
        "equal_opportunity_difference": max(valid_tprs) - min(valid_tprs) if valid_tprs else None
    }

# مثال استخدام
results = demographic_parity(
    predictions=model.predict(X_test),
    protected_attribute=X_test["gender"]
)

if results["demographic_parity_difference"] > 0.1:
    print("تحذير: تحيز محتمل مُكتشف")
    print(f"معدلات إيجابية حسب المجموعة: {results['positive_rates']}")

قائمة فحص الحوكمة

قبل النشر

  • بطاقة النموذج موثقة
  • اختبار التحيز مكتمل
  • آلية الإشراف البشري معرفة
  • إجراء التراجع موثق
  • تسجيل التدقيق مُنفذ
  • نسب البيانات قابل للتتبع
  • موافقة من الامتثال/القانون

مراقبة الإنتاج

  • توزيع التنبؤات مُراقب
  • مقاييس العدالة متتبعة
  • معدل التجاوز البشري مُراقب
  • اكتشاف الانحراف نشط
  • سجلات التدقيق محتفظ بها وفق السياسة

الرؤية الرئيسية: الحوكمة ليست مجرد امتثال—إنها بناء أنظمة AI موثوقة يمكن للمنظمات والمستخدمين الاعتماد عليها.

التالي، سنراجع رحلة MLOps ونستكشف ما يجب تعلمه بعد ذلك. :::

اختبار

الوحدة 6: مراقبة ML والخطوات التالية

خذ الاختبار