Этот проект изначально предназначен для моего проекта Udacity Machine Learning Engineer Nanodegree capstone.

Я нашел набор данных на Kaggle, связанный как:



Обзор проекта

Я очень горжусь завершением этого проекта, потому что он бросил вызов моим навыкам не только в области машинного обучения, но и в таких областях, как инженерия данных и разработка программного обеспечения. Мне удалось научиться использовать библиотеку Streamlit в Python для создания всего моего веб-приложения ML. В веб-интерфейсе вы можете просто начать с выбора типа модели машинного обучения, затем настроить гиперпараметры модели и, наконец, выбрать метрики оценки.

Ниже в качестве обзора:

  • Модели машинного обучения: классификатор случайного леса (RF) и классификатор логистической регрессии (LR).
  • Гиперпараметры: n_estimators для RF и C для LR.
  • Метрики оценки: матрица неточностей; Классификационный отчет; Оценка точности.

Постановка задачи

Что касается этого поста, я постараюсь изо всех сил провести вас по моему проекту в качестве очень практического примера использования Streamlit для создания веб-приложения.

Согласно информации этого набора данных на Kaggle, есть некоторые конкретные факты, о которых нам нужно знать в начале.

  • Во-первых, нам нужен только комбинированный набор данных для нашего проекта. Издатель любезно объединил для нас два других набора данных. Combined_News_DJIA.csv - это тот файл, над которым мы будем работать. ;)
  • Во-вторых, когда мы работаем на шаге train_test_split, издатель предъявляет особые требования. Я скопировал, как показано ниже:

Для оценки задачи используйте данные с 2008-08-08 по 2014-12-31 в качестве обучающего набора, а тестовый набор - это данные за следующие два года (с 2015-01-02 по 2016-07-01). . Это примерно 80% / 20%.

Исследование данных

Набор данных содержит 27 столбцов (25 столбцов - это 25 заголовков, просканированных с Reddit World News Channel). Столбец с меткой показывает, вырос ли промышленный индекс Доу-Джонса (DJIA) на прежнем уровне (1) или снизился (0). Каждая строка содержит информацию на определенную дату. Всего в этом наборе данных 1989 строк.

Изложив распределение меток, мы видим, что данные лишь немного неравномерны.

Предварительная обработка данных

Включенные этапы предварительной обработки данных:

  • Заполните значения NaN медианами.
  • Чистые тексты в каждой новостной колонке.
  • Объедините столбцы новостей в один столбец с названием «заголовки».

Последние два шага могут быть достигнуты путем написания функции предварительной обработки данных, как показано ниже:

def create_df(dataset):
    
    dataset = dataset.drop(columns=['Date', 'Label'])
    dataset.replace("[^a-zA-Z]", " ", regex=True, inplace=True)
    for col in dataset.columns:
        dataset[col] = dataset[col].str.lower()
        
    headlines = []
    for row in range(0, len(dataset.index)):
        headlines.append(' '.join(str(x) for x in dataset.iloc[row, 0:25]))
        
    df = pd.DataFrame(headlines, columns=['headlines'])
    # data is the dataset after filling NaNs defined out of the function scope
    df['label'] = data.Label 
    df['date'] = data.Date
    
    return df

Реализация

Включенные этапы реализации:

  • Токенизируйте тексты.
  • Создайте конвейер машинного обучения.
  • Выполните train_test_split.
  • Установите конвейер данных.
  • Оцените результаты.

Чтобы токенизировать текст заголовков в первом столбце, нам нужно создать другую функцию для выполнения этой задачи.

def tokenize(text):
    text = re.sub(r'[^\w\s]','',text)
    tokens = word_tokenize(text)
    lemmatizer = WordNetLemmatizer()
    clean_tokens = []
    for token in tokens:
        clean_token = lemmatizer.lemmatize(token).lower().strip()
        clean_tokens.append(clean_token)
    return clean_tokens

Эта функция принимает абзац текста в качестве входных данных и возвращает токенизированный список слов в качестве выходных данных.

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

Для меня я начал с классификатора случайных лесов в качестве эталонной модели.

from sklearn.pipeline import Pipeline
from sklearn.feature_extraction.text import CountVectorizer, TfidfTransformer
pipeline = Pipeline([
        ('vect', CountVectorizer(tokenizer=tokenize, stop_words = 'english')),
        ('tfidf', TfidfTransformer()),
        ('clf', RandomForestClassifier())
    ])

Поскольку метод train_test_split уже определен издателем, мы можем просто написать код, как показано ниже:

# seperating the data into train and test by date following the instruction by the data creator
train = df[df['date'] < '20150101']
test = df[df['date'] > '20141231']
# selecting features and targets 
x_train = train.headlines
y_train = train.label
x_test = test.headlines
y_test = test.label

Установите конвейер данных и оцените результаты с помощью отчета о классификации.

# fit on the pipeline 
pipeline.fit(x_train, y_train)
# predicting the results 
y_pred = pipeline.predict(x_test)
print(classification_report(y_test, y_pred))

Наша эталонная модель ML (RF) достигла точности 81%.

В качестве альтернативы мы можем использовать модель логистической регрессии в качестве эталона.

Логистическая регрессия достигла точности 82%, что на 1% превосходит случайный лес.

Уточнение

Чтобы еще больше повысить производительность нашей модели, я выбираю GridSearch CV, чтобы перебирать пространство параметров и возвращаться с лучшими параметрами. Поскольку логистическая регрессия почему-то не очень хорошо работает после настройки гиперпараметров, я покажу только, как построить простое резюме GridSearch для модели случайного леса.

from sklearn.model_selection import GridSearchCV 
# method using GridSearchCV
parameters = {
        'vect__ngram_range': ((1, 1), (2, 2)),
        'clf__n_estimators': [50, 100, 150, 200, 250, 300]
    }
Grid = GridSearchCV(pipeline, param_grid=parameters, cv= 3, verbose=10)
Grid.fit(x_train, y_train)

Когда подгонка завершена, вы можете просто вернуть лучшие параметры одной строкой кода.

Grid.best_params_

После уточнения мы можем повторно оценить производительность нашей настроенной модели с помощью отчета о классификации.

Настроенная модель случайного леса достигла точности 84%, что на 3% больше, чем у эталонной версии.

Закончив рабочий процесс в Jupyter Notebook, мы переходим к Visual Studio, чтобы создать веб-приложение машинного обучения с помощью Streamlit!

Оценка и проверка модели с помощью Streamlit

Мы собираемся использовать библиотеку Streamlit в Python для проверки нашей модели машинного обучения.

Если вы раньше не слышали о Streamlit, я рекомендую в качестве введения руководство по проектам на Coursera.



Мое веб-приложение имеет интерфейс, подобный приведенному ниже:

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

Чтобы сделать его более эффективным, я разбиваю шаги на следующие, чтобы не было слишком много путаницы. ;)

  • Импортируйте все библиотеки Python, необходимые для создания веб-приложения.
  • Разбейте свой рабочий процесс на отдельные функции. Например, load_data () помогает загрузить набор данных / create_df () помогает очистить и объединить столбцы новостей в один столбец заголовков / tokenize () помогает преобразовать текст в список слов и т. д.
  • Создайте интерфейс своего веб-приложения на языке Streamlit. Это звучит сложно, но на самом деле это очень легко понять!
  • Наконец, вы действительно можете писать свой код, как будто вы находитесь в среде Python.

Попробуйте команды Streamlit для создания своего интерфейса:

  • st.sidebar.title («Сентиментальный анализ новостей НЛП») помогает создать заголовок на боковой панели.
  • st.subheader («Матрица путаницы») отображать заголовок на главной странице.
  • st.write («Матрица неточностей», матрица) отображает результаты матрицы неточностей.

Если вам интересно, как я создаю свое веб-приложение, вы можете проверить логику кода ниже:

Библиотеки:

from nltk.tokenize import word_tokenize
from nltk.stem import WordNetLemmatizer
import streamlit as st
import pandas as pd
import numpy as np
import warnings
from sklearn.pipeline import Pipeline
from sklearn.feature_extraction.text import CountVectorizer, TfidfTransformer
from sklearn.ensemble import RandomForestClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import classification_report, confusion_matrix, accuracy_score
import nltk
import re
nltk.download(['punkt', 'wordnet'])

Функции:

  • load_data () возвращает загруженный набор данных из вашего локального пути к файлу.
  • create_df (набор данных) вводит исходный набор данных и выводит набор данных объединенного столбца заголовков.
  • tokenize (text) вводит текст и выводит список слов.
  • split (df) вводит фрейм данных и выводит x_train, x_test, y_train, y_test.
  • Vectorize () реализован как конвейер CountVectorizer и TfidfTransformer.

Другая функция для интерфейса веб-приложения:

def plot_metrics(metrics_list):
if 'Confusion Matrix' in metrics_list:
    st.subheader('Confusion Matrix')
    predictions = model.predict(x_test)
    matrix = confusion_matrix(y_test, predictions)
    st.write("Confusion Matrix ", matrix)
if 'Classification_Report' in metrics_list:
    st.subheader('Classification_Report')
    predictions = model.predict(x_test)
    report = classification_report(y_test, predictions)
    st.write("Classification_Report ", report)
if 'Accuracy_Score' in metrics_list:
    st.subheader('Accuracy_Score')
    predictions = model.predict(x_test)
    score = accuracy_score(y_test, predictions)
    st.write("Accuracy_Score: ", score.round(2))

Обоснование

Что касается заключения, мы начали с прохождения всего рабочего процесса создания проекта машинного обучения в Jupyter Notebook, чтобы наконец реализовать модель в виде веб-приложения машинного обучения с использованием библиотеки Streamlit.

Модель случайного леса и модель логистической регрессии сначала тестируются в качестве эталонных моделей, и только модель случайного леса используется для дальнейших шагов по уточнению.

Перед уточнением модель RF оценивается методом отчета о классификации и достигает точности 81%. Однако после использования метода уточнения, включая GridSearch CV, модель RF успешно улучшает свою точность с шагом от 3% до 84%.

Наконец, в качестве проблемы мы попытались развернуть модель машинного обучения в веб-приложении. Используя Streamlit, нам нужно только разложить рабочий процесс на функции. И большинство функций можно скопировать из рабочей области в Jupyter Notebook.

В заключение я искренне надеюсь, что эта статья будет полезна для изучающих науку о данных и машинное обучение.

Спасибо, что уделили время чтению этой статьи!

Увидимся в следующий раз.

Ссылка на Github на репозиторий проекта:

Https://github.com/TanjirouNezuko/Machine-Learning-Engineer-Nanodegree/tree/main/Capstone%20Project