/
urfu_itis_limits
/
code-review-101-LenLin
Обзор
Документация
Войти
/
urfu_itis_limits
/
code-review-101-LenLin
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
master
assignment.py
218 строк
10 KB
LenLin
update assignment.py
29 ноя 2025, 20:21
29 ноя 2025, 20:21
ac9797f
Код
Авторство
О чём код?
""" Задание 10: Анализ датасета Digits - РЕАЛИЗАЦИЯ Цель: Анализ данных рукописных цифр - многоклассовая классификация """ import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns from sklearn.datasets import load_digits plt.rcParams['font.sans-serif'] = ['DejaVu Sans'] plt.rcParams['axes.unicode_minus'] = False def load_data(): """Загрузить датасет Digits и конвертировать в DataFrame""" digits = load_digits() # Создаем DataFrame с пиксельными признаками df = pd.DataFrame(digits.data, columns=[f'pixel_{i}' for i in range(64)]) # Добавляем целевую переменную (убрал дублирующий столбец 'digit') df['target'] = digits.target return df def target_analysis(df): """Анализ целевой переменной (цифры 0-9)""" print("\n" + "="*50) print("АНАЛИЗ ЦЕЛЕВОЙ ПЕРЕМЕННОЙ") print("="*50) # Распределение цифр target_counts = df['target'].value_counts().sort_index() target_percent = df['target'].value_counts(normalize=True).sort_index() * 100 print("Распределение цифр:") for digit in range(10): count = target_counts[digit] percent = target_percent[digit] print(f"Цифра {digit}: {count:3d} примеров ({percent:5.2f}%)") print(f"\nВсего примеров: {len(df)}") print(f"Количество классов: {df['target'].nunique()}") def feature_statistics(df): """Вычислить статистику по пиксельным значениям""" print("\n" + "="*50) print("СТАТИСТИКА ПИКСЕЛЕЙ") print("="*50) # Выбираем только пиксельные колонки pixel_columns = [col for col in df.columns if col.startswith('pixel_')] pixel_data = df[pixel_columns] print("Общая статистика пиксельных значений:") print(f"Среднее значение: {pixel_data.values.mean():.3f}") print(f"Минимальное значение: {pixel_data.values.min()}") print(f"Максимальное значение: {pixel_data.values.max()}") print(f"Стандартное отклонение: {pixel_data.values.std():.3f}") print(f"Медиана: {np.median(pixel_data.values):.3f}") def visualize_target(df): """Визуализировать распределение цифр""" fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5)) # Уменьшил размер # Столбчатая диаграмма target_counts = df['target'].value_counts().sort_index() ax1.bar(target_counts.index, target_counts.values, color='skyblue', edgecolor='navy') ax1.set_title('Распределение цифр в датасете', fontsize=12, fontweight='bold') ax1.set_xlabel('Цифра') ax1.set_ylabel('Количество примеров') ax1.grid(axis='y', alpha=0.3) # Круговая диаграмма colors = plt.cm.Set3(np.linspace(0, 1, 10)) ax2.pie(target_counts.values, labels=target_counts.index, autopct='%1.1f%%', colors=colors, startangle=90) ax2.set_title('Процентное распределение цифр', fontsize=12, fontweight='bold') plt.tight_layout() plt.savefig('10_digits_target_distribution.png', dpi=300, bbox_inches='tight') plt.show() def sample_digit_images(df): """Визуализировать примеры цифр""" fig, axes = plt.subplots(2, 5, figsize=(12, 5)) # Уменьшил размер # Выбираем по одному примеру для каждой цифры for digit in range(10): digit_sample = df[df['target'] == digit].iloc[0] pixel_columns = [col for col in df.columns if col.startswith('pixel_')] image_data = digit_sample[pixel_columns].values.reshape(8, 8) ax = axes[digit // 5, digit % 5] ax.imshow(image_data, cmap='gray', interpolation='nearest') ax.set_title(f'Цифра: {digit}', fontsize=10, fontweight='bold') ax.set_xticks([]) ax.set_yticks([]) plt.suptitle('Примеры рукописных цифр из датасета', fontsize=14, fontweight='bold') plt.tight_layout() plt.savefig('10_digits_sample_images.png', dpi=300, bbox_inches='tight') plt.show() def pixel_intensity_analysis(df): """Анализ интенсивности пикселей""" fig, axes = plt.subplots(2, 2, figsize=(12, 10)) # Уменьшил размер pixel_columns = [col for col in df.columns if col.startswith('pixel_')] pixel_data = df[pixel_columns] # 1. Гистограмма всех пиксельных значений axes[0, 0].hist(pixel_data.values.flatten(), bins=30, color='lightcoral', alpha=0.7, edgecolor='darkred') axes[0, 0].set_title('Распределение интенсивности пикселей', fontweight='bold') axes[0, 0].set_xlabel('Интенсивность пикселя') axes[0, 0].set_ylabel('Частота') axes[0, 0].grid(alpha=0.3) # 2. Средняя интенсивность по цифрам mean_intensity_by_digit = df.groupby('target')[pixel_columns].mean().mean(axis=1) axes[0, 1].bar(mean_intensity_by_digit.index, mean_intensity_by_digit.values, color='lightgreen', edgecolor='darkgreen') axes[0, 1].set_title('Средняя интенсивность по цифрам', fontweight='bold') axes[0, 1].set_xlabel('Цифра') axes[0, 1].set_ylabel('Средняя интенсивность') axes[0, 1].grid(axis='y', alpha=0.3) # 3. Дисперсия пикселей по цифрам variance_by_digit = df.groupby('target')[pixel_columns].var().mean(axis=1) axes[1, 0].bar(variance_by_digit.index, variance_by_digit.values, color='lightblue', edgecolor='darkblue') axes[1, 0].set_title('Средняя дисперсия по цифрам', fontweight='bold') axes[1, 0].set_xlabel('Цифра') axes[1, 0].set_ylabel('Средняя дисперсия') axes[1, 0].grid(axis='y', alpha=0.3) # 4. Среднее количество ненулевых пикселей - ИСПРАВЛЕННАЯ ЧАСТЬ # Вычисляем количество ненулевых пикселей для каждого изображения df['non_zero_count'] = (df[pixel_columns] > 0).sum(axis=1) non_zero_by_digit = df.groupby('target')['non_zero_count'].mean() axes[1, 1].bar(non_zero_by_digit.index, non_zero_by_digit.values, color='gold', edgecolor='orange') axes[1, 1].set_title('Среднее количество ненулевых пикселей', fontweight='bold') axes[1, 1].set_xlabel('Цифра') axes[1, 1].set_ylabel('Количество ненулевых пикселей') axes[1, 1].grid(axis='y', alpha=0.3) plt.suptitle('Анализ интенсивности и характеристик пикселей', fontsize=14, fontweight='bold') plt.tight_layout() plt.savefig('10_digits_pixel_analysis.png', dpi=300, bbox_inches='tight') plt.show() # Удаляем временный столбец df.drop('non_zero_count', axis=1, inplace=True) def heatmap_mean_images(df): """Тепловые карты средних изображений для каждой цифры""" fig, axes = plt.subplots(2, 5, figsize=(12, 5)) # Уменьшил размер pixel_columns = [col for col in df.columns if col.startswith('pixel_')] # Создаем список для хранения всех изображений images = [] for digit in range(10): # Вычисляем среднее изображение для каждой цифры digit_data = df[df['target'] == digit][pixel_columns] mean_image = digit_data.mean().values.reshape(8, 8) images.append(mean_image) ax = axes[digit // 5, digit % 5] im = ax.imshow(mean_image, cmap='hot', interpolation='nearest') ax.set_title(f'Средняя цифра: {digit}', fontsize=10, fontweight='bold') ax.set_xticks([]) ax.set_yticks([]) # Добавляем ОДНУ общую цветовую шкалу - ИСПРАВЛЕННАЯ ЧАСТЬ plt.tight_layout() cbar = fig.colorbar(im, ax=axes.ravel().tolist(), shrink=0.95, pad=0.05) cbar.set_label('Интенсивность пикселя') plt.suptitle('Тепловые карты средних изображений цифр', fontsize=14, fontweight='bold') plt.savefig('10_digits_mean_heatmaps.png', dpi=300, bbox_inches='tight') plt.show() def main(): """Главная функция""" print("=" * 60) print("ЗАДАНИЕ 10: EXPLORATORY DATA ANALYSIS - DIGITS DATASET") print("=" * 60) df = load_data() print(f"\nДатасет загружен. Размер: {df.shape}") print("\nПервые 5 строк:") print(df.head()) target_analysis(df) feature_statistics(df) visualize_target(df) sample_digit_images(df) pixel_intensity_analysis(df) heatmap_mean_images(df) print("\n" + "=" * 60) print("Анализ завершен!") print("=" * 60) if __name__ == "__main__": main()