0Pricing
Pandas & NumPy Academy · درس

اكتشاف القيم الشاذة ومعالجتها

حدد القيم الشاذة باستخدام سياج IQR ودرجات Z، وقرّر ما إذا كنت ستحدّها أو تزيلها أو تضع علامة عليها، ووثّق القرارات.

اكتشاف القيم الشاذة ومعالجتها درس مجاني في Pandas & NumPy Academy على CoddyKit. هذا هو الدرس 2 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Pandas & NumPy Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Pandas & NumPy Academy 4 دروس في المجموع.

ما القيمة الشاذة؟

القيمة الشاذة هي نقطة بيانات تختلف اختلافًا كبيرًا عن بقية مجموعة البيانات. وقد تكون القيم الشاذة حقيقية (مثل عميل مؤسسي واحد لديه طلب بقيمة 500,000 دولار ضمن مجموعة بيانات يبلغ متوسط الطلبات فيها 100 دولار) أو خاطئة (مثل سعر سالب أو خطأ مطبعي حوّل 120 إلى 12,000). تتمثل الخطوة الأولى في معالجة القيم الشاذة في تحديد ما إذا كانت القيمة المتطرفة حقيقية وذات معنى، أم أنها مشكلة في جودة البيانات — إذ تختلف المعالجة اختلافًا كبيرًا بين الحالتين.

import pandas as pd
import numpy as np

df = pd.read_parquet('sales_clean.parquet')
print(df['revenue'].describe())

اكتشاف القيم الشاذة بصريًا: مخطط الصندوق

مخطط الصندوق هو أسرع أداة مرئية لاكتشاف القيم الشاذة. يمتد الصندوق عبر المدى الربيعي (IQR، من Q1 إلى Q3)، وتمتد العوارض حتى 1.5× IQR، بينما تُرسم النقاط الواقعة خارج العوارض منفردةً بوصفها قيمًا شاذة محتملة. استخدم df['revenue'].plot(kind='box') أو sns.boxplot() في Seaborn لرؤية القيم الشاذة فورًا دون حساب الحدود يدويًا.

import matplotlib.pyplot as plt
import seaborn as sns

fig, ax = plt.subplots(figsize=(6, 4))
df['revenue'].plot(kind='box', ax=ax)
ax.set_title('Revenue Distribution — Box Plot')
plt.tight_layout()
plt.show()

طريقة تحديد الحدود باستخدام IQR

تحسب طريقة تحديد الحدود باستخدام IQR المدى الربيعي، وتحدد حدّين عند Q1 − 1.5×IQR وQ3 + 1.5×IQR. وتُعلَّم القيم الواقعة خارج هذين الحدين بوصفها قيمًا شاذة. ويُعدّ معامل 1.5 قياسيًا للقيم الشاذة المعتدلة؛ فاستخدم 3.0 للقيم الشاذة المتطرفة فقط. تمتاز هذه الطريقة بأنها متينة؛ فعلى خلاف درجات Z، لا تفترض أن التوزيع طبيعي.

Q1 = df['revenue'].quantile(0.25)
Q3 = df['revenue'].quantile(0.75)
IQR = Q3 - Q1

lower = Q1 - 1.5 * IQR
upper = Q3 + 1.5 * IQR

outliers = df[(df['revenue'] < lower) | (df['revenue'] > upper)]
print(f'Q1={Q1:.0f}, Q3={Q3:.0f}, IQR={IQR:.0f}')
print(f'Bounds: [{lower:.0f}, {upper:.0f}]')
print(f'Outliers: {len(outliers)}')

طريقة درجة Z لاكتشاف القيم الشاذة

تقيس درجة Z عدد الانحرافات المعيارية التي تفصل القيمة عن المتوسط. وتُعدّ القيمة التي تحقق |Z| > 3 قيمة شاذة تقليديًا، إذ يغطي ذلك 99.7% من البيانات الموزعة توزيعًا طبيعيًا. إلا أن درجات Z تتأثر بالقيم الشاذة نفسها التي تحاول اكتشافها؛ فالقيم المتطرفة تسحب المتوسط وتزيد الانحراف المعياري، ما قد يحجب قيمًا شاذة أخرى.

mean = df['revenue'].mean()
std = df['revenue'].std()

df['revenue_z'] = (df['revenue'] - mean) / std
z_outliers = df[df['revenue_z'].abs() > 3]

print(f'Z-score outliers (|z|>3): {len(z_outliers)}')
print(z_outliers[['revenue', 'revenue_z']].head())

تمييز القيم الشاذة مقابل حذفها

لا تحذف القيم الشاذة مطلقًا من دون توثيق القرار وتبريره. بدلًا من ذلك، علِّمها أولًا باستخدام عمود منطقي (is_outlier)، ثم حلّل ما إذا كانت تشترك في نمط معين (المنطقة نفسها أو المنتج نفسه أو اليوم نفسه). فإذا كانت حقيقية، فأبقِ عليها ونمذجها صراحةً. أما إذا كانت أخطاء، فاحذفها وسجّل عدد الصفوف المحذوفة في سجل تدقيق مسار المعالجة.

df['is_revenue_outlier'] = (df['revenue'] < lower) | (df['revenue'] > upper)

print('Flagged rows:', df['is_revenue_outlier'].sum())
print(df.groupby('is_revenue_outlier')['revenue'].describe())

وضع حد أعلى للقيم الشاذة (Winsorizing)

يستبدل وضع الحدود (أو Winsorising) القيم التي تتجاوز الحدود بقيمة الحد نفسه بدلًا من حذف الصف. ويحافظ ذلك على جميع الصفوف في مجموعة البيانات، مع تقليل التشويه الذي تسببه القيم الشاذة في النماذج الخطية والإحصاءات الملخّصة. استخدم clip(lower=, upper=) لتطبيق الحدود في عملية متجهية واحدة.

df['revenue_capped'] = df['revenue'].clip(lower=lower, upper=upper)

print('Original max:', df['revenue'].max())
print('Capped max:', df['revenue_capped'].max())
print('Rows changed:', (df['revenue'] != df['revenue_capped']).sum())

التحويل اللوغاريتمي للبيانات المنحرفة إلى اليمين

غالبًا ما تكون توزيعات الإيرادات والأسعار منحرفة إلى اليمين، مع ذيل طويل من القيم الكبيرة. يؤدي تطبيق التحويل اللوغاريتمي باستخدام np.log1p() (لوغاريتم القيمة + 1 للتعامل مع الأصفار) إلى ضغط الذيل وجعل التوزيع أكثر تماثلًا. تفترض كثير من النماذج الإحصائية والتصورات البصرية التوزيع الطبيعي، لذا فإن تطبيق التحويل اللوغاريتمي على عمود الإيرادات قبل النمذجة يحسّن النتائج غالبًا.

df['log_revenue'] = np.log1p(df['revenue'])

fig, axes = plt.subplots(1, 2, figsize=(12, 4))
df['revenue'].hist(bins=50, ax=axes[0])
axes[0].set_title('Original Revenue')
df['log_revenue'].hist(bins=50, ax=axes[1])
axes[1].set_title('Log Revenue')
plt.tight_layout()
plt.show()

القيم الشاذة في أعمدة متعددة

عند تحليل أعمدة كثيرة دفعةً واحدة، احسب حدود القيم الشاذة باستخدام IQR برمجيًا لجميع الأعمدة الرقمية. كرّر العملية على الأعمدة الرقمية، واحسب الحدود، واحفظ النتائج في قاموس. يتيح لك ذلك إنشاء تقرير شامل عن القيم الشاذة في بضعة أسطر بدلًا من تكرار حساب IQR يدويًا لكل عمود.

numeric_cols = df.select_dtypes(include=['number']).columns

outlier_report = {}
for col in numeric_cols:
    Q1 = df[col].quantile(0.25)
    Q3 = df[col].quantile(0.75)
    IQR = Q3 - Q1
    n_out = ((df[col] < Q1 - 1.5*IQR) | (df[col] > Q3 + 1.5*IQR)).sum()
    outlier_report[col] = n_out

print(pd.Series(outlier_report).sort_values(ascending=False))

القيم الشاذة ثنائية المتغير باستخدام مخططات التبعثر

لا تظهر بعض النقاط كقيم شاذة إلا عند النظر إلى متغيرين معًا: فسعر الوحدة البالغ 10 دولارات طبيعي، والكمية البالغة 500 غير معتادة لكنها ليست مستحيلة، إلا أن اجتماع سعر وحدة قدره 10 دولارات مع كمية قدرها 500 لمنتج فاخر يثير الشك. تظهر القيم الشاذة ثنائية المتغير كنقاط معزولة في مخططات التبعثر. استخدم df.plot.scatter('quantity', 'unit_price') لاكتشاف النقاط البعيدة عن التجمع الرئيسي.

fig, ax = plt.subplots(figsize=(8, 5))
df.plot.scatter(x='quantity', y='unit_price', alpha=0.3, ax=ax)
ax.set_title('Quantity vs. Unit Price — Bivariate Outliers')
plt.tight_layout()
plt.show()

توثيق قرارات التعامل مع القيم الشاذة

يجب تسجيل كل قرار يتعلق بالقيم الشاذة: العمود، وطريقة الاكتشاف، والحد المستخدم، وعدد الصفوف التي تم تعليمها، والمعالجة المطبقة (الإبقاء أو وضع حد أو الحذف). تحمي هذه الوثائق المحلل أثناء مراجعات الشيفرة وعمليات التدقيق. احفظها في قاموس لسجل التنظيف، ثم احفظه إلى جانب مجموعة البيانات الناتجة.

outlier_log = {
    'column': 'revenue',
    'method': 'IQR 1.5x',
    'lower_bound': round(lower, 2),
    'upper_bound': round(upper, 2),
    'rows_flagged': int(df['is_revenue_outlier'].sum()),
    'treatment': 'cap (winsorise)'
}
for k, v in outlier_log.items():
    print(f'{k}: {v}')

حفظ مجموعة البيانات بعد معالجة القيم الشاذة

بعد تعليم القيم الشاذة ومعالجتها، احفظ DataFrame المحدّث. أبقِ عمود العلامة is_outlier في الناتج، حتى يتمكن المستخدمون اللاحقون من اختيار استبعاد الصفوف المعلّمة في تحليلات معينة. احفظ النسخة التي وُضعت لها حدود في عمود ذي لاحقة واضحة (_capped) إلى جانب العمود الأصلي، حتى تظل عملية التنظيف قابلة للعكس.

cols_to_save = [c for c in df.columns if c not in ['revenue_z']]
df[cols_to_save].to_parquet('sales_treated.parquet', index=False)
print('Outlier-treated dataset saved:', df.shape)

تحقق سريع

اختبر مدى فهمك لمفاهيم تحليل البيانات التي تناولها هذا الدرس.

مراجعة الدرس

تعلّمت في هذا الدرس: اكتشاف القيم الشاذة باستخدام تحديد الحدود بـ IQR ودرجات Z، وتحديد ما إذا كان ينبغي تعليم القيم الشاذة أو وضع حدود لها أو حذفها، وتطبيق التحويلات اللوغاريتمية على التوزيعات المنحرفة إلى اليمين. في القسم التالي، سنستكشف توحيد تسميات الفئات غير المتسقة في أعمدة النصوص.

الأسئلة الشائعة

هل درس «اكتشاف القيم الشاذة ومعالجتها» مجاني؟

نعم — نص درس «اكتشاف القيم الشاذة ومعالجتها» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Pandas & NumPy Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Pandas & NumPy Academy 4 دروس في المجموع.

ماذا ستتعلم في «اكتشاف القيم الشاذة ومعالجتها»؟

حدد القيم الشاذة باستخدام سياج IQR ودرجات Z، وقرّر ما إذا كنت ستحدّها أو تزيلها أو تضع علامة عليها، ووثّق القرارات. تتمرن على Pandas & NumPy Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ Pandas & NumPy Academy؟

لا تُشترط خبرة سابقة. Pandas & NumPy Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 2 من أصل 4.

كم من الوقت يستغرق درس «اكتشاف القيم الشاذة ومعالجتها»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس Pandas & NumPy Academy هذا؟

نعم. كل درس في Pandas & NumPy Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. اكتشاف التكرارات وإزالتها
  2. اكتشاف القيم الشاذة ومعالجتها
  3. توحيد الفئات غير المتسقة
  4. التحقق من المخطط والتأكيدات
← العودة إلى Pandas & NumPy Academy