Проверка качества эталонов
После запуска calibrate_cores сервер выводит попарные косинусы между эталонами — в двух вариантах: сырые и mean-centered.
Почему два числа
Трансформерные эмбеддинги страдают от анизотропии (Gao et al. 2019, Ethayarajh 2019): все векторы сжаты в узкий конус, и косинусы между любыми двумя текстами завышены. Mean subtraction вычитает средний вектор из каждого эталона перед сравнением — это убирает общий «конус», оставляя истинную семантическую разницу.
Реальный пример расчёта
Вот сохранённый результат calibrate_cores для стартовых эталонов S/D/E из config.template.yaml с моделью text-embedding-granite-embedding-278m-multilingual (LM Studio). Эти же тексты приведены в разделе Конфигурация — их можно взять как пример, если ваши домены действительно похожи.
S/D/E выбраны не как универсальная онтология, а как переносимый пример трёх хорошо различимых областей:
- S — Systems Analysis: обратные связи, эмерджентность, кибернетика, сложные системы.
- D — Data & Science: физика, космология, материя, энергия, пространство-время.
- E — Engineering: код, ML, инфраструктура, деплой, production-системы.
=== Pairwise Cosine (raw) ===
S↔D: 0.5894 S↔E: 0.5862 D↔E: 0.6022
S↔S: 1.0000 D↔D: 1.0000 E↔E: 1.0000
=== Pairwise Cosine (mean-centered) ===
S↔D: -0.5059 S↔E: -0.5117 D↔E: -0.4822
S↔S: 1.0000 D↔D: 1.0000 E↔E: 1.0000Как интерпретировать
| Метрика | Значение | Что значит |
|---|---|---|
| Raw S↔D = 0.5894 | Умеренный | Нормально — анизотропия трансформеров, все тексты «немного похожи» |
| Centered S↔D = -0.5059 | Отрицательный | ✅ Отлично — ядра семантически хорошо разделены |
| Centered cross-domain < 0 | Цель | ✅ Достигнуто — отрицательные значения означают, что ядра направлены в разные стороны |
Самоклассификация эталонов
Когда каждый эталон классифицируется против всех ядер (нормализация через spread):
| Эталон | S % | D % | E % | Доминанта | Spread |
|---|---|---|---|---|---|
| S (Systems Analysis) | 99.4 | 0.6 | 0.0 | S | 0.7889 |
| D (Data & Science) | 0.0 | 97.5 | 2.5 | D | 0.7888 |
| E (Engineering) | 0.0 | 3.1 | 96.9 | E | 0.7928 |
Все три эталона классифицируют себя правильно с уверенностью >96%. Значения spread (~0.79) значительно выше порога sign_spread = 0.05, что означает надёжную классификацию.
Что означают эти числа
Отрицательные mean-centered косинусы — это хороший знак. Они означают, что после удаления общего компонента «трансформерного конуса» эталоны направлены в разные стороны в пространстве эмбеддингов. Эталоны S/D/E хорошо спроектированы: каждый захватывает отдельный семантический домен с минимальным перекрытием.
Для заметок сервер использует тот же принцип: embedding заметки сравнивается с mean-centered эталонами, затем считается spread и нормализованные проценты. Если все домены почти равны, сервер оставляет результат без уверенного доменного выбора: при spread < sign_spread различие между доменами считается слишком слабым.
Плохой результат (условный пример)
=== Pairwise Cosine (mean-centered) ===
S↔D: 0.08 S↔E: -0.03 D↔E: 0.05Это не “фатальные” числа сами по себе, а тревожный паттерн: после mean-centering домены почти не разъехались. Значения болтаются около нуля, значит эталоны не дают устойчивого направления для классификации. Обычно причина в том, что тексты эталонов говорят одними и теми же общими словами: «система», «модель», «структура», «процесс».
Плохая самоклассификация выглядела бы так:
| Эталон | S % | D % | E % | Доминанта | Spread |
|---|---|---|---|---|---|
| S | 42 | 31 | 27 | S | 0.1500 |
| D | 35 | 40 | 25 | D | 0.1400 |
| E | 30 | 28 | 42 | E | 0.1600 |
Здесь доминанта есть формально, но она слабая. Классификатор почти не отличает ядра друг от друга. Решение: убрать общие слова, добавить доменно-специфичный язык и явно обозначить границы между соседними доменами.
Целевые значения
| Метрика | Цель |
|---|---|
| Centered cross-domain | < 0.3 (отрицательный — ещё лучше) |
| Self cosine | 1.0 как sanity check |
| Raw cross-domain | 0.5–0.75 (нормально для трансформеров) |
| Самоклассификация | > 90% для каждого эталона |
| Spread | > 0.5 (значительно выше порога sign_spread) |
Как mean-centering работает математически
# 1. Средний вектор всех эталонов
mean_vec = (vec_S + vec_D + vec_E) / 3
# 2. Вычитаем из каждого
S_centered = vec_S - mean_vec
D_centered = vec_D - mean_vec
E_centered = vec_E - mean_vec
# 3. Cosine между centered векторами
cosine_SD = cosine_similarity(S_centered, D_centered)При классификации заметок сервер сравнивает embedding заметки с mean-centered эталонами и затем считает spread-normalized проценты.
Как воспроизвести расчёт
Для воспроизведения используйте те же тексты S/D/E из config.template.yaml и ту же embedding-модель. Если endpoint LM Studio доступен по другому адресу:
set EMBED_API_URL=http://10.8.0.10:1234
set EMBED_MODEL=text-embedding-granite-embedding-278m-multilingual
python scripts/calc_etalons.pyЕсли меняете тексты эталонов или embedding-модель, цифры должны быть пересчитаны. Старые cosine уже не доказывают качество нового набора.