برنامه نویسی 183 بازدید

گارتنر به عنوان بزرگ‌ترین شرکت تحقیقات و مشاوره دنیا، پیش‌بینی کرده است که تا سال 2020، چت‌بات‌ها 85 درصد از تعامل‌های بین مشتری-سرویس را مدیریت خواهند کرد. چت‌بات‌ها هم اینک در حدود 30 درصد از این تراکنش‌ها را مدیریت می‌کنند. در این مقاله با روش ساخت یک چت‌بات پایتون به کمک پکیج NLTK آشنا خواهیم شد.

احتمالاً تاکنون نام Duolingo به گوش شما خورده است. این اپلیکیشن محبوب یک روش یادگیری زبان از طریق تمرین بازی‌گونه زبان جدید ارائه کرده است. دلیل محبوبیت آن سبک‌های نوآورانه تدریس زبان خارجی محسوب می‌شود. مفهوم کار ساده است: پنج تا ده دقیقه تمرین تعاملی در روز برای یادگیری یک زبان کافی است.

با این وجود علی‌رغم این که Duolingo به افراد امکان یادگیری یک زبان جدید را داده است؛ اما کاربران آن یک دغدغه دارند. افراد حس می‌کنند که چیزی را در خصوص یادگیری مهارت‌های محاوره‌ای ارزشمند از دست داده‌اند، زیرا زبان را به صوت کاملاً مستقل آموخته‌اند. همچنین این افراد در مورد مکالمه با دیگر یادگیرندگان آن زبان دچار واهمه هستند، زیرا از عدم اعتمادبه‌نفس رنج می‌برند. مشخص شده است که این یک تنگنای بزرگ در نقشه‌های Duolingo محسوب می‌شود.

بدین ترتیب تیم آن‌ها این مسئله را از طریق ساخت یک چت‌بات بومی داخل اپلیکیشن حل کرد. این چت‌بات به کاربران کمک می‌کند که مهارت‌های محاوره‌ای را بیاموزند و آن چه را که آموخته‌اند تمرین کنند.

NLTK

از آنجا که ربات‌ها به صورت محاوره‌ای و دوستانه طراحی شده‌اند، یادگیرندگان Duolingo می‌توانند هر زمان در طی روز با آن‌ها گفتگو کنند و از شخصیت‌هایی که خودشان استفاده می‌کنند بهره بگیرند تا این که آن قدر شجاعت پیدا بکنند که زبان جدیدشان را با گویشوران دیگر نیز تمرین کنند. بدین ترتیب یکی از دغدغه‌های اصلی مشتریان حل و یادگیری از طریق این اپلیکیشن بسیار جالب‌تر شد.

چت‌بات چیست؟

یک «چت‌بات» (chatbot) در واقع نوعی نرم‌افزار بهره گرفته از هوش مصنوعی روی یک دستگاه (مانند Siri ،Alexa ،Google Assistant و غیره)، اپلیکیشن، وب‌سایت یا دیگر شبکه‌ها است که تلاش می‌کند نیازهای مشتری را سنجیده و سپس به آن‌ها در اجرای وظایف خاص مانند تراکنش تجاری، رزرو هتل، تحویل فرم و غیره کمک کند. امروزه تقریباً همه شرکت‌ها یک چت‌بات را مورد استفاده قرار می‌دهند تا به ارزیابی کاربران بپردازند. برخی از روش‌هایی که شرکت‌ها از چت‌بات‌ها استفاده می‌کنند به شرح زیر هستند:

  • ارائه اطلاعات پرواز
  • اتصال مشتری‌ها و حساب‌های مالی
  • پشتیبانی از مشتری
  • امکانات بهره‌گیری از چت‌بات‌ها (تقریباً) نامحدود است.

تاریخچه چت‌بات‌ها به سال 1966 بازمی‌گردد که یک برنامه رایانه‌ای به نام ELIZA از سوی Weizenbaum اختراع شد. این چت‌بات، زبان یک روان‌درمانگر را با تنها 200 خط کد تقلید می‌کرد. شما می‌توانید در این آدرس (+) با الیزا صحبت کنید.

NLTK

چت‌بات چگونه کار می‌کند؟

به طور عمده دو نسخه از چت‌بات وجود دارد که یکی «مبتنی بر قواعد» (Rule-Based) و دیگری «خودآموز» (Self Learning) است.

  • ربات در یک رویکرد مبتنی بر قواعد، به سؤالات بر مبنای برخی قواعد که برای آن‌ها آموزش دیده است پاسخ می‌دهد. این قواعد ممکن است بسیار ساده و یا بسیار پیچیده تعریف شده باشند. این ربات‌ها می‌توانند کوئری‌های ساده را مدیریت کنند؛ اما در مدیریت کوئری‌های پیچیده ناتوان هستند.
  • ربات‌های «خودآموز» آن‌هایی هستند که از برخی رویکردهای مبتنی بر یادگیری ماشین استفاده می‌کنند و قطعاً بسیار کارآمدتر از ربات‌های مبتنی بر قواعد هستند. این ربات‌ها خود می‌توانند بر دو نوع باشند: «مبتنی بر بازیابی» (Retrieval Based) و یا «تولیدی» (Generative).

مدل‌های مبتنی بر بازیابی

در این مدل‌ها یک چت‌بات از نوعی شهود برای انتخاب یک پاسخ از کتابخانه‌ای از پاسخ‌های از پیش تعریف‌شده اقدام می‌کند. این چت‌بات از پیام و زمینه مکالمه برای انتخاب بهترین پاسخ از یک فهرست از پیش تعریف شده از پیام‌های ربات استفاده می‌کند. زمینه گفتگو می‌تواند شامل موقعیت کنونی در یک درخت گفتگو، همه مکالمه‌های قبلی در گفتگو، متغیرهای ذخیره شده قبلی (مانند نام‌های کاربری) و موارد دیگر باشد. شهود برای انتخاب پاسخ‌ها می‌تواند به روش‌های مختلفی مهندسی شود که از منطق شرطی if-else مبتنی بر قواعد تا روش‌های طبقه‌بندی یادگیری ماشین متفاوت است.

مدل‌های تولیدی

ربات‌ها می‌توانند پاسخ‌ها را تولید هم بکنند و لازم نیست که همواره از میان یک مجموعه از پاسخ‌های از پیش تعریف شده انتخاب کنند. این وضعیت موجب می‌شود که آن‌ها به موجودات هوشمندی تبدیل شوند و با انتخاب کلمه به کلمه از کوئری، پاسخ‌ها را تولید کنند.

NLTK

در این مقاله ما یک چت‌بات ساده مبتنی بر بازیابی به وسیله کتابخانه NLTK پایتون می‌سازیم.

ساخت ربات

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

پیش‌نیازها

فرض شده است که شما دانش ابتدایی در مورد کتابخانه scikit و NLTK دارید. با این وجود اگر در حوزه NLP مبتدی هستید، همچنان می‌توانید از این مقاله بهره بگیرید و سپس به منابع بازگردید.

NLP

این رشته مطالعاتی روی تعامل‌های بین زبان انسانی و رایانه‌ها تمرکز دارد و «پردازش زبان طبیعی» (Natural Language Processing) یا به اختصار NLP نامیده می‌شود. این حوزه از علم در تقاطع بین علوم رایانه، هوش مصنوعی و زبان‌شناسی رایانشی قرار می‌گیرد. NLP روشی است که رایانه‌ها استفاده‌ می‌کنند تا زبان انسانی را به روشی هوشمندانه و مفید، تحلیل، درک و معنایابی کنند. توسعه‌دهنده‌ها با بهره‌گیری از NLP می‌توانند دانش اجرای وظایفی مانند خلاصه‌سازی خودکار، ترجمه، شناسایی موجودیت‌های نامدار، استخراج رابطه، تحلیل احساسی، بازشناسی گفتار و دسته‌بندی موضوعی را به دست آورند.

مقدمه مختصری در خصوص NLTK

NLTK که اختصاری برای عبارت «کیت ابزار زبان طبیعی» (Natural Language Toolkit) است یک پلتفرم پیشرو برای ساخت برنامه‌های پایتون با داده‌های زبان انسانی محسوب می‌شود. این پلتفرم اینترفیس‌های سهل‌الاستفاده‌ای برای بیش از 50 منبع متنی و واژگانی مانند WordNet ارائه می‌کند و مجموعه‌ای از کتابخانه‌های پردازش متن برای طبقه‌بندی، توکن سازی، «ریشه‌یابی» (stemming)، تگ گذاری، تجزیه و استدلال احساسی و پوشش‌هایی برای کتابخانه‌های NLP قدرتمند ارائه می‌کند.

NLTK به نام «یک ابزار شگفت‌انگیز برای یادگیری و کار در زمینه زبان‌شناسی رایانشی در پایتون» و «یک کتابخانه عالی برای کار با زبان طبیعی» توصیف شده است.

کتاب پردازش زبان طبیعی در پایتون (+) یک مقدمه عملی برای برنامه‌نویسی پردازش زبان ارائه کرده است. مطالعه این کتاب را برای افرادی که قصد آغاز کار با NLP در پایتون را دارند، توصیه می‌کنیم.

دانلود و نصب NLTK

برای نصب NLTK دستور زیر را اجرا کنید:

pip install nltk

با اجرای دستورهای زیر می‌توانید از صحت نصب مطمئن شوید:

python

import nltk

نصب پکیج‌های NLTK

NLTK را ایمپورت و دستور زیر را اجرا کنید:

nltk.download()

دستور فوق دانلود کننده NLTK را باز می‌کند و در این بخش می‌توانید مجموعه متون و مدل‌هایی که می‌خواهید دانلود کنید را انتخاب نمایید. همچنین می‌توانید همه پکیج‌ها را به یک باره انتخاب کنید.

پیش‌پردازش متن با NLTK

مشکل اصلی در داده‌های متنی این است که کلاً در قالب متن (String) هستند. با این حال، الگوریتم‌های یادگیری ماشین به نوعی بردار ویژگی عددی نیاز دارند تا بتوانند وظایف خود را اجرا کنند. بنابراین پیش از آغاز کار روی هر پروژه NLP باید آن را پیش‌پردازش کنیم تا برای کار مناسب‌سازی شود. مراحل مقدماتی پیش‌پردازش شامل موارد زیر هستند:

  • تبدیل کل متن به حالت حروف بزرگ یا حروف کوچک. بدین ترتیب الگوریتم با کلمه یکسان در حالت‌های مختلف، به روش متفاوتی برخورد نمی‌کند.
  • توکن سازی: توکن سازی اصطلاحی است که برای توصیف فرایند تبدیل رشته‌های متنی معمولی به فهرستی از توکن‌ها یعنی کلماتی که در عمل می‌خواهیم گفته می‌شود. توکن ساز جمله می‌تواند برای یافتن فهرستی از جمله‌ها و توکن ساز کلمه می‌تواند برای یافتن فهرستی از کلمات در رشته استفاده شود.

پکیج‌های داده NLTK شامل توکن‌سازهای از پیش آموزش دیده Punkt برای زبان انگلیسی هستند.

  • حذف Noise: هر چیزی که یک حرف یا عدد استاندارد نباشد از متن حذف می‌شود.
  • حذف Stop Words: در برخی موارد کلمات بسیار متداول که به ظاهر ارزش بسیار کمی در کمک به انتخاب سندها و تطبیق نیازهای کاربر دارند به کلی از واژه‌نامه حذف می‌شوند. این کلمه‌ها به نام Stop words نامیده می‌شوند.
  • «ریشه‌یابی» (Stemming): ریشه‌یابی فرایندی است که در آن کلمات مشتق شده یا دارای پسوند به شکل بن یا ریشه خود تبدیل می‌شوند که عموماً شکل نوشتاری کلمه است. برای ارائه مثالی از ریشه‌یابی باید بگوییم که اگر بخواهیم کلمه‌های Stems ،Stemming ،Stemmed و Stemtization را ریشه‌یابی کنیم به کلمه stem می‌رسیم.
  • «بن‌واژه‌سازی» (Lemmatization): این روش نسخه کمی متفاوت از ریشه‌یابی است. تفاوت اصلی بین این دو آن است که در ریشه‌یابی در اغلب موارد می‌توان کلمات ناموجود به دست آورد، در حالی که بن‌واژه‌ها کلماتی واقعی هستند. بنابراین کلمه ریشه‌یابی شده که در انتهای فرایند ریشه‌یابی به دست می‌آید، ممکن است چیزی نباشد که بتوان آن را در یک فرهنگ لغت پیدا کرد؛ اما بن‌واژه را حتماً می‌توان در واژه‌نامه‌ها پیدا کرد. نمونه‌هایی از بن‌واژه‌سازی کلمه run است که بن‌واژه‌ای برای کلماتی مانند running یا ran است و همچنین کلماتی مانند better یا good در بن‌واژه مشترکی قرار دارند و از این رو دارای بن‌واژه مشترکی محسوب می‌شوند.

کیسه کلمات (Bag of Words)

پس از مرحله ابتدایی پیش‌پردازش متن باید آن را به یک بردار (یا آرایه‌ای) معنی‌دار از اعداد تبدیل کنیم. کیسه کلمات یک بازنمایی از متن محسوب می‌شود که به توصیف رخداد کلمه‌ها درون یک سند می‌پردازد. این مدل‌سازی دو نکته دارد:

  • یک واژه‌نامه از کلمه‌های شناخته‌شده
  • معیاری از وجود کلمه‌های شناخته‌شده

شاید از خود بپرسید چرا آن را «کیسه» کلمات می‌نامیم؟ دلیل این امر آن است که در این فاز هر اطلاعاتی در مورد ترتیب یا ساختار کلمه‌ها در سند حذف می‌شود و مدل تنها به بررسی این نکته می‌پردازد که آیا کلمه شناخته‌شده مفروض در سند موجود است و محل رخداد آن مهم نیست.

شهودی که در پس کیسه کلمات قرار دارد این است که سندهای متنی در صورت داشتن محتوای مشابه، مشابه نگریسته می‌شوند. ضمناً این که می‌توانیم صرفاً از روی محتوای یک سند در مورد معنای آن نتایجی به دست آوریم.

برای نمونه اگر یک واژه‌نامه شامل کلمه‌های {Learning, is, the, not, great} باشد و بخواهیم متن «Learning is great» را بردارسازی بکنیم به بردار زیر می‌رسیم:

(1, 1, 0, 0, 1)

رویکرد TF-IDF

یک مشکل رویکرد کیسه کلمات این است که کلمه‌های با فراوانی بالا بر کل سند احاطه می‌یابند (یعنی امتیاز بالاتری کسب می‌کنند) اما ممکن است محتوای آگاهی‌بخش زیادی را شامل نشوند. ضمناً به سندهای طولانی‌تر وزن بیشتری نسبت به سندهای کوتاه‌تر می‌دهد.

یک رویکرد به این مسئله آن است که فراوانی کلمه‌ها را برحسب این که چه مقدار در همه سندها ظاهر می‌شوند مقیاس‌بندی مجدد بکنیم و بدین ترتیب امتیازهای کلمه‌های با فراوانی بالا مانند the در همه سندها بالا خواهد بود و از این رو اثرشان خنثی می‌شود. این رویکرد به امتیازبندی به نام «فراوانی اصطلاح-معکوس فراوانی سند» (Term Frequency-Inverse Document Frequency) یا به اختصار TF-IDF نامیده می‌شود که در آن موارد زیر برقرار است.

Term Frequency یک امتیازبندی از فراوانی کلمه مفروض در سند کنونی است:

TF = (Number of times term t appears in a document)/(Number of terms in the document)

و Inverse Document Frequency امتیازبندی میزان نادر بودن کلمه در سندهای دیگر است:

IDF = 1+log(N/n), where, N is the number of documents and n is the number of documents a term t has appeared in.

وزن TF-IDF وزنی است که غالباً در بازیابی اطلاعات و متن‌کاوی مورد استفاده قرار می‌گیرد. این وزن یک معیار آماری است که برای ارزیابی میزان مهم بودن کلمه در یک سند در مجموعه متنی استفاده می‌شود:

مثال:

سندی را در نظر بگیرید که شامل 100 کلمه است و کلمه phone در آن 5 بار آمده است. فراوانی اصطلاح (یعنی TF) برای phone برابر با 0.05 = 100/5 است. اکنون فرض کنید سندی با 100 میلیون کلمه داریم که کله phone در هزار مورد در آن تکرار شده است. در این صورت معکوس فراوانی سند (IDF) به صورت 4 = 1000000/1000 محاسبه می‌شود. از این رو وزن TF-IDF نهایی برابر با 0.20 = 4 * 0.05 خواهد بود.

TF-IDF می‌تواند در یادگیری Scikit به صورت زیر استفاده شود:

from sklearn.feature_extraction.text import TfidfVectorizer

مشابهت کسینوس (Cosine Similarity)

TF-IDF یک تبدیل است که روی متن‌ها اعمال می‌شود تا دو بردار با ارزش واقعی در فضای برداری به دست آید. سپس می‌توانیم مشابهت کسینوسی هر جفت از بردارها را با انتخاب ضرب نقطه‌ای آن‌ها و تقسیم کردن بر حاصل نرم‌هایشان به دست آوریم. بدین ترتیب کسینوس زاویه بین بردارها به دست می‌آید. مشابهت کسینوسی معیاری برای مشابهت بین دو بردار غیر صفر محسوب می‌شود. با استفاده از این فرمول می‌توانیم مشابهت بین دو سند d1 و d2 را به صورت زیر پیدا کنیم:

Cosine Similarity (d1, d2) = Dot product(d1, d2) / ||d1|| * ||d2||

که d1 و d2 دو بردار غیر صفر هستند.

اکنون ایده نسبتاً جامعی از پردازش NLP داریم و زمان آن رسیده است که کار واقعی خود یعنی ایجاد یک چت‌بات را آغاز کنیم. ما چت‌بات خود را به صورت ROBO نامگذاری می‌کنیم.

ایمپورت کردن کتابخانه‌های مورد نیاز

برای ایمپورت کردن کتابخانه‌های مورد نیاز می‌توانید از دستورهای زیر استفاده کنید:

import nltk
import numpy as np
import random
import string # to process standard python strings

مجموعه متون

ما در خصوص مثال مورد بررسی‌مان از صفحه ویکی‌پدیا در مورد چت‌بات‌ها (+) استفاده خواهیم کرد. محتوای صفحه را کپی کرده و آن را در یک فایل متنی به نام chatbot.txt قرار دهید. البته شما می‌توانید از هر مجموعه متنی بنا به دلخواه خود استفاده کنید.

خواندن داده‌ها

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

در ادامه مثالی از sent_tokens و word_tokens می‌بینید:

پیش‌پردازش متن خام

اکنون باید تابعی تعریف کنیم که LemTokens نام دارد و توکن‌ها را به عنوان ورودی می‌گیرد و توکن‌های نرمال‌سازی شده را بازگشت می‌دهد:

تطبیق کلیدواژه

سپس تابعی تعریف خواهیم کرد که وظیفه خوشامدگویی از سوی بات را بر عهده دارد، یعنی اگر یک کاربر سلام بکند، ربات در ادامه با سلام و خوشامدگویی پاسخ می‌دهد. ELIXA از یک تطبیق کلیدواژه ساده برای خوشامدگویی استفاده می‌کند. ما نیز در اینجا از مفاهیم مشابهی استفاده می‌کنیم.

تولید پاسخ‌ها

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

از کتابخانه scikit learn ماژول TFidf vectorizer (+) را ایمپورت می‌کنیم تا یک مجموعه از سندهای خام را به ماتریسی از ویژگی‌های TF-IDF تبدیل کنیم.

from sklearn.feature_extraction.text import TfidfVectorizer

همچنین ماژول cosine similarity (+) را از کتابخانه scikit learn ایمپورت می‌کنیم.

from sklearn.metrics.pairwise import cosine_similarity

این ماژول برای یافتن مشابهت بین کلمه‌های واردشده از سوی کاربر و کلمه‌های موجود در متن استفاده می‌شود. این ساده‌ترین پیاده‌سازی ممکن برای یک چت‌بات محسوب می‌شود.

ما یک تابع به نام response تعریف می‌کنیم که رویکرد کاربر به یک یا چند مورد از کلیدواژه‌های شناخته‌شده را جستجو کرده و چند پاسخ ممکن را بازگشت می‌دهد. اگر مورد مطابقت ورودی برای هیچ کلیدواژه‌ای را پیدا نکند، یک پاسخ به صورت: «متأسفم، سخن شما را درک نکردم» (I am sorry! I don’t understand you) بازگشت می‌دهد.

در نهایت خطوطی را که می‌خواهیم ربات در زمان آغاز و خاتمه مکالمه بسته به ورودی کاربر بیان کند را تعریف می‌کنیم.

بدین ترتیب کار ما تقریباً به پایان رسیده است. ما نخستین چت‌بات خود را در NLTK کدنویسی کرده‌ایم. شما می‌توانید کل کد را به همراه مجموعه متنی در این آدرس گیت‌هاب (+) مشاهده کنید.

کد منبع کامل چت‌بات ما به صورت زیر است:

اینک نوبت آن رسیده است که ببینیم ربات ما چگونه با انسان‌ها تعامل می‌کند:

عملکرد آن چندان هم بد نیست. علی رغم این که چت‌بات نمی‌تواند پاسخ رضایت‌بخشی به برخی سئوالات بدهد، اما در مورد برخی سؤال‌های دیگر به خوبی عمل می‌کند.

سخن پایانی

با این که چت‌بات ما یک ربات بسیار ساده محسوب می‌شود و مهارت‌های شناختی آن کاملاً محدود است، اما روشی مناسب برای آشنایی با NLP و چت‌بات‌ها به حساب می‌آید. اگر چه ROBO به ورودی کاربر پاسخ می‌دهد، اما نمی‌توانید با آن دوستانتان را فریب بدهید و برای یک سیستم production باید به یکی از پلتفرم‌ها یا فریمورک‌های موجود مراجعه کنید. این نمونه به شما کمک می‌کند که در مورد طراحی و چالش‌های ایجاد یک چت‌بات تأمل بکنید. اینترنت مملو از منابع مختلف است و پس از خواندن این مقاله مطمئن هستیم که در خصوص ایجاد یک چت‌بات برای خودتان بسیار مشتاق شده‌اید.

اگر این مطلب برای شما مفید بوده است، آموزش‌های زیر نیز به شما پیشنهاد می‌شوند:

==

telegram
twitter

میثم لطفی

«میثم لطفی» دانش‌آموخته کارشناسی ریاضیات کاربردی و شیفته فناوری به خصوص در حوزه رایانه است. وی در حال حاضر علاوه بر پیگیری همه علاقه‌مندی‌های خود در رشته‌های برنامه‌نویسی، کپی‌رایتینگ و تولید محتوای چندرسانه‌ای، در زمینه نگارش مقالاتی با محوریت نرم‌افزار نیز با مجله فرادرس همکاری دارد.

آیا این مطلب برای شما مفید بود؟

نظر شما چیست؟

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *