Genealogy Analyzer
Анализ генеалогических данных в формате GEDCOM с фокусом на поиске аномалий, нетипичных дат и интересных паттернов. Специализация на русских православных традициях (до 1917 года).
Когда использовать этот skill
Активировать когда пользователь:
- Просит проанализировать GEDCOM файл на аномалии
- Хочет найти нетипичные даты браков/свадеб
- Спрашивает о соответствии дат православным традициям
- Просит исследовать конкретную семью на аномалии
- Хочет проверить даты рождения детей относительно брака родителей
- Хочет проверить соответствие имён дням крещения по святцам
- Хочет найти ошибки или несоответствия в датах (validate_dates.py)
- Хочет проверить соответствие отчеств именам отцов (patronymic_check.py)
- Ищет «кирпичные стены» — тупики без известных родителей (brick_walls.py)
- Хочет оценить качество/полноту данных в дереве (data_quality.py)
- Ищет паттерн «замещающих имён» умерших младенцев (replacement_names.py)
- Хочет рассчитать коэффициент инбридинга (родства супругов) (inbreeding.py)
- Анализирует географию происхождения семьи или миграцию (migration_analysis.py)
- Изучает продолжительность жизни предков (longevity.py)
- Хочет узнать интервалы между поколениями (generation_stats.py)
- Исследует фамилии и их происхождение (surname_analysis.py)
Доступные скрипты
Базовые скрипты анализа
| Скрипт | Назначение |
|---|---|
analyze_marriages.py |
Анализ дат браков на соответствие православным традициям |
analyze_births.py |
Аналитика рождений: распределение по годам, месяцам, сезонам зачатия |
check_first_child.py |
Проверка дат рождения первых детей (добрачная беременность) |
check_nameday.py |
Проверка имён по святцам + поиск родственников-тёзок |
find_namesakes.py |
Поиск родственников с одинаковыми именами |
Скрипты валидации данных
| Скрипт | Назначение |
|---|---|
validate_dates.py |
Детектор аномалий дат (рождение после смерти родителя и т.д.) |
patronymic_check.py |
Проверка соответствия отчеств именам отцов |
brick_walls.py |
Анализ «кирпичных стен» — конечных предков без родителей |
data_quality.py |
Оценка качества и полноты данных |
replacement_names.py |
Поиск «замещающих имён» умерших младенцев |
Продвинутая аналитика
| Скрипт | Назначение |
|---|---|
inbreeding.py |
Расчёт коэффициента инбридинга (COI) по алгоритму Райта |
migration_analysis.py |
Анализ географической миграции по поколениям |
longevity.py |
Статистика продолжительности жизни |
generation_stats.py |
Интервалы между поколениями, возраст родительства |
surname_analysis.py |
Анализ и этимология фамилий |
Семейные паттерны
| Скрипт | Назначение |
|---|---|
sibling_analysis.py |
Интервалы между рождениями сиблингов, смертность, соотношение полов |
marriage_patterns.py |
Возраст брака, эндогамия/экзогамия, разница в возрасте супругов |
multiple_marriages.py |
Повторные браки, вдовство, интервалы между браками |
Социально-историческая аналитика
| Скрипт | Назначение |
|---|---|
occupation_analysis.py |
Профессии и сословия, социальная мобильность |
war_impact.py |
Влияние войн на демографию (1812, Крымская, ПМВ, ВОВ и др.) |
epidemic_detection.py |
Детекция эпидемий по кластерам смертей |
orphan_analysis.py |
Анализ сирот и потери родителей |
Специфические паттерны
| Скрипт | Назначение |
|---|---|
twin_detection.py |
Поиск близнецов по датам рождения |
name_trends.py |
Популярность имён по периодам, тренды |
godparent_network.py |
Сеть крёстных родителей, кумовство |
cause_of_death.py |
Анализ причин смерти, категоризация |
witness_analysis.py |
Анализ свидетелей на свадьбах и крещениях |
Экспорт и обзор
| Скрипт | Назначение |
|---|---|
timeline_export.py |
Экспорт событий в JSON/CSV/HTML для визуализации |
tree_statistics.py |
Общая статистика древа, метрики качества |
Библиотека парсинга (lib/)
Общая библиотека для работы с GEDCOM файлами:
from lib import parse_gedcom, Person, Family, GedcomData
# Парсинг файла
data = parse_gedcom("tree.ged")
# Доступ к данным
person = data.get_person("@I1@")
father, mother = data.get_parents(person)
children = data.get_children(person)
siblings = data.get_siblings(person)
spouses = data.get_spouses(person)
grandparents = data.get_grandparents(person)
Модели данных
@dataclass
class Person:
id: str
name: str
given_name: str # Имя
surname: str # Фамилия
patronymic: str # Отчество
sex: str # M/F
birth_date: Optional[date]
birth_year: Optional[int]
birth_place: str
death_date: Optional[date]
death_year: Optional[int]
# ... и другие поля
@dataclass
class Family:
id: str
husband_id: Optional[str]
wife_id: Optional[str]
children_ids: List[str]
marriage_date: Optional[date]
marriage_year: Optional[int]
marriage_place: str
GEDCOM формат
Ключевые записи
0 @I123@ INDI # Персона
1 NAME Иван /Петров/ # Имя
1 BIRT # Рождение
2 DATE @#DJULIAN@ 15 MAY 1893 # Дата (юлианский календарь)
2 PLAC Вишур # Место
1 DEAT # Смерть
1 FAMC @F45@ # Семья где персона - ребёнок
1 FAMS @F67@ # Семья где персона - супруг
0 @F67@ FAM # Семья
1 HUSB @I123@ # Муж
1 WIFE @I124@ # Жена
1 CHIL @I125@ # Ребёнок
1 MARR # Брак
2 DATE @#DJULIAN@ 17 MAY 1893
Важные маркеры дат
@#DJULIAN@— дата по юлианскому календарю (старый стиль)ABT— приблизительноBEF— доAFT— послеBET ... AND ...— между
Православные свадебные традиции (до 1917)
Разрешённые периоды для венчания
1. Зимний свадебник (самый популярный ~66%)
- Начало: 7 января (Крещение, ст.ст.) / 19-20 января (н.ст.)
- Конец: Масленица (за 49 дней до Пасхи)
- Длительность: 4-7 недель в зависимости от Пасхи
2. Весенний свадебник (~12%)
- Начало: Красная горка (первое воскресенье после Пасхи, +7 дней)
- Конец: Неделя всех святых (воскресенье через неделю после Троицы, +56 дней после Пасхи)
- Длительность: ~7 недель
- Включает Троицу, День Святого Духа и Неделю всех святых
3. Осенний свадебник (~22%)
- Начало: Покров (1 октября ст.ст. / 14 октября н.ст.)
- Конец: Филиппово заговенье (14 ноября ст.ст. / 27 ноября н.ст.)
- Длительность: ~6 недель
Запретные периоды
- Великий пост — 48 дней до Пасхи
- Петров пост — от понедельника через неделю после Троицы (после Недели всех святых) до 29 июня (ст.ст.) включительно
- Успенский пост — 1-14 августа (ст.ст.)
- Рождественский (Филиппов) пост — 15 ноября - 24 декабря (ст.ст.)
- Святки — 25 декабря - 6 января (ст.ст.)
- Сырная (Масленичная) неделя — неделя перед Великим постом
Нетипичные периоды (не запрещены, но редки)
- Лето (июнь-август) — страда, полевые работы
- Сентябрь — уборка урожая
- Венчания в эти периоды требуют объяснения (война, беременность, междеревенский брак)
Расчёт православной Пасхи (алгоритм Гаусса)
def orthodox_easter_julian(year: int) -> tuple:
"""
Расчёт православной Пасхи по юлианскому календарю.
Возвращает (месяц, день) по старому стилю.
"""
a = year % 4
b = year % 7
c = year % 19
d = (19 * c + 15) % 30
e = (2 * a + 4 * b - d + 34) % 7
month = (d + e + 114) // 31
day = ((d + e + 114) % 31) + 1
return (month, day)
def julian_to_gregorian(year: int, month: int, day: int) -> tuple:
"""
Конвертация юлианской даты в григорианскую.
Добавляет 12 дней для 19 века, 13 дней для 20 века.
"""
from datetime import date, timedelta
if year < 1900:
delta = 12
else:
delta = 13
julian = date(year, month, day)
gregorian = julian + timedelta(days=delta)
return (gregorian.year, gregorian.month, gregorian.day)
Расчёт свадебных окон
from datetime import date, timedelta
def get_wedding_windows(year: int):
"""
Возвращает разрешённые периоды для венчания в году (юлианский календарь).
"""
easter_month, easter_day = orthodox_easter_julian(year)
easter = date(year, easter_month, easter_day)
# Зимний свадебник: Крещение (7 янв) — Масленица (за 49 дней до Пасхи)
winter_start = date(year, 1, 7) # Крещение
maslenitsa_end = easter - timedelta(days=49) # Начало Великого поста
winter_end = maslenitsa_end - timedelta(days=7) # Конец Масленицы
# Весенний свадебник: Красная горка (+7) — Неделя всех святых (+56)
krasnaya_gorka = easter + timedelta(days=7)
trinity = easter + timedelta(days=49)
spring_end = trinity + timedelta(days=7) # Неделя всех святых
# Осенний свадебник: Покров (1 окт) — Филиппово заговенье (14 ноя)
pokrov = date(year, 10, 1)
filippov = date(year, 11, 14)
return {
'winter': (winter_start, winter_end),
'spring': (krasnaya_gorka, spring_end),
'autumn': (pokrov, filippov),
'easter': easter
}
def get_forbidden_periods(year: int):
"""
Возвращает запретные периоды для венчания.
Петров пост начинается в понедельник через неделю после Троицы
(на следующий день после Недели всех святых).
"""
easter_month, easter_day = orthodox_easter_julian(year)
easter = date(year, easter_month, easter_day)
trinity = easter + timedelta(days=49)
return {
'great_lent': (easter - timedelta(days=48), easter - timedelta(days=1)),
'petrov_post': (trinity + timedelta(days=8), date(year, 6, 29)),
'assumption_post': (date(year, 8, 1), date(year, 8, 14)),
'christmas_post': (date(year, 11, 15), date(year, 12, 24)),
'svyatki': (date(year, 12, 25), date(year + 1, 1, 6)),
}
Типы аномалий для поиска
1. Брак в запретный период
Критичность: ВЫСОКАЯ
Венчание во время поста — серьёзное нарушение. Причины:
- Добрачная беременность (наиболее частая)
- Смерть одного из родителей невесты/жениха
- Военные обстоятельства
- Особое разрешение епископа
Проверка:
Если дата брака попадает в:
- Великий пост, Петров пост, Успенский пост, Рождественский пост
→ АНОМАЛИЯ: Брак в запретный период
→ Проверить дату рождения первого ребёнка
2. Брак в нетипичный период (лето/сентябрь)
Критичность: СРЕДНЯЯ
Возможные объяснения:
- Междеревенский брак (переговоры затянулись)
- Военные свадьбы (ПМВ 1914-1918)
- Добрачная беременность
- Экономические причины
3. Ребёнок рождён слишком рано после свадьбы
Критичность: ВЫСОКАЯ
Если первый ребёнок родился < 260 дней после свадьбы:
→ АНОМАЛИЯ: Возможна добрачная беременность
→ Особенно если < 200 дней — почти наверняка
Нормальные сроки:
- 260-300 дней — нормально (зачатие сразу после свадьбы)
- 200-260 дней — подозрительно
- < 200 дней — добрачная беременность
- < 100 дней — свадьба явно из-за беременности
4. Ребёнок рождён ДО свадьбы родителей
Критичность: КРИТИЧЕСКАЯ
Возможные объяснения:
- Ошибка в данных (неправильный год)
- Ребёнок от предыдущего брака/отношений
- Приёмный ребёнок
- Ребёнок родственников, записанный как свой
5. Несоответствие отчества
Критичность: СРЕДНЯЯ
Если отчество ребёнка ≠ имя отца:
→ АНОМАЛИЯ: Возможно ребёнок от другого отца
→ Или ошибка в записи
→ Или ребёнок назван в честь деда (редко)
6. Аномальный возраст при браке
Критичность: НИЗКАЯ-СРЕДНЯЯ
Нормы (крестьяне, 19 век):
- Мужчины: 18-25 лет
- Женщины: 16-22 года
Аномалии:
- Невеста старше жениха на 3+ года
- Жених < 18 или > 30 лет
- Невеста < 16 или > 25 лет
7. Высокая младенческая смертность в семье
Критичность: ИНФОРМАЦИОННАЯ
Если > 40% детей умерли в младенчестве:
→ Возможно эпидемия, плохие условия, генетические проблемы
Команды для поиска в GEDCOM
Найти все браки
grep -n "^1 MARR" tree.ged
Найти браки с датами
grep -B2 -A5 "^1 MARR" tree.ged | grep -A3 "MARR"
Найти конкретную семью
grep -A30 "^0 @F18@ FAM" tree.ged
Найти персону по имени
grep -B2 -A20 "NAME.*Иванов" tree.ged
Найти детей семьи
grep "CHIL" tree.ged | grep "@F18@" -A1
Извлечь все даты браков до 1930
grep -B5 "^2 DATE.*@#DJULIAN@.*18[0-9][0-9]\|^2 DATE.*@#DJULIAN@.*19[0-2][0-9]" tree.ged | grep -A1 "MARR"
Алгоритм полного анализа
Шаг 1: Извлечение браков
- Найти все записи FAM с датами MARR
- Извлечь ID мужа, жены, дату, место
- Отфильтровать браки до 1930 (или другой даты)
Шаг 2: Классификация дат
Для каждого брака:
- Определить год
- Рассчитать Пасху этого года
- Определить свадебные окна
- Классифицировать дату:
- Типичная (в окне)
- Нетипичная (лето/сентябрь)
- Запретная (пост)
Шаг 3: Проверка детей
Для нетипичных/запретных браков:
- Найти первого ребёнка
- Вычислить дни между свадьбой и рождением
- Если < 260 дней → флаг добрачной беременности
Шаг 4: Формирование отчёта
ТИПИЧНЫЕ БРАКИ: XX (YY%)
НЕТИПИЧНЫЕ: XX (YY%)
ЗАПРЕТНЫЕ: XX (YY%)
Детальный список аномалий:
1. [ДАТА] [Жених + Невеста] - [Тип аномалии] - [Причина]
Интерпретация результатов
Брак в Петров пост + ребёнок через 60-100 дней
Вывод: Добрачная беременность. Свадьба экстренная, священник закрыл глаза на нарушение.
Два брака из одной деревни в июле 1916
Вывод: Военные свадьбы (ПМВ). Молодые люди женились перед отправкой на фронт.
Сентябрьский брак между людьми из разных деревень
Вывод: Междеревенские переговоры затянулись. Не аномалия, а логистика.
Ребёнок с годом рождения ДО свадьбы родителей
Вывод: Требует проверки источника. Возможно:
- Ошибка при вводе данных
- Приёмный ребёнок
- Ребёнок от другого отца/матери
Пример вывода анализа
================================================================================
АНАЛИЗ ДАТ БРАКОВ ДО 1930 ГОДА
================================================================================
Всего браков с точными датами: 46
СТАТИСТИКА:
- Типичные (в традиционные периоды): 41 (89%)
- Нетипичные (лето/сентябрь): 4 (8%)
- В запретные периоды: 1 (2%)
================================================================================
АНОМАЛИИ
================================================================================
❌ ЗАПРЕТНЫЙ ПЕРИОД:
📅 17.05.1893 (ст.ст.)
👫 Терентий Ефстафьев Аверин + Дарья Фролова Санникова
⚠️ Венчание в ПЕРВЫЙ ДЕНЬ Петрова поста
🔍 Первый ребёнок: 20.07.1893 (через 64 дня!)
💡 Причина: Добрачная беременность
⚠️ НЕТИПИЧНЫЕ ДАТЫ:
📅 20.09.1882 — Никита Кондратьев + Христина Кущова
💡 Причина: Междеревенский брак (невеста из д. Шакшино)
📅 08.07.1916 — Василий Кондратьев + Евдокия Ермолаева
📅 21.07.1916 — Пётр Аверин + Ольга Колягина
💡 Причина: Военные свадьбы (ПМВ, перед отправкой на фронт)
Связанные исследования
После выявления аномалии рекомендуется:
- Проверить первого ребёнка — дата рождения, выжил ли
- Проверить судьбу семьи — смертность детей, продолжительность жизни
- Найти родственные связи — братья/сёстры с похожими аномалиями
- Проверить исторический контекст — война, эпидемия, голод
Ограничения
- Анализ работает только с датами в формате GEDCOM
- Расчёт Пасхи точен для 1800-2099 годов
- Юлианский/григорианский календарь: данные до 1918 обычно в юлианском
- Региональные особенности могут влиять на традиции