Как определить стиль письма с помощью эмбеддингов: поиск авторов и коллабораторов | AiManual
AiManual Logo Ai / Manual.
05 Янв 2026 Гайд

Стиль письма — это вектор. Находите авторов и коллабораторов через эмбеддинги

Поиск авторов с похожим стилем письма через эмбеддинги. Практический гайд по анализу стилистических особенностей текста, инструменты и методы.

Почему семантика убивает стиль (и как это исправить)

Вы ищете соавтора для проекта. Нашли человека, который пишет на нужную тему. Открываете его текст — и понимаете: стиль не ваш. Слишком академично. Или слишком разговорно. Или слишком... не ваше.

Проблема в том, что все современные поисковые системы ищут по смыслу. Они понимают, что вы пишете о DevOps, но не понимают, как вы это делаете. Короткими рублеными фразами? Длинными философскими рассуждениями? С техническим сленгом или академическим языком?

Стиль — это не про «что». Это про «как». И вот здесь эмбеддинги показывают свою настоящую силу.

Стилевые эмбеддинги игнорируют содержание. Они смотрят на структуру предложений, выбор слов, пунктуационные привычки, ритм текста. Два автора могут писать о разных вещах, но иметь идентичный стиль письма.

Что такое стилевой эмбеддинг (и чем он отличается от обычного)

Представьте стандартный текстовый эмбеддинг. Это вектор, который кодирует смысл. «Кошка» и «собака» будут ближе, чем «кошка» и «программирование».

Стилевой эмбеддинг работает иначе. Он смотрит на:

  • Среднюю длину предложения
  • Соотношение существительных и глаголов
  • Частоту использования определенных союзов
  • Лексическое разнообразие (сколько уникальных слов на 1000 символов)
  • Использование пассивного залога
  • Пунктуационные паттерны (любите ли вы тире, точки с запятой, многоточия)

Два текста про кошек и про микросервисы могут иметь одинаковые стилевые эмбеддинги, если их авторы пишут похоже.

Готовые инструменты: что работает прямо сейчас

1 FastText с стилевыми признаками

Самый простой способ — дообучить FastText на ваших текстах. Но не на содержании, а на стилевых метках.

Как НЕ надо делать:

# ПЛОХО: так вы получите семантические эмбеддинги
from gensim.models import FastText
model = FastText(sentences=all_texts, vector_size=100)

Как надо делать:

# ХОРОШО: создаем стилевые признаки
import re
from collections import Counter

def extract_style_features(text):
    features = []
    sentences = re.split(r'[.!?]+', text)
    
    # Средняя длина предложения
    avg_sentence_len = sum(len(s.split()) for s in sentences) / len(sentences)
    features.append(f"SENT_LEN_{int(avg_sentence_len)}")
    
    # Соотношение существительных к глаголам (упрощенно)
    nouns = len([w for w in text.split() if w.endswith(('ость', 'ие', 'ация'))])
    verbs = len([w for w in text.split() if w.endswith(('ть', 'ться', 'ил', 'ал'))])
    ratio = nouns / max(verbs, 1)
    features.append(f"NOUN_VERB_{int(ratio*10)}")
    
    # Любимая пунктуация
    punct = Counter(c for c in text if c in ',;:-—')
    most_common = punct.most_common(1)[0] if punct else ('none', 0)
    features.append(f"PUNCT_{most_common[0]}")
    
    return features

# Собираем стилевые "слова" для FastText
style_corpus = []
for text in all_texts:
    style_features = extract_style_features(text)
    style_corpus.append(style_features)

# Обучаем на стилевых признаках
model = FastText(sentences=style_corpus, vector_size=50)
💡
Этот подход грубый, но работает. Вы получаете вектора, которые кодируют стиль, а не содержание. Два текста с разной тематикой, но одинаковыми стилевыми признаками, будут близки в векторном пространстве.

2 Sentence-BERT с fine-tuning на стиле

Более продвинутый вариант — взять Sentence-BERT и дообучить его различать стили.

Собираете пары текстов:

  • Положительные пары: тексты одного автора (даже на разные темы)
  • Отрицательные пары: тексты разных авторов (даже на одну тему)
from sentence_transformers import SentenceTransformer, losses, InputExample
from torch.utils.data import DataLoader
import torch

# Берем предобученную модель
model = SentenceTransformer('sentence-transformers/all-MiniLM-L6-v2')

# Готовим данные для обучения
# Каждая пара - два текста и метка (1 - один стиль, 0 - разные стили)
train_examples = []
for author_id, texts in author_texts.items():
    # Положительные пары: случайные тексты одного автора
    for i in range(len(texts)):
        for j in range(i+1, min(i+3, len(texts))):
            train_examples.append(InputExample(
                texts=[texts[i], texts[j]],
                label=1.0  # одинаковый стиль
            ))
    # Отрицательные пары: тексты этого автора и случайного другого
    other_authors = [aid for aid in author_texts.keys() if aid != author_id]
    for other_id in other_authors[:2]:
        other_text = author_texts[other_id][0]
        train_examples.append(InputExample(
            texts=[texts[0], other_text],
            label=0.0  # разные стили
        ))

# Обучаем с контрастивной потерей
train_dataloader = DataLoader(train_examples, shuffle=True, batch_size=16)
train_loss = losses.CosineSimilarityLoss(model)
model.fit(
    train_objectives=[(train_dataloader, train_loss)],
    epochs=3,
    warmup_steps=100
)

Важно: не используйте слишком много отрицательных пар. Если взять все возможные комбинации, модель начнет переобучаться. Достаточно 2-3 отрицательных примеров на каждого автора.

Как искать авторов с похожим стилем

Допустим, у вас есть ваш текст. Вы хотите найти авторов, которые пишут похоже.

Шаг 1: Собираете корпус текстов потенциальных коллабораторов. Блоги, статьи на Хабре, посты в телеграме.

Шаг 2: Генерируете стилевые эмбеддинги для всех текстов (включая ваш).

Шаг 3: Ищете ближайших соседей в векторном пространстве.

import numpy as np
from sklearn.neighbors import NearestNeighbors

# Ваш текст
your_text = "Ваш текст здесь"
your_embedding = model.encode([your_text])[0]

# Все тексты потенциальных авторов
all_texts = [...]  # список текстов
all_embeddings = model.encode(all_texts)

# Ищем 10 ближайших соседей
nn = NearestNeighbors(n_neighbors=10, metric='cosine')
nn.fit(all_embeddings)
distances, indices = nn.kneighbors([your_embedding])

print("Ближайшие по стилю авторы:")
for i, (dist, idx) in enumerate(zip(distances[0], indices[0])):
    print(f"{i+1}. Текст #{idx}, расстояние: {dist:.3f}")

Но здесь есть проблема: близкий текст может быть близким по стилю, но его автор может быть недоступен для коллаборации.

Решение: кластеризуем авторов, а не отдельные тексты.

3 Кластеризация авторов по стилю

Берем несколько текстов каждого автора, усредняем их эмбеддинги, получаем «стилевой профиль» автора.

from sklearn.cluster import DBSCAN
import pandas as pd

# Словарь: автор -> список его текстов
author_to_texts = {
    "author1": ["текст1", "текст2", ...],
    "author2": ["текст3", "текст4", ...],
    # ...
}

# Считаем средний эмбеддинг для каждого автора
author_embeddings = {}
for author, texts in author_to_texts.items():
    embeddings = model.encode(texts)
    avg_embedding = np.mean(embeddings, axis=0)
    author_embeddings[author] = avg_embedding

# Кластеризуем авторов
embeddings_matrix = np.array(list(author_embeddings.values()))
clustering = DBSCAN(eps=0.3, min_samples=2, metric='cosine').fit(embeddings_matrix)

# Смотрим, кто в одном кластере с вами
authors = list(author_embeddings.keys())
your_index = authors.index("ваш_авторский_ник")
your_cluster = clustering.labels_[your_index]

print(f"Ваш кластер: {your_cluster}")
print(f"Авторы в вашем кластере:")
for i, label in enumerate(clustering.labels_):
    if label == your_cluster and i != your_index:
        print(f"- {authors[i]}")

Теперь у вас есть список авторов, которые пишут в похожем стиле. Можно писать им предложения о коллаборации.

Четыре ошибки, которые все совершают

ОшибкаПочему это проблемаКак исправить
Слишком короткие текстыСтиль проявляется на 500+ словах. Короткие твиты не дают статистикиИспользуйте тексты от 1000 символов. Или объединяйте несколько постов одного автора
Смешивание жанровТехническая документация и личный блог — разный стиль даже у одного автораОбучайте отдельные модели для каждого жанра. Или добавляйте жанр как признак
Игнорирование темыСпецифическая лексика (например, DevOps термины) влияет на статистикуИспользуйте лемматизацию или удаляйте доменные слова перед анализом
Только косинусная близостьРазные стили могут быть равноудалены от вашего, но в разных направленияхСмотрите на распределение расстояний. Используйте t-SNE для визуализации

Практический кейс: поиск соавтора для технического блога

У меня есть DevOps-блог. Я пишу короткими предложениями, с минимумом прилагательных, с примерами кода в каждом посте. Хочу найти соавтора, который пишет так же.

Что я делаю:

  1. Собираю 50 своих постов (это мой «стилевой эталон»)
  2. Скачиваю 1000 постов с DevOps-тематики с Хабра и Medium
  3. Обучаю Sentence-BERT на парах: мои посты vs чужие посты
  4. Кластеризую всех авторов
  5. Нахожу 3-х авторов в моем кластере
  6. Пишу им: «Привет, я заметил, что мы пишем в очень похожем стиле. Хочешь сделать совместный пост?»

Результат: из 3-х писем — 2 положительных ответа. Один автор сказал: «Да, я тоже заметил, что мы используем похожие конструкции. Думал, это только мне кажется».

Магия? Нет. Просто математика.

Что делать, если нет своих текстов для обучения

Используйте предобученные модели с вниманием к стилевым признакам.

Вариант 1: Анализируйте внутренние представления моделей. Возьмите Llama или Qwen, подайте текст и посмотрите на активации определенных слоев. Стилевая информация часто кодируется в средних слоях.

Вариант 2: Используйте EmergentFlow или подобные инструменты для быстрого прототипирования. Соберите пайплайн: текст -> извлечение стилевых признаков -> сравнение.

Вариант 3: Генерируйте синтетические тексты в разных стилях. Как в методе DocuLite для финансовых данных, но для стилей. Попросите ChatGPT написать один и тот же контент в 10 разных стилях. Используйте эти пары для обучения.

Стиль vs качество: важное различие

Стилевые эмбеддинги не измеряют качество письма. Плохо написанный текст и хорошо написанный текст могут иметь одинаковый стиль.

Если вы ищете не просто похожий стиль, а еще и качество — добавляйте второй этап фильтрации.

  • Сначала находите авторов с похожим стилем
  • Потом оцениваете качество их текстов (читаемость, грамотность, структура)
  • Только потом предлагаете коллаборацию

Для оценки качества можно использовать те же LLM. Попросите GPT-4 оценить текст по шкале от 1 до 10 по критериям: ясность, структура, аргументация.

💡
Интересный факт: анализ стиля письма может выявить случаи, когда автор использует LLM для редактуры. Если в тексте появляются стилевые несоответствия (одна часть в одном стиле, другая — в другом), возможно, часть текста была сгенерирована или отредактирована нейросетью. Подробнее об этом в статье про LLM-редактуру.

Этический момент: стиль как отпечаток пальцев

Стиль письма — это почти как биометрические данные. Уникальный. Узнаваемый.

Когда вы анализируете чужой стиль без разрешения — это серый этический район. Особенно если вы используете это для коммерческих целей.

Мое правило: если вы собираетесь связаться с автором — анализируйте. Если нет — не храните его стилевые эмбеддинги. Или хотя бы анонимизируйте данные.

Технически можно определить автора по стилю с точностью до 85-95%. Это мощно. И немного страшно.

Что будет дальше: стилевые рынки и коллаборационные платформы

Через год-два появятся платформы, где авторы будут регистрироваться со своими стилевыми эмбеддингами.

Вы загружаете свой текст. Система находит 10 авторов с максимально похожим стилем. Показывает их рейтинг, темы, на которых они специализируются. Вы выбираете одного, система предлагает шаблон письма для коллаборации.

Или еще интереснее: стилевые рекомендательные системы. «Вам понравился автор X. Вот авторы Y и Z, которые пишут в похожем стиле».

Это уже происходит с фильмами и музыкой. Почему бы не с текстами?

Следующий шаг — стилевая трансфер. «Напиши этот текст в стиле автора X». Но это уже другая история.

А пока — берите код выше, адаптируйте под свои нужды. Ищите своих стилевых двойников. Пишите им.

Самый неочевидный совет в конце: иногда лучшая коллаборация — с автором, чей стиль НЕ похож на ваш. Контраст создает интерес. Но чтобы это понять, нужно сначала найти тех, кто похож. А потом — сознательно выбрать того, кто отличается.

Математика дает варианты. Выбор — за вами.