سلسلة ماركوف بسيطة: دعونا نلقي نظرة على المبدأ بالتفصيل. توسيع قاعدة المفردات

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


سلسلة ماركوف عبارة عن سلسلة من الاختبارات يظهر في كل منها اختبار واحد فقط من k. أحداث غير متوافقةآي من مجموعة كاملة. في نفس الوقت احتمال مشروط pij(s) من حقيقة وقوع الحدث Aj في التجربة رقم 1، بشرط وقوع الحدث Ai في التجربة (s - 1)، لا يعتمد على نتائج التجارب السابقة.

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

بسبب الغابة، بسبب الجبال
الجد إيجور قادم:
نفسي على الحصان
زوجة على بقرة,
أطفال على العجول,
الأحفاد على الماعز الصغيرة.

دعونا نحلل النص إلى روابط وروابط

بسبب [الغابات والجبال]
الغابات [بسبب]
جبال [ركوب الخيل]
[الجد] قادم
جد [إيجور]
إيجور [نفسه]
نفسي [على]
على [الحصان، البقرة، العجول، الأطفال]
حصان [زوجة]
زوجة [على]
بقرة [أطفال]
أطفال [على]
عجول [أحفاد]
أحفاد [على]

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

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

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

  1. // اقرأ النص المصدر الذي سيتم على أساسه إنشاء نص جديد
  2. $str = file_get_contents("markov.txt");
  3. // ضبط ترميز النظام
  4. setlocale(LC_ALL, "ru_RU.CP1251");
  5. // إزالة الأحرف من النص باستثناء الأرقام والحروف وبعض علامات الترقيم
  6. $str = eregi_replace ("[^-a-zа-я0-9 !\?\.\,]" , " " , $str );
  7. // تنظيف المسافات قبل إنهاء الجمل
  8. $str = eregi_replace (" (1,)([!\?\.\,])" , "\\1" , $str );
  9. // قسم النص إلى كلمات
  10. $tmp = preg_split ("/[[:space:]]+/is" , $str );
  11. // مجموعة من "الروابط"
  12. $words =Array();
  13. // املأ الروابط
  14. ل($i = 0 ; $i< count ($tmp ); $i ++) {
  15. إذا ($tmp [ $i + 1 ]!= "" ) (
  16. $words [ $tmp [ $i ]]= $tmp [ $i + 1 ];
  17. $words = array_map("array_unique" , ​​​​$words );
  18. // مجموعة من الكلمات الأولية في الجمل
  19. $start =Array();
  20. foreach($words كـ $word => $links) (
  21. إذا (ereg ("^[A-Z] [a-Z]+" , $word )) (
  22. بداية $ = كلمة $؛
  23. // أنشئ 100 جملة بناءً على النص المصدر
  24. لـ ($i = 0؛ $i< 100 ; $i ++) {
  25. بينما (صحيح) (
  26. $w = $start [ rand (0 ,(count ($start )- 1 ))]);
  27. إذا (ereg ("[\.!\?]$" , $w )) (تابع؛)
  28. جملة $ = $w . " " ;
  29. // عدد الكلمات في الجملة
  30. $cnt = 1 ;
  31. // إنشاء العرض
  32. بينما (صحيح) (
  33. روابط $ = كلمات $ [ $w ];
  34. // سلسلة التبديل
  35. $w = $words [ $w ] [ rand (0 ,(count ($words [ $w ])- 1 )]);
  36. جملة $ .= $w . " " ;
  37. // إذا كانت الكلمة في نهاية الجملة
  38. إذا (ereg ("[\.!\?]$" , $w )) (break;)
  39. $cnt++;
  40. // إذا كان المولد في حلقة، فافرض الخروج
  41. إذا ($cnt > 19) (استراحة؛)
  42. // الجملة التي يبلغ طولها من 5 إلى 20 كلمة تعتبر ناجحة
  43. إذا ($cnt > 5 && $cnt< 20 ) { break; }
  44. // العرض الذي تم إنشاؤه
  45. صدى جملة $ ؛

شرح بسيط لكيفية عمل كل شيء. أولاً، يتم تحميل الملف "markov.txt"، ويجب أن يكون بترميز win-1251. ثم يتم إزالة جميع الأحرف منه، باستثناء الحروف وبعض علامات الترقيم، ثم يتم قطع المسافات غير الضرورية. اتضح نص واضح، والتي يتم تقسيمها بعد ذلك إلى الكلمات الفردية. هذا كل شيء، لدينا روابط فردية في السلسلة. الآن نحن بحاجة إلى تحديد الروابط بين الكلمات، أي الكلمات التي يمكن أن تكون موجودة خلف أي منها. هذه هي العملية الأكثر استهلاكًا للموارد، لذا سيتعين عليك التحلي بالصبر عند التعامل مع الملفات الكبيرة. إذا كان الإنشاء مطلوبًا بشكل متكرر، فمن المحتمل أن يكون من المنطقي تخزين مجموعة من الروابط والروابط في بعض قواعد البيانات من أجل الوصول إليها بسرعة. الخطوة التالية- التعرف على الكلمات التي تبدأ بها الجمل . لقد قبلت شرط أن الحرف الأول من هذه الكلمات يجب أن يكون بالأحرف الكبيرة، ويمكنك فعل المزيد تعريف دقيق. يتم إنشاء النص وفقًا للخوارزمية الموضحة أعلاه، لقد أضفت للتو عدة اختبارات ضد تكرارها.

يمكنك رؤية مثال عملي لمولد نص يعتمد على سلاسل ماركوف والبرنامج النصي أعلاه

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

بادئ ذي بدء ، دعنا نكتب التعريفات الضرورية ، ولكن ليست واضحة تمامًا بعد ، من صفحة ويكيبيديا من أجل فهم ما نتعامل معه تقريبًا على الأقل:

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

سلسلة ماركوف

ماذا يعني كل هذا؟ دعونا معرفة ذلك.

الأساسيات

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

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

ونقوم بتدوين عدد مرات ظهور كل رابط في النص:

في الصورة أعلاه يمكنك أن ترى أن الكلمة "سمكة"تظهر في النص 4 مرات أكثر من كل كلمة من الكلمات الأخرى ( "واحد"، "اثنان"، "أحمر"، "أزرق"). وهذا هو، احتمال مواجهة الكلمة في مجموعتنا "سمكة"أعلى بـ 4 مرات من احتمال مواجهة كل كلمة أخرى موضحة في الشكل. بالتحدث بلغة الرياضيات، يمكننا تحديد قانون توزيع المتغير العشوائي وحساب احتمالية ظهور إحدى الكلمات في النص بعد الكلمة الحالية. يتم حساب الاحتمال على النحو التالي: نحتاج إلى قسمة عدد مرات ظهور الكلمة التي نحتاجها في المجموعة على العدد الإجماليكل الكلمات فيه. للكلمة "سمكة"هذا الاحتمال هو 50% لأنه يظهر 4 مرات في جملة مكونة من 8 كلمات. ولكل رابط من الروابط المتبقية هذا الاحتمال هو 12.5% ​​(1/8).

تمثل التوزيع بيانيا المتغيرات العشوائيةممكن باستخدام الرسوم البيانية. في في هذه الحالة، فإن تكرار حدوث كل رابط من الروابط في الجملة واضح للعيان:

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

جوهر التعريف

الآن دعونا نضيف إلى النص عناصر ضمنية دائمًا، ولكن لا يتم التعبير عنها في الكلام اليومي - بداية الجملة ونهايتها:

أي جملة تحتوي على هاتين الكلمتين "البداية" و"النهاية" غير المرئيتين، فلنضيفهما كروابط لتوزيعنا:

لنعد إلى التعريف الوارد في بداية المقال:

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

سلسلة ماركوف - حالة خاصةعملية ماركوف، عندما يكون فضاء حالاته منفصلاً (أي لا يزيد عن عدد معدود).

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

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

وبالتالي، يتم تشكيل أزواج من الكلمات (حتى نهاية الجملة لها زوج خاص بها - معنى فارغ):

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

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

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

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

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

عظيم! لقد تعلمنا المعلومات الضروريةللمضي قدمًا وتحليل نماذج أكثر تعقيدًا.

توسيع قاعدة المفردات

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

لنأخذ أربعة اقتباسات أخرى من نفس المؤلف (باللغة الإنجليزية أيضًا، لن يضرنا ذلك):

"اليوم أنت أنت. وهذا أصدق من الصحيح. لا يوجد أحد على قيد الحياة من هو أنت أكثر منك.

« لديكالعقول في رأسك. لديك أقدام في حذائك. يمكنك توجيه نفسك في أي اتجاه تختاره. أنت وحدك."

"كلما قرأت أكثر، كلما عرفت أشياء أكثر." كلما تعلمت أكثر، زادت الأماكن التي ستذهب إليها."

"فكر يسارًا والتفكيرالحق والتفكير المنخفض والتفكير العالي. أوه، يعتقد أنت تستطيعفكر إذا حاولت فقط."

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

أسهل طريقة لشرح ذلك هي من وجهة نظر البرنامج. نحن نعلم أنه يوجد لكل رابط مجموعة من الكلمات التي يمكن أن تتبعه. وأيضا تتميز كل كلمة بعدد مرات ظهورها في النص. نحن بحاجة إلى طريقة ما لجمع كل هذه المعلومات في مكان واحد؛ ولهذا الغرض، يعتبر القاموس الذي يخزن أزواج "(المفتاح، القيمة)" هو الأنسب. سيسجل مفتاح القاموس الحالة الحالية للنظام، أي أحد روابط الجسم (على سبيل المثال، "ال"في الصورة أدناه)؛ وسيتم تخزين قاموس آخر في قيمة القاموس. في القاموس المتداخل، ستكون المفاتيح عبارة عن كلمات يمكن أن تظهر في النص بعد الرابط الحالي للنص ( "يعتقد"و "أكثر"قد يذهب بعد في النص "ال")، والقيم هي عدد ظهور هذه الكلمات في النص بعد الرابط الخاص بنا (كلمة "يعتقد"يظهر في النص بعد الكلمة "ال" 1 مرة، كلمة "أكثر"بعد الكلمة "ال"- 4 مرات):

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

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

أكثر:

أي إذا كانت الكلمة الحالية هي الكلمة "أكثر"، بعده يمكن أن تكون هناك كلمات ذات احتمال متساوي 25٪ "أشياء"و "الأماكن"وباحتمال 50% - الكلمة "الذي - التي". لكن الاحتمالات يمكن أن تكون متساوية:

يفكر:

العمل مع ويندوز

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

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

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

التنفيذ في بايثون

بنية بيانات الإملاء

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

استيراد Dictogram(dict): def __init__(self, iterable=None): # تهيئة توزيعنا كـ كائن جديد class, # إضافة العناصر الموجودة super(Dictogram, self).__init__() self.types = 0 # عدد المفاتيح الفريدة في التوزيع self.tokens = 0 # إجمالي عدد جميع الكلمات في التوزيع إذا كانت قابلة للتكرار: self.update( iterable) def update (self, iterable): # تحديث التوزيع بعناصر من مجموعة البيانات القابلة للتكرار الموجودة للعنصر في iterable: if item in self: self += 1 self.tokens += 1 else: self = 1 self. أنواع += 1 self.tokens += 1 def count(self, item): # إرجاع قيمة عداد العنصر، أو 0 إذا كان العنصر في self: return self return 0 def return_random_word(self): Random_key = Random.sample(self, 1) # طريقة أخرى: # اختيار عشوائي (histogram.keys()) return Random_key def return_weighted_random_word(self): # إنشاء رقم عشوائي زائف بين 0 و (n-1)، # حيث n هو العدد الإجمالي للكلمات Random_int = Random.randint(0, self.tokens-1) Index = 0 list_of_keys = self.keys() # print "random Index:"، Random_int for i in range(0, self.types): Index += self] # فهرس الطباعة if(index > Random_int): # طباعة list_of_keys [i] return list_of_keys[i]

يمكن لمنشئ بنية Dictogram تمرير أي كائن يمكن التكرار عليه. ستكون عناصر هذا الكائن عبارة عن كلمات لتهيئة الإملاء، على سبيل المثال، كل الكلمات من كتاب. في هذه الحالة، نقوم بعد العناصر بحيث للوصول إلى أي منها لا نحتاج إلى المرور عبر مجموعة البيانات بأكملها في كل مرة.

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

هيكل سلسلة ماركوف

من الرسوم البيانية import Dictogram def make_markov_model(data): markov_model = dict() for i in range(0, len(data)-1): if data[i] in markov_model: # فقط ألحق بتوزيع موجود markov_model].update( ]) else: markov_model] = Dictogram() يُرجع markov_model

في التنفيذ أعلاه، لدينا قاموس يخزن النوافذ كمفتاح في زوج "(مفتاح، قيمة)" والتوزيعات كقيم في هذا الزوج.

هيكل سلسلة ماركوف من الرتبة N

من الرسوم البيانية استيراد Dictogram def make_higher_order_markov_model(order, data): markov_model = dict() for i in range(0, len(data)-order): # إنشاء نافذة window = tuple(data) # أضف إلى القاموس إذا كانت النافذة في markov_model: # إرفاق بتوزيع موجود markov_model.update() else: markov_model = Dictogram() return markov_model

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

تحليل النموذج

عظيم، لقد قمنا بتنفيذ القاموس. ولكن كيف يمكننا الآن إنشاء محتوى بناءً على الحالة الحالية والخطوة إلى الحالة التالية؟ دعنا نذهب من خلال نموذجنا:

من الرسوم البيانية، قم باستيراد Dictogram بشكل عشوائي من المجموعات import deque import re def generator_random_start(model): # لإنشاء أي كلمة بداية، قم بإلغاء التعليق على السطر: # return Random.choice(model.keys()) # لإنشاء كلمة البداية "الصحيحة" استخدم الكود أدناه: # صحيح الكلمات الأولية- هذه هي تلك التي كانت بداية الجمل في المجموعة إذا كانت "END" في النموذج: Seed_word = "END" بينما Seed_word == "END": Seed_word = model["END"].return_weighted_random_word() تُرجع Seed_word تُرجع عشوائيًا. Choice(model .keys()) def generator_random_sentence(length, markov_model): current_word = generator_random_start(markov_model) الجملة = for i في النطاق (0, الطول): current_dictogram = markov_model Random_weighted_word = current_dictogram.return_weighted_random_word() current_word = كلمة عشوائية مرجحة جملة.append (الكلمة_الحالية) الجملة = الجملة.الحرف الكبير () العودة " ".الانضمام (الجملة) + "."

ما هي الخطوة التالية؟

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

تم وصف كيفية تدريب شبكة نيوترونية بحيث تلعب دور ماريو أو تتحكم في الروبوت. ولكن يمكن الشبكة العصبيةتوليد النص؟ سلاسل ماركوف يمكن أن تساعد في هذا.

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

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

وهذا على الرغم من أن الفكرة الأساسية لسلاسل ماركوف بسيطة للغاية، إلا أنه من المستحيل فهم ذلك من ويكيبيديا دون تعليم رياضي.

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

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

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

دعونا نحاول كتابة مولد الفطائر.

فطائر

فطائر - رباعيات بدون قافية وعلامات ترقيم وأرقام وبدون الحروف الكبيرة. يجب أن يكون عدد المقاطع 9-8-9-8.


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

على سبيل المثال، بعد المقطع "at" قد تكون هناك المقاطع التالية (الحواف وأوزانها):
"chem" (1) "ho" (4) "me" (1) "du" (2) "chi" (4) "yatel" (4) "went" (5) "ku" (1) " " (9) "su"(1) "vych"(3) "mi"(1) "kos"(1) "ob"(1) "det"(2) "قاد"(1) "uchi"(1) ) "mu"(1) "bi"(1) "tse"(1) "int"(2) "tom"(1) "ko"(1) "shaft"(1) "nes"(1) " ديت"(1) "لكن"(1) "vez"(1) "ميث"(1) "طبيب بيطري"(1) "ضياء"(1) "أنت"(1)

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

size_t nth = rand() % count;

size_t الكل = 0 ;

لـ (const auto &n: التالي) (

الكل += n.count;

إذا (الكل >= ن)

إرجاع كلمة n؛

وبالتالي، نقوم بإنشاء خطوط بحيث يتكون السطر الأول من 9 مقاطع، والثاني - 8، ثم 9 و 8، نحصل على:

ذات مرة كانت هناك نكتة حول المنبه
تم اختطافه بينما كان كذلك
رئيسك هنا نعم
أريكة تأثيرات Onegin

حتى الآن لا يبدو وكأنه نص متماسك بشكل خاص. غالبًا ما تتم مواجهة الكلمات غير الموجودة ("poku"). يوجد الآن مقطع واحد فقط كمفتاح. لكن من الصعب بناء جملة مبنية على مقطع واحد. دعونا نزيد عدد المقاطع التي على أساسها سنقوم بإنشاء المقطع التالي إلى 3 مقاطع على الأقل:

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

تسمح لك هذه البرامج بالفعل بكتابة المزيد من النصوص "ذات المغزى". على سبيل المثال، الجذر عبارة عن مقالة كتبها منشئ نص علمي، وتمت مراجعتها وحتى نشرها في مجلة علمية.

سلسلة ماركوف هي سلسلة من الأحداث التي يعتمد فيها كل حدث لاحق على الحدث السابق. في هذه المقالة سوف ندرس هذا المفهوم بمزيد من التفصيل.

سلسلة ماركوف هي طريقة شائعة وبسيطة إلى حد ما لنمذجة الأحداث العشوائية. تستخدم في معظم مناطق مختلفة، من إنشاء النص إلى النمذجة المالية. الأكثر مثال مشهورهو SubredditSimulator. في هذه الحالة، يتم استخدام Markov Chain لأتمتة إنشاء المحتوى عبر subreddit.

تتميز سلسلة ماركوف بالوضوح وسهولة الاستخدام لأنه يمكن تنفيذها دون استخدام أي مفاهيم إحصائية أو رياضية. تعتبر سلسلة ماركوف مثالية لتعلم النمذجة الاحتمالية وعلوم البيانات.

سيناريو

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

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

يمكنك الآن التنبؤ بالطقس قبل عدة أيام بناءً على الطقس الحالي.

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

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

نموذج

رسميًا، سلسلة ماركوف هي إنسان آلي احتمالي. عادةً ما يتم تمثيل توزيع احتمالية الانتقال كمصفوفة. إذا كانت سلسلة ماركوف تحتوي على N الدول الممكنة، فإن المصفوفة سيكون لها الشكل N x N، حيث سيكون الإدخال (I، J) هو احتمال الانتقال من الحالة I إلى الحالة J. بالإضافة إلى ذلك، يجب أن تكون هذه المصفوفة عشوائية، أي الصفوف أو يجب أن يصل مجموع الأعمدة إلى واحد. في مثل هذه المصفوفة، سيكون لكل صف توزيع احتمالي خاص به.

منظر عام لسلسلة ماركوف بحالات على شكل دوائر وحواف على شكل انتقالات.

مثال لمصفوفة انتقالية بثلاث حالات محتملة.

سلسلة ماركوف لديها ناقلات الأوليةالحالات، ممثلة بمصفوفة N x 1 وهي تصف التوزيعات الاحتمالية للبداية في كل حالة من الحالات N المحتملة. يصف الإدخال I احتمالية بدء السلسلة في الحالة الأولى.

هذان الهيكلان كافيان تمامًا لتمثيل سلسلة ماركوف.

لقد ناقشنا بالفعل كيفية الحصول على احتمالية الانتقال من حالة إلى أخرى، ولكن ماذا عن الحصول على هذا الاحتمال في بضع خطوات؟ للقيام بذلك، نحن بحاجة إلى تحديد احتمالية الانتقال من الحالة I إلى الحالة J في خطوات M. انها في الواقع بسيطة جدا. يمكن تحديد مصفوفة الانتقال P عن طريق حساب (I، J) عن طريق رفع P إلى القوة M. بالنسبة للقيم الصغيرة لـ M، يمكن القيام بذلك يدويًا باستخدام الضرب المتكرر. ولكن ل قيم كبيرةم إذا كنت على دراية الجبر الخطي، أكثر بطريقة فعالةسيؤدي رفع المصفوفة إلى قوة إلى جعل تلك المصفوفة قطرية أولًا.

سلسلة ماركوف: الاستنتاج

الآن، بعد أن عرفت ما هي سلسلة ماركوف، يمكنك بسهولة تنفيذها بإحدى لغات البرمجة. سلاسل بسيطةماركوف هي الأساس لدراسة المزيد أساليب معقدةالنمذجة.