Наша цель сегодня состоит в том, чтобы предсказать, куда попадет аннотация новой публикации в треке 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 наших прогнозов по этим моделям. Этот метод можно использовать для дальнейшего повышения прозрачности моделей машинного обучения, чтобы сообщать конечным пользователям о том, насколько точно наши алгоритмы работают за капотом.