От Джесика Круз, Сами Чиен, Девина Парихар, Алекс Текле и Саника Фансе

Въведение

Търсим да рационализираме достъпа до важна информация относно COVID-19, като разработим чатбот, който може да отговори на различни въпроси и притеснения на потребителя относно коронавируса. Част от информацията, която планираме да споделим, включва намиране на местни места за тестване, валидиране на симптоми, споделяне на ресурси за управление на безпокойството и т.н.

Планираме да обучим модела, като използваме набор от данни от туитове, които задават заявка за „COVID-19“, както и други синоними на вируса. Освен това ще използваме моделиране на теми, за да намерим клъстери от популярни и подходящи категории в набора от данни. Нашият модел ще се научи от набора от данни за туитове, за да маркира въведените от потребителите данни въз основа на теми като „брой случаи в окръг X“, „симптоми“, „опции за тестване“.

В отговора на чатбота планираме да предадем проверена информация от източници, включително CDC, СЗО и други, свързани с тяхната заявка или с резултат от полезно търсене в Google.

Получаване на туитове

Искахме да разберем по-добре как хората разговарят за COVID-19. Обмислихме няколко различни медии, но решихме, че използването на туитове ни предоставя достатъчно ресурс за диалог, свързан с COVID-19, който можем да използваме за обучение на нашия модел. Освен това туитовете често се пишат в непринуден формат, подобно на това как човек може да взаимодейства с чатбот.

След като направихме някои проучвания, открихме, че няколко изследователи са събрали всички туитове, които споменават „COVID-19“ от 10 януари. Това значително улесни работата ни, тъй като не се налагаше сами да търсим и извличаме туитове.

В този момент използвахме уникалните идентификатори на туитове в набора от данни, за да направим повиквания към API на Twitter, за да получим допълнителна информация за всеки туит, използвайки крайната точка GET statuses/show/:id. При извличане на JSON за всички туитове, ние вмъкнахме текста на туита в рамка с данни, която можехме да използваме за нашия модел. Кодът на скрипта можете да видите тук:

count=0;
df_tweets = pd.DataFrame({'tweet': []})
for filename in os.listdir('./json'):
    with jsonlines.open("./json/" + filename) as f:
        for obj in f:
            df_tweets.loc[count]=str(obj['full_text']);
            print(filename + ": " + str(count) + ". " + 
                obj['full_text']);
            count=count+1;
df_tweets.to_pickle("./tweets.pkl")
print(df_tweets.head())

Намерение за учене

Критична част от създаването на нашия чатбот беше разбирането на намерението на нашия потребител във въпросите, които може да зададат, докато разговарят с Flow. За целите на простата първа итерация ние опростихме намерението за обучение до идентифициране на темата на зададения въпрос. За да направим това, първо обработихме предварително нашия набор от туитове и след това приложихме различни неконтролирани и контролирани алгоритми за моделиране на теми.

Предварителна обработка

След като всички туитове бяха извлечени, трябваше да ги почистим и обработим предварително, преди да ги използваме като входни данни за нашите модели. За да изчистим туитовете, ние филтрирахме всички туитове, които не бяха на английски, като използвахме библиотеката langdetect и премахнахме дръжките на twitter и уеб връзките в туитовете. За предварителна обработка извадихме спиращите думи на NLTK заедно с допълнителни стоп думи като „коронавирус“, „Тръмп“ и „COVID-19“. След това токенизирахме всеки от нашите туитове, като премахнахме препинателните знаци с Gensim и последвахме с Porter stemmer на NLTK, за да спрем всяка дума в туитовете. След това тествахме както TF-IDF, така и Count Vectorizer, за да векторизираме нашите почистени и прекратени туитове. Освен това тествахме различни групи от нашия токенизиран текст в униграми, биграми или както униграми, така и биграми. За нашите базови модели решихме да използваме само TF-IDF Vectorizer с униграми. Това е така, защото Count Vectorizer ще преброи думите, които се появяват много пъти в текста, въпреки че не са много значими, а биграмите водят до смесени резултати при прогнозиране на теми и биха изисквали повече оптимизиране от позволеното време.

Моделиране без надзор

След предварителна обработка на нашите данни, бихме могли да започнем да изучаваме потребителските намерения чрез моделиране на теми. Първият ни подход беше да използваме моделиране на теми без надзор, което ще създаде определено количество клъстери, съдържащи думи и фрази, които най-добре характеризират набора от данни. Подходът без надзор изглеждаше подходящ, тъй като имахме милиони немаркирани туитове. Чрез прилагане на техники за моделиране на теми без надзор към нашия набор от данни, ние ще намерим популярните клъстери около COVID-19, след което ще използваме тези клъстери като представа за това какво потребителите могат да поискат от нашия чатбот.

С нашите предварително обработени данни изградихме два типа тематични модели като базови модели, използвайки два алгоритъма: LDA (латентно разпределение на Дирихле) и NMF (факторизация на неотрицателна матрица). Забелязахме, че двата модела се представят доста сходно с нашите данни, като някои клъстери са по-добри в LDA, а други са по-добри в NMF. Забелязахме също, че има странни клъстери и в двата модела.

Ето снимка на изхода от един от нашите базирани на NMF модели.

Както можете да видите, първият клъстер в нашия примерен резултат по-горе се състоеше от думи като „бяло момиче“ и „starbucks“. Това се дължи на популярен туит, в който се говори за „малко бяло момиче в Starbucks“ и нейните погрешни схващания за COVID-19. Въпреки че признахме, че моделът върши добра работа при намирането на най-популярните клъстери в нашия набор от данни с думи, които са силно свързани, не смятахме, че всички наши клъстери са подходящи за целта на нашия чатбот.

Надзорно моделиране

За да се борим с тези проблеми, ние започнахме да работим върху техника за моделиране на контролирана тема върху нашия набор от данни. За да избегнем проблема с нашия модел, който изхвърля неподходящи клъстери, вместо това искахме да дадем на нашия модел набор от подходящи теми за COVID-19, към които той ще може да присвоява клъстери. За да направим това, първо трябваше да присвоим етикети на нашите немаркирани данни за туитове. Това беше направено чрез използване на свързване на обекти с API на Babelfy, за да получите имена на ключови етикети за обекти, споменати в туитовете. След това филтрирахме етикетите на обекта въз основа на определени ограничения, като честота на името на етикета и връзка с COVID-19. На фигура 2 по-долу показваме 50-те най-чести обекта от извадка от около 950 туита. Може да се види как етикети като „хора“, „случаи“ и „огнище“ са най-често срещаните в този примерен набор. Може да е важно да се обмисли дали това може да доведе до дисбаланс в целевите етикети и потенциално отклонение по време на класификацията.

След разделянето на нашите данни на обучение и тестване, ние обработваме предварително обучаващите и тествани туитове с Count vectorizer и след това изпълняваме LDA, монтиран върху обучителните туитове, за да произведем нов обучаващ и тестов набор от вектори за туитове, които съдържат разпределението на темите за всеки туит.

Сега, когато имаме вектор за разпределение на теми, можем да тестваме различни контролирани класификатори (логистична регресия, OneVSRest за данни с множество етикети), които приемат тези нови вектори като входни данни и имената на обектите като целеви етикети.

Поради ограничения във времето не успяхме да етикетираме и тестваме достатъчно от нашите данни, за да получим значими показатели за ефективност, но бележникът, който работи за контролирано моделиране на теми, е в нашето хранилище на GitHub. Надяваме се да видим подобрени резултати в сравнение с нашите базови модели на неконтролирани теми.

Генериране на отговор

За да генерираме най-подходящия отговор, първо трябваше да разберем как потенциален потребител би взаимодействал с чатбота. Първоначално обмисляхме употреби като управление на безпокойството и си играехме с идеята да произвеждаме отговори, базирани на съпричастност. Въпреки това, въз основа на нашите констатации за намерението на потребителя по-горе, ние изместихме фокуса си към отговаряне на въпроси въз основа на логистиката и фактите, свързани с вируса.

Първоначалният ни опит за отговор използва генериране на текст: много модерни модели за генериране на текст като „модела GPT-2 от OpenAI“ и „BERT на Google“ бяха привлекателни. Въпреки това, предвид чувствителния характер на COVID-19 и нашия ангажимент да предоставяме фактически точни отговори, ние се отклонихме от използването на модел за генериране на текст. Не бихме могли да разчитаме на такъв модел за свързване на надеждни твърдения в 100% от времето.

След известно проучване попаднахме на този COVID-19 чатбот. Идеята да използваме ЧЗВ в техния чатбот съвпадна и с нашия случай на употреба, така че решихме да надградим върху това. Чрез добавяне на често задавани въпроси от научни източници, включително CDC, FDA, John Hopkins и Texas Human Health Services, нашият „окончателен набор от данни“ имаше 107 двойки въпроси и отговори. След това влязохме и ръчно маркирахме дали двойката има отношение към един от 14-те етикета, генерирани от алгоритъма за клъстериране по-горе. Двойка въпрос и отговор може да бъде класифицирана в множество етикети. Използването на изявления от тези доверени източници на данни като отговори на нашия чатбот ни позволи да гарантираме, че точната информация се споделя с потребителя, като същевременно ни предпазва от задължения за разпространение на фалшиви новини.

След това изградихме модел, който съпостави въпроса, зададен от потребителя, с отговор в нашата база данни, използвайки универсален енкодер на изречения.

Универсален енкодер за изречения

За да генерираме точна информация за потребителя, трябваше да намерим най-подходящия въпрос, зададен от потребителя, на който беше отговорено в ЧЗВ. Потребителите обикновено не задават въпроси, формулирани по точния начин, по който се появяват в ЧЗВ, но основната идея на техния въпрос все още обикновено е свързана с ЧЗВ. Например един въпрос с често задавани въпроси е „Мога ли да се заразя с COVID-19 от моя домашен любимец?“. Потребител може да попита „Може ли моето куче да ми даде коронавируса?“, което е почти същият въпрос и може да получи точен отговор от нашия свързан отговор на често задавани въпроси: „Няма доказателства, че куче, котка или друг домашен любимец може да предава COVID-19 .”

Открихме най-сходния въпрос с ЧЗВ на потребителската заявка с универсалния енкодер на изречения (USE) на Tensorflow. USE основно кодира текст във вектор с постоянна висока размерност. Общата идея е, че два текстови фрагмента, които имат подобни значения, ще бъдат картографирани към два вектора, които имат подобни характеристики. Сходството между векторите може да се определи числено с помощта на вътрешния продукт. Колкото по-висок е вътрешният продукт, толкова по-сходни са двете части от текста по смисъл (т.е. по-голямо семантично сходство). Намирането на въпроса в банката с въпроси на ЧЗВ, който най-много съответства на значението на въпроса на потребителя, включва кодиране на всички въпроси с ЧЗВ и въпроса на потребителя и намиране на най-високия вътрешен продукт между вектора на въпроса на потребителя и вектора на въпроса на ЧЗВ.

Тъй като нашият набор от данни за въпроси нараства, определянето на семантичното сходство отнема все повече и повече време. За да се борим с това и да дадем на потребителя разумна времева рамка за получаване на отговор, ние използваме етикета на въпроса, определен от раздела Намерение за обучение по-горе. Въпросите в често задаваните въпроси са предварително обозначени в зависимост от значението (напр. „Мога ли да заразя COVID-19 от моя домашен любимец?“ може да има етикет „куче“ или „домашен любимец“, докато „Колко тежък е COVID-19?“ не би трябвало ). Етикетът на потребителския въпрос се използва за филтриране на напълно неподходящи въпроси, за да се намали времето, необходимо на Flow да определи най-подходящия въпрос.

Тестване

Тъй като нямахме солиден набор от нови потребителски въпроси, върху които да тестваме нашия модел, измислихме тестова банка, която съдържаше 3 различни вида въпроси:

  1. „Обикновени“ въпроси, свързани с COVID-19, които съответстват на типовете въведени данни, които очакваме — правилен правопис, подобно значение на въпросите в банката с въпроси на ЧЗВ
  2. По-трудни въпроси, свързани с COVID-19, които са неправилно изписани и имат значение, което не е уловено от нашия набор от данни
  3. Въпроси, несвързани с COVID-19, или текст, който не е въпрос по смисъл

По въпроси от категория 1, Flow успя да идентифицира правилно свързаните въпроси в ЧЗВ и да отговори добре почти през цялото време. За категория 2 Flow успя да идентифицира най-подходящия въпрос дори с правописните грешки, но въпросите, чиито значения не са уловени в нашия набор от данни, не получиха добър отговор. За категория 3 Flow, както се очакваше, не излезе с никакви смислени отговори. Тъй като Flow може да отговаря само с отговори въз основа на банката с отговори на ЧЗВ, въвеждане като „Не сте много добър в отговарянето на въпроси“ няма да получи смислен отговор.

Потокът на Flow

За да определим дали на въпроса на потребителя е отговорено успешно или не, ни е необходима обратна връзка от потребителя. След като потребителят зададе въпрос, Flow отговаря с отговора на най-подходящия въпрос с ЧЗВ и подканва потребителя за обратна връзка. Ако потребителят не е доволен, Flow му показва първите 5 въпроса в ЧЗВ, които смята, че потребителят е задал, и дава опция за това, че все още не е доволен. Ако потребителят избере показан въпрос, Flow отговаря на този въпрос. Ако потребителят избере незадоволената опция, Flow извършва просто търсене в Google по заявката и връща първата връзка. По-долу е показана основна блок-схема за крайната машина на Flow.

Потребителски интерфейс

За да интегрираме различните части от нашия проект, решихме, че уеб приложение ще работи най-добре. Използвахме Flask за управление на задния Javascript/CSS за разработване на потребителския интерфейс. Освен това използвахме BotUi JS рамка с отворен код, която ни помага да създадем нашия прост интерфейс за чат.

Демонстрация

Както е показано във видеото по-горе, нашият чатбот за COVID-19 е в състояние да предостави подходяща информация въз основа на заявка на потребител. Ако чатботът не може да разбере съобщението на потребителя, той ще предостави друг уебсайт, който може да има по-подходяща информация, свързана със заявката.

Следващи стъпки

Има много стъпки в бъдеще, които се надяваме да подобрят нашия чатбот, Flow. Първо, ще използваме текст от научни статии за COVID-19 или ще използваме само туитове от проверени източници в нашия набор от данни. Едно притеснение относно нашите тематични модели беше, че данните, които използвахме, се състоеха единствено от туитове. Туитовете са добър източник на данни, тъй като съдържат различни теми, свързани с COVID-19, но съдържат и дезинформация и понякога могат да бъдат напълно неуместни. Ако използваме текст от научни статии за COVID-19, ще получим теми, които са по-точни и свързани с най-новите изследвания. Друг начин да подобрим нашия набор от данни е да използваме само туитове от проверени източници. Освен това е по-вероятно проверените източници да разполагат с подходяща и точна информация и придаването на по-голямо значение на тези туитове може също да подобри клъстерите от нашите тематични модели.

Второто бъдещо подобрение на нашия чатбот ще бъде генерирането на отговор. Един недостатък на нашия набор от данни с често задавани въпроси е, че е статичен. Нова информация за COVID-19 се открива през цялото време и след няколко месеца нашите отговори може вече да не са точни. Можем да поправим това, като изчерпим CDC, СЗО и други надеждни източници за нова информация и съответно актуализираме нашия набор от данни за ЧЗВ. Освен това е вероятно да получим входни заявки, които се задават често, но не съществуват в нашия набор от данни. Ако достатъчно потребители зададат въпроса и са доволни от същия отговор, можем също така да включим път за добавяне на тази заявка и съответния отговор към нашия набор от данни за ЧЗВ. Като се има предвид, че точността все още е нашата основна грижа, най-вероятно ще трябва да направим ръчен преглед, преди да добавим новата двойка въпрос и отговор.

И накрая, в настоящия момент Flow може да поеме само по три различни пътя. Тази негъвкавост може да затрудни потребителите, които може да искат повече информация или може да искат да имат по-малко елементарен разговор с Flow. Има много начини, по които винаги можем да подобрим държавната машина на Flow, като например да използваме рамки за чатбот като Rasa, които се опитват да уловят контекст в рамките на разговор.

В заключение, научихме много за това какво включва изграждането на чатбот. Въпреки че нашият чатбот не е перфектен, ние все пак успяхме успешно да внедрим модели за обучение и генериране на отговор в удобна за потребителя рамка, която предостави на нашите потребители достоверна информация за COVID-19.

Връзка към Github Repo

Препратки

[1] https://dzone.com/articles/python-chatbot-project-build-your-first-python-pro
[2] https://towardsdatascience.com/natural-language- разбиране-с-последователност-към-последователност-модели-e87d41ad258b
[3] https://medium.com/deep-math-machine-learning-ai/chapter-11-chatbots-to-question- answer-systems-e06c648ac22a
[4] https://chatbotsjournal.com/25-chatbot-platforms-a-comparative-table-aeefc932eaff
[5] https://github. com/echen102/COVID-19-TweetIDs
[6] https://towardsdatascience.com/how-we-created-an-open-source-covid-19-chatbot-c5c900b382df