import pandas as pd import matplotlib.pyplot as plt import numpy as np from scipy import stats def calculate_confidence_interval(data, confidence=0.95): """ Вычисление доверительного интервала для среднего значения Parameters: data: массив данных confidence: уровень доверия (по умолчанию 95%) Returns: tuple: (среднее, нижняя граница, верхняя граница, стандартная ошибка) """ n = len(data) mean = np.mean(data) std_error = stats.sem(data) # Стандартная ошибка среднего # Вычисление доверительного интервала с использованием t-распределения ci = stats.t.interval(confidence, n-1, loc=mean, scale=std_error) return mean, ci[0], ci[1], std_error def plot_delay_histogram_with_ci(csv_file_path, save_to_file=True, show_plot=False, confidence_level=0.99, delimiter=','): """ Универсальный скрипт для построения гистограммы с доверительным интервалом """ try: # Чтение данных df = pd.read_csv(csv_file_path, delimiter=delimiter, header=None, names=['index', 'delay_ms']) delays = df['delay_ms'].values # Вычисление базовой статистики mean_delay = np.mean(delays) median_delay = np.median(delays) std_delay = np.std(delays) min_delay = np.min(delays) max_delay = np.max(delays) # Вычисление доверительного интервала mean_ci, ci_lower, ci_upper, std_error = calculate_confidence_interval( delays, confidence_level) # Вывод статистики print("=" * 60) print("АНАЛИЗ ЗАДЕРЖЕК С ДОВЕРИТЕЛЬНЫМ ИНТЕРВАЛОМ") print("=" * 60) print(f"Количество измерений (n): {len(delays)}") print(f"Уровень доверия: {confidence_level*100}%") print("\n--- ОСНОВНАЯ СТАТИСТИКА ---") print(f"Минимальная задержка: {min_delay:.2f} мс") print(f"Максимальная задержка: {max_delay:.2f} мс") print(f"Средняя задержка: {mean_delay:.2f} мс") print(f"Медианная задержка: {median_delay:.2f} мс") print(f"Стандартное отклонение: {std_delay:.2f} мс") print(f"Стандартная ошибка: {std_error:.4f} мс") print(f"\n--- ДОВЕРИТЕЛЬНЫЙ ИНТЕРВАЛ {confidence_level*100}% ---") print(f"Точечная оценка среднего: {mean_ci:.2f} мс") print(f"Доверительный интервал: [{ci_lower:.2f}, {ci_upper:.2f}] мс") print(f"Ширина интервала: {ci_upper - ci_lower:.2f} мс") print(f"Погрешность: ±{(ci_upper - ci_lower)/2:.2f} мс") # Дополнительные метрики cv = (std_delay / mean_delay) * 100 # Коэффициент вариации print(f"\n--- ДОПОЛНИТЕЛЬНЫЕ МЕТРИКИ ---") print(f"Коэффициент вариации: {cv:.1f}%") print(f"Q1 (25-й перцентиль): {np.percentile(delays, 25):.2f} мс") print(f"Q3 (75-й перцентиль): {np.percentile(delays, 75):.2f} мс") print(f"IQR (межквартильный размах): {np.percentile(delays, 75) - np.percentile(delays, 25):.2f} мс") # Создание гистограммы plt.figure(figsize=(14, 8)) n_bins = min(30, len(delays) // 5) # Гистограмма n, bins, patches = plt.hist(delays, bins=n_bins, alpha=0.7, color='steelblue', edgecolor='black', linewidth=0.5, density=False) plt.xlabel('Задержка (мс)', fontsize=12) plt.ylabel('Частота', fontsize=12) plt.title(f'Распределение задержек на обработку нажатия мыши (n={len(delays)}, CI={confidence_level*100}%)', fontsize=14, fontweight='bold') plt.grid(True, alpha=0.3) # Добавление статистических линий plt.axvline(mean_delay, color='red', linestyle='-', linewidth=2, label=f'Среднее ({mean_delay:.1f} мс)') plt.axvline(median_delay, color='green', linestyle='-', linewidth=2, label=f'Медиана ({median_delay:.1f} мс)') # Добавление доверительного интервала plt.axvspan(ci_lower, ci_upper, alpha=0.2, color='yellow', label=f'ДИ {confidence_level*100}%: [{ci_lower:.1f}, {ci_upper:.1f}] мс') # Вертикальные линии для границ доверительного интервала plt.axvline(ci_lower, color='orange', linestyle='--', linewidth=1, alpha=0.7) plt.axvline(ci_upper, color='orange', linestyle='--', linewidth=1, alpha=0.7) plt.legend(loc='upper right', fontsize=10) plt.tight_layout() # Сохранение в файл if save_to_file: output_file = f'delay_distribution_ci_{int(confidence_level*100)}.png' plt.savefig(output_file, dpi=300, bbox_inches='tight') print(f"\n✓ Гистограмма сохранена как: {output_file}") # Показ графика if show_plot: plt.show() else: plt.close() print("\n✓ Анализ завершен успешно") return { 'data': delays, 'mean': mean_delay, 'median': median_delay, 'std': std_delay, 'ci_lower': ci_lower, 'ci_upper': ci_upper, 'confidence_level': confidence_level } except FileNotFoundError: print(f"✗ Ошибка: Файл '{csv_file_path}' не найден") return None except Exception as e: print(f"✗ Ошибка: {e}") return None def compare_confidence_intervals(csv_file_path, confidence_levels=[0.90, 0.95, 0.99], delimiter=','): """ Сравнение доверительных интервалов для разных уровней доверия """ try: df = pd.read_csv(csv_file_path, delimiter=delimiter, header=None, names=['index', 'delay_ms']) delays = df['delay_ms'].values print("=" * 70) print("СРАВНЕНИЕ ДОВЕРИТЕЛЬНЫХ ИНТЕРВАЛОВ ДЛЯ РАЗНЫХ УРОВНЕЙ ДОВЕРИЯ") print("=" * 70) print(f"Количество измерений: {len(delays)}") print(f"Среднее значение: {np.mean(delays):.2f} мс") print(f"Стандартная ошибка: {stats.sem(delays):.4f} мс\n") results = [] for conf in confidence_levels: mean, ci_lower, ci_upper, std_error = calculate_confidence_interval(delays, conf) width = ci_upper - ci_lower margin = width / 2 results.append({ 'confidence': conf, 'mean': mean, 'ci_lower': ci_lower, 'ci_upper': ci_upper, 'width': width, 'margin': margin }) print(f"Доверительный интервал {conf*100:.0f}%:") print(f" [{ci_lower:.2f}, {ci_upper:.2f}] мс") print(f" Ширина: {width:.2f} мс, Погрешность: ±{margin:.2f} мс") print() return results except Exception as e: print(f"Ошибка при сравнении интервалов: {e}") return None # Пример использования if __name__ == "__main__": # Укажите путь к вашему файлу csv_file = "delays.csv" print("АНАЛИЗ ДОВЕРИТЕЛЬНЫХ ИНТЕРВАЛОВ ДЛЯ ЗАДЕРЖЕК") print("=" * 50) # Основной анализ с 95% доверительным интервалом results = plot_delay_histogram_with_ci( csv_file_path=csv_file, save_to_file=True, show_plot=False, confidence_level=0.99 ) print("\n" + "=" * 50) # Сравнение разных уровней доверия compare_results = compare_confidence_intervals(csv_file, [0.90, 0.95, 0.99]) # Интерпретация результатов if results: print("\n--- ИНТЕРПРЕТАЦИЯ РЕЗУЛЬТАТОВ ---") print(f"С вероятностью 95% истинное среднее значение задержки ") print(f"находится в интервале от {results['ci_lower']:.2f} до {results['ci_upper']:.2f} мс.") print(f"Это означает, что если бы мы повторили эксперимент много раз,") print(f"95% вычисленных таким образом интервалов содержали бы истинное среднее значение.")