اندکی تجربه از پروژه چت بات هوشمند

باسلام امیدوارم حالتون خوب باشه.

مدتی هست که در حال تحقیق درباره چت بات های هوشمند بودم در مقاله امروز می‌‎خوام تجربیاتی که بدست آوردم رو با شما به اشتراک بگذارم.

از همراهیتون صمیمانه سپاسگزارم.



اوایل وقتی به Google Assistant نگاه می کردم با خودم می گفتم: راحت ترین راه پیاده سازی این پروژه براساس منطق if و else هست!
ولی خب این روش مشکلات خاص خودش رو داره. باید به ازای هر گفت و گو if نوشت! مضحک ترین کار دقیقا همینه!

با خودم گفتم چه میشد اگه رباتی می ساختم که مثل انسان یاد بگیره؟! مثل یک انسان درک کنه؟!

پس برای دستیابی به این هدف شروع به جستجو و مطالعه و تحقیق درباره معماری چت بات های هوشمند که مبتنی بر هوش مصنوعی بود کردم. در حقیقت می خواستم بفهمم این مدل چت بات ها رو چطور می سازن؟!

در این بین من با فریم ورک رسا آشنا شدم. فریم ورک Rasa ابزاری برای خلق چت باتی که مبتنی بر هوش مصنوعی باشه هست. از طرفی با زبان پایتون هم نوشته شده.

با خودم گفتم آره همییینه!!!

اولین چالشی که در نصب رسا خوردم این بود که چون از tensorflow استفاده می کرد، در نصبش مشکل داشتم. (اگر می‌خواهید درباره System requirements های تنسور فلو بدونید اینجا رو کلیک کنید. یکی از راه های کم دردسر تر نصب تنسورفلو، نصب از طریق conda هست.)
پس شما می تونید از conda به جای pip برای نصب رسا استفاده کنید.
یکی از گزینه های دیگه نصب رسا از طریق داکر هست.
اگر هم تمایل دارید رسا رو روی محیط google colab نصب کنید هم می تونید.

پس از نصب اون، شروع کردم به ساخت یک چت بات ساده.
اولین پروژه ای که ساختم به زبان انگلیسی بود که با پوشش یکسری chitchat های ساده مثل intent های سلام و احوال پرسی، تشکر، خداحافظی و همچنین intent های چت که درباره subscribe یک خبرنامه بود.

اگر با اصطلاحات پاراگراف بالا بیگانه هستید باید بگم که منظور از chitchat همون گفت‌وگو هایی هست که معمولا در مکالمات وجود داره و اصلا ربطی به هدفی که چت بات دنبال می کنه نداره مثل سلام و احوال پرسی یا خداحافظی. اگر موضوع یا intent ما مرتبط با هدف ربات باشه دیگه chitchat محسوب نمی شه.
اصطلاح intent هم همون موضوع صحبت هست. به عنوان مثال وقتی من به ربات می گم: Hi there اون می فهمه که موضوع درباره greet هست. درواقع greet میشه intrent.

این رباتی ساختم به گفت و گو با کاربر می‌پرداخت و در نهایت با دریافت ایمیل از کاربر، آخرین اخبار را به ایمیل کاربر ارسال می کرد.
بعد از اینکه پروژه درست شد، من با استفاده از webchat درخواست های کاربر رو به core رسا می فرستادم. در واقع webchat فرانت اند من بود که روی وب سایت قرار می گرفت.

آیکن چتی که روی وب سایت قرار می گیره
آیکن چتی که روی وب سایت قرار می گیره


محیط چت
محیط چت


نتیجه ای که بدست آوردم خیلی خوب بود.

این پروژه ای که انجام دادم مشخصات زیر رو داشت:

  • کوچک وساده بود.
  • با زبان انگلیسی بود.

من همین پروژه رو اینبار به زبان فارسی train کردم. ایندفعه با موضوع صندوق در حسابداری بود. توی این مثال موضوعات خیلی بهم نزدیک نبودند. اما نتیجه قابل قبول بود.

تا اینجا ربات رو با مفاهیمی که بهم نزدیک نبودند train کرده بودم اما برای دفعه بعد می خواستم خلافشو عمل کنم یعنی ربات رو با مفاهیم نزدیک به هم train کنم.

مثلا :

  • صندوق چیست؟
  • صندوق باز چیست؟
  • صندوق بسته چیست؟

این جمله های بالا هر کدوم درسته که به لحاظ مفهومی و ساختار کلمات به هم نزدیک هستند اما هر کدوم مفهوم مجزایی هستند. که برنامه در این حالت به اشتباه همه این ها رو intent صندوق تشخیص میده.

یا در مثال زیر من به زبان خودم از برنامه پرسیده بودم که معنی صندوق چیست؟ اما پاسخ غیر مرتبط بر می گرداند.

من برای حل این مشکل با تغییر pipeline ، از الگوریتم fasttext و مدل pre train شده زبان فارسی که حدود دو میلیون کلمه بود استفاده کردم. در واقع با استفاده از spacy که خود رسا ساپورت می کرد، اون مدل رو import کردم. اما نتیجه باز هم درست نبود. استفاده این الگوریتم به یک سیستم خیلی قوی نیاز داشت. از اونجایی که سیستم عاملم لینوکس بود و از یک دسکتاپ سبک استفاده می کردم و همچنین هشت گیگ رمم بود در نتیجه بعد از مدت ها اجرا شد! حداقل 12 گیگ برای اجرا نیاز هست! فکر کنم حدود 45 دقیقه ای طول کشید که فقط اجرا بشه.

از نقاط قوت رسا میشه گفت که می تونه به عنوان چت بات در slack، وب سایت ها و ... استفاده بشه. علاوه بر این از api اون هم میشه استفاده کرد.

قسمتی که من خیلی نتونستم باهاش ارتباط برقرار کنم بخش آموزشش بود. اضافه کردن یه intent کمی پیچیده هست. به اینصورت هست که یکبار باید example های intent رو به برنامه بدیم بعد بریم توی فایل domain عنوان intent رو معرفی کنیم. بعد response اون intent رو باید اضافه کرد. در نهایت rule یا story رو هم براش مشخص کنیم.
البته یکسری ابزار هم برای ساده سازی این فرایند وجود داره مثلا از rasa x یا botfront استفاده کنیم.

یکی دیگه از قسمت هایی که خوشم نیومد استفاده از فایل هایی به فرمت yml یا md بود. اگر بخوام مدل رو از دیتا سورس های مختلف بسازم، خیلی منعطف نیست. مثلا من هنوز راهی پیدا نکردم که چطور میشه مدل رو از دیتا های دیتابیس یا فایل های csv بسازم.

در آخر من تصمیم گرفتم همین چت بات رو که درواقع یک FAQ بود بدون استفاده از این فریم ورک بنویسم. من با استفاده از شبکه عصبی این ربات رو درست کردم و یک api با میکروفریم ورک فلسک ساختم.

همون طور که می بینید accuracy ربات خودم برای تشخیص intent ها از rasa خیلی بیشتر و دقیق تر هست. از طرفی از هر دیتا سورسی که بخوام می تونه train کنه.

همونطور که در تصویر بالا مشاهده می کنید اولین intent که شناسایی می کنه درسته و مفهوم گزارش صندوق هست و دیگه صندوق نیست.



امیدوارم این نوشته براتون جالب و مفید بوده باشه.

نویسنده: ابوالفضل وکیلی