diff --git a/latency.py b/latency.py index 49e8785..c834b73 100644 --- a/latency.py +++ b/latency.py @@ -2,50 +2,60 @@ import pandas as pd import matplotlib.pyplot as plt import numpy as np from scipy import stats +import argparse + + +def parse_args(): + parser = argparse.ArgumentParser() + parser.add_argument('-f', '--file', type=str, help='Path to the file') + return parser.parse_args() + 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=','): + +def plot_delay_histogram_with_ci(csv_file_path, save_to_file=True, show_plot=False, + confidence_level=0.99, title="default", delimiter=','): """ Универсальный скрипт для построения гистограммы с доверительным интервалом """ - + try: # Чтение данных - df = pd.read_csv(csv_file_path, delimiter=delimiter, header=None, - names=['index', 'delay_ms']) - delays = df['delay_ms'].values - + df = pd.read_csv(csv_file_path, delimiter=delimiter, header=None, + names=['index', 'delay_ms']) + delays = np.array(df['delay_ms'].values) + plt.rcParams.update({'font.size': 18}) + # Вычисление базовой статистики 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("АНАЛИЗ ЗАДЕРЖЕК С ДОВЕРИТЕЛЬНЫМ ИНТЕРВАЛОМ") @@ -59,66 +69,71 @@ def plot_delay_histogram_with_ci(csv_file_path, save_to_file=True, show_plot=Fal 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} мс") - + 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') + n, bins, patches = plt.hist(delays, bins=n_bins, alpha=0.7, color='steelblue', + edgecolor='black', linewidth=0.5, density=False) + + plt.xlabel('Задержка (мс)') + plt.ylabel('Частота') + plt.title(f'Распределение задержек на обработку нажатия мыши {title} (n={len(delays)}, CI={confidence_level*100}%)', + fontsize=14, fontweight='bold') plt.grid(True, alpha=0.3) - + + mean_delay = float(mean_delay) + median_delay = float(median_delay) # Добавление статистических линий - 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.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.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.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') plt.tight_layout() - + # Сохранение в файл if save_to_file: - output_file = f'delay_distribution_ci_{int(confidence_level*100)}.png' + output_file = f'delay_distribution_{title}_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, @@ -128,7 +143,7 @@ def plot_delay_histogram_with_ci(csv_file_path, save_to_file=True, show_plot=Fal 'ci_upper': ci_upper, 'confidence_level': confidence_level } - + except FileNotFoundError: print(f"✗ Ошибка: Файл '{csv_file_path}' не найден") return None @@ -136,28 +151,30 @@ def plot_delay_histogram_with_ci(csv_file_path, save_to_file=True, show_plot=Fal 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 - + df = pd.read_csv(csv_file_path, delimiter=delimiter, header=None, + names=['index', 'delay_ms']) + delays = np.array(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) + 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, @@ -166,43 +183,47 @@ def compare_confidence_intervals(csv_file_path, confidence_levels=[0.90, 0.95, 0 '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" - + csv_file = parse_args().file + title = csv_file.split('/')[1].split('.')[0] 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 + confidence_level=0.99, + title=title ) - + print("\n" + "=" * 50) - + # Сравнение разных уровней доверия - compare_results = compare_confidence_intervals(csv_file, [0.90, 0.95, 0.99]) - + 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"находится в интервале от {results['ci_lower']:.2f} до {results['ci_upper']:.2f} мс.") print(f"Это означает, что если бы мы повторили эксперимент много раз,") - print(f"95% вычисленных таким образом интервалов содержали бы истинное среднее значение.") \ No newline at end of file + print(f"95% вычисленных таким образом интервалов содержали бы истинное среднее значение.")