Agent Skillsbenchflow-ai/skillsbench › Speaker Clustering Methods

Speaker Clustering Methods

GitHub

用于在VAD和嵌入提取后对说话人嵌入进行聚类,以识别唯一说话人。提供层次、KMeans和凝聚三种方法,支持自动或手动确定说话人数,强调聚类前需归一化嵌入。

tasks-extra/speaker-diarization-subtitles/environment/skills/speaker-clustering/SKILL.md benchflow-ai/skillsbench

Trigger Scenarios

从VAD片段提取说话人嵌入后 需要将相似说话人分组时 需要自动或手动确定说话人数量时

Install

npx skills add benchflow-ai/skillsbench --skill Speaker Clustering Methods -g -y
More Options

Non-standard path

npx skills add https://github.com/benchflow-ai/skillsbench/tree/main/tasks-extra/speaker-diarization-subtitles/environment/skills/speaker-clustering -g -y

Use without installing

npx skills use benchflow-ai/skillsbench@Speaker Clustering Methods

指定 Agent (Claude Code)

npx skills add benchflow-ai/skillsbench --skill Speaker Clustering Methods -a claude-code -g -y

安装 repo 全部 skill

npx skills add benchflow-ai/skillsbench --all -g -y

预览 repo 内 skill

npx skills add benchflow-ai/skillsbench --list

SKILL.md

Frontmatter
{
    "name": "Speaker Clustering Methods",
    "description": "Choose and implement clustering algorithms for grouping speaker embeddings after VAD and embedding extraction. Compare Hierarchical clustering (auto-tunes speaker count), KMeans (fast, requires known count), and Agglomerative clustering (fixed clusters). Use Hierarchical clustering when speaker count is unknown, KMeans when count is known, and always normalize embeddings before clustering."
}

Speaker Clustering Methods

Overview

After extracting speaker embeddings from audio segments, you need to cluster them to identify unique speakers. Different clustering methods have different strengths.

When to Use

  • After extracting speaker embeddings from VAD segments
  • Need to group similar speakers together
  • Determining number of speakers automatically or manually

Available Clustering Methods

1. Hierarchical Clustering (Recommended for Auto-tuning)

Best for: Automatically determining number of speakers, flexible threshold tuning

from scipy.cluster.hierarchy import linkage, fcluster
from scipy.spatial.distance import pdist
import numpy as np

# Prepare embeddings
embeddings_array = np.array(embeddings_list)
n_segments = len(embeddings_array)

# Compute distance matrix
distances = pdist(embeddings_array, metric='cosine')

# Create linkage matrix
linkage_matrix = linkage(distances, method='average')

# Auto-tune threshold to get reasonable speaker count
min_speakers = 2
max_speakers = max(2, min(10, n_segments // 2))

threshold = 0.7
labels = fcluster(linkage_matrix, t=threshold, criterion='distance')
n_speakers = len(set(labels))

# Adjust threshold if needed
if n_speakers > max_speakers:
    for t in [0.8, 0.9, 1.0, 1.1, 1.2]:
        labels = fcluster(linkage_matrix, t=t, criterion='distance')
        n_speakers = len(set(labels))
        if n_speakers <= max_speakers:
            threshold = t
            break
elif n_speakers < min_speakers:
    for t in [0.6, 0.5, 0.4]:
        labels = fcluster(linkage_matrix, t=t, criterion='distance')
        n_speakers = len(set(labels))
        if n_speakers >= min_speakers:
            threshold = t
            break

print(f"Selected: t={threshold}, {n_speakers} speakers")

Advantages:

  • Automatically determines speaker count
  • Flexible threshold tuning
  • Good for unknown number of speakers
  • Can visualize dendrogram

2. KMeans Clustering

Best for: Known number of speakers, fast clustering

from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score
import numpy as np

# Normalize embeddings
embeddings_array = np.array(embeddings_list)
norms = np.linalg.norm(embeddings_array, axis=1, keepdims=True)
embeddings_normalized = embeddings_array / np.clip(norms, 1e-9, None)

# Try different k values and choose best
best_k = 2
best_score = -1
best_labels = None

for k in range(2, min(7, len(embeddings_normalized))):
    kmeans = KMeans(n_clusters=k, random_state=0, n_init=10)
    labels = kmeans.fit_predict(embeddings_normalized)

    if len(set(labels)) < 2:
        continue

    score = silhouette_score(embeddings_normalized, labels, metric='cosine')
    if score > best_score:
        best_score = score
        best_k = k
        best_labels = labels

print(f"Best k={best_k}, silhouette score={best_score:.3f}")

Advantages:

  • Fast and efficient
  • Works well with known speaker count
  • Simple to implement

Disadvantages:

  • Requires specifying number of clusters
  • May get stuck in local minima

3. Agglomerative Clustering

Best for: Similar to hierarchical but with fixed number of clusters

from sklearn.cluster import AgglomerativeClustering
from sklearn.metrics import silhouette_score
import numpy as np

# Normalize embeddings
embeddings_array = np.array(embeddings_list)
norms = np.linalg.norm(embeddings_array, axis=1, keepdims=True)
embeddings_normalized = embeddings_array / np.clip(norms, 1e-9, None)

# Try different numbers of clusters
best_n = 2
best_score = -1
best_labels = None

for n_clusters in range(2, min(6, len(embeddings_normalized))):
    clustering = AgglomerativeClustering(n_clusters=n_clusters)
    labels = clustering.fit_predict(embeddings_normalized)

    if len(set(labels)) < 2:
        continue

    score = silhouette_score(embeddings_normalized, labels, metric='cosine')
    if score > best_score:
        best_score = score
        best_n = n_clusters
        best_labels = labels

print(f"Best n_clusters={best_n}, silhouette score={best_score:.3f}")

Advantages:

  • Deterministic results
  • Good for fixed number of clusters
  • Can use different linkage methods

Comparison Table

Method Auto Speaker Count Speed Best For
Hierarchical ✅ Yes Medium Unknown speaker count
KMeans ❌ No Fast Known speaker count
Agglomerative ❌ No Medium Fixed clusters needed

Embedding Normalization

Always normalize embeddings before clustering:

# L2 normalization
embeddings_normalized = embeddings_array / np.clip(
    np.linalg.norm(embeddings_array, axis=1, keepdims=True),
    1e-9, None
)

Distance Metrics

  • Cosine: Best for speaker embeddings (default)
  • Euclidean: Can work but less ideal for normalized embeddings

Choosing Number of Speakers

Method 1: Silhouette Score (for KMeans/Agglomerative)

from sklearn.metrics import silhouette_score

best_k = 2
best_score = -1

for k in range(2, min(7, len(embeddings))):
    labels = clusterer.fit_predict(embeddings)
    score = silhouette_score(embeddings, labels, metric='cosine')
    if score > best_score:
        best_score = score
        best_k = k

Method 2: Threshold Tuning (for Hierarchical)

# Start with reasonable threshold
threshold = 0.7
labels = fcluster(linkage_matrix, t=threshold, criterion='distance')
n_speakers = len(set(labels))

# Adjust based on constraints
if n_speakers > max_speakers:
    # Increase threshold to merge more
    threshold = 0.9
elif n_speakers < min_speakers:
    # Decrease threshold to split more
    threshold = 0.5

Post-Clustering: Merging Segments

After clustering, merge adjacent segments with same speaker:

def merge_speaker_segments(labeled_segments, gap_threshold=0.15):
    """
    labeled_segments: list of (start, end, speaker_label)
    gap_threshold: merge if gap <= this (seconds)
    """
    labeled_segments.sort(key=lambda x: (x[0], x[1]))

    merged = []
    cur_s, cur_e, cur_spk = labeled_segments[0]

    for s, e, spk in labeled_segments[1:]:
        if spk == cur_spk and s <= cur_e + gap_threshold:
            cur_e = max(cur_e, e)
        else:
            merged.append((cur_s, cur_e, cur_spk))
            cur_s, cur_e, cur_spk = s, e, spk

    merged.append((cur_s, cur_e, cur_spk))
    return merged

Common Issues

  1. Too many speakers: Increase threshold (hierarchical) or decrease k (KMeans)
  2. Too few speakers: Decrease threshold (hierarchical) or increase k (KMeans)
  3. Poor clustering: Check embedding quality, try different normalization
  4. Over-segmentation: Increase gap_threshold when merging segments

Best Practices

  1. Normalize embeddings before clustering
  2. Use cosine distance for speaker embeddings
  3. Try multiple methods and compare results
  4. Validate speaker count with visual features if available
  5. Merge adjacent segments after clustering
  6. After diarization, use high-quality ASR: Use Whisper small or large-v3 model for transcription (see automatic-speech-recognition skill)

Version History

  • 9a1f4dd Current 2026-07-24 16:38

Same Skill Collection

.agents/skills/skill-creator/SKILL.md
.agents/skills/skillsbench/SKILL.md
.agents/skills/task-creator/SKILL.md
tasks-extra/cobol-gl-batch-reconcile/environment/skills/comp3-packed-decimal/SKILL.md
tasks-extra/cobol-gl-batch-reconcile/environment/skills/ebcdic-overpunch-decoding/SKILL.md
tasks-extra/cobol-gl-batch-reconcile/environment/skills/gl-posting-codes/SKILL.md
tasks-extra/cobol-gl-batch-reconcile/environment/skills/gnucobol-mainframe-batch/SKILL.md
tasks-extra/diff-transformer_impl/environment/skills/attention-variants-from-papers/SKILL.md
tasks-extra/diff-transformer_impl/environment/skills/modal-gpu/SKILL.md
tasks-extra/find-topk-similiar-chemicals/environment/skills/pdf/SKILL.md
tasks-extra/find-topk-similiar-chemicals/environment/skills/pubchem-database/SKILL.md
tasks-extra/find-topk-similiar-chemicals/environment/skills/rdkit/SKILL.md
tasks-extra/gh-repo-analytics/environment/skills/gh-cli/SKILL.md
tasks-extra/gpu-cluster-online-scheduling/environment/skills/fragmentation-aware-packing/SKILL.md
tasks-extra/gpu-cluster-online-scheduling/environment/skills/multi-resource-allocation-validation/SKILL.md
tasks-extra/gpu-cluster-online-scheduling/environment/skills/online-resource-scheduling/SKILL.md
tasks-extra/mhc-layer-impl/environment/skills/mhc-algorithm/SKILL.md
tasks-extra/mhc-layer-impl/environment/skills/modal-gpu/SKILL.md
tasks-extra/mhc-layer-impl/environment/skills/nanogpt-training/SKILL.md
tasks-extra/nda-playbook-review/environment/skills/nda-clause-taxonomy/SKILL.md
tasks-extra/nda-playbook-review/environment/skills/xlsx-parsing/SKILL.md
tasks-extra/pedestrian-traffic-counting/environment/skills/gemini-count-in-video/SKILL.md
tasks-extra/pedestrian-traffic-counting/environment/skills/gemini-video-understanding/SKILL.md
tasks-extra/pedestrian-traffic-counting/environment/skills/gpt-multimodal/SKILL.md
tasks-extra/pedestrian-traffic-counting/environment/skills/video-frame-extraction/SKILL.md
tasks-extra/pg-essay-to-audiobook/environment/skills/audiobook/SKILL.md
tasks-extra/pg-essay-to-audiobook/environment/skills/elevenlabs-tts/SKILL.md
tasks-extra/pg-essay-to-audiobook/environment/skills/gtts/SKILL.md
tasks-extra/pg-essay-to-audiobook/environment/skills/openai-tts/SKILL.md
tasks-extra/scheduling-email-assistant/environment/skills/gmail-skill/SKILL.md
tasks-extra/speaker-diarization-subtitles/environment/skills/automatic-speech-recognition/SKILL.md
tasks-extra/speaker-diarization-subtitles/environment/skills/multimodal-fusion/SKILL.md
tasks-extra/speaker-diarization-subtitles/environment/skills/voice-activity-detection/SKILL.md
tasks-extra/taxonomy-tree-merge/environment/skills/hierarchical-taxonomy-clustering/SKILL.md
tasks-extra/video-filler-word-remover/environment/skills/ffmpeg-video-editing/SKILL.md
tasks-extra/video-filler-word-remover/environment/skills/filler-word-processing/SKILL.md
tasks-extra/video-filler-word-remover/environment/skills/whisper-transcription/SKILL.md
tasks-extra/video-tutorial-indexer/environment/skills/speech-to-text/SKILL.md
tasks/3d-scan-calc/environment/skills/mesh-analysis/SKILL.md
tasks/ada-bathroom-plan-repair/environment/skills/ada-plan-view-accessibility/SKILL.md
tasks/ada-bathroom-plan-repair/environment/skills/architectural-dxf-extraction/SKILL.md
tasks/ada-bathroom-plan-repair/environment/skills/geometric-layout-repair/SKILL.md
tasks/adaptive-cruise-control/environment/skills/csv-processing/SKILL.md
tasks/adaptive-cruise-control/environment/skills/pid-controller/SKILL.md
tasks/adaptive-cruise-control/environment/skills/simulation-metrics/SKILL.md
tasks/adaptive-cruise-control/environment/skills/vehicle-dynamics/SKILL.md
tasks/adaptive-cruise-control/environment/skills/yaml-config/SKILL.md
tasks/azure-bgp-oscillation-route-leak/environment/skills/azure-bgp/SKILL.md
tasks/bike-rebalance/environment/skills/geospatial-routing-data/SKILL.md

Metadata

Files
0
Version
9a1f4dd
Hash
915873f1
Indexed
2026-07-24 16:38

- 위키
Copyright © 2011-2026 iteam. Current version is 2.155.2. UTC+08:00, 2026-08-09 01:17
浙ICP备14020137号-1 $방문자$