
حقق خط الأساس الساذج في كاشف السقوط الراداري استرجاع 1.0 نفسه، لكنه أطلق سبعة إنذارات كاذبة في ليلة واحدة.
في نوبة الليل الاصطناعية التي بنيتها لنظام Vigil، يطلق خط الأساس الجاهز تسعة تنبيهات بين الساعة 02:00 و06:00، وسبعة منها خاطئة. مروحة سقف تم رصدها عند ذروة سرعة بلغت 5.0 م/ث. كلب علاج بمقطع راداري عرضي 0.27. نزيل يجلس بقوة على مقعد بسرعة 2.92 م/ث. اثنان من تلك التنبيهات التسعة يمثلان سقوطًا حقيقيًا، وأحدهما في حمام: مسار نقطة مركزية ينحدر من 1.53 م في وضع الوقوف نزولاً عبر 1.07، و0.84، و0.625، و0.344 قبل أن يستقر عند 0.119 م، أي على مستوى الأرضية، مع وجود تنفس، ودون أي نهوض.
كل حدث في تلك النوبة اصطناعي، وموسوم، ومؤصَّل فيزيائيًا، وتم توليده من بذرة أولية ثابتة، وأنا من كتب كلا الكاشفين. ولهذا السبب أستطيع قول الجزء غير المريح بوضوح: لقد رصد خط الأساس سقوط الحمام ذلك أيضًا.
إن Vigil هو طبقة الذكاء التي بنيتها لتتوسط بين دفق خصائص الرادار ونظام استدعاء التمريض في دور رعاية كبار السن. وهو يُرجع ALERT (تنبيه) أو SUPPRESS (كبح) أو ROUTE TO HUMAN (توجيه إلى إنسان)، مع إرفاق سبب لكل قرار يمكن للمنشأة حفظه في ملفاتها. ومسار العرض التوضيحي هو https://veriprajna.com/demos/smart-facility-fall-detection. بدأت عملية البناء على افتراض أن الجزء الصعب يكمن في رصد السقوط. لكن المعيار خالفني الرأي منذ أول تشغيل له.
كان الاسترجاع هو الرقم الذي أردت أن أبدأ به
قمت بتشغيل المعيار متوقعًا أن تكون حساسية كشف السقوط هي العنوان الرئيسي، وهو رقم جيد: استرجاع بمقدار 1.0 للنظام المتتابع عبر مجموعة ثابتة من 360 حدثًا اصطناعيًا موسومًا ومحملًا بالضوضاء. العمود المجاور له هو ما غيّر المقال الذي كنت أظن أنني أكتبه. يتكون خط الأساس الساذج من بندين حسابيين، فأي حركة سريعة أو منخفضة تُعد سقوطًا (peak_v > 2.0 OR min_cz < 0.45)، وعلى المجموعة نفسها يحقق أيضًا استرجاعًا قدره 1.0. الحساسية هي الميدان الذي يرتع فيه تسويق كشف السقوط، وكلا الكاشفين مثبتان في قمته.
الفارق الحقيقي يكمن بالكامل في الصف الذي لا يضعه أحد في شريحة عرض. تبلغ نوعية العوامل المربكة 1.0 للنظام المتتابع و0.167 لخط الأساس، وهو معدل إنذارات كاذبة يبلغ 0.833 لكل حدث حميد. وبإسقاط ذلك على مشغلات الحركة الحميدة البالغة 30 مشغلًا لكل غرفة يوميًا كما يفترض المعيار، يصل خط الأساس إلى 25.0 إنذارًا كاذبًا لكل غرفة في اليوم الواحد. ويتراوح المعدل المنشور للأنظمة الحالية من أجهزة الاستشعار الجاهزة بين 5 و15 إنذارًا كاذبًا لكل غرفة يوميًا، ويُعد إجهاد الإنذارات، وليس حساسية المستشعر، السبب الرئيسي الموثق لفشل مشاريع النشر هذه.
ينبغي أن أقول هذا قبل أن يسبقني إليه قارئ تقني. أوزان الدمج في data/fall_model.json تمت ملاءمتها بواسطة tools/fit_fall_classifier.py على مولدات السيناريوهات الخاصة بالعرض التوضيحي نفسه، وهي نفس المولدات التي أنتجت مجموعة الأحداث البالغ عددها 360 حدثًا. هذا أقوى اعتراض يمكن لأي شخص إثارته ضد نتيجتي 1.0 اللتين حققتهما، وهو أيضًا السبب في أنني أهتم بالرقم 0.167 أكثر من اهتمامي بأي منهما. ففشل خط الأساس ليس أثرًا جانبيًا مصطنعًا لإعداد التدريب لدي؛ بل هو ما يفعله الحد الحرج عندما يحتوي العالم على مراوح سقف.
الإنذارات الكاذبة السبعة هي التي تقرر ما إذا كان هناك من لا يزال يستمع عند وصول الإنذار الحقيقي.
صُممت العوامل المربكة لإسقاط أي خاصية منفردة
كانت غريزتي الأولى تتجه نحو تحسين المصنف، وكانت غريزة خاطئة. أمضيت الجزء الأول من التطوير في التعامل مع هذا كمسألة تمييز: إيجاد الخاصية التي تفصل بين السقوط وغير السقوط، وإعطاؤها وزنًا ثقيلاً، ثم المضي قدمًا. لكن مولدات السيناريوهات التي كنت قد كتبتها بالفعل جعلت ذلك مستحيلاً عن عمد.
تم توليد كل عامل مربك لكي يتطابق جزئيًا مع سقوط حقيقي في خاصية فردية ما. فالجلوس العنيف عند الكاميرا Cam 5 يحمل دفقة سرعة تبلغ 2.92 م/ث، وهو ما يماثل مقدار السقوط، ويستقر عند 0.46 م. ونظيره في الحمام عند الكاميرا Cam 10 يبلغ ذروته عند 3.31 م/ث ويستقر عند 0.44 م. وكلب العلاج والانحناء لالتقاط منشفة كلاهما يخفضان النقطة المركزية، وهو النصف الآخر من قاعدة خط الأساس. وأي اختبار فردي كان بإمكاني كتابته تم إفشاله بحكم التصميم، ولهذا السبب تم خداع خط الأساس حقيقة بنسبة 0.167 بدلاً من أن يُخدع بفخ مصطنع صممته ليخسر.
كانت السرعة هي الخاصية التي كنت الأكثر ثقة بشأنها، وهي الخاصية التي لم تنجُ للدخول في المصنف. ما نجا هو نموذج لوجستي يعتمد على أربع خصائص: القرب من الأرضية، وطاقة الارتطام، وهبوط النزول، ومؤشر بديل للمقطع الراداري العرضي، مدمجة في احتمال سقوط P(fall) معاير. لا يوجد أي حد للسرعة يصل إلى P(fall) على الإطلاق. ولا يزال هناك سطر قديم مهمل في توثيق الوحدة (docstring) يعود إلى الوقت الذي اعتقدت فيه أنها ستدخل. إنه كود numpy بسيط، وصغير بما يكفي ليفتحه أي شخص في classifier.py ويستوعب المنظومة بأكملها في ذهنه، وهو أمر يساوي بالنسبة لي في مسار الحفاظ على الحياة أكثر من كسب نقطة إضافية في مقياس AUC.
أعرض كبح الكاميرا Cam 10 أمام الناس أولاً، لأن اللوحة توضح الخلاف بأكمله في سطر واحد.

أربعة شروط، ونافذة واحدة مدتها 8 ثوانٍ
كتبتُ أداة التحقق السردي الزمني بصفتها العنصر الذي أود قراءته لو كنت طرفًا خارجيًا. temporal.py يتطلب أربعة شروط داخل نفس النافذة البالغة 8 ثوانٍ، مع تأكيد حالة الوقوف في الخُمس الأول منها: متوسط النقطة المركزية أعلى من 1.2 م، وهبوط يزيد عن 0.6 م إلى جانب سرعة قصوى أعلى من 1.8 م/ث في مكان ما داخل النافذة، وارتطام عريض النطاق مستدام يتجاوز متوسطه المتحرك عبر 3 إطارات 0.50، ووصول النقطة المركزية فعليًا إلى ما دون 0.30 م. يوجد اختبار الارتطام المستدام لأن الارتفاع الحاد في إطار واحد سهل الحدوث وعارض، بينما ارتطام الجسد بالأرض ليس كذلك.
تنص سلسلة السبب التي يُصدرها التطبيق على "وقوف → هبوط → ارتطام → أرضية"، وهي الطريقة التي تقرأ بها الممرضة أي حادث، لكن التنفيذ البرمجي يربط تلك الشروط بمعامل AND المنطقي عبر النافذة بدلاً من فرض تسلسل زمني صارم. إنها ليست آلة حالات (state machine)، وأفضّل أن أكتب ذلك بنفسي على أن يكتشفه مهندس في الكود المصدري ويتساءل عن التفاصيل الأخرى التي أهملتها الصياغة.
عندئذٍ فقط تضيف البوابة تأكيد التنفس بما يتجاوز 0.20 ومستوى ثقة في السقوط لا يقل عن 0.70. هذه القيم الثلاث: مستوى الأرضية 0.30 م، والتنفس 0.20، والحد الأدنى للثقة 0.70، تعيش في كود برمجي صريح خارج كل النماذج. الاتجاه هو ما يهم: يجب أن تتحقق الشروط الحتمية قبل الرجوع إلى درجة النموذج إطلاقًا، بحيث لا يمكن لرقم الثقة أن يختلق تنبيهًا بمفرده أبدًا. ولا يزال بإمكان انخفاض P(fall) تحويل ALERT (تنبيه) إلى SUPPRESS (كبح)، وهو التفاوت الصحيح لطبقة يُسمح لها بالبقاء صامتة ولا يُسمح لها بالاختلاق. ويوجد حد حاسم إضافي يقبع خارج تلك الكتلة الموثقة، وهو قيمة مبرمجة ثابتة p_fall >= 0.40 في gate.py يمكنها إرسال حدث متعدد الأشخاص للمراجعة البشرية بناءً على درجة النموذج وحدها. أذكر ذلك صراحة لأن عبارة "ثلاثة حدود موثقة" ستبدو بخلاف ذلك وكأنها تدعي دقة أكثر مما تستحق.
حالات الكبح هي السجل الذي تطلبه لجان التفتيش الرسمية في الواقع
بنيتُ سجل القرارات (Decision Ledger) قبل أن أبني أي شيء يشبه المنتج، لأن السؤال الذي لم أكن قادرًا على الإجابة عليه لم يكن قط "هل التقطت السقوط؟". بل كان "لماذا لم ينطلق تنبيه في الغرفة 203 عند الساعة 2:13؟"، ويجب أن تكون الإجابة موجودة بالفعل في سجل مكتوب قبل أن يسأل عنها أحد. عشرة من الأحداث الاثني عشر في تلك النوبة هي قرارات كبح، ويحمل كل منها قيمة الخاصية المسجلة ضده: الهدف غير البشري في الكاميرا Cam 6 بمقطع راداري عرضي 0.27 مقابل حد أدنى بشري قدره 0.55، وانحناءات الكاميرا Cam 7 والكاميرا Cam 12 حيث تتوقف النقطة المركزية عند 0.60 م و0.59 م مع طاقة ارتطام 0.07 مقابل عتبة 0.50.

تلك الصفوف المكبوحة العشرة هي ما يسأل عنه مفتش الولاية، لأنها تمثل الأحداث التي لم يقع فيها شيء ومع ذلك يتعين على شخص ما توضيح السبب.
جزء فقط من المعايرة المخصصة لكل غرفة متصل فعليًا باتخاذ القرار. يتم كبح مروحة السقف في الكاميرا Cam 1 لأن خريطة التشويش في الغرفة 214 تتضمن قيد دوبلر ثابت الموقع عند (1.5، 1.5، 2.45 م) وcheck_clutter يحجبها عند ذلك الفوكسل. هذا المسار حقيقي. أما ارتفاعات المقاعد والأسرة لكل غرفة في rooms.json، وهي 0.42 م في حمام الغرفة 118 و0.45 م في الغرفة 203، مع قيود قضبان الإمساك بجانبها، فهي بيانات معايرة لا يقرؤها أي مسار كود في V1؛ فنطاق المقعد الذي أستخدمه لتصنيف الجلوس العنيف هو اختبار عام موحد بين 0.38 و0.60 م. بل يوجد long_lie_sec: 180.0 كمفتاح في ذلك الملف لا يستهلكه أي جزء من الكود. إن المعايرة المخصصة لكل غرفة هي عمل التكامل الذي تتكبده عمليات النشر الواقعية، وفي هذا الإصدار وحدها أقنعة دوبلر متصلة باتخاذ القرار.
التصدير عبارة عن ملف JSON لتدقيق النوبة يغطي كل تنبيه وتوجيه وكبح مع قيم الخصائص الحاسمة وسبب السياسة المعتمد، وهو ما يتطلبه ملف الامتثال لـ CMS F689 أو برنامج QAPI. وتُصاغ ملاحظة الحادث السريري بشكل منفصل عن تلك الأدلة المهيكلة وتُعرض في لوحة الحادث، وليس داخل ملف JSON.
التنبيه الذي سمحتُ له بإطلاقه، والسقوط الذي رفضتُ السماح له بالجزم به
وضعتُ ذروة أحداث النوبة داخل الحمام عن قصد. فهو الغرفة الأعلى خطورة والمكان الوحيد الذي لا تشكل الكاميرا فيه خيارًا قابلاً للاستخدام: فقد سنت تسع عشرة ولاية أمريكية قوانين تنظم وضع الكاميرات في غرف دور رعاية المسنين، وتسمح بها عمومًا داخل غرفة النزيل بموافقته، بينما تظل الحمامات مستبعدة عمليًا لدواعي الخصوصية. وخصائص الرادار لا تحمل أي صور، ولهذا السبب تحديدًا يمكنها الوصول إلى حيث تعجز الكاميرات.
الكاميرا Cam 3 هي ذلك الحدث، ويُرجع Vigil ALERT، فئة long_lie، بمستوى ثقة 0.99، وزمن بقاء على الأرض 4.8 ثوانٍ، مع تجهيز سلم التصعيد عند مساعد التمريض المعتمد (CNA) فورًا، والممرض المسؤول (Charge Nurse) عند 90 ثانية، ومدير التمريض (DON) عند 180 ثانية. ويقرأ نص شارة استدعاء التمريض: "حمام الغرفة 118B: تم اكتشاف سقوط، ثقة 99%. النزيل على الأرض منذ 5 ثوانٍ. تم تأكيد التنفس.". ويبث نظام الإرسال إشارة اتصال جاف تقليدية من نوع Rauland وحمولة MQTT/REST متوافقة مع Ascom/Austco، وكلاهما يمر عبر محول صوري مُسجَّل. لا يوجد أي عتاد استدعاء تمريض متصل بأي من هذا. والسبب الذي يجعل بناءه جديرًا بالاهتمام على أي حال هو الاستلقاء الطويل: فنصف كبار السن الذين يظلون ممددين على الأرض لأكثر من ساعة يفارقون الحياة خلال ستة أشهر.

هناك رقم واحد في تلك اللوحة أرفض الترويج له تجاريًا. زمن الـ 7.0 ثوانٍ من الارتطام إلى التنبيه محسوب في gate.py كمؤقت احتجاز مضافًا إليه ثلاث ثوانٍ، وهو ثابت حسابي. يعرضه التطبيق، وسأنقل ما يعرضه، لكنه ناتج عملية حسابية وليس سرعة نظام مقاسة، وتسميته زمن انتقال معياري سيكون بمثابة كذبة صغيرة تكلفك الحقائق الكبرى الصادقة التي تقف إلى جانبها.
الحدث الذي أفتخر به أكثر هو الذي رفضه Vigil. فالكاميرا Cam 2 تمثل سقوطًا حقيقيًا في الواقع الفعلي (ground truth) ويصل P(fall) إلى 0.99، ومع ذلك لا يجزم Vigil بحدوثه: فالغرفة تضم هدفين، وتتبع الشخص المنفرد يقع خارج نطاق تغطية V1، وتُرجع البوابة ROUTE TO HUMAN at low confidence. يطلق خط الأساس الساذج تنبيهًا تلقائيًا ويحصد الفضل في رصد لم يستحقه. وقع حادثا سقوط حقيقيان في تلك النوبة؛ أطلق Vigil تنبيهًا لأحدهما وأرسل الآخر لفحص الطاقم، ولن أصف ذلك بأنه التقاط لكل سقوط، لأنه ليس كذلك. وعبر الاختبار المعياري بالكامل، يتم توجيه 40 من أصل 40 حالة سقوط متعددة الأشخاص إلى إنسان، دون أي تنبيهات مفرطة ودون تفويت أي حالة.
ما يُسمح للوحة النتائج بادعائه
سطر التنبيه الاحترازي أسفل نافذة نتائج النوبة (Shift Results) هو الجزء الذي صغته أولاً في تلك اللوحة. تذكر النافذة 0 إنذار كاذب لمحركنا مقابل 7 للنظام الحالي في هذه النوبة، مع رصد حالة سقوط حقيقي واحدة من أصل 2، وتوجيه حالة واحدة إلى إنسان، ونوعية عوامل مربكة بنسبة 100% عبر 360 حدثًا موسومًا، و0.0 مقابل 25 إنذارًا كاذبًا متوقعًا لكل غرفة يوميًا.

تصف هذه الأرقام مجموعة ذهبية اصطناعية ثابتة لا أكثر. إنها ليست دقة بيئة إنتاجية، وليست نتيجة سريرية، وليست ادعاءً طبيًا تم التحقق منه، وليست بأي حال ضمانًا لمنشأة رعاية. تستهدف التجربة الريادية الحقيقية أقل من إنذارين كاذبين لكل غرفة يوميًا بعد المعايرة في وضع الظل، وهذا هو الرقم الذي سأطرحه أمام مدير التمريض، لأنه الرقم الذي يمكن محاسبتي عليه. والرقم 0.0 دليل على أن الآلية تفصل حالات السقوط عن العوامل المربكة على مجموعة يمكنني تسليمها لك؛ وليس وعدًا بشأن مبنى لم أمشِ فيه قط.
المعيار الذي أُلزم به تنبيهات الحفاظ على الحياة الآن
خرجتُ من هذا المشروع بتعريف أكثر دقة وتحديدًا لما يجب أن يتقنه كشف السقوط. فالكشف مجرد حد عتبة، وحد العتبة يحقق بالفعل استرجاعًا قدره 1.0 على مجموعة الاختبار الخاصة بي. والجهد الذي يستحق انتباه الممرضة هو الرفض: خريطة التشويش التي تعرف أي فوكسل تشغله المروحة، واختبار الارتطام الذي لا يقبل إطارًا واحدًا فقط، وشرط الوصول للأرضية الذي يفصل الجلوس العنيف عن السقوط، وبوابة مصممة بحيث يستطيع مفتش الولاية، لا مجرد نموذج رياضي، قراءة الأسباب الكامنة وراء تصرف النظام.
الشرح التفصيلي الكامل متاح على https://veriprajna.com/demos/smart-facility-fall-detection، والصفوف العشرة المكبوحة في السجل هي حيث تتقرر نتائج النوبة فعليًا.
وإذا كنت تفضل مشاهدة النوبة بدلاً من قراءة وصفي لها، فإليك الليلة بأكملها وهي تعمل من البداية إلى النهاية.
النظام الذي ينطلق بإنذار بسبب مروحة سقف يتم كتم صوته في غضون أسبوع، والنظام المكتوم لا يكشف أي شيء على الإطلاق. كان السلوك الأكثر تطورًا الذي تمكنت من تقديمه لهذه الطبقة هو القدرة على الرفض، وتوثيق ذلك رسميًا، مع إرفاق الرقم الحاسم في اتخاذ القرار. وفي الكاميرا Cam 2 كان ذلك الرقم 0.99، ومع ذلك كان القرار الصحيح هو تحويل الحدث إلى مراجعة بشرية.


