حول المشروع (شرح علمي تفصيلي)

هذه الصفحة تُوثّق الفكرة العلمية للنظام وتحويله من MATLAB إلى نظام ويب، وتشرح بالتفصيل آلية عمل خدمات الحساب (ANFIS/XAI) مع المراجع.

توثيق

0) الفكرة العلمية للمشروع

ANFIS + XAI

يبني المشروع نظاماً لتقدير كلفة صيانة الطرق اعتماداً على نموذج ANFIS (Adaptive Neuro-Fuzzy Inference System) من نوع Sugeno FIS، ثم يضيف طبقة تفسير (XAI) لتوضيح “لماذا” أعطى النموذج هذه النتيجة، وليس فقط “كم” هي الكلفة.

المخرجات الكلفة (IQD) + تصنيف Gauge + Bar Chart + تفسير نصّي
الهدف البحثي توثيق تحويل نموذج MATLAB إلى نظام ويب قابل للاستخدام

نموذج ANFIS قُدّم أساساً بواسطة Jang (1993) كنظام يدمج الشبكات العصبية مع منطق ضبابي (FIS) باستخدام تعلم هجين (Hybrid Learning) لبناء mapping بين المدخلات والمخرجات انطلاقاً من بيانات تدريب وقواعد if-then. أمّا Sugeno FIS فهو مناسب للنمذجة لأنه ينتج مخرجات على شكل دوال (غالباً خطية) في consequents مما يدعم interpolation داخل فضاء المدخلات.

مراجع أساسية
  • • ورقة ANFIS الأصلية (Jang 1993). PDF
  • • توثيق Sugeno FIS في MathWorks. MathWorks

1) شرح HTS Service بالتفصيل

HTS

في هذا المشروع، HTS ليس اسماً لمعيار عالمي جاهز، بل هو “Proxy” هندسي (مؤشر بديل) لشدة الظروف الحرارية عبر الزمن. الفكرة: نجمع عدد الأيام شديدة الحرارة (فوق 40°C) خلال نافذة زمنية تمثل عمر الرصف قبل تاريخ الصيانة. كلما زاد التعرض الحراري عبر السنوات، زادت احتمالية تدهور خصائص الأسفلت (مثل التخدد rutting والتشوه).

تعريف المدخلات والمنطق
  • • pavementAgeCode: كود عمر الرصف (1/2/3).
  • • maintenanceDate: تاريخ الصيانة (نستخرج منه سنة الصيانة).
  • • HeatDay table: مخزن سنوي days_above_40.
Mapping لعمر الرصف
كود 1 6 سنوات
كود 2 12 سنة
كود 3 18 سنة
المعادلة المطابقة للكود

نحسب سنة البداية startYear ثم نجمع days_above_40 من (startYear + 1) إلى maintenanceYear:

startYear = maintenanceYear - yearsSpan

HTS = Σ_{y = startYear + 1 إلى maintenanceYear}  days_above_40(y)
        

هذا يعادل منطق Laravel: whereBetween(year, [startYear+1, maintenanceYear]) ثم sum(days_above_40).

لماذا اخترنا 40°C؟ (مبرر علمي)

لأن مصادر بحثية تشير إلى أنه عند تجاوز الحرارة المحيطة 40°C قد تصل حرارة سطح الرصف إلى نطاق 65–75°C، وهذا يرفع مخاطر التخدد (rutting) والتشوه وانخفاض قدرة التحمل. لذلك “عدد الأيام فوق 40” يعد مؤشراً مبسطاً لكن ذا معنى لشدة التعرض الحراري عبر الزمن، خصوصاً لمناخ العراق/كربلاء.

  • • مرجع يذكر نطاق 65–75°C عند >40°C ambient وارتباطه بالـ rutting. MDPI (2025)
  • • وصف evalfis/منطق تقييم FIS (يهمنا لأن HTS يدخل لاحقاً للـ ANFIS). MathWorks evalfis

تنويه بحثي: HTS هنا Proxy مدروس وليس “اسم معيار عالمي”. الهدف: تمثيل شدة المناخ بحرارة/زمن بشكل رقمي قابل للإدخال للنموذج.

2) شرح AnfisService (حساب الكلفة) بالتفصيل العلمي

ANFIS

هذه الخدمة هي قلب المشروع: تنفّذ نفس pipeline الذي كان موجوداً في MATLAB. الفكرة الأساسية: (1) نُجري تحويلات على المدخلات (Log + Normalization) لتصبح مناسبة للنموذج، (2) نقيّم نظام Sugeno FIS (evalfis concept) لإنتاج yNorm، (3) نرجع yNorm إلى نطاقه الأصلي (Reverse normalization) ثم نُطبّق inverse log لإخراج الكلفة بالدينار.

2.1) Log Transform: log10(x + 1)

نستخدم log10(x + 1) لتقليل تشتت القيم الكبيرة وتقريب التوزيع (تقليل skew) ولتحسين الاستقرار العددي قبل التطبيع والتقييم داخل النموذج. هذا شائع عندما تكون قيم المدخلات واسعة المدى.

x_log = log10(x + 1)
        

ملاحظة تنفيذية: الدالة log10_safe تحمي من قيم سالبة غير متوقعة حتى لا يتعطل التنفيذ.

2.2) Normalization: mapminmax (Apply) باستخدام PS_in

بعد log، نطبّق تطبيعاً مطابقاً لإعدادات MATLAB (PS_in). في MATLAB، mapminmax يستطيع أن يعيد Process Settings (PS) ويُعاد استخدام نفس PS لاحقاً لتطبيع بيانات جديدة بنفس الطريقة، وهذا يضمن أن بيئة PHP تطبّق نفس التحويلات تماماً.

  • • PS_in.gain / xoffset / ymin / yrange تُستخدم لتحويل كل عنصر إلى النطاق المُستهدف.
  • • أنت خزّنت هذه القيم في config(anfis.ps_in.*) لضمان الثبات.
مرجع

توثيق mapminmax في MathWorks يوضح فكرة تطبيع البيانات وإرجاع إعدادات PS لإعادة الاستخدام. MathWorks mapminmax

2.3) Sugeno FIS Evaluation (evalfis concept)

هنا يتم تقييم نظام Sugeno FIS: تُحسب درجات الانتماء (membership) لكل قاعدة، ثم firing strengths (قوة تفعيل القواعد) وفق عامل AND (مثل prod)، ثم تُحسب مخرجات consequents (غالباً خطية)، وبعدها تُجمع بطريقة Sugeno لإنتاج yNorm. هذا مكافئ لمفهوم evalfis في MATLAB.

نوع النظام Sugeno (Type-1)
المنطق evalfis
  • • توثيق Sugeno FIS. MathWorks sugfis
  • • توثيق evalfis (تقييم FIS وإرجاع نتائج) - نستخدمه كمفهوم مرجعي. MathWorks evalfis
2.4) Reverse Output Normalization + Inverse Log

بعد yNorm، نرجع الخرج إلى نطاقه الحقيقي باستخدام PS_out (Reverse mapminmax)، فينتج outLog. ثم نطبّق inverse log للحصول على الكلفة النهائية:

outLog = reverse_mapminmax(yNorm, PS_out)

cost = (10 ^ outLog) - 1
        

بهذا أنت فعلياً أنجزت: Log → mapminmax → Sugeno eval → reverse mapminmax → inverse log، وهي سلسلة مطابقة للـ MATLAB.

2.5) لماذا هذا مهم بحثياً؟ (مبدأ التكرارية Reproducibility)

القيمة البحثية هنا أنك لم “تعِد تدريب” النموذج في الويب، بل نقلت (conversion) نموذجاً مدرباً من MATLAB إلى PHP، مع الحفاظ على نفس التحويلات والمعلمات (fis + PS settings). هذا يجعل المقارنة MATLAB vs PHP ممكنة بدقة.

مرجع أساس: ANFIS

Jang (1993) يشرح معمارية ANFIS والتعلم الهجين وبناء mapping من بيانات التدريب. Jang 1993 PDF

3) شرح CostGaugeService بالتفصيل العلمي

Gauge

بعد الحصول على الكلفة الكلية (Total Cost)، نحتاج إلى تصنيفها بطريقة عادلة قابلة للمقارنة بين مشاريع مختلفة المساحات. لذلك استخدمنا مؤشر A = Cost per m² (كلفة لكل متر مربع). هذا أسلوب شائع كـ normalization أو parametric indicator حتى تكون المقارنات معقولة.

المعادلة الأساسية
A = TotalCost / Area   (IQD per m²)
        

الخدمة تتحقق أولاً أن المساحة > 0 ثم تحسب A وتطابقها مع ranges موجودة في config(cost_gauge.ranges).

منطق التصنيف (Ranges)
  • • إذا A ضمن [min, max) نختار هذا الرينج.
  • • إذا A أقل من أول رينج → أول رينج.
  • • إذا A أعلى من آخر رينج → آخر رينج.
  • • النتيجة ترجع label_key + label + range_used + كل ranges حتى ترسم Gauge.
مرجع للفكرة (Cost per m²)

مفهوم كلفة لكل متر مربع/وحدة مساحة يستخدم في تقديرات البناء/المشاريع كمعيار parametric للتطبيع والمقارنة. RAIC CHOP (Cost Planning)

4) شرح SensitivityService بالتفصيل (OAT + Perturbation)

XAI

هذه الخدمة تُخرج “نسبة تأثير” لكل من 7 مدخلات (مختارة من أصل 13). المنهج المتّبع هو One-At-a-Time (OAT): نغيّر عامل واحد فقط كل مرة ونراقب تغيّر خرج النموذج. هذه طريقة حساسية محلية (local) وبسيطة وواضحة للمستخدم.

الخطوات الحسابية كما في الكود
1) Base cost:
   C0 = f(x)

2) For each feature i:
   - If continuous: test (xi - 10%) and (xi + 10%)
   - If categorical: test all allowed values (except current)

3) Max absolute impact:
   Δi = max | f(x_test) - C0 |

4) Impact percentage:
   Impact%i = (Δi / C0) * 100

5) Sort descending -> bar chart + top influencers
        

بالنهاية نرتّب النتائج تنازلياً حسب impact_percent ونأخذ أعلى top_n حتى ندعم تفسير ExplanationService.

لماذا OAT عملياً؟
  • • واضح للمستخدم النهائي: “غيّرت هذا العامل فقط فصار الفرق كذا”.
  • • سريع وقابل للتطبيق بدون تدريب جديد.
  • • مناسب كتفسير محلي Instance-based (لكل مشروع).
حدود الطريقة (Limitations)
  • • قد لا تلتقط تداخلات العوامل (feature interactions) لأننا نغيّر عامل واحد فقط.
  • • تعتمد على حجم perturbation (مثلاً ±10%).

هذه الحدود معروفة علمياً في تحليل الحساسية، لكنها تبقى مقبولة جداً للشرح والتفسير المحلي داخل نظام ويب.

مراجع علمية للفكرة

5) شرح ExplanationService بالتفصيل (Rule/Template-based NLG)

NLG

هذه الخدمة هي طبقة “اللغة” فوق الأرقام: تحوّل نتائج الحساب إلى تفسير مفهوم ومهني. علمياً هذا يسمى Data-to-Text / Natural Language Generation (NLG). طريقتك هنا Rule/Template-based: تستخدم قوالب جاهزة + قواعد اختيار الأسباب حسب أعلى المؤثرات.

5.1) المدخلات التي تعتمد عليها الخدمة
  • • Gauge: التصنيف + قيمة A (كلفة/م²).
  • • Sensitivity: top_influencers + debug_payload (اتجاه التأثير، delta...).
  • • inputsAssoc: القيم الحالية للمدخلات حتى نشرح “الحالة الحالية”.
5.2) قواعد اختيار الأسباب (Reason Selection Rules)
- min_influence_pct: أقل نسبة تأثير لقبول السبب
- max_reasons: الحد الأعلى لعدد الأسباب
- نمر على top_influencers:
    إذا pct >= minPct -> نولد سبب (AR + EN)
- إذا ماكو أسباب قوية -> fallback sentence
        

الخدمة أيضاً تُحدد اتجاه التأثير (increase/decrease/neutral) بالاعتماد على delta = cost_after_change - base_cost، وتستخدم ذلك لصياغة جملة هندسية توضح هل القيمة الحالية أقل/أعلى كلفة من بدائلها ضمن نطاق الاختبار.

5.3) لماذا Template-based NLG اختيار منطقي؟
  • • ثبات الصياغة الرسمية (مناسب للأكاديميا والتقارير).
  • • قابل للتدقيق: نعرف بالضبط من أين جاءت كل جملة (debug payload).
  • • قابل للصيانة: تغيير قالب أو قاعدة أسهل من تدريب نموذج لغوي.
  • • يدعم لغتين بسهولة (AR/EN).
مراجع NLG
  • • تعريف NLG (تحويل بيانات إلى نص). IBM (NLG)
  • • ورقة عن Template-Based NLG وتطبيقه. IAENG PDF
  • • نقاش علمي حول قيمة Template-based NLG (ليس بالضرورة أدنى). van Deemter et al. PDF

Implementation & System Conversion (فصل التحويل من MATLAB إلى Web)

فصل بحثي
A) معمارية النظام (Architecture)
  • • UI Layer: صفحات إدخال/نتائج/تقارير + مخططات Plotly.
  • • Service Layer: HtsService, AnfisService, CostGaugeService, SensitivityService, ExplanationService.
  • • Data Layer: Projects/Calculations + HeatDay (HTS) + configs للـ PS settings.
  • • Report Layer: توليد PDF (ملخص + أسباب + مخططات).
B) مخطط تدفق البيانات (Data Flow)
User Inputs
   ↓
(1) HTS  ← HeatDay(year → days_above_40)
   ↓
Build ordered13 (V1..V13)
   ↓
(2) ANFIS predictCost → TotalCost
   ↓
(3) Gauge A = TotalCost/Area → label/range
   ↓
(4) Sensitivity OAT → impact% + top influencers
   ↓
(5) Explanation NLG → summary + reasons
   ↓
UI Charts + PDF Report
          
C) Training Metrics (ضمن MATLAB)

هنا توثّق ما تم في MATLAB أثناء التدريب: نوع البيانات، عدد العينات، تقسيم Train/Validation، واختيار membership functions، وعدد القواعد، وخطأ التدريب (MSE/RMSE) على التدريب.

ملاحظة: تدريب ANFIS يتم وفق ما يشرحه Jang 1993 (Hybrid learning).

D) Testing Metrics (MATLAB vs PHP)
  • • نفس 13 مدخل تُمرّر إلى MATLAB وPHP.
  • • مقارنة output النهائي (Cost) بعد inverse log.
  • • حساب فرق مطلق/نسبي: |PHP − MATLAB| و %Error.
E) HTS Validation

توثيق صحة HTS يكون بإظهار: (1) مثال تاريخ صيانة، (2) startYear حسب الكود، (3) السنوات المشمولة، (4) مجموع days_above_40، مع لقطة من جدول HeatDay أو query output.

F) Console Outputs Screenshots

ضمن التقرير، سنضع Screenshots لأوامر CLI التي نفذتها لاختبار الخدمات (مثل anfis:test-gauge وغيرها) ولنوضح أن النتائج ثابتة مع نفس المدخلات.

G) شرح Cost Gauge Logic

أثبت أن التصنيف يعتمد على A (Cost/m²) وليس فقط TotalCost، واذكر رينجات الكونفگ ولماذا تم اختيارها (حسب سياق الدراسة/المشروع).

H) مقارنة MATLAB vs PHP خطوة بخطوة
  • • Log: نفس المعادلة log10(x+1).
  • • PS_in: نفس gain/xoffset/ymin/yrange.
  • • fis: نفس ملف الـ .fis (Sugeno rules).
  • • PS_out: نفس reverse normalization.
  • • Inverse log: (10^outLog) - 1.
مراجع عامة للتحويل/النشر كويب

هذه المراجع ليست “تحويلك أنت”، لكنها أمثلة رسمية على مفهوم نشر/استضافة تطبيقات MATLAB كويب، وتفيد كفكرة عامة في فصل التحويل. MathWorks Web App Server

Example Walkthrough (مثال واحد خطوة بخطوة)

مثال

هذا مثال واحد يوضح مرور البيانات عبر الخدمات الخمس: HTS → ANFIS → Gauge → Sensitivity → Explanation. الأرقام هنا لشرح المنطق، أما قيمة ANFIS الدقيقة فتتحدد بحسب PS settings وملف الـ FIS .

0) مدخلات المثال

نفترض مشروع صيانة لطريق في كربلاء بتاريخ صيانة محدد ومساحة معقولة، مع كود عمر رصف متوسط. الهدف هو توضيح كيف تنتقل القيم داخل النظام.

تاريخ الصيانة 2024-06-15
كود عمر الرصف 2 (متوسط)
مساحة الصيانة (م²) 12,000
المحافظة/الطريق (وصف) كربلاء — طريق رئيسي (مثال)
1) حساب HTS (مثال رقمي)
HTS

بما أن كود عمر الرصف = 2، إذن نافذة السنوات = 12 سنة. سنة الصيانة = 2024.

yearsSpan = 12
maintenanceYear = 2024
startYear = 2024 - 12 = 2012

HTS = sum(days_above_40) from (2013 .. 2024)
    

نفترض أن مجموع الأيام فوق 40°C من 2013 إلى 2024 حسب جدول HeatDay يساوي: 980 يوم.

HTS 980

هذا الرقم يدخل لاحقاً كواحد من مدخلات نموذج ANFIS (ضمن ordered13) حسب الترتيب .

2) حساب الكلفة بـ ANFIS (مثال توضيحي للـ Pipeline)
ANFIS

ندخل 13 قيمة مرتبة ordered13 (V1..V13). سنعرض مثالاً مبسطاً لثلاث قيم فقط لشرح التحويلات، ثم نوضح كيف تُستنتج الكلفة.

مثال (3 مدخلات من أصل 13) لتوضيح التحويل
Assume three raw inputs (subset):
V3 (Area) = 12000
V7 (HTS)  = 980
V9 (Traffic) = 2   (categorical code as numeric)

Step A) log10(x+1):
log10(12000+1) ≈ 4.079
log10(980+1)   ≈ 2.992
log10(2+1)     ≈ 0.477

Step B) mapminmax apply (0..1):
xNorm = applyVector(xLog, PS_in)   // exact values depend on PS_in in your config

Step C) Sugeno eval:
yNorm = evaluateSugeno(xNorm)      // depends on FIS (.fis rules & parameters)

Step D) reverse output normalization:
outLog = reverseScalar(yNorm, PS_out)

Step E) inverse log:
cost = (10^outLog) - 1
      

الأرقام الدقيقة لـ xNorm/yNorm/outLog تعتمد على PS_in/PS_out وملف الـ FIS لديك، لذلك هذا مثال توضيحي للمنهج وليس رقمك النهائي.

لإكمال المثال end-to-end سنفترض أن ANFIS أعطى الكلفة الكلية التالية لهذا المشروع: 540,000,000 دينار.

Total Cost (افتراضي للمثال) 540,000,000
3) Gauge: حساب A وتصنيف الكلفة (مثال رقمي)
Gauge

نحسب A = TotalCost / Area حتى نقارن بين المشاريع بشكل عادل.

A = 540,000,000 / 12,000
  = 45,000  IQD/m²
    
A (IQD/m²) 45,000

بعدها الخدمة تطابق A مع ranges الموجودة في config(cost_gauge.ranges) لتحديد (واطئة/متوسطة/عالية...) ولون الرينج.

4) Sensitivity: نسبة التأثير للـ 7 مدخلات (مثال مبسط)
XAI

هنا سنعرض مثالين صغيرين داخل نفس المثال: عامل continuous (±10%) وعامل categorical (تجربة قيم). الفكرة: نأخذ أكبر فرق ونحوّله إلى نسبة.

مثال (Continuous): المساحة Area ±10%

BaseCost = 540,000,000. نختبر Area=10,800 و Area=13,200 ونقيس الفرق.

Base cost C0 = 540,000,000

Test low  (Area -10%): newCost = 575,000,000   → diff = 35,000,000
Test high (Area +10%): newCost = 510,000,000   → diff = 30,000,000

Δ = max(diff) = 35,000,000
Impact% = (Δ / C0) * 100
        = (35,000,000 / 540,000,000) * 100
        ≈ 6.48%
        
Impact% 6.48%
مثال (Categorical): نوع الطريق Road Type

نفترض RoadType الحالي = 2. نجرب القيم [1,3] ونختار أكبر فرق.

Base cost C0 = 540,000,000
Current RoadType = 2

Test RoadType = 1 → newCost = 520,000,000 → diff = 20,000,000
Test RoadType = 3 → newCost = 610,000,000 → diff = 70,000,000

Δ = 70,000,000
Impact% = (70,000,000 / 540,000,000) * 100
        ≈ 12.96%
        
Impact% 12.96%

هذه الأرقام مثال لشرح الحساب. داخل النظام الحقيقي، newCost يأتي من predictCost بعد تعديل قيمة العامل.

5) Explanation: كيف تولّدت الجمل؟ (مثال نصّي واحد)
NLG

نفترض أن الـ Gauge صنّف الحالة “متوسطة” وأن أعلى مؤثرين هما RoadType (≈12.96%) وArea (≈6.48%). هنا يظهر كيف تتحول هذه النتائج إلى Summary + Reasons وفق قوالب ثابتة واتجاه التأثير.

Summary (AR)

التكلفة التقديرية ضمن مستوى (متوسطة)، وقيمة المؤشر A ≈ 45,000 دينار/م². الكلفة الكلية المقدّرة ≈ 540,000,000 دينار. بشكل عام، هذا التصنيف يتوافق مع تأثير خصائص الطريق والأحمال والبيئة على عمق التدخل المطلوب.

Summary (EN)

Reasons (مختصر مثال)
• (Road Type) — approx. impact 12.96%.
  Changing this factor increased the cost compared to the current state.
  (Δ ≈ 70,000,000 IQD).

• (Area) — approx. impact 6.48%.
  Changing this factor affected the cost within the tested ±10% range.
  (Δ ≈ 35,000,000 IQD).
      

لاحظ أن صياغة الجمل تأتي من: (1) label العامل من الكونفگ، (2) impact% من Sensitivity، (3) direction من debug_payload، ثم قالب Template ثابت.