Чтобы наглядно представить семантику и структуру сайта для дальнейшей оптимизации, можно использовать векторное представление его страниц на диаграммах рассеяния. Здесь представлен способ, использующий Python и его библиотеки.
Подготовка #
- Определите, какие страницы сайта должны попасть в список сканирования. Процесс достаточно ресурсоёмкий, и если на вашем сайте есть разделы, в принципе ненужные для анализа, их стоит исключить.
- Определите зону основного контента, из которого и будут извлекаться векторные вложения (эмбеддинги). Избыточный контент сквозных зон и служебной информации в данном случае – просто шум, который усложнит процессы и ухудшит качество полученных эмбеддингов. Как извлечь только полезный контент средствами Screaming Frog SEO Spider.
- После окончания парсинга вы должны получить csv-файл с двумя колонками: “url” и “content”. Обратите внимание, что для использования скрипта ниже вам понадобится csv с запятыми в качестве разделителей, в кодировке UTF-8.
- Установите необходимые библиотеки Python. Для векторизации тут используется numpy, pandas, sentence-transformers, для снижения размерности – UMAP, диаграмма формируется с помощью Plotly. Примечание. Для работы я использую Anaconda и её окружение Conda. Вместо этого можно использовать venv.
- Для удобства работы создайте отдельную проектную папку, где будут храниться ваши рабочие скрипты, исходные и полученные данные. На вход подаётся файл pages.csv, на выходе вы получите файл результатов с координатами pages_with_coords.csv, и при желании – сохраненную визуализацию в формате HTML и PNG.
Скрипт #
Сохраните в проектной папке представленный ниже скрипт (назовите его любым понятным именем, например, vector.py):
import numpy as np
import pandas as pd
from sentence_transformers import SentenceTransformer
import umap
import plotly.express as px
# 1. Загрузка модели (мультиязычная, хорошо работает с русским и английским)
model = SentenceTransformer('intfloat/multilingual-e5-large')
# 2. Загрузка данных (ожидаются колонки: url, content)
df = pd.read_csv('pages.csv')
# Для E5 моделей рекомендуется префикс "passage:" для документов.
# Используем URL как дополнительный контекст + содержимое (первые 1500 символов)
texts = [f"passage: {row['url']}. {row['content'][:1500]}"
for _, row in df.iterrows()]
# 3. Получение эмбеддингов (L2-нормализация включена)
embeddings = model.encode(texts, show_progress_bar=True,
batch_size=32,
normalize_embeddings=True)
# 4. Снижение размерности до 2D с помощью UMAP
reducer = umap.UMAP(
n_neighbors=15,
min_dist=0.1,
metric='cosine',
random_state=42,
n_epochs=500
)
embeddings_2d = reducer.fit_transform(embeddings)
# 5. Добавление координат в DataFrame
df['x'] = embeddings_2d[:, 0]
df['y'] = embeddings_2d[:, 1]
# 6. Интерактивная визуализация (Plotly)
fig = px.scatter(
df, x='x', y='y',
hover_data=['url'], # показываем URL при наведении
title='Семантическая карта сайта',
width=1200, height=800
)
fig.update_traces(marker=dict(size=6, opacity=0.7))
fig.update_layout(
xaxis_title='', yaxis_title='',
xaxis=dict(showticklabels=False),
yaxis=dict(showticklabels=False)
)
fig.show()
# 7. Сохранение эмбеддингов и данных с координатами
np.save('embeddings.npy', embeddings)
df.to_csv('pages_with_coords.csv', index=False) # сохраняет URL, content, x, y
Запустите терминал (командную строку). Я использую Anaconda prompt. Перейдите в папку со скриптом и запустите его.
После обработки данных автоматически загрузится визуализация в виде диаграммы рассеяния, а таблица с координатами контента будет сохранена в проектной папке вместе с рабочим скриптом. Там же будет сохранен файл с эмбеддингами в формате NPY (бинарный файл NumPy), который вы сможете использовать для других задач.

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