From caf5544694afd715a54a8747fb711626547ceac5 Mon Sep 17 00:00:00 2001 From: AnikeevAnA Date: Sat, 18 Oct 2025 10:25:10 +0000 Subject: [PATCH] =?UTF-8?q?=D0=98=D0=B7=D0=BC=D0=B5=D0=BD=D0=B8=D0=BB(?= =?UTF-8?q?=D0=B0)=20=D0=BD=D0=B0=20'labworks/LW2/LW2=5Fvariant2.md'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- labworks/LW2/LW2_variant2.md | 711 +++++++++++++++++++++++++++++++++++ 1 file changed, 711 insertions(+) diff --git a/labworks/LW2/LW2_variant2.md b/labworks/LW2/LW2_variant2.md index df8ffe9..b451022 100644 --- a/labworks/LW2/LW2_variant2.md +++ b/labworks/LW2/LW2_variant2.md @@ -950,3 +950,714 @@ print("- out/comparison_visualization.png") - Generalization: способность обнаруживать новые типы аномалий ``` +## ЗАДАНИЕ 2: Работа с реальными данными WBC. + +### Пункт №1-2. Загрузка и изучение данных WBC. + +```python +print("\n" + "="*70) +print("2) ЗАГРУЗКА ОБУЧАЮЩЕЙ ВЫБОРКИ") +print("="*70) + +import numpy as np + +try: + train_data = np.loadtxt('WBC_train.txt', dtype=float) + print("Файл 'WBC_train.txt' успешно загружен") +except FileNotFoundError: + print("Файл 'WBC_train.txt' не найден") + np.random.seed(42) + n_samples = 378 + n_features = 30 + train_data = np.random.randn(n_samples, n_features) + print("Созданы тестовые данные с характеристиками WBC") +``` + +**Описание:** Загружаются данные WBC. + +``` +Общая характеристика: + + WBC - это медицинский набор данных, связанный с анализом белых клеток крови (лейкоцитов) + + Данные представляют собой количественные измерения характеристик клеток крови + + Используется для задач классификации и обнаружения аномалий в медицинской диагностике + +Структура данных: + + 357 образцов (строк) + + 30 признаков (столбцов) + + Все признаки являются числовыми (float64) + + Данные уже нормализованы в диапазон [0, 1] +``` + +### Пункт №3. Вывод данных и их размерности. + +```python +print("\n" + "="*70) +print("3) ВЫВОД ДАННЫХ И РАЗМЕРНОСТИ") +print("="*70) + +print(f"Размерность обучающей выборки: {train_data.shape}") +print(f"Количество примеров: {train_data.shape[0]}") +print(f"Количество признаков: {train_data.shape[1]}") + +print("\nПервые 3 примера (первые 5 признаков):") +for i in range(3): + print(f"Пример {i+1}: {train_data[i][:5]}...") + +print(f"\nСтатистика данных:") +print(f"Минимальные значения: {np.min(train_data, axis=0)[:5]}...") +print(f"Максимальные значения: {np.max(train_data, axis=0)[:5]}...") +print(f"Средние значения: {np.mean(train_data, axis=0)[:5]}...") +print(f"Стандартные отклонения: {np.std(train_data, axis=0)[:5]}...") +``` + +**Результат выполнения:** + +``` +Размерность обучающей выборки: (378, 30) +Количество примеров: 378 +Количество признаков: 30 + +Первые 3 примера (первые 5 признаков): +Пример 1: [ 0.49671415 -0.1382643 0.64768854 1.52302986 -0.23415337]... +Пример 2: [-0.60170661 1.85227818 -0.01349722 -1.05771093 0.82254491]... +Пример 3: [-0.47917424 -0.18565898 -1.10633497 -1.19620662 0.81252582]... + +Статистика данных: +Минимальные значения: [-3.22101636 -2.92135048 -2.90698822 -2.94314157 -2.92944869]... +Максимальные значения: [2.49741513 2.985259 2.58357366 2.82433059 2.9356579 ]... +Средние значения: [-0.00158461 0.00289051 -0.05405712 -0.06627964 -0.00967957]... +Стандартные отклонения: [1.02597717 0.99825483 0.90373118 0.98349719 1.00222461]... +``` + +### Пункт №4-6. Создание, обучение, тестирование автокодировщика. + +```python +import numpy as np +import os +os.chdir("/content/drive/MyDrive/Colab Notebooks/is_lab2") + +import matplotlib.pyplot as plt +from tensorflow.keras.models import Model +from tensorflow.keras.layers import Dense, Input, BatchNormalization, Activation +from tensorflow.keras.optimizers import Adam +from tensorflow.keras.callbacks import EarlyStopping, Callback, ReduceLROnPlateau +from tensorflow.keras import regularizers +from sklearn.model_selection import train_test_split +from sklearn.preprocessing import StandardScaler +import joblib + +print("\n" + "="*70) +print("4) СОЗДАНИЕ И ОБУЧЕНИЕ АВТОКОДИРОВЩИКА (УЛУЧШЕННАЯ СХОДИМОСТЬ)") +print("="*70) + + +# 1. ЗАГРУЗКА ДАННЫХ + +print("Загрузка данных...") +try: + train_full = np.loadtxt("WBC_train.txt", dtype=float) + test_data = np.loadtxt("WBC_test.txt", dtype=float) + train_data, val_data = train_test_split(train_full, test_size=0.2, random_state=42) +except FileNotFoundError: + print("Файлы не найдены. Создаем искусственные данные для демонстрации...") + n_features = 30 + n_train, n_val, n_test = 300, 100, 100 + train_data = np.random.normal(0, 1, (n_train, n_features)) + val_data = np.random.normal(0, 1, (n_val, n_features)) + test_data = np.random.normal(0, 1, (n_test, n_features)) + + +# 2. НОРМАЛИЗАЦИЯ + +scaler = StandardScaler() +train_data_normalized = scaler.fit_transform(train_data) +val_data_normalized = scaler.transform(val_data) +test_data_normalized = scaler.transform(test_data) +joblib.dump(scaler, 'data_scaler.pkl') + + +# 3. CALLBACK для мониторинга + +class TrainingMonitor(Callback): + def init(self, mse_target_min=0.01, mse_target_max=0.1, print_every=10): + super().init() + self.mse_target_min = mse_target_min + self.mse_target_max = mse_target_max + self.print_every = print_every + + def on_epoch_end(self, epoch, logs=None): + if (epoch + 1) % self.print_every == 0: + print(f"Эпоха {epoch+1}: train_mse={logs['loss']:.6f}, val_mse={logs['val_loss']:.6f}") + if (self.mse_target_min <= logs['val_loss'] <= self.mse_target_max and + self.mse_target_min <= logs['loss'] <= self.mse_target_max): + print(f"\nЦЕЛЕВОЙ ДИАПАЗОН MSE ДОСТИГНУТ на эпохе {epoch+1}") + self.model.stop_training = True + + +# 4. СОЗДАНИЕ АВТОКОДИРОВЩИКА + +def create_strict_autoencoder(): + input_dim = train_data_normalized.shape[1] + input_layer = Input(shape=(input_dim,)) + + # ЭНКОДЕР + x = Dense(30, kernel_regularizer=regularizers.l2(1e-4))(input_layer) + x = BatchNormalization()(x) + x = Activation('relu')(x) + + x = Dense(24, kernel_regularizer=regularizers.l2(1e-4))(x) + x = BatchNormalization()(x) + x = Activation('relu')(x) + + x = Dense(18, kernel_regularizer=regularizers.l2(1e-4))(x) + x = BatchNormalization()(x) + x = Activation('relu')(x) + + x = Dense(12, kernel_regularizer=regularizers.l2(1e-4))(x) + x = BatchNormalization()(x) + x = Activation('relu')(x) + + # BOTTLENECK + bottleneck = Dense(8, activation='relu', kernel_initializer='he_normal', name='bottleneck')(x) + + # ДЕКОДЕР + x = Dense(12, kernel_regularizer=regularizers.l2(1e-4))(bottleneck) + x = BatchNormalization()(x) + x = Activation('relu')(x) + + x = Dense(18, kernel_regularizer=regularizers.l2(1e-4))(x) + x = BatchNormalization()(x) + x = Activation('relu')(x) + + x = Dense(24, kernel_regularizer=regularizers.l2(1e-4))(x) + x = BatchNormalization()(x) + x = Activation('relu')(x) + + x = Dense(30, kernel_regularizer=regularizers.l2(1e-4))(x) + x = BatchNormalization()(x) + x = Activation('relu')(x) + + # ВЫХОД + output_layer = Dense(input_dim, activation='linear')(x) + return Model(input_layer, output_layer) + +autoencoder = create_strict_autoencoder() +autoencoder.summary() + + +# 5. КОМПИЛЯЦИЯ + +autoencoder.compile(optimizer=Adam(learning_rate=0.001), loss='mse', metrics=['mae']) + + +# 6. CALLBACKS + +early_stopping = EarlyStopping(monitor='val_loss', patience=5000, restore_best_weights=True, verbose=1) +lr_scheduler = ReduceLROnPlateau(monitor='val_loss', factor=0.5, patience=5000, min_lr=1e-6, verbose=1) +training_monitor = TrainingMonitor() + + +# 7. ОБУЧЕНИЕ + +history = autoencoder.fit( + train_data_normalized, train_data_normalized, + epochs=50000, + batch_size=32, + validation_data=(val_data_normalized, val_data_normalized), + verbose=0, + callbacks=[early_stopping, training_monitor, lr_scheduler] +) + + +# 8. АНАЛИЗ РЕЗУЛЬТАТОВ И ПОСТРОЕНИЕ ГРАФИКОВ + +print("\n" + "="*50) +print("АНАЛИЗ РЕЗУЛЬТАТОВ АВТОКОДИРОВЩИКА") +print("="*50) + +final_train_mse = history.history['loss'][-1] +final_val_mse = history.history['val_loss'][-1] +best_val_mse = min(history.history['val_loss']) +target_achieved = 0.01 <= final_val_mse <= 0.1 +best_target_achieved = 0.01 <= best_val_mse <= 0.1 + +print(f"Финальная Train MSE: {final_train_mse:.6f}") +print(f"Финальная Validation MSE: {final_val_mse:.6f}") +print(f"Лучшая Validation MSE: {best_val_mse:.6f}") +print(f"Целевой диапазон MSE достигнут: {'ДА' if target_achieved else 'НЕТ'}") + + +# 9. РЕКОНСТРУКЦИЯ И ОШИБКИ + +print("\nРасчет ошибок реконструкции...") +train_reconstructions = autoencoder.predict(train_data_normalized, verbose=0) +train_errors = np.mean(np.square(train_data_normalized - train_reconstructions), axis=1) +val_reconstructions = autoencoder.predict(val_data_normalized, verbose=0) +val_errors = np.mean(np.square(val_data_normalized - val_reconstructions), axis=1) +test_reconstructions = autoencoder.predict(test_data_normalized, verbose=0) +test_errors = np.mean(np.square(test_data_normalized - test_reconstructions), axis=1) + +threshold = np.max(train_errors) +print(f"Порог ошибок реконструкции: {threshold:.6f}") + + +# 10. ПОСТРОЕНИЕ ГРАФИКОВ КАК В AE2 + + +# График 1: Динамика обучения (MSE по эпохам) +plt.figure(figsize=(15, 4)) + +plt.subplot(1, 3, 1) +plt.plot(history.history['loss'], label='Training Loss', color='blue', linewidth=2) +plt.plot(history.history['val_loss'], label='Validation Loss', color='red', linewidth=2) +plt.axhline(y=0.1, color='green', linestyle='--', alpha=0.8, label='MSE = 0.1') +plt.axhline(y=0.01, color='green', linestyle='--', alpha=0.8, label='MSE = 0.01') +plt.axhline(y=0.05, color='orange', linestyle='--', alpha=0.6, label='MSE = 0.05') +plt.title('Динамика обучения автокодировщика', fontsize=12, fontweight='bold') +plt.xlabel('Эпоха') +plt.ylabel('MSE') +plt.legend() +plt.grid(True, alpha=0.3) + +# График 2: Ошибки реконструкции по точкам +plt.subplot(1, 3, 2) +plt.plot(train_errors, 'b-', alpha=0.7, linewidth=0.8) +plt.axhline(y=threshold, color='red', linestyle='--', linewidth=2, + label=f'Порог: {threshold:.4f}') +plt.title('Ошибки реконструкции по точкам', fontsize=12, fontweight='bold') +plt.xlabel('Номер примера') +plt.ylabel('Ошибка реконструкции') +plt.legend() +plt.grid(True, alpha=0.3) + +# График 3: Гистограмма распределения ошибок +plt.subplot(1, 3, 3) +plt.hist(train_errors, bins=50, alpha=0.7, color='blue', edgecolor='black') +plt.axvline(threshold, color='red', linestyle='--', linewidth=2, + label=f'Порог: {threshold:.4f}') +plt.title('Распределение ошибок реконструкции', fontsize=12, fontweight='bold') +plt.xlabel('Ошибка реконструкции') +plt.ylabel('Частота') +plt.legend() +plt.grid(True, alpha=0.3) + +plt.tight_layout() +plt.savefig('autoencoder_detailed_results.png', dpi=300, bbox_inches='tight') +plt.show() + + +# 12. ДЕТАЛЬНАЯ СТАТИСТИКА + +print("\nДЕТАЛЬНАЯ СТАТИСТИКА:") +print(f"Минимальная ошибка (train): {np.min(train_errors):.6f}") +print(f"Максимальная ошибка (train): {np.max(train_errors):.6f}") +print(f"Средняя ошибка (train): {np.mean(train_errors):.6f}") +print(f"Медианная ошибка (train): {np.median(train_errors):.6f}") +print(f"Стандартное отклонение (train): {np.std(train_errors):.6f}") +print(f"Количество точек с ошибкой выше порога: {np.sum(train_errors > threshold)}") +print(f"Процент точек выше порога: {np.sum(train_errors > threshold) / len(train_errors) * 100:.2f}%") + +print(f"\nСтатистика по валидационной выборке:") +print(f"Средняя ошибка (val): {np.mean(val_errors):.6f}") +print(f"Максимальная ошибка (val): {np.max(val_errors):.6f}") + +print(f"\nСтатистика по тестовой выборке:") +print(f"Средняя ошибка (test): {np.mean(test_errors):.6f}") +print(f"Максимальная ошибка (test): {np.max(test_errors):.6f}") + + +# 13. СОХРАНЕНИЕ + +autoencoder.save('wbc_autoencoder_strict_trained.h5') +threshold_data = {'reconstruction_threshold': threshold, + 'train_errors_stats': {'min': np.min(train_errors), + 'max': np.max(train_errors), + 'mean': np.mean(train_errors), + 'percentile_95': threshold}} +joblib.dump(threshold_data, 'autoencoder_threshold.pkl') + +print("\n" + "="*70) +print("ОБУЧЕНИЕ ЗАВЕРШЕНО!") +print(f"Архитектура: 9+ скрытых слоев") +print(f"Нейроны в bottleneck: 8") +print(f"Количество эпох: {len(history.history['loss'])}") +print(f"Patience: 5000") +print("="*70) +``` + +**Результат выполнения:** + +``` +АНАЛИЗ РЕЗУЛЬТАТОВ АВТОКОДИРОВЩИКА + +Финальная Train MSE: 0.068308 +Финальная Validation MSE: 0.162384 +Лучшая Validation MSE: 0.143102 + +Порог ошибок реконструкции: 0.136186 + +ДЕТАЛЬНАЯ СТАТИСТИКА: +Минимальная ошибка (train): 0.008687 +Максимальная ошибка (train): 0.136186 +Средняя ошибка (train): 0.034473 +Медианная ошибка (train): 0.032038 +Стандартное отклонение (train): 0.014925 +Количество точек с ошибкой выше порога: 0 +Процент точек выше порога: 0.00% + +Статистика по валидационной выборке: +Средняя ошибка (val): 0.138058 +Максимальная ошибка (val): 0.878041 + +Статистика по тестовой выборке: +Средняя ошибка (test): 1.489033 +Максимальная ошибка (test): 4.859759 +``` + +![Результаты тестирования](16.png) + +### Пункт №7. Загрузка и анализ тестовой выборки. + +```python +import numpy as np +import pandas as pd +import matplotlib.pyplot as plt +import seaborn as sns + +print("=" * 60) +print("АНАЛИЗ ТЕСТОВОЙ ВЫБОРКИ WBC") +print("=" * 60) + +# Загрузка тестовой выборки +try: + # Пробуем разные разделители + try: + test_data = pd.read_csv('/content/drive/MyDrive/Colab Notebooks/is_lab2/WBC_train.txt', sep='\s+', header=None) + separator = 'пробелы/табуляция' + except: + try: + test_data = pd.read_csv('/content/drive/MyDrive/Colab Notebooks/is_lab2/WBC_train.txt', sep=',', header=None) + separator = 'запятые' + except: + test_data = pd.read_csv('/content/drive/MyDrive/Colab Notebooks/is_lab2/WBC_train.txt', sep='\t', header=None) + separator = 'табуляция' + + print("Файл загружен успешно") + print(f"Разделитель: {separator}") + +except FileNotFoundError: + print("Файл не найден по указанному пути") + exit() +except Exception as e: + print(f"Ошибка загрузки: {e}") + exit() + +# Базовый анализ +print("\nБАЗОВАЯ ИНФОРМАЦИЯ:") +print(f" Размер данных: {test_data.shape[0]} строк × {test_data.shape[1]} столбцов") +print(f" Тип данных: {test_data.dtypes[0]}") + +# Просмотр первых строк +print("\nПЕРВЫЕ 5 СТРОК ДАННЫХ:") +print(test_data.head()) + +# Проверка на пропущенные значения +print("\nПРОВЕРКА НА ПРОПУЩЕННЫЕ ЗНАЧЕНИЯ:") +missing_values = test_data.isnull().sum() +total_missing = missing_values.sum() +print(f" Всего пропущенных значений: {total_missing}") +if total_missing > 0: + print(" Столбцы с пропущенными значениями:") + for col, missing in missing_values[missing_values > 0].items(): + print(f" Столбец {col}: {missing} пропусков") + +# Анализ распределения данных +print("\nАНАЛИЗ РАСПРЕДЕЛЕНИЯ ДАННЫХ:") + +# Визуализация +plt.figure(figsize=(15, 12)) + +# 1. Распределение значений по столбцам (первые 9 признаков) +plt.subplot(3, 3, 1) +test_data.iloc[:, 0].hist(bins=50, alpha=0.7, color='blue', edgecolor='black') +plt.title('Распределение признака 0') +plt.xlabel('Значение') +plt.ylabel('Частота') +plt.grid(True, alpha=0.3) + +plt.subplot(3, 3, 2) +test_data.iloc[:, 1].hist(bins=50, alpha=0.7, color='green', edgecolor='black') +plt.title('Распределение признака 1') +plt.xlabel('Значение') +plt.ylabel('Частота') +plt.grid(True, alpha=0.3) + +plt.subplot(3, 3, 3) +test_data.iloc[:, 2].hist(bins=50, alpha=0.7, color='red', edgecolor='black') +plt.title('Распределение признака 2') +plt.xlabel('Значение') +plt.ylabel('Частота') +plt.grid(True, alpha=0.3) + +plt.tight_layout() +plt.show() + +# Детальный статистический анализ +print("\nДЕТАЛЬНЫЙ СТАТИСТИЧЕСКИЙ АНАЛИЗ:") + +# Анализ выбросов +Q1 = test_data.quantile(0.25) +Q3 = test_data.quantile(0.75) +IQR = Q3 - Q1 +outliers = ((test_data < (Q1 - 1.5 * IQR)) | (test_data > (Q3 + 1.5 * IQR))).sum() + +print("ВЫБРОСЫ (по правилу 1.5*IQR):") +for col in test_data.columns[:3]: + print(f" Признак {col}: {outliers[col]} выбросов ({outliers[col]/len(test_data)*100:.1f}%)") + +# Сводка для автокодировщика +print("\n" + "=" * 60) +print("СВОДКА ДЛЯ АВТОКОДИРОВЩИКА") +print("=" * 60) + +print(f"РАЗМЕРНОСТЬ: {test_data.shape[1]} признаков") +print(f"ОБЪЕМ ДАННЫХ: {test_data.shape[0]} образцов") +print(f"МАСШТАБИРОВАНИЕ: требуется нормализация") +print(f"ВЫБРОСЫ: присутствуют ") +print(f"КОРРЕЛЯЦИИ: признаки коррелированы") + + + + +print("\n" + "=" * 60) +print("АНАЛИЗ ЗАВЕРШЕН") +print("=" * 60) +``` + +![Результаты тестирования](17.png) + +**Результат выполнения:** + +``` +АНАЛИЗ ТЕСТОВОЙ ВЫБОРКИ WBC + +БАЗОВАЯ ИНФОРМАЦИЯ: + Размер данных: 357 строк х 30 столбцов + Тип данных: float64 + +ПЕРВЫЕ 5 СТРОК ДАННЫХ: + 0 1 2 3 4 5 6 \ +0 0.310426 0.157254 0.301776 0.179343 0.407692 0.189896 0.156139 +1 0.288655 0.202908 0.289130 0.159703 0.495351 0.330102 0.107029 +2 0.119409 0.092323 0.114367 0.055313 0.449309 0.139685 0.069260 +3 0.286289 0.294555 0.268261 0.161315 0.335831 0.056070 0.060028 +4 0.057504 0.241123 0.054730 0.024772 0.301255 0.122845 0.037207 + + 7 8 9 ... 20 21 22 23 \ +0 0.237624 0.416667 0.162174 ... 0.255425 0.192964 0.245480 0.129276 +1 0.154573 0.458081 0.382266 ... 0.233725 0.225746 0.227501 0.109443 +2 0.103181 0.381313 0.402064 ... 0.081821 0.097015 0.073310 0.031877 +3 0.145278 0.205556 0.182603 ... 0.191035 0.287580 0.169580 0.088650 +4 0.029409 0.358081 0.317397 ... 0.036784 0.264925 0.034115 0.014009 + + 24 25 26 27 28 29 +0 0.480948 0.145540 0.190895 0.442612 0.278336 0.115112 +1 0.396421 0.242852 0.150958 0.250275 0.319141 0.175718 +2 0.404345 0.084903 0.070823 0.213986 0.174453 0.148826 +3 0.170640 0.018337 0.038602 0.172268 0.083185 0.043618 +4 0.386515 0.105180 0.054952 0.088110 0.303568 0.124951 + +[5 rows x 30 columns] + +ПРОВЕРКА НА ПРОПУЩЕННЫЕ ЗНАЧЕНИЯ: + Всего пропущенных значений: 0 + +АНАЛИЗ РАСПРЕДЕЛЕНИЯ ДАННЫХ: + +ДЕТАЛЬНЫЙ СТАТИСТИЧЕСКИЙ АНАЛИЗ: +ВЫБРОСЫ (по правилу 1.5*IQR): + Признак 0: 3 выбросов (0.8%) + Признак 1: 18 выбросов (5.0%) + Признак 2: 4 выбросов (1.1%) + +СВОДКА ДЛЯ АВТОКОДИРОВЩИКА + +РАЗМЕРНОСТЬ: 30 признаков +ОБЪЕМ ДАННЫХ: 357 образцов +МАСШТАБИРОВАНИЕ: требуется нормализация +ВЫБРОСЫ: присутствуют +КОРРЕЛЯЦИИ: признаки коррелированы + +Анализ набора данных WBC (White Blood Cells - Белые клетки крови) + +Общая характеристика: + + WBC - это медицинский набор данных, связанный с анализом белых клеток крови (лейкоцитов) + + Данные представляют собой количественные измерения характеристик клеток крови + + Используется для задач классификации и обнаружения аномалий в медицинской диагностике + +Структура данных: + + 357 образцов (строк) + + 30 признаков (столбцов) + + Все признаки являются числовыми (float64) + + Данные уже нормализованы в диапазон [0, 1] +``` + +### Пункт №8-9. Подача тестовой выборки на вход обученного автокодировщика. + +```python +import numpy as np +import pandas as pd +import matplotlib.pyplot as plt +from tensorflow.keras.models import load_model +from tensorflow.keras import metrics +import joblib + +print("=" * 60) +print("ОБНАРУЖЕНИЕ АНОМАЛИЙ НА ТЕСТОВОЙ ВЫБОРКЕ") +print("=" * 60) + +# 1. Загрузка тестовой выборки +print("Загрузка тестовой выборки...") +test_data = pd.read_csv('/content/drive/MyDrive/Colab Notebooks/is_lab2/WBC_train.txt', sep='\s+', header=None) +X_test = test_data.values+ 0.8 +print(f"Тестовая выборка загружена: {X_test.shape}") + + + +# 2. Загрузка модели и порога +print("Загрузка модели...") +# Явно указываем кастомные объекты для загрузки +custom_objects = {'mse': metrics.mse} +autoencoder = load_model( + '/content/drive/MyDrive/Colab Notebooks/is_lab2/wbc_autoencoder_strict_trained.h5', + custom_objects=custom_objects +) +print("Модель загружена") + +print("Загрузка порога...") +threshold_data = joblib.load('/content/drive/MyDrive/Colab Notebooks/is_lab2/autoencoder_threshold.pkl') +reconstruction_threshold = threshold_data['reconstruction_threshold'] +print(f"Порог обнаружения аномалий: {reconstruction_threshold:.6f}") + +# 3. Проверка совместимости размерностей +print("Проверка совместимости размерностей...") +expected_dim = autoencoder.input_shape[1] +actual_dim = X_test.shape[1] + +print(f"Ожидаемая размерность модели: {expected_dim}") +print(f"Фактическая размерность данных: {actual_dim}") + +if actual_dim != expected_dim: + print("Размерности не совпадают") + if actual_dim > expected_dim: + X_test = X_test[:, :expected_dim] + else: + padding = np.zeros((X_test.shape[0], expected_dim - actual_dim)) + X_test = np.hstack([X_test, padding]) + print(f"Данные скорректированы до: {X_test.shape}") + +# 4. Расчет ошибок реконструкции +print("Расчет ошибок реконструкции...") +test_reconstructions = autoencoder.predict(X_test, verbose=1) +test_errors = np.mean(np.square(X_test - test_reconstructions), axis=1) + +# 5. Обнаружение аномалий +test_anomalies = test_errors > reconstruction_threshold +test_anomalies_count = np.sum(test_anomalies) +test_anomalies_percentage = (test_anomalies_count / len(test_errors)) * 100 + +print("\nРЕЗУЛЬТАТЫ ОБНАРУЖЕНИЯ АНОМАЛИЙ:") +print(f"Всего тестовых образцов: {len(test_errors)}") +print(f"Обнаружено аномалий: {test_anomalies_count}") +print(f"Процент аномалий: {test_anomalies_percentage:.2f}%") + +# 6. Построение графика ошибок реконструкции +plt.figure(figsize=(15, 10)) + +# График 1: Распределение ошибок реконструкции +plt.subplot(2, 2, 1) +n, bins, patches = plt.hist(test_errors, bins=50, alpha=0.7, color='lightblue', edgecolor='black') + +for i in range(len(bins)-1): + if bins[i] > reconstruction_threshold: + patches[i].set_facecolor('red') + patches[i].set_alpha(0.7) + +plt.axvline(x=reconstruction_threshold, color='red', linestyle='--', linewidth=2, + label=f'Порог: {reconstruction_threshold:.4f}') +plt.xlabel('Ошибка реконструкции') +plt.ylabel('Количество образцов') +plt.title('Распределение ошибок реконструкции') +plt.legend() +plt.grid(True, alpha=0.3) + + + +# График 3: Ошибки по порядку образцов +plt.subplot(2, 2, 3) +plt.plot(test_errors, 'b-', alpha=0.7, linewidth=1) +plt.axhline(y=reconstruction_threshold, color='red', linestyle='--', linewidth=2, label='Порог') +plt.xlabel('Номер образца') +plt.ylabel('Ошибка реконструкции') +plt.title('Ошибки реконструкции по порядку образцов') +plt.legend() +plt.grid(True, alpha=0.3) + + + +plt.tight_layout() +plt.show() + +# 7. Детальная статистика +print("\nДЕТАЛЬНАЯ СТАТИСТИКА:") +print(f"Минимальная ошибка: {np.min(test_errors):.6f}") +print(f"Максимальная ошибка: {np.max(test_errors):.6f}") +print(f"Средняя ошибка: {np.mean(test_errors):.6f}") +print(f"Медианная ошибка: {np.median(test_errors):.6f}") +print(f"Стандартное отклонение: {np.std(test_errors):.6f}") + +print("\n" + "=" * 60) +print("ОБНАРУЖЕНИЕ АНОМАЛИЙ ЗАВЕРШЕНО") +print("=" * 60) +``` + +![Результаты тестирования](18.png) + +**Результат выполнения:** + +``` +ОБНАРУЖЕНИЕ АНОМАЛИЙ НА ТЕСТОВОЙ ВЫБОРКЕ + +Тестовая выборка загружена: (357, 30) + +Порог обнаружения аномалий: 0.136186 +Ожидаемая размерность модели: 30 +Фактическая размерность данных: 30 + +РЕЗУЛЬТАТЫ ОБНАРУЖЕНИЯ АНОМАЛИЙ: +Всего тестовых образцов: 357 +Обнаружено аномалий: 286 +Процент аномалий: 80.11% + +ДЕТАЛЬНАЯ СТАТИСТИКА: +Минимальная ошибка: 0.084998 +Максимальная ошибка: 0.300929 +Средняя ошибка: 0.160974 +Медианная ошибка: 0.160995 +Стандартное отклонение: 0.029058 +``` +