Создание классификатора спам-сообщений и развертывание его приложения на Heroku

Сегодня мы будем создавать простой классификатор спам-сообщений, модель, основанную на обработке естественного языка. Затем мы создадим приложение-флягу, которое будет отображать домашнюю страницу на основе HTML и страницу прогнозов. Пользователь будет вводить текст на домашней странице, и приложение предскажет, будет ли оно похоже на спам-сообщение или как на спам (не спам) на странице прогноза. Этот API-интерфейс flask будет развернут на общедоступном хосте на Heroku. Heroku - очевидный выбор, поскольку это очень быстро и очень просто. Я уже упоминал, что это бесплатно? Да, это так! Сначала попробуйте сами и поиграйте с приложением здесь, чтобы знать, что вы будете строить.

Итак, теперь, когда вы это увидели, давайте приступим!

Модель

Первым шагом будет построение нашей модели НЛП, которая принимает естественный текст от пользователя и предсказывает, является ли он спамом или ветчиной (не спамом). Мы сделаем это с помощью нескольких фрагментов кода Python. Полный код и набор данных доступны на моем Github. Во-первых, давайте импортируем все необходимые библиотеки.

import pandas as pd  #Pandas for data pre-processing

import pickle #Pickle for pickling (saving) the model 

from sklearn.feature_extraction.text import CountVectorizer #To Vectorize the textual data 

from sklearn.naive_bayes import MultinomialNB #The algorithm for prediction 

from sklearn.externals import joblib #Alternative Usage of Saved Model 

from sklearn.model_selection import train_test_split #Validation split

Затем нам нужно загрузить данные и разделить их на текстовые данные (X) и метки (y).

df = pd.read_csv("spam.csv", encoding="latin-1")

df.drop(['Unnamed: 2', 'Unnamed: 3', 'Unnamed: 4'], axis=1, inplace=True) #Some garbage features that need to be removed

# Text and Labels

df['label'] = df['class'].map({'ham': 0, 'spam': 1}) 

X = df['message']

y = df['label']

Теперь нам нужно векторизовать (преобразовать текст в числовую форму) текстовые данные с помощью Count Vectorizer. Затем просто разделите данные для обучения и тестирования. Никакая дальнейшая предварительная обработка текста не принимается во внимание, поскольку наша цель - быстро построить модель и развернуть ее. Вы можете поэкспериментировать с частью очистки текста, чтобы улучшить производительность.

# Extract Feature With CountVectorizer 

cv = CountVectorizer() 

X = cv.fit_transform(X) # Fit the Data 

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=42)

Как только это будет сделано, нам просто нужно подогнать модель и сохранить ее как файл pickle, который позже будет загружен в приложение Flask.

#Naive Bayes Classifier  

clf = MultinomialNB() 
clf.fit(X_train,y_train) 
print(clf.score(X_test,y_test)) 

#Alternative Usage of Saved Model 

joblib.dump(clf, 'NB_spam_model.pkl') 
joblib.dump(cv, 'cv.pkl')

Обратите внимание, что мы сохранили модель Наивного Байеса и векторизатор подсчета. Это связано с тем, что для вашего ввода текста, который будет взят от пользователя, необходимо будет векторизовать его с использованием тех же параметров Count Vectorizer, на которых была обучена модель. Итак, теперь у нас есть модель и векторизатор.

Затем нам нужно создать приложение flask, которое подключит модель НЛП, которую мы только что создали, к нашему браузеру, а затем разместит ее в облаке.

Приложение Flask

Приложение Flask перенаправит пользователя на домашнюю страницу, как только пользователь получит доступ к URL-адресу приложения. Позже, когда пользователь вводит текст и нажимает кнопку прогнозирования, он перенаправляет его на страницу прогноза и отображает результат. Посмотрим, как это делается.

Нам нужно импортировать flask и несколько других функций. Вам нужно будет установить flask с помощью простой команды pip install, если у вас ее еще нет.

from flask import Flask, render_template, request

Здесь Flask будет использоваться для определения приложения, которое мы используем. Затем render_template отобразит домашнюю страницу (home.html) и страницу прогноза (result.html). И запрос будет использоваться для получения введенного текста, который будет отправлен в приложение Flask через метод HTML Post со страницы HTML.

Теперь нам нужно определить приложение flask и его маршрутизацию по умолчанию на домашнюю страницу, которая называется home.html. Мы определим функцию, которая ничего не будет делать, кроме как отображать домашнюю страницу при вызове URL-адреса приложения.

app = Flask(__name__) 

@app.route('/') #Routes the app to below task when the URL is called 

def home(): 

    return render_template('home.html')

Теперь переходит к основной части приложения - предсказанию. Нам нужно определить функцию, которая открывает и загружает файлы рассола модели NLP и Count Vectorizer. Затем он получает текстовый ввод, который отправляется ему через метод POST. Полученный текстовый ввод затем векторизуется с использованием того же векторизатора и выгружается в нашу модель для получения прогноза. Вот и все! Теперь нам просто нужно вернуть этот результат прогноза на страницу прогноза, и все готово.

def predict_fun(): 

    NB_spam_model = open('NB_spam_model.pkl','rb') 
    clf = joblib.load(NB_spam_model)
	
    cv_model = open('cv.pkl', 'rb')
    cv = joblib.load(cv_model)	
	
    if request.method == 'POST': 

        message = request.form['message'] 
        data = [message] 
        vect = cv.transform(data).toarray()
        my_prediction = clf.predict(vect) 

    return render_template('result.html',prediction = my_prediction)   

#Calling the main function and running the flask app 

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

Наша модель и приложения для фляги готовы. Теперь нам просто нужно развернуть эти файлы на Heroku.

Развертывание

Чтобы развернуть приложение на Heroku, вам необходимо разместить все файлы на вашем Github, которые будут связаны с Heroku. Вам нужно будет загрузить в репозиторий следующие файлы:

  1. НЛП модель рассола
  2. Рассчитать рассол в векторизаторе
  3. Приложение Flask
  4. HTML и CSS файлы
  5. Файл требований
  6. Procfile

Итак, вам может быть интересно, какие требования и файлы procfile. Требования - это текстовый файл, который содержит все зависимости (библиотеки, такие как pandas, flask и т. Д.) И их версии, необходимые для того, чтобы приложение работало должным образом. Heroku установит все эти зависимости до развертывания приложения. Procfile - это файл конфигурации, который выглядит примерно так:

web: gunicorn app1:app

Здесь «app1» - это имя моего файла фляги, то есть «app1.py», а «app» - это приложение фляги, которое мы определили ранее в приведенном выше коде. Это просто говорит Heroku искать файл фляги с именем app1 и в нем приложение фляги, определенное как «приложение».

После того, как вы закончите отправку всех файлов в новый репозиторий github, вам нужно будет создать приложение на Heroku и подключить к нему свой репозиторий github. Для этого просто зайдите в Heroku . Создайте учетную запись, если вы еще этого не сделали, и перейдите в раздел Создать новое приложение.

Во вновь созданном приложении вам необходимо подключиться к репозиторию github, в котором есть код. Найдите имя репозитория github в поле поиска и нажмите кнопку «Подключиться».

После подключения вам просто нужно нажать кнопку «Развернуть», и все готово! Heroku сначала проверит файл требований и установит все зависимости, а затем развернет приложение flask на общедоступном хосте. Будет создан URL-адрес вашего приложения. Просто скопируйте его и откройте в своем браузере - и вуаля! все готово.

Это было для этого урока. Надеюсь, вы запустили приложение и получили достойные результаты!

Если вы зашли так далеко и приложение уже готово, похлопайте себя по плечу. Ты заслуживаешь это!

Поэтому мы использовали здесь Heroku Cloud, так как его легко и быстро настроить. Однако я рекомендую вам попробовать развернуть приложение и на других облачных платформах, таких как AWS EC2, Google Cloud Platform и Azure.

Не стесняйтесь получать исходный код из моего github и обращаться ко мне с любыми вопросами и предложениями по LinkedIn.

Увидимся в следующем посте, ура!