diff --git a/README.md b/README.md index 23b8c45..e7bf52f 100644 --- a/README.md +++ b/README.md @@ -51,16 +51,20 @@ #### Общие зависимости -Зависимости — пакеты Python — записаны в файле `requirements.txt` (см. **Пакеты Python**). +Зависимости — пакеты Python — записаны в файле `requirements/requirements.txt` (см. **Пакеты Python**). #### Пакеты Python -Установка/обновление пакетов Python в активное окружение из файла `requirements.txt`: +Установка/обновление пакетов Python в активное окружение из файла `requirements/requirements.txt`: ```sh -pip install -U -r requirements.txt +pip install -U -r requirements/requirements.txt ``` ## Разведочный анализ данных (EDA) См. `eda/README.md`. + +## Исследование и настройка предсказательной модели + +См. `research/README.md`. diff --git a/docs/jupyter.md b/docs/jupyter.md new file mode 100644 index 0000000..1adbb23 --- /dev/null +++ b/docs/jupyter.md @@ -0,0 +1,143 @@ +# Использование среды Jupyter + +Для исследовательских задач в проекте используется среда [Jupyter](https://jupyter.org/). Т.к. блокноты хранятся в текстовом формате под контролем версий, нужно также дополнение [Jupytext](https://jupytext.readthedocs.io/en/latest/) (как минимум для ручной конвертации блокнотов; см. ниже). + +Опционально можно использовать дополнение [papermill](https://papermill.readthedocs.io/en/latest/) для простого параметризованного исполнения блокнотов. + +## Установка + +### Общий порядок + +**Внимание**: Оптимальный порядок установки и конфигурации Jupyter для работы с проектом неоднозначен. См. обоснование выбранного здесь порядка работы с блокнотами Jupyter и возможные альтернативные варианты в статье [Использование Jupyter с виртуальными окружениями Python](https://asrelo.hashnode.dev/using-jupyter-with-python-virtual-environments-ru). + +1. Jupyter и дополнения должны быть установлены в систему, а **не** в виртуальное окружение. При необходимости деактивируйте виртуальное окружение. + + ```sh + deactivate + ``` + +2. [Установите Jupyter](https://jupyter.org/install) и Jupytext в систему (**не** в виртуальное окружение). + + ```sh + pip install -U notebook jupytext + ``` + + Полная инструкция по установке Jupytext: [Installation — Jupytext documentation](https://jupytext.readthedocs.io/en/latest/install.html). + +3. **Опционально**, установите papermill в систему (**не** в виртуальное окружение). + + ```sh + pip install -U papermill + ``` + + Полная инструкция по установке: [Installation - papermill 2.4.0 documentation](https://papermill.readthedocs.io/en/stable/installation.html). + +4. Активируйте **виртуальное окружение** повторно. + +5. Установите ядро Jupyter, связанное с данным виртуальным окружением, в директорию этого виртуального окружения. Укажите следующее имя ядра: `python3_venv`. + + ```sh + python -m ipykernel --sys-prefix --name python3_venv + ``` + +6. **Опционально**, **заранее** сохраните в переменную окружения `JUPYTER_PATH` путь к данным Jupyter в виртуальном окружении `` — см. п. 1 в инструкции по использованию. + + * Windows (PowerShell): + + ```ps + [System.Environment]::SetEnvironmentVariable('JUPYTER_PATH', ";$env:JUPYTER_PATH", 'User') + ``` + + * Windows (cmd): + + ```bat + setx JUPYTER_PATH ";%PATH%;JUPYTER_PATH" + ``` + + * UNIX (sh): + + ```sh + echo 'export JUPYTER_PATH=":$JUPYTER_PATH"' >> ~/.profile + ``` + +**Внимание**: На данном этапе могут отсутствовать пригодные для прямого использования блокноты `.ipynb` (например, если проект развёртывается с нуля). Об использовании спаренных блокнотов и конвертации форматов см. [Использование Jupytext](#использование-jupytext). + +### Зависимости + +*Используемые при работе с Jupyter зависимости — пакеты Python — на данный момент включены в общие зависимости (см. выше), дополнительных действий не требуется.* + +## Работа с блокнотами Jupyter + +### Jupyter + +1. **Если** при выполнении инструкции по установке Вы **не** сохранили в переменную окружения JUPYTER_PATH путь к данным Jupyter в виртуальном окружении, этот путь нужно добавить в переменную окружения сейчас. + + Добавьте в переменную окружения `JUPYTER_PATH` абсолютный путь (далее обозначаемый ``) `$VIRTUAL_ENV/share/jupyter`, где следует заменить `$VIRTUAL_ENV` на путь к директории, где развёрнуто виртуальное окружение. Для инструментов [`venv`](https://docs.python.org/3/library/venv.html), [`virtualenv`](https://virtualenv.pypa.io/en/stable/) можно просто в активном виртуальном окружении использовать подстановку переменной окружения `VIRTUAL_ENV` (активное виртуальное окружение не повлияет на дальнейшие шаги). + + * Windows (PowerShell): + + ```ps + $env:JUPYTER_PATH = ";$env:JUPYTER_PATH" + ``` + + * Windows (cmd): + + ```bat + set "JUPYTER_PATH=;%JUPYTER_PATH%" + ``` + + * UNIX (sh): + + ```sh + export JUPYTER_PATH=":$JUPYTER_PATH" + ``` + +2. Запустите глобальный установленное приложение Jupyter (**не** из виртуального окружения). + + * Например, запустите Jupyter Notebook: + + ```sh + jupyter notebook + ``` + + Веб-приложение Notebook должно открыться в веб-браузере автоматически. Если этого не произошло, найдите в сообщениях сервера Jupyter строку примерно следующего содержания: + + [I 08:58:24.417 NotebookApp] The Jupyter Notebook is running at: http://localhost:8888/ + + Откройте веб-браузер и перейдите по ссылке, выведенной в конце указанного сообщения. + + См. также [документацию Jupyter](https://docs.jupyter.org/en/stable/running.html). + +2. Используйте приложение для навигации по файловой системе (в частности, по каталогу `eda/`), редактирования и исполнения кода в блокнотах. + +3. Если приложение Jupyter запрашивает **выбор ядра** Jupyter (**kernel**) или Вы сталкиваетесь с необъяснимыми **ошибками импортов**, выберите для текущего блокнота ядро с именем `python3_venv`. + + * **Jupyter Notebook**: Может понадобиться выбор вручную; кнопка для выбора ядра для открытого блокнота находится в верхнем правом углу веб-страницы. + +### Расширение Jupyter для Visual Studio Code + +1. Запустите Visual Studio Code. + +2. Откройте корневую директорию проекта в VS Code (*File* -> *Open Folder...*). + +3. Если Вы открыли директорию проекта и VS Code запрашивает выбор автоматически обнаруженного виртуального окружения, согласитесь. + +3. **Если** VS Code запрашивает выбор автоматически обнаруженного виртуального окружения, согласитесь. + + **Иначе** [укажите](https://code.visualstudio.com/docs/python/environments#_working-with-python-interpreters) своё виртуальное окружение самостоятельно. + +4. Используйте VS Code с расширением Jupyter для навигации по файловой системе (в частности, по каталогу `eda/`), редактирования и исполнения кода в блокнотах. **Не забывайте** при открытии любого блокнота проверять, что выбрано корректное ядро Jupyter (принадлежащее корректному виртуальному окружению). (Кнопка для выбора ядра для открытого блокнота находится в верхнем правом углу области содержимого вкладки; по умолчанию Вы увидите название выбранного виртуального окружения; если ядро не выбрано, на кнопке написано *Select Kernel*.) + +### Использование Jupytext + +Описанные ниже команды `jupytext` используют глобальной установленный экземпляр Jupytext (однако его можно запускать и изнутри виртуального окружения). + +Для автоматической синхронизации связанных блокнотов (включая создание блокнотов отсутствующих, но ожидаемых форматов): + +```sh +jupytext --sync eda/cars_eda.py +``` + +Jupytext довольно удобно работает в оригинальной среде Jupyter, синхронизируя изменения связанных файлов на лету при работе в Jupyter, **ориентируясь на метки времени на файлах**. См. документацию [Jupytext](https://jupytext.readthedocs.io/en/latest/index.html). + +**Внимание**: С расширением Jupyter для Visual Studio Code Jupytext **не работает напрямую**. Для использования блокнотов `.ipynb` с расширением Jupyter для VS Code нужно синхронизировать текстовый файл под контролем версий и файл `.ipynb` вручную указанными выше командами. Однако заметьте, что это же расширение может исполнять блокнот в текстовом формате самостоятельно, посредством автоматизированного ведения временного блокнота; и оно даже автоматически создаёт/подхватывает локальное ядро Jupyter в виртуальном окружении. diff --git a/eda/README.md b/eda/README.md index 4788723..514dd61 100644 --- a/eda/README.md +++ b/eda/README.md @@ -32,144 +32,12 @@ Для EDA необходимы общие зависимости, см. [Общие зависимости](../README.md#общие-зависимости) в `README.md`. -Для EDA используется среда [Jupyter](https://jupyter.org/). Т.к. блокноты хранятся в текстовом формате под контролем версий, нужно также дополнение [Jupytext](https://jupytext.readthedocs.io/en/latest/) (как минимум для ручной конвертации блокнотов; см. ниже). - -Опционально можно использовать дополнение [papermill](https://papermill.readthedocs.io/en/latest/) для простого параметризованного исполнения блокнотов. - -### Общий порядок - -**Внимание**: Оптимальный порядок установки и конфигурации Jupyter для работы с проектом неоднозначен. См. обоснование выбранного здесь порядка работы с блокнотами Jupyter и возможные альтернативные варианты в статье [Использование Jupyter с виртуальными окружениями Python](https://asrelo.hashnode.dev/using-jupyter-with-python-virtual-environments-ru). - -1. Выполните установку общих зависимостей, если это ещё не выполнено, см. **Общие зависимости** в `README.md`. - -2. Jupyter и дополнения должны быть установлены в систему, а **не** в виртуальное окружение. При необходимости деактивируйте виртуальное окружение. - - ```sh - deactivate - ``` - -3. [Установите Jupyter](https://jupyter.org/install) и Jupytext в систему (**не** в виртуальное окружение). - - ```sh - pip install -U notebook jupytext - ``` - - Полная инструкция по установке Jupytext: [Installation — Jupytext documentation](https://jupytext.readthedocs.io/en/latest/install.html). - -4. **Опционально**, установите papermill в систему (**не** в виртуальное окружение). - - ```sh - pip install -U papermill - ``` - - Полная инструкция по установке: [Installation - papermill 2.4.0 documentation](https://papermill.readthedocs.io/en/stable/installation.html). - -5. Активируйте **виртуальное окружение** повторно. - -6. Установите ядро Jupyter, связанное с данным виртуальным окружением, в директорию этого виртуального окружения. Укажите следующее имя ядра: `python3_venv`. - - ```sh - python -m ipykernel --sys-prefix --name python3_venv - ``` - -7. **Опционально**, **заранее** сохраните в переменную окружения `JUPYTER_PATH` путь к данным Jupyter в виртуальном окружении `` — см. п. 1 в инструкции по использованию. - - * Windows (PowerShell): - - ```ps - [System.Environment]::SetEnvironmentVariable('JUPYTER_PATH', ";$env:JUPYTER_PATH", 'User') - ``` - - * Windows (cmd): - - ```bat - setx JUPYTER_PATH ";%PATH%;JUPYTER_PATH" - ``` - - * UNIX (sh): - - ```sh - echo 'export JUPYTER_PATH=":$JUPYTER_PATH"' >> ~/.profile - ``` - -**Внимание**: На данном этапе могут отсутствовать пригодные для прямого использования блокноты `.ipynb` (например, если проект развёртывается с нуля). Об использовании спаренных блокнотов и конвертации форматов см. [Использование Jupytext](#использование-jupytext). +Для EDA используется среда [Jupyter](https://jupyter.org/). См. об установке и использовании Jupyter в проекте в `docs/jupyter.md`. ### Зависимости -Используемые непосредственно кодом проекта зависимости для разведочного анализа данных (EDA) (директория `eda/`) — пакеты Python — на данный момент включены в общие зависимости (см. выше). +Дополнительные зависимости, необходимые для EDA, — пакеты Python — записаны в файле `requirements/requirements-eda.txt` (см. **Пакеты Python**). См. об установке пакетов Python в **Пакеты Python** в `README.md`. ## Работа с блокнотами Jupyter -### Jupyter - -1. **Если** при выполнении инструкции по установке Вы **не** сохранили в переменную окружения JUPYTER_PATH путь к данным Jupyter в виртуальном окружении, этот путь нужно добавить в переменную окружения сейчас. - - Добавьте в переменную окружения `JUPYTER_PATH` абсолютный путь (далее обозначаемый ``) `$VIRTUAL_ENV/share/jupyter`, где следует заменить `$VIRTUAL_ENV` на путь к директории, где развёрнуто виртуальное окружение. Для инструментов [`venv`](https://docs.python.org/3/library/venv.html), [`virtualenv`](https://virtualenv.pypa.io/en/stable/) можно просто в активном виртуальном окружении использовать подстановку переменной окружения `VIRTUAL_ENV` (активное виртуальное окружение не повлияет на дальнейшие шаги). - - * Windows (PowerShell): - - ```ps - $env:JUPYTER_PATH = ";$env:JUPYTER_PATH" - ``` - - * Windows (cmd): - - ```bat - set "JUPYTER_PATH=;%JUPYTER_PATH%" - ``` - - * UNIX (sh): - - ```sh - export JUPYTER_PATH=":$JUPYTER_PATH" - ``` - -2. Запустите глобальный установленное приложение Jupyter (**не** из виртуального окружения). - - * Например, запустите Jupyter Notebook: - - ```sh - jupyter notebook - ``` - - Веб-приложение Notebook должно открыться в веб-браузере автоматически. Если этого не произошло, найдите в сообщениях сервера Jupyter строку примерно следующего содержания: - - [I 08:58:24.417 NotebookApp] The Jupyter Notebook is running at: http://localhost:8888/ - - Откройте веб-браузер и перейдите по ссылке, выведенной в конце указанного сообщения. - - См. также [документацию Jupyter](https://docs.jupyter.org/en/stable/running.html). - -2. Используйте приложение для навигации по файловой системе (в частности, по каталогу `eda/`), редактирования и исполнения кода в блокнотах. - -3. Если приложение Jupyter запрашивает **выбор ядра** Jupyter (**kernel**) или Вы сталкиваетесь с необъяснимыми **ошибками импортов**, выберите для текущего блокнота ядро с именем `python3_venv`. - - * **Jupyter Notebook**: Может понадобиться выбор вручную; кнопка для выбора ядра для открытого блокнота находится в верхнем правом углу веб-страницы. - -### Расширение Jupyter для Visual Studio Code - -1. Запустите Visual Studio Code. - -2. Откройте корневую директорию проекта в VS Code (*File* -> *Open Folder...*). - -3. Если Вы открыли директорию проекта и VS Code запрашивает выбор автоматически обнаруженного виртуального окружения, согласитесь. - -3. **Если** VS Code запрашивает выбор автоматически обнаруженного виртуального окружения, согласитесь. - - **Иначе** [укажите](https://code.visualstudio.com/docs/python/environments#_working-with-python-interpreters) своё виртуальное окружение самостоятельно. - -4. Используйте VS Code с расширением Jupyter для навигации по файловой системе (в частности, по каталогу `eda/`), редактирования и исполнения кода в блокнотах. **Не забывайте** при открытии любого блокнота проверять, что выбрано корректное ядро Jupyter (принадлежащее корректному виртуальному окружению). (Кнопка для выбора ядра для открытого блокнота находится в верхнем правом углу области содержимого вкладки; по умолчанию Вы увидите название выбранного виртуального окружения; если ядро не выбрано, на кнопке написано *Select Kernel*.) - -### Использование Jupytext - -Описанные ниже команды `jupytext` используют глобальной установленный экземпляр Jupytext (однако его можно запускать и изнутри виртуального окружения). - -Для автоматической синхронизации связанных блокнотов (включая создание блокнотов отсутствующих, но ожидаемых форматов): - -```sh -jupytext --sync eda/cars_eda.py -``` - -Jupytext довольно удобно работает в оригинальной среде Jupyter, синхронизируя изменения связанных файлов на лету при работе в Jupyter, **ориентируясь на метки времени на файлах**. См. документацию [Jupytext](https://jupytext.readthedocs.io/en/latest/index.html). - -**Внимание**: С расширением Jupyter для Visual Studio Code Jupytext **не работает напрямую**. Для использования блокнотов `.ipynb` с расширением Jupyter для VS Code нужно синхронизировать текстовый файл под контролем версий и файл `.ipynb` вручную указанными выше командами. Однако заметьте, что это же расширение может исполнять блокнот в текстовом формате самостоятельно, посредством автоматизированного ведения временного блокнота; и оно даже автоматически создаёт/подхватывает локальное ядро Jupyter в виртуальном окружении. +См. об установке и использовании Jupyter в проекте в `docs/jupyter.md`. diff --git a/research/README.md b/research/README.md new file mode 100644 index 0000000..9f2f255 --- /dev/null +++ b/research/README.md @@ -0,0 +1,59 @@ +# Исследование и настройка предсказательной модели + +## Блокноты Jupyter + +* `research` — Создание множества разных моделей, с использованием разных создаваемых признаков и оптимизацией гиперпараметров. + + Использует файл аугментированных данных датасета о подержанных автомобилях, создаваемый блокнотом `eda/cars_eda.py`. См. `eda/README.md`. + + Если параметр блокнота `mlflow_do_log` установлен в `True`, блокнот логирует в MLFlow создаваемые модели в отдельные вложенные (nested) прогоны под одним (новым) общим прогоном с именем, определяемым параметром `mlflow_experiment_name`. + + Точность предсказания текущей цены автомобиля оценивается в первую очередь по показателю MAPE (из-за наличия в выборке значений цены разных порядков), во вторую очередь учитывается MSE (ради отслеживания систематических ошибок на подвыборках). Исследованные модели: + + 1. baseline (MAPE = 0.35, MSE = 1.18); + 2. с использованием добавленных признаков (feature engineering с помощью scikit-learn) — точность неоднозначна по сравнению с baseline (MAPE = 0.31, MSE = 1.50); + 3. с использованием добавленных и выбранных (SFS) признаков — точность существенно лучше baseline (MAPE = 0.20, MSE = 1.02); + 4. с использованием добавленных и выбранных признаков и оптимизированными гиперпараметрами (optuna) — точность немного лучше модели 3 по MAPE (MAPE = 0.20, MSE = 0.94). + + Модель 4 выбрана как финальная модель для последующего развёртывания. Она использует следующие признаки (такие же, как и модель 3): + * `extend_features_as_polynomial__selling_price` (исходная цена продажи, нормализована `StandardScaler`), + * `extend_features_as_polynomial__selling_price^2`, + * `extend_features_as_spline__age_sp_1` (значение базисной функции 2/5 однородного сплайна, нормализованного к крайним значениям возраста автомобилей), + * `extend_features_as_spline__age_sp_2` (то же, но базисная функция 3/5), + * `scale_to_standard__age` (исходный возраст автомобиля, нормализован `StandardScaler`). + + По указанию преподавателя, скриншоты пользовательского интерфейса MLFlow сохранены в директории `./mlflow_ui_figures`. + + По указанию преподавателя, ID финального прогона: `4c7f04ad9ee94237b44f60b6eb14b41e` (вложен в прогон `4e4a9094cb3c4eed9d4a056a27cadcd9`). + +## Установка + +Для исследования и настройки предсказательной модели необходимы общие зависимости, см. [Общие зависимости](../README.md#общие-зависимости) в `README.md`. + +Для исследования и настройки предсказательной модели используется среда [Jupyter](https://jupyter.org/). См. об установке и использовании Jupyter в проекте в `docs/jupyter.md`. + +### Зависимости + +Дополнительные зависимости, необходимые для исследования и настройки предсказательной модели, — пакеты Python — записаны в файле `requirements/requirements-research.txt` (см. **Пакеты Python**). См. об установке пакетов Python в **Пакеты Python** в `README.md`. + +## Работа с блокнотами Jupyter + +См. об установке и использовании Jupyter в проекте в `docs/jupyter.md`. + +## Работа с MLFlow + +Для управления жизненным циклом моделей машинного обучения используется платформа [MLFlow](https://mlflow.org/). + +Запуск локального сервера MLFlow (**выполнять в корневой директории проекта**): + + run_mlflow_server + +Для остановки сервера MLFlow пошлите ему сигнал `SIGINT` (`Ctrl+C` в терминале). + +Очистка локальной tracking БД MLFlow от удалённых прогонов (**выполнять в корневой директории проекта**): + + gc_mlflow + +Очистка локальной tracking БД MLFlow от конкретных удалённых экспериментов по списку их ID, разделённым запятыми, `` (**выполнять в корневой директории проекта**): + + gc_mlflow --experiment-ids= diff --git a/research/mlflow_ui_figures/registered_model_experimental.png b/research/mlflow_ui_figures/registered_model_experimental.png new file mode 100644 index 0000000..da56d65 Binary files /dev/null and b/research/mlflow_ui_figures/registered_model_experimental.png differ diff --git a/research/mlflow_ui_figures/registered_model_final.png b/research/mlflow_ui_figures/registered_model_final.png new file mode 100644 index 0000000..37afd17 Binary files /dev/null and b/research/mlflow_ui_figures/registered_model_final.png differ diff --git a/research/mlflow_ui_figures/run_final_model_artifacts_mlmodel.png b/research/mlflow_ui_figures/run_final_model_artifacts_mlmodel.png new file mode 100644 index 0000000..e5bc8fe Binary files /dev/null and b/research/mlflow_ui_figures/run_final_model_artifacts_mlmodel.png differ diff --git a/research/mlflow_ui_figures/runs_with_metrics_display.png b/research/mlflow_ui_figures/runs_with_metrics_display.png new file mode 100644 index 0000000..0dfbcab Binary files /dev/null and b/research/mlflow_ui_figures/runs_with_metrics_display.png differ diff --git a/research/research.py b/research/research.py index 8179e28..ade4998 100644 --- a/research/research.py +++ b/research/research.py @@ -41,7 +41,7 @@ mlflow_tracking_server_uri: str = 'http://localhost:5000' mlflow_registry_uri: Optional[str] = None # URL сервера registry MLFlow (если не указан, используется `mlflow_tracking_server_uri`). -mlflow_do_log: bool = False +mlflow_do_log: bool = True # Записывать ли прогоны (runs) в MLFlow. mlflow_experiment_id: Optional[str] = None # ID эксперимента MLFlow, имеет приоритет над `mlflow_experiment_name`.