www.machinelearningmastery.ru

Машинное обучение, нейронные сети, искусственный интеллект
Header decor

Home

Оживите свой ноутбук Jupyter с помощью интерактивных виджетов

Дата публикации May 3, 2019

Расширение Jupyter в интерфейс пользователя

Традиционно, каждый раз, когда вам нужно изменить вывод ячеек вашего ноутбука, вам нужно изменить код и повторно запустить затронутые ячейки. Это может быть громоздким, неэффективным и подверженным ошибкам, а в случае нетехнического пользователя это может быть даже неосуществимым. Это гдеipywidgetsвступить в игру: они могут быть встроены в ноутбук и обеспечитьудобныйинтерфейс для сбора пользовательского ввода и просмотра влияния изменений на данные / результаты без необходимости взаимодействия с кодом; Ваши ноутбуки могут быть преобразованы из статических документов в динамические информационные панели - идеально для демонстрации вашей истории данных!


⚠️ Область применения:Ресурсы по ipywidgets ограничены, и очень немногие учебники либо неполные, либо посвященыinteractФункция / декоратор. Этополный учебнико том, как вы можете получить полный контроль над виджетами для создания мощных панелей.

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


Что такое виджет?

Если вы когда-либо создалиграфический интерфейс пользователя(GUI), тогда вы уже знаете, что такое виджет. Но давайте дадим определение быстро в любом случае:
Виджет представляет собой графический элемент, такие как кнопку, выпадающий список или текстовое поле, которое постоянно находится в браузере и позволяет нам контролировать код и данные, реагируя на события и вызов указанных обработчиков.

Эти элементы GUI могут быть собраны и настроены для создания сложных панелей мониторинга.

Демонстрация: Некоторые из наиболее популярных виджетов

В этой статье мы увидим некоторые из них в действии.

Готовы? 🏁


❶ Начало работы

Для того, чтобы начать использовать библиотеку нам нужно установитьipywidgetsрасширение. Если используется conda, мы набираем эту команду в терминале:

conda install -c conda-forge ipywidgets

Для pip это будет двухэтапный процесс: 1. установить и 2. включить:

pip install ipywidgetsjupyter nbextension enable --py widgetsnbextension

Добавление виджета

Чтобы включить виджеты в блокнот, мы должны импортировать модуль, как показано ниже:

import ipywidgets as widgets

Чтобы добавить слайдер, мы можем определить минимальное и максимальное значения, размер интервала (шаг), описание и начальное значение:

widgets.IntSlider(
min=0,
max=10,
step=1,
description='Slider:',
value=3
)
Демо: Слайдер

Отображение этого

display()Функция предоставляет объект виджета в ячейке ввода.
Первый импорт:

from IPython.display import display

Затем передайте виджет в качестве параметра в функцию display ():

slider = widgets.IntSlider()
display(slider)

Получение / Установка его значения

Чтобы прочитать значение виджета, мы запросим егоvalueсвойство. Кроме того, мы можем установить значение виджета:

Демо: Значение

Связывание двух виджетов

Мы можем синхронизировать значения двух виджетов, используяjslink()функция.

slider = widgets.IntSlider()
text = widgets.IntText()
display(slider, text)widgets.jslink((slider, 'value'), (text, 'value'))
Демо: Связывание

Список виджетов

Для полного списка виджетов вы можете проверитьдокументацияИли выполните следующую команду:

print(dir(widgets))

❷ Обработка Виджет События

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

Давайте посмотрим, как это работает ...

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

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

Здесь мы создадим простую кнопку под названиемbtn,on_clickметод вызывается при нажатии на кнопку.

Наш обработчик событий,btn_eventhandler, напечатает короткое сообщение с заголовком кнопки - обратите внимание, что входной аргумент обработчика,obj, это сам объект кнопки, который позволяет нам получить доступ к его свойствам.

Чтобы связать событие с обработчиком, мы назначаем последнее кнопкеon_clickметод.

btn = widgets.Button(description='Medium')
display(btn)def btn_eventhandler(obj):
print('Hello from the {} button!'.format(obj.description))btn.on_click(btn_eventhandler)
Демонстрация: Кнопка Event Handler

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


❸ Управление Widget Выход

В этом разделе мы рассмотрим, как использовать виджеты дляуправлять кадром данных, Образец набора данных я выбрал это «Количество международных посетителей в Лондон», Который показывает итоговые посетителей Лондона касаемо ночей, посещений и расходов, с разбивкой по годам, кварталам, цели, продолжительность, режим и страны.

Изначально мы получим данные и загрузим их в фрейм данных:

import pandas as pd
import numpy as npurl = "https://data.london.gov.uk/download/number-international-visitors-london/b1e0f953-4c8a-4b45-95f5-e0d143d5641e/international-visitors-london-raw.csv"df_london = pd.read_csv(url)
df_london.sample (5)

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

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

ALL = 'ALL'def unique_sorted_values_plus_ALL(array):
unique = array.unique().tolist()
unique.sort()
unique.insert(0, ALL)
return unique

Теперь мы инициализируем выпадающий список:

dropdown_year = widgets.Dropdown(options =    unique_sorted_values_plus_ALL(df_london.year))

Выпадающий виджет предоставляетobserveметод, который принимает функцию, которая будет вызываться при изменении значения раскрывающегося списка. Таким образом, мы затем создадим обработчик наблюдателя для фильтрации кадра данных по выбранным значениям - обратите внимание, что входной аргумент обработчика,change, содержит информацию об изменениях, которые произошли, что позволяет нам получить доступ кnewценность (change.new).
Если новое значениеALLмы удаляем фильтр, иначе применяем его:

def dropdown_year_eventhandler(change):
if (change.new == ALL):
display(df_london)
else:
display(df_london[df_london.year == change.new])

Затем мы свяжем обработчик с выпадающим списком:

dropdown_year.observe(dropdown_year_eventhandler, names='value')
Использование раскрывающегося списка для фильтрации данных

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

Захват вывода виджетов

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

Мы немного подправим код:

  • создать новый экземплярOutput
output_year = widgets.Output()
  • позвонитьclear_outputметод в обработчике событий, чтобы очистить предыдущий выбор на каждой итерации и захватить выходные данные кадра данных вwithблок.
def dropdown_year_eventhandler(change):
output_year.clear_output()
with output_year:
display(df_london[df_london.year == change.new])

Затем мы отобразим вывод в новой ячейке:

display(output_year)

Вот как это работает:

Демо: захват вывода в новой ячейке

Как вы можете видеть, выходные данные отображаются в новой ячейке, и фильтрация работает, как и ожидалось! 👍


❹ Связывание выходов виджета

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

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

Давайте посмотрим, как это должно работать:

Во-первых, нам нужен общий вывод для обоих выпадающих списков:

output = widgets.Output()

Вот два выпадающих списка:

dropdown_year = widgets.Dropdown(options =    unique_sorted_values_plus_ALL(df_london.year))dropdown_purpose = widgets.Dropdown(options = unique_sorted_values_plus_ALL(df_london.purpose))

Затем мы создаем новую функцию,common_filtering, который будет вызываться обоими обработчиками событий. Эта функция будет применять фильтр к данным на оба годаANDцель:
Мы очищаем вывод, затем мы проверяем, является ли какое-либо из значенийALL, в этом случае мы считаем, что соответствующий фильтр удален. Когда оба фильтра присутствуют, вelseЗаявление, мы применяем&работа в обоих фильтрах. Наконец мы фиксируем вывод:

def common_filtering(year, purpose):
output.clear_output()

if (year == ALL) & (purpose == ALL):
common_filter = df_london
elif (year == ALL):
common_filter = df_london[df_london.purpose == purpose]
elif (purpose == ALL):
common_filter = df_london[df_london.year == year]
else:
common_filter = df_london[(df_london.year == year) &
(df_london.purpose == purpose)]

with output:
display(common_filter)

Мы изменяем обработчики событий, чтобы вызватьcommon_filteringфункционировать и передатьchange.newзначение, а также текущийvalueдругого выпадающего списка:

def dropdown_year_eventhandler(change):
common_filtering(change.new, dropdown_purpose.value)def dropdown_purpose_eventhandler(change):
common_filtering(dropdown_year.value, change.new)

Мы привязываем обработчики к выпадающим спискам, и на этом все!

dropdown_year.observe(
dropdown_year_eventhandler, names='value')dropdown_purpose.observe(
dropdown_purpose_eventhandler, names='value')

Фрагмент кода:

Фильтрация кадра данных на основе двух значений

Вот демо:

Демонстрация: фильтрация кадра данных на основе двух значений

❺ Создание панели инструментов

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

Полезный числовой виджетBoundedFloatText; мы дадим емуmin,maxи начальныйvalueи инкрементныйstep,

bounded_num = widgets.BoundedFloatText(
min=0, max=100000, value=5, step=1)

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

def colour_ge_value(value, comparison):
if value >= comparison:
return 'color: red'
else:
return 'color: black'

Теперь мы минимально исправимcommon_filteringфункция для:

  • Добавить новоеnumвходной параметр:
def common_filtering(year, purpose, num):
  • применить стиль, вызвавcolour_ge_valueфункция для трех числовых столбцов:
with output:
display(common_filter
.style.applymap(
lambda x: colour_ge_value(x, num),
subset=['visits','spend', 'nights']))

Существующие обработчики событий должны быть скорректированы, чтобы передатьbounded_num.value:

def dropdown_year_eventhandler(change):
common_filtering(change.new, dropdown_purpose.value,
bounded_num.value)def dropdown_purpose_eventhandler(change):
common_filtering(dropdown_year.value, change.new,
bounded_num.value)

И, наконец, мы подключим обработчик событий нового виджета:

def bounded_num_eventhandler(change):
common_filtering(dropdown_year.value, dropdown_purpose.value,
change.new)bounded_num.observe(bounded_num_eventhandler, names='value')

Фрагмент кода:

Значения цветового кадра

Вот демо:

Демо: цвет данных

Черчение

Далее мы добавим новый график, чтобы построить базовую одномерную плотность числа посещений (KDE → Оценка плотности ядра). Мы будем использовать seaborn, поэтому давайте импортируем библиотеки:

import seaborn as sns
import matplotlib.pyplot as plt

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

plot_output = widgets.Output()

Теперь мы изменимcommon_filteringФункция для построения новой диаграммы:

  • Сначала мы очищаем вывод:
plot_output.clear_output()
  • а потом мы называемkdeplotМетод морского происхождения путем передачи количества посещений:
with plot_output:
sns.kdeplot(common_filter['visits'], shade=True)
plt.show()

Наконец, единственное, что нам нужно сделать, это отобразить выходные данные в новой ячейке:

display(output)
display(plot_output)

Фрагмент кода:

Управление графиком

Вот демо:

Демо: Управление графиком

❻ Макет приборной панели

До сих пор наш пользовательский интерфейс функционировал, но занимал много недвижимости.

Мы будем первымиорганизоватьвиджеты ввода по горизонтали.HBoxдобавим виджеты к нему по одному слева направо:

input_widgets = widgets.HBox(
[dropdown_year, dropdown_purpose, bounded_num])display(input_widgets)
HBox

Далее мы создадимконтейнердля выхода.Tabотлично подходит для этого. На первой вкладке будет размещен фрейм данных, а на второй - график.

tab = widgets.Tab([output, plot_output])
tab.set_title(0, 'Dataset Exploration')
tab.set_title(1, 'KDE Plot')display(tab)
табуляция

Наконец, мы сложим входные виджеты и вкладку друг над другом с помощьюVBox,

dashboard = widgets.VBox([input_widgets, tab])display(dashboard)
VBox

Это выглядит немного «застрявшим», поэтому в качестве последнего шага мыпольскийнаша панель инструментов, добавив немного места Мы определимLayoutдавая 50px поле между пунктами.

item_layout = widgets.Layout(margin='0 0 50px 0')

Мы будем называть этот макет для каждого элемента:

input_widgets = widgets.HBox(
[dropdown_year, dropdown_purpose, bounded_num],
layout=item_layout)tab = widgets.Tab([output, plot_output],
layout=item_layout)

и та да ... Наша готовая панель приборов:

Панель приборов

Финальная демонстрация

Демо: Final Dashboard

PSВ целях демонстрации в некоторых из этих демонстраций я использовал подмножество набора данных, т.е.df_london = df_london.sample(250),


Идти дальше

Вы также можете использовать несколько сторонних виджетов, среди которых наиболее популярными являются:
• 2D графика:bqplot
• 3-D визуализация:pythreejsа такжеipyvolume
• Картирование:ipyleafletа такжеGMaps,

Вы также можете создавать свои собственные виджеты! Для получения дополнительной информации посмотритеВот,


резюмировать

Мы увидели довольно широкий спектр виджетов в действии, но мы все еще здесь только немного поцарапали - мы можем создавать действительно сложные и обширные графические интерфейсы с использованием ipywidgets. Я надеюсь, что вы все согласны с тем, что они заслуживают места в любом наборе инструментов Data Scientist, поскольку они повышают нашу производительность и повышают ценность при исследовании данных.

Спасибо за чтение!


Я регулярно пишу о технологии и данных на среднем - если вы хотите прочитать мои будущие сообщения, пожалуйста,'Подписывайтесь на меня!

Оригинальная статья

Footer decor

© www.machinelearningmastery.ru | Ссылки на оригиналы и авторов сохранены. | map