برنامهنویسی پایتون – چگونه با کمتر از ۲۰ خط کد، جملههای الهامبخش ایجاد کنیم؟


زمانی که از تولید زبان طبیعی صحبت میکنیم، افراد معمولاً به سیستمهای هوش مصنوعی پیشرفته فکر میکنند که از ریاضیات عالی استفاده میکنند. با این حال این گزاره همیشه صحیح نیست. در این نوشته از ایده زنجیرههای مارکوف و مجموعه داده کوچکی از نقلقولهای معروف برای تولید جملههای جدید استفاده میکنیم. برای مثال همه جملههای بالا به وسیله یک رایانه و با استفاده از برنامهای تولید شدهاند که در زبان پایتون و با کمتر از 20 خط کد نوشته شده است.
“Don’t think of the overwhelming majority of the impossible.”
“Grew up your bliss and the world.”
“what we would end create, creates the ground and you are the one to warm it”
“look and give up in miracles”
رمز کار در استفاده از مدلی ریاضی به نام زنجیره مارکف است.
زنجیره مارکوف
زنجیره مارکوف مدلی تصادفی است که یک رویداد را تنها بر اساس رویداد قبلیاش پیشبینی میکند. بهعنوان یک مثال ساده میتوان به رفتارهای یک گربه اشاره کرد. گربهها معمولاً یا در حال خوردن، یا خوابیدن و بازی کردن هستند. آنها در اغلب اوقات در خواب هستند. زمانی که از خواب بیدار میشوند به دنبال غذا میگردند و معمولاً پس از خوردن انرژی یافته و شروع به بازیگوشی میکنند. پس از آن یا دوباره به خواب میروند و یا غذا میخورند.
وضعیت یک گربه را میتوان به سادگی با استفاده از زنجیره مارکوف مدلسازی کرد، زیرا بر اساس وضعیت قبلی خود تصمیمگیری میکند که الان چه باید بکند. بسیار نامحتمل است که یک گربه از خواب بیدار شده و مستقیماً به بازیگوشی بپردازد، اما احتمال این وضعیت پس از غذا خوردن بسیار بالا است. اینها تغییر رفتارهایی هستند که در نمودار گذار وضعیت زیر به نمایش در آمدهاند.
هر دایره یک وضعیت گربه را نشان میدهد و فلشها گذار به وضعیت بعدی را نشان میدهند. عدد کنار هر فلش نشان دهنده احتمال گذار از یک وضعیت به وضعیت دیگر است. همانطور که میبینید احتمال یک گذار تنها به وضعیت قبلی بستگی دارد.
تولید متن با استفاده از زنجیرههای مارکوف
تولید متن با زنجیرههای مارکوف از همان ایدهای پیروی میکند که احتمال ظاهر شدن یک واژه را پس از واژهای دیگر پیشبینی میکند. برای شناسایی احتمالات هر گذار با برخی جملههای ساده، مدل خود را تمرین میدهیم.
برای نمونه میتوانیم با استفاده از جملههای زیر مدل خود را تمرین دهیم.
I like to eat apples.
You eat oranges.
صرفاً از روی همین جملات میتوانیم نتیجه بگیریم که واژههای «I»، «like» و «to» همواره قبل از «eat» هستند. همچنین واژه «you» نیز همواره همراه «eat» است. با این حال شانس برابری برای مشاهده واژههای «oranges» و «apples» پس از واژه «eat» وجود دارد. نمودار گذار زیر آن چه را که توضیح دادیم بهتر نشان میدهد.
دو جمله تمرینی ظرفیت تولید دو جمله جدید را دارند؛ اما این گزاره همواره صحیح نیست. مدل دیگری را با چهار جمله زیر تمرین میدهیم و نتایج کاملاً متفاوت بودند.
my friend makes the best raspberry pies in town
i think apple pies are the best pies
steve thinks apple makes the best computers in the world
I own two computers and they’re not apple because I am not steve or rich
نمودار گذار برای مدل تمرینی با چهار جمله بسیار بزرگتر است.
با این که نمودار از یک نمودار معمولی زنجیره مارکوف خیلی متفاوت به نظر میرسد؛ اما ایده اصلی همان است. یک مسیر از گره آغازین شروع میشود و به طور تصادفی واژههای بعدی را انتخاب میکند تا این که به گره انتهایی برسد. احتمالهای هر واژه با ضخامت مسیر نشان داده شده است.
مدل فوق علیرغم این واقعیت که تنها با چهار جمله تمرین داده شده است، قابلیت تولید صدها جمله منحصربهفرد را دارد.
کد
کدی که برای تولید متن استفاده میشود، به طرز خارقالعادهای ساده است و نیازمند هیچ ماژول یا کتابخانه پایتون به جز ماژول random نیست. این کد دو بخش دارد. یکی برای تمرین دادن و دیگری برای تولید متن.
تمرین دادن
کد تمرین مدلی را میسازد که بعداً برای تولید جملههای الهامبخش استفاده میشود. در این کد از یک دیکشنری به عنوان مدل استفاده شده است که در آن واژهها به عنوان کلید هستند و فهرستی از واژههای بعدی بالقوه به عنوان مقادیر متناظر هستند. برای نمونه دیکشنری مدلی که با دو جمله نخست یعنی «I like to eat apples» و «You eat oranges» تمرین داده شده است، به صورت زیر است:
{'START': ['i', 'you'], 'i': ['like'], 'like': ['to'], 'to': ['eat'], 'you': ['eat'], 'eat': ['apples', 'oranges'], 'END': ['apples', 'oranges']}
لازم نیست احتمال رخداد واژه بعدی را محاسبه کنیم، زیرا اگر شانس ظاهر شدن آنها بالا باشد، در این صورت در فهرست واژگان بالقوه بعدی چندین بار ظاهر میشوند. برای مثال اگر جمله تمرینی دیگری را به صورت «we eat apples» اضافه کنیم، واژه «apples» در دو جمله پس از «eat» ظاهر شده است و از این رو احتمال رخداد بالاتری دارد. احتمال رخداد بالا به صورت نمایش دوباره در فهرست «eat» در دیکشنری مدل خود را نشان میدهد.
{'START': ['i', 'we', 'you'], 'i': ['like'], 'like': ['to'], 'to': ['eat'], 'you': ['eat'], 'we': ['eat'], 'eat': ['apples', 'oranges', 'apples'], 'END': ['apples', 'oranges', 'apples']}
به علاوه دو آیتم دیگر نیز به صورت «START» و «END» در دیکشنری مدل فوق وجود دارند. این دو آیتم نشان میدهند که واژههای ابتدایی و انتهایی یک جمله تولید شده کدام هستند.
for line in dataset_file: line = line.lower().split() for i, word in enumerate(line): if i == len(line)-1: model['END'] = model.get('END', []) + [word] else: if i == 0: model['START'] = model.get('START', []) + [word] model[word] = model.get(word, []) + [line[i+1]]
تولید عبارتها
بخش تولیدکننده جملهها شامل یک حلقه است. این حلقه با انتخاب یک واژه آغازین تصادفی و الحاق آن به فهرست شروع میشود. سپس در دیکشنری جستجو کرده و به دنبال فهرستی که شامل واژه بالقوه بعدی است میگردد و یکی از آنها را به طور تصادفی انتخاب کرده و به واژهای که قبلاً انتخاب کرده بود ملحق میکند. این کد به انتخاب تصادفی واژههای بالقوه بعدی ادامه میدهد تا این که به یک واژه انتخابی برسد. در این لحظه حلقه متوقف شده و جمله یا «نقلقول» تولید شده را در خروجی ارائه میدهد.
import random generated = [] while True: if not generated: words = model['START'] elif generated[-1] in model['END']: break else: words = model[generated[-1]] generated.append(random.choice(words))
بدین ترتیب دیدیم که چگونه میتوان از زنجیرههای مارکوف برای تولد نقلقولهای الهامبخش استفاده کرد. با این حال وقتی از تولید متن صحبت میکنیم، میتوان هر نوع ورودی ارائه کرد و متن مشابهی در خروجی تولید خواهد شد.
کار جالب دیگری که میتوان با تولیدکنندههای متن مبتنی بر زنجیرههای مارکوف انجام داد ترکیب انواع مختلفی از متنها است. برای نمونه در یکی از نمایشهای تلویزیونی محبوب به نام «ریک و مورتی» شخصیتی هست که آبرادولف لینکلر (Abradolf Lincler) نامیده میشود. این نام مخلوطی از دو نام آبراهام لینکلن و آدولف هیتلر است. شما میتوانید با ارائه سخنرانیهای این دو رهبر سیاسی به یک تولیدکننده متن زنجیرههای مارکوف به عنوان دادههای تمرینی، یک متن سخنرانی برای آبرادولف لینکلر تهیه کنید.
زنجیرههای مارکوف ابزار شگفت انگیزی است که کاربردهای زیادی در رشتههای مختلف دارد. تولید متن مفیدترین کاربرد زنجیرههای مارکوف محسوب نمیشود؛ اما قطعاً یکی از سرگرمکنندهترین کاربردهای آن است.
اگر به این نوشته علاقهمند بودید، احتمالاً موارد زیر نیز مورد توجه شما واقع میشوند:
- آموزش تکمیلی برنامه نویسی پایتون
- آموزش یادگیری ماشین (Machine Learning) با پایتون (Python)
- آموزش نظریه زبان ها و ماشین ها
- گنجینه آموزش های برنامه نویسی پایتون (Python)
- مجموعه آموزشهای هوش مصنوعی
- آموزش برنامه نویسی یادگیری عمیق با پایتون (TensorFlow و Keras)
==