قامت المترجمة بولينا كابيروفا خصيصًا لـ Netologia بتعديل مقال بقلم مهندس جامعة كامبريدج فيفيك بالانيابان حول كيفية إنشاء نموذج باستخدام الشبكات العصبية التي يمكنها التنبؤ بأسعار الأسهم في البورصة.أصبح التعلم الآلي والتعليم العميق استراتيجية جديدة فعالة تستخدمها العديد من صناديق الاستثمار لزيادة الدخل. في المقالة ، سأشرح كيف تساعد الشبكات العصبية في التنبؤ بالوضع في سوق الأسهم - على سبيل المثال ، سعر الأسهم (أو المؤشر). يستند النص إلى مشروعي المكتوب بلغة Python. يمكن العثور على الكود الكامل ودليل البرنامج على GitHub. اقرأ مقالات أخرى ذات صلة على مدونة
Medium .
الشبكات العصبية في الاقتصاد
التغييرات في مجال التمويل ليست خطية ، وأحيانًا قد يبدو أن أسعار الأسهم تتشكل بشكل عشوائي تمامًا. تعتبر طرق السلاسل الزمنية التقليدية ، مثل نماذج ARIMA و GARCH ، فعالة عندما تكون السلسلة ثابتة - ولا تتغير خصائصها الأساسية بمرور الوقت. ويتطلب هذا أن تكون السلسلة قد تمت معالجتها مسبقًا باستخدام عمليات
log returns
أو جلبها إلى السمة المختلفة بشكل مختلف. ومع ذلك ، تبرز المشكلة الرئيسية عندما يتم تنفيذ هذه النماذج في نظام تداول حقيقي ، حيث لا يتم ضمان التوازن عند إضافة بيانات جديدة.
يمكن أن يكون الحل لهذه المشكلة هو الشبكات العصبية التي لا تتطلب الاستقامة. الشبكات العصبية فعالة في البداية في إيجاد العلاقات بين البيانات وهي قادرة على التنبؤ (أو تصنيف) البيانات الجديدة بناءً عليها.
عادةً ما يتكون مشروع علوم البيانات من العمليات التالية:
- جمع البيانات - يوفر مجموعة من الخصائص الضرورية.
- غالبًا ما تكون المعالجة المسبقة للبيانات خطوة مخيفة ولكنها ضرورية قبل استخدام البيانات.
- تطوير وتنفيذ النموذج هو اختيار نوع الشبكة العصبية ومعلماتها.
- نماذج الاختبار الخلفي (الاختبار على البيانات التاريخية) هي خطوة رئيسية في أي استراتيجية تداول.
- التحسين - ابحث عن المعلمات المناسبة.
مدخلات لشبكتنا العصبية - بيانات عن أسعار الأسهم خلال الأيام العشرة الأخيرة. بمساعدتهم ، سوف نتوقع الأسعار في اليوم التالي.
جمع البيانات
لحسن الحظ ، يمكن العثور على البيانات اللازمة لهذا المشروع على Yahoo Finance. يمكن جمع البيانات باستخدام Python API
pdr.get_yahoo_data(ticker, start_date, end_date)
أو مباشرة من الموقع.
معالجة البيانات
في حالتنا ، يجب تقسيم البيانات إلى مجموعات تدريب تتكون من 10 أسعار سابقة وأسعار اليوم التالي. للقيام بذلك ، حددت فئة
Preprocessing
، والتي ستعمل مع بيانات التدريب والاختبار. داخل الفصل ، قمت بتعريف طريقة
get_train(self, seq_len)
، والتي تحول مدخلات التدريب وبيانات المخرجات إلى مصفوفات
NumPy
، مع تحديد طول نافذة معينة (في حالتنا 10). يبدو الرمز بالكامل كما يلي:
def gen_train(self, seq_len): """ Generates training data :param seq_len: length of window :return: X_train and Y_train """ for i in range((len(self.stock_train)//seq_len)*seq_len - seq_len - 1): x = np.array(self.stock_train.iloc[i: i + seq_len, 1]) y = np.array([self.stock_train.iloc[i + seq_len + 1, 1]], np.float64) self.input_train.append(x) self.output_train.append(y) self.X_train = np.array(self.input_train) self.Y_train = np.array(self.output_train)
وبالمثل ، حددت طريقة تحول بيانات الاختبار
X_test
و
Y_test
.
نماذج الشبكات العصبية
بالنسبة للمشروع ، استخدمت نموذجين للشبكات العصبية: Multilayer Perceptron (MLP) و Long Short Term Model (LSTM). سأتحدث باختصار عن كيفية عمل هذه النماذج. اقرأ المزيد عن MLP في
مقال آخر ، وعن عمل LSTM في Jacob Aungiers.
MLP هو أبسط شكل من أشكال الشبكات العصبية. تقع بيانات الإدخال في النموذج وباستخدام أوزان معينة ، يتم إرسال القيم من خلال طبقات مخفية للحصول على بيانات الإخراج. يأتي تعلم الخوارزمية من الانتشار الخلفي من خلال طبقات مخفية لتغيير قيم الوزن لكل خلية عصبية. المشكلة في هذا النموذج هي نقص "الذاكرة". من المستحيل تحديد ماهية البيانات السابقة وكيف يمكن وينبغي أن تؤثر على البيانات الجديدة. في سياق نموذجنا ، قد تهم الاختلافات لمدة 10 أيام بين بيانات مجموعتي بيانات ، لكن MLPs غير قادرة على تحليل هذه العلاقات.
للقيام بذلك ، استخدم LSTM أو الشبكات العصبية المتكررة (RNN). تخزن شبكات RNN معلومات معينة للبيانات لاستخدامها لاحقًا ، وهذا يساعد الشبكة العصبية على تحليل الهيكل المعقد للعلاقات بين بيانات أسعار الأسهم. ولكن مع RNN ، تنشأ مشكلة التدرج المتلاشي. ينخفض التدرج لأن عدد الطبقات يزداد ويتضاعف مستوى التدريب (قيمة أقل من الوحدة) عدة مرات. حل مشكلة LSTM عن طريق زيادة الكفاءة.
تنفيذ النموذج
لتنفيذ النموذج ، استخدمت
Keras
، لأنه تتم إضافة طبقات تدريجيًا ، ولا تحدد الشبكة بالكامل مرة واحدة. حتى نتمكن من تغيير عدد ونوع الطبقات بسرعة ، وتحسين الشبكة العصبية.
يعد تطبيع البيانات خطوة مهمة في العمل مع أسعار الأسهم. عادة ما تقوم بطرح متوسط الخطأ وتقسيمه على الخطأ القياسي. لكننا نحتاج إلى استخدام هذا النظام في التداول الحقيقي لفترة زمنية معينة. وبالتالي ، قد لا يكون استخدام الإحصاءات الطريقة الأكثر دقة لتطبيع البيانات. لذلك قمت فقط بتقسيم جميع البيانات إلى 200 (رقم عشوائي مقارنة بجميع الأرقام الأخرى صغيرة). وعلى الرغم من أنه يبدو أن مثل هذا التطبيع ليس له ما يبرره ولا معنى له ، فمن الفعال التأكد من أن الأوزان في الشبكة العصبية لا تصبح كبيرة جدًا.
لنبدأ بنموذج أبسط - MLP. Keras يبني تسلسل ويضيف طبقات كثيفة فوقه. يبدو الرمز الكامل كما يلي:
model = tf.keras.models.Sequential() model.add(tf.keras.layers.Dense(100, activation=tf.nn.relu)) model.add(tf.keras.layers.Dense(100, activation=tf.nn.relu)) model.add(tf.keras.layers.Dense(1, activation=tf.nn.relu)) model.compile(optimizer="adam", loss="mean_squared_error")
باستخدام Keras في خمسة أسطر من التعليمات البرمجية ، أنشأنا MLP مع طبقات مخفية ، مائة عصبون في كل منها. والآن قليلاً عن المحسن. تكتسب طريقة Adam (تقدير اللحظة التكيفية) شعبية - خوارزمية تحسين أكثر كفاءة مقارنة
بنسب التدرج العشوائي . هناك نوعان من الامتدادات الأخرى لنسب التدرج العشوائي - تظهر مزايا آدم على الفور على خلفيتهم:
AdaGrad - يحافظ على سرعة تعلم محددة ، مما يحسن النتائج عند اختلاف التدرجات (على سبيل المثال ، مع مشاكل في اللغة الطبيعية ورؤية الكمبيوتر).
RMSProp - يحافظ على سرعة تدريب محددة ، والتي يمكن أن تختلف اعتمادًا على متوسط قيم التدرجات الحديثة للوزن (على سبيل المثال ، مدى سرعة تغييره). هذا يعني أن الخوارزمية تتكيف بشكل جيد مع المشاكل غير الثابتة (على سبيل المثال ، الضوضاء).
يجمع آدم بين فوائد هذه الامتدادات ، لذلك اخترت ذلك.
الآن نناسب النموذج مع بيانات التدريب لدينا. يبسط Keras المهمة مرة أخرى ، فقط الرمز التالي مطلوب:
model.fit(X_train, Y_train, epochs=100)
عندما يكون النموذج جاهزًا ، تحتاج إلى التحقق منه على بيانات الاختبار لتحديد مدى نجاحه. يتم ذلك على النحو التالي:
model.evaluate(X_test, Y_test)
يمكن استخدام المعلومات التي تم الحصول عليها من التحقق لتقييم قدرة النموذج على التنبؤ بأسعار الأسهم.
يتم استخدام إجراء مماثل لنموذج LSTM ، لذلك سأعرض الكود وأشرحه قليلاً:
model = tf.keras.Sequential() model.add(tf.keras.layers.LSTM(20, input_shape=(10, 1), return_sequences=True)) model.add(tf.keras.layers.LSTM(20)) model.add(tf.keras.layers.Dense(1, activation=tf.nn.relu)) model.compile(optimizer="adam", loss="mean_squared_error") model.fit(X_train, Y_train, epochs=50) model.evaluate(X_test, Y_test)
يرجى ملاحظة أن Keras تحتاج إلى بيانات بحجم معين ، اعتمادًا على طرازك. من المهم جدًا تغيير شكل الصفيف باستخدام NumPy.
نماذج الاختبار الخلفي
عندما قمنا بإعداد نماذجنا باستخدام بيانات التدريب واختبرناها على بيانات الاختبار ، يمكننا اختبار النموذج على البيانات التاريخية. يتم ذلك على النحو التالي:
def back_test(strategy, seq_len, ticker, start_date, end_date, dim): """ A simple back test for a given date period :param strategy: the chosen strategy. Note to have already formed the model, and fitted with training data. :param seq_len: length of the days used for prediction :param ticker: company ticker :param start_date: starting date :type start_date: "YYYY-mm-dd" :param end_date: ending date :type end_date: "YYYY-mm-dd" :param dim: dimension required for strategy: 3dim for LSTM and 2dim for MLP :type dim: tuple :return: Percentage errors array that gives the errors for every test in the given date range """ data = pdr.get_data_yahoo(ticker, start_date, end_date) stock_data = data["Adj Close"] errors = [] for i in range((len(stock_data)//10)*10 - seq_len - 1): x = np.array(stock_data.iloc[i: i + seq_len, 1]).reshape(dim) / 200 y = np.array(stock_data.iloc[i + seq_len + 1, 1]) / 200 predict = strategy.predict(x) while predict == 0: predict = strategy.predict(x) error = (predict - y) / 100 errors.append(error) total_error = np.array(errors) print(f"Average error = {total_error.mean()}")
ومع ذلك ، هذه نسخة مبسطة من الاختبار. بالنسبة لنظام الاختبار الخلفي الكامل ، يجب مراعاة عوامل مثل "تحيز البقاء على قيد الحياة" ، والتحيز (التطلع إلى المستقبل) ، وظروف السوق المتغيرة وتكاليف المعاملات. نظرًا لأن هذا مجرد مشروع تعليمي ، فإن الاختبار الخلفي البسيط يكفي.
توقعات نموذج LSTM الخاص بي لأسعار أسهم Apple في فبرايربالنسبة إلى نموذج LSTM البسيط بدون تحسين ، هذه نتيجة جيدة جدًا. ويبين أن الشبكات العصبية ونماذج التعلم الآلي قادرة على بناء اتصالات معقدة ومستقرة بين المعلمات.
تحسين المعلمات
غالبًا ما تكون هناك حاجة إلى التحسين لتحسين نتائج النموذج بعد الاختبار. لم أقم بتضمينها في إصدار مفتوح المصدر بحيث يمكن للقراء محاولة تحسين النموذج بأنفسهم. سيتعين على أولئك الذين لا يعرفون كيفية التحسين العثور على معلمات مفرطة من شأنها تحسين أداء النموذج. هناك العديد من الطرق للعثور على المعلمات المفرطة: من تحديد المعلمات على الشبكة إلى الأساليب العشوائية.
أنا متأكد من أنه مع تحسين النماذج ، تنتقل المعرفة في مجال التعلم الآلي إلى مستوى جديد. حاول تحسين النموذج بحيث يعمل بشكل أفضل من النموذج الخاص بي. قارن النتيجة بالرسم البياني أعلاه.
الخلاصة
يتطور التعلم الآلي باستمرار - تظهر طرق جديدة كل يوم ، لذلك من المهم جدًا التعلم باستمرار. أفضل طريقة للقيام بذلك هي إنشاء مشاريع مثيرة للاهتمام ، على سبيل المثال ، بناء نماذج للتنبؤ بأسعار الأسهم. وعلى الرغم من أن نموذج LSTM الخاص بي ليس جيدًا بما يكفي للاستخدام في التداول الحقيقي ، إلا أن الأساس الذي تم وضعه في تطوير مثل هذا النموذج قد يساعد في المستقبل.
من المحررين
دورات Netology حول هذا الموضوع: