Разработка AI-системы детекции стресса/агрессии в голосе клиента

Проектируем и внедряем системы искусственного интеллекта: от прототипа до production-ready решения. Наша команда объединяет экспертизу в машинном обучении, дата-инжиниринге и MLOps, чтобы AI работал не в лаборатории, а в реальном бизнесе.
Показано 1 из 1 услугВсе 1566 услуг
Разработка AI-системы детекции стресса/агрессии в голосе клиента
Сложная
~5 рабочих дней
Часто задаваемые вопросы
Направления AI-разработки
Этапы разработки AI-решения
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1218
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1161
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    853
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1047
  • image_logo-advance_0.png
    Разработка логотипа компании B2B Advance
    561
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    825

Разработка AI-системы детекции стресса/агрессии в голосе клиента

Акустическая детекция стресса и агрессии работает без анализа слов — только по характеристикам голоса: темп речи, частота основного тона (F0), энергия, тремор. Это позволяет реагировать за 2–3 секунды, до того как человек произнесёт угрозу.

Акустические маркеры стресса и агрессии

import librosa
import numpy as np
from dataclasses import dataclass

@dataclass
class EmotionalAcoustics:
    f0_mean: float      # средняя частота (агрессия: рост >20%)
    f0_range: float     # диапазон тона (стресс: сужение)
    f0_std: float       # вариабельность
    speaking_rate: float # темп (стресс: ускорение или замедление)
    energy_mean: float  # громкость (агрессия: значительный рост)
    jitter: float       # тремор голоса (стресс: рост)
    shimmer: float      # неравномерность амплитуды
    hnr: float          # гармоническое отношение (стресс: снижение)

def extract_stress_features(audio: np.ndarray, sr: int = 16000) -> EmotionalAcoustics:
    # Основной тон
    f0, voiced_flag, _ = librosa.pyin(audio, fmin=75, fmax=500, sr=sr)
    f0_voiced = f0[voiced_flag & ~np.isnan(f0)]

    # Энергия
    rms = librosa.feature.rms(y=audio, frame_length=2048, hop_length=512)[0]

    # Spectral features для HNR proxy
    zcr = librosa.feature.zero_crossing_rate(audio)[0]

    return EmotionalAcoustics(
        f0_mean=float(np.mean(f0_voiced)) if len(f0_voiced) > 0 else 0,
        f0_range=float(np.ptp(f0_voiced)) if len(f0_voiced) > 0 else 0,
        f0_std=float(np.std(f0_voiced)) if len(f0_voiced) > 0 else 0,
        speaking_rate=estimate_speaking_rate(audio, sr),
        energy_mean=float(np.mean(rms)),
        jitter=estimate_jitter(f0_voiced),
        shimmer=estimate_shimmer(rms),
        hnr=float(1.0 / (np.mean(zcr) + 1e-8))
    )

Классификатор на ML

from sklearn.ensemble import GradientBoostingClassifier
import joblib

class StressAggressionClassifier:
    LABELS = {0: "neutral", 1: "stressed", 2: "aggressive"}

    def __init__(self, model_path: str):
        self.model = joblib.load(model_path)
        self.baseline = {}  # персональный baseline первых 10 секунд

    def classify(
        self,
        features: EmotionalAcoustics,
        baseline: EmotionalAcoustics = None
    ) -> dict:
        feat_vector = self._to_vector(features)

        if baseline:
            # Нормализуем относительно персонального baseline
            base_vector = self._to_vector(baseline)
            feat_vector = (feat_vector - base_vector) / (base_vector + 1e-8)

        proba = self.model.predict_proba([feat_vector])[0]
        label_id = np.argmax(proba)

        return {
            "label": self.LABELS[label_id],
            "confidence": float(proba[label_id]),
            "probabilities": {self.LABELS[i]: float(p) for i, p in enumerate(proba)}
        }

Обучение на датасете эмоций

Используем RAVDESS (английский) + EMOVO + кастомные записи с разметкой. Для русского — RESD (Russian Emotional Speech Dataset) или собственная разметка.

Производительность после обучения: accuracy ~78–85% на 3 классах (neutral / stressed / aggressive).

Интеграция в поток звонка

CLASSIFICATION_WINDOW_SEC = 3.0  # анализируем каждые 3 секунды

async def continuous_emotion_monitoring(call_id: str, audio_stream):
    classifier = StressAggressionClassifier("models/stress_model.pkl")
    baseline = None
    buffer = bytearray()

    async for chunk in audio_stream:
        buffer.extend(chunk)
        if len(buffer) >= 16000 * CLASSIFICATION_WINDOW_SEC * 2:
            audio = np.frombuffer(buffer, dtype=np.int16).astype(np.float32) / 32768.0
            features = extract_stress_features(audio)

            # Первые 10 сек — устанавливаем baseline
            if baseline is None and len(buffer) < 160000:
                baseline = features
                buffer = bytearray()
                continue

            result = classifier.classify(features, baseline)
            if result["label"] == "aggressive" and result["confidence"] > 0.75:
                await trigger_aggression_alert(call_id, result)

            buffer = bytearray()

Сроки: классификатор на готовом датасете — 2–3 недели. Сбор датасета и обучение с нуля — 2–3 месяца.