إعداد مجموعة البيانات
جودة البيانات والتنظيف
3 دقيقة للقراءة
جودة البيانات السيئة هي السبب #1 لفشل الضبط الدقيق. دعنا نتعلم كيفية تحديد وإصلاح مشاكل جودة البيانات الشائعة.
مشاكل جودة البيانات الشائعة
1. التكرارات
الأمثلة المكررة تسبب إفراط النموذج في التعلم على الأنماط المكررة.
from datasets import Dataset
def remove_duplicates(dataset):
seen = set()
unique_examples = []
for example in dataset:
# أنشئ تجزئة للتعليمة
key = hash(example["instruction"].strip().lower())
if key not in seen:
seen.add(key)
unique_examples.append(example)
print(f"أُزيلت {len(dataset) - len(unique_examples)} تكرارات")
return Dataset.from_list(unique_examples)
2. الأمثلة الفارغة أو المشوهة
def validate_example(example):
"""تحقق إذا المثال صالح."""
# تحقق من الحقول الفارغة
if not example.get("instruction", "").strip():
return False, "تعليمة فارغة"
if not example.get("output", "").strip():
return False, "مخرج فارغ"
# تحقق من الحد الأدنى للطول
if len(example["instruction"]) < 10:
return False, "التعليمة قصيرة جداً"
if len(example["output"]) < 5:
return False, "المخرج قصير جداً"
return True, "صالح"
def clean_dataset(dataset):
valid_examples = []
issues = []
for i, example in enumerate(dataset):
is_valid, reason = validate_example(example)
if is_valid:
valid_examples.append(example)
else:
issues.append(f"مثال {i}: {reason}")
print(f"أُبقي على {len(valid_examples)}/{len(dataset)} مثال")
return Dataset.from_list(valid_examples), issues
3. التنسيق غير المتسق
def normalize_example(example):
"""طبّع التنسيق عبر الأمثلة."""
return {
"instruction": example["instruction"].strip(),
"output": example["output"].strip(),
# أزل المسافات الزائدة
"input": " ".join(example.get("input", "").split())
}
dataset = dataset.map(normalize_example)
مقاييس الجودة
درجة التنوع
قس مدى تنوع تعليماتك:
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity
import numpy as np
def calculate_diversity(instructions):
"""احسب درجة التنوع (0-1، أعلى = أكثر تنوعاً)."""
vectorizer = TfidfVectorizer(max_features=1000)
tfidf_matrix = vectorizer.fit_transform(instructions)
# احسب متوسط التشابه الزوجي
similarities = cosine_similarity(tfidf_matrix)
# استثنِ التشابه الذاتي (القطر)
np.fill_diagonal(similarities, 0)
avg_similarity = similarities.sum() / (len(instructions) * (len(instructions) - 1))
# التنوع = 1 - التشابه
diversity = 1 - avg_similarity
return diversity
instructions = [ex["instruction"] for ex in dataset]
print(f"درجة التنوع: {calculate_diversity(instructions):.3f}")
توزيع الأطوال
تحقق من أطوال الاستجابات المتوازنة:
import matplotlib.pyplot as plt
def analyze_lengths(dataset):
instruction_lengths = [len(ex["instruction"]) for ex in dataset]
output_lengths = [len(ex["output"]) for ex in dataset]
print(f"طول التعليمة: {np.mean(instruction_lengths):.0f} ± {np.std(instruction_lengths):.0f}")
print(f"طول المخرج: {np.mean(output_lengths):.0f} ± {np.std(output_lengths):.0f}")
# علّم المشاكل المحتملة
if np.std(output_lengths) < 50:
print("تحذير: أطوال المخرجات موحدة جداً - قد تفتقر للتنوع")
استراتيجيات التصفية
مُرشح الجودة
def quality_filter(example):
"""صفّي الأمثلة منخفضة الجودة."""
instruction = example["instruction"]
output = example["output"]
# معايير التصفية
filters = [
len(output) >= 50, # الحد الأدنى لطول المخرج
len(output) <= 4000, # الحد الأقصى لطول المخرج
not output.startswith("I cannot"), # ليس رفضاً
not output.startswith("I'm sorry"), # ليس اعتذاراً
"```" not in instruction or "```" in output, # كود في المخرج إذا طُلب
]
return all(filters)
dataset = dataset.filter(quality_filter)
إزالة التكرار الدلالي
أزل الأمثلة المتشابهة دلالياً، حتى لو لم تكن تكرارات دقيقة:
from sentence_transformers import SentenceTransformer
def semantic_dedup(dataset, threshold=0.95):
"""أزل الأمثلة المتشابهة دلالياً."""
model = SentenceTransformer('all-MiniLM-L6-v2')
instructions = [ex["instruction"] for ex in dataset]
embeddings = model.encode(instructions)
# اعثر على الأزواج المتشابهة
similarity_matrix = cosine_similarity(embeddings)
keep_indices = []
for i in range(len(dataset)):
# تحقق إذا هذا المثال متشابه جداً مع أي مثال محتفظ به
is_unique = True
for j in keep_indices:
if similarity_matrix[i][j] > threshold:
is_unique = False
break
if is_unique:
keep_indices.append(i)
return dataset.select(keep_indices)
خط أنابيب التحقق من البيانات
def validate_dataset(dataset):
"""خط أنابيب التحقق الكامل."""
print("=" * 50)
print("تقرير التحقق من مجموعة البيانات")
print("=" * 50)
# 1. إحصائيات أساسية
print(f"\nإجمالي الأمثلة: {len(dataset)}")
# 2. أزل التكرارات
dataset = remove_duplicates(dataset)
# 3. تحقق ونظّف
dataset, issues = clean_dataset(dataset)
# 4. طبّع التنسيق
dataset = dataset.map(normalize_example)
# 5. مُرشح الجودة
before = len(dataset)
dataset = dataset.filter(quality_filter)
print(f"مُرشح الجودة أزال: {before - len(dataset)} أمثلة")
# 6. حلل التنوع
instructions = [ex["instruction"] for ex in dataset]
diversity = calculate_diversity(instructions)
print(f"درجة التنوع: {diversity:.3f}")
if diversity < 0.5:
print("تحذير: تنوع منخفض - اعتبر إضافة أمثلة أكثر تنوعاً")
# 7. حلل الأطوال
analyze_lengths(dataset)
print("\n" + "=" * 50)
print(f"حجم مجموعة البيانات النهائي: {len(dataset)}")
print("=" * 50)
return dataset
# شغّل التحقق
clean_dataset = validate_dataset(raw_dataset)
ملخص أفضل الممارسات
| المشكلة | الحل |
|---|---|
| التكرارات | إزالة تكرار بالتجزئة + دلالية |
| حقول فارغة | مُرشحات التحقق |
| تنوع منخفض | أضف أمثلة متنوعة، تحقق من التغطية |
| تنسيق غير متسق | خط أنابيب التطبيع |
| قصير/طويل جداً | تصفية مبنية على الطول |
| مخرجات منخفضة الجودة | مراجعة يدوية + تسجيل LLM |
بعد ذلك، سنتعلم كيفية إنشاء بيانات التفضيل لتدريب DPO. :::