{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Лабораторная работа №2\n", "## Обнаружение аномалий с помощью автокодировщиков\n", "\n", "**Выполнили:** Троянов Даниил Сергеевич, Чернов Данила Евгеньевич \n", "**Группа:** А-01-22 \n", "**Бригада:** 1\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Задание 1\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 1) Импорт необходимых библиотек и модулей\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import os\n", "import numpy as np\n", "import matplotlib.pyplot as plt\n", "import lab02_lib as lib\n", "from unittest.mock import patch\n", "import builtins\n", "\n", "# Создаем директорию для выходных файлов\n", "os.makedirs('out', exist_ok=True)\n", "\n", "print('Библиотеки успешно импортированы')\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 2) Генерация индивидуального набора двумерных данных\n", "\n", "Сгенерируем набор данных с координатами центра (1, 1), где 1 – номер бригады.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Генерация датасета для бригады 1\n", "brigade_num = 1\n", "data = lib.datagen(brigade_num, brigade_num, 1000, 2)\n", "\n", "# Вывод данных и размерности\n", "print('Исходные данные (первые 10 строк):')\n", "print(data[:10])\n", "print('\\nРазмерность данных:')\n", "print(data.shape)\n", "print(f'\\nЦентр кластера: ({brigade_num}, {brigade_num})')\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 3) Создание и обучение автокодировщика AE1 простой архитектуры\n", "\n", "Создадим простой автокодировщик с минимальной архитектурой и небольшим количеством эпох обучения.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Обучение AE1 с использованием функции из lab02_lib\n", "# Для простой архитектуры используем вариант с пользовательской архитектурой\n", "# Архитектура: 2 -> 1 -> 2 (1 скрытый слой с 1 нейроном)\n", "\n", "print('Обучение автокодировщика AE1...')\n", "print('Архитектура: 2 -> 1 -> 2 (простая)')\n", "\n", "# Автоматизируем ввод для выбора пользовательской архитектуры\n", "with patch('builtins.input', side_effect=['1', '1', '1']):\n", " ae1_trained, IRE1, IREth1 = lib.create_fit_save_ae(\n", " data, \n", " 'out/AE1.h5', \n", " 'out/AE1_ire_th.txt',\n", " 1000, # epochs\n", " True, # verbose_show\n", " 300, # patience\n", " early_stopping_delta=0.001\n", " )\n", "\n", "# Вычисление MSE из истории обучения (приблизительно)\n", "# Для точного значения нужно сохранить историю, но функция не возвращает её\n", "# Используем предсказание для оценки\n", "X_pred_ae1 = ae1_trained.predict(data, verbose=0)\n", "mse_ae1 = np.mean((data - X_pred_ae1) ** 2)\n", "\n", "print(f'\\nОбучение завершено!')\n", "print(f'MSE_stop (приблизительно): {mse_ae1:.6f}')\n", "print(f'Порог IRE: {IREth1:.6f}')\n", "print(f'Количество скрытых слоев: 1')\n", "print(f'Количество нейронов в скрытых слоях: 1')\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 4) Построение графика ошибки реконструкции для AE1\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Построение графика ошибки реконструкции\n", "lib.ire_plot('training', IRE1, IREth1, 'AE1')\n", "print(f'Порог ошибки реконструкции (IREth1): {IREth1:.6f}')\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 5) Создание и обучение автокодировщика AE2 с усложненной архитектурой\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Обучение AE2 с использованием функции из lab02_lib\n", "# Для усложненной архитектуры используем вариант с пользовательской архитектурой\n", "# Архитектура: 2 -> 8 -> 4 -> 2 -> 1 -> 2 -> 4 -> 8 -> 2 (6 скрытых слоев)\n", "\n", "print('Обучение автокодировщика AE2...')\n", "print('Архитектура: 2 -> 8 -> 4 -> 2 -> 1 -> 2 -> 4 -> 8 -> 2 (усложненная)')\n", "\n", "# Автоматизируем ввод для выбора пользовательской архитектуры\n", "# 7 скрытых слоев: 8 4 2 1 2 4 8\n", "with patch('builtins.input', side_effect=['1', '7', '8 4 2 1 2 4 8']):\n", " ae2_trained, IRE2, IREth2 = lib.create_fit_save_ae(\n", " data, \n", " 'out/AE2.h5', \n", " 'out/AE2_ire_th.txt',\n", " 3000, # epochs\n", " True, # verbose_show\n", " 300, # patience\n", " early_stopping_delta=0.001\n", " )\n", "\n", "# Вычисление MSE из предсказания\n", "X_pred_ae2 = ae2_trained.predict(data, verbose=0)\n", "mse_ae2 = np.mean((data - X_pred_ae2) ** 2)\n", "\n", "print(f'\\nОбучение завершено!')\n", "print(f'MSE_stop (приблизительно): {mse_ae2:.6f}')\n", "print(f'Порог IRE: {IREth2:.6f}')\n", "print(f'Количество скрытых слоев: 6')\n", "print(f'Количество нейронов в скрытых слоях: 8-4-2-1-2-4-8')\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 6) Построение графика ошибки реконструкции для AE2\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Построение графика ошибки реконструкции\n", "lib.ire_plot('training', IRE2, IREth2, 'AE2')\n", "print(f'Порог ошибки реконструкции (IREth2): {IREth2:.6f}')\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 7) Расчет характеристик качества обучения EDCA для AE1 и AE2\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Расчет EDCA для AE1\n", "numb_square = 20\n", "xx, yy, Z1 = lib.square_calc(numb_square, data, ae1_trained, IREth1, '1', True)\n", "\n", "# Сохраняем результаты EDCA для AE1 сразу после расчета\n", "excess_ae1 = None\n", "approx_ae1 = None\n", "try:\n", " with open('out/result.txt', 'r') as f:\n", " content = f.read()\n", " if 'AE1' in content:\n", " lines = content.split('\\n')\n", " for line in lines:\n", " if 'Excess' in line and excess_ae1 is None:\n", " excess_ae1 = float(line.split('=')[1].strip())\n", " elif 'Approx' in line and approx_ae1 is None:\n", " approx_ae1 = float(line.split('=')[1].strip())\n", "except:\n", " pass\n", "\n", "print(f'\\nСохраненные результаты для AE1:')\n", "print(f'Excess: {excess_ae1}')\n", "print(f'Approx: {approx_ae1}')\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Расчет EDCA для AE2\n", "xx, yy, Z2 = lib.square_calc(numb_square, data, ae2_trained, IREth2, '2', True)\n", "\n", "# Сохраняем результаты EDCA для AE2 сразу после расчета\n", "excess_ae2 = None\n", "approx_ae2 = None\n", "try:\n", " with open('out/result.txt', 'r') as f:\n", " content = f.read()\n", " if 'AE2' in content:\n", " lines = content.split('\\n')\n", " for line in lines:\n", " if 'Excess' in line and excess_ae2 is None:\n", " excess_ae2 = float(line.split('=')[1].strip())\n", " elif 'Approx' in line and approx_ae2 is None:\n", " approx_ae2 = float(line.split('=')[1].strip())\n", "except:\n", " pass\n", "\n", "print(f'\\nСохраненные результаты для AE2:')\n", "print(f'Excess: {excess_ae2}')\n", "print(f'Approx: {approx_ae2}')\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Сравнение характеристик качества обучения и областей аппроксимации\n", "lib.plot2in1(data, xx, yy, Z1, Z2)\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 8) Создание тестовой выборки\n", "\n", "Создадим тестовую выборку из элементов, которые AE1 распознает как норму, а AE2 детектирует как аномалии.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Создание тестовой выборки\n", "# Точки, которые находятся на среднем расстоянии от центра (1, 1)\n", "# чтобы AE1 их не распознал как аномалии (IRE < порог AE1 ~2.06),\n", "# но AE2 распознал как аномалии (IRE > порог AE2 ~0.41)\n", "# Выбираем точки на расстоянии примерно 1-1.5 от центра\n", "data_test = np.array([\n", " [-0.5, 0.5], \n", " [1, 0.5], \n", " [0.2, 1.2], \n", " [0, 0.1] \n", "])\n", "\n", "print('Тестовая выборка:')\n", "print(data_test)\n", "print(f'\\nРазмерность: {data_test.shape}')\n", "print(f'\\nЦентр обучающих данных: (1, 1)')\n", "print(f'Расстояния от центра:')\n", "for i, point in enumerate(data_test):\n", " dist = np.sqrt((point[0] - 1)**2 + (point[1] - 1)**2)\n", " print(f' Точка {i+1} {point}: расстояние = {dist:.3f}')\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 9) Применение автокодировщиков к тестовым данным\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Тестирование AE1\n", "predicted_labels1, ire1_test = lib.predict_ae(ae1_trained, data_test, IREth1)\n", "lib.anomaly_detection_ae(predicted_labels1, ire1_test, IREth1)\n", "lib.ire_plot('test', ire1_test, IREth1, 'AE1')\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Тестирование AE2\n", "predicted_labels2, ire2_test = lib.predict_ae(ae2_trained, data_test, IREth2)\n", "lib.anomaly_detection_ae(predicted_labels2, ire2_test, IREth2)\n", "lib.ire_plot('test', ire2_test, IREth2, 'AE2')\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Визуализация элементов обучающей и тестовой выборки\n", "lib.plot2in1_anomaly(data, xx, yy, Z1, Z2, data_test)\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Подсчет обнаруженных аномалий\n", "anomalies_ae1 = int(predicted_labels1.sum())\n", "anomalies_ae2 = int(predicted_labels2.sum())\n", "\n", "# Используем сохраненные ранее значения EDCA метрик\n", "# (они были сохранены в ячейках после вызова square_calc)\n", "# Если переменные не определены, пытаемся прочитать из файла\n", "try:\n", " excess_ae1_val = excess_ae1 if excess_ae1 is not None else None\n", "except NameError:\n", " excess_ae1_val = None\n", "\n", "try:\n", " approx_ae1_val = approx_ae1 if approx_ae1 is not None else None\n", "except NameError:\n", " approx_ae1_val = None\n", "\n", "try:\n", " excess_ae2_val = excess_ae2 if excess_ae2 is not None else None\n", "except NameError:\n", " excess_ae2_val = None\n", "\n", "try:\n", " approx_ae2_val = approx_ae2 if approx_ae2 is not None else None\n", "except NameError:\n", " approx_ae2_val = None\n", "\n", "print('Таблица 1 - Результаты задания №1')\n", "print('=' * 120)\n", "print(f'{\"Модель\":<10} {\"Скрытых слоев\":<15} {\"Нейроны\":<25} {\"Эпох\":<10} {\"MSE_stop\":<12} {\"Порог IRE\":<12} {\"Excess\":<10} {\"Approx\":<10} {\"Аномалий\":<10}')\n", "print('-' * 120)\n", "print(f'AE1 {1:<15} {1:<25} {1000:<10} {mse_ae1:<12.6f} {IREth1:<12.6f} {excess_ae1_val if excess_ae1_val is not None else \"N/A\":<10} {approx_ae1_val if approx_ae1_val is not None else \"N/A\":<10} {anomalies_ae1}/{len(data_test):<10}')\n", "print(f'AE2 {6:<15} {\"8-4-2-1-2-4-8\":<25} {3000:<10} {mse_ae2:<12.6f} {IREth2:<12.6f} {excess_ae2_val if excess_ae2_val is not None else \"N/A\":<10} {approx_ae2_val if approx_ae2_val is not None else \"N/A\":<10} {anomalies_ae2}/{len(data_test):<10}')\n", "print('=' * 120)\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Задание 2\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 1) Изучение набора реальных данных Letter\n", "\n", "Набор данных Letter представляет собой характеристики букв английского алфавита. Для обнаружения аномалий нормальные примеры используются для обучения, а аномальные - для тестирования.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Загрузка обучающей и тестовой выборки Letter\n", "train_letter = np.loadtxt('data/letter_train.txt', dtype=float)\n", "test_letter = np.loadtxt('data/letter_test.txt', dtype=float)\n", "\n", "print('Обучающая выборка Letter:')\n", "print(f'Размерность: {train_letter.shape}')\n", "print(f'Количество признаков: {train_letter.shape[1]}')\n", "print(f'Количество примеров: {train_letter.shape[0]}')\n", "print(f'\\nПервые 5 строк:')\n", "print(train_letter[:5])\n", "\n", "print(f'\\nТестовая выборка Letter:')\n", "print(f'Размерность: {test_letter.shape}')\n", "print(f'Количество примеров: {test_letter.shape[0]}')\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 2.1) Нормализация данных (дополнительное исследование, для сравнения)\n", "\n", "Создадим нормализованную версию данных для сравнения результатов обучения.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Нормализация данных для сравнения результатов\n", "from sklearn.preprocessing import StandardScaler\n", "\n", "# Создаем нормализованные версии данных\n", "scaler = StandardScaler()\n", "train_letter_normalized = scaler.fit_transform(train_letter)\n", "test_letter_normalized = scaler.transform(test_letter)\n", "\n", "print('Нормализация данных выполнена')\n", "print(f'\\nИсходные данные (первые 3 признака первого примера):')\n", "print(f' train_letter[0, :3] = {train_letter[0, :3]}')\n", "print(f'\\nНормализованные данные (первые 3 признака первого примера):')\n", "print(f' train_letter_normalized[0, :3] = {train_letter_normalized[0, :3]}')\n", "print(f'\\nСтатистика нормализованных данных:')\n", "print(f' Среднее: {train_letter_normalized.mean(axis=0)[:5]}...')\n", "print(f' Стд. отклонение: {train_letter_normalized.std(axis=0)[:5]}...')\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 2.2) Обучение автокодировщика на ненормализованных данных\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Обучение автокодировщика для Letter на НЕнормализованных данных\n", "# Входной и выходной слои создаются автоматически по размеру данных (32 признака)\n", "# Мы задаем только скрытые слои\n", "# Полная архитектура: 32(вход) -> 100 -> 68 -> 48 -> 32 -> 24 -> 16 -> 8 -> 16 -> 24 -> 32 -> 48 -> 64 -> 100 -> 32(выход)\n", "# 11 скрытых слоев: 100 64 48 32 24 16 8 16 24 32 48 64 100 \n", "\n", "import warnings\n", "# Подавляем предупреждение о формате сохранения HDF5\n", "warnings.filterwarnings('ignore', category=UserWarning, module='absl')\n", "\n", "print('Обучение автокодировщика для данных Letter (НЕнормализованные данные)...')\n", "print('Архитектура: 32(вход) -> 100 -> 68 -> 48 -> 32 -> 24 -> 16 -> 8 -> 16 -> 24 -> 32 -> 48 -> 64 -> 100 -> 32(выход)')\n", "\n", "# Автоматизируем ввод для выбора пользовательской архитектуры\n", "with patch('builtins.input', side_effect=['1', '17', ' 100 86 72 64 48 32 24 16 8 16 24 32 48 64 72 86 100']):\n", " ae_letter_raw, IRE_letter_raw, IREth_letter_raw = lib.create_fit_save_ae(\n", " train_letter, \n", " 'out/Letter_AE_raw.h5', \n", " 'out/Letter_AE_raw_ire_th.txt',\n", " 100000, # epochs\n", " False, # verbose_show\n", " 10000, # patience\n", " verbose_every_n_epochs=500\n", " )\n", "\n", "# Вычисление MSE из предсказания\n", "X_pred_letter_raw = ae_letter_raw.predict(train_letter, verbose=0)\n", "mse_letter_raw = np.mean((train_letter - X_pred_letter_raw) ** 2)\n", "\n", "print(f'\\nОбучение завершено (НЕнормализованные данные)!')\n", "print(f'MSE_stop (приблизительно): {mse_letter_raw:.6f}')\n", "print(f'Порог IRE: {IREth_letter_raw:.6f}')\n", "print(f'Количество скрытых слоев: 11')\n", "print(f'Количество нейронов в скрытых слоях: 100 -> 68 -> 48 -> 32 -> 24 -> 16 -> 8 -> 16 -> 24 -> 32 -> 48 -> 64 -> 100')\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 2.3) Обучение автокодировщика на нормализованных данных\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Обучение автокодировщика для Letter на нормализованных данных\n", "# Та же архитектура для сравнения: 32(вход) -> 100 -> 68 -> 48 -> 32 -> 24 -> 16 -> 8 -> 16 -> 24 -> 32 -> 48 -> 64 -> 100 -> 32(выход)\n", "# 11 скрытых слоев: 100 86 72 64 48 32 24 16 8 16 24 32 48 64 72 86 100\n", "\n", "print('Обучение автокодировщика для данных Letter (нормализованные данные)...')\n", "print('Архитектура: 32(вход) -> 100 -> 68 -> 48 -> 32 -> 24 -> 16 -> 8 -> 16 -> 24 -> 32 -> 48 -> 64 -> 100 -> 32(выход)')\n", "\n", "# Автоматизируем ввод для выбора пользовательской архитектуры\n", "with patch('builtins.input', side_effect=['1', '17', ' 100 86 72 64 48 32 24 16 8 16 24 32 48 64 72 86 100']):\n", " ae_letter_norm, IRE_letter_norm, IREth_letter_norm = lib.create_fit_save_ae(\n", " train_letter_normalized, \n", " 'out/Letter_AE_norm.h5', \n", " 'out/Letter_AE_norm_ire_th.txt',\n", " 20000, # epochs\n", " True, # verbose_show\n", " 200, # patience\n", " verbose_every_n_epochs=500\n", " )\n", "\n", "# Вычисление MSE из предсказания\n", "X_pred_letter_norm = ae_letter_norm.predict(train_letter_normalized, verbose=0)\n", "mse_letter_norm = np.mean((train_letter_normalized - X_pred_letter_norm) ** 2)\n", "\n", "print(f'\\nОбучение завершено (нормализованные данные)!')\n", "print(f'MSE_stop (приблизительно): {mse_letter_norm:.6f}')\n", "print(f'Порог IRE: {IREth_letter_norm:.6f}')\n", "print(f'Количество скрытых слоев: 11')\n", "print(f'Количество нейронов в скрытых слоях: 100 -> 68 -> 48 -> 32 -> 24 -> 16 -> 8 -> 16 -> 24 -> 32 -> 48 -> 64 -> 100')\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 2.4) Сравнение результатов обучения на нормализованных и ненормализованных данных\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Сравнение результатов\n", "print('=' * 100)\n", "print('СРАВНЕНИЕ РЕЗУЛЬТАТОВ ОБУЧЕНИЯ')\n", "print('=' * 100)\n", "print(f'{\"Параметр\"} {\"НЕнормализованные\"} {\"Нормализованные\"}')\n", "print('-' * 100)\n", "print(f'{\"MSE_stop\"} {mse_letter_raw} {mse_letter_norm}')\n", "print(f'{\"Порог IRE\"} {IREth_letter_raw} {IREth_letter_norm:}')\n", "print(f'{\"Архитектура\":<30} {\"17 слоев\"} {\"17 слоев\"}')\n", "print(f'{\"Нейроны\"} {\"32(вход) -> 100 -> 68 -> 48 -> 32 -> 24 -> 16 -> 8 -> 16 -> 24 -> 32 -> 48 -> 64 -> 100 -> 32(выход)\"} {\"32(вход) -> 100 -> 68 -> 48 -> 32 -> 24 -> 16 -> 8 -> 16 -> 24 -> 32 -> 48 -> 64 -> 100 -> 32(выход)\"}')\n", "print('=' * 100)\n", "\n", "# Выбираем лучшую модель для дальнейшей работы\n", "if mse_letter_norm < mse_letter_raw:\n", " print('\\nЛучшая модель: НОРМАЛИЗОВАННЫЕ данные')\n", " ae_letter = ae_letter_norm\n", " IRE_letter = IRE_letter_norm\n", " IREth_letter = IREth_letter_norm\n", " mse_letter = mse_letter_norm\n", " test_letter_used = test_letter_normalized\n", " print(f'Используем эту модель для дальнейших экспериментов')\n", "else:\n", " print('\\nЛучшая модель: НЕнормализованные данные')\n", " ae_letter = ae_letter_raw\n", " IRE_letter = IRE_letter_raw\n", " IREth_letter = IREth_letter_raw\n", " mse_letter = mse_letter_raw\n", " test_letter_used = test_letter\n", " print(f'Используем эту модель для дальнейших экспериментов')\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 3) Построение графика ошибки реконструкции для Letter\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Построение графика ошибки реконструкции для выбранной модели\n", "lib.ire_plot('training', IRE_letter, IREth_letter, 'Letter_AE')\n", "print(f'Порог ошибки реконструкции: {IREth_letter:.6f}')\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 4) Применение автокодировщика к тестовой выборке Letter\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Тестирование автокодировщика на тестовой выборке\n", "# Используем выбранную модель (лучшую из нормализованных/ненормализованных)\n", "predicted_labels_letter, ire_letter_test = lib.predict_ae(ae_letter, test_letter_used, IREth_letter)\n", "\n", "# Подсчет обнаруженных аномалий\n", "num_anomalies = int(predicted_labels_letter.sum())\n", "total_test = len(test_letter_used)\n", "anomaly_percentage = (num_anomalies / total_test) * 100\n", "\n", "print(f'Обнаружено аномалий: {num_anomalies} из {total_test}')\n", "print(f'Процент обнаруженных аномалий: {anomaly_percentage:.1f}%')\n", "\n", "lib.anomaly_detection_ae(predicted_labels_letter, ire_letter_test, IREth_letter)\n", "lib.ire_plot('test', ire_letter_test, IREth_letter, 'Letter_AE')\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 5) Результаты задания №2\n", "\n", "Результаты исследования занесены в таблицу:\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print('Таблица 2 - Результаты задания №2')\n", "print('=' * 100)\n", "print(f'{\"Dataset\":<15} {\"Скрытых слоев\":<15} {\"Нейроны\":<40} {\"Эпох\":<10} {\"MSE_stop\":<12} {\"Порог IRE\":<12} {\"% аномалий\":<12}')\n", "print('-' * 100)\n", "print(f'Letter {11:<15} {\"32(вход) -> 100 -> 68 -> 48 -> 32 -> 24 -> 16 -> 8 -> 16 -> 24 -> 32 -> 48 -> 64 -> 100 -> 32(выход)\":<40} {20000:<10} {mse_letter:<12.6f} {IREth_letter:<12.6f} {anomaly_percentage:.1f}%')\n", "print('=' * 100)\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Выводы\n", "\n", "### Требования к данным для обучения:\n", "- Данные для обучения должны быть без аномалий, чтобы автокодировщик смог рассчитать верное пороговое значение\n", "\n", "### Требования к архитектуре автокодировщика:\n", "- Архитектура должна постепенно сужаться к бутылочному горлышку, а затем постепенно возвращаться к исходным выходным размерам\n", "- Для двумерных данных оптимальное количество скрытых слоев: 3-6\n", "- Для многомерных данных (32 признака) оптимальное количество скрытых слоев: от 7-ми\n", "\n", "### Требования к количеству эпох обучения:\n", "- Для простых данных (2D): 1000-3000 эпох\n", "- Для сложных данных (многомерных): до 100000 эпох\n", "\n", "### Требования к ошибке MSE_stop:\n", "- Для двумерных данных: оптимальная ошибка MSE-stop в районе 0.01\n", "- Для многомерных данных: оптимальная ошибка MSE-stop в районе 0.1-0.01\n", "\n", "### Требования к порогу обнаружения аномалий:\n", "- Для двумерных данных: значение порога в районе 0.4-2.5\n", "- Для многомерных данных: значение порога не больше 1.6\n", "\n", "### Требования к характеристикам качества обучения EDCA:\n", "- Значение Excess должно быть как можно ближе к 0\n", "- Значение Deficit должно быть как можно ближе к 0 \n", "- Значение Coating должно быть как можно ближе к 1 \n", "- Значение Approx должно быть как можно ближе к 1\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.11.9" } }, "nbformat": 4, "nbformat_minor": 2 }