Dalam konteks hype universal tentang Coronavirus, saya memutuskan untuk melakukan setidaknya sesuatu yang bermanfaat (tapi tidak kurang hype). Dalam artikel ini saya akan berbicara tentang cara membuat dan menggunakan Telegram Bot menggunakan metode NLP Berbasis Aturan dalam 2,5 jam (itulah yang membuat saya perlu) untuk menjawab pertanyaan FAQ menggunakan kasus COVID-19 sebagai contoh.Dalam pekerjaan, kita akan menggunakan Python tua yang baik, API Telegram, beberapa pustaka NLP standar, serta Docker.

Menit Perawatan UFO
Pandemi COVID-19, infeksi pernafasan akut yang berpotensi parah yang disebabkan oleh coronavirus SARS-CoV-2 (2019-nCoV), telah secara resmi diumumkan di dunia. Ada banyak informasi tentang Habré tentang topik ini - selalu ingat bahwa Habré dapat diandalkan / bermanfaat, dan sebaliknya.
Kami mendesak Anda untuk kritis terhadap informasi apa pun yang dipublikasikan.
Cuci tangan, rawat orang yang Anda cintai, tinggal di rumah kapan saja memungkinkan dan bekerja dari jarak jauh.
Baca publikasi tentang: coronavirus | kerja jarak jauh
Kata Pengantar Singkat
Artikel ini menjelaskan proses membuat Bot Telegram sederhana menjawab pertanyaan FAQ pada COVID-19. Teknologi pengembangan sangat sederhana dan serbaguna, dan dapat digunakan untuk kasus lain. Saya menekankan sekali lagi bahwa saya tidak berpura-pura sebagai Negara Seni, tetapi hanya menawarkan solusi sederhana dan efektif yang dapat digunakan kembali.Karena saya percaya bahwa pembaca artikel ini sudah memiliki pengalaman dengan Python, kami akan menganggap bahwa Anda sudah menginstal Python 3.X dan alat pengembangan yang diperlukan (PyCharm, VS Code), Anda dapat membuat Bot di Telegram melalui BotFather, dan oleh karena itu, saya akan melewatkan hal-hal ini.1. Konfigurasi API
Hal pertama yang perlu Anda instal adalah library wrapper untuk API Telegram " python-telegram-bot ". Perintah standar untuk ini adalah:pip install python-telegram-bot --upgrade
Selanjutnya, kami akan membangun kerangka kerja program kecil kami dengan mendefinisikan "penangan" untuk acara Bot berikut:- mulai - perintah peluncuran Bot;
- help - help command (bantuan);
- pesan - pemrosesan pesan teks;
- kesalahan - kesalahan.
Tanda tangan dari penangan akan terlihat seperti ini:def start(update, context):
pass
def help(update, context):
pass
def message(update, context):
pass
def error(update, context):
pass
Selanjutnya, dengan analogi dengan contoh dari dokumentasi perpustakaan, kami mendefinisikan fungsi utama di mana kami menetapkan semua penangan ini dan memulai bot: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()
Saya menarik perhatian Anda pada kenyataan bahwa ada 2 mekanisme cara meluncurkan bot:- Polling Standar - polling berkala Bot menggunakan alat API Telegram standar untuk acara baru (
updater.start_polling()
); - Webhook - kami memulai server kami dengan titik akhir, tempat peristiwa dari bot tiba, memerlukan HTTPS.
Seperti yang sudah Anda perhatikan, untuk kesederhanaan kami menggunakan Polling standar.2. Kami mengisi penangan standar dengan logika
Mari kita mulai dengan yang sederhana, mengisi awal dan membantu penangan dengan jawaban standar, kita mendapatkan sesuatu seperti ini: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)
Sekarang, ketika pengguna mengirim / memulai atau / membantu perintah, mereka akan menerima jawaban yang ditentukan oleh kami. Saya menarik perhatian Anda pada fakta bahwa teks diformat dalam Markdownparse_mode=telegram.ParseMode.MARKDOWN
Selanjutnya, tambahkan logging kesalahan ke penangan kesalahan:def error(update, context):
"""Log Errors caused by Updates."""
logger.warning('Update "%s" caused error "%s"', update, context.error)
Sekarang, mari kita periksa apakah Bot kita berfungsi. Menyalin seluruh kode yang ditulis dalam satu file, misalnya app.py . Tambahkan impor yang diperlukan .Jalankan file dan pergi ke Telegram ( jangan lupa untuk memasukkan Token Anda ke dalam kode ). Kami menulis perintah / mulai dan / membantu dan bersukacita:
3. Kami memproses pesan dan menghasilkan respons
Hal pertama yang perlu kita jawab adalah Basis Pengetahuan. Hal paling sederhana yang dapat Anda lakukan adalah membuat file json sederhana dalam bentuk nilai Key-Value, di mana Key adalah teks dari pertanyaan yang diajukan, dan Value adalah jawaban untuk pertanyaan itu. Contoh Basis Pengetahuan:{
" ?": " — . - , , , . , , . , .",
" ?": " :\n \n \n \n \n\n , .",
" ?": " :\n- ( , , )\n- ( )",
}
Algoritma untuk menjawab pertanyaan adalah sebagai berikut:- Kami mendapatkan teks pertanyaan dari pengguna;
- Lemasi semua kata dalam teks pengguna;
- Kami tidak dengan jelas membandingkan teks yang dihasilkan dengan semua pertanyaan lemmatized dari basis pengetahuan ( jarak Levenshtein );
- Kami memilih pertanyaan yang paling "mirip" dari basis pengetahuan;
- Kami mengirim jawaban untuk pertanyaan yang dipilih kepada pengguna.
Untuk mengimplementasikan rencana kami, kami membutuhkan perpustakaan: fuzzywuzzy (untuk perbandingan fuzzy) dan pymorphy2 (untuk lemmatization).Buat file baru dan terapkan algoritma yang terdengar: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
Sebelum menulis penangan pesan, kami akan menulis fungsi yang menyimpan riwayat korespondensi dalam file 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)
Sekarang, kami menggunakan metode yang kami tulis dalam pesan teks pesan penangan pesan: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)
Voila, sekarang pergi ke Telegram dan nikmati tulisannya:
4. Konfigurasikan Docker dan gunakan aplikasi
Seperti yang dikatakan klasik: "Jika Anda mengeksekusi, maka itu indah untuk dieksekusi.", Sehingga kami memiliki segalanya sebagai orang, kami akan mengonfigurasikan containerization menggunakan Docker Compose.Untuk ini kita perlu:- Buat Dockerfile - mendefinisikan gambar wadah dan titik masuk;
- Buat docker-compose.yml - meluncurkan banyak wadah menggunakan Dockerfile tunggal (dalam kasus kami itu tidak perlu, tetapi jika Anda memiliki banyak layanan, itu akan berguna.)
- Buat boot.sh (skrip bertanggung jawab langsung untuk meluncurkan).
Jadi, isi 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"]
Isi dari 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
Isi dari 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
Jadi, kami siap, untuk memulai semua ini, Anda perlu menjalankan perintah berikut di folder proyek:sudo docker build -t covid19_rus_bot:latest .
sudo docker-compose up
Itu dia, bot kami sudah siap.Alih-alih sebuah kesimpulan
Seperti yang diharapkan, semua kode tersedia di repositori .Pendekatan ini, yang ditunjukkan oleh saya, dapat diterapkan dalam hal apa pun untuk menjawab pertanyaan FAQ, sesuaikan basis pengetahuan! Mengenai basis pengetahuan, itu juga dapat ditingkatkan dengan mengubah struktur Kunci dan Nilai menjadi array, sehingga setiap pasangan akan menjadi array pertanyaan potensial pada satu topik dan array jawaban potensial untuk mereka (untuk berbagai jawaban, Anda dapat memilih secara acak). Secara alami, pendekatan Berbasis Aturan tidak terlalu fleksibel untuk penskalaan, tetapi saya yakin bahwa pendekatan ini akan tahan terhadap basis pengetahuan dengan sekitar 500 pertanyaan.Mereka yang telah membaca sampai akhir saya mengundang Anda untuk mencoba Bot saya di sini .