Предварительные требования для этой публикации: базовые знания Python и Jupyter Notebook; базовые знания о машинном обучении.
В этом посте я расскажу, как создать причудливую и интерактивную визуализацию данных, подобную этой.
Но прежде чем мы перейдем к этому, давайте начнем с понимания, почему нам нужно визуализировать данные.
Зачем нужна визуализация данных?
Визуализация данных - это группа методов, которые могут преобразовывать гигантские данные с сотнями или тысячами измерений в 2D / 3D представление, чтобы мы, крошечные люди, могли хорошо понимать.
Обычно есть две причины для его использования:
- Визуализируйте необработанные данные, когда данные представлены в 2D / 3D пространстве, их легко идентифицировать. Если для каждой точки данных есть категориальные метки, мы можем легко сказать, какие категории похожи, а какие дальше друг от друга. И это может дать нам представление о том, насколько сложна модель, которую нам нужно построить для такого набора данных. Например, если на нашем 2D / 3D графике разные категории уже находятся в соответствующих блоках, мы, вероятно, не захотим использовать Excalibur, чтобы убить такую курицу.
- Визуализируйте закодированные функции из необработанных данных / внедрений, мы хотели бы знать, имеют ли эти функции смысл или модель кодировщика усвоила правильные вещи. Обычно это более применимо к наборам данных изображений, где по графику мы можем сказать, соответствуют ли закодированные функции тем семантическим характеристикам, которые распознаются людьми.
В этом посте я расскажу о методах визуализации данных, дам несколько практических примеров и, конечно же, сделаю это увлекательным, сделав его интерактивным.
Методы визуализации данных
Существует множество способов визуализации данных, два самых популярных из них - PCA и t-SNE:
- PCA: анализ основных компонентов, как следует из названия, он находит наиболее важные и релевантные компоненты для представления данных. По сути, этот алгоритм снижает размерность до минимума. Для любопытных есть более подробное объяснение.
- T-SNE: t-распределенное стохастическое соседнее встраивание, более сложное название. По сути, этот алгоритм смотрит на распределение данных и пытается представить то же распределение с меньшим количеством измерений. Опять более подробная информация.
Алгоритм T-SNE требует больших вычислительных ресурсов и времени по сравнению с PCA. Однако у PCA есть ограничение: это метод уменьшения линейных размеров. В общем, t-SNE может моделировать истинное распределение данных лучше, чем PCA.
Визуализация статических данных
Сначала я хотел бы начать с неинтерактивной визуализации данных, поскольку ее проще реализовать. Другая причина заключается в том, что преимущества интерактивной визуализации данных можно будет лучше оценить, если у вас будет некоторый опыт работы с неинтерактивной версией.
Но если вы любите приключения и готовы принять вызов, смело переходите к следующему разделу :)
Вот ссылка на полный код на github, но позвольте мне помочь вам шаг за шагом.
Пакеты python, которые нам нужны для визуализации статических данных, - это numpy, matplotlib и sklearn, пожалуйста, установите их, если вы этого не сделали, и импортируйте их в наш проект.
import numpy as np import matplotlib.pyplot as plt from matplotlib import offsetbox from sklearn import manifold, datasets, decomposition
и мы будем использовать классические наборы данных рукописных цифр MNIST, чтобы продемонстрировать визуализацию необработанных данных, так что давайте подготовим данные
digits = datasets.load_digits(n_class=10) X = digits.data y = digits.target
Давайте определим функцию построения графика, которая будет использоваться позже. Эта простая функция в основном выполняет три задачи. Сначала он масштабирует значения, чтобы они соответствовали графику. Затем он форматирует представление точки данных так, чтобы каждая точка данных отображалась в виде цветного текста. Наконец, он добавляет AnnotationBox для некоторых образцов, который показывает соответствующее изображение точки данных.
def plot_MNIST(X, title=None): x_min, x_max = np.min(X, 0), np.max(X, 0) X = (X - x_min) / (x_max - x_min) # scale the values to fit plt.figure(figsize= (10,10)) ax = plt.subplot(111) for i in range(X.shape[0]): plt.text(X[i, 0], X[i, 1], str(digits.target[i]), color=plt.cm.Set1(y[i] / 10.), fontdict={'weight': 'bold', 'size': 9}) if hasattr(offsetbox, 'AnnotationBbox'): ## only print thumbnails with matplotlib > 1.0 shown_images = np.array([[1., 1.]]) # just something big for i in range(digits.data.shape[0]): dist = np.sum((X[i] - shown_images) ** 2, 1) if np.min(dist) < 5e-3: ## don't show points that are too close continue shown_images = np.r_[shown_images, [X[i]]] imagebox = offsetbox.AnnotationBbox( offsetbox.OffsetImage(digits.images[i], cmap=plt.cm.gray_r), X[i]) ax.add_artist(imagebox) plt.xticks([]), plt.yticks([]) if title is not None: plt.title(title)
Затем мы используем функцию sklearn для вычисления PCA, как вы можете догадаться, «n_components = 2» указывает, что результат должен состоять из двух измерений.
print("Computing PCA projection") t0 = time() X_pca = decomposition.TruncatedSVD(n_components=2).fit_transform(X) plot_MNIST(X_pca, "Principal Components projection of the digits (time %.2fs)" % (time() - t0)) plt.show()
Ниже представлен результат визуализации данных PCA. Время, необходимое для его обработки, невероятно быстрое, всего 0,01 секунды. Мы можем сказать, что цифры в одной категории собраны вместе, но кластеры перекрывают друг друга, и в центральной части графика есть большой беспорядок.
Тогда давай попробуем t-SNE. Снова мы используем предварительно созданную функцию sklearn для вычисления t-SNE, кроме нашего старого друга «n_components», есть еще один параметр «init = 'pca'», он предназначен для инициализации распределения с помощью pca, чтобы лучше сохранить глобальную структуру распространение.
print("Computing t-SNE embedding") t0 = time() X_tsne = manifold.TSNE(n_components=2, init='pca').fit_transform(X) plot_MNIST(X_tsne, "t-SNE embedding of the digits (time %.2fs)" % (time() - t0)) plt.show()
В результате t-SNE разные рукописные цифры хорошо разделены, это более четкое представление по сравнению с PCA, а также четкое указание на то, что этому набору данных не требуется слишком сложная модель для выполнения классификации.
Интерактивная визуализация данных
Мы успешно реализовали визуализацию данных PCA и t-SNE в предыдущем разделе. Но такая визуализация статична, мы не можем увеличивать интересующую нас область, мы не можем делать такие крутые вещи, как вращение точек данных в трехмерном пространстве, и у нее определенно отсутствует красивый интерфейс.
Tensorboard - это волшебный инструмент, который предоставляет все, что нам нужно. Это инструмент визуализации из семейства Tensorflow. Он изначально поддерживает Tensorflow и недавно также открыл границу с Pytorch. В этом посте мы будем использовать Tensorflow, вот ссылка на полный код, а ниже - пошаговое руководство.
Помимо пакетов, которые мы уже установили ранее, нам также необходимо установить Tensorflow, поэтому, пожалуйста, установите его, если вы еще не сделали этого.
%matplotlib inline import matplotlib.pyplot as plt import tensorflow as tf import numpy as np import os from tensorflow.contrib.tensorboard.plugins import projector from tensorflow.examples.tutorials.mnist import input_data
Чтобы использовать тензорную плату для визуализации данных, нам нужно подготовить для нее три вещи:
- данные в форме ckpt. Это точки данных, которые мы собираемся визуализировать.
- метаданные в формате TSV (необязательно). Метаданные могут быть категориальной меткой, чтобы мы могли позже раскрасить точки по метке. Он также может быть в текстовом формате, поэтому, если мы визуализируем вложение слова, мы можем проверить, какое слово представляет точка данных.
- спрайт в формате png (необязательно). Это для набора данных изображения. Когда мы хотим видеть образцы изображений, а не просто точки, нам это нужно.
Все они должны быть помещены в один каталог журнала, поэтому давайте определим каталог и имена файлов, а также настроим проектор (который будет использоваться Tensorboard) так, чтобы он указывал на правильные пути.
LOG_DIR = os.getcwd()+'/mnist_log' path_for_mnist_checkpoint = os.path.join(LOG_DIR, "model.ckpt") path_for_mnist_metadata = os.path.join(LOG_DIR,'metadata.tsv') path_for_mnist_sprites = os.path.join(LOG_DIR,'mnistdigits.png') tensor_name = 'mnist_embeddings' summary_writer = tf.summary.FileWriter(LOG_DIR) config = projector.ProjectorConfig() embedding = config.embeddings.add() embedding.tensor_name = tensor_name embedding.metadata_path = path_for_mnist_metadata embedding.sprite.image_path = path_for_mnist_sprites embedding.sprite.single_image_dim.extend([28,28]) projector.visualize_embeddings(summary_writer, config)
Загрузим набор данных MNIST.
Samples_to_visualize = 500 mnist = input_data.read_data_sets("MNIST_data/", one_hot=False) batch_xs, batch_ys = mnist.train.next_batch(Samples_to_visualize)
Давайте сначала создадим данные в форме ckpt (checkpoint)。
embedding_var = tf.Variable(batch_xs, name=tensor_name) sess = tf.InteractiveSession() sess.run(tf.global_variables_initializer()) saver = tf.train.Saver() saver.save(sess, path_for_mnist_checkpoint, 1)
Для метаданных мы будем использовать целевые метки и записывать их в формате tsv.
with open(path_for_mnist_metadata,'w') as f: f.write("Index\tLabel\n") for index,label in enumerate(batch_ys): f.write("%d\t%d\n" % (index,label))
Затем мы создаем изображение спрайта. Этот спрайт похож на большой контейнер для всех образцов изображений в нем. Поскольку мы уже установили размер образца изображения в проекте, tenorboard будет сканировать большое изображение спрайта, используя указанное нами измерение в качестве размера окна. Это изображение спрайта должно быть квадратным, но не обязательно полностью заполненным. Вот почему вы видите пробелы в правом нижнем углу изображения.
to_visualise = batch_xs # Reshapes mnist digit embedding shape (batch,28*28) to image shape (batch,28,28) to_visualise = np.reshape(to_visualise,(-1,28,28)) # invert black white to_visualise = 1-to_visualise to_visualise = np.array(to_visualise) img_h = to_visualise.shape[1] img_w = to_visualise.shape[2] n_plots = int(np.ceil(np.sqrt(to_visualise.shape[0]))) # create big sprite template sprite_image = np.ones((img_h * n_plots ,img_w * n_plots )) # fill the sprite templates with the handwritten digits for i in range(n_plots): for j in range(n_plots): this_filter = i * n_plots + j if this_filter < to_visualise.shape[0]: this_img = to_visualise[this_filter] sprite_image[i * img_h:(i + 1) * img_h, j * img_w:(j + 1) * img_w] = this_img # save the sprite image plt.imsave(path_for_mnist_sprites,sprite_image,cmap='gray') plt.imshow(sprite_image,cmap='gray')
Когда все файлы будут подготовлены, каталог журнала должен выглядеть примерно так.
Наконец, мы cd в каталог, содержащий каталог журнала, и вводим команду:
tensorboard --logdir=mnist_log
Результат должен быть:
TensorBoard 1.12.0 at http://YOUR_PC_NAME:6006 (Press CTRL+C to quit)
Поздравляю! Tensorboard работает успешно, и все, что вам нужно сделать, это перейти на ваш localhost: 6006 (этот порт может быть другим, просто следуйте тому, который показан в выводе), чтобы проверить свою работу.
Еще одна вещь, которую нужно изменить, - это опция «Coloyby», мы можем выбрать метаданные в качестве цветового индикатора.
И после этого вы увидите это:
Если вы переключите вкладку PCA на вкладку t-SNE в левом нижнем углу, появится что-то вроде этого
Он продолжает меняться, потому что обучение t-SNE все еще продолжается, когда вы его визуализируете. Когда он станет относительно стабильным, вы можете нажать кнопку «Пауза» в нижнем левом углу, чтобы заморозить танцевальные данные.
Tensorboard - довольно мощный инструмент, и есть немало вещей, которые вы можете настроить. Я не буду вдаваться в подробности в этой части, просто приятно поиграться!
Заключение
В этом посте я кратко представил визуализацию данных, продемонстрировал как статическую, так и интерактивную визуализацию данных.
Пока что мы визуализировали необработанные данные. Поскольку я не хочу, чтобы этот пост был слишком длинным, я упустил часть визуализации встраиваемых / закодированных функций. Основное изменение для визуализации внедрений состоит в том, что вместо использования необработанных данных нам нужно использовать кодировщик для преобразования необработанных данных в пространство функций и использовать преобразованные данные для визуализации. Те, кто хочет попробовать, могут проверить word2vec, который преобразует слова в вложения, или предварительно обученную модель vgg / resnet, которая преобразует изображения в вложения. Удачного знакомства :)