Время речи каждого говорящего: как посчитать интервалы CSV без двойного счёта
Сумма и объединение временных интервалов одного говорящего через Python. Проверка start и end, перекрытий и ограничений оценки времени речи.
Сначала определите, что считается речью
По тексту с одним стартовым таймкодом нельзя точно определить длительность реплики. Следующая метка может включать паузу, а начало другого говорящего не всегда означает конец первого. Для расчёта нужны проверенные начало и конец каждого отрезка и правила включения пауз.
В этой статье start и end — секунды от начала одной записи. Поле speaker обозначает подтверждённую метку человека. Если ваш CSV содержит только text и timecode, сначала подготовьте интервальную разметку по аудио. Не утверждайте, что сервис автоматически выдал точные границы, если такой результат не проверен. Текстовую основу можно получить через Транскрибатор.
Различайте сумму и объединённую длительность
У одного говорящего отрезки 0–5 и 4–8 секунд имеют сумму 9 секунд, но покрывают 8 секунд записи. Общая часть 4–5 не должна считаться дважды. Отрезок 10–12 добавляет ещё 2: итог объединения равен 10 секундам, простая сумма — 11.
Если говорят два человека одновременно, этот момент входит во время обоих. Сумма длительностей людей может быть больше длительности аудио. Это не обязательно ошибка. Не превращайте долю времени в оценку участия или качества ответа: короткая реплика может содержать ключевое решение, а длинный отрезок — чтение документа.
Посчитайте оба показателя и сохраните проверку
Подготовьте speech-intervals.csv с колонками speaker,start,end. В учебной схеме используется десятичная точка: 12.5, а не строка 00:12,500. Сохраните код как speaker_time.py и выполните python speaker_time.py. Результат speaker-duration.csv создаётся в режиме x.
Код запрещает отрицательное начало, конец не позже начала, пустую метку и бесконечные значения. Сначала сортируются интервалы каждого говорящего; соприкасающиеся и перекрывающиеся объединяются. Округление происходит только при записи итогов до трёх знаков. Все группы хранятся в памяти.
import csv, math
from pathlib import Path
from collections import defaultdict
groups = defaultdict(list)
with Path("speech-intervals.csv").open(encoding="utf-8-sig", newline="") as file:
reader = csv.DictReader(file)
fields = reader.fieldnames or []
if not {"speaker", "start", "end"} <= set(fields) or len(fields) != len(set(fields)):
raise ValueError("Проверьте колонки")
for row in reader:
if None in row or any(v is None for v in row.values()):
raise ValueError("Неполные записи или лишние поля")
speaker = row["speaker"]
a, b = float(row["start"]), float(row["end"])
if not speaker.strip() or not all(map(math.isfinite, (a,b))) or not 0 <= a < b:
raise ValueError("Неверный говорящий или интервал")
groups[speaker].append((a,b))
def union_duration(intervals):
merged = []
for a,b in sorted(intervals):
if merged and a <= merged[-1][1]:
merged[-1][1] = max(merged[-1][1], b)
else:
merged.append([a,b])
return sum(b-a for a,b in merged)
with Path("speaker-duration.csv").open("x", encoding="utf-8-sig", newline="") as file:
writer = csv.writer(file)
writer.writerow(["speaker", "intervals", "sum_seconds", "union_seconds"])
for speaker, intervals in groups.items():
writer.writerow([speaker, len(intervals), round(sum(b-a for a,b in intervals), 3),
round(union_duration(intervals), 3)])
print("Результат описывает размеченные интервалы, не важность выступлений")
Проверьте расхождения по аудио
Сравните sum_seconds и union_seconds. Большое расхождение у одного человека — повод изучить дубли интервалов, неверное имя или перекрывающуюся разметку. Совпадение показателей не подтверждает точность границ. Прослушайте начало, конец и спорные смены говорящих, а также проверьте, что end не выходит за фактический конец источника.
Для таблицы с разными интервью сначала выполните разделение по источнику. Числа секунд разных записей не принадлежат одному таймлайну. При ошибках колонок поможет проверка CSV.
В отчёте укажите, включены ли паузы внутри реплики, как обработана неразборчивая речь и кто проверял метки. Алгоритм не выделяет речь из аудио, не определяет личность и не исправляет диаризацию. Он лишь считает уже заданные интервалы по явному правилу.
Учебный расчёт для одного говорящего
Вымышленные интервалы используют общий отсчёт одной записи.
| Интервалы | Простая сумма | Объединение |
|---|---|---|
| 0–5 и 4–8 | 9 с | 8 с |
| Плюс 10–12 | 11 с | 10 с |
| Другой говорящий 4–6 | Считается отдельно | Перекрытие людей допустимо |
Все числа учебные. При неизвестных границах не подставляйте предполагаемую длительность как измеренный результат.
Паспорт расчёта времени речи
Аудиофайл: [источник] CSV и версия: [имя] Единицы: секунды Правило пауз: [описание] Метки людей: [проверка] Выход за конец записи: [проверка] Сумма и объединение: [расхождения] Спорные границы: [таймкоды] Ограничения результата: [описание]
Частые вопросы
Достаточно стартовых таймкодов?
Нет. Нужны проверенные начало и конец каждого учитываемого интервала.
Почему время всех людей больше записи?
При одновременной речи один участок может входить во время нескольких людей.
Объединение исправляет диаризацию?
Нет. Оно считает интервалы внутри предоставленных меток.
Длиннее говорил — лучше участвовал?
Такого вывода длительность сама по себе не позволяет.