← К портфолио LinkedIn Content Analytics preview
Ситуация
Рейтинг форматов, у которого доверительный интервал накрывает всё поле, — не ответ: показать его как ответ хуже, чем не показать ничего
Задача
Отвечать не на «сколько показов я набрал», а на «какой формат писать дальше — и доказано ли вообще, что разница есть»
Действия
Одно ядро разбора workbook, четыре рендера (markdown-отчёт, HTML-дашборд, SVG-график, заметка в хранилище) и bootstrap-интервалы по постам вместо точечного рейтинга
Результат
50 101 показов, охват 9 440, ER 1.71 % за окно 12.10.2025 — 11.10.2026; три из четырёх разрезов оказались внутри шума, и это записано как результат
Стек
Pythonopenpyxluvbootstrappytest
Исходники Смотреть на GitHub → Репозиторий приватный — доступ по запросу Обновлено: Oct 11, 2026
Содержание
  1. Ситуация
  2. Задача
  3. Действия
  4. Одно ядро — четыре рендера
  5. Статистический стандарт
  6. Запуск
  7. Результат
  8. Ограничения
  9. Документация

LinkedIn Content Analytics

▶ Схема потока данных — самодостаточный HTML, открывается в браузере — без установки и сборки

Ситуация

Один workbook, выгруженный руками из LinkedIn, — единственный источник правды о том, как работает мой контент. Вопрос не «сколько показов я набрал», а «какой формат писать дальше — и доказано ли вообще, что разница есть».

Рейтинг, у которого доверительный интервал накрывает всё поле, — не ответ: показать его как ответ хуже, чем не показать ничего.

Задача

От меня требовался отчёт, который ранжирует форматы только там, где различие установлено, и честно называет шумом то, что шумом является. Плюс — одинаковые цифры во всех форматах вывода.

Действия

Одно ядро — четыре рендера

Раньше один и тот же workbook парсился дважды — в хранилище и в проекте, — и парсеры разошлись: хранилище склеивало посты по URL, проект — по дате. В один день 13.09.2026 попало два поста, и склейка по дате молча схлопнула их в один: 48 парных постов вместо верных 49, доля топа 93.7 % вместо 97 %. Ничего не покраснело.

Теперь ядро одно (linkedin_analytics_core), а тест держит инвариант: markdown-отчёт, HTML-дашборд, SVG-график для README и заметка в хранилище выдают одинаковые числа.

Статистический стандарт

  • Ресемплим посты, а не показы. Показы детерминированы, как только пост выбран; варьируется лишь то, какие посты оказались написанными.
  • Интервалы, а не точки. n мал, поэтому рядом с каждой серией стоит 95 % percentile bootstrap по постам.
  • Перекрывающиеся интервалы называются перекрывающимися. Большая часть рейтинга серий — внутри шума, и отчёт обязан это сказать.
  • Пустой результат — результат. Оригинал против репоста (p = 0.60) и ритм недели (p = 0.060) не прячутся.
  • Величина, которая не может меняться, — не метрика. Доля топа убрана.

Запуск

./run.sh --analytics-only --dry-run   # превью, только аналитика контента
./run.sh --apply                      # отчёты + правка заметки

Результат

Окно 12.10.2025 — 11.10.2026:

Метрика Значение
Показы 50 101
Охвачено участников 9 440
Вовлечённости 859
Engagement rate 1.71 %
Новых подписчиков 2 175
  • Серии. Swipe 22.9 [18.8, 26.2] и «Материал к собесу» 20.3 [19.6, 21.4] не перекрываются с «A/B и статистикой» 12.9 [9.9, 16.3] — различие установлено. «Диванная аналитика» 16.6 [11.6, 23.6] перекрывается со всеми: сказать нечего.
  • Оригинал против репоста. 16.9 против 19.4, p = 0.60 — различие не установлено.
  • Ритм недели. Пн 23.1, Вс 12.6, p = 0.060 — порог не пройден, пока гипотеза.
  • Показы и подписчики. r = 0.35, 95 % CI [−0.15, 0.72] — интервал содержит ноль, подписчики не мера удачи поста.

Ограничения

Серии держат по 3–8 постов, недельные бакеты — по 6–9: при таком n узкий интервал почти наверняка означает, что в выборку попали удачные посты, а не что формат действительно лучше. Демографию аудитории (компании, города, должности) README намеренно не выносит — она остаётся в отчёте и дашборде. Число отписок (около 81) — выведено: прямой цифры workbook не несёт.

Документация