added new type of plots; cloud point & overall view
This commit is contained in:
parent
bd7889eed2
commit
5841701bb9
1
.gitignore
vendored
1
.gitignore
vendored
@ -2,3 +2,4 @@
|
||||
.py
|
||||
compile_commands.json
|
||||
build
|
||||
__pycache__
|
||||
68
confidence.py
Normal file
68
confidence.py
Normal file
@ -0,0 +1,68 @@
|
||||
import pandas as pd
|
||||
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 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
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 155 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 167 KiB |
527
delays.csv
527
delays.csv
@ -1,527 +0,0 @@
|
||||
0,40.04
|
||||
1,45.29
|
||||
2,42.51
|
||||
3,47.70
|
||||
4,41.81
|
||||
5,38.94
|
||||
6,47.21
|
||||
7,44.49
|
||||
8,47.85
|
||||
9,37.17
|
||||
10,35.34
|
||||
11,38.51
|
||||
12,45.75
|
||||
13,42.85
|
||||
14,42.02
|
||||
15,45.20
|
||||
16,42.42
|
||||
17,48.65
|
||||
18,39.86
|
||||
19,44.28
|
||||
20,43.61
|
||||
21,36.93
|
||||
22,49.29
|
||||
23,44.65
|
||||
24,38.64
|
||||
25,36.87
|
||||
26,45.01
|
||||
27,36.96
|
||||
28,44.16
|
||||
29,44.49
|
||||
30,48.80
|
||||
31,41.11
|
||||
32,47.27
|
||||
33,48.46
|
||||
34,38.73
|
||||
35,41.96
|
||||
36,43.09
|
||||
37,36.38
|
||||
38,36.53
|
||||
39,38.64
|
||||
40,43.95
|
||||
41,40.16
|
||||
42,43.24
|
||||
43,39.37
|
||||
44,40.53
|
||||
45,39.79
|
||||
46,49.99
|
||||
47,44.13
|
||||
48,40.31
|
||||
49,42.57
|
||||
50,42.79
|
||||
51,39.92
|
||||
52,38.02
|
||||
53,36.32
|
||||
54,38.48
|
||||
55,38.57
|
||||
56,38.88
|
||||
57,40.04
|
||||
58,44.16
|
||||
59,45.56
|
||||
60,46.75
|
||||
61,44.95
|
||||
62,37.17
|
||||
63,46.30
|
||||
64,42.42
|
||||
65,37.72
|
||||
66,44.01
|
||||
67,48.19
|
||||
68,42.42
|
||||
69,38.54
|
||||
70,37.69
|
||||
71,41.90
|
||||
72,39.00
|
||||
73,43.37
|
||||
74,41.60
|
||||
75,39.61
|
||||
76,33.87
|
||||
77,39.98
|
||||
78,42.27
|
||||
79,38.27
|
||||
80,42.36
|
||||
81,40.62
|
||||
82,41.81
|
||||
83,39.83
|
||||
84,41.99
|
||||
85,45.07
|
||||
86,35.16
|
||||
87,49.29
|
||||
88,41.38
|
||||
89,41.60
|
||||
90,43.91
|
||||
91,40.99
|
||||
92,44.19
|
||||
93,42.48
|
||||
94,40.59
|
||||
95,34.79
|
||||
96,40.74
|
||||
97,43.76
|
||||
98,39.89
|
||||
99,40.01
|
||||
100,41.11
|
||||
101,40.22
|
||||
102,46.42
|
||||
103,41.69
|
||||
104,38.91
|
||||
105,34.91
|
||||
106,47.21
|
||||
107,41.38
|
||||
108,42.63
|
||||
109,35.64
|
||||
110,41.78
|
||||
111,35.77
|
||||
112,41.84
|
||||
113,46.02
|
||||
114,41.29
|
||||
115,36.35
|
||||
116,45.59
|
||||
117,42.79
|
||||
118,36.83
|
||||
119,41.11
|
||||
120,39.28
|
||||
121,47.58
|
||||
122,43.98
|
||||
123,44.22
|
||||
124,38.42
|
||||
125,36.62
|
||||
126,41.63
|
||||
127,43.82
|
||||
128,49.10
|
||||
129,36.35
|
||||
130,39.52
|
||||
131,41.60
|
||||
132,40.86
|
||||
133,36.07
|
||||
134,40.16
|
||||
135,43.37
|
||||
136,40.56
|
||||
137,38.54
|
||||
138,35.77
|
||||
139,41.05
|
||||
140,45.38
|
||||
141,43.46
|
||||
142,46.78
|
||||
143,42.02
|
||||
144,45.26
|
||||
145,39.49
|
||||
146,38.67
|
||||
147,39.92
|
||||
148,43.95
|
||||
149,40.04
|
||||
150,43.12
|
||||
151,38.09
|
||||
152,40.41
|
||||
153,35.55
|
||||
154,39.70
|
||||
155,39.83
|
||||
156,46.17
|
||||
157,39.22
|
||||
158,39.52
|
||||
159,37.60
|
||||
160,46.94
|
||||
161,42.94
|
||||
162,41.08
|
||||
163,39.09
|
||||
164,46.33
|
||||
165,41.38
|
||||
166,35.68
|
||||
167,38.85
|
||||
168,36.07
|
||||
169,41.11
|
||||
170,48.40
|
||||
171,41.56
|
||||
172,42.63
|
||||
173,41.87
|
||||
174,40.92
|
||||
175,38.24
|
||||
176,36.29
|
||||
177,47.52
|
||||
178,39.73
|
||||
179,38.76
|
||||
180,36.99
|
||||
181,37.11
|
||||
182,42.14
|
||||
183,40.31
|
||||
184,41.38
|
||||
185,36.56
|
||||
186,45.93
|
||||
187,40.13
|
||||
188,38.48
|
||||
189,39.55
|
||||
190,38.70
|
||||
191,38.94
|
||||
192,39.18
|
||||
193,39.28
|
||||
194,40.50
|
||||
195,41.60
|
||||
196,39.67
|
||||
197,41.72
|
||||
198,39.95
|
||||
199,43.06
|
||||
200,36.10
|
||||
201,35.34
|
||||
202,42.66
|
||||
203,36.99
|
||||
204,36.10
|
||||
205,35.10
|
||||
206,43.15
|
||||
207,35.22
|
||||
208,40.50
|
||||
209,40.71
|
||||
210,37.69
|
||||
211,40.89
|
||||
212,35.86
|
||||
213,42.97
|
||||
214,39.06
|
||||
215,42.33
|
||||
216,41.60
|
||||
217,42.69
|
||||
218,36.71
|
||||
219,42.79
|
||||
220,37.99
|
||||
221,38.06
|
||||
222,51.39
|
||||
223,39.55
|
||||
224,41.60
|
||||
225,35.80
|
||||
226,40.95
|
||||
227,43.30
|
||||
228,44.49
|
||||
229,41.66
|
||||
230,36.71
|
||||
231,48.98
|
||||
232,45.17
|
||||
233,41.44
|
||||
234,34.67
|
||||
235,41.81
|
||||
236,35.83
|
||||
237,43.03
|
||||
238,38.09
|
||||
239,35.34
|
||||
240,42.51
|
||||
241,42.69
|
||||
242,42.76
|
||||
243,50.02
|
||||
244,41.08
|
||||
245,42.45
|
||||
246,41.50
|
||||
247,47.67
|
||||
248,44.95
|
||||
249,41.14
|
||||
250,36.16
|
||||
251,35.28
|
||||
252,43.40
|
||||
253,48.58
|
||||
254,41.72
|
||||
255,40.80
|
||||
256,49.13
|
||||
257,41.38
|
||||
258,35.34
|
||||
259,38.42
|
||||
260,37.41
|
||||
261,37.60
|
||||
262,40.80
|
||||
263,44.89
|
||||
264,38.91
|
||||
265,36.90
|
||||
266,40.13
|
||||
267,43.27
|
||||
268,36.47
|
||||
269,43.55
|
||||
270,38.57
|
||||
271,42.63
|
||||
272,41.69
|
||||
273,48.00
|
||||
274,40.22
|
||||
275,39.43
|
||||
276,40.71
|
||||
277,40.74
|
||||
278,35.86
|
||||
279,38.06
|
||||
280,38.12
|
||||
281,46.26
|
||||
282,39.34
|
||||
283,41.50
|
||||
284,37.66
|
||||
285,37.84
|
||||
286,34.09
|
||||
287,43.15
|
||||
288,43.40
|
||||
289,45.53
|
||||
290,41.78
|
||||
291,42.91
|
||||
292,35.98
|
||||
293,48.07
|
||||
294,38.33
|
||||
295,40.50
|
||||
296,44.56
|
||||
297,42.91
|
||||
298,36.04
|
||||
299,37.23
|
||||
300,40.44
|
||||
301,41.66
|
||||
302,38.85
|
||||
303,42.14
|
||||
304,38.39
|
||||
305,36.62
|
||||
306,41.72
|
||||
307,39.00
|
||||
308,38.18
|
||||
309,43.21
|
||||
310,42.45
|
||||
311,37.69
|
||||
312,46.02
|
||||
313,42.11
|
||||
314,45.20
|
||||
315,43.58
|
||||
316,46.78
|
||||
317,39.03
|
||||
318,38.24
|
||||
319,45.59
|
||||
320,45.84
|
||||
321,45.20
|
||||
322,45.29
|
||||
323,40.41
|
||||
324,44.77
|
||||
325,42.97
|
||||
326,38.06
|
||||
327,39.09
|
||||
328,38.33
|
||||
329,34.58
|
||||
330,39.70
|
||||
331,43.88
|
||||
332,43.09
|
||||
333,38.24
|
||||
334,44.34
|
||||
335,41.56
|
||||
336,48.98
|
||||
337,39.18
|
||||
338,40.37
|
||||
339,39.58
|
||||
340,42.72
|
||||
341,44.10
|
||||
342,44.34
|
||||
343,40.47
|
||||
344,47.70
|
||||
345,37.96
|
||||
346,40.01
|
||||
347,36.19
|
||||
348,38.21
|
||||
349,39.40
|
||||
350,42.45
|
||||
351,45.62
|
||||
352,38.73
|
||||
353,35.95
|
||||
354,37.11
|
||||
355,45.47
|
||||
356,38.73
|
||||
357,47.06
|
||||
358,40.34
|
||||
359,35.58
|
||||
360,40.89
|
||||
361,34.94
|
||||
362,47.24
|
||||
363,42.30
|
||||
364,41.38
|
||||
365,37.63
|
||||
366,47.03
|
||||
367,39.18
|
||||
368,43.55
|
||||
369,37.63
|
||||
370,42.97
|
||||
371,42.24
|
||||
372,45.32
|
||||
373,38.39
|
||||
374,49.50
|
||||
375,39.67
|
||||
376,37.87
|
||||
377,39.06
|
||||
378,44.46
|
||||
379,38.70
|
||||
380,34.88
|
||||
381,38.02
|
||||
382,42.18
|
||||
383,40.47
|
||||
384,52.83
|
||||
385,45.01
|
||||
386,41.08
|
||||
387,50.51
|
||||
388,42.51
|
||||
389,53.71
|
||||
390,44.92
|
||||
391,39.06
|
||||
392,39.37
|
||||
393,44.74
|
||||
394,41.99
|
||||
395,36.16
|
||||
396,41.47
|
||||
397,38.67
|
||||
398,35.71
|
||||
399,46.08
|
||||
400,44.28
|
||||
401,36.25
|
||||
402,39.43
|
||||
403,45.59
|
||||
404,36.59
|
||||
405,39.79
|
||||
406,44.98
|
||||
407,49.13
|
||||
408,41.38
|
||||
409,40.41
|
||||
410,35.71
|
||||
411,44.89
|
||||
412,39.00
|
||||
413,46.11
|
||||
414,43.33
|
||||
415,48.65
|
||||
416,38.73
|
||||
417,38.88
|
||||
418,41.02
|
||||
419,44.25
|
||||
420,51.51
|
||||
421,45.84
|
||||
422,40.07
|
||||
423,44.22
|
||||
424,43.40
|
||||
425,46.75
|
||||
426,37.87
|
||||
427,42.97
|
||||
428,41.17
|
||||
429,38.21
|
||||
430,39.34
|
||||
431,34.33
|
||||
432,43.46
|
||||
433,44.59
|
||||
434,35.68
|
||||
435,39.76
|
||||
436,46.05
|
||||
437,40.34
|
||||
438,46.48
|
||||
439,43.67
|
||||
440,41.90
|
||||
441,53.31
|
||||
442,43.43
|
||||
443,39.46
|
||||
444,36.47
|
||||
445,46.69
|
||||
446,34.88
|
||||
447,41.96
|
||||
448,38.12
|
||||
449,36.38
|
||||
450,40.50
|
||||
451,45.84
|
||||
452,35.98
|
||||
453,38.18
|
||||
454,44.28
|
||||
455,36.29
|
||||
456,37.41
|
||||
457,42.72
|
||||
458,42.91
|
||||
459,43.21
|
||||
460,44.53
|
||||
461,37.51
|
||||
462,39.73
|
||||
463,44.89
|
||||
464,41.11
|
||||
465,43.52
|
||||
466,42.69
|
||||
467,37.90
|
||||
468,38.15
|
||||
469,35.40
|
||||
470,37.57
|
||||
471,44.83
|
||||
472,44.10
|
||||
473,40.44
|
||||
474,44.56
|
||||
475,42.69
|
||||
476,36.80
|
||||
477,39.00
|
||||
478,40.22
|
||||
479,37.32
|
||||
480,40.44
|
||||
481,40.71
|
||||
482,39.92
|
||||
483,45.29
|
||||
484,41.60
|
||||
485,41.66
|
||||
486,42.82
|
||||
487,47.21
|
||||
488,43.49
|
||||
489,47.76
|
||||
490,44.04
|
||||
491,41.29
|
||||
492,37.26
|
||||
493,39.49
|
||||
494,44.80
|
||||
495,39.03
|
||||
496,42.21
|
||||
497,45.59
|
||||
498,46.72
|
||||
499,41.05
|
||||
500,38.24
|
||||
501,40.44
|
||||
502,42.57
|
||||
503,53.38
|
||||
504,67.84
|
||||
505,44.98
|
||||
506,43.06
|
||||
507,43.18
|
||||
508,45.50
|
||||
509,47.88
|
||||
510,36.04
|
||||
511,40.22
|
||||
512,44.62
|
||||
513,43.76
|
||||
514,40.95
|
||||
515,39.15
|
||||
516,39.43
|
||||
517,39.55
|
||||
518,41.75
|
||||
519,48.00
|
||||
520,35.16
|
||||
521,43.52
|
||||
522,39.61
|
||||
523,36.68
|
||||
524,39.79
|
||||
525,51.21
|
||||
526,40.37
|
||||
|
BIN
histogram.png
BIN
histogram.png
Binary file not shown.
|
Before Width: | Height: | Size: 144 KiB |
269
latency.py
269
latency.py
@ -1,225 +1,50 @@
|
||||
import pandas as pd
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
from scipy import stats
|
||||
from latencyPlots import plot_delay_histogram_with_ci, plot_horizontal_hist_with_ci, plot_point_cloud
|
||||
from latencyData import LatencyData
|
||||
from confidence import compare_confidence_intervals
|
||||
import argparse
|
||||
import glob, logging, yaml, os
|
||||
import numpy as np
|
||||
|
||||
logging.basicConfig(level=logging.INFO,
|
||||
format='%(asctime)s - %(levelname)s - %(message)s')
|
||||
|
||||
def parse_args():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('-f', '--file', type=str, help='Path to the file')
|
||||
parser.add_argument('-f', '--file',
|
||||
type=str,
|
||||
help='Path to the csv or yml file, depends on the mode',
|
||||
required=True)
|
||||
parser.add_argument('-m', '--mode',
|
||||
type=int,
|
||||
default=0,
|
||||
help='Mode of the script; 0 - one file, 1 - dir')
|
||||
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__":
|
||||
# Укажите путь к вашему файлу
|
||||
def one_file_run():
|
||||
csv_file = parse_args().file
|
||||
title = csv_file.split('/')[1].split('.')[0]
|
||||
path_splitted = csv_file.split('/')
|
||||
title = path_splitted[len(path_splitted) - 1].split('.')[0]
|
||||
print("АНАЛИЗ ДОВЕРИТЕЛЬНЫХ ИНТЕРВАЛОВ ДЛЯ ЗАДЕРЖЕК")
|
||||
print("=" * 50)
|
||||
l = None
|
||||
try:
|
||||
l = LatencyData(csv_file, confidence_level=0.99)
|
||||
except FileNotFoundError:
|
||||
print(f"✗ Ошибка: Файл '{csv_file}' не найден")
|
||||
exit(1)
|
||||
|
||||
# Основной анализ с 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
|
||||
title=title,
|
||||
l=l
|
||||
)
|
||||
|
||||
print("\n" + "=" * 50)
|
||||
|
||||
# Сравнение разных уровней доверия
|
||||
compare_results = compare_confidence_intervals(
|
||||
csv_file, [0.90, 0.95, 0.99])
|
||||
|
||||
# Интерпретация результатов
|
||||
if results:
|
||||
print("\n--- ИНТЕРПРЕТАЦИЯ РЕЗУЛЬТАТОВ ---")
|
||||
print(f"С вероятностью 95% истинное среднее значение задержки ")
|
||||
@ -227,3 +52,45 @@ if __name__ == "__main__":
|
||||
f"находится в интервале от {results['ci_lower']:.2f} до {results['ci_upper']:.2f} мс.")
|
||||
print(f"Это означает, что если бы мы повторили эксперимент много раз,")
|
||||
print(f"95% вычисленных таким образом интервалов содержали бы истинное среднее значение.")
|
||||
|
||||
def validate_csv_list(csv_arr: list, dirConfig: dict) -> bool:
|
||||
is_colors_valid = all(file in dirConfig['colors'].keys() for file in csv_arr)
|
||||
is_labels_valid = all(file in dirConfig['labels'].keys() for file in csv_arr)
|
||||
if not is_labels_valid:
|
||||
logging.error("Labels in yaml is not fully valid")
|
||||
if not is_colors_valid:
|
||||
logging.error("Colors in yaml is not fully valid")
|
||||
return is_colors_valid & is_labels_valid
|
||||
|
||||
def dir_run():
|
||||
dirConfig = None
|
||||
with open(parse_args().file + '/dir.yml') as f:
|
||||
dirConfig = yaml.safe_load(f)
|
||||
if dirConfig is None:
|
||||
raise Exception("File not found or not loaded")
|
||||
|
||||
title = parse_args().file.split('/')[1]
|
||||
all_csv_in_dir = glob.glob(parse_args().file + '/*.csv')
|
||||
logging.info(f"Found {len(all_csv_in_dir)} csv files in directory {parse_args().file}")
|
||||
lDataArr = {os.path.basename(file): LatencyData(file) for file in all_csv_in_dir}
|
||||
|
||||
validate_csv_list([os.path.basename(file) for file in all_csv_in_dir], dirConfig)
|
||||
plot_point_cloud(lDataArr,
|
||||
dirConfig['colors'],
|
||||
dirConfig['labels'],
|
||||
float(dirConfig['point_cloud']['dT']),
|
||||
title=title)
|
||||
|
||||
plot_horizontal_hist_with_ci(lDataArr,
|
||||
dirConfig['colors'],
|
||||
dirConfig['labels'],
|
||||
title=title)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
args = parse_args()
|
||||
mode = args.mode
|
||||
if mode == 0:
|
||||
one_file_run()
|
||||
elif mode == 1:
|
||||
dir_run()
|
||||
59
latencyData.py
Normal file
59
latencyData.py
Normal file
@ -0,0 +1,59 @@
|
||||
import pandas as pd
|
||||
import numpy as np
|
||||
from confidence import calculate_confidence_interval
|
||||
|
||||
class LatencyData:
|
||||
def __init__(self, filepath, delimiter=',', confidence_level=0.99):
|
||||
self.df = pd.read_csv(filepath, delimiter=delimiter, header=None,
|
||||
names=['index', 'delay_ms'])
|
||||
self.__parse(confidence_level)
|
||||
|
||||
def __parse(self, confidence_level):
|
||||
self.delays = np.array(self.df['delay_ms'].values)
|
||||
self.confidence_level = confidence_level
|
||||
# Вычисление базовой статистики
|
||||
self.mean_delay = np.mean(self.delays)
|
||||
self.median_delay = np.median(self.delays)
|
||||
self.std_delay = np.std(self.delays)
|
||||
self.min_delay = np.min(self.delays)
|
||||
self.max_delay = np.max(self.delays)
|
||||
|
||||
# Вычисление доверительного интервала
|
||||
self.mean_ci, self.ci_lower, self.ci_upper, self.std_error = calculate_confidence_interval(
|
||||
self.delays, confidence_level)
|
||||
|
||||
self.__output_data()
|
||||
|
||||
@property
|
||||
def err(self):
|
||||
return (self.ci_upper - self.ci_lower)/2
|
||||
|
||||
def __output_data(self):
|
||||
# Вывод статистики
|
||||
print("=" * 60)
|
||||
print("АНАЛИЗ ЗАДЕРЖЕК С ДОВЕРИТЕЛЬНЫМ ИНТЕРВАЛОМ")
|
||||
print("=" * 60)
|
||||
print(f"Количество измерений (n): {len(self.delays)}")
|
||||
print(f"Уровень доверия: {self.confidence_level*100}%")
|
||||
print("\n--- ОСНОВНАЯ СТАТИСТИКА ---")
|
||||
print(f"Минимальная задержка: {self.min_delay:.2f} мс")
|
||||
print(f"Максимальная задержка: {self.max_delay:.2f} мс")
|
||||
print(f"Средняя задержка: {self.mean_delay:.2f} мс")
|
||||
print(f"Медианная задержка: {self.median_delay:.2f} мс")
|
||||
print(f"Стандартное отклонение: {self.std_delay:.2f} мс")
|
||||
print(f"Стандартная ошибка: {self.std_error:.4f} мс")
|
||||
|
||||
print(f"\n--- ДОВЕРИТЕЛЬНЫЙ ИНТЕРВАЛ {self.confidence_level*100}% ---")
|
||||
print(f"Точечная оценка среднего: {self.mean_ci:.2f} мс")
|
||||
print(f"Доверительный интервал: [{self.ci_lower:.2f}, {self.ci_upper:.2f}] мс")
|
||||
print(f"Ширина интервала: {self.ci_upper - self.ci_lower:.2f} мс")
|
||||
print(f"Погрешность: ±{(self.ci_upper - self.ci_lower)/2:.2f} мс")
|
||||
|
||||
# Дополнительные метрики
|
||||
cv = (self.std_delay / self.mean_delay) * 100 # Коэффициент вариации
|
||||
print(f"\n--- ДОПОЛНИТЕЛЬНЫЕ МЕТРИКИ ---")
|
||||
print(f"Коэффициент вариации: {cv:.1f}%")
|
||||
print(f"Q1 (25-й перцентиль): {np.percentile(self.delays, 25):.2f} мс")
|
||||
print(f"Q3 (75-й перцентиль): {np.percentile(self.delays, 75):.2f} мс")
|
||||
print(
|
||||
f"IQR (межквартильный размах): {np.percentile(self.delays, 75) - np.percentile(self.delays, 25):.2f} мс")
|
||||
182
latencyPlots.py
Normal file
182
latencyPlots.py
Normal file
@ -0,0 +1,182 @@
|
||||
import matplotlib.pyplot as plt
|
||||
from latencyData import LatencyData
|
||||
import logging
|
||||
|
||||
def plot_delay_histogram_with_ci(l : LatencyData, save_to_file=True, show_plot=False, title="default"):
|
||||
"""
|
||||
Универсальный скрипт для построения гистограммы с доверительным интервалом
|
||||
"""
|
||||
try:
|
||||
plt.rcParams.update({'font.size': 18})
|
||||
# Создание гистограммы
|
||||
plt.figure(figsize=(14, 8))
|
||||
n_bins = min(30, len(l.delays) // 5)
|
||||
|
||||
n, bins, patches = plt.hist(l.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(l.delays)}, CI={l.confidence_level*100}%)',
|
||||
fontsize=14, fontweight='bold')
|
||||
plt.grid(True, alpha=0.3)
|
||||
|
||||
l.mean_delay = float(l.mean_delay)
|
||||
l.median_delay = float(l.median_delay)
|
||||
# Добавление статистических линий
|
||||
plt.axvline(l.mean_delay, color='red', linestyle='-', linewidth=2,
|
||||
label=f'Среднее ({l.mean_delay:.1f} мс)')
|
||||
plt.axvline(l.median_delay, color='green', linestyle='-', linewidth=2,
|
||||
label=f'Медиана ({l.median_delay:.1f} мс)')
|
||||
|
||||
# Добавление доверительного интервала
|
||||
plt.axvspan(l.ci_lower, l.ci_upper, alpha=0.2, color='yellow',
|
||||
label=f'ДИ {l.confidence_level*100}%: [{l.ci_lower:.1f}, {l.ci_upper:.1f}] мс')
|
||||
|
||||
# Вертикальные линии для границ доверительного интервала
|
||||
plt.axvline(l.ci_lower, color='orange',
|
||||
linestyle='--', linewidth=1, alpha=0.7)
|
||||
plt.axvline(l.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(l.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': l.delays,
|
||||
'mean': l.mean_delay,
|
||||
'median': l.median_delay,
|
||||
'std': l.std_delay,
|
||||
'ci_lower': l.ci_lower,
|
||||
'ci_upper': l.ci_upper,
|
||||
'confidence_level': l.confidence_level
|
||||
}
|
||||
except Exception as e:
|
||||
print(f"✗ Ошибка: {e}")
|
||||
return None
|
||||
|
||||
def plot_horizontal_hist_with_ci(latencies : dict, colors: dict, labels: dict, save_to_file=True, show_plot=True, title="default"):
|
||||
"""
|
||||
Parameters
|
||||
----------
|
||||
latencies: dict
|
||||
key is a filename, value is a latencyData object
|
||||
|
||||
colors: dict
|
||||
key is a filename, value is string in format tab:<color>
|
||||
|
||||
labels: dict
|
||||
key is a filename, value is a string label
|
||||
|
||||
"""
|
||||
plt.rcParams.update({'font.size': 14})
|
||||
# Создание гистограммы
|
||||
fig, ax = plt.subplots(figsize=(12,6))
|
||||
|
||||
keys = latencies.keys()
|
||||
values = latencies.values()
|
||||
|
||||
medians = [i.mean_delay for i in values]
|
||||
errors = [i.err for i in values]
|
||||
y_idx = range(len(keys))
|
||||
logging.info(f"medians={medians}; errors={errors}")
|
||||
# sorting of all arrays to have same order of elements
|
||||
bar_colors = [colors[key] for key in keys]
|
||||
bar_labels = [labels[key] for key in keys]
|
||||
|
||||
ax.barh(y_idx, medians, xerr=errors, color=bar_colors, capsize=15, align='center')
|
||||
|
||||
logging.info(f"y_idx={y_idx}; bar_labels={bar_labels}")
|
||||
ax.set_yticks(y_idx, bar_labels)
|
||||
ax.set_xlabel('Задержка (мс)')
|
||||
fig.tight_layout()
|
||||
|
||||
if show_plot:
|
||||
plt.show()
|
||||
else:
|
||||
plt.close()
|
||||
|
||||
if save_to_file:
|
||||
fig.savefig(f'delay_dist_overall_{title}')
|
||||
|
||||
|
||||
def plot_point_cloud(latencies : dict,
|
||||
colors: dict,
|
||||
labels: dict,
|
||||
dT : float,
|
||||
hlines = dict,
|
||||
save_to_file=True,
|
||||
show_plot=True,
|
||||
title="default"):
|
||||
"""
|
||||
Parameters
|
||||
----------
|
||||
latencies: dict
|
||||
key is a filename, value is a latencyData object
|
||||
|
||||
colors: dict
|
||||
key is a filename, value is string in format tab:<color>
|
||||
|
||||
labels: dict
|
||||
key is a filename, value is a string label
|
||||
|
||||
"""
|
||||
|
||||
plt.rcParams.update({'font.size': 14})
|
||||
# Создание гистограммы
|
||||
fig, ax = plt.subplots(figsize=(10,8))
|
||||
|
||||
keys = latencies.keys()
|
||||
values = latencies.values()
|
||||
|
||||
medians = [i.mean_delay for i in values]
|
||||
|
||||
# sorting of all arrays to have same order of elements
|
||||
point_labels = [labels[key] for key in keys]
|
||||
point_colors = [colors[key] for key in keys]
|
||||
point_xminall = min(len(value.delays) for value in values)
|
||||
point_values = [value.delays[:point_xminall] for value in values]
|
||||
point_x = list(range(point_xminall))
|
||||
point_x = [float(x) * dT for x in point_x]
|
||||
point_ld = [value for value in values]
|
||||
for i in range(len(point_values)):
|
||||
ax.plot(point_x,
|
||||
point_values[i],
|
||||
color=point_colors[i],
|
||||
label=point_labels[i],
|
||||
marker='o',
|
||||
linestyle='None')
|
||||
ax.axhline(y=medians[i],
|
||||
color=point_colors[i],
|
||||
linestyle='--')
|
||||
ax.axhspan(point_ld[i].ci_lower,
|
||||
point_ld[i].ci_upper,
|
||||
alpha=0.2,
|
||||
color=point_colors[i])
|
||||
ax.legend(ncol=3,bbox_to_anchor=(0.75, 1.1), fancybox=True)
|
||||
ax.set_xlabel('Время (секунды)')
|
||||
ax.set_ylabel('Задержка (мс)')
|
||||
|
||||
fig.tight_layout()
|
||||
|
||||
if show_plot:
|
||||
plt.show()
|
||||
else:
|
||||
plt.close()
|
||||
|
||||
if save_to_file:
|
||||
fig.savefig(f'delay_dist_cloud_{title}')
|
||||
19
shit.py
19
shit.py
@ -10,6 +10,25 @@ import matplotlib.pyplot as plt
|
||||
logging.basicConfig(level=logging.INFO,
|
||||
format='%(asctime)s - %(levelname)s - %(message)s')
|
||||
|
||||
def mix_csv_column_pandas(filename, index_col=0, value_col=1):
|
||||
"""
|
||||
Read a CSV file, mix up values in the specified column, and overwrite the file using pandas.
|
||||
|
||||
Args:
|
||||
filename (str): Path to the CSV file
|
||||
index_col (int): Column index for identifiers (default: 0)
|
||||
value_col (int): Column index for values to mix (default: 1)
|
||||
"""
|
||||
# Read CSV
|
||||
df = pd.read_csv(filename, header=None)
|
||||
|
||||
# Mix values in the specified column
|
||||
mixed_values = df[value_col].sample(frac=1).reset_index(drop=True)
|
||||
df[value_col] = mixed_values
|
||||
|
||||
# Save back to same file
|
||||
df.to_csv(filename, index=False, header=False)
|
||||
|
||||
class Interpol:
|
||||
"""
|
||||
Huhu, interpol
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user