МИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ РОССИЙСКОЙ ФЕДЕРАЦИИ федеральное государственное бюджетное образовательное учреждение высшего профессионального образования «САНКТ-ПЕТЕРБУРГСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ ТЕЛЕКОММУНИКАЦИЙ ИМ. ПРОФ. М.А. БОНЧ-БРУЕВИЧА» Факультет Информационных систем и технологий Кафедра Информационных управляющих систем КУРСОВОЙ ПРОЕКТ по дисциплине “Технологии обработки информации” ПОЯСНИТЕЛЬНАЯ ЗАПИСКА Автор: студент гр. ИСТ-114 _________/Горохов Д.Г./ (шифр группы) (подпись) (Ф.И.О.) Оценка: ______________ Дата: ________________ Проверил: руководитель проекта _________ _________/_____________/ (должность) (подпись) (Ф.И.О.) Санкт-Петербург 2023 г. СОДЕРЖАНИЕ Введение ................................................................................................................... 3 Задание 1. Понижение размерности данных ........................................................ 5 1.1. Постановка задачи ................................................................................... 5 1.2. Теоретическая информация .................................................................... 6 1.3. Решение поставленной задачи ............................................................... 7 1.4. Анализ выполненного задания............................................................. 12 1.5. Листинг кода .......................................................................................... 16 Задание 2. Кластеризация данных. ...................................................................... 19 2.1. Постановка задачи ................................................................................. 19 2.2. Теоретическая информация .................................................................. 19 2.3. Решение поставленной задачи ............................................................. 21 2.4. Анализ выполненного задания............................................................. 24 2.5. Листинг кода .......................................................................................... 27 Задание 3. Обработка графической информации .............................................. 29 3.1. Постановка задачи ................................................................................. 29 3.2. Теоретическая информация .................................................................. 29 3.3. Решение поставленной задачи ............................................................. 30 3.4. Листинг кода .......................................................................................... 34 Заключение ............................................................................................................ 39 Список использованных источников .................................................................. 40 2 Введение Курсовая работа подразумевает выполнения трех различных по своей тематике заданий, связанных необходимостью обрабатывать данные для их анализа. Ниже будут кратко описаны цели заданий, а более подробная информация с исходными данными будет приведена в соответствующих разделах каждого задания в отдельности. Первое задание. Изучение эффективных методов понижения размерности данных на примере изображения в формате «.jpg». Второе задание. Исследование алгоритмов визуальной классификации данных на примере базы данных субъективных экспертных оценок. Третье задание. Визуализация текстовой информации при помощи технологии SVG. Целью выполнения курсовой работы является на практике использовать полученные теоретические и практические навыки на примере заданий с минимальной поясняющей информацией, требующей от студента более глубокого понимания задания и правильного выбора дальнейших действий. Выполнение каждого из заданий подразумевает подробный разбор действий и приведение полного отчета по анализу (задания 1 и 2). Так же при необходимости будут использованы математические формулы для обоснования моих действий, а также и минимальные научные справки о различиях методов обработки данных. Дополнительной целью при выполнении курсовой работы будет итоговое достижения требований по таким компетенциям, как: 1) ПК-1 – способность проводить исследования на всех этапах жизненного цикла программных средств; 3 2) ПК-18 – способность выполнять работы по созданию (модификации) и сопровождению ИС, автоматизирующих задачи организационного управления и бизнес-процессы; 3) ПК-19 – способность выполнять работы и управлять работами по созданию (модификации) и сопровождению ИС, автоматизирующих задачи организационного управления и бизнес-процессы. Для выполнения первого и второго задания я буду использовать язык программирования Python версии 3.11.6. Выбор версии обусловлен отсутствием на версии 3.12 необходимой библиотеки. Редактором кода был выбран Visual Studio Code, а ниже приведен список использованных мной библиотек: Первое задание: PIL (Python Imaging Library) для работы с изображениями. NumPy для работы с массивами и матрицами, а также для метода SVD. Scikit-learn для машинного обучения. MatPlotLib для визуализации данных. Второе задание: UMAP для нелинейного снижения размерности и визуализации данных. Pandas для обработки и анализа данных. MatPlotLib для визуализации данных. Scikit-learn для машинного обучения. Для выполнения третьего задания будут использована технология SVG, которая может быть выполнена в любом текстовом редакторе. Я же выбрал Sublime Text 3 для более комфортной работы. 4 Задание 1. Понижение размерности данных 1.1. Постановка задачи Задание: «Исследовать эффективность методов PCA и SVD для понижения размерности данных. В качестве исходных данных для анализа следует самостоятельно выбрать изображение в формате jpg. Размер изображения должен быть не менее 400 х 400 пикселей.» Для выполнения задания я выбрал живописную картинку размером 1920х1200 (см. рисунок 1) Рис. 1. Рисунок для понижения размерности. Главными элементами картинки можно обозначить следующее: дом, река, мост, лодка, костер и олень на камнях. Думаю, это можно назвать 5 главными частями информации, которую мы получаем при визуальном анализе картинки. 1.2. Теоретическая информация Для выполнения задания мы переведем данное изображение в чёрнобелый формат и будем использовать метод разложения по сингулярным значениям SVD (Singular Value Decomposition). Этот метод тесно связан с методом главных компонент PCA (Principal Component Analysis). Главные компоненты – линейные комбинации исходных признаков, представляющие собой направления максимальной дисперсии в данных и связаны с сингулярными значениями: главные компоненты соответствуют направлениям в пространстве признаков, определенным сингулярными векторами, а сингулярные значения векторов показывают важность соответствующих главных компонент. Сама суть методов – разложение главной матрицы на две (в случае PCA) или три (в случае SVD) матрицы. Основы двух методов в графическом виде представлены на рисунках 2 и 3. Рис. 2. Метод PCA. Разложение матрицы X на T и P. 6 Рис. 3. Метод SVD. Разложение матрицы X на U, S и V 1.3. Решение поставленной задачи Код выполнен на языке программирования Python и весь листинг кода будет представлен в конце решения. Для начала я определил необходимые библиотеки и установил их на свой ПК. Рис. 4. Библиотеки для первого задания. Далее я загрузил изображения, перевел его в чёрно-белый формат и вывел их на экран при помощи библиотеки «matplotlib». Строки, отвечающие за отображение, подписаны в первом случае, так как потом они будут одинаковыми и не будет необходимости перегружать экран информацией. 7 Рис. 5. Открытие, преобразование и вывод изображений. Рис. 6. Результат выполнения фрагмента кода. Конечно, на данный момент изображения выглядят мелко, но при анализе я обязательно приведу изображения в более широком формате. Теперь самое интересное. Для разложения методом SVD нам потребуется всего 2 строки. Так как SVD предполагает работу с матрицами (по сути, массивами), то благодаря библиотеке «numpy» мы преобразуем изображение в массив и из него будем выполнять разложение благодаря возможностям всё той же библиотеки, а конкретно модуля «linalg» Рис. 7. Получение матриц U, S, Vt из массива изображения (матрицы X). 8 Далее, я восстановлю изображение, но буду менять количество главных компонент, которые будут использованы при восстановлении. Таким образом мы получим изображения различной размерности и, следовательно, разного качества и разной наполненностью информацией. Рис. 8. Визуализация изображения с ограничениями в главных компонентах. Чтобы не занимать много места, я показал фрагмент кода и показал, что меняю количество компонент и как вывожу изображения. В конечном итоге, мы получаем такой результат при выполнении основной части кода (см. рисунок 9). Дополнительно же я решил найти то количество главных компонент, при котором количество объясненной дисперсии будет равно 95%. То есть, то количество компонент, при котором будет сохранено 95% информации относительно исходного изображения. Если вас не интересует блок с дисперсией, то после рисунка 9 и пояснения к нему можно сразу перейти в раздел «1.4. Анализ выполненного задания». 9 Рис. 9. Результат выполнения основной части кода. Можно сразу заметить, как меняются восстановленные изображения при различных значениях главных компонент. Сравнивать их я буду в следующем разделе, а пока что я продолжу разбор своего кода. Я сохранил изображения для более детального сравнения, которое будет сделано позже. Рис. 10. Сохранение восстановленных изображений. Далее, я решил узнать количество главных компонент, при котором будет объяснена 95% дисперсия. 10 Рис. 11. Расчет значения главных компонент для получения не менее 95% дисперсии. Рис. 12. Вывод в консоли. Рассчитав кумулятивное значение объясненной дисперсии, используя сингулярные значения матрицы S, для каждого значения главных компонент, мы определяем индекс, которому соответствует значение, при котором объясненная дисперсия будет не меньше 95%. Я решил вывести это в графике, для более объемного понимания. Рис. 13. Код для вывода графика объясненной дисперсии от количества главных компонент. 11 Рис. 14. График зависимости объясненной дисперсии от главных компонент. На графике видно, что даже для 99% дисперсии хватит менее 200 главных компонент (к слову, для 99% необходимо 81 главных компонент). Анализ графика я проведу в следующем разделе. 1.4. Анализ выполненного задания Первое, что я предлагаю посмотреть, это как же изменился размер изображений. Для этого, в том числе, я и сохранил изображения. По названию файлов должно быть понятно его содержимое. К примеру, changed_20.jpg означает, что это восстановленное изображение с 20 главными компонентами. 12 Рис. 15. Просмотр размера изображений. Как мы видим, исходное цветное изображение весило 554 КБ. Только переводом в черно-белый формат мы сбросили 60 КБ и получили 494 КБ. Дальше, мы видим, как достаточно сильно меняется размер при различных значениях главных компонент. А теперь сравним кое какие изображения, но возьмем мы только три: 50, 20 и 5 компонент. Даже на рисунке 9 было видно, что 250 компонент очень хорошо читаются. Рис. 16. Увеличенное изображение при 50 главных компонентах. 13 Рис. 17. Увеличенное изображение при 20 главных компонентах. В глаза сразу бросается «призрачные» элементы моста и веранды дома при 20 компонентах. При 50 компонентах мы видим все ранее обозначенные мной компоненты для получения информации с картинки. Даже олень, которого при 20 компонентах почти невозможно разобрать, сохранился достаточно хорошо. Соответственно, для визуального анализа идеально подходят 50 главных компонент, так как видны все элементы картинки и при этом мы имеем 256 КБ веса от 494 (554 у цветного) КБ. Теперь сравним размерность исходного и измененного изображений. Оригинал = 1920 * 1200 = 2.304.000 пикселей U = 1920 * 50 = 96.000 S = 50 * 50 = 2.500 V = 50 * 1200 = 60.000 Измененное при 50 компонентах = U + S + V = 158.500 пикселей 14 2.304.000 / 158.500 = 14,5 Мы получили в 14,5 раз меньше пикселей и снизили вес файла в 1,9 раз относительно черно-белого исходного файла. При этом сохранили достаточно информации, по подсчетам это где-то около 95 и 99% дисперсии. Что касаемо дисперсии, то для сохранения 95% информации нам, согласно расчетам, хватит и 5 главных компонент. Рис. 18. Увеличенное изображение при 5 главных компонентах. Как мы видим, мы ничего не видим. Но ведь согласно расчетам, мы сохранили 95% информации. Как же так? Я предполагаю, что машина в данном случае основывалась не на объектах картинки (дом, мост, олень и т.д.), а на цветах, вернее, количестве белого и черного. Если присмотреться, то мы можем увидеть очертания моста, достаточно точно можем определить очертания реки и что-то отдаленно напоминающее дом. Если сравнить эту картинку с 20 главными компонентами, то можно отдаленно заметить, что дом и лес обладают более темными цветами, которые при желании можно 15 объединить. К сведению, светлая трава у дома уже более выделена и контрастирует с домом. Поэтому, чисто теоретически, машина посчитала, что сохранила достаточно информации, просто человеческому взгляду очень сложно это воспринимать. Таким образом, мы выполнили задание и понизили размерность изображения, так же узнали какое значение главных компонент достаточно для сохранения 95% процентов информации и провели анализ изображений на примере видимых сохраненных объектов при визуальном анализе и преимуществе понижения размерности на примере размеров файлов и количестве пикселей, необходимых для обработки. 1.5. Листинг кода Python 3.12 64-bit: from PIL import Image from numpy.linalg import svd from sklearn.decomposition import PCA import matplotlib.pyplot as plt import numpy as np # Открываем и преобразуем оригинальное изображение в черно-белое image = Image.open('D:/Kurs/Zadanie_1/house.jpg') gray_image = image.convert('L') # черно-белое отображение gray_image.save('D:/Kurs/Zadanie_1/gray_image.jpg') # сохранение черно-белого изображения # Создаем два подграфика для отображения оригинальных изображений plt.subplot(3, 2, 1) # создаем график с 3 строками и 2 столбцами и вносим следующий график в первую ячейку plt.title(f"Original") # название "графика" plt.imshow(image, cmap = 'gray') # выбор изображения для вывода "image" plt.axis('off') # отключение отображения осей plt.subplot(3, 2, 2) plt.title(f"Black-White") # plt.imshow(gray_image, cmap = 'gray') plt.axis('off') # Преобразуем изображение в массив NymPy gray_image_array = np.array(gray_image) # Формуируем матрицы SVD для разложения 16 U, S, Vt = np.linalg.svd(gray_image_array, full_matrices = True) # Формируем и показываем изображения при различных значениях главных компонент k k = 5 # формирование изображения с ограничением размерности для каждой матрицы changed_image_5 = np.dot(U[:, :k], np.dot(np.diag(S[:k]), Vt[:k, :])) # вывод изображения с 5 главными компонентами plt.subplot(3, 2, 3) plt.title(f"k = 5") plt.imshow(changed_image_5, cmap = 'gray') plt.axis('off') k = 20 changed_image_20 = np.dot(U[:, :k], np.dot(np.diag(S[:k]), Vt[:k, :])) plt.subplot(3, 2, 4) plt.title(f"k = 20") plt.imshow(changed_image_20, cmap = 'gray') plt.axis('off') k = 50 changed_image_50 = np.dot(U[:, :k], np.dot(np.diag(S[:k]), Vt[:k, :])) plt.subplot(3, 2, 5) plt.title(f"k = 50") plt.imshow(changed_image_50, cmap = 'gray') plt.axis('off') k = 250 changed_image_250 = np.dot(U[:, :k], np.dot(np.diag(S[:k]), Vt[:k, :])) plt.subplot(3, 2, 6) plt.title(f"k = 250") plt.imshow(changed_image_250, cmap = 'gray') plt.axis('off') plt.show() # Преобразуем массивы в целочисленные 8-битные числа и сохраняем полученные изображения в формате .jpg для сравнения размера changed_image_5_jpg = Image.fromarray(changed_image_5.astype('uint8')) changed_image_5_jpg.save('D:/Kurs/Zadanie_1/changed_5.jpg') changed_image_20_jpg = Image.fromarray(changed_image_20.astype('uint8')) changed_image_20_jpg.save('D:/Kurs/Zadanie_1/changed_20.jpg') changed_image_50_jpg = Image.fromarray(changed_image_50.astype('uint8')) changed_image_50_jpg.save('D:/Kurs/Zadanie_1/changed_50.jpg') changed_image_250_jpg = Image.fromarray(changed_image_250.astype('uint8')) changed_image_250_jpg.save('D:/Kurs/Zadanie_1/changed_250.jpg') 17 # Дополнительно: находим минимальное количество главных компонент для 95% дисперсии desired_ratio = 0.99 # искомая дисперсия cumulative_explained_variance = np.cumsum(S**2)/np.sum(S**2) # кумулятивное значение дисперсии для компонент k_threshold = np.argmax(cumulative_explained_variance >= desired_ratio) # значение главных компонент для дисперсии 95% и больше print(f"Количество компонент для объяснения {desired_ratio * 100}% дисперсии: {k_threshold}") # Визуализация графика зависимости объясненной дисперсии к количеству компонент plt.plot(cumulative_explained_variance, marker='o') plt.axvline(x=k_threshold, color='r', linestyle='--', label=f'k={k_threshold}') plt.xlabel('Количество компонент') plt.ylabel('Объясненная дисперсия') plt.legend() plt.show() 18 Задание 2. Кластеризация данных. 2.1. Постановка задачи Задание: «Исследовать возможности классификации данных с использованием алгоритмов t-SNE и UMAP… Анализируемые данные включают 11 объективных параметров различных сортов вина… Последний, 12-ый параметр является субъективной оценкой качества, проставляемой экспертом, и имеет несколько градаций. Основная задача исследования состоит в определении качества субъективной оценки экспертов и формированию обоснованной кластеризации вин.» Во втором задании нам необходимо исследовать базу данных по химическому составу вин и дать оценку качеству субъективной оценки эксперта. Для классификации данных мы будем использовать методы t-SNE и UMAP. Для начала, скачаем необходимую базу данных. Согласно условию, её выбор – номер моей зачетной книжки заканчивается на 1, поэтому я скачаю базу данных белых вин. В результате мы получим файл «winequalitywhite.csv». Если открыть такой файл, то мы увидим нагромождение данных в строках, так как формат .csv разделяет данные запятыми или точками с запятой. Далее, именно с ним мы и будем работать. 2.2. Теоретическая информация Для выполнения задания мы будем использовать методы t-SNE и UMAP из библиотек scikit-learn и UMAP-learn соответственно. Так как UMAP-learn отсутствует в Python 3.12, то мы будем использовать Python 3.11.6. 19 Оба используемых метода используются для визуализации данных высокой размерности, но дают они разные результаты из-за различных алгоритмов и их параметров. Отличия разберем по отдельности. UMAP (Uniform Manifold Approximation and Projection) – преобразует данные высокой размерности в более низкую, сохраняя при этом глобальные и локальные структуры данных. Он базируется на математическом приближении гладкого многообразия данных. Главное отличие от t-SNE – способность сохранять глобальные структуры лучше и более быстрое вычисление. Преимущества: эффективен для визуализации как локальных, так и глобальных структур данных. Недостатки: требует больше вычислительных ресурсов при работе с очень большими данными. t-SNE (t-Distributed Stochastic Neighbor Embedding) – преобразует многомерные данные в двумерное или трехмерное пространство таким образом, чтобы схожие объекты в исходном пространстве оказывались близкими, а различные – далекими. Минимизирует сумму условных вероятностей отнесения пар точек в исходном и новом пространстве. Преимущества: эффективен для визуализации данных высокой размерности, хорошо передает локальные структуры. Недостатки: чувствителен к параметрам, не сохраняет глобальные расстояния и результаты могут зависеть от случайной инициализации. Чаще всего рекомендуется использовать UMAP, но всё же они оба используются при необходимости. Сейчас мы и исследуем какой из методов лучше подойдет для визуализации наших данных. Да, данные методы не 20 подходят для прямой классификации и кластеризации. Но они очень полезны для обработки данных для последующих модификаций. 2.3. Решение поставленной задачи Для начала откроем и просмотрим нашу таблицу. Делать всё это я буду в редакторе кода Visual Studio Code. Рис. 19. Фрагмент таблицы winequality-white.csv Как и говорилось, в оригинале файлы формата .csv очень сложно читать человеку. Для более понятного отображения откроем её в другом формате. Рис. 20. Фрагмент таблицы winequality-white.csv Вот с этой таблицей мы и будем работать. К слову, в дальнейшем она понадобится нам для ручного анализа, но никаких проблем это не вызовет. 21 Подключаем необходимые библиотеки и загружаем таблицу. Рис. 21. Фрагмент кода с загрузкой базы данных Как можно заметить, я указал разделитель в функции «;», так как csvфайлы допускают использование и запятых, и точек с запятой. Так как база данных содержит 4,898 строк, то мы «обрежем» её, чтобы не нагружать ПК. Считаю допустимым взять 1,000 случайных строк. Рис. 22. Фрагмент кода с обработкой базы данных В 9 строке я выбрал случайные 1,000 строк и поставил рандомизатор на определенное значение «42», чтобы при последующем исполнении программы получались одни и те же значения. В 11 строке я начал процесс визуализации. Переменная «features» содержит в себе базу данных из 1,000 строк, но из неё убран столбец «quality». Это нужно для того, чтобы машина попыталась сама научиться искать взаимосвязь 11 параметров, присваивая их каждому объекту (строке). Таким образом, мы увидим закономерности на плоскости и сможем провести анализ. 22 Рис. 23. Фрагмент кода с созданием объектов на основе моделей UMAP и t-SNE. На рисунке 23 вы можете наблюдать, как я создал два объекта, которые и будут содержать в себе результат выполнения методов t-SNE и UMAP. Условия для них почти одинаковые, только в UMAP я указал дополнительно «min_dist», чтобы регулировать масштаб для более читаемого формата. Параметр n_components нужен для определения количества компонентов, а random_state для фиксации рандомизации. Рис. 24. Фрагмент кода с отображением результатов В первом задании я уже использовал похожий формат вывода данных благодаря библиотеке «matplotlib». Так же я решил вывести результат работы метода t-SNE при различных значениям перплексии. 23 Рис. 25. Фрагмент кода с созданием и выводов объектов метода t-SNE с различными значениями перплексии. Она будет изменять однородность полученных данных и при разных значениях повышать/понижать локальные/глобальные детали. Теперь посмотрим на вывод, полученный в результате выполнения первого крупного блока программы до цикла. Рис. 26. Результат вывода двух методов 2.4. Анализ выполненного задания Начнем анализировать. Сразу заметно, помимо главного, отсутствие легенды. Она здесь попросту не нужна. Каждый цвет точки означает 24 отдельную оценку эксперта. Здесь нет кластеризации привычной нам на примерах. Все точки попросту смешаны между собой. Если возникает вопрос по поводу осей Х и У на двух графиках, то это относительные размеры, полученные в результате выполнения двух методов. Они различные, так как и алгоритмы вычислений разные, но саму суть относительности они выполняют. Для исследования эти оси можно даже опустить, указав, что масштаб метода t-SNE куда больше, что связано с его алгоритмом отображения схожих рядом, а разных – поодаль. Как мы видим, точки сильно смешаны, хотя, конечно, можно выделить области, где их больше, но такие зоны будут очень незначительными и в них всё равно будут исключения. Мы не видим явно отличительных вин, которые получили какую-то оценку и при этом их химический состав явно отличен от других вин. Давайте проведем ручной анализ какого-нибудь фрагмента из оригинальной таблицы. Рис. 27. Фрагмент таблицы Сравним этот фрагмент таблицу между строк. Здесь представлены вина, которым были поставлены оценки от 4 до 8 включительно. Мы не можем явно сказать, что какой-то параметр имеет явное отличие от других вин, при котором есть зависимость с оценкой. Точно так же отсутствует и логика, по которой одно вино получило большую или меньшую оценку. Как вывод, можно отметить, что субъективная оценка вина экспертом никак не зависит от объективных значений химического состава белого вина. Теперь посмотрим на график при различных значениях перплексии. 25 Рис. 28. Результат вывода метода t-SNE при различном значении перплексии. Большое значение перплексии – равномерно распределенная глобальная структура, но в итоге мы теряем локальные детали и наоборот. Мы видим, что меняются и значения на осях Х и У, так как меняется относительное расстояние между объектами (точками). При перплексии 5 мы можем наблюдать змейки из точек, которые содержат в себе приблизительно похожие объекты. Заметно, что в таких змейках собраны различные цвета, так что это дополнительно доказывает отсутствие явных отличий. При повышении перплексии змейки расплываются, превращаясь в облако при перплексии в 50. Мы видим как точки глобально зависят друг от друга, но вот локально змеек больше не наблюдаем. К слову, при значении 50 видно, если притянуть за уши, что фиолетовые точки больше собираются слева, а зеленые справа, но и они, и другие точки смешаны с этими зонами и со всей площадью графика. 26 2.5. 3. 4. 5. 6. 7. 8. 9. Листинг кода import umap import pandas as pd import matplotlib.pyplot as plt from sklearn.manifold import TSNE # открываем базу данных original_df = pd.read_csv('D:/Kurs/Zadanie_2/winequality-white.csv', delimiter = ';') 10. # берем 1000 случайных строк и подготавливаем их для машинного обучения 11. original_df = original_df.sample(n = 1000, random_state = 42) 12. # исключаем столбец с оценкой эксперта, оставляя только признаки 13. features = original_df.drop('quality', axis = 1) 14. 15. # создаем объект tsne, где n_components - количество компонентов для визуализации 16. # в нашем случае 2 (двумерное пространство) 17. tsne = TSNE(n_components = 2, random_state = 42) 18. # обучение модели t-SNE и трансформация в двумерное пространство 19. tsne_result = tsne.fit_transform(features) 20. # повторение для модели UMAP, но я установил минимальную дистанцию в 0.1, для более понятного представления 21. umap_model = umap.UMAP(n_components = 2, min_dist = 0.1 ,random_state = 42) 22. umap_result = umap_model.fit_transform(features) 23. 24. # создаем две ячейки для визуализации и подаем в них результаты обучения методами UMAP и t-SNE 25. x1 = plt.subplot(1, 2, 1) # выбор ячейки 26. x1.set_title('UMAP') # название графика 27. # вывод графика с настройками 28. # первые два значения отвечают за оси Х и У 29. # c = original_df['quality'] - цвет соответствующий значению в столбце quality 30. # s = 5 - размер маркеров (точек) 31. # cmap = 'hsv' - цветовая карта 32. x1.scatter(umap_result[:, 0], umap_result[:, 1], c = original_df['quality'], s = 5, cmap = 'hsv') 33. x1.set_facecolor('#EAEAF2') # выбор цвета фона для графика 34. 35. x2 = plt.subplot(1, 2, 2) 36. x2.set_title(f"t-SNE") 37. x2.scatter(tsne_result[:, 0], tsne_result[:, 1], c = original_df['quality'], s = 5, cmap = 'hsv') 38. x2.set_facecolor('#EAEAF2') 39. plt.show() 40. 41. # создаем цикл для расчета и вывода графиков методом t-SNE с различными значениями перплексии 42. for i, el in enumerate([5, 7, 10, 15, 20, 50]): 27 43. 44. 45. 46. 47. 48. tsne = TSNE(n_components = 2, random_state = 42, perplexity = el) tsne_result = tsne.fit_transform(features) x3 = plt.subplot(2, 3, i+1) x3.set_title(f"Perplexity = {el}") x3.scatter(tsne_result[:, 0], tsne_result[:, 1], c = original_df['quality'], s = 5, cmap = 'hsv') 49. x3.set_facecolor('#EAEAF2') 50. 51. plt.show() 28 Задание 3. Обработка графической информации 3.1. Постановка задачи Задание: «Визуализировать отрывок сказки К.И.Чуковского «Муха-цокотуха» с использованием технологии SVG, соответствующий номеру фрагмента. Номер своего фрагмента определяется последней цифрой номера зачетной книжки.» Тараканы прибегали, Все стаканы выпивали, А букашки – По три чашки С молоком И крендельком: Нынче Муха-Цокотуха Именинница! Данный текст надо визуализировать в браузере с использованием технологии SVG, которая позволит нам анимировать изображения и полностью представить текст из стишка для восприятия. Таким образом, мы преобразуем текст в графическую и звуковую информацию, чтобы улучшить её восприятие. Мы сможем увидеть прочитанное, и услышать. Во всем этом, кроме звука, нам поможет технология SVG. 3.2. Теоретическая информация Технология SVG (Scalable Vector Graphics) позволяет нам объединить текст, графику, анимации и объекты. Интегрировав его с html мы сможем получить приятную глазу анимацию с озвучкой. 29 Использовать я буду текстовый редактор Sublime Text 3 и браузер Firefox, так как в браузерах Google Chrome и Microsoft Edge не проигрывается звук, но при этом анимация выполняется стандартно. 3.3. Решение поставленной задачи В графическом редакторе SVG – Adobe Illustrator, я создам примерную картину, которую получу в конце. Рис. 29. Примерный конечный результат. Здесь букашки пьют из чашки, как и таракашки. Каждый объект представлен отдельно, что позволит нам анимировать их лучше и приятнее. <?xml version="1.0" encoding="UTF-8"?> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 1378.31 768"> <defs> <style> .cls-1 { fill: none; stroke-width: 0px; 30 } .cls-2 { clip-path: url(#clippath); } </style> <clipPath id="clippath"> <rect class="cls-1" x="0" width="1366" height="768"/> </clipPath> <image id="image" width="600" height="600" xlink:href="cup.png"/> <image id="image-1" width="512" height="512" xlink:href="таракан.png"> <animateTransform attributeName="transform" attributeType="XML" type="translate" values="-1000.22 -300.2; -800.22 -200.2; -500.22 -100.07; -10 -10; 33.22 0" keyTimes="0; 0.2; 0.4; 0.6; 1" dur="4s" repeatCount="1"/> </image> <image id="image-2" width="512" height="512" xlink:href="таракан.png"> <animateTransform attributeName="transform" attributeType="XML" type="translate" values="0.22 900.2; 10.22 750.2; 20.22 550.2; 30.22 250.2; 33.22 0" keyTimes="0; 0.2; 0.4; 0.6; 1" dur="4s" 31 repeatCount="1"/> </image> <image id="image-3" width="600" height="600" xlink:href="крендель.png"/> <image id="image-4" width="600" height="600" xlink:href="beatle.png"/> </defs> <g id="_Домик" data-name="Домик"> <g class="cls-2"> <image width="1150" height="864" transform="scale(1.19 .89)" xlink:href="home.jpg"/> </g> </g> <g id="_интерьер" data-name="интерьер"> <image width="866" height="900" transform="translate(1355.5 159) rotate(-180) scale(.43 -.4)" xlink:href="муха.png"> <animate attributeName="y" values="0; -150; 0" dur="1s" begin="9s" repeatCount="4"/> </image> <use transform="translate(237.76 320) rotate(2.26) scale(.22 .2) skewX(-.4)" xlink:href="#image"/> <use transform="translate(243.43 320) rotate(172.68) scale(.22 -.2) skewX(-.4)" xlink:href="#image"/> <g class="bug"> <use transform="translate(775.63 816) rotate(36.49) scale(.24)" xlink:href="#image4"/> <use transform="translate(719 824.77) rotate(-18.39) scale(.15)" xlink:href="#image3"/> </g> 32 <g class="bug"> <use transform="translate(1179 844.74) rotate(-33.15) scale(.24)" xlink:href="#image4"/> <use transform="translate(1265.65 740) rotate(18.31) scale(.15)" xlink:href="#image3"/> </g> <use transform="translate(1272.02 497.71) rotate(-158.61) scale(.22 -.2) skewX(-.4)" xlink:href="#image" style="opacity: 0"> <animate attributeName="opacity" values="0;1" keyTimes="0;1" dur="1s" begin="8s" fill="freeze"/> </use> <use transform="translate(815.92 546.76) rotate(-21.67) scale(.22 .2) skewX(-.4)" xlink:href="#image" style="opacity: 0"> <animate attributeName="opacity" values="0;1" keyTimes="0;1" dur="1s" begin="8s" fill="freeze"/> </use> <use transform="translate(822 566.92) rotate(-12.95) scale(.22 .2) skewX(-.4)" xlink:href="#image" style="opacity: 0"> <animate attributeName="opacity" values="0;1" keyTimes="0;1" dur="1s" begin="7s" fill="freeze"/> </use> <use transform="translate(831 585.05) rotate(-2.6) scale(.22 .2) skewX(-.4)" xlink:href="#image" style="opacity: 0"> <animate attributeName="opacity" values="0;1" keyTimes="0;1" dur="1s" begin="6s" fill="freeze"/> </use> <use transform="translate(1257.6 520.92) rotate(-167.05) scale(.22 -.2) skewX(-.4)" xlink:href="#image" style="opacity: 0"> <animate attributeName="opacity" values="0;1" keyTimes="0;1" dur="1s" begin="7s" fill="freeze"/> </use> <use transform="translate(1247.98 544.05) rotate(-177.4) scale(.22 -.2) skewX(-.4)" xlink:href="#image" style="opacity: 0"> <animate attributeName="opacity" values="0;1" keyTimes="0;1" dur="1s" begin="6s" fill="freeze"/> 33 </use> <use transform="translate(33.22 468.2) rotate(-89.8) scale(.31 .33)" xlink:href="#image-1"/> <use transform="translate(480.4 435.07) rotate(167.59) scale(.31 .33)" xlink:href="#image-2"/> </svg> Это код, связанный конкретно с SVG, весь код будет представлен в соответствующем разделе. В результате мы получаем такой результат. Рис. 30. Эпизод из анимации. Получилось очень плавно и лаконично, всё сходится с аудиодорожкой. 3.4. Листинг кода <html> <style> .bug { 34 animation: moveUp 3s ease forwards; animation-delay: 5s; } @keyframes moveUp { from { transform: translateY(0); } to { transform: translateY(-300px); } } </style> <?xml version="1.0" encoding="UTF-8"?> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1378.31 768"> xmlns:xlink="http://www.w3.org/1999/xlink" <defs> <style> .cls-1 { fill: none; stroke-width: 0px; } .cls-2 { clip-path: url(#clippath); } </style> <clipPath id="clippath"> <rect class="cls-1" x="0" width="1366" height="768"/> 35 </clipPath> <image id="image" width="600" height="600" xlink:href="cup.png"/> <image id="image-1" width="512" height="512" xlink:href="таракан.png"> <animateTransform attributeName="transform" attributeType="XML" type="translate" values="-1000.22 -300.2; -800.22 -200.2; -500.22 -100.07; -10 -10; 33.22 0" keyTimes="0; 0.2; 0.4; 0.6; 1" dur="4s" repeatCount="1"/> </image> <image id="image-2" width="512" height="512" xlink:href="таракан.png"> <animateTransform attributeName="transform" attributeType="XML" type="translate" values="0.22 900.2; 10.22 750.2; 20.22 550.2; 30.22 250.2; 33.22 0" keyTimes="0; 0.2; 0.4; 0.6; 1" dur="4s" repeatCount="1"/> </image> <image id="image-3" width="600" height="600" xlink:href="крендель.png"/> <image id="image-4" width="600" height="600" xlink:href="beatle.png"/> </defs> <g id="_Домик" data-name="Домик"> <g class="cls-2"> 36 <image width="1150" height="864" transform="scale(1.19 .89)" xlink:href="home.jpg"/> </g> </g> <g id="_интерьер" data-name="интерьер"> <image width="866" height="900" transform="translate(1355.5 159) rotate(-180) scale(.43 .4)" xlink:href="муха.png"> <animate attributeName="y" values="0; -150; 0" dur="1s" begin="9s" repeatCount="4"/> </image> <use transform="translate(237.76 xlink:href="#image"/> 320) rotate(2.26) scale(.22 .2) skewX(-.4)" <use transform="translate(243.43 xlink:href="#image"/> 320) rotate(172.68) scale(.22 -.2) skewX(-.4)" <g class="bug"> <use transform="translate(775.63 816) rotate(36.49) scale(.24)" xlink:href="#image-4"/> <use transform="translate(719 824.77) rotate(-18.39) scale(.15)" xlink:href="#image-3"/> </g> <g class="bug"> <use transform="translate(1179 844.74) rotate(-33.15) scale(.24)" xlink:href="#image-4"/> <use transform="translate(1265.65 740) rotate(18.31) scale(.15)" xlink:href="#image-3"/> </g> <use transform="translate(1272.02 497.71) rotate(-158.61) scale(.22 -.2) skewX(-.4)" xlink:href="#image" style="opacity: 0"> <animate attributeName="opacity" values="0;1" keyTimes="0;1" dur="1s" begin="8s" fill="freeze"/> </use> 37 <use transform="translate(815.92 546.76) xlink:href="#image" style="opacity: 0"> rotate(-21.67) scale(.22 .2) skewX(-.4)" <animate attributeName="opacity" values="0;1" keyTimes="0;1" dur="1s" begin="8s" fill="freeze"/> </use> <use transform="translate(822 566.92) xlink:href="#image" style="opacity: 0"> rotate(-12.95) scale(.22 .2) skewX(-.4)" <animate attributeName="opacity" values="0;1" keyTimes="0;1" dur="1s" begin="7s" fill="freeze"/> </use> <use transform="translate(831 585.05) xlink:href="#image" style="opacity: 0"> rotate(-2.6) scale(.22 .2) skewX(-.4)" <animate attributeName="opacity" values="0;1" keyTimes="0;1" dur="1s" begin="6s" fill="freeze"/> </use> <use transform="translate(1257.6 520.92) rotate(-167.05) scale(.22 -.2) skewX(-.4)" xlink:href="#image" style="opacity: 0"> <animate attributeName="opacity" values="0;1" keyTimes="0;1" dur="1s" begin="7s" fill="freeze"/> </use> <use transform="translate(1247.98 544.05) rotate(-177.4) scale(.22 -.2) skewX(-.4)" xlink:href="#image" style="opacity: 0"> <animate attributeName="opacity" values="0;1" keyTimes="0;1" dur="1s" begin="6s" fill="freeze"/> </use> <use transform="translate(33.22 468.2) rotate(-89.8) scale(.31 .33)" xlink:href="#image-1"/> <use transform="translate(480.4 435.07) rotate(167.59) scale(.31 .33)" xlink:href="#image2"/> </svg> <audio id="Sound" src="audio_fixed.mp3" autoplay="autoplay"></audio> </html> 38 Заключение В результате выполнения курсовой работы, я закрепил навыки программирования на языке программирования Python, а также использовал теоретические знания для выполнения задач по визуализации данных. В том числе и визуализация текста при помощи технологии SVG. Применив уже имеющиеся навыки с теоретической основой, я понял, как работают различные методы для обработки данных на разных этапах. Так, я узнал, что методы t-SNE и UMAP не используются для кластеризации или классификации, правильнее сказать, что они помогают визуализировать данные для их дальнейшей классификации и кластеризации. 39 Список использованных источников 1. Метод главных компонент: https://rcs.chemometrics.ru/old/Tutorials/pca.htm 2. Как работает метод главных компонент (примеры на Python) https://habr.com/ru/post/304214/ 3. Метод главных компонент: введение (примеры на R) https://rpubs.com/AllaT/pca-intro 4. Как уменьшить количество измерений и извлечь из этого пользу (SVD примеры на R) https://habr.com/ru/post/275273/ 5. Препарируем t-SNE https://habr.com/ru/post/267041/ 6. Comprehensive Guide on t-SNE algorithm with implementation in R & Python: https://www.analyticsvidhya.com/blog/2017/01/t-sne- implementation-r-python/ 7. Обзор нового алгоритма уменьшения размерности UMAP: https://habr.com/ru/company/newprolab/blog/350584/ 8. Uniform Manifold Approximation and Projection in R: https://cran.r-project.org/web/packages/umap/vignettes/umap.html 9. Machine Learning Repository [Электронный http://archive.ics.uci.edu/ml/index.php 40 ресурс]. ‒ URL: