test-app-ldat/latency.py

230 lines
9.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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, title="default", delimiter=','):
"""
Универсальный скрипт для построения гистограммы с доверительным интервалом
"""
try:
# Чтение данных
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("АНАЛИЗ ЗАДЕРЖЕК С ДОВЕРИТЕЛЬНЫМ ИНТЕРВАЛОМ")
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('Задержка (мс)')
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.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')
plt.tight_layout()
# Сохранение в файл
if save_to_file:
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,
'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 = 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)
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 = 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,
title=title
)
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% вычисленных таким образом интервалов содержали бы истинное среднее значение.")