Урок 9: Патерни, тренди та кластеризація
Навігація курсу: Хаб: Уроки
Попередній: Урок-08-Воркшоп | Наступний: Урок-10-Моніторинг-реального-часу
Слайди (Презентаційний текст)
Слайд 1 — Заголовок
Патерни, тренди та кластеризація
Від окремих фактів до системного розуміння
Слайд 2 — Навіщо аналіз патернів?
Один факт = одна точка.
Патерн = смисл.
OSINT-аналітик не тільки збирає — він виявляє структуру:
- Чи є цикл у поведінці суб’єкта?
- Які теми домінують у спільноті?
- Куди рухається тренд?
- Хто схожий на кого?
AI-підхід 2025-2026: ML-алгоритми знаходять патерни у даних де людина бачить хаос
Слайд 3 — Типи патернів у OSINT
| Тип патерну | Приклад | Інструменти |
|---|---|---|
| Часовий | Публікації щовівторка о 9:00 → часовий пояс | Pandas, матриці активності |
| Мовний | Перехід з UK на RU у пості → аудиторія змінилась | NLP, topic modeling |
| Мережевий | Той самий набір акаунтів репостить завжди разом → ботоферма | Gephi, Betweenness |
| Контентний | Тематичні кластери публікацій | TF-IDF, BERTopic |
| Поведінковий | Різка зміна частоти публікацій → щось сталось | Anomaly detection |
Слайд 4 — Аналіз тимчасових патернів
Матриця активності (теплова карта):
import pandas as pd
import matplotlib.pyplot as plt
# posts_df має колонки: timestamp, platform
posts_df['hour'] = posts_df['timestamp'].dt.hour
posts_df['weekday'] = posts_df['timestamp'].dt.day_name()
# Матриця: день тижня × година дня
pivot = posts_df.pivot_table(
index='weekday', columns='hour',
values='id', aggfunc='count'
)
plt.figure(figsize=(14, 5))
plt.imshow(pivot, aspect='auto', cmap='YlOrRd')
plt.colorbar(label='Кількість постів')
plt.title('Матриця активності')Що виявляємо:
- Часовий пояс (пік активності)
- Робочий vs особистий час
- Аномальна активність (ніч, вихідні)
Слайд 5 — Кластеризація тексту
Мета: знайти тематичні групи без попередніх міток
Алгоритми:
- K-Means — потрібно вказати кількість кластерів
- DBSCAN — сам знаходить кількість, виявляє шум
- BERTopic — сучасний підхід на трансформерах, 2025-2026 стандарт
from bertopic import BERTopic
model = BERTopic(language="multilingual")
topics, probs = model.fit_transform(documents)
# Переглянути топ-теми
print(model.get_topic_info())Слайд 6 — BERTopic для OSINT (2025-2026)
BERTopic — виявлення тем у корпусі документів:
- Векторизація документів (BERT ембедінги)
- Зменшення розмірності (UMAP)
- Кластеризація (HDBSCAN)
- Видалення стоп-слів (c-TF-IDF)
Практика OSINT:
- Аналіз 1000+ Telegram-постів → виявлення тематичних кластерів
- Аналіз новинного потоку → визначення домінантних наративів
- Аналіз коментарів → розуміння настроїв спільноти
Слайд 7 — Аналіз трендів
TF-IDF для виявлення ключових термінів:
from sklearn.feature_extraction.text import TfidfVectorizer
# Порівняти два часових проміжки
vectorizer = TfidfVectorizer(max_features=100, ngram_range=(1,2))
period_1 = vectorizer.fit_transform(docs_jan)
period_2 = vectorizer.transform(docs_apr)
# Слова що зросли у вазі → новий трендДля OSINT: відстеження зміни наративів у часі, виявлення нових тем
Слайд 8 — Виявлення аномалій
Anomaly Detection для моніторингу:
from sklearn.ensemble import IsolationForest
# Ознаки: кількість постів на день, uniq авторів, engagement
X = df[['daily_posts', 'unique_authors', 'avg_engagement']].values
model = IsolationForest(contamination=0.05)
df['anomaly'] = model.fit_predict(X)
# anomaly = -1 → аномальний день (атака, кампанія, подія)
anomalies = df[df['anomaly'] == -1]Застосування: виявлення координованих інформаційних кампаній, раптового зростання уваги до суб’єкта
Слайд 9 — Поведінкові патерни особи
Що аналізуємо:
| Сигнал | Інтерпретація |
|---|---|
| Час постів щодня о 7-9 | Особа в UTC+2 або UTC+3 |
| Різкий стоп публікацій | Подорож, проблеми, зміна ролі |
| Зміна мови | Нова аудиторія, переїзд |
| Новий тип контенту | Зміна стратегії або аудиторії |
| Видалення старих постів | OpSec, юридичні проблеми, переформатування |
Слайд 10 — Практичний інструментарій (2025-2026)
| Завдання | Інструмент | Мова |
|---|---|---|
| Тематична кластеризація | BERTopic | Python |
| Часові ряди | Prophet (Meta), statsmodels | Python |
| Мережевий аналіз | Gephi, NetworkX | GUI / Python |
| Аномалії | Isolation Forest, LSTM | Python |
| Sentiment trends | VADER, HuggingFace pipelines | Python |
| Візуалізація | Matplotlib, Plotly, Tableau | Python / GUI |
Слайд 11 — Кейс: аналіз дезінформаційної кампанії
Крок 1: Зібрати 5000+ постів за темою (Telegram + Twitter/X)
Крок 2: BERTopic → виявити 8 кластерів наративів
Крок 3: Часовий аналіз → коли кожен наратив з’явився
Крок 4: Мережевий аналіз → хто першим поширював кожний наратив
Крок 5: Anomaly detection → виявити дні координованих публікацій
Результат: карта наративів + часова шкала + мережа поширення
Слайд 12 — Обмеження алгоритмів
- K-Means: погано на нерівних кластерах, потребує k
- BERTopic: повільний на дуже великих даних (>1M документів)
- Isolation Forest: чутливий до параметра contamination
- Все алгоритмічне: виявляє кореляції, не причинно-наслідкові зв’язки
Правило: алгоритм вказує де дивитись, людина вирішує що це означає
Нотатки доповідача
До слайду 4 — Матриця активності
Демонстрація: візьміть публічний Telegram-канал, зберіть метадані 200+ постів (тільки timestamp, без контенту), побудуйте теплову карту. Часовий пояс автора часто видний одразу. Цей аналіз займає 15-20 хвилин у Jupyter і дає чіткий результат.
До слайду 6 — BERTopic
BERTopic — справжній прорив 2022-2023 який став стандартом до 2025-2026. Він не потребує попереднього визначення кількості тем і чудово справляється з багатомовними корпусами. Підкресліть: для аналітика без ML-бекграунду достатньо знати як запустити і як інтерпретувати результат.
До слайду 11 — Кейс
Розберіть реальний або гіпотетичний кейс детально. Ідеально якщо є реальний приклад дезінформаційної кампанії яку студенти пам’ятають. Пройдіть кроки вголос, показуючи як кожен інструмент додає до загальної картини.
Домашнє завдання
Завдання 1 — Матриця активності (обов’язкове)
Знайдіть будь-який публічний Telegram-канал (мінімум 500 постів).
- Зберіть metadata останніх 200+ постів (timestamp, views)
- Побудуйте матрицю активності (день × година)
- Зробіть висновки: часовий пояс, ритм роботи, аномалії
- Здайте: Jupyter notebook + скріншот матриці + висновки
Завдання 2 — Тематична кластеризація (обов’язкове)
Зберіть 100+ текстових постів на одну тему з Telegram або Twitter.
- Встановіть BERTopic:
pip install bertopic - Запустіть кластеризацію
- Опишіть знайдені кластери: як би ви їх назвали?
- Чи є кластер що виглядає аномально?
Завдання 3 — Trend аналіз (бажане)
Оберіть ключове слово або особу. Зберіть кількість згадок по тижнях за останні 3 місяці.
Побудуйте часовий ряд. Знайдіть піки і поясніть їх (яка подія викликала ріст?).
Матеріали для студентів
Ресурси
Кластеризація і ML для OSINT:
- BERTopic Documentation — офіційна документація
- OSINT Mastery 2026: Advanced Techniques
- Automated OSINT Techniques (MDPI 2025) — академічна стаття
Стартовий код: матриця активності
"""
Аналіз матриці активності Telegram-каналу
Для курсу AI for OSINT 2026
"""
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from datetime import datetime
# Припускаємо що у вас є CSV з колонкою 'timestamp'
# (зібраний через Telegram API або ручно)
def build_activity_matrix(csv_path, tz_offset=0):
df = pd.read_csv(csv_path)
df['timestamp'] = pd.to_datetime(df['timestamp'], utc=True)
# Корекція часового поясу
df['local_time'] = df['timestamp'] + pd.Timedelta(hours=tz_offset)
df['hour'] = df['local_time'].dt.hour
df['weekday'] = df['local_time'].dt.day_name()
# Порядок днів тижня
day_order = ['Monday', 'Tuesday', 'Wednesday',
'Thursday', 'Friday', 'Saturday', 'Sunday']
# Побудова pivot-таблиці
pivot = df.pivot_table(
index='weekday', columns='hour',
values='message_id' if 'message_id' in df.columns else df.columns[0],
aggfunc='count',
fill_value=0
).reindex(day_order)
# Теплова карта
plt.figure(figsize=(16, 6))
sns.heatmap(pivot, cmap='YlOrRd', linewidths=0.5,
annot=True, fmt='d', cbar_kws={'label': 'Кількість постів'})
plt.title('Матриця активності')
plt.xlabel('Година дня (UTC+{})'.format(tz_offset))
plt.ylabel('День тижня')
plt.tight_layout()
plt.savefig('activity_matrix.png', dpi=150)
plt.show()
# Висновки
peak_hour = pivot.values.sum(axis=0).argmax()
peak_day = pivot.sum(axis=1).idxmax()
print(f"Пік активності: {peak_day}, {peak_hour}:00")
print(f"Орієнтовний часовий пояс: UTC+{tz_offset}")
return pivot
# Використання:
# matrix = build_activity_matrix('telegram_posts.csv', tz_offset=2)← Урок-08-Воркшоп | Наступний урок: Урок-10-Моніторинг-реального-часу →