تحليل السلاسل الزمنية لبيانات الآلات
ما هو تحليل السلاسل الزمنية؟
تخيّل أنك تراقب درجة حرارة فرن صناعي كل دقيقة على مدار أسبوع — ستحصل على آلاف القراءات المرتّبة زمنياً. هذه القراءات ليست مجرد أرقام عشوائية، بل تحمل أنماطاً مخفية: ارتفاع تدريجي بسبب تآكل العازل، تذبذب يومي بسبب دورات التشغيل والإيقاف، وضوضاء عشوائية من الحساسات.
السلسلة الزمنية (Time Series) هي سلسلة من نقاط البيانات المُقاسة عند فترات زمنية منتظمة. تحليلها يعني فهم ماضي النظام والتنبؤ بمستقبله — وهذا جوهر الصيانة التنبؤية والتخطيط الصناعي.
مكوّنات السلسلة الزمنية
كل سلسلة زمنية يمكن تفكيكها إلى ثلاثة مكوّنات أساسية:
الاتجاه العام (Trend)
هو التغيّر طويل المدى في البيانات — هل القيم ترتفع أم تنخفض أم تبقى ثابتة على مدار أشهر أو سنوات؟
تصوّر اهتزاز محرك: إذا كان متوسط الاهتزاز يرتفع بشكل بطيء على مدار 6 أشهر، فهذا اتجاه صاعد يدل على تآكل تدريجي في المحامل (bearings).
الموسمية (Seasonality)
أنماط متكررة بشكل دوري — يومياً أو أسبوعياً أو سنوياً. في المصانع، استهلاك الكهرباء ينخفض ليلاً ويرتفع نهاراً (دورة يومية)، والطلب على الإسمنت يرتفع صيفاً وينخفض شتاءً (دورة سنوية).
الضوضاء (Noise / Residuals)
التقلبات العشوائية التي لا يمكن تفسيرها بالاتجاه أو الموسمية — تداخل كهربائي في حساس، اهتزاز عابر من شاحنة مرّت قرب المصنع.
القيمة المُقاسة = الاتجاه + الموسمية + الضوضاء
y(t) = T(t) + S(t) + R(t)
import numpy as np
# توليد سلسلة زمنية اصطناعية (365 يوم)
days = np.arange(365)
# الاتجاه: ارتفاع تدريجي (تآكل)
trend = 0.05 * days
# الموسمية: دورة يومية
seasonality = 10 * np.sin(2 * np.pi * days / 7)
# الضوضاء العشوائية
noise = np.random.normal(0, 2, 365)
# السلسلة الكاملة
vibration = 50 + trend + seasonality + noise
print(f"اليوم 1: {vibration[0]:.1f} mm/s")
print(f"اليوم 365: {vibration[364]:.1f} mm/s")
الاستقرارية (Stationarity)
سلسلة زمنية مستقرة تعني أن خصائصها الإحصائية (المتوسط والتباين) لا تتغير مع الزمن. معظم نماذج التنبؤ الكلاسيكية تتطلب بيانات مستقرة.
تخيّل خط إنتاج مستقر: متوسط الإنتاج اليومي حوالي 500 قطعة مع تذبذب ±20 قطعة — هذا مستقر. لكن لو أضفنا آلة جديدة فقفز الإنتاج إلى 700 قطعة — السلسلة لم تعد مستقرة.
اختبار الاستقرارية — اختبار ديكي-فولر (ADF Test)
from statsmodels.tsa.stattools import adfuller
# اختبار ADF: الفرضية الصفرية = السلسلة غير مستقرة
result = adfuller(vibration)
print(f"إحصائية ADF: {result[0]:.4f}")
print(f"القيمة الاحتمالية (p-value): {result[1]:.4f}")
if result[1] < 0.05:
print("السلسلة مستقرة ✓")
else:
print("السلسلة غير مستقرة — نحتاج تفاضل (differencing)")
تحويل السلسلة إلى مستقرة
أبسط طريقة هي التفاضل (Differencing): بدل قراءة القيمة y(t)، نحسب الفرق y(t) - y(t-1). هذا يزيل الاتجاه العام.
نموذج ARIMA: التنبؤ الكلاسيكي
ARIMA (AutoRegressive Integrated Moving Average) هو أشهر نموذج للتنبؤ بالسلاسل الزمنية. اسمه يصف مكوّناته الثلاثة:
| المكوّن | الرمز | الوظيفة |
|---|---|---|
| الانحدار الذاتي (AR) | p | استخدام القيم السابقة للتنبؤ |
| التكامل (I) | d | عدد مرات التفاضل للوصول للاستقرارية |
| المتوسط المتحرك (MA) | q | استخدام أخطاء التنبؤ السابقة |
ARIMA(p, d, q) — مثلاً ARIMA(2, 1, 1) يعني: استخدام آخر قيمتين، تفاضل مرة واحدة، واستخدام آخر خطأ تنبؤ.
from statsmodels.tsa.arima.model import ARIMA
# بيانات استهلاك كهرباء شهري (24 شهر)
power_consumption = [
450, 470, 460, 480, 520, 550, 580, 590,
560, 530, 490, 460, 470, 490, 480, 500,
540, 570, 600, 610, 580, 550, 510, 480
]
# بناء نموذج ARIMA(1,1,1)
model = ARIMA(power_consumption, order=(1, 1, 1))
fitted = model.fit()
# التنبؤ بالأشهر الثلاثة القادمة
forecast = fitted.forecast(steps=3)
print("التنبؤ بالاستهلاك:")
for i, val in enumerate(forecast):
print(f" الشهر {25 + i}: {val:.0f} كيلوواط ساعة")
كيف نختار p, d, q؟
- d: نبدأ بـ d=0 ونختبر الاستقرارية. إذا لم تكن مستقرة، نجرب d=1 ثم d=2.
- p و q: نستخدم رسم دالة الارتباط الذاتي (ACF) ودالة الارتباط الذاتي الجزئي (PACF)، أو نستخدم
auto_arimaالذي يجرب تلقائياً.
شبكات LSTM: التنبؤ بالتعلم العميق
عندما تكون العلاقات الزمنية معقدة جداً لنموذج ARIMA — مثل التنبؤ بأعطال معدات تعتمد على عشرات الحساسات — نلجأ لشبكات LSTM (Long Short-Term Memory).
تصوّر LSTM كمهندس خبير يتذكر أحداثاً مهمة من الماضي البعيد (ارتفاع اهتزاز قبل 3 أشهر) ويتجاهل التفاصيل غير المهمة (تذبذب عابر لثوانٍ).
لماذا LSTM وليس RNN عادية؟
الشبكات العصبية التكرارية (RNN) العادية تعاني من مشكلة التدرج المتلاشي — تنسى المعلومات القديمة. LSTM تحل هذا بثلاث بوابات:
| البوابة | الوظيفة |
|---|---|
| بوابة النسيان (Forget Gate) | تقرر ما يُحذف من الذاكرة |
| بوابة الإدخال (Input Gate) | تقرر ما يُضاف للذاكرة |
| بوابة الإخراج (Output Gate) | تقرر ما يُرسل كمخرج |
import numpy as np
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM, Dense
# تحضير البيانات: نوافذ بطول 10 خطوات
def create_sequences(data, window=10):
X, y = [], []
for i in range(len(data) - window):
X.append(data[i:i+window])
y.append(data[i+window])
return np.array(X), np.array(y)
# بيانات اهتزاز (مُطبَّعة بين 0 و 1)
vibration_data = np.random.rand(500).astype(np.float32)
X, y = create_sequences(vibration_data, window=10)
X = X.reshape(-1, 10, 1) # (عينات، خطوات زمنية، ميزات)
# بناء نموذج LSTM
model = Sequential([
LSTM(32, input_shape=(10, 1)),
Dense(1)
])
model.compile(optimizer='adam', loss='mse')
model.fit(X, y, epochs=10, batch_size=32, verbose=0)
# التنبؤ
prediction = model.predict(X[-1:])
print(f"التنبؤ القادم: {prediction[0][0]:.4f}")
مقارنة ARIMA و LSTM
| المعيار | ARIMA | LSTM |
|---|---|---|
| نوع البيانات | سلسلة واحدة (univariate) | متعددة المتغيرات (multivariate) |
| حجم البيانات المطلوب | مئات النقاط | آلاف إلى ملايين |
| قابلية التفسير | عالية — معاملات واضحة | منخفضة — صندوق أسود |
| العلاقات غير الخطية | لا يلتقطها | يلتقطها جيداً |
| سرعة التدريب | ثوانٍ | دقائق إلى ساعات |
| أفضل استخدام | تنبؤ قصير المدى، بيانات بسيطة | أنماط معقدة، حساسات متعددة |
التطبيقات الصناعية
التنبؤ بالطلب (Demand Forecasting)
مصنع إسمنت يحتاج معرفة الطلب المتوقع الشهر القادم لتحديد كمية المواد الخام وجدولة الشحنات. نموذج ARIMA الموسمي (SARIMA) يلتقط الموسمية السنوية ويتنبأ بدقة معقولة.
نمذجة التدهور (Degradation Modeling)
تصوّر مضخة صناعية: نراقب الاهتزاز والحرارة والضغط يومياً. LSTM متعدد المتغيرات يتعلم العلاقة بين هذه الحساسات ويتنبأ بالعمر المتبقي (Remaining Useful Life).
# مثال مبسط: تقدير العمر المتبقي
sensors = {
"vibration_trend": "صاعد", # اتجاه الاهتزاز
"temperature_trend": "مستقر", # اتجاه الحرارة
"pressure_trend": "هابط قليلاً" # اتجاه الضغط
}
# القاعدة: إذا كان الاهتزاز صاعداً والضغط هابطاً → تآكل محامل
if sensors["vibration_trend"] == "صاعد" and "هابط" in sensors["pressure_trend"]:
print("تحذير: تآكل محتمل في المحامل")
print("العمر المتبقي المقدّر: 45-60 يوم")
print("الإجراء: جدولة صيانة خلال 30 يوم")
كشف الشذوذ (Anomaly Detection)
نبني نموذج ARIMA أو LSTM يتنبأ بالقيمة التالية. إذا انحرفت القيمة الفعلية عن التنبؤ بأكثر من 3 انحرافات معيارية — هذا شذوذ يستحق التحقيق.
مراقبة جودة الإنتاج
تحليل السلاسل الزمنية لأبعاد القطع المُصنّعة يكشف الانحراف التدريجي قبل أن تخرج القطع عن حدود التحمّل (tolerances).
نصائح عملية للمهندس
- ابدأ بالرسم البياني — ارسم البيانات أولاً قبل أي نموذج. العين تلتقط الأنماط بسرعة.
- تحقق من الاستقرارية — استخدم اختبار ADF قبل تطبيق ARIMA.
- ARIMA أولاً — ابدأ بـ ARIMA كخط أساس (baseline) قبل الانتقال لـ LSTM.
- حجم البيانات مهم — LSTM يحتاج آلاف النقاط على الأقل. إذا كانت بياناتك صغيرة، ARIMA أفضل.
- التطبيع ضروري — قبل LSTM، حوّل البيانات إلى نطاق [0,1] باستخدام MinMaxScaler.
- التحقق الزمني — لا تستخدم التحقق المتقاطع العشوائي. قسّم البيانات زمنياً: الأقدم للتدريب والأحدث للاختبار.