Виджеты в jupyter notebook - это по сути добавление к интерфейсу тетрадок. Они привносят интерактив, могут использоваться для хранения и передачи информации. С их помощью можно превратить тетрадку в нечто понятное простому пользователю и использовать как dashboard или простой аналитический инструмент.
Вот что вы увидите:
Самый простой способ работать с этой тетрадкой - использовать https://try.jupyter.org/. Это официальная возможность загрузить и запустить тетрадку.
Установка сама по себе не является сложной: это можно сделать через pip:
pip install ipywidgets
pip install widgetsnbextension
jupyter nbextension enable --py widgetsnbextension
Или через Anaconda:
conda install -c conda-forge ipywidgets
conda install -c conda-forge widgetsnbextension
Но вот нюанс: установить-то легко, а вот заставить корректно работать - сложно. Если достаточно, чтобы всё работало в локальной тетрадке, то можно просто установить самые последние версии (только проверьте, что они последние, а то в канале может быть не самая последняя версия). Если же хочется, чтобы этим можно было поделиться, например, через nbviewer, нужно ставить ipywidgets 6.0.0 и widgetsnbextension 2.0.0 - nbviewer пока не поддерживает более новые версии. С другой стороны, nbviewer всё равно не может отображать все виджеты корректно.
#Импорт библиотек
from ipywidgets import interact, interactive, interact_manual
import ipywidgets as widgets
import time
import numpy as np
import pandas as pd
import datetime
import seaborn as sns
import matplotlib.pyplot as plt
%matplotlib inline
from IPython.display import display
Во-первых, можно просто отобразить виджет сам по себе.
widgets.IntSlider()
A Jupyter Widget
Но это просто создаёт слайдер, с которым можно поиграться, а пользы от него нет. Следующим шагом является создание переменной с виджетом
w = widgets.IntSlider(value=2)
w
A Jupyter Widget
И теперь мы можем получить значение виджета и использовать для чего-нибудь.
print(w.value, w.value ** 2)
2 4
Другой вариант - отображение виджета с помощью функции IPython display; это работает точно также как и сам вызов переменной.
display(w)
A Jupyter Widget
Вы передвигали слайдер в прошлой ячейке? Если нет - попробуйте. Можно заметить, что слайдер двигается в обеих ячейках, где была использована переменная w. Это нормальное поведение - у нас есть лишь один объект на back-end, так что получаются синхронизированные объекты на front-end.
После того как в виджете было установлено некое значение, виджет можно закрыть командой w.close()
.
Пока мы видели простые виджеты, значения которых можно было использовать в дальнейшем. Если же хочется, чтобы с выбранным значением что-то произошло сразу, стоит использовать interact
. interact
позволяет вызывать функцию, в которую передаётся значение виджета. При изменении значения виджета функция будет динамически показывать обновлённый результат.
def f(x):
return x, str(x) * 2
interact(f, x=10);
A Jupyter Widget
Замечу, что в interact
обязательно передавать начальное значение, поскольку это напрямую определяет тип виджета. Если передать int или float, то будет слайдер с соответствующими данными (как это показано выше).
Кроме того можно передать:
interact(f, x='Текст');
interact(f, x=['лопата', 'солнце']);
interact(f, x=True);
A Jupyter Widget
A Jupyter Widget
A Jupyter Widget
Кому-то может быть интересна возможность использовать interact
в качестве декоратора. В таком случае функцию можно не передавать в interact
.
@interact(x=1.0)
def g(x):
return x
A Jupyter Widget
Наконец, есть такая интересная штука как interactive
. По сути это является комбинацией двух предыдущих спообов: мы задаем функцию, а потом можем использовать как сами результаты, так и значения отдельных виджетов.
По умолчанию interactive
показывает только сами виджеты, но не результат функции. Чтобы увидеть результат, надо явно его отображать, используя display
.
Замечу, что можно использовать больше одной переменной и получить больше одного виджета.
def f(x, y, z):
if z == 'Сумма':
display(x + y)
return x + y
else:
display(x * y)
return x * y
w = interactive(f, x=1, y=2.5, z=['Сумма', 'Произведение'])
w
A Jupyter Widget
print(w.kwargs)
print(w.result)
{'x': 1, 'y': 2.5, 'z': 'Сумма'} 3.5
До сих пор я показывал отдельные виджеты и простые способы их использования, но с ними можно делать много интересных вещей. Просто перечислять их довольно нудно, поэтому я буду приводить примеры и на их основе объяснять возможности.
Мы уже видели, что в interact
можно передавать функцию, результат которой будет обновляться при изменении параметров. Интереснее посмотреть это на примере построения графиков. Я хочу сделать график, который будет зависеть от задаваемого параметра, а также предложить возможность выбирать цвет графика.
Для начала нужно создать виджет для выбора цвета. Вообще говоря виджеты можно передавать в функцию как значение параметра, но это громоздко, поэтому удобнее создать виджет, а потом передавать его в виде переменной.
Виджеты имеют 2 группы свойств: общие (например, описание или начальное значение) и специфичные для типа виджета (например, границы для числовых виджетов).
Этот виджет имеет следующие параметры:
pick_color = widgets.ColorPicker(
concise=False,
description='Цвет линии:',
value='teal',
disabled=False
)
Теперь сам интерактивный виджет. Функция для построения графика будет иметь 2 параметра:
Далее использую interact
:
def h(n=3, c='orange'):
x = np.linspace(0, 5, 10)
plt.plot(x, x ** (n / (x + 1)) + x ** (x / n) / (n ** 2) + (n - x) ** 2 - x * np.log(n) + n * np.exp(x / n), color=c)
plt.show()
interact(h, n=[i for i in range(2, 6)], c=pick_color);
A Jupyter Widget
Виджеты позволяют делать вызов функции после определённых событий:
Кроме того можно связать виджеты - чтобы при изменении значения одного виджета изменялось значение другого виджета.
Рассмотрим пример: пользователь задаёт длины сторон прямоугольника и хочет узнать его площадь. Для начала я задаю 2 виджета с соответсвующими названиями. Для ограничения значений можно задать минимальное и максимальное значение, а также шаг, с которым будут изменяться значения.
x1 = widgets.IntSlider(min=2, max=40.0, step=2, description='Высота')
x2 = widgets.FloatSlider(min=2, max=80.0, step=0.5, description='Ширина', value=5.0)
Добавим ограничение - высота прямоугольника не может быть больше его ширины. Для этого используется observe
- при каждом изменении объекта мгновенно вызывается функция. А в функции мы будет приравнивать максимальное значение виджета x к текущему значению виджета y.
def update_x1_range(*args):
x1.max = x2.value
x2.observe(update_x1_range, 'value')
Теперь создадим кнопку, при нажатии на которую будет происходить вычисление. Для этого задаём соответствующий объект. И здесь в первый раз используется настройка внешнего вида виджетов. layout
позволяет настраивать css объектов. Большинство параметров взять из самого CSS, но есть и различия, почитать подробнее можно тут. В данном случае я просто задаю ширину кнопки.
При нажатии на кнопку будет показана площадь прямоугольника, кнопка и слайдеры станут неактивными (значение disabled
становится True
).
button1 = widgets.Button(description="Нажмите, чтобы посчитать площадь прямоугольника!", layout=widgets.Layout(width='40%'))
def on_button_clicked(b):
print('Площадь прямоугольника: {}.'.format(x1.value * x2.value))
button1.disabled = True
x1.disabled = True
x2.disabled = True
def stat(x1, x2):
print('Высота: {0}. Ширина: {1}.'.format(x1, x2))
interact(stat, x1=x1, x2=x2);
display(button1)
button1.on_click(on_button_clicked)
A Jupyter Widget
A Jupyter Widget
Площадь прямоугольника: 243.0. Площадь прямоугольника: 972.0.
Для полноты картины добавлю ещё одну кнопку, которая откроет данные для ввода, чтобы можно было ещё раз посчитать площать прямоугольника.
Стоит заметить, что старые результаты по умолчанию остаются, а новые появляются на следующих строках.
button2 = widgets.Button(description="Использовать другие данные", layout=widgets.Layout(width='40%'))
def on_button_clicked2(b):
button1.disabled = False
x1.disabled = False
x2.disabled = False
display(button2)
button2.on_click(on_button_clicked2)
A Jupyter Widget
На основе игрушечного примера о заказе компьютера я продемонстрирую большое количество разнообразных виджетов и то, как они могут быть использованы.
Для начала мы предлагаем пользователю выбрать интересующий его товар. Этот виджет позволяет выбрать одно значение из списка.
print('Выбор товара:')
pc_type = widgets.Select(
options=['Компьютер', 'Планшет', 'Ноутбук'],
value='Компьютер',
description='Товар:'
)
pc_type
Выбор товара:
A Jupyter Widget
Теперь предложим указать количество товара. jslink
связывает 2 виджета, имеющих сравнимые значения (например числа), либо изменяет значения виджетов согласно заданному правилу (например, при положительных значениях получается один текст, при неотрицательных - другой).
Также здесь используется новый виджет - BoundedIntText
. Это поле для ввода integer, для которого можно задать минимальные и максимальные значения. Можно попробовать ввести значение вне заданных пределов, но после того, как будет выделено что-то другое, значение сбросится к ближайшему значению из пределов.
a = widgets.BoundedIntText(min=1, max=5)
b = widgets.IntSlider(min=1, max=5)
print('Укажите количество - введите число или выберите нужное значение')
display(a, b)
mylink = widgets.jslink((a, 'value'), (b, 'value'))
Укажите количество - введите число или выберите нужное значение
A Jupyter Widget
A Jupyter Widget
В качестве шутки предложим выбрать мощность покупаемой техники. Для этого используется виджет-слайдер для которого можно добавить ранжированный список текстовых значений.
power = widgets.SelectionSlider(
options=['калькулятор', 'хороший', 'мощный', 'deep learning', 'kaggle'],
value='хороший',
description='Мощность:',
disabled=False,
orientation='horizontal',
readout=True, layout=widgets.Layout(width='40%')
)
power
A Jupyter Widget
А теперь подарим клиенту бонус. Это виджет для множественного выбора с помощью клавиш Ctrl/Shift.
sel_mult = widgets.SelectMultiple(
options=['Ручка', 'Стикер', 'Скидка'],
value=['Стикер'],
#rows=10,
description='Бонусы:',
disabled=False
)
sel_mult
A Jupyter Widget
Заказ укомплектован, теперь пора обговорить условия доставки. Первое - как будет доставлен товар. RadioButtons
, как и Select
, даёт возможность выбора одной опции.
Заодно познакомимся с такой удобной штукой как HBo
x. Он позволяет делать более гибкую настройку отображения виджетов и их описания. Например, изменять ширину описания виджета можно его свойствами, а можно описание и виджет вложить внутрь Box
. HBox
и VBox
являются соответственно горизонтальными и вертикальными контейнерами для виджетов или их описаний.
delivery = widgets.RadioButtons(
options=['Доставка', 'Самовывоз'],
disabled=False
)
widgets.HBox([widgets.Label(value="Способ доставки:"), delivery])
A Jupyter Widget
Настала пора выбрать способ оплаты. ToggleButtons
выводит кнопки, одна из которых может быть нажата. Виджет позволяет настроить названия кнопок, всплывающие тултипы и даже иконки (для задания иконок используются названия иконок для Font Awesome).
Также здесь используется задание параметров виджета используя style
. Это дополнительный способ (по отношению к layout
), но это уже не css, а внутренние свойства виджетов. Есть ряд свойств, которые относятся только к определённым виджетам.
pay_method = widgets.ToggleButtons(
options=['Карта', 'Наличные'],
description='Способ оплаты:',
disabled=False,
button_style='success',
tooltips=['Карта', 'Наличные'],
icons=['credit-card', 'money']
)
pay_method.style.button_width='100px'
pay_method
A Jupyter Widget
Ещё есть виджет для выбора даты доставки.
date = widgets.DatePicker(
description='',
disabled=False
)
date
widgets.VBox([widgets.Label(value="Дата доставки:"), date])
A Jupyter Widget
Дата вполне может быть выбрана неверно. Допустим мы позволяет выбрать дату в промежутке от 2 до 7 дней от текущего. Сделаем проверку.
Для отображения результата будет использован виджет Valid
, который показывает валидность.
button3 = widgets.Button(description="Проверить дату", layout=widgets.Layout(width='40%'))
def on_button_clicked3(d):
valid = widgets.Valid(
value=False,
description='Корректная дата!',
)
valid.style.description_width='200px'
if date.value == None:
valid.description='Некорректная дата!'
display(valid)
print('Дата доставки не указана.')
elif (date.value - datetime.datetime.today().date()).days in range(2,8):
valid.value = True
display(valid)
else:
valid.description='Некорректная дата!'
display(valid)
print('Дата доставки должна быть в периоде 2-7 дней от текущей даты.')
display(button3)
button3.on_click(on_button_clicked3)
A Jupyter Widget
A Jupyter Widget
Теперь можно выбрать время дня, в которое следует осуществить доставку. IntRangeSlider
позволяет указать интервал.
period = widgets.IntRangeSlider(
value=[9, 18],
min=7,
max=22,
step=1,
description='Время:',
disabled=False,
continuous_update=False,
orientation='vertical',
readout=True,
readout_format='',
)
period
A Jupyter Widget
И, конечно, есть виджет для ввода текста. Для ввода короткого текста можно использовать Text, для текста побольше - Textarea.
Здесь мы видим событие on_submit при вводе текста - оно происходит после ввода текста и нажатия Enter.
text_comment = widgets.Text(
value=' ',
description='Комментарий к доставке:',
disabled=False
)
text_comment
def text_submit(t=text_comment):
print("Комментарий '{0}' зафиксирован.".format(text_comment.value.strip()))
text_comment.style.description_width='200px'
display(text_comment)
text_comment.on_submit(text_submit)
A Jupyter Widget
Комментарий 'Быстрее хочу!' зафиксирован.
Заказ оформлен, теперь надо бы показать клиенту все, что он указывал раньше, и предложить ввести адрес доставки. Первый вариант этого - сделать вложенные VBox
и HBox
, второй вариант - использовать Accordion
и Tab
.
Предварительно я "поворачиваю" слайдер для выбора временного периода доставки в горизонтальное положение, а также создаю новый виджет для ввода адреса доставки. Textarea
позволяет задавать значение по умолчанию, а также значение, которое будет отображаться, если очистить поле.
Виджет Tab
содержит в себе Accordion
. Accordion
, в свою очередь, содержит в себе обычные виджеты, каждый из которых хранится на отдельной мини-вкладке. Это осуществляется перез параметр children
. Названия этих мини-вкладок задаются для соответствующих индексов через set_title
. Подобным образом Accordion
вкладывается в Tab
.
period.orientation='horizontal'
address = widgets.Textarea(
value='Адрес',
placeholder='Не дом и не улица',
description='Адрес:',
disabled=False
)
tab_nest = widgets.Tab()
accordion1 = widgets.Accordion(children=[pc_type, b, power, sel_mult])
accordion1.set_title(0, 'Товар:')
accordion1.set_title(1, 'Количество:')
accordion1.set_title(2, 'Мощность:')
accordion1.set_title(3, 'Бонус:')
accordion2 = widgets.Accordion(children=[widgets.HBox([widgets.Label(value="Способ доставки:"), delivery]),
pay_method,
widgets.VBox([widgets.Label(value="Дата доставки:"), date]),
period,
text_comment, address])
accordion2.set_title(0, 'Способ доставки:')
accordion2.set_title(1, 'Способ оплаты:')
accordion2.set_title(2, 'Дата доставки:')
accordion2.set_title(3, 'Время доставки:')
accordion2.set_title(4, 'Комментарий:')
accordion2.set_title(5, 'Адрес доставки:')
tab_nest.children = [accordion1, accordion2]
tab_nest.set_title(0, 'Заказ:')
tab_nest.set_title(1, 'Доставка:')
tab_nest
A Jupyter Widget
На завершающем этапе пользователь видит итоговую информацию о заказе.
Во-первых, используется виджет для отображения прогресса. Самый удобный способ обновлять его значение - увеличивать его value
при определенном событии.
progress = widgets.IntProgress(
value=0,
min=0,
max=10,
step=1,
description='',
bar_style='success',
orientation='horizontal'
)
Ещё один интересный виджет - Out
. Он отображает то, что передаётся в него: это может быть просто печать данных через print
, rich text, media и другие вещи.
out = widgets.Output()
out
A Jupyter Widget
button4 = widgets.Button(description="Проверить данные", layout=widgets.Layout(width='40%'))
def on_button_clicked4(d):
with out:
display(widgets.VBox([widgets.Label(value="Проверка информации заказе:"), progress]))
print('Информация о заказе:')
for i in range(len(accordion1.children)):
if type(accordion1.children[i].value) != tuple:
print(accordion1.get_title(i), accordion1.children[i].value)
progress.value +=1
time.sleep(0.5)
else:
print(accordion1.get_title(i), ' '.join([j for j in accordion1.children[i].value]))
progress.value +=1
time.sleep(0.5)
#print(accordion1.get_title(i)), [print(j) for j in accordion1.children[i].value]
for i, e in enumerate([delivery, pay_method, date, period, text_comment, address]):
print(accordion2.get_title(i), e.value)
progress.value +=1
time.sleep(0.5)
display(button4)
button4.on_click(on_button_clicked4)
A Jupyter Widget
Поскольку этот гайд о виджетах, а не об оформлении доставки, я не делаю много вещей, которые следовало бы делать: проверка на заполненность и адекватность значений, разные возможности при выборе самовывоза и доставки и т. д.
Я описал почти все возможности и способы применения ipywidgets. Есть ещё некоторые, но они являются более глубокими и будут реже использоваться, поэтому не буду заострять на этом внимание.
Поскольку наш курс посвящён машинному обучению, я решил сделать дополнительную часть, где с помощью виджетов можно поиграть с датасетом iris и попробовать разные алгоритмы машинного обучения. Это простой пример того, как виджеты могут использоваться для создания интерфейса, который может быть понятным простому пользователю.
В ячейке ниже будет импорт всех библиотек, определение функций и задание виджетов, чтобы дальше ничто не отвлекало от взаимодействия с интерфейсом. В этой ячейке содержится следующее:
Стоит заметить, что для запуска классификации используется interact_manual
, а не просто interact
. В результате появляется кнопка для запуска, и не происходит автоматический пересчёт результатов. Это довольно удобно, иначе при передвижении слайдеров модели несколько раз пересчитывались бы.
from sklearn.datasets import load_iris
from sklearn import linear_model
from sklearn.model_selection import cross_val_score, train_test_split
from sklearn.metrics import adjusted_rand_score
from sklearn.neural_network import MLPClassifier
from sklearn.neighbors import KNeighborsClassifier
from sklearn.svm import SVC
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.decomposition import PCA
from sklearn.cluster import KMeans
iris = load_iris()
X = iris.data
y = iris.target
data = pd.DataFrame(np.concatenate((X, y.reshape(-1, 1)), axis=1), columns=iris.feature_names + ['y'])
def pp(kind='scatter', diag_kind='hist'):
sns.pairplot(data, hue='y', kind=kind, diag_kind=diag_kind, vars=iris.feature_names);
def dp(graph_type='distr', variable=iris.feature_names[0]):
if graph_type == 'distr':
sns.distplot(data[variable]);
elif graph_type == 'box':
sns.boxplot(y=variable, orient='v', width=0.2, x="y", data=data)
else:
sns.stripplot(x="y", y=variable, data=data, jitter=True);
c = widgets.Checkbox(
value=True,
description='Stratify',
disabled=False
)
ts = widgets.FloatSlider(value=0.25, min=0.05, max=0.4, description='Test_size', step=0.05)
ts.style.handle_color = 'lightblue'
def plot_graph(clf, X_train, y_train):
x_min, x_max = X_train[:, 0].min() - .5, X_train[:, 0].max() + .5
y_min, y_max = X_train[:, 1].min() - .5, X_train[:, 1].max() + .5
xx, yy = np.meshgrid(np.arange(x_min, x_max, .02), np.arange(y_min, y_max, .02))
Z = clf.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
plt.figure(1, figsize=(4, 3))
plt.pcolormesh(xx, yy, Z)
plt.scatter(X_train[:, 0], X_train[:, 1], c=y_train, edgecolor='k')
plt.xlim(xx.min(), xx.max())
plt.ylim(yy.min(), yy.max())
plt.xlabel('Признак 1')
plt.ylabel('Признак 2')
plt.show()
def kn(n_neighbors=5, weights='uniform', test_size=ts.value, strat=c.value):
X1 = PCA(n_components=2).fit_transform(X)
if c.value == True:
X_train, X_valid, y_train, y_valid = train_test_split(X1, y, test_size=test_size, stratify=y)
else:
X_train, y_train, X_valid, y_valid = train_test_split(X1, y, test_size=test_size, stratify=None)
clf = KNeighborsClassifier(n_neighbors=n_neighbors, weights=weights)
clf.fit(X_train, y_train)
plot_graph(clf, X_train, y_train)
print('Точность на кросс-валидации: {0:.2f}%.'.format(cross_val_score(clf, X_train, y_train).mean() * 100))
print('Точность на отложенной выборке: {0:.2f}%.'.format((np.sum(y_valid == clf.predict(X_valid)) / len(y_valid)) * 100))
def lr(reg=1.0, fi=True, solver='newton-cg', multi_class='ovr', test_size=ts.value, strat=c.value):
X1 = PCA(n_components=2).fit_transform(X)
if c.value == True:
X_train, X_valid, y_train, y_valid = train_test_split(X1, y, test_size=test_size, stratify=y)
else:
X_train, y_train, X_valid, y_valid = train_test_split(X1, y, test_size=test_size, stratify=None)
clf = linear_model.LogisticRegression(C=reg, fit_intercept=fi, solver=solver, max_iter=1000, multi_class=multi_class)
clf.fit(X_train, y_train)
plot_graph(clf, X_train, y_train)
print('Точность на кросс-валидации: {0:.2f}%.'.format(cross_val_score(clf, X_train, y_train).mean() * 100))
print('Точность на отложенной выборке: {0:.2f}%.'.format((np.sum(y_valid == clf.predict(X_valid)) / len(y_valid)) * 100))
def svc(reg=1.0, kernel=True, sfs='ovr', test_size=ts.value, strat=c.value):
X1 = PCA(n_components=2).fit_transform(X)
if c.value == True:
X_train, X_valid, y_train, y_valid = train_test_split(X1, y, test_size=test_size, stratify=y)
else:
X_train, y_train, X_valid, y_valid = train_test_split(X1, y, test_size=test_size, stratify=None)
clf = SVC(C=reg, kernel=kernel, decision_function_shape=sfs)
clf.fit(X_train, y_train)
plot_graph(clf, X_train, y_train)
print('Точность на кросс-валидации: {0:.2f}%.'.format(cross_val_score(clf, X_train, y_train).mean() * 100))
print('Точность на отложенной выборке: {0:.2f}%.'.format((np.sum(y_valid == clf.predict(X_valid)) / len(y_valid)) * 100))
def dt(criterion='gini', min_samples_split=2, min_samples_leaf=1, min_weight_fraction_leaf=0.0, test_size=ts.value,
strat=c.value):
X1 = PCA(n_components=2).fit_transform(X)
if c.value == True:
X_train, X_valid, y_train, y_valid = train_test_split(X1, y, test_size=test_size, stratify=y)
else:
X_train, y_train, X_valid, y_valid = train_test_split(X1, y, test_size=test_size, stratify=None)
clf = DecisionTreeClassifier(criterion=criterion, max_depth=None, min_samples_split=2, min_samples_leaf=min_samples_leaf,
min_weight_fraction_leaf=min_weight_fraction_leaf, max_features=None)
clf.fit(X_train, y_train)
plot_graph(clf, X_train, y_train)
print('Точность на кросс-валидации: {0:.2f}%.'.format(cross_val_score(clf, X_train, y_train).mean() * 100))
print('Точность на отложенной выборке: {0:.2f}%.'.format((np.sum(y_valid == clf.predict(X_valid)) / len(y_valid)) * 100))
def rf(n_estimators=10, criterion='gini', min_samples_split=2, min_samples_leaf=1, min_weight_fraction_leaf=0.0,
test_size=ts.value, strat=c.value):
X1 = PCA(n_components=2).fit_transform(X)
if c.value == True:
X_train, X_valid, y_train, y_valid = train_test_split(X1, y, test_size=ts.value, stratify=y)
else:
X_train, y_train, X_valid, y_valid = train_test_split(X1, y, test_size=ts.value, stratify=None)
clf = RandomForestClassifier(n_estimators=10, criterion=criterion, max_depth=None, min_samples_split=min_samples_split,
min_samples_leaf=min_samples_leaf, min_weight_fraction_leaf=min_weight_fraction_leaf,
max_features='auto')
clf.fit(X_train, y_train)
plot_graph(clf, X_train, y_train)
print('Точность на кросс-валидации: {0:.2f}%.'.format(cross_val_score(clf, X_train, y_train).mean() * 100))
print('Точность на отложенной выборке: {0:.2f}%.'.format((np.sum(y_valid == clf.predict(X_valid)) / len(y_valid)) * 100))
def mlp(hidden_layers=10, nodes=100, activation='relu', solver='adam', alpha=0.0001, test_size=ts.value, strat=c.value):
X1 = PCA(n_components=2).fit_transform(X)
if c.value == True:
X_train, X_valid, y_train, y_valid = train_test_split(X1, y, test_size=ts.value, stratify=y)
else:
X_train, y_train, X_valid, y_valid = train_test_split(X1, y, test_size=ts.value, stratify=None)
clf = MLPClassifier(hidden_layer_sizes=tuple([nodes for i in range(3)]), activation=activation, solver=solver,
alpha=alpha, max_iter=2000)
clf.fit(X_train, y_train)
plot_graph(clf, X_train, y_train)
print('Точность на кросс-валидации: {0:.2f}%.'.format(cross_val_score(clf, X_train, y_train).mean() * 100))
print('Точность на отложенной выборке: {0:.2f}%.'.format((np.sum(y_valid == clf.predict(X_valid)) / len(y_valid)) * 100))
def km(n_clusters=3):
reduced_data = PCA(n_components=2).fit_transform(X)
kmeans = KMeans(init='k-means++', n_clusters=n_clusters)
kmeans.fit(reduced_data)
x_min, x_max = reduced_data[:, 0].min() - 1, reduced_data[:, 0].max() + 1
y_min, y_max = reduced_data[:, 1].min() - 1, reduced_data[:, 1].max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, 0.02), np.arange(y_min, y_max, 0.02))
Z = kmeans.predict(np.c_[xx.ravel(), yy.ravel()]).reshape(xx.shape)
plt.figure(1)
plt.imshow(Z, interpolation='nearest',
extent=(xx.min(), xx.max(), yy.min(), yy.max()),
cmap=plt.cm.Paired,
aspect='auto', origin='lower')
plt.plot(reduced_data[:, 0], reduced_data[:, 1], 'k.', markersize=2)
centroids = kmeans.cluster_centers_
plt.scatter(centroids[:, 0], centroids[:, 1], marker='x', s=169, linewidths=3, color='w', zorder=10)
plt.title('K-means кластеризация')
plt.xlim(x_min, x_max)
plt.ylim(y_min, y_max)
plt.xlabel('Признак 1')
plt.ylabel('Признак 2')
plt.show()
print('Adjusted Rand Index: {0:.2f}%.'.format(adjusted_rand_score(y, kmeans.labels_) * 100))
print('Pairplot показывает взаимодействие между переменными в датасете')
interact(pp, kind=['scatter', 'reg'], diag_kind=['hist', 'kde']);
Pairplot показывает взаимодействие между переменными в датасете
A Jupyter Widget
print('Распределение переменных:')
interact(dp, graph_type=['distr', 'box', 'swarm'], variable=iris.feature_names);
Распределение переменных:
A Jupyter Widget
print('Параметры разбиения тренировочных данных:')
display(ts)
display(c)
Параметры разбиения тренировочных данных:
A Jupyter Widget
A Jupyter Widget
print('Кластеризация с помощью KMeans:')
interact_manual(km, n_clusters=(2,50));
Кластеризация с помощью KMeans:
A Jupyter Widget
print('Классификация с помощью KNeighborsClassifier:')
interact_manual(kn, n_neighbors=(1,50), weights=['uniform', 'distance']);
Классификация с помощью KNeighborsClassifier:
A Jupyter Widget
print('Классификация с помощью Logistic Regression:')
interact_manual(lr, reg=np.logspace(-3, 1, 10), fi=True, solver=['newton-cg', 'sag', 'saga', 'lbfgs'],
multi_class=['ovr', 'multinomial']);
Классификация с помощью Logistic Regression:
A Jupyter Widget
print('Классификация с помощью SVC:')
interact_manual(svc, reg=np.logspace(-3, 1, 10), kernel=['linear', 'poly', 'rbf', 'sigmoid'], sfs=['ovr', 'ovo']);
Классификация с помощью SVC:
A Jupyter Widget
print('Классификация с помощью Decision Tree:')
interact_manual(dt, criterion=['gini', 'entropy'], min_samples_split=(2,30), min_samples_leaf=(1,30),
min_weight_fraction_leaf=(0.0, 0.5));
Классификация с помощью Decision Tree:
A Jupyter Widget
print('Классификация с помощью Random Forest:')
interact_manual(rf, n_estimators=(2, 100), criterion=['gini', 'entropy'], min_samples_split=(2,30), min_samples_leaf=(1,30),
min_weight_fraction_leaf=(0.0, 0.5));
Классификация с помощью Random Forest:
A Jupyter Widget
print('Классификация с помощью Multi-layer Perceptron:')
interact_manual(mlp, hidden_layers=(1, 10), nodes=(3, 100), activation=['identity', 'logistic', 'tanh', 'relu'],
solver=['lbfgs', 'sgd', 'adam'], alpha=np.logspace(-3, 1, 10));
Классификация с помощью Multi-layer Perceptron:
A Jupyter Widget