Наша цель сегодня состоит в том, чтобы предсказать, куда попадет аннотация новой публикации в треке IEEE VIS, используя исторический набор данных из принятых публикаций и визуализируя точность наших прогнозов.

Этапы:

  • Создайте нашу модель машинного обучения с помощью Pandas и Scikilearn
  • Создайте наше веб-приложение для хранения модели с помощью Flask и Jinja
  • Визуализируйте результаты прогнозов и неопределенность нашей модели с помощью d3.js (uvis.js)

Создайте нашу модель машинного обучения

Наши данные. Мы будем работать с данными публикаций IEEE Vis, подготовленными командой V isPub, чтобы включить информацию о публикациях IEEE Visualization (IEEE VIS) за период с 1990 по 2018 год. Набор данных включает разнообразную информацию о каждой статье, включая название, авторов, DOI и т. д., а также список ссылок на другие предыдущие статьи VIS.

Начнем с изучения данных

import pandas as pd
df = pd.read_csv("ieee.csv", encoding="latin-1")
print(df.head())

Первая строка кода импортирует pandas, затем читает данные ieee.csv и печатает результат столбцов и первых 5 строк данных.

Наше основное внимание будет сосредоточено на двух полях данных: «Аннотация» и «Конференция». Мы создадим модель, чтобы предсказать, где наша предлагаемая аннотация лучше всего подходит.

df[['Conference','Abstract']]

Мы ясно видим два поля «Конференция» и «Реферат», теперь нам нужно удалить все строки NaN из данных, чтобы избежать ошибок в нашей модели прогнозирования, это можно сделать с помощью кода ниже

df.drop(df[df.isnull().any(axis=1)].index,inplace=True)

Существует два основных типа машинного обучения: обучение с учителем и обучение без учителя(Ссылка на дополнительную информацию об обоих). Мы будем использовать обучение с учителем. Обучение с учителем требует, чтобы человек контролировал и сообщал компьютеру, что его нужно обучить, чтобы предсказывать или давать ему правильный ответ. В нашем случае, какой конференции принадлежит каждый тезис? Мы начнем с определения наших меток для модели и сопоставления их с числами, которые модель может легко прочитать, приведенный ниже код должен делать именно это.

df['label'] = df['Conference'].map({'InfoVis': 0, 'SciVis': 1, 'VAST':2, 'Vis':3})

Выбор нашей модели. Существует два типа проблем, которые может решить обучение с учителем: проблема классификации и проблемы регрессии (дополнительную информацию можно найти здесь, на оба"). Наша проблема тесно связана с проблемой классификации, которая включает в себя разделение определенного наблюдения на группы. в нашем случае, классифицируя новые рефераты по каждой из этих групп конференций (InfoVis, SciVis, VAST и Vis). Чтобы достичь этого, мы должны выбрать алгоритм, поддерживающий нашу классификацию.

Выбор нашего алгоритма: существуют различные типы алгоритмов, используемых для машинного обучения, каждый из которых служит своей уникальной цели, некоторые из них включают, но не ограничиваются; Наивный байесовский алгоритм Гаусса, деревья решений и случайные леса. Я не буду углубляться в объяснение каждого алгоритма, но дополнительную информацию можно найти, перейдя по ссылкам на них. Мы будем использовать гауссовский наивный алгоритм Байеса, так как он обычно используется для классификации новостных статей и спам-писем. Для этого нам придется импортировать все необходимые расширения из Scikit Learn Library,как показано ниже.

from sklearn.naive_bayes import MultinomialNB
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.metrics import classification_report
from sklearn.externals import joblib

1-я строка импортирует алгоритм классификатора MultinomialNB из sklearn.naive_bayes, 2-я строка импортирует CountVectorizer для преобразования набора текстовых документов в матрицу количества токенов, 3-я строка импортирует classification_report для отображения результатов метрик нашей модели, а 4-я строка предназначена для сохранение и загрузка обученных моделей. Для начала нам нужно будет определить функции и метки, извлечь функции из абстрактного текста, поместить наши данные в обучающие и тестовые наборы и, наконец, запустить наш прогноз.

# Features and Labels
df['label'] = df['Conference'].map({'InfoVis': 0, 'SciVis': 1, 'VAST':2, 'Vis':3})
X = df['Abstract']
y = df['label']
# Extract Feature With CountVectorizer
cv = CountVectorizer()
X = cv.fit_transform(X)
# Fit the Data
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.33, random_state=42)
# Naive Bayes Classifier
clf = MultinomialNB()
clf.fit(X_train, y_train)
clf.score(X_test, y_test)
# Predict model with test data and output the result
y_pred = clf.predict(X_test)
my_report = classification_report(y_test, y_pred, output_dict=True)

1-й раздел посвящен меткам и определению признаков, 2-й раздел извлекает текстовые признаки из абстрактного поля, 3-й раздел определяет переменную clf и прикрепляет к ней классификацию MultinomialNB(), а 4-й раздел используется для тестирования модели с помощью определенные тестовые данные и вывести результат прогноза. Результат приведенного выше кода можно найти на изображении ниже.

То, что нас сейчас интересует, и неопределенность модели - это вывод из print(my_report), как показано ниже.

{'0': {'precision': 0.6, 'recall': 0.8571428571428571, 'f1-score': 0.7058823529411764, 'support': 14}, '1': {'precision': 1.0, 'recall': 0.2, 'f1-score': 0.33333333333333337, 'support': 5}, '2': {'precision': 0.6, 'recall': 0.42857142857142855, 'f1-score': 0.5, 'support': 7}, '3': {'precision': 0.8, 'recall': 0.8, 'f1-score': 0.8000000000000002, 'support': 5}, 'accuracy': 0.6451612903225806, 'macro avg': {'precision': 0.75, 'recall': 0.5714285714285714, 'f1-score': 0.5848039215686275, 'support': 31}, 'weighted avg': {'precision': 0.6967741935483871, 'recall': 0.6451612903225806, 'f1-score': 0.6144845034788108, 'support': 31}}

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

Создайте наше веб-приложение для хранения модели

Чтобы создать наше веб-приложение для хранения модели и предоставления ее пользователям, мы будем использовать микрофреймворк Flask. Мы добьемся этого, установив flask, создав структуру папок для нашего веб-приложения, наш файл прогнозирования в маршруты flask, создав шаблоны и предоставив наши результаты. несколько замечаний о flask ниже (подробнее о flask здесь).

Я постараюсь как можно быстрее пропустить этот участок кода, более подробную информацию о размещении модели машинного обучения в приложении flask можно найти здесь. Мы начнем с установки Flask, создадим структуру папок, заполним наш код app.py маршрутами, заполним style.css, заполним файлы home.html и Prediction.html.

pip install flask or pip3 install flask

Создайте структуру папок, подобную этой

appy.py
templates
|- index.html
|- prediction.html
static
|- style.css
data
|- ieee.csv

app.py

index.html

предсказание.html

стиль.css

Визуализируйте результаты прогнозов и неопределенность нашей модели с помощью Jinja и d3.js

В нашем Prediction.html мы будем реализовывать весь наш код d3 и jinja для визуализации отчетов о прогнозах на этапе построения модели, результат отчета из нашего примера приведен ниже.

{'0': {'precision': 0.6, 'recall': 0.8571428571428571, 'f1-score': 0.7058823529411764, 'support': 14}, '1': {'precision': 1.0, 'recall': 0.2, 'f1-score': 0.33333333333333337, 'support': 5}, '2': {'precision': 0.6, 'recall': 0.42857142857142855, 'f1-score': 0.5, 'support': 7}, '3': {'precision': 0.8, 'recall': 0.8, 'f1-score': 0.8000000000000002, 'support': 5}, 'accuracy': 0.6451612903225806, 'macro avg': {'precision': 0.75, 'recall': 0.5714285714285714, 'f1-score': 0.5848039215686275, 'support': 31}, 'weighted avg': {'precision': 0.6967741935483871, 'recall': 0.6451612903225806, 'f1-score': 0.6144845034788108, 'support': 31}}

Некоторые из ключевых значений, представляющих интерес в приведенном выше коде, — это точность, точность, полнота и оценка F1.

Точность. Точность — это самый простой и наиболее часто используемый показатель производительности.

Точность: отношение истинно положительных результатов. Скажите нам, какая доля реферата, классифицированного, например, как InfoVis, где на самом деле InfoVis

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

Оценка F1: это гармоническое среднее точности и полноты. Это дается формулой.

Визуализация вышеуказанных показателей

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

Вид входа

<form action="{{ url_for('predict')}}" method="POST">
<div class="form-group">
<label for="exampleFormControlTextarea1"></label>
<textarea name="message" class="form-control" id="exampleFormControlTextarea1" rows="4"></textarea>
</div>
<button type="submit" class="btn btn-primary" value="predict">Submit</button>
</form>

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

Предварительный просмотр

{% if prediction == 0%}
<h2 style="color:red;">InfoVis</h2>
{% elif prediction == 1%}
<h2 style="color:red;">SciVis</h2>
{% elif prediction == 2%}
<h2 style="color:red;">VAST</h2>
{% elif prediction == 3%}
<h2 style="color:red;">Vis</h2>
{% endif %}

Мы используем приведенный выше код jinja для отображения различных дорожек с результатами прогнозирования 0 сопоставлений с InfoVis, 1 с SciVis, 2 с VAST и 3 с дорожкой Vis соответственно.

let reportData = {{ report | safe }}
let predictionData = {{ prediction | safe }}
let macro_avg = [{name:'precision', value:reportData['macro avg'].precision, uncert: reportData['accuracy']* 10},{name:'recall', value:reportData['macro avg'].recall, uncert: reportData['accuracy']* 10},{name:'f1-score', value:reportData['macro avg']['f1-score'], uncert: reportData['accuracy']* 10}]
let weighted_avg = [{name:'precision', value:reportData['weighted avg'].precision, uncert: reportData['accuracy']* 10},{name:'recall', value:reportData['weighted avg'].recall, uncert: reportData['accuracy']* 10},{name:'f1-score', value:reportData['weighted avg']['f1-score'], uncert: reportData['accuracy']* 10}]

let macroAvgChart = uvis.barChart().utype('gradient').width(600);
d3.select('#macro_avg')
.datum(macro_avg)
.call(macroAvgChart)
let weightedAvgChart = uvis.barChart().utype('gradient').width(600);
d3.select('#weighted_avg')
.datum(weighted_avg)
.call(weightedAvgChart)

Мы будем использовать библиотеку uvis.js, созданную поверх d3.js, специально для визуализации неопределенности, а также в настоящее время поддерживаем использование BarChart и LineChart. Используя гистограмму, приведенный выше код считывает данные прогноза и отчета и преобразует их в формат, читаемый чатом гистограммы uvis.js. Часть приведенного выше кода создает экземпляр гистограммы uvis.js, инициирует неопределенность градиента, применяет ширину и вызывает форматированные данные. Результат вышеизложенного можно увидеть ниже (см. также прогнозирование.html)

Мы продемонстрировали полномасштабный проект прогнозирования науки о данных, от обработки данных до выбора модели классификации и визуализации точности с использованием библиотеки uvis.js наших прогнозов по этим моделям. Этот метод можно использовать для дальнейшего повышения прозрачности моделей машинного обучения, чтобы сообщать конечным пользователям о том, насколько точно наши алгоритмы работают за капотом.