التنبؤ: كيفية اكتشاف القيم المتطرفة؟

المقالة أدناه هي مقتطف من كتابي Science Science for Supply Chain Forecast ، المتاح هنا. يمكنك العثور على مقالاتي الأخرى هنا:

  • كيفية اكتشاف القيم المتطرفة
  • تعلم الآلة لتوقعات سلسلة التوريد
  • توقعات كرستون للتنبؤ المتقطع
  • توقعات KPI: RMSE ، MAE ، MAPE والتحيز
"لن أحاول اليوم مواصلة تحديد هذا النوع من المواد (...) ، وربما لم أتمكن من النجاح مطلقًا في القيام بذلك بذكاء. لكنني أعرف ذلك عندما أراه ".
بوتر ستيوارت

في عام 1964 ، كان بوتر ستيوارت قاضي المحكمة العليا في الولايات المتحدة. لم يكن يناقش القيم المتطرفة ولكن هل كان فيلم The Lovers فاحشًا أم لا.

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

تظهر هذه القيم المتطرفة طوال الوقت في سلاسل التوريد الحديثة. معظمهم بسبب سببين رئيسيين:

الأخطاء والأخطاء هذه هي القيم المتطرفة الواضحة. إذا لاحظت وجود مثل هذا النوع من الأخطاء أو أخطاء الترميز ، فهذا يستدعي تحسين العملية لمنع حدوثها مرة أخرى.
طلب استثنائي رغم أن بعض ملاحظات الطلب حقيقية ، فإن هذا لا يعني أنها ليست استثنائية ولا ينبغي تنظيفها أو سلاستها. هذا النوع من المبيعات الاستثنائية ليست في الواقع غير شائعة في سلاسل التوريد. فكر في العروض الترويجية ، أو التسويق ، أو سلوكيات العملاء الغريبة ، أو التدمير. عادة ، قد لا ترغب في أن تأخذ في الاعتبار توقعاتك للمبيعات الاستثنائية -80٪ ​​التي قمت بها العام الماضي للتخلص من المخزون القديم الذي عفا عليه الزمن تقريبًا.

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

في هذه المقالة ، سنناقش ثلاثة ونصف أفكار لتحديد هذه القيم المتطرفة ووضعها مرة أخرى في مستوى معقول.

فكرة # 1 - الطبعات

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

هذه التقنية الأولى ستخفض ببساطة قيم أعلى / أسفل ×٪ من طلبنا التاريخي إلى الحد الأدنى للنسبة المئوية العاشرة.

المئوية xth هي قيمة أدناه x٪ من الملاحظات في مجموعة ستنخفض. على سبيل المثال ، ستكون 99٪ من ملاحظات الطلب على المنتج أقل من النسبة المئوية التاسعة والتسعين.

وتسمى هذه التقنية المتمثلة في تقليص الطلب ببساطة إلى نسبة مئوية معينة winsorization. يأتي الاسم من تشارلز ب. وينسور ، وهو إحصائي من النصف الأول من القرن العشرين.

إذا نظرنا إلى المئين الأول والتسعين في مجموعتي بياناتنا الوهميتين أعلاه ، فهذا ما نحصل عليه:

في هذا الجدول ، نرى أنه في مجموعتي البيانات ، سيتم زيادة جميع القيم المنخفضة إلى 4.4. يمكنك أن ترى في الشكل أدناه أن هذا يقطع جزءًا من مجموعة البيانات الخاصة بنا. ستنخفض القيم العالية إلى 16.6 على مجموعة البيانات دون القيم المتطرفة (انظر الشكل 10.1) وصولاً إلى 70.9 لمجموعة البيانات ذات الحدود الخارجية (انظر الشكل 10.2).

ربما لاحظت أن winsorization لم يمنحنا نتائج مستديرة مثل 4 أو 5 ، ولكن بدلاً من ذلك حصلنا على 4.4. في الواقع ، نظرًا لأننا لا نملك قيمة دقيقة تخفض مجموعة البيانات بنسبة 99٪ ، فإننا نقوم بتقريب خطي استنادًا إلى أقرب القيمتين. هكذا حصلنا على هذه الأرقام بدلاً من الأرقام المستديرة.

لذلك ، هل نحن سعداء بهذه التقنية؟
لا، لسنا كذلك.
- لقد رصدنا القيم المتطرفة وهمية على مجموعة بيانات دون القيم المتطرفة.
- في مجموعة البيانات ذات القيم المتطرفة ، لم نقم بتخفيض القيمة الخارجية (من 100 إلى 70.9).

بالطبع ، يمكن للمرء أن يقترح ببساطة تخفيض الحد الأعلى للنسخة من 99٪ إلى 95٪ لمزيد من التقليل من الحد الأقصى في مجموعة البيانات رقم 2 ، لكن لسوء الحظ سيكون لهذا أيضًا تأثير على مجموعة البيانات رقم 1. هذا ليس حلا جيدا. يمكن للمرء أن يقترح أيضًا إزالة هذا الحد الأدنى حتى لا نزيد من طلبنا إلى 4.4. ولكن ، ماذا لو كان لدينا فترات مع الطلب في عداد المفقودين؟ ألا ينبغي لنا تنظيف هذه كذلك إن وجدت؟

افعلها بنفسك
في Excel ، يمكنك بسهولة الحصول على النسب المئوية المختلفة لنطاق من الخلايا في Excel باستخدام الصيغة = PERCENTILE.INC (النطاق ، الحد). بالطبع سيتعين عليك استخدام هذه الصيغة مرة واحدة للحد الأعلى (بقيمة تتراوح بين 0.95 - 0.99) ومرة ​​واحدة للحد الأدنى (بقيمة تتراوح بين 0.01 - 05.05).
Python يمكننا أن نفوز بسهولة بمجموعة بياناتنا في Python بفضل NumPy. يمكننا حساب النسب المئوية المختلفة للصفيف بفضل الدالة np.percentile (المصفوفة ، المئوية).

استيراد numpy كـ np
higher_limit = np.percentile (مجموعة ، 99)
lower_limit = np.percentile (صفيف ، 1)

لاحظ أن الدالة المئوية تأخذ النسبة المئوية المعبر عنها كقيمة بين 0 و 100 وليس كنسبة (أي قيمة بين 0 و 1) كما في Excel.

يمكننا بعد ذلك ببساطة قطع الصفيف إلى هذه الحدود الدنيا والعالية بفضل الدالة np.clip (array، min، max):

صفيف = np.clip (صفيف ، a_min = lower_limit ، a_max = higher_limit)

فكرة # 2 الانحراف المعياري

كما رأينا للتو ، لم تكن winsorization هي الطريقة المثالية لاستبعاد القيم المتطرفة لأنها ستستحوذ على قيم عالية ومنخفضة لمجموعة البيانات حتى لو لم تكن استثنائية لكل رؤية.

هناك طريقة أخرى تتمثل في النظر إلى تباين الطلب حول المتوسط ​​التاريخي واستبعاد القيم البعيدة بشكل استثنائي عن هذا المتوسط.
دعونا نحدد الانحراف المعياري للطلب على النحو التالي:

حيث n هو مقدار ملاحظات الطلب لدينا.

إذا افترضنا أن بياناتنا يتم توزيعها عادة حول المتوسط ​​التاريخي ، فيمكننا حساب احتمال أن يكون الطلب بين عتبة اثنين. إن الرياضيات الدقيقة المعنية هنا خارجة عن نطاق المقالة ، وللأسف في كثير من الأحيان لا يتم الاحترام الصارم لافتراض الحالة الطبيعية. سيتم تركيز هذين العتبة على متوسط ​​الطلب (μ) مع انتشار x أضعاف الانحراف المعياري (σ) في كلا الاتجاهين. فكلما زاد الطلب على الفوضى (بمعنى أنه كبير) ، زادت الحدود.

على سبيل المثال ، لدينا احتمال بنسبة 98٪ في أن نكون في النطاق: متوسط ​​الطلب +/- 2.33 ضعف الانحراف المعياري (كما في الشكل أعلاه). لذلك إذا أردنا إزالة أعلى 1٪ من القيمتين المرتفعة والمنخفضة ، فسنحدد الطلب على μ +/- 2.33 σ.

لاحظ أن هذا يعني أن لدينا احتمال بنسبة 99 ٪ لتكون أقل من μ + 2.33 σ. واحتمال 99٪ أن يكون أعلى من 2.3 - 2.33 σ.

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

دعونا نرى كيف تتصرف هذه الحدود الطبيعية الجديدة مقارنة مع حدود winsorization.

هذا بالفعل أفضل بكثير من النتائج التي حصلنا عليها مع winsorization:
- في مجموعة البيانات بدون القيم الخارجية (انظر الشكل 10.4) ، لا نغير أي ملاحظة للطلب (مثالية! - تمامًا كما نريد).
- في مجموعة البيانات ذات الحدود الخارجية ، لا نغير نقاط الطلب المنخفض ولكن فقط النقاط الخارجية الفعلية (انظر الشكل 10.5).

ومع ذلك ، على الرغم من أننا قمنا بتقليل المبلغ الخارجي إلى مبلغ أكثر قابلية للإدارة (47.9) مقارنةً مع winsorization (70.9) ، فقد لا يكون ذلك كافيًا بعد.

هل نحن سعداء الآن؟
ليس تماما بعد.

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

يمكنك أن ترى كيف يعمل التطبيع والتطبيع على هذا الطلب الموسمي على الشكل أدناه.

الأمر ببساطة ليس منطقيًا: فالتقنيتان تشيران إلى أن ذروة الموسم تعتبر غريبة وتخطي القيم الحقيقية الحقيقية وهي Y2 M11.

سوف نحل هذا مع تقنية المقبل لدينا.

افعلها بنفسك
Excel يمكنك حساب الانحراف المعياري لنطاق من الخلايا بفضل الصيغة = STDEV.P (range). كما هو الحال دائمًا ، يمكنك حساب الوسط بفضل = AVERAGE (range). بمجرد حصولك على هذين ، يمكنك حساب الحدود العليا والدنيا بفضل = NORM.INV (النسبة المئوية ، يعني ، stdev). عادةً ما تريد أن تكون النسبة المئوية المرتفعة حوالي 0.99 والأقل حول 0.01.
Python يمكنك حساب الانحراف المعياري عبر np.std (صفيف) لشبه الصفيف (مثل قائمة ، DataFrame وما إلى ذلك) أو للحصول على DataFrame مباشرة عبر الطريقة .std (). بحيث إذا كان لديك DataFrame df ، يمكنك ببساطة كتابة:

m = df.mean ()
s = df.std ()

سنستخدم مكتبة SciPy مرة أخرى لحساب الاحتمالات العادية. بعد ذلك ، سوف نستخدم طريقة .clip على DataFrame الخاصة بنا لوضع حد أقصى لها.

من استيراد scipy.stats القاعدة
#Print احتمالات كل مراقبة الطلب
print (norm.cdf (df.values، m، s). run (2))
limit_high = norm.ppf (0.99 ، م ، ث)
limit_low = norm.ppf (0.01 ، م ، ق)
df = df.clip (أقل = limit_low ، العلوي = limit_high)

الفكرة رقم 3 خطأ الانحراف المعياري

الفكرة الثانية التي كان يجب أن نعلمها عن القيم المتطرفة هي مقارنة كل ملاحظة بمتوسط ​​الطلب. لقد رأينا أنه لم يكن من المنطقي إذا كان لدينا اتجاه أو موسمية لأن الفرق بين الملاحظة والوسط التاريخي لم يكن ذا صلة.

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

دعنا نستعيد المثال الموسمي الذي قدمناه أعلاه. سنقارن الطلب التاريخي بتوقعات بسيطة (ولكن موسمية) لدينا.

إذا قمنا بحساب الخطأ الذي لدينا لمثل هذا التوقع (والذي هو ببساطة متوسط ​​الطلب التاريخي) ، فسوف نحصل على خطأ متوسط ​​قدره 0.4 وانحراف معياري قدره 3.2 (وهذا بالطبع يتأثر بشدة بالخطأ الذي لدينا Y2 M11). إذا أخذنا فاصل ثقة بنسبة 99٪ حول هذا المتوسط ​​، فسنقلص أخطاء التنبؤ إلى -0.4 +/- 2.33 × 3.2 = -8،7. يمكنك أن ترى في الشكل أدناه كيف تناسب هذه الحدود المحيطة بالتوقعات الطلب الموسمي تمامًا.

يمكننا الآن تصحيح هدفنا من Y2 M11. كان الطلب 19 ولكن التوقعات كانت 5 لهذه الفترة. الحد الأقصى للقيمة المقبولة هو 5 + 7 = 12. وهذا يعني أنه يمكننا استبدال قيمة Y2 M11 (19) بهذه القيمة الجديدة (12).

خاتمة
باستخدام طريقة الكشف الأكثر ذكاءً - تحليل انحراف الخطأ المتوقع بدلاً من مجرد تباين الطلب حول المتوسط ​​- سنكون قادرين على تحديد القيم المتطرفة بدقة أكبر بكثير وتقليلها إلى مبلغ معقول. كما ترون في الشكل أعلاه ، فإن التطبيع والنسخة لا يمكن أن يحققا أي نتائج ذات مغزى لهذا الطلب الموسمي.

الضبط الدقيق لهذه الطريقة كم عدد الانحرافات المعيارية التي يجب أن تأخذها كحد أقصى؟ - بالطبع - متروك لك للتجربة ...

افعلها بنفسك
Python إذا كان لديك الباندا DataFrame مع عمود واحد كما توقع والآخر حسب الطلب (الإخراج النموذجي من نماذج تجانس الأسي لدينا) ، يمكننا استخدام هذا الرمز:

df ["Error"] = df ["Forecast"] - df ["Demand"]
m = df ["خطأ"]. mean ()
s = df ["Error"]. std ()
من استيراد scipy.stats القاعدة
limit_high = norm.ppf (0.99، m، s) + df ["Forecast"]
limit_low = norm.ppf (0.01، m، s) + df ["Forecast"]
df ["محدّثة"] = df ["الطلب"]. مقطع (انخفاض = حد_أقصى ، أعلى = حد_ العالي)
طباعة (مدافع)

الذهاب ميلا إضافيا!

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

  1. نشر أول التوقعات مقابل الطلب التاريخي.
  2. حساب الخطأ ، يعني الخطأ والانحراف المعياري للخطأ
  3. حساب العتبات الدنيا والعليا المقبولة (بناءً على متوسط ​​الخطأ والانحراف المعياري).
  4. تحديد القيم المتطرفة تماما كما هو موضح سابقا.
  5. أعد حساب متوسط ​​الخطأ والانحراف المعياري ولكن باستثناء القيم المتطرفة.
  6. حدّث الحدود الدنيا والعليا المقبولة بناءً على هذه القيم الجديدة.
  7. قم بتحديث القيم الخارجية بناءً على العتبة الجديدة.

إذا استرجعنا مثالنا الموسمي من الأعلى ، فكان لدينا في البداية خطأ متوسط ​​خطأ قدره 0.4 وانحراف معياري قدره 3.22. إذا أزلنا النقطة Y2 M11 ، فسنحصل على خطأ يعني -0.1 وانحراف معياري قدره 2.3. هذا يعني أن العتبات الآن هي -5.3،5.2 حول التوقعات. عندئذٍ سيتم تحديث بياناتنا الخارجية في Y2 M11 إلى 10 (بدلاً من 12 باستخدام أسلوبنا السابق).

افعلها بنفسك
سنسترجع الشفرة من فكرتنا السابقة ونضيف خطوة جديدة لتحديث قيم الخطأ وقيم الانحراف المعياري.

df ["Error"] = df ["Forecast"] - df ["Demand"]
m = df ["خطأ"]. mean ()
s = df ["Error"]. std ()
من استيراد scipy.stats القاعدة
prob = norm.cdf (df ["Error"]، m، s)
القيم المتطرفة = (prob> 0.99) | (prob <0.01)
m2 = df ["خطأ"] [~ القيم المتطرفة] .mean ()
s2 = df ["خطأ"] [~ القيم المتطرفة] .std ()
limit_high = norm.ppf (0.99 ، m2 ، s2) + df ["التنبؤ"]
limit_low = norm.ppf (0.01 ، m2 ، s2) + df ["التنبؤ"]
df ["محدّثة"] = df ["الطلب"]. مقطع (انخفاض = حد_أقصى ، أعلى = حد_ العالي)
طباعة (مدافع)

عن المؤلف

نيكولاس فانديبوت هو عالم بيانات سلسلة التوريد متخصص في التنبؤ بالطلب وتحسين المخزون.
في عام 2016 ، أسس SupChains (www.supchains.com) ، شركته الاستشارية ؛ بعد ذلك بعامين ، شارك في تأسيس SKU Science (www.skuscience.com) ، وهي منصة ذكية على الإنترنت لإدارة سلسلة التوريد.
إذا كنت مهتمًا بالتنبؤ والتعلم الآلي ، فيمكنك شراء كتابه "Science Science for Supply Chain Forecast"