في سياق الضجيج العالمي على Coronavirus ، قررت أن أفعل شيئًا مفيدًا على الأقل (ولكن ليس أقل من الضجيج). في هذه المقالة سأتحدث عن كيفية إنشاء ونشر Telegram Bot باستخدام أساليب البرمجة اللغوية العصبية المستندة إلى القواعد في 2.5 ساعة (هذا هو مقدار الوقت الذي استغرقته) للإجابة على أسئلة الأسئلة الشائعة باستخدام حالة COVID-19 كمثال.في سياق العمل ، سنستخدم Python القديم الجيد ، Telegram API ، واثنين من مكتبات NLP القياسية ، وكذلك Docker.

دقيقة العناية UFO
تم الإعلان رسمياً عن وباء COVID-19 الوبائي ، وهو عدوى تنفسية حادة حادة محتملة ناجمة عن الفيروس التاجي SARS-CoV-2 (2019-nCoV) ، في العالم. هناك الكثير من المعلومات حول حبري حول هذا الموضوع - تذكر دائمًا أنه يمكن أن يكون موثوقًا / مفيدًا ، والعكس صحيح.
نحثك على انتقاد أي معلومات منشورة.
اغسل يديك ، ورعاية أحبائك ، والبقاء في المنزل كلما أمكن ذلك والعمل عن بعد.
قراءة المنشورات حول: فيروسات التاجية | العمل عن بعد
مقدمة موجزة
توضح هذه المقالة عملية إنشاء بوت Telegram بسيط للإجابة على أسئلة الأسئلة الشائعة حول COVID-19. تكنولوجيا التطوير بسيطة للغاية ومتعددة الاستخدامات ، ويمكن استخدامها في أي حالات أخرى. أؤكد مرة أخرى أنني لا أتظاهر بأنني دولة حديثة ، ولكني أقدم فقط حلًا بسيطًا وفعالًا يمكن إعادة استخدامه.نظرًا لأنني أعتقد أن قارئ هذه المقالة لديه بالفعل بعض الخبرة مع Python ، فإننا نفترض أن لديك بالفعل Python 3.X مثبت وأدوات التطوير الضرورية (PyCharm ، VS Code) ، يمكنك إنشاء بوت في Telegram عبر BotFather ، و لذلك ، سوف أتخطى هذه الأشياء.1. تكوين API
أول شيء تحتاج إلى تثبيته هو مكتبة الغلاف لـ Telegram API " python-telegram-bot ". الأمر القياسي لهذا هو:pip install python-telegram-bot --upgrade
بعد ذلك ، سنقوم ببناء إطار برنامجنا الصغير من خلال تحديد "معالجات" لأحداث Bot التالية:- بدء - أمر إطلاق بوت ؛
- مساعدة - أمر مساعدة (مساعدة) ؛
- رسالة - معالجة الرسائل النصية ؛
- خطأ - خطأ.
سيبدو توقيع المعالجات كما يلي:def start(update, context):
pass
def help(update, context):
pass
def message(update, context):
pass
def error(update, context):
pass
بعد ذلك ، عن طريق القياس مع المثال من وثائق المكتبة ، نحدد الوظيفة الرئيسية التي نعين فيها كل هذه المعالجات ونبدأ الروبوت:def get_answer():
"""Start the bot."""
updater = Updater("Token", use_context=True)
dp = updater.dispatcher
dp.add_handler(CommandHandler("start", start))
dp.add_handler(CommandHandler("help", help))
dp.add_handler(MessageHandler(Filters.text, message))
dp.add_error_handler(error)
updater.start_polling()
updater.idle()
if __name__ == "__main__":
get_answer()
أوجه انتباهكم إلى حقيقة وجود آليتين لكيفية إطلاق الروبوت:- الاستطلاع القياسي - الاستقصاء الدوري للبوت باستخدام أدوات Telegram API القياسية للأحداث الجديدة (
updater.start_polling()
) ؛ - Webhook - نبدأ الخادم الخاص بنا بنقطة نهاية ، حيث تصل الأحداث من البوت ، يتطلب HTTPS.
كما لاحظت بالفعل ، من أجل البساطة ، نستخدم الاستقصاء القياسي.2. نملأ المعالجات القياسية بالمنطق
لنبدأ بأخرى بسيطة ، واملأ البداية وساعد المعالجات بالإجابات القياسية ، نحصل على شيء مثل هذا:def start(update, context):
"""Send a message when the command /start is issued."""
update.message.reply_text("""
!
COVID-19.
:
- * ?*
- * ?*
- * ?*
..
!
""", parse_mode=telegram.ParseMode.MARKDOWN)
def help(update, context):
"""Send a message when the command /help is issued."""
update.message.reply_text("""
( COVID-19).
:
- * ?*
- * ?*
- * ?*
..
!
""", parse_mode=telegram.ParseMode.MARKDOWN)
الآن ، عندما يرسل المستخدم أوامر / start أو / help ، سيتلقى الإجابة المحددة من قبلنا. ألفت انتباهكم إلى حقيقة أن النص تم تنسيقه في ماركداونparse_mode=telegram.ParseMode.MARKDOWN
بعد ذلك ، أضف تسجيل الأخطاء إلى معالج الأخطاء:def error(update, context):
"""Log Errors caused by Updates."""
logger.warning('Update "%s" caused error "%s"', update, context.error)
الآن ، دعونا نتحقق مما إذا كان برنامج Bot يعمل. نسخ رمز كله مكتوب في ملف واحد، على سبيل المثال app.py . أضف المستوردات اللازمة .قم بتشغيل الملف وانتقل إلى Telegram ( لا تنس إدخال الرمز الخاص بك في الرمز ). نكتب الأوامر / البداية و / المساعدة ونفرح:
3. نقوم بمعالجة الرسالة وإنشاء استجابة
أول شيء نحتاجه للإجابة على السؤال هو قاعدة المعارف. إن أبسط شيء يمكنك القيام به هو إنشاء ملف json بسيط على شكل قيم Key-Value ، حيث Key هو نص السؤال المقترح ، و Value هي إجابة السؤال. مثال قاعدة المعرفة:{
" ?": " — . - , , , . , , . , .",
" ?": " :\n \n \n \n \n\n , .",
" ?": " :\n- ( , , )\n- ( )",
}
ستكون خوارزمية الإجابة على السؤال كما يلي:- نحصل على نص السؤال من المستخدم ؛
- Lemmatize جميع الكلمات في نص المستخدم ؛
- نحن لا نقارن بوضوح النص الناتج مع جميع الأسئلة المميتة من قاعدة المعرفة ( مسافة Levenshtein ) ؛
- نختار السؤال الأكثر "مماثلة" من قاعدة المعرفة ؛
- نرسل إجابة السؤال المحدد إلى المستخدم.
لتنفيذ خططنا ، نحتاج إلى مكتبات: fuzzywuzzy ( لمقارنات غامضة) و pymorphy2 (ل lemmatization).قم بإنشاء ملف جديد وتنفيذ الخوارزمية السليمة:import json
from fuzzywuzzy import fuzz
import pymorphy2
morph = pymorphy2.MorphAnalyzer()
with open("faq.json") as json_file:
faq = json.load(json_file)
def classify_question(text):
text = ' '.join(morph.parse(word)[0].normal_form for word in text.split())
questions = list(faq.keys())
scores = list()
for question in questions:
norm_question = ' '.join(morph.parse(word)[0].normal_form for word in question.split())
scores.append(fuzz.token_sort_ratio(norm_question.lower(), text.lower()))
answer = faq[questions[scores.index(max(scores))]]
return answer
قبل كتابة معالج الرسائل ، سنكتب دالة تحفظ محفوظات المراسلات في ملف tsv:def dump_data(user, question, answer):
username = user.username
full_name = user.full_name
id = user.id
str = """{username}\t{full_name}\t{id}\t{question}\t{answer}\n""".format(username=username,
full_name=full_name,
id=id,
question=question,
answer=answer)
with open("/data/dump.tsv", "a") as myfile:
myfile.write(str)
الآن ، نستخدم الطريقة التي كتبناها في رسالة معالج الرسالة النصية:def message(update, context):
"""Answer the user message."""
answer = classify_question(update.message.text)
dump_data(update.message.from_user, update.message.text, answer)
update.message.reply_text(answer)
فويلا ، انتقل الآن إلى Telegram واستمتع بالكتابة:
4. تكوين Docker ونشر التطبيق
كما قال الكلاسيكي: "إذا نفذت ، فسيكون التنفيذ جميلًا." ، حتى يكون لدينا كل شيء كأشخاص ، سنقوم بتكوين حاوية باستخدام Docker Compose.لهذا نحن بحاجة إلى:- إنشاء Dockerfile - يحدد صورة الحاوية ونقطة الإدخال ؛
- إنشاء docker-compose.yml - يُطلق العديد من الحاويات باستخدام ملف Dockerfile واحد (في حالتنا ليس ضروريًا ، ولكن في حالة وجود العديد من الخدمات ، سيكون مفيدًا.)
- قم بإنشاء boot.sh (البرنامج النصي مسؤول عن التشغيل مباشرة).
لذا ، فإن محتويات ملف Dockerfile:#
FROM python:3.6.6-slim
#
WORKDIR /home/alex/covid-bot
# requirements.txt
COPY requirements.txt ./
# Install required libs
RUN pip install --upgrade pip -r requirements.txt; exit 0
#
COPY data data
#
COPY app.py faq.json reply_generator.py boot.sh ./
#
RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
#
RUN chmod +x boot.sh
#
ENTRYPOINT ["./boot.sh"]
محتوى docker-compose.yml:# docker-compose
version: '2'
#
services:
bot:
restart: unless-stopped
image: covid19_rus_bot:latest
container_name: covid19_rus_bot
# boot.sh
environment:
- SERVICE_TYPE=covid19_rus_bot
# volume
volumes:
- ./data:/data
محتويات boot.sh:#!/bin/bash
if [ -n $SERVICE_TYPE ]
then
if [ $SERVICE_TYPE == "covid19_rus_bot" ]
then
exec python app.py
exit
fi
else
echo -e "SERVICE_TYPE not set\n"
fi
لذا ، نحن جاهزون لبدء كل هذا تحتاج إلى تنفيذ الأوامر التالية في مجلد المشروع:sudo docker build -t covid19_rus_bot:latest .
sudo docker-compose up
هذا كل شيء ، بوتنا جاهز.بدلا من الاستنتاج
كما هو متوقع ، كل الكود متاح في المستودع .يمكن تطبيق هذا النهج ، الذي أظهرته ، في أي حال للإجابة على أسئلة الأسئلة الشائعة ، ما عليك سوى تخصيص قاعدة المعرفة! فيما يتعلق بقاعدة المعرفة ، يمكن أيضًا تحسينها عن طريق تغيير بنية المفتاح والقيمة إلى صفائف ، لذلك سيكون كل زوج مجموعة من الأسئلة المحتملة حول موضوع واحد ومجموعة من الإجابات المحتملة عليها (لمجموعة متنوعة من الإجابات ، يمكنك الاختيار عشوائيًا). بطبيعة الحال ، فإن النهج القائم على القواعد ليس مرنًا جدًا للتوسع ، ولكني متأكد من أن هذا النهج سوف يتحمل قاعدة معرفية مع حوالي 500 سؤال.أولئك الذين قرأوا حتى النهاية أدعوكم لتجربة بوتي هنا .