Ваш первый чат-бот со встроенным машинным обучением в Google DialogFlow за 4 шага!

Любая модель машинного обучения бесполезна, если вы не примените ее в реальной жизни. Запустить модель на Jupyter Notebook и похвастаться точностью 99,99% не поможет. Вам нужно сделать из него сквозное приложение, чтобы представить его внешнему миру. И чат-боты - один из забавных и простых способов сделать это.

Создание чат-ботов еще никогда не было таким простым. DialogFlow от Google - очевидный выбор, поскольку он чрезвычайно простой, быстрый и бесплатный! Прежде чем продолжить, сначала попробуйте приложение здесь!

Течение

Теперь, когда вы попробовали это сделать, приступая к созданию полного приложения, мы перейдем к следующим шагам:

  1. Ваша модель машинного обучения (в данном случае Iris)
  2. Чат-бот DialogFlow, который получает данные от пользователя.
  3. Приложение Flask, развернутое на любом общедоступном хосте, которое отображает запрос и ответ.
  4. Вызов веб-перехватчика, который ваш чат-бот делает в api фляги, чтобы отправить данные и получить результат.
  5. Интеграция DialogFlow с Telegram

Мы рассмотрим каждый шаг по очереди. Давайте сначала посмотрим, как будет выглядеть архитектура нашего полного приложения:

Что случилось?

Таким образом, у пользователя есть доступ к чат-боту Telegram, который мы построим на DialogFlow и интегрируем с Telegram позже. Разговор начинается, и чат-бот предлагает пользователю ввести данные, которые являются размерами цветка (длина лепестка, ширина лепестка, длина чашелистиков и ширина чашелистиков). Как только чат-бот получит последний ввод, он вызовет веб-перехватчик API фляги, который будет развернут на общедоступном хосте. Этот API-интерфейс флакона состоит из нашего приложения, которое извлекает 4 точки данных и подгоняет их под нашу модель машинного обучения, а затем отвечает чат-боту с прогнозом. Вы можете найти полный код на моем Github.

А теперь пройдемся по каждому шагу!

Сборка компонентов

Модель машинного обучения

Во-первых, давайте создадим базовую модель машинного обучения, которая принимает размеры радужной оболочки и предсказывает ее тип. Здесь нет ракетостроения. Просто очень простая модель, которая дает результат с приличной точностью. Ниже приведен простой код для этого.

#Load data
iris = load_iris() 
X = iris.data      
y = iris.target

#Train test split
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state = 42, test_size = 0.25)

#Define and fit to the model
clf = RandomForestClassifier(n_estimators=10)
clf.fit(X_train, y_train)
predicted = clf.predict(X_test)
print(accuracy_score(predicted, y_test))
print(clf.predict(X_test))

#Save the model as Pickle
import pickle
with open(r'rf.pkl','wb') as model_pkl:
    pickle.dump(clf, model_pkl, protocol=2)

Мы просто загружаем данные и подгоняем их к классификатору случайного леса. Нет необходимости очищать данные, поскольку набор данных уже очень мал. Я не углубляюсь в оптимизацию, чтобы избежать сложностей, поскольку наша главная цель - не точность модели, а полное приложение. Затем просто засолите модель, а затем эта модель, ‘rf.pkl’, будет загружена в наше приложение Flask.

Чат-бот DialogFlow

Теперь давайте перейдем к DialogFlow и создадим нашего чат-бота. Вы также можете использовать другие API и фреймворки для создания чат-бота, но DialogFlow от Google - очевидный выбор, поскольку его легко, бесплатно и очень быстро создать! Зайдите в DialogFlow и войдите в свою учетную запись Google. Затем нажмите Создать агента, чтобы создать своего чат-бота.

Затем нам нужно создать намерение, которое будет запрашивать данные у пользователя и выполнять вызов веб-перехватчика. Давайте сначала отредактируем приветственное намерение по умолчанию, чтобы оно запрашивало у пользователя «Да» или «Нет».

Теперь, как только пользователь набирает «Да», DialogFlow должен вызвать другое намерение, которое попросит пользователя ввести данные и сохранит точки данных в «Сущностях». Здесь мы имеем дело с простыми случайными числами, поэтому нам не нужно создавать собственные объекты. DialogFlow имеет сущности по умолчанию для обработки таких данных. Поэтому нам нужно создать «Yes-FollowUp Intent» для этого намерения, потому что это намерение будет вызываться после положительного ответа от пользователя.

Нажмите «Добавить намерение о дальнейших действиях» ›« Да ». Вы можете переименовать это намерение во что-нибудь другое, если хотите. Я переименую это в «IrisData». Теперь нам нужно добавить сущности, в которых будут храниться данные, полученные от пользователя. Мы просто будем использовать сущность по умолчанию @ sys.number здесь для всех 4 входов. Задайте 4 различных параметра для 4 точек данных, необходимых от пользователя - Длина лепестка, Ширина лепестка, Длина чашелистиков, Ширина чашелистиков. Не забудьте добавить подсказки, чтобы отдельно запрашивать ввод данных у пользователя.

Обучите модель несколькими входными данными, чтобы она знала, чего ожидать. Теперь вы можете протестировать чат-бота на правой панели, чтобы проверить, правильно ли он работает.

После этого вам нужно будет активировать выполнение с помощью «Включить вызов веб-перехватчика для этого намерения». Таким образом, это конкретное намерение вызовет веб-перехватчик нашего приложения, развернутого на общедоступном хосте, которым является Heroku. Теперь нам нужно создать приложение Flask и развернуть его на Heroku, а затем поместить URL-адрес во вкладку «Выполнение», которая доступна слева.

Приложение Flask на Heroku

Теперь нам нужно создать наше приложение-флягу, которое получает вызов веб-перехватчика от нашего чат-бота, извлекает данные, затем соответствует модели машинного обучения (rf.pkl) и возвращает обратно текст выполнения в DialogFlow с предсказанием. Ниже приведен код:

# Importing necessary libraries
import numpy as np
from flask import Flask, request, make_response
import json
import pickle
from flask_cors import cross_origin

# Declaring the flask app
app = Flask(__name__)

#Loading the model from pickle file
model = pickle.load(open('rf.pkl', 'rb'))


# geting and sending response to dialogflow
@app.route('/webhook', methods=['POST'])
@cross_origin()
def webhook():


    req = request.get_json(silent=True, force=True)
    res = processRequest(req)
    res = json.dumps(res, indent=4)
    r = make_response(res)
    r.headers['Content-Type'] = 'application/json'
    return r

Как только это будет сделано, нам нужно обработать запрос выполнения от DialogFlow, который находится в формате JSON для получения данных. Запрос выполнения выглядит примерно так:

Итак, нам нужно попасть в ‘queryResult’ ›› ‘parameters’ ›› ‘number’, ‘number1’, ‘number2’, ‘number4’. После получения мы сбрасываем эти точки данных в массив, вставляем его в нашу модель и получаем прогноз.

# processing the request from dialogflow
def processRequest(req):


    result = req.get("queryResult")
    
    #Fetching the data points
    parameters = result.get("parameters")
    Petal_length=parameters.get("number")
    Petal_width = parameters.get("number1")
    Sepal_length=parameters.get("number2")
    Sepal_width=parameters.get("number3")
    int_features = [Petal_length,Petal_width,Sepal_length,Sepal_width]
    
    #Dumping the data into an array
    final_features = [np.array(int_features)]
    
    #Getting the intent which has fullfilment enabled
    intent = result.get("intent").get('displayName')
    
    #Fitting out model with the data points
    if (intent=='IrisData'):
        prediction = model.predict(final_features)
    
        output = round(prediction[0], 2)
    
    	
        if(output==0):
            flowr = 'Setosa'
    
        if(output==1):
            flowr = 'Versicolour'
        
        if(output==2):
            flowr = 'Virginica'
            
        #Returning back the fullfilment text back to DialogFlow
        fulfillmentText= "The Iris type seems to be..  {} !".format(flowr)
        #log.write_log(sessionID, "Bot Says: "+fulfillmentText)
        return {
            "fulfillmentText": fulfillmentText
        }


if __name__ == '__main__':
    app.run()

Как только это будет сделано, нам просто нужно развернуть код на общедоступном хосте. Я снова выбрал Heroku, это просто, бесплатно и супер быстро! Вам просто нужно добавить следующие файлы в ваш новый репозиторий Github: приложение flask, файл pickle модели, файл Procfile (это очень важно и помогает Heroku найти приложение flask) и текстовый файл требований, который сообщает Heroku, какие все библиотеки и версии для предварительной установки, чтобы приложение работало правильно.

Просто создайте репозиторий на своем Github и перейдите на Heroku. Создайте Новое приложение и Подключите к нему свой репозиторий Github. После подключения просто нажмите кнопку развертывания, и все готово!

Вызов Webhook

А теперь перейдем к последнему шагу. Теперь нам нужно подключить развернутое приложение к нашему чат-боту. Просто введите URL-адрес, на котором развернуто ваше приложение, и добавьте к нему «/ webhook». Помните из приведенного выше кода фляги, что приложение перенаправляется на «/ webhook». Просто перейдите на вкладку «Выполнение» на левой панели в DialogFlow, включите «Webhook» и просто добавьте ‹your_app’s_URL› / webhook.

И готово! (Не забудьте нажать кнопку сохранения!) Вы можете проверить на правой панели, запустив чат, чтобы проверить, нормально ли работает запрос / ответ веб-перехватчика. Вы должны получить ответ выполнения с предсказанием.

Интеграция с Telegram

Подходим к заключительному этапу. Здесь особо нечего делать, поскольку интегрировать веб-приложения с DialogFlow очень просто. Сначала нам нужно зайти в Telegram, чтобы сгенерировать там фиктивного бота и сгенерировать его токен. Найдите BotFather и нажмите новый бот. Вам будет предложено ввести имя бота. Введите любое имя, какое пожелаете. Затем вам будет предложено ввести имя пользователя.

После того, как вы это сделаете, там будут сгенерированы токен и ссылка для вашего бота. Просто скопируйте этот токен и перейдите на панель «Интеграции» DialogFlow слева. Включите там Telegram, вставьте только что сгенерированный токен и нажмите «Пуск». Вот и все! Теперь просто перейдите по ссылке на бота Telegram и попробуйте приложение!