Compare commits
75 Commits
b205d7211e
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eb4c3fce2d | ||
|
|
a80e20862c | ||
|
|
216cf27e1b | ||
|
|
6bddd048ca | ||
|
|
7f880df10c | ||
|
|
fd3225b8b3 | ||
|
|
32c1955305 | ||
|
|
eb295fdf41 | ||
|
|
4ebb210103 | ||
|
|
3595549e62 | ||
|
|
e61c314311 | ||
|
|
304c3cc1d4 | ||
|
|
457a1d397b | ||
|
|
96910eea02 | ||
|
|
f180169558 | ||
|
|
8456b95098 | ||
|
|
ac172c0357 | ||
|
|
d04ae45f10 | ||
|
|
9f012896d8 | ||
|
|
80a547df3b | ||
|
|
8af5a68a39 | ||
|
|
b71d1d4809 | ||
|
|
424e72f232 | ||
|
|
709bb61cf3 | ||
|
|
7d93ef9790 | ||
|
|
1bfac10d9a | ||
|
|
48d07c7d65 | ||
|
|
d21f1db4bf | ||
|
|
2ad1e0c48d | ||
|
|
b5d706683c | ||
|
|
344ee7a343 | ||
|
|
9a36e5d7d2 | ||
|
|
8ff36d994d | ||
|
|
ee294e1d37 | ||
|
|
775c3e6936 | ||
|
|
7e995357f9 | ||
|
|
170f9555d2 | ||
|
|
6af8d049b9 | ||
|
|
3ba1a5da15 | ||
|
|
2eebeefdde | ||
|
|
aae89afff0 | ||
|
|
4c78c1990f | ||
|
|
6bb96d67de | ||
|
|
971107a38e | ||
|
|
8a4d5e673a | ||
|
|
ffa3fc8b00 | ||
|
|
0d95d51d55 | ||
|
|
df0bbb0f4b | ||
|
|
72133bd71f | ||
|
|
c0d7ce44c7 | ||
|
|
dba60d8a77 | ||
|
|
49fa395a10 | ||
|
|
8d50afe15b | ||
|
|
719826c1a5 | ||
|
|
744f329f68 | ||
|
|
d648934dd3 | ||
|
|
9c0dd24b78 | ||
|
|
87c033da3a | ||
|
|
e36e9f8bbb | ||
|
|
38b092b567 | ||
|
|
3c66d4a3d6 | ||
|
|
70998fe74b | ||
|
|
185aa1c47c | ||
|
|
4f53829af4 | ||
|
|
a2cb0a4ca1 | ||
|
|
a6d1e86cda | ||
|
|
1b00fb9950 | ||
|
|
7cc2691693 | ||
|
|
b92c2fcc1a | ||
|
|
fbe8ec627a | ||
|
|
e464dde870 | ||
|
|
e3aa74b1af | ||
|
|
0e5036527a | ||
|
|
993a601e21 | ||
|
|
380e1b0295 |
1
.gitignore
vendored
@@ -1 +1,2 @@
|
|||||||
venv/
|
venv/
|
||||||
|
*.bak
|
||||||
|
|||||||
217
docs/common/ach.md
Normal file
@@ -0,0 +1,217 @@
|
|||||||
|
# Немного про принятие решений и нейросети
|
||||||
|
|
||||||
|
## Мотивация
|
||||||
|
|
||||||
|
Сейчас очень распространились нейросети различных форматов: для работы
|
||||||
|
с текстом, видео, аудио, для обработки и прогнозирования данных. В
|
||||||
|
твиттере ажиотаж вокруг новой возможности ChatGPT: обработка
|
||||||
|
изображений в стиле студии Ghibli, известной по фильмам "Мой сосед
|
||||||
|
Тоторо", "Унесенные призраками" и пр.
|
||||||
|
|
||||||
|
Нейросети применяются не только для "развлечений", но и в весьма
|
||||||
|
ответственных областях, например, анализ снимков рентгена, разработке
|
||||||
|
программ. Для последнего даже был придуман термин [Vibe Coding](https://en.wikipedia.org/wiki/Vibe_coding).
|
||||||
|
|
||||||
|
Я, в некоторой степени, являюсь луддитом по отношению к нейросетям,
|
||||||
|
которые генерируют тексты. Это обусловлено преимущественно тем, что
|
||||||
|
люди относятся к ним, как к некой "палочке-выручалочке", которая
|
||||||
|
представляет собой кнопку "сделать красиво". Такой подход не только
|
||||||
|
снижает *критичное отношение* к окружающему миру (зачем придумывать
|
||||||
|
решение, если нейросеть может сгенерировать его за меня, *даже если он
|
||||||
|
будет некорректный*), но уменьшает общее качество деятельности.
|
||||||
|
|
||||||
|
Но даже так, я не являюсь противником нейросетей *просто по
|
||||||
|
существу*. У всего есть качественные области применения, иногда не
|
||||||
|
совсем очевидные.
|
||||||
|
|
||||||
|
Здесь я хочу рассказать об **анализе конкурирующих гипотез**,
|
||||||
|
**мозговом штурме** и **попытке применения в них нейросетей**.
|
||||||
|
|
||||||
|
## Большие языковые модели
|
||||||
|
|
||||||
|
Должен признать, что у меня весьма смутное представление о работе
|
||||||
|
таких нейросетей *под капотом*.
|
||||||
|
|
||||||
|
В моем понимании, суть их работы заключается в том, при анализе
|
||||||
|
запроса любого толка, они "понимают", какие слова будут уместны в
|
||||||
|
контексте этого запроса (получается такая очень сложная "китайская
|
||||||
|
комната"[2]).
|
||||||
|
|
||||||
|
Результатом же работы нейросети является текст, который я воспринимаю
|
||||||
|
как *случайное число*, которое параметризовали запросом (*prompt*),
|
||||||
|
примерно как случайное число из нормального распределения
|
||||||
|
параметризуется математическим ожиданием и дисперсией. Хотя, есть и
|
||||||
|
[другое мнение](https://x.com/tsoding/status/1896205552415658463).
|
||||||
|
|
||||||
|
А если есть случайность, то значит можно её можно использовать.
|
||||||
|
|
||||||
|
## Суть анализа конкурирующих гипотез
|
||||||
|
|
||||||
|
**Анализ конкурирующих гипотез** - методология, разработанная Ричардом
|
||||||
|
Хоером в 70-х годах. Целью создания метода было уменьшение влияния
|
||||||
|
когнитивных сдвигов (*bias*) на работу аналитиков при анализе и принятии
|
||||||
|
решений.
|
||||||
|
|
||||||
|
Особенность метода заключается в том, что вместо сопоставления каждой
|
||||||
|
гипотезе всех доказательств, наоборот, каждое доказательство
|
||||||
|
противопоставляется всем гипотезам.
|
||||||
|
|
||||||
|
Пошаговая инструкция к методу:
|
||||||
|
|
||||||
|
1. Определить все **возможные** гипотезы. Лучше использовать *команду
|
||||||
|
аналитиков* с различным опытом, чтобы реализовать **мозговой
|
||||||
|
штурм**.
|
||||||
|
2. Создать список всех существенных доказательств, аргументов "за" и
|
||||||
|
"против, а также фактов, которые могут помочь в анализе гипотез.
|
||||||
|
3. Подготовить матрицу, где номер строки будет отвечать за номер
|
||||||
|
аргумента, а номер столбца за номер гипотезы.
|
||||||
|
4. Проверить матрицу: уточнить формулировку гипотез, удалить аргументы,
|
||||||
|
которые не имеют диагностической ценности.
|
||||||
|
5. Сопоставьте каждое доказательство каждой гипотезе. Двигайтесь
|
||||||
|
по столбцам.
|
||||||
|
6. Проанализируйте, как устойчивы ваши заключение к аргумента.
|
||||||
|
Посмотрите, как изменится вывод в случае, если какие-то аргументы
|
||||||
|
окажутся ложными.
|
||||||
|
7. Составьте отчет. Проверьте правдоподобность каждой гипотезы, *не
|
||||||
|
только самой приятной*.
|
||||||
|
8. Оцените дальнейшие шаги для улучшения оценки.
|
||||||
|
|
||||||
|
Можно долго вдаваться в детали реализации метода. В нашем случае, нас
|
||||||
|
интересует часть, где необходимо придумать как можно большее число
|
||||||
|
вариантов, используя **мозговой штурм**.
|
||||||
|
|
||||||
|
### Применение нейросетей
|
||||||
|
|
||||||
|
Когда нет большой *команды аналитиков*, можно попробовать заменить их
|
||||||
|
нейросетью. В данном случае, нейросеть можно применить в двух местах:
|
||||||
|
|
||||||
|
1. В п. 1 для определения всех **возможных** гипотез. Само собой,
|
||||||
|
качество этих гипотез определяет аналитик, но их генерацию можно
|
||||||
|
частично делегировать ИИ.
|
||||||
|
2. В п.2 можно попробовать определить области, где **искать
|
||||||
|
доказательства** за и против. Нужно помнить, что доказательства
|
||||||
|
также могут представлять собой *отсутствие* чего-либо.
|
||||||
|
|
||||||
|
## Пример
|
||||||
|
|
||||||
|
Приведу пример (полученный также с помощью ИИ): "Почему в городе
|
||||||
|
резко выросло число ДТП на конкретном перекрестке?".
|
||||||
|
|
||||||
|
Полученный список гипотез:
|
||||||
|
|
||||||
|
```
|
||||||
|
- Инфраструктурные факторы
|
||||||
|
1. **Изменение дорожной разметки или знаков**: Неправильно
|
||||||
|
нанесенная разметка, противоречивые знаки или их отсутствие.
|
||||||
|
2. **Неисправность светофора**: Сбои в работе (например, мигающий
|
||||||
|
желтый сигнал), некорректные временные интервалы.
|
||||||
|
3. **Сужение полос** из-за ремонтных работ, парковки или временных
|
||||||
|
ограждений.
|
||||||
|
4. **Новые препятствия**: Установка рекламных щитов, столбов,
|
||||||
|
деревьев, ограничивающих обзор.
|
||||||
|
5. **Плохое состояние дорожного покрытия**: Выбоины, ледяная
|
||||||
|
корка, отсутствие освещения в темное время суток.
|
||||||
|
6. **Изменение типа перекрестка**: Например, переход от светофора
|
||||||
|
к круговому движению без должного информирования.
|
||||||
|
|
||||||
|
- Транспортный поток
|
||||||
|
7. **Рост трафика** из-за открытия новых ТЦ, офисов, жилых
|
||||||
|
комплексов.
|
||||||
|
8. **Перенаправление движения** с других улиц из-за ремонта,
|
||||||
|
аварий или изменений в маршрутах.
|
||||||
|
9. **Увеличение грузового транспорта**: Новые логистические
|
||||||
|
маршруты через перекресток.
|
||||||
|
10. **Активность общественного транспорта**: Новые автобусные
|
||||||
|
остановки или троллейбусные линии.
|
||||||
|
|
||||||
|
- Человеческий фактор
|
||||||
|
11. **Нарушение ПДД водителями**: Частые проезды на красный свет,
|
||||||
|
превышение скорости, агрессивное вождение.
|
||||||
|
12. **Низкая видимость пешеходов**: Отсутствие зебры, освещения
|
||||||
|
или знаков у пешеходного перехода.
|
||||||
|
13. **Отвлекающие факторы**: Яркая реклама, использование
|
||||||
|
телефонов за рулем.
|
||||||
|
14. **Новички на дороге**: Увеличение числа неопытных водителей
|
||||||
|
(например, из-за новой автошколы поблизости).
|
||||||
|
|
||||||
|
- Внешние условия
|
||||||
|
15. **Погодные аномалии**: Гололед, туман, дождь, слепящее солнце
|
||||||
|
в определенные часы.
|
||||||
|
16. **Сезонные факторы**: Туристы, листопад, снежные заносы.
|
||||||
|
17. **Животные на дороге**: Бродячие собаки, птицы или дикие
|
||||||
|
животные, вызывающие резкие торможения.
|
||||||
|
|
||||||
|
- Технические причины
|
||||||
|
18. **Неисправности автомобилей**: Массовые отзывы авто из-за
|
||||||
|
брака тормозных систем.
|
||||||
|
19. **Сбои в системах помощи водителю**: Например, ошибки в
|
||||||
|
навигаторах, предлагающих опасные маневры.
|
||||||
|
20. **Электромагнитные помехи**, влияющие на работу датчиков или
|
||||||
|
светофоров.
|
||||||
|
|
||||||
|
- Организационные и социальные факторы
|
||||||
|
21. **Снижение контроля со стороны ГИБДД**: Уменьшение числа
|
||||||
|
патрулей или камер фиксации нарушений.
|
||||||
|
22. **Новые правила движения**, которые водители не успели
|
||||||
|
изучить.
|
||||||
|
23. **Вандализм**: Повреждение знаков, светофоров или разметки.
|
||||||
|
24. **Массовые мероприятия**: Концерты, митинги или фестивали,
|
||||||
|
создающие заторы и невнимательность.
|
||||||
|
|
||||||
|
- Статистические аномалии
|
||||||
|
25. **Случайная кластеризация**: Краткосрочный всплеск аварий без
|
||||||
|
системной причины.
|
||||||
|
26. **Изменение методики учета ДТП**: Теперь фиксируются даже
|
||||||
|
мелкие столкновения, которые раньше игнорировались.
|
||||||
|
27. **Ошибки в данных**: Технические сбои при сборе статистики.
|
||||||
|
```
|
||||||
|
|
||||||
|
Хочется обратить внимание, что гипотез очень много и часть из низ
|
||||||
|
можно отмести в зависимости от контекста исследования. Но эту задачу
|
||||||
|
**должен делать аналитик**.
|
||||||
|
|
||||||
|
Ответ на вопрос: "где искать доказательства":
|
||||||
|
|
||||||
|
```
|
||||||
|
- Данные ГИБДД: Статистика нарушений, протоколы ДТП, видео с камер.
|
||||||
|
- Дорожные службы: Отчеты о ремонтах, изменениях разметки, проверках
|
||||||
|
светофоров.
|
||||||
|
- Метеорологические службы: Погодные сводки на даты аварий.
|
||||||
|
- Соцсети и СМИ: Жалобы водителей, репортажи о проблемах на
|
||||||
|
перекрестке.
|
||||||
|
- Технические данные: Логи навигаторов (Яндекс.Пробки, Google Maps),
|
||||||
|
отчеты автопроизводителей.
|
||||||
|
```
|
||||||
|
|
||||||
|
На основе полученных ответов можно пробовать строить анализ.
|
||||||
|
|
||||||
|
## Выводы
|
||||||
|
|
||||||
|
В заключении этого небольшого текста, хочу отметить несколько выводов:
|
||||||
|
|
||||||
|
1. Данная заметка не является инструкцией в стиле "вы используете
|
||||||
|
языковые модели неправильно". Здесь я просто хочу высказать мнение
|
||||||
|
касательно ИИ и отметить, какое применение я вижу у этого
|
||||||
|
инструмента.
|
||||||
|
2. В моем понимании, нейросети подойдут в тех случаях, когда нужно
|
||||||
|
применить **мозговой штурм**: составление гипотез, поиск
|
||||||
|
доказательств, составление списка действия для решения задачи в
|
||||||
|
методологии *GTD*.
|
||||||
|
3. Не стоит отдавать под контроль ИИ принятие решений на _любом
|
||||||
|
уровне_. Все логические выкладки должен делать аналитик, который
|
||||||
|
использует языковую модель как инструмент.
|
||||||
|
4. Думаю, обращаться за помощью к нейросетям, нужно если не в
|
||||||
|
*последнюю очередь*, то хотя бы не сразу. Во-первых, стоит не
|
||||||
|
забывать про собственное *критичное отношение* к миру, а во-вторых,
|
||||||
|
цель **мозгового штурма** -- это сбор _всех_ возможных вариантов,
|
||||||
|
которые могут пройти ниже радаров нейросети, и про которые потом не
|
||||||
|
станет думать аналитик, будучи отвлеченный анализом результатов.
|
||||||
|
|
||||||
|
По итогу, я убежден, что языковые модели -- это *инструмент*, который
|
||||||
|
можно применить во множестве областей, но это все же *инструмент*. Он
|
||||||
|
не решит все проблемы за вас, но поможет вам решить ваши проблемы.
|
||||||
|
|
||||||
|
## Источники
|
||||||
|
|
||||||
|
1. [Psychology of intelligence analysis](https://www.amazon.com/Psychology-Intelligence-Analysis-Richards-Heuer/dp/B0016OST3O)
|
||||||
|
2. [Китайская комната](https://ru.wikipedia.org/wiki/%D0%9A%D0%B8%D1%82%D0%B0%D0%B9%D1%81%D0%BA%D0%B0%D1%8F_%D0%BA%D0%BE%D0%BC%D0%BD%D0%B0%D1%82%D0%B0)
|
||||||
3
docs/common/index.md
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# Общие заметки
|
||||||
|
|
||||||
|
## 2025-04-23 [Немного про принятие решений и нейросети](ach.md)
|
||||||
@@ -3,15 +3,27 @@
|
|||||||
|
|
||||||
Меня зовут Рустам.
|
Меня зовут Рустам.
|
||||||
|
|
||||||
Люблю Linux и все, что связано с ним.
|
Увлекаюсь автоматизацией, аналитикой и программированием, а также смежными
|
||||||
|
направлениями.
|
||||||
|
|
||||||
Предпочитаю командную строку графическим
|
Ввиду того, что я часто делаю "*Proof of Concept*" и "*Probe*" проекты, было
|
||||||
приложениям.
|
решено завести для этого блог.
|
||||||
|
|
||||||
Также увлекаюсь математической статистикой и машинным обучением.
|
Здесь время от времени выкладываю заметки по различным темам, которые мне
|
||||||
|
показались интересными.
|
||||||
|
|
||||||
В свободное время, если есть возможность, занимаюсь спортивным туризмом, в
|
# Технологический стэк
|
||||||
частности, горным. В 2019 году взошел на Казбек (5033 м, 2Б к.с.) и в 2021 году
|
|
||||||
— на Эльбрус (5642 м, 2А к.с.).
|
|
||||||
|
|
||||||
# TBD
|
- **Администрирование**: дистрибутивы Linux, права доступа, управление
|
||||||
|
процессами, **nginx** (веб-сервер), сетевые протоколы, ведение документации
|
||||||
|
(**mkdocs**);
|
||||||
|
- **DevOps**: основы **docker** и **ansible**, docker-compose (в т.ч.
|
||||||
|
Portainer), основы **CI/CD** (GitHub Actions, GitLab CI, Jenkins);
|
||||||
|
- **Программирование**: **python** (в том числе: numpy, scipy, pandas,
|
||||||
|
matplotlib), **bash** и zsh, **C/C++**;
|
||||||
|
- **Математика**: основы теории случайных процессов, машинное обучение,
|
||||||
|
построение критериев для проверки **гипотез**, численные методы,
|
||||||
|
моделирование (**метод отбора, MCMC, bootstrap**);
|
||||||
|
- **Вёрстка**: $\LaTeX$, Markdown, groff, HTML, CSS;
|
||||||
|
- **Общее**: чтение документации (на русском и английском), **git**,
|
||||||
|
**терминал** (vim, tmux, различные утилиты командной строки);
|
||||||
|
|||||||
BIN
docs/linux/assets/distccmon-text.png
Normal file
|
After Width: | Height: | Size: 255 KiB |
BIN
docs/linux/assets/manpage.jpg
Normal file
|
After Width: | Height: | Size: 838 KiB |
BIN
docs/linux/assets/result.png
Normal file
|
After Width: | Height: | Size: 961 KiB |
284
docs/linux/distrant.md
Normal file
@@ -0,0 +1,284 @@
|
|||||||
|
# Немного про распределенную компиляцию
|
||||||
|
|
||||||
|
## Мотивация / Введение
|
||||||
|
|
||||||
|
Мне, как любителю Linux, всегда было интересно изучить Gentoo
|
||||||
|
Linux. На это есть множество причин, сейчас не о них.
|
||||||
|
Суть в том, этап установки системы на виртуальную машину пройден и
|
||||||
|
есть желание попробовать установить на второстепенный маломощный нетбук.
|
||||||
|
Возникает проблема: Gentoo Linux -- это т.н. "source-based" дистрибутив,
|
||||||
|
т.е. она распространяется в виде исходного кода. В свою очередь, компиляция
|
||||||
|
системы на нетбуке занимает чуть больше суток (возможно, это можно поправить
|
||||||
|
более тщательной конфигурацией перед сборкой, но, на мой взгляд, это
|
||||||
|
слишком "хардкорный" путь для знакомства с системой). Конечно, компиляция
|
||||||
|
ядра, строго говоря, необязательна, так как можно поставить предварительно
|
||||||
|
скомпилированную версию. Но так неинтересно.
|
||||||
|
|
||||||
|
Таким образом, возникает вопрос -- можно ли ускорить компиляцию
|
||||||
|
на слабых ПК? Тут на помощь приходит `distcc`,
|
||||||
|
своего рода фронтенд для компиляторов C/C++.
|
||||||
|
|
||||||
|
Сегодня мы хотим посмотреть на возможность компиляции ядра Linux (минимальной
|
||||||
|
конфигурации `tinyconfig`) на двух виртуальных машинах с разными
|
||||||
|
характеристиками. Но для этого нужно рассказать про утилиту `vagrant`,
|
||||||
|
конфигуратор виртуальных машин.
|
||||||
|
|
||||||
|
## Vagrant
|
||||||
|
|
||||||
|
Vagrant[^1] (с англ. — «бродяга») — свободное и открытое программное
|
||||||
|
обеспечение для создания и конфигурирования виртуальной среды разработки.
|
||||||
|
Является обёрткой для программного обеспечения виртуализации, например
|
||||||
|
VirtualBox, и средств управления конфигурациями, таких как Chef, Salt и
|
||||||
|
Puppet.
|
||||||
|
|
||||||
|
Данная утилита полезна тем, что позволяет, используя шаблоны виртуальных
|
||||||
|
машин, запускать их. Для описания стэка требуется один т.н. Vagrantfile.
|
||||||
|
Она может работать совместно с qemu, VirtualBox, VMWare и пр.
|
||||||
|
|
||||||
|
О vagrant стоит знать потому, что в какой момент, эксперементируя с
|
||||||
|
виртуальными машинами, надоест каждый раз их устанавливать в условном VMWare.
|
||||||
|
|
||||||
|
## Distcc
|
||||||
|
|
||||||
|
distcc[^2] (от англ. distributed C/C++/ObjC compiler) — инструмент,
|
||||||
|
позволяющий компилировать исходные коды при помощи
|
||||||
|
компиляторов C/C++/ObjC на удалённых машинах, что ускоряет процесс компиляции.
|
||||||
|
|
||||||
|
Важно понимать, что это своего рода фронтенд для компиляторов,
|
||||||
|
сам по себе он не компилирует код.
|
||||||
|
|
||||||
|
## Компиляция
|
||||||
|
|
||||||
|
### Демонстрация стенда
|
||||||
|
|
||||||
|
Для начала построчно рассмотрим Vagrantfile.
|
||||||
|
При его написании используется язык Ruby.
|
||||||
|
|
||||||
|
Описание "шаблона" для виртуальных машин. В данном случае это Debian
|
||||||
|
12 Bookworm.
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
# Default box
|
||||||
|
box_name = "debian.jessie64.libvirt.box"
|
||||||
|
```
|
||||||
|
|
||||||
|
Файл можно скачать с сайта HashiCorp.
|
||||||
|
|
||||||
|
Описание виртуальной машины, на которой будет основная компиляция:
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
# Master
|
||||||
|
master_node = {
|
||||||
|
:hostname => "master", :ip => "10.200.1.2", :memory => 1024, :cpu => 1
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Характеристики:
|
||||||
|
|
||||||
|
- IP: 10.200.1.2,
|
||||||
|
- RAM: 1Gb,
|
||||||
|
- 1 поток.
|
||||||
|
|
||||||
|
Они похожи на характеристики моего нетбука, но занижены в целях демонстрации.
|
||||||
|
|
||||||
|
Описание второстепенной виртуальной машины:
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
# List of slaves
|
||||||
|
slaves = [
|
||||||
|
{ :memory => 4096, :cpu => 4 },
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
Характеристики:
|
||||||
|
|
||||||
|
- RAM: 4Gb,
|
||||||
|
- 4 потока.
|
||||||
|
|
||||||
|
Скрипт для автоматической установки зависимостей:
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
$distcc_install = <<-SCRIPT
|
||||||
|
apt update
|
||||||
|
apt install -y make distcc gcc g++ tmux libz-dev git fakeroot build-essential ncurses-dev xz-utils libssl-dev bc flex libelf-dev bison time neofetch
|
||||||
|
SCRIPT
|
||||||
|
```
|
||||||
|
|
||||||
|
Старт конфигурации виртуальных машин:
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
Vagrant.configure("2") do |config|
|
||||||
|
```
|
||||||
|
|
||||||
|
Конфигурация основной машины:
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
# Master node's config
|
||||||
|
config.vm.box_check_update = false
|
||||||
|
config.vm.define master_node[:hostname] do |nodeconfig|
|
||||||
|
nodeconfig.vm.box = box_name
|
||||||
|
nodeconfig.vm.hostname = master_node[:hostname]
|
||||||
|
nodeconfig.vm.network(:private_network, ip: master_node[:ip])
|
||||||
|
nodeconfig.vm.provision "shell", inline: $distcc_install
|
||||||
|
nodeconfig.vm.provision "file", source: "./linux-6.13.tar.gz", destination: "~/linux-6.13.tar.gz"
|
||||||
|
nodeconfig.vm.provider :libvirt do |vb|
|
||||||
|
vb.memory = master_node[:memory]
|
||||||
|
vb.cpus = master_node[:cpu]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
В нем:
|
||||||
|
|
||||||
|
1. Отключаются обновления,
|
||||||
|
2. Задаются характеристики ВМ,
|
||||||
|
3. Запускается скрипт установки зависимостей,
|
||||||
|
4. Копируется
|
||||||
|
[архив](https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.13.tar.gz)
|
||||||
|
с исходным кодом ядра (должен лежать в директории с Vagrantfile).
|
||||||
|
|
||||||
|
Конфигурация второстепенных машин:
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
# Slaves configs
|
||||||
|
slaves.each_with_index do |slave, i|
|
||||||
|
config.vm.box_check_update = false
|
||||||
|
config.vm.define "slave-#{ i+1 }" do |nodeconfig|
|
||||||
|
# Default box-name (cause I have only it)
|
||||||
|
nodeconfig.vm.box = box_name
|
||||||
|
|
||||||
|
# Hostname: slave-N
|
||||||
|
nodeconfig.vm.hostname = "slave-#{ i+1 }"
|
||||||
|
|
||||||
|
# IP-address: 10.200.1.{N+2}
|
||||||
|
nodeconfig.vm.network :private_network, ip: "10.200.1.#{ i+3 }"
|
||||||
|
nodeconfig.vm.provision "shell", inline: $distcc_install
|
||||||
|
nodeconfig.vm.provider :libvirt do |vb|
|
||||||
|
vb.memory = slave[:memory]
|
||||||
|
vb.cpus = slave[:cpu]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
Стоит обратить внимание, что IP задается автоматически, начиная от
|
||||||
|
`10.200.1.3` и далее. Сделано это на случай нескольких ВМ.
|
||||||
|
|
||||||
|
### Компиляция на одной машине (gcc)
|
||||||
|
|
||||||
|
Для начала запустим стенд командой `vagrant up`. На моем ноутбуке это занимает
|
||||||
|
примерно 127 секунд.
|
||||||
|
|
||||||
|
Далее необходимо подключиться к главной машине и распаковать исходники ядра[^3]:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
vagrant ssh master
|
||||||
|
tar xvf linux-6.13.tar.gz
|
||||||
|
cd linux-6.13
|
||||||
|
```
|
||||||
|
|
||||||
|
Создаем файл минимальной конфигурации
|
||||||
|
(с остальными вариантам можно ознакомиться командой `make help | less`):
|
||||||
|
|
||||||
|
```shell
|
||||||
|
make tinyconfig
|
||||||
|
```
|
||||||
|
|
||||||
|
> **Важно**: для чистоты эксперимента все замеры делаются после команды `make
|
||||||
|
distclean` (см. `make help`).
|
||||||
|
|
||||||
|
Запускаем компиляцию с замером времени:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
time -p make CC=gcc
|
||||||
|
```
|
||||||
|
|
||||||
|
### Компиляция на одной машине (distcc)
|
||||||
|
|
||||||
|
По смыслу, все тоже самое, только нужно указать distcc, на каких хостах
|
||||||
|
можно компилировать:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
export DISTCC_HOSTS="localhost"
|
||||||
|
```
|
||||||
|
|
||||||
|
Запускаем компиляцию с замером времени:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
time -p make CC="distcc gcc"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Компиляция на двух машинах (distcc)
|
||||||
|
|
||||||
|
Для запуска распределенной компиляции, нужно сначала запустить демон на
|
||||||
|
второй виртуальной машине. Для этого подключаемся к ней и запускаем его:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
vagrant ssh slave-1
|
||||||
|
distccd --daemon --allow-private
|
||||||
|
```
|
||||||
|
|
||||||
|
Параметр `--allow-private` разрешает стучаться только с приватных сетей.
|
||||||
|
|
||||||
|
Для проверки можно:
|
||||||
|
|
||||||
|
1. На второй машине проверить открытые порты: `ss -ntlp | grep 3632`,
|
||||||
|
2. С основной машины постучаться в этот порт: `telnet 10.200.1.3 3632`
|
||||||
|
(выход на `C-] C-d`).
|
||||||
|
|
||||||
|
Теперь нужно добавить хост, чтобы на нем можно было удаленно компилировать.
|
||||||
|
Для этого на основной машине:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
export DISTCC_HOSTS="localhost 10.200.1.3"
|
||||||
|
```
|
||||||
|
|
||||||
|
Для проверки можно посмотреть список хостов для компиляции: `distcc --show-hosts`.
|
||||||
|
|
||||||
|
Запустим компиляцию на 5 потоках с замером времени:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
time -p make -j5 CC="distcc gcc"
|
||||||
|
```
|
||||||
|
|
||||||
|
Мониторить компиляцию можно с помощью команды (на основной машине):
|
||||||
|
|
||||||
|
```shell
|
||||||
|
watch -n 1 distccmon-text
|
||||||
|
```
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### Таблица сравнения
|
||||||
|
|
||||||
|
|Итерация|Одна машина (gcc), с|Одна машина (distcc), с|Две машины (distcc), с|
|
||||||
|
|:------:|:------------------:|:---------------------:|:--------------------:|
|
||||||
|
| 1 | 176 | 176 | 111 |
|
||||||
|
| 2 | 186 | 162 | 109 |
|
||||||
|
| 3 | 187 | 174 | 127 |
|
||||||
|
|Среднее | 183 | 170 | 115 |
|
||||||
|
|
||||||
|
## Итог
|
||||||
|
|
||||||
|
Можно увидеть, что такая параллелизация дает прирост 37%.
|
||||||
|
Сложно сказать, можно ли разогнать сильнее, так как многое зависит от
|
||||||
|
правил компиляции (например, их нельзя распараллелить больше чем на 5 потоков).
|
||||||
|
|
||||||
|
Очевидно, что распределенная компиляция при прочих равных будет проигрывать
|
||||||
|
параллельной, так как общение между потоками по определению быстрее.
|
||||||
|
Но для слабых машин это отлично подходит. К сожалению, у данного метода есть
|
||||||
|
существенные ограничения:
|
||||||
|
|
||||||
|
1. Версии gcc и distcc должны совпадать (хотя, пишут, что достаточно
|
||||||
|
совпадения только мажорных версий).
|
||||||
|
2. В некоторых случаях нет возможности общения по TCP и требуется подключение по
|
||||||
|
SSH. Например, когда есть ограничения безопасности или при сложной организации
|
||||||
|
сети. Определенно, такое подключение будет медленнее.
|
||||||
|
|
||||||
|
Все материалы стенда можно найти в
|
||||||
|
[репозитории](https://github.com/rustbas/disgrant/) на Github.
|
||||||
|
|
||||||
|
[^1]: Википедия [Vagrant](https://ru.wikipedia.org/wiki/Vagrant).
|
||||||
|
[^2]: Википедия [distcc](https://ru.wikipedia.org/wiki/Distcc).
|
||||||
|
[^3]: Исходный код ядра можно найти [здесь](https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.13.tar.gz).
|
||||||
@@ -1 +1,6 @@
|
|||||||
# Linux
|
# Linux
|
||||||
|
|
||||||
|
## 2024-11-01 [Немного про мануалы](manpage.md)
|
||||||
|
|
||||||
|
## 2025-01-24 [Немного про распределенную компиляцию](distrant.md)
|
||||||
|
|
||||||
|
|||||||
110
docs/linux/manpage.md
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
# Немного про мануалы
|
||||||
|
|
||||||
|
## Мотивация
|
||||||
|
|
||||||
|
Какое-то время назад возникла задача:
|
||||||
|
написать мануал к репозиторию с дотфайлами.
|
||||||
|
|
||||||
|
Вообще, сложилось впечатление, что сейчас большая часть документации создается
|
||||||
|
либо автоматически, либо техническими писателями. Причем сама документация
|
||||||
|
лежит на каком-то сайте, например, **github.io** и нечасто можно получить
|
||||||
|
к ней доступ офлайн. В таких случаях спасают `man`-ы.
|
||||||
|
|
||||||
|
## Способы
|
||||||
|
|
||||||
|
Вообще, сам мануал -- это документ для [препроцессора](https://en.wikipedia.org/wiki/Groff_(software)) `groff`, который
|
||||||
|
умеет читать команда `man`, и который можно перевести в другие форматы,
|
||||||
|
при желании.
|
||||||
|
|
||||||
|
[Пример](https://www.cyberciti.biz/faq/linux-unix-creating-a-manpage/) (`test.1`):
|
||||||
|
|
||||||
|
```groff
|
||||||
|
.\" Manpage for nuseradd.
|
||||||
|
.\" Contact vivek@nixcraft.net.in to correct errors or typos.
|
||||||
|
.TH man 8 "06 May 2010" "1.0" "nuseradd man page"
|
||||||
|
.SH NAME
|
||||||
|
nuseradd \- create a new LDAP user
|
||||||
|
.SH SYNOPSIS
|
||||||
|
nuseradd [USERNAME]
|
||||||
|
.SH DESCRIPTION
|
||||||
|
nuseradd is high level shell program for adding users to LDAP server. On Debian, administrators should usually use nuseradd.debian(8) instead.
|
||||||
|
.SH OPTIONS
|
||||||
|
The nuseradd does not take any options. However, you can supply username.
|
||||||
|
.SH SEE ALSO
|
||||||
|
useradd(8), passwd(5), nuseradd.debian(8)
|
||||||
|
.SH BUGS
|
||||||
|
No known bugs.
|
||||||
|
.SH AUTHOR
|
||||||
|
Vivek Gite (vivek@nixcraft.net.in)
|
||||||
|
```
|
||||||
|
|
||||||
|
Если выполнить команду `man ./test.1`, то увидите следующее:
|
||||||
|

|
||||||
|
|
||||||
|
Красиво, но не слишком удобно для создания. Я использовал другой -- через
|
||||||
|
конвертацию `markdown`-файлов.
|
||||||
|
|
||||||
|
## Процесс
|
||||||
|
|
||||||
|
### `pandoc`
|
||||||
|
|
||||||
|
Для начала, нужна сама [программа](https://en.wikipedia.org/wiki/Pandoc) `pandoc`. Ставим:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
sudo apt install pandoc
|
||||||
|
```
|
||||||
|
|
||||||
|
### Написание мануала
|
||||||
|
|
||||||
|
Само написание мануала, думаю, стоит опустить. Синтаксис `markdown`-а
|
||||||
|
можно посмотреть на википедии.
|
||||||
|
|
||||||
|
Есть только два нюанса при написании:
|
||||||
|
|
||||||
|
1. В начале нужно указать что-то вроде
|
||||||
|
`% dotfiles(1) | dotfiles usage documentation`
|
||||||
|
2. По умолчанию, `pandoc` распознает каждую строку как отдельный
|
||||||
|
параграф. Из-за этого между строками в результате получается
|
||||||
|
разрыв. Чтобы избежать этого, нужно в конце строки добавлять `\`.
|
||||||
|
|
||||||
|
Сконвертировать файл можно командой:
|
||||||
|
```shell
|
||||||
|
pandoc --standalone --to man manpage.md --output=dotfiles.1
|
||||||
|
```
|
||||||
|
|
||||||
|
Также, стоит отметить принятое оглавление. Есть три обязательные секции:
|
||||||
|
|
||||||
|
- **NAME** - название
|
||||||
|
- **SYNOPSIS** - краткое описание (в одну строку) команды или примеры аргументов
|
||||||
|
или ключей.
|
||||||
|
- **DESCRIPTION** - подробное описание команды
|
||||||
|
|
||||||
|
Также, можно указать:
|
||||||
|
|
||||||
|
- **OPTIONS** - описание опций/аргументов.
|
||||||
|
- **EXAMPLES** - примеры запуска.
|
||||||
|
- **FILES** - описание файлов, если есть файлы конфигурации.
|
||||||
|
- **ENVIRONMENT** - описание переменных окружения.
|
||||||
|
- **BUGS** - Известные баги/ошибки.
|
||||||
|
- **AUTHORS** - авторы.
|
||||||
|
- **SEE ALSO** - референсы к другим мануалам.
|
||||||
|
- **COPYRIGHT | LICENSE** - текст лицензии.
|
||||||
|
|
||||||
|
### Как пользоваться
|
||||||
|
|
||||||
|
Для того, чтобы можно было удобно пользоваться написанным мануалом,
|
||||||
|
нужно:
|
||||||
|
|
||||||
|
1. Сжать его -- `gzip dotfiles.1`.
|
||||||
|
2. Поместить архив в любую папку, из которой читает `man` в директорию `man1`.
|
||||||
|
|
||||||
|
Для того, чтобы узнать директории, из которых читает `man`,
|
||||||
|
можно выполнить команду `manpath`
|
||||||
|
|
||||||
|
В моем случае, я поместил все в директорию `$HOME/.local/share/man/man1`,
|
||||||
|
так как `$HOME/.local/share` это как раз `$XDG_DATA_HOME`
|
||||||
|
(см. [спецификацию XDG](https://specifications.freedesktop.org/basedir-spec/latest/)).
|
||||||
|
|
||||||
|
Результат ([репозиторий](https://github.com/rustbas/dotfilesV2/tree/potatoless-pc)):
|
||||||
|
|
||||||
|

|
||||||
BIN
docs/maths/assets/stat-madness/bootstrap.png
Normal file
|
After Width: | Height: | Size: 77 KiB |
BIN
docs/maths/assets/stat-madness/conf_interval.png
Normal file
|
After Width: | Height: | Size: 57 KiB |
BIN
docs/maths/assets/stat-madness/modeling.png
Normal file
|
After Width: | Height: | Size: 77 KiB |
BIN
docs/maths/assets/type-pred/file_sig.png
Normal file
|
After Width: | Height: | Size: 207 KiB |
BIN
docs/maths/assets/type-pred/heatmaps.png
Normal file
|
After Width: | Height: | Size: 288 KiB |
BIN
docs/maths/assets/type-pred/stats.png
Normal file
|
After Width: | Height: | Size: 79 KiB |
@@ -1,4 +1,4 @@
|
|||||||
# Приложение производящей функции последовательности к числам Фибоначчи
|
# Немного про производящие функции
|
||||||
## Мотивация
|
## Мотивация
|
||||||
|
|
||||||
Идея данной публикации родилась в процессе чтения статьи на [викиконспектах](https://neerc.ifmo.ru/wiki/index.php?title=%D0%9F%D1%80%D0%BE%D0%B8%D0%B7%D0%B2%D0%BE%D0%B4%D1%8F%D1%89%D0%B0%D1%8F_%D1%84%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D1%8F#.D0.9F.D1.80.D0.B8.D0.BC.D0.B5.D1.80.D1.8B_.D1.80.D0.B5.D1.88.D0.B5.D0.BD.D0.B8.D0.B9_.D0.B7.D0.B0.D0.B4.D0.B0.D1.87_.D0.BC.D0.B5.D1.82.D0.BE.D0.B4.D0.BE.D0.BC_.D0.BF.D1.80.D0.BE.D0.B8.D0.B7.D0.B2.D0.BE.D0.B4.D1.8F.D1.89.D0.B8.D1.85_.D1.84.D1.83.D0.BD.D0.BA.D1.86.D0.B8.D0.B9) о производящих рядах. Мне показалось очень интересным, что существует способ решения рекуррентных уравнений с помощью бесконечных сумм.
|
Идея данной публикации родилась в процессе чтения статьи на [викиконспектах](https://neerc.ifmo.ru/wiki/index.php?title=%D0%9F%D1%80%D0%BE%D0%B8%D0%B7%D0%B2%D0%BE%D0%B4%D1%8F%D1%89%D0%B0%D1%8F_%D1%84%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D1%8F#.D0.9F.D1.80.D0.B8.D0.BC.D0.B5.D1.80.D1.8B_.D1.80.D0.B5.D1.88.D0.B5.D0.BD.D0.B8.D0.B9_.D0.B7.D0.B0.D0.B4.D0.B0.D1.87_.D0.BC.D0.B5.D1.82.D0.BE.D0.B4.D0.BE.D0.BC_.D0.BF.D1.80.D0.BE.D0.B8.D0.B7.D0.B2.D0.BE.D0.B4.D1.8F.D1.89.D0.B8.D1.85_.D1.84.D1.83.D0.BD.D0.BA.D1.86.D0.B8.D0.B9) о производящих рядах. Мне показалось очень интересным, что существует способ решения рекуррентных уравнений с помощью бесконечных сумм.
|
||||||
@@ -50,6 +50,7 @@ _**Математическая индукция** — метод математ
|
|||||||
([Википедия](https://ru.wikipedia.org/wiki/%D0%9C%D0%B0%D1%82%D0%B5%D0%BC%D0%B0%D1%82%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B0%D1%8F_%D0%B8%D0%BD%D0%B4%D1%83%D0%BA%D1%86%D0%B8%D1%8F))
|
([Википедия](https://ru.wikipedia.org/wiki/%D0%9C%D0%B0%D1%82%D0%B5%D0%BC%D0%B0%D1%82%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B0%D1%8F_%D0%B8%D0%BD%D0%B4%D1%83%D0%BA%D1%86%D0%B8%D1%8F))
|
||||||
|
|
||||||
Нам понадобится этот метод для того, чтобы доказать верность формулы, которую мы получим. Применяя к нашему случаю, можно сформулировать идею доказательства так:
|
Нам понадобится этот метод для того, чтобы доказать верность формулы, которую мы получим. Применяя к нашему случаю, можно сформулировать идею доказательства так:
|
||||||
|
|
||||||
1. Нужно доказать **базу индукции**. То есть, что формула верна для $a_0$ и $a_1$.
|
1. Нужно доказать **базу индукции**. То есть, что формула верна для $a_0$ и $a_1$.
|
||||||
2. Нужно доказать **переход индукции**. В нашем случае, это означает, что нужно проверить, что формула удовлетворяет изначальному рекуррентному уравнению.
|
2. Нужно доказать **переход индукции**. В нашем случае, это означает, что нужно проверить, что формула удовлетворяет изначальному рекуррентному уравнению.
|
||||||
|
|
||||||
@@ -97,31 +98,36 @@ $$
|
|||||||
Рассмотрим $(I)$ и $(II)$.
|
Рассмотрим $(I)$ и $(II)$.
|
||||||
|
|
||||||
$$\Large{
|
$$\Large{
|
||||||
(I) = \sum_{n=2}^\infty a_{n-1} z^{n-1} = \Big<
|
(I) = \sum_{n=2}^\infty a_{n-1} z^{n-1} = \left<
|
||||||
\begin{split}
|
\begin{split}
|
||||||
k = n-1\\
|
k = n-1\\
|
||||||
n = k+1
|
n = k+1
|
||||||
\end{split}
|
\end{split}
|
||||||
\Big> = \sum_{k=1}^\infty a_{k} z^{k} =
|
\right> = \sum_{k=1}^\infty a_{k} z^{k} =
|
||||||
}$$
|
}$$
|
||||||
|
|
||||||
$$\Large{
|
$$\Large{
|
||||||
= a_0 + \sum_{k=1}^\infty a_{k} z^{k} - a_0
|
= \underbrace{a_0 + \sum_{k=1}^\infty a_{k} z^{k}}_
|
||||||
|
{\sum_{k=0}^\infty a_{k} z^{k}}
|
||||||
|
- a_0
|
||||||
= \sum_{k=0}^\infty a_{k} z^{k} - a_0 = G(z) - a_0
|
= \sum_{k=0}^\infty a_{k} z^{k} - a_0 = G(z) - a_0
|
||||||
}$$
|
}$$
|
||||||
|
|
||||||
$$\Large{
|
$$\Large{
|
||||||
(II) = \sum_{n=2}^\infty a_{n-2} z^{n-2} = \Big<
|
(II) = \sum_{n=2}^\infty a_{n-2} z^{n-2} =
|
||||||
|
\left<
|
||||||
\begin{split}
|
\begin{split}
|
||||||
k = n-2\\
|
k = n-2\\
|
||||||
n = k+2
|
n = k+2
|
||||||
\end{split}
|
\end{split}
|
||||||
\Big> = \sum_{k=0}^\infty a_{k} z^{k} = G(z)
|
\right>
|
||||||
|
= \sum_{k=0}^\infty a_{k} z^{k} = G(z)
|
||||||
}$$
|
}$$
|
||||||
|
|
||||||
Здесь мы производим замену и приводим суммы к виду $\sum_{i=0}^\infty a_iz^i$. Очевидно, значение суммы не зависит от названия счетчика $i$.
|
Здесь мы производим замену и приводим суммы к виду $\sum\limits_{i=0}^\infty a_iz^i$. Очевидно, значение суммы не зависит от названия счетчика $i$.
|
||||||
|
|
||||||
Таким образом:
|
Таким образом:
|
||||||
|
|
||||||
$$\Large{
|
$$\Large{
|
||||||
G(z) = a_0 + a_1 z + z \left( G\left(z\right) - a_0 \right) + z^2G(z) =
|
G(z) = a_0 + a_1 z + z \left( G\left(z\right) - a_0 \right) + z^2G(z) =
|
||||||
}$$
|
}$$
|
||||||
@@ -146,7 +152,7 @@ $$\Large{
|
|||||||
G(z) = \frac{a_0 +a_1z-a_0z}{1 - z - z^2}
|
G(z) = \frac{a_0 +a_1z-a_0z}{1 - z - z^2}
|
||||||
}$$
|
}$$
|
||||||
|
|
||||||
*Замечание*: получившееся дробь правильная. То есть степень многочлена в знаменателе больше, чем в числителе.
|
> *Замечание*: получившееся дробь правильная. То есть степень многочлена в знаменателе больше, чем в числителе.
|
||||||
|
|
||||||
## Разложение дроби на элементарные дроби
|
## Разложение дроби на элементарные дроби
|
||||||
|
|
||||||
@@ -204,8 +210,8 @@ a_0 + z(a_1 - a_0) = -Az + Az_2 - Bz + Bz_1 = (Az_2 + Bz_1) + z(-A -B)
|
|||||||
|
|
||||||
$$\Large{
|
$$\Large{
|
||||||
\begin{cases}
|
\begin{cases}
|
||||||
a_0 = Az_2 + B z_1\\
|
&Az_2 &+ &B z_1 &= a_0\\
|
||||||
a_1 - a_0 = -A-B
|
&A &+ &B &= a_0 - a_1
|
||||||
\end{cases}
|
\end{cases}
|
||||||
}$$
|
}$$
|
||||||
|
|
||||||
@@ -222,11 +228,11 @@ $$\Large{
|
|||||||
|
|
||||||
$$\Large{
|
$$\Large{
|
||||||
\begin{cases}
|
\begin{cases}
|
||||||
z_{1} = - \frac{1 + \sqrt{5}}{2}\\
|
z_{1} &= - \frac{1 + \sqrt{5}}{2}\\
|
||||||
z_{2} = - \frac{1 - \sqrt{5}}{2}\\
|
z_{2} &= - \frac{1 - \sqrt{5}}{2}\\
|
||||||
A = a_0 - a_1 - \frac{a_0 - a_0z_2 + a_1z_2}{z_1-z_2}\\
|
A &= a_0 - a_1 - \frac{a_0 - a_0z_2 + a_1z_2}{z_1-z_2}\\
|
||||||
B = \frac{a_0 - a_0z_2 + a_1z_2}{z_1-z_2}\\
|
B &= \frac{a_0 - a_0z_2 + a_1z_2}{z_1-z_2}\\
|
||||||
G(z) = \frac{A}{z - z_1} + \frac{B}{z - z_2}
|
G(z) &= \frac{A}{z - z_1} + \frac{B}{z - z_2}
|
||||||
\end{cases}
|
\end{cases}
|
||||||
}$$
|
}$$
|
||||||
|
|
||||||
@@ -260,6 +266,7 @@ $$\Large{
|
|||||||
}$$
|
}$$
|
||||||
|
|
||||||
Проведя аналогичные вычисления для $B$ получим:
|
Проведя аналогичные вычисления для $B$ получим:
|
||||||
|
|
||||||
$$\Large{
|
$$\Large{
|
||||||
B = \frac{a_0}{z_1-z_2} - z_2 \frac{a_0-a_1}{z_1-z_2}
|
B = \frac{a_0}{z_1-z_2} - z_2 \frac{a_0-a_1}{z_1-z_2}
|
||||||
}$$
|
}$$
|
||||||
@@ -291,8 +298,9 @@ z_1z_2 = \frac{(1+\sqrt{5})(1-\sqrt{5})}{2\cdot2} = \frac{1-5}{4} = -1
|
|||||||
}$$
|
}$$
|
||||||
|
|
||||||
Подставив результат в наше выражение:
|
Подставив результат в наше выражение:
|
||||||
|
|
||||||
$$\Large{
|
$$\Large{
|
||||||
-\frac{a_0}{-1} = a_0, \text{Q.E.D.}
|
-\frac{a_0}{-1} = a_0, \text{ Q.E.D.}
|
||||||
}$$
|
}$$
|
||||||
|
|
||||||
#### $n = 1$
|
#### $n = 1$
|
||||||
@@ -335,6 +343,7 @@ $$\Large{
|
|||||||
}$$
|
}$$
|
||||||
|
|
||||||
Как мы доказали:
|
Как мы доказали:
|
||||||
|
|
||||||
$$\Large{
|
$$\Large{
|
||||||
z_1z_2 = -1
|
z_1z_2 = -1
|
||||||
}$$
|
}$$
|
||||||
@@ -344,7 +353,9 @@ z_1z_2 = -1
|
|||||||
$$\Large{
|
$$\Large{
|
||||||
z_1+z_2 = \frac{-1-
|
z_1+z_2 = \frac{-1-
|
||||||
\cancelto{0}{\sqrt{5}+\sqrt{5}}
|
\cancelto{0}{\sqrt{5}+\sqrt{5}}
|
||||||
-1}{2} = -1
|
-1}{2} =
|
||||||
|
\frac{-1-1}{2} =
|
||||||
|
-1
|
||||||
}$$
|
}$$
|
||||||
|
|
||||||
Подставив значения в выражение, получим:
|
Подставив значения в выражение, получим:
|
||||||
@@ -360,7 +371,7 @@ $$\Large{
|
|||||||
= -\left(
|
= -\left(
|
||||||
\cancelto{0}{a_0 - a_0}
|
\cancelto{0}{a_0 - a_0}
|
||||||
-a_1
|
-a_1
|
||||||
\right) = -(-a_1) = a_1, \text{Q.E.D.}
|
\right) = -(-a_1) = a_1, \text{ Q.E.D.}
|
||||||
}$$
|
}$$
|
||||||
|
|
||||||
### Переход индукции
|
### Переход индукции
|
||||||
@@ -483,12 +494,13 @@ $$\Large{
|
|||||||
$$\Large{
|
$$\Large{
|
||||||
= -A \frac{1}{z_1^{n+3}}
|
= -A \frac{1}{z_1^{n+3}}
|
||||||
-B \frac{1}{z_2^{n+3}} =
|
-B \frac{1}{z_2^{n+3}} =
|
||||||
a_{n+2}, \text{Q.E.D.}
|
a_{n+2}, \text{ Q.E.D.}
|
||||||
}$$
|
}$$
|
||||||
|
|
||||||
## Выводы
|
## Выводы
|
||||||
|
|
||||||
В данной публикации были рассмотрены:
|
В данной публикации были рассмотрены:
|
||||||
|
|
||||||
- получение производящей функции из рекуррентного уравнения;
|
- получение производящей функции из рекуррентного уравнения;
|
||||||
- разложение функции в ряд для нахождения $n$-го члена последовательности;
|
- разложение функции в ряд для нахождения $n$-го члена последовательности;
|
||||||
- доказана верность полученной формулы с помощью математической индукции.
|
- доказана верность полученной формулы с помощью математической индукции.
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
# Математика
|
# Математика
|
||||||
|
|
||||||
# Статистика
|
## 2024-10-30 [Немного про производящие функции](gen_fun.md)
|
||||||
|
|
||||||
## 2024-09-24 [Немного про Байесовскую статистику](baes.md)
|
## 2024-09-24 [Немного про Байесовскую статистику](baes.md)
|
||||||
|
|
||||||
## 2024-10-30 [Приложение производящей функции последовательности к числам Фибоначчи](gen_fun.md)
|
## 2020-09-01 [Немного про проверку гипотез](stat-madness.md)
|
||||||
|
|
||||||
|
## 2025-05-30 [Немного про работу с файлами, numpy и предсказаниях](type-pred.md)
|
||||||
|
|||||||
199
docs/maths/stat-madness.md
Normal file
@@ -0,0 +1,199 @@
|
|||||||
|
# Немного про проверку гипотез
|
||||||
|
|
||||||
|
## Введение
|
||||||
|
|
||||||
|
Любые статистические испытания зиждятся на проверке гипотез, например:
|
||||||
|
|
||||||
|
1. Проверка действия лекарств.
|
||||||
|
2. Установление зависимости между явлениями.
|
||||||
|
3. A/B тестирование и пр.
|
||||||
|
|
||||||
|
В зависимости от вида данных, целей исследования и других факторов
|
||||||
|
можно по-разному формулировать гипотезы и по-разному их проверять.
|
||||||
|
|
||||||
|
Многое зависит от не только знаний и опыта исследователя, но и в целом
|
||||||
|
от его подхода. В процессе работы можно все меньше уделять внимание
|
||||||
|
математической составляющей и все больше полагаться на компьютер и его
|
||||||
|
вычислительные мощности.
|
||||||
|
|
||||||
|
Здесь я хочу рассказать о стадиях, через которые проходит исследователь,
|
||||||
|
в попытках упростить себе жизнь и ускорить процесс проверки гипотез.
|
||||||
|
|
||||||
|
## Небольшой ликбез
|
||||||
|
|
||||||
|
В статистике, если упростить, проверку гипотезы можно описать так:
|
||||||
|
|
||||||
|
1. По данной выборке считается статистика (т.е. функция от выборки).
|
||||||
|
2. Из распределения статистики находятся две области, где гипотеза отвергается и где нет. Исходя из этого, принимается решение.
|
||||||
|
|
||||||
|
**N.B.** Проверяется гипотеза, модель постулируется.
|
||||||
|
|
||||||
|
## Стадия 1. Строгие доказательства
|
||||||
|
|
||||||
|
На данной стадии ученый строго выводит распределения статистик, чтобы построить как можно более хорошие критерии.
|
||||||
|
|
||||||
|
$$\Large
|
||||||
|
\sqrt{n}
|
||||||
|
\frac
|
||||||
|
{\overline{\mathbb{X}} - \mu}
|
||||||
|
{S} =
|
||||||
|
\sqrt{n}
|
||||||
|
\frac
|
||||||
|
{\overline{\mathbb{X}} - \mu}
|
||||||
|
{\sigma} \cdot
|
||||||
|
\frac{1}
|
||||||
|
{\frac{S}{\sigma}} =
|
||||||
|
$$
|
||||||
|
|
||||||
|
$$\Large
|
||||||
|
= \sqrt{n}
|
||||||
|
\frac
|
||||||
|
{\overline{\mathbb{X}} - \mu}
|
||||||
|
{\sigma} \cdot
|
||||||
|
\frac{1}
|
||||||
|
{\sqrt{\frac{(n-1)S^2}{\sigma^2}\cdot
|
||||||
|
\frac{1}{n-1}
|
||||||
|
}}
|
||||||
|
$$
|
||||||
|
|
||||||
|
Получим:
|
||||||
|
|
||||||
|
$$\Large
|
||||||
|
\begin{matrix}
|
||||||
|
&\sqrt{n}
|
||||||
|
\frac{\overline{\mathbb{X}} - \mu}
|
||||||
|
{\sigma} &\sim &N(0,1) \\
|
||||||
|
&\frac{(n-1)S^2}{\sigma^2} &\sim &\chi^2(n-1)
|
||||||
|
\end{matrix}
|
||||||
|
$$
|
||||||
|
|
||||||
|
Таким образом, по [определению](https://ru.wikipedia.org/wiki/Распределение_Стьюдента#Определение):
|
||||||
|
|
||||||
|
$$\Large
|
||||||
|
\sqrt{n}
|
||||||
|
\frac
|
||||||
|
{\overline{\mathbb{X}} - \mu}
|
||||||
|
{S} \sim t(n-1).
|
||||||
|
$$
|
||||||
|
|
||||||
|
## Небольшой пример (критерий Стьюдента)
|
||||||
|
|
||||||
|
**Дано**: выборка Х объема 10
|
||||||
|
|
||||||
|
$$\Large
|
||||||
|
\mathbb{X} = \left(
|
||||||
|
\begin{matrix}
|
||||||
|
3.175 \\
|
||||||
|
4.042 \\
|
||||||
|
2.127 \\
|
||||||
|
3.841 \\
|
||||||
|
1.699 \\
|
||||||
|
2.223 \\
|
||||||
|
3.211 \\
|
||||||
|
3.33 \\
|
||||||
|
2.447 \\
|
||||||
|
2.904
|
||||||
|
\end{matrix}
|
||||||
|
\right)
|
||||||
|
$$
|
||||||
|
|
||||||
|
**Модель**: $N(\mu, \theta_2)$
|
||||||
|
|
||||||
|
**Нулевая гипотеза**: $\mu = 3$
|
||||||
|
|
||||||
|
**Решение**:
|
||||||
|
|
||||||
|
Статистика критерия:
|
||||||
|
|
||||||
|
$$\Large
|
||||||
|
T(\mathbb{X}) =
|
||||||
|
\sqrt{n}
|
||||||
|
\frac
|
||||||
|
{\overline{\mathbb{X}} - \mu}
|
||||||
|
{S}
|
||||||
|
\sim
|
||||||
|
t(n-1)
|
||||||
|
$$
|
||||||
|
|
||||||
|
Статистика равна:
|
||||||
|
|
||||||
|
$$\Large
|
||||||
|
T(\mathbb{X}) = -1.9066
|
||||||
|
$$
|
||||||
|
|
||||||
|
Пусть уровень значимости $\alpha = 0.05$.
|
||||||
|
|
||||||
|
Область, где не отвергается нулевая гипотеза: $(g_1, g_2) = (-2.262, 2.262)$, т.е. это область, которую принимает значение статистики при условии верности нулевой гипотезы с вероятностью $1 - \alpha = 0.95$. $g_1$ в данном случае это $0.025$-квантиль, а $g_2$, соотвественно, 0.975-квантиль.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Красным обозначен интервал $(g_1, g_2)$
|
||||||
|
|
||||||
|
Таким образом, нулевая гипотеза не отвергается, так как значение статистики лежит в данном интервале.
|
||||||
|
|
||||||
|
> **Примечание**: можно было выбрать доверительный интервал иначе,
|
||||||
|
> но его стараются выбрать так, чтобы минимизировать его длину.
|
||||||
|
|
||||||
|
## Стадия 2. Открытие моделирования
|
||||||
|
|
||||||
|
Иногда (вернее, даже как правило) распределение статистики вывести
|
||||||
|
невозможно. В таком случае пользуются моделированием. Идея в том, что
|
||||||
|
нам известно распределение выборки в случае нулевой гипотезы. Таким
|
||||||
|
образом, можно многократно генерировать выборки и считать статистику,
|
||||||
|
таким образом получив ее распределение.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
В данном случае, моделирование выборки проводилось
|
||||||
|
в условиях $X \sim N(\mu, S^2)$.
|
||||||
|
|
||||||
|
Можно увидеть некоторое расхождение. В этом, кстати, заключается интересный
|
||||||
|
момент. Часто критикуются исследования построенные на моделировании, так как
|
||||||
|
есть ненулевая (хоть и очень маленькая) вероятность, что выборки
|
||||||
|
сгенерировались так, что полученное распределение статистики плохо отражает
|
||||||
|
реальность.
|
||||||
|
|
||||||
|
## Стадия 3. Бутстрэп
|
||||||
|
|
||||||
|
Бывают случаи, когда распределение выборки неизвестно совсем
|
||||||
|
(или его сложно/нельзя в обычном смысле генерировать,
|
||||||
|
[пример](https://stepik.org/lesson/40491/step/1?unit=24794)). В таком случае
|
||||||
|
постулируют, что данная выборка хорошо отражает генеральную совокупность и в
|
||||||
|
качестве функции распределения берут эмпирическую функцию распределения.
|
||||||
|
|
||||||
|
$$\Large
|
||||||
|
F_n(x) = \frac
|
||||||
|
{\sum_{i=1}^{n} \mathbb{1}(x)}
|
||||||
|
{n}
|
||||||
|
$$
|
||||||
|
|
||||||
|
где:
|
||||||
|
|
||||||
|
$$\Large
|
||||||
|
\mathbb{1}(x) =
|
||||||
|
\begin{cases}
|
||||||
|
1, x > X_i, \\
|
||||||
|
0, \text{ иначе.}
|
||||||
|
\end{cases}
|
||||||
|
$$
|
||||||
|
|
||||||
|
В итоге, получается, что для проверки гипотез не нужно ничего кроме выборки и выдуманной статистики (которая, вообще, может быть любой, от нее зависит только качество получаемого критерия).
|
||||||
|
|
||||||
|
Основная идея заключается в том, чтобы генерировать выборки объемом как и данная выборка из следующего распределения:
|
||||||
|
|
||||||
|
$$\Large
|
||||||
|
\mathcal{F} =
|
||||||
|
\begin{pmatrix}
|
||||||
|
X_1 &X_2 &\cdots &X_n \\
|
||||||
|
\frac{1}{n} &\frac{1}{n} &\cdots &\frac{1}{n}
|
||||||
|
\end{pmatrix}.
|
||||||
|
$$
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Таким образом, из расхождения графиков можно сделать следующие выводы:
|
||||||
|
|
||||||
|
- применение бутстрэпа требует большой объема первоначальной выборки,
|
||||||
|
- наблюдения в выборке должны быть независимыми.
|
||||||
|
|
||||||
|
Несмотря на это, он часто применяется невпопад, так как не требует особых затрат на реализацию.
|
||||||
166
docs/maths/type-pred.md
Normal file
@@ -0,0 +1,166 @@
|
|||||||
|
# Немного про работу с файлами, numpy и предсказаниях
|
||||||
|
|
||||||
|
## Введение
|
||||||
|
|
||||||
|
Известно, что файлы в памяти представлены последовательностью байтов.
|
||||||
|
Структурно, эта последовательность может быть разной. Она может
|
||||||
|
содержать только ASCII-текст, текст с любой кодировкой, сжатый архив,
|
||||||
|
mp3, etc. При взаимодействии с файлом (например, открыть файл
|
||||||
|
текстовым редактором), операционная система не смотрит на
|
||||||
|
т.н. **расширение файла**, её интересует *побайтовое* содержание
|
||||||
|
файла.
|
||||||
|
|
||||||
|
В Unix для определения типа файла есть утилита `file`. Как она
|
||||||
|
определяет тип я точно не знаю, но могу сказать, что частично метод
|
||||||
|
основан на *"заголовке"* файла (первых байтах).
|
||||||
|
|
||||||
|
Пример работы `file` на исполняемом файле:
|
||||||
|
|
||||||
|
```
|
||||||
|
./program: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, ...
|
||||||
|
```
|
||||||
|
|
||||||
|
Шестнадцатеричное представление (первые несколько строк) с помощью
|
||||||
|
`xxd`:
|
||||||
|
|
||||||
|
```console
|
||||||
|
00000000: 7f45 4c46 0201 0100 0000 0000 0000 0000 .ELF............
|
||||||
|
00000010: 0300 3e00 0100 0000 6010 0000 0000 0000 ..>.....`.......
|
||||||
|
00000020: 4000 0000 0000 0000 c036 0000 0000 0000 @........6......
|
||||||
|
00000030: 0000 0000 4000 3800 0d00 4000 1f00 1e00 ....@.8...@.....
|
||||||
|
```
|
||||||
|
|
||||||
|
В начале видно последовательность `ELF` -- формат исполняемых файлов в
|
||||||
|
Unix[1].
|
||||||
|
|
||||||
|
Возникает вопрос: **есть какой-то паттерн для различных типов файлов,
|
||||||
|
который можно увидеть, не считая специальных симвовол в *заголовке*?**
|
||||||
|
|
||||||
|
Можно усложнить вопрос: можно ли по какому-то обобщению (*сигнатуре*)
|
||||||
|
файла предсказать его тип? Попробуем это выяснить.
|
||||||
|
|
||||||
|
Для этого нужно решить следующие задачи:
|
||||||
|
|
||||||
|
1. Написать модуль (**на Си**), который по имени файла просчитывает
|
||||||
|
сигнатуру и возвращает её;
|
||||||
|
2. Посмотреть, как выглядят эти сигнатуры;
|
||||||
|
3. Попробовать обучить простую нейросеть.
|
||||||
|
|
||||||
|
## Как считать сигнатуру файла
|
||||||
|
|
||||||
|
Возьмем нулевую матрицу `M` размера 256х256, так как один байт это
|
||||||
|
число от 0 до 255. Считаем файл в память в виде последовательности
|
||||||
|
байтов. Теперь будем двигаться по последовательности с окном
|
||||||
|
размера 2. В этом окне первый элемент будет отвечать за номер строки,
|
||||||
|
а второй за номер столбца. И каждый раз с окном `(x, y)` будем
|
||||||
|
увеличивать элемент матрицы `M[x][y]` на единицу.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## Причины использования Си
|
||||||
|
|
||||||
|
Если **кратко**: python очень медленный. Например, средний `wav`-файл
|
||||||
|
занимает около 10 мегабайт. Это порядка десяти миллионов байт, по
|
||||||
|
которым нужно пробежать и заполнить матрицу. А для обучения нейросети,
|
||||||
|
таких файлов должно быть много.
|
||||||
|
|
||||||
|
**Отдельный интерес**, также, представляет возможность написать модуль
|
||||||
|
для python на C, который умеет взаимодействовать с API библиотеки
|
||||||
|
NumPy.
|
||||||
|
|
||||||
|
## Чтение файлов в память
|
||||||
|
|
||||||
|
Для чтения файла в память, был написан модуль на Си, доступный
|
||||||
|
репозитории[2]. Здесь кратко опишу, как он работает.
|
||||||
|
|
||||||
|
В нем реализована функция `signature_from_filepath_by2`, которая
|
||||||
|
получает на вход два параметра: имя файла и уровень `verbose`. `by_2`
|
||||||
|
в названии обусловлено тем, что работа не с матрицами, а `n`-мерными
|
||||||
|
тензорами улучшает качество предсказания.
|
||||||
|
|
||||||
|
Функция `read_file` считывает файл в структуру `raw_data`, которая
|
||||||
|
представляет собой просто последовательность байтов и размер этой
|
||||||
|
последовательности. После этого функция `build_matrix` считывает по
|
||||||
|
этой струтуре сигнатуру и записывает в `matrix`.
|
||||||
|
|
||||||
|
Далее создается объект `PyObject *result`, представляющий собой
|
||||||
|
указатель на массив `NumPy` типа `uint32`. На его основе создается
|
||||||
|
динамический массив `result_data`.
|
||||||
|
|
||||||
|
Так как `matrix` лежит в памяти последовательно (ввиду того, что
|
||||||
|
она аллоцирована на стеке), то её можно просто скопировать в
|
||||||
|
`result_data`. После всего этого возвращается указатель `*result`.
|
||||||
|
|
||||||
|
Помимо этого в коде много второстепенных действий, которые требует API
|
||||||
|
Python для работы. Эти подробности я опустил, их можно увидеть в коде,
|
||||||
|
все достаточно предсказуемо.
|
||||||
|
|
||||||
|
## Пайплайн обучения нейросети
|
||||||
|
|
||||||
|
**Нюанс обучения нейросети**: так как получившиеся матрицы вышли очень
|
||||||
|
неравномерными, дополнительно они были размыты [*методом
|
||||||
|
Гаусса*](https://ru.wikipedia.org/wiki/%D0%A0%D0%B0%D0%B7%D0%BC%D1%8B%D1%82%D0%B8%D0%B5_%D0%BF%D0%BE_%D0%93%D0%B0%D1%83%D1%81%D1%81%D1%83).
|
||||||
|
|
||||||
|
Для обучения нейросети необходимо создать матрицу меток. Так как
|
||||||
|
предполагается, что нейросеть будет предсказывать различные типы
|
||||||
|
файлов, то матрица меток будет иметь размер `M*NxM`, где:
|
||||||
|
|
||||||
|
- `M` -- количество типов файлов
|
||||||
|
- `N` -- количество файлов в одном типе (берется минимальное из всех,
|
||||||
|
чтобы обучение было равномерным)
|
||||||
|
|
||||||
|
Для разбиения на тренировочную и обучающию выборки отлично подходит
|
||||||
|
функция `train_test_split` из модуля `sklearn.model_selection`.
|
||||||
|
|
||||||
|
Сам перцептрон будет иметь следующую архитектуру:
|
||||||
|
|
||||||
|
1. На входном слое будет 65536 нейронов (`256х256`). Функцией активации
|
||||||
|
будет `ReLu`-функция.
|
||||||
|
2. Скрытый слой будет иметь 512 нейронов и `sigmoid`-функцию активации.
|
||||||
|
3. На выходе будет столько нейронов, сколько типов файлов нужно будет
|
||||||
|
предсказать.
|
||||||
|
|
||||||
|
Для для задания `loss`-функции и оптимизатора:
|
||||||
|
|
||||||
|
```python
|
||||||
|
loss_fn = nn.CrossEntropyLoss()
|
||||||
|
optimizer = t.optim.SGD(model.parameters(), lr=1e-3)
|
||||||
|
```
|
||||||
|
|
||||||
|
Цикл обучения в данном случае состоял из 250 эпох.
|
||||||
|
|
||||||
|
Пайплайн обучения можно будет найти в репозитории
|
||||||
|
[проекта](https://github.com/rustbas/filetype-prediction), вместе с
|
||||||
|
инструкцией по воспроизведению результатов (кроме того факта, что
|
||||||
|
файлы различных типов нужно будет скачать самому).
|
||||||
|
|
||||||
|
## Результаты и картинки
|
||||||
|
|
||||||
|
Усреденные сигнатуры различных типов файлов можно увидеть ниже.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Также, показатели обучения:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## Выводы
|
||||||
|
|
||||||
|
По итогу, можно сказать, что в некоторых случаях, *сигнатура* файла
|
||||||
|
является неплохим предиктором его типа.
|
||||||
|
|
||||||
|
Гипотетически, это можно использовать для следующих идей:
|
||||||
|
|
||||||
|
1. Восстановление частично поврежденных файлов, так как можно попытаться
|
||||||
|
угадать его структуру и восстановить её.
|
||||||
|
2. Определение исполняемых файлов при анализе вредоносного ПО.
|
||||||
|
3. Обнаружение скрытых данных (когда сигнатура файла и его тип не
|
||||||
|
соответствуют друг другу).
|
||||||
|
|
||||||
|
## Источники
|
||||||
|
|
||||||
|
1. [Википедия про ELF-формат](https://ru.wikipedia.org/wiki/Executable_and_Linkable_Format);
|
||||||
|
2. [Репозиторий проекта](https://github.com/rustbas/filetype-prediction);
|
||||||
|
3. [Основание идеи заметки](https://youtu.be/AUWxl0WdiNI?si=mklboGVUC-mZ-d1M);
|
||||||
|
1. [Пояснение про сигнатуру](https://youtu.be/4bM3Gut1hIk?si=zSGWLHKTKW7bStPb);
|
||||||
|
4. [Модули для Python](https://youtu.be/45TOazYbedI?si=jykTbnbjcyzTsN0r).
|
||||||
34
mkdocs.yml
@@ -3,23 +3,45 @@ site_url: https://rustbas.github.io/blog
|
|||||||
repo_url: https://github.com/rustbas/blog
|
repo_url: https://github.com/rustbas/blog
|
||||||
edit_uri: edit/main/docs/
|
edit_uri: edit/main/docs/
|
||||||
theme:
|
theme:
|
||||||
name: terminal
|
name: material
|
||||||
palette: dark
|
palette:
|
||||||
|
- scheme: default
|
||||||
|
toggle:
|
||||||
|
icon: material/toggle-switch
|
||||||
|
name: Switch to dark mode
|
||||||
|
primary: green
|
||||||
|
|
||||||
|
- scheme: slate
|
||||||
|
toggle:
|
||||||
|
icon: material/toggle-switch-off-outline
|
||||||
|
name: Switch to light mode
|
||||||
|
primary: teal
|
||||||
|
|
||||||
features:
|
features:
|
||||||
- revision.date
|
- navigation.instant # TODO: check troubles with TeX loading
|
||||||
- revision.history
|
- navigation.instant.progress
|
||||||
- navigation.side.hide
|
- header.autohide
|
||||||
|
icon:
|
||||||
|
repo: fontawesome/brands/git
|
||||||
|
font:
|
||||||
|
# text: Roboto
|
||||||
|
code: JetBrains Mono
|
||||||
|
|
||||||
|
# - revision.date
|
||||||
|
# - revision.history
|
||||||
|
# - navigation.side.hide
|
||||||
nav:
|
nav:
|
||||||
# - "Обо мне": 'index.md'
|
# - "Обо мне": 'index.md'
|
||||||
- "Математика": 'maths/index.md'
|
- "Математика": 'maths/index.md'
|
||||||
- "Linux": 'linux/index.md'
|
- "Linux": 'linux/index.md'
|
||||||
|
- "Общее": 'common/index.md'
|
||||||
|
|
||||||
plugins:
|
plugins:
|
||||||
- search:
|
- search:
|
||||||
lang: ["ru", "en"]
|
lang: ["ru", "en"]
|
||||||
indexing: 'full'
|
indexing: 'full'
|
||||||
- git-revision-date
|
- git-revision-date
|
||||||
|
|
||||||
markdown_extensions:
|
markdown_extensions:
|
||||||
- pymdownx.arithmatex:
|
- pymdownx.arithmatex:
|
||||||
generic: true
|
generic: true
|
||||||
|
|||||||