diff --git a/.gitignore b/.gitignore index 6bc0743..0b1b6d7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,10 @@ ### Python *.pyc +### Jupyter +.ipynb_checkpoints/ +*.ipynb + ### Project # virtual environments .venv/ diff --git a/README.md b/README.md index 949484d..23b8c45 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,66 @@ # Лабораторный проект по курсу "Интеллектуальные информационные системы" **Выполняет**: **Сыропятов В.В.** (А-01м-24) + +## Данные + +Используемый датасет: [Car price prediction(used cars) +](https://www.kaggle.com/datasets/vijayaadithyanvg/car-price-predictionused-cars/data) — +продажа подержанных автомобилей на рынке в Индии. + +## Установка + +### Общий порядок + +**Внимание**: Здесь описан только общий порядок установки. Определённые части проекта могут требовать установки по отдельным инструкциям. + +1. Проект разработан для Python 3.10–3.12. Установите совместимую версию Python ([Download Python](https://www.python.org/downloads/)). + +2. Скопируйте/склонируйте репозиторий в выделенную директорию и перейдите в неё. + + ```sh + tar -xzf iis-project.tar.xz + cd iis-project + ``` + +3. Создайте виртуальное окружение Python. + + ```sh + python -m venv .venv + ``` + + Активируйте созданное виртуальное окружение Python. + + * **Linux**: + + ```sh + source .venv/bin/activate + ``` + + * **Windows**: + + ```ps + .\.venv\Scripts\activate + ``` + +4. Установите зависимости для необходимых частей проекта. См. **Зависимости**. + +5. **При необходимости** скачайте данные. Каноническое расположение для данных проекта: `data/`. + +### Зависимости + +#### Общие зависимости + +Зависимости — пакеты Python — записаны в файле `requirements.txt` (см. **Пакеты Python**). + +#### Пакеты Python + +Установка/обновление пакетов Python в активное окружение из файла `requirements.txt`: + +```sh +pip install -U -r requirements.txt +``` + +## Разведочный анализ данных (EDA) + +См. `eda/README.md`. diff --git a/docs/dev/jupyter_workflow_motivation.md b/docs/dev/jupyter_workflow_motivation.md new file mode 100644 index 0000000..a37a234 --- /dev/null +++ b/docs/dev/jupyter_workflow_motivation.md @@ -0,0 +1,73 @@ +# Обоснование порядка работы с блокнотами Jupyter + +[Архитектура](https://docs.jupyter.org/en/latest/projects/architecture/content-architecture.html) экосистемы Jupyter очень сложна, особенно если учитывать сторонние дополнения; данное обоснование может содержать неточности. + +Концептуально, важные для темы компоненты в архитектуре Jupyter: + +* *Ядро* ([kernel](https://docs.jupyter.org/en/latest/projects/kernels.html#kernels)) — независимый процесс, непосредственно исполняющий код на конкретном языке программирования (основываясь на конкретном экземпляре интерпретатора) и предоставляющий API для передачи исполняемого кода и получения результатов. (Самое популярное ядро — `ipykernel` — использует [IPython](https://ipython.org/), программный пакет, реализующий Python с расширенными возможностями интерактивной работы.) + +* *Сервер* (server) и *приложение* (application) — компоненты, обеспечивающие выполнение прикладных задач. Так, стандартный `jupyter_server` и использующие его популярные [веб-приложения](https://jupyter.org/) (Notebook, JupyterLab) реализуют редактирование и исполнение блокнотов и других файлов (делегируя только непосредственное исполнение кода ядрам) и все пользовательские интерфейсы. + +Чтобы пользователь могу выбрать ядро для использования (а значит, выбрать язык программирования и конкретный экземпляр интерпретатора), сервер Jupyter выполняет поиск доступных *спецификаций ядер* (kernelspec). + +В случае Python, выбор конкретного экземпляра интерпретатора важен в частности потому, что это означает и выбор конкретного виртуального окружения. И здесь начинаются проблемы. + +* Сервер Jupyter реализует только примитивный механизм поиска спецификаций ядер. "**Ядра [устанавливается](https://ipython.readthedocs.io/en/stable/install/kernel_install.html#installing-the-ipython-kernel)**" (install) глобально в систему либо для отдельного пользователя, что означает размещение спецификаций ядер под глобально уникальными именами (с учётом приоритета ядер, установленных для конкретного пользователя). Механизма локального размещения спецификаций ядер просто не предусмотрено. (Сервер Jupyter, возможно, реализует и другой механизм поиска *активных* ядер, который здесь нерелевантен.) + +* Расширение [Jupyter](https://marketplace.visualstudio.com/items?itemName=ms-toolsai.jupyter) для Visual Studio Code самостоятельно реализует ограниченные функции сервера и приложения. Однако оно имеет [продвинутый механизм](https://code.visualstudio.com/docs/datascience/jupyter-kernel-management#_python-environments) поиска спецификаций ядер. Спецификации ядер, размещённые в виртуальном окружении (в директории данных (например, `share`), далее `jupyter/kernels`), также подбираются и могут быть использованы пользователем. Они должны иметь *локально* (в отношении виртуального окружения) уникальные имена, **однако** они делят пространство имён с глобально установленными ядрами, просто с более высоким приоритетом. + +* Блокнот Jupyter сохраняет имя нужного для его исполнения ядра в своих метаданных (`kernelspec.name`) (даже при использовании Jupytext). + +Таким образом, отдельный блокнот требует ядро с определённым именем, это имя ищется в системе глобально, и при использовании оригинальной системы Jupyter нет возможности даже определить это имя локально для отдельного виртуального окружения с приоритетом выше, чем у ядер, установленных глобально. Т.е. блокнот существенно привязывается к окружению конкретной системы, что мешает переносимости и контролю версий, а также захламляет систему глобально установленными ядрами. + +Найденные варианты смягчения проблемы: + +1. Разворачивать Jupyter целиком внутри виртуального окружения. + + При этом подходе проблемы с выбором ядра, вероятно, нет вообще. + + **\*** Нет полной уверенности, что Jupyter в виртуальном окружении действительно будет использовать его экземпляр интерпретатора для ядра по умолчанию. + + **+** Простота работы, по крайней мере в пределах одного виртуального окружения. + + **−** Повышенный расход ресурсов хранилища; пакет `notebook` версии 7.4 со всеми зависимостями занимает порядка 264 МБ на диске 12 тысячами файлов. + + **−** Возможные проблемы из-за изоляции среды Jupyter от других проектов. + +2. Использовать только Visual Studio Code с расширением Jupyter и пакетом `ipykernel` в каждом проекте; не использовать оригинальную систему (сервер Jupyter и веб-приложения) вообще. + + В каждом виртуальном окружении также нужен пакет `ipykernel` для работы с ядром. + + **+** Довольно надёжная локальная связь ядер с виртуальными окружениями. + + **−** Большая проблема с переносимостью блокнотов из-за необходимости использовать конкретную IDE с расширением вместо оригинальной системы. + + **−** Ограниченный функционал и нестабильность расширения Jupyter для Visual Studio Code. + + **−** Потенциальная необходимость ручных хаков в случае использования более одного виртуального окружения в одном проекте. + +3. Использовать единственное определённое и зафиксированное для проекта имя ядра; устанавливать ядро с указанным именем глобально либо, для использования нескольких ядер (например, для нескольких виртуальных окружений для одного проекта), править каждый блокнот локально. + + **+** Относительно простой порядок работы в случае с единственным виртуальным окружением для каждого проекта. + + **−** Необходимо обеспечить уникальность имени ядра для проекта; имя ядра может стать нечитаемым. + + **−** Если появляется необходимость иметь несколько ядер для одного проекта (например, для нескольких виртуальных окружений) или переименовать единственное ядро, необходимо применять локальные правки к каждому релевантному блокноту, что существенно усложняет контроль версий. + + **−** Установленные спецификации ядер остаются в системе глобально и захламляют систему. + +4. Запускать ядро самостоятельно из виртуального окружения и использовать механизм поиска активных ядер. + + Есть интерфейсы, намекающие на возможность этого варианта (см. пакет `ipykernel_launcher`), но неясно, насколько это было бы практично. + + **\*** Непонятно, возможно ли это. + + **\*** Непонятно, практично ли это. + + **+** Довольно надёжная локальная связь ядер с виртуальными окружениями. + + **−** Довольно много телодвижений для обычной работы с Jupyter. + + **−** Очень сложно в реализации, может потребовать разработки собственного ПО. + +Вариант **3** выбран на данный момент для данного проекта из-за экономии ресурсов, переносимости и относительной простоты порядка работы с блокнотами в тривиальном рабочем процессе. diff --git a/eda/README.md b/eda/README.md new file mode 100644 index 0000000..ceacb12 --- /dev/null +++ b/eda/README.md @@ -0,0 +1,154 @@ +# Разведочный анализ данных (EDA) + +## Блокноты Jupyter + +* `cars_eda` — Очистка и первичный анализ данных о подержанных автомобилях. + + Использует CSV-файл сырых данных из [датасета](https://www.kaggle.com/datasets/vijayaadithyanvg/car-price-predictionused-cars/data). Каноническое расположение файла данных: `data/cars.csv`. + + Создаёт файлы очищенных данных (по умолчанию — CSV) и аугментированных данных (по умолчанию — pickle). Канонические расположения: соответственно `data/cars.clean.` и `data/cars.aug.`, с заменой `` на расширение в зависимости от формата: `csv` для CSV, `pickle` для pickle. + + **Выводы по исследованию**: + + * Выполнена очистка датасета: удалены несколько аномальных объектов, переименованы некоторые ошибочно названные признаки. (Пропущенных значений в датасете нет.) + + * Датасет дополнен (аугментирован) потенциально полезными синтетическими признаками: отношение цены с пробегом к изначальной цене, возраст (предполагаемый на основе года выпуска автомобиля и распределения этих годов выпуска в датасете), логарифмы количественных величин. Аугментированная версия сохраняется отдельно. + + * Предварительно подтверждена возможность определения рыночной цены автомобиля с пробегом по использованным признакам, **в особенности** по следующим: исходная цена, возраст и пробег автомобиля, тип продающего лица (дилер или частное лицо), топливо (автомобили на дизельном топливе редко бывают дешёвыми). + + * Цена продажи с пробегом сильно линейно коррелирует с изначальной ценой. + + * Интересно, что возраст автомобиля является заметно лучшим предиктором снижения стоимости, чем пробег, при этом корреляция между возрастом и пробегом существенная, но не определяющая. + + * Существует огромная разница в ценах у дилеров и частных лиц (у частных лиц дешевле в разы). + + * Существует слабая, но заметная прямая корреляция между изначальной ценой автомобиля и пробегом к дате последующей продажи. + + * Датасет не очень однороден (у него есть "тяжёлый центр"), и с малым количеством объектов это может создать проблемы с устойчивостью предсказания цен. Рекомендуется применение робастных методов ограниченной сложности; однако прямая линейная регрессия для предсказания цены проодажи может всё-таки оказаться не лучшим методом. + + Графические артефакты исследования сохранены в директории `./cars_eda_figures/`. + +## Установка + +Для EDA необходимы общие зависимости, см. **Общие зависимости** в `README.md`. + +Для EDA используется среда [Jupyter](https://jupyter.org/). Т.к. блокноты хранятся в текстовом формате под контролем версий, нужно также дополнение [Jupytext](https://jupytext.readthedocs.io/en/latest/) (как минимум для ручной конвертации блокнотов; см. ниже). + +Опционально можно использовать дополнение [papermill](https://papermill.readthedocs.io/en/latest/) для простого параметризованного исполнения блокнотов. + +### Общий порядок + +**Внимание**: Оптимальный порядок установки и конфигурации Jupyter для работы с проектом неоднозначен. См. обоснование выбранного здесь порядка работы с блокнотами Jupyter и возможные альтернативные варианты в `eda/docs/jupyter_workflow_motivation.md`. + +1. Выполните установку общих зависимостей, если это ещё не выполнено, см. **Общие зависимости** в `README.md`. + +2. Jupyter и дополнения должны быть установлены в систему, а НЕ в виртуальное окружение. При необходимости деактивируйте виртуальное окружение. + + ```sh + deactivate + ``` + +3. [Установите Jupyter](https://jupyter.org/install) и Jupytext в систему (НЕ в виртуальное окружение). + + ```sh + pip install -U notebook + ``` + +4. Установите Jupytext в систему (НЕ в виртуальное окружение). + + ```sh + pip install -U jupytext + ``` + + Полная инструкция по установке: [Installation — Jupytext documentation](https://jupytext.readthedocs.io/en/latest/install.html). + +5. **Опционально**, установите papermill в систему (НЕ в виртуальное окружение). + + ```sh + pip install -U papermill + ``` + + Полная инструкция по установке: [Installation - papermill 2.4.0 documentation](https://papermill.readthedocs.io/en/stable/installation.html). + +**Шаги 6–7** **необходимо** выполнить **только** если Вы желаете использовать что-то кроме расширения Jupyter для Visual Studio Code для работы с блокнотами **или собираетесь** коммитить писать блокноты под контроль версий. + +6. Активируйте виртуальное окружение вновь. + +7. Установите ядро Jupyter, связанное с данным виртуальным окружением, в систему. Используйте следующее имя для ядра: `mpei-iis-99040779`. (*Да, это странно, но это признано лучшим подходом на данный момент; см. обоснование в `docs/dev/jupyter_workflow_motivation.md`.*) + + ```sh + ipython kernel install --user --name=mpei-iis-99040779 + ``` + + (Эта команда устанавливает виртуальное окружение глобально для текущего пользователя; для установки глобально в систему, уберите флаг `--user`). + +**Внимание**: На данном этапе могут отсутствовать пригодные для прямого редактирования блокноты `.ipynb` (например, если проект развёртывается с нуля). Об использовании спаренных блокнотов и конвертации форматов см. **Использование Jupytext**. + +#### Удаление ядра из системы + +Во избежание захламления системы ядро можно удалить из системы **позднее**, вызвав глобально установленный Jupyter (НЕ в виртуальном окружении) и передав имя ядра. + +```sh +jupyter kernelspec uninstall mpei-iis-99040779 +``` + +**Примечание**: Установленное ядро НЕ занимает значительные ресурсы хранилища. На самом деле в систему устанавливается крайне лёгкая *спецификация ядра*, ограниченная коротким текстовым файлом и иконками. + +### Зависимости + +Используемые непосредственно кодом проекта зависимости для разведочного анализа данных (EDA) (директория `eda/`) — пакеты Python — на данный момент включены в общие зависимости (см. выше). + +### Использование 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 + +### Jupyter + +1. Запустите глобальный глобально установленный сервер 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**) или Вы сталкиваетесь с необъяснимыми **ошибками импортов**, выберите для текущего блокнота ядро с именем `mpei-iis-99040779` (которое Вы установили в систему раньше). + + * **Notebook**: Может понадобиться выбор вручную; кнопка для выбора ядра для открытого блокнота находится в верхнем правом углу веб-страницы. + +### Расширение Jupyter для Visual Studio Code + +1. Запустите Visual Studio Code. + +2. **Если** Вы НЕ установили ядро Jupyter, связанное с виртуальным окружением для проекта, в систему, обязательно откройте корневую директорию проекта в VS Code (*File* -> *Open Folder...*). **Иначе** это необязательный, но удобный шаг. + +3. Если Вы открыли директорию проекта и VS Code запрашивает выбор автоматически обнаруженного виртуального окружения, согласитесь. + +4. **При открытии любого блокнота** убедитесь, что выбрано корректное ядро Jupyter. (Кнопка для выбора ядра для открытого блокнота находится в верхнем правом углу области содержимого вкладки; если ядро не выборано, на кнопке написано *Select Kernel*.) + + * **Если** Вы установили ядро Jupyter в систему, рекомендуется выбрать установленное в систему ядро с именем `mpei-iis-99040779`. + * **Если** Вы совсем **не собираетесь** использовать Jupyter для работы с проектом **и не собираетесь** записывать блокноты под контроль версий, можно выбрать локальное ядро, связанное с виртуальным окружением (по умолчанию имеет название виртуального окружения — `.venv`). + +5. Используйте IDE с расширением для навигации по файловой системе (в частности, по каталогу `eda/`), редактирования и исполнения кода в блокнотах. diff --git a/eda/cars_eda.py b/eda/cars_eda.py new file mode 100644 index 0000000..37ff99f --- /dev/null +++ b/eda/cars_eda.py @@ -0,0 +1,717 @@ +# --- +# jupyter: +# jupytext: +# formats: ipynb,py:percent +# text_representation: +# extension: .py +# format_name: percent +# format_version: '1.3' +# jupytext_version: 1.17.3 +# kernelspec: +# display_name: mpei-iis-project-99040779 +# language: python +# name: mpei-iis-project-99040779 +# --- + +# %% [markdown] +# # Очистка и первичный анализ данных о подержанных автомобилях + +# %% [markdown] +# **ОСТОРОЖНО**: Исполнение этого блокнота может тихо (пере)записать (и по умолчанию (пере)записывает) файлы очищенных/аугментированных +# данных. См. ниже параметры блокнота для papermill. + +# %% [markdown] +# Блокнот использует файл сырых данных датасета о подержанных автомобилях ([источник](https://www.kaggle.com/datasets/vijayaadithyanvg/car-price-predictionused-cars)). Блокнот записывает очищенные и аугментированные данные. См. ниже параметры блокнота для papermill. + +# %% +from typing import Optional + +# %% [markdown] +# Параметры блокнота для papermill: + +# %% [markdown] +# (Ячейка с параметрами блокнота для papermill требует осторожного обращения; её содержимое парсится как текст очень простым парсером.) + +# %% tags=["parameters"] +data_path: Optional[str] = None +# Полный путь к файлу (CSV) с исходным датасетом. Если не установлен, ищется файл в `data/`. +data_relpath: str = 'cars.csv' +# Путь к файлу (CSV) с исходным датасетом относительно директории данных `data`. Игнорируется, если установлен data_path. + +data_clean_csv: bool = True +# Сохранить ли очищенный датасет как CSV. +data_clean_csv_path: Optional[str] = None +# Полный путь к файлу (CSV) для сохранения очищенного датасета. Если не установлен, используется `data/`. +data_clean_csv_relpath: str = 'cars.clean.csv' +# Путь к файлу (CSV) для сохранения очищенного датасета относительно директории данных `data`. Игнорируется, если установлен data_clean_csv_path. + +data_clean_pickle: bool = False +# Сохранить ли очищенный датасет как pandas.DataFrame через pickle. +data_clean_pickle_path: Optional[str] = None +# Полный путь к файлу (pickle) для сохранения очищенного датасета. Если не установлен, используется `data/`. +data_clean_pickle_relpath: str = 'cars.clean.pickle' +# Путь к файлу (pickle) для сохранения очищенного датасета относительно директории данных `data`. Игнорируется, если установлен data_clean_pickle_path. + +data_aug_csv: bool = False +# Сохранить ли аугментированный датасет как CSV. +data_aug_csv_path: Optional[str] = None +# Полный путь к файлу (CSV) для сохранения аугментированного датасета. Если не установлен, используется `data/`. +data_aug_csv_relpath: str = 'cars.aug.csv' +# Путь к файлу (CSV) для сохранения аугментированного датасета относительно директории данных `data`. Игнорируется, если установлен data_aug_csv_path. + +data_aug_pickle: bool = True +# Сохранить ли очищенный датасет как pandas.DataFrame через pickle. +data_aug_pickle_path: Optional[str] = None +# Полный путь к файлу (pickle) для сохранения очищенного датасета. Если не установлен, используется `data/`. +data_aug_pickle_relpath: str = 'cars.aug.pickle' +# Путь к файлу (pickle) для сохранения очищенного датасета относительно директории данных `data`. Игнорируется, если установлен data_aug_pickle_path. + +# %% +# #%matplotlib ipympl + +# %% +import os.path +import pathlib +import re +import sys + +# %% +import bokeh.io +import bokeh.models +import bokeh.plotting +import bokeh.transform +import matplotlib.pyplot +import matplotlib.ticker +import numpy +import pandas +import seaborn + +# %% +BASE_PATH = pathlib.Path('..') + +# %% +CODE_PATH = BASE_PATH +sys.path.insert(0, str(CODE_PATH.resolve())) + +# %% +import iis_project.plotting_utils + +# %% +bokeh.io.output_notebook() + +# %% +DATA_PATH = ( + pathlib.Path(os.path.dirname(data_path)) + if data_path is not None + else (BASE_PATH / 'data') +) + +# %% [markdown] jp-MarkdownHeadingCollapsed=true +# ## Загрузка и обзор данных + +# %% +df_orig = pandas.read_csv(data_path if data_path is not None else (DATA_PATH / data_relpath)) + +df_orig = df_orig.rename(columns=lambda s: re.sub(r'\s', '_', s.lower().replace(' ', '_'))) + +# %% [markdown] +# Обзор строк сырого датасета: + +# %% +df_orig.head(0x10) + +# %% [markdown] +# Размер сырого датасета: + +# %% +len(df_orig) + +# %% [markdown] +# Количество непустых значений и тип каждого столбца: + +# %% +df_orig.info() + +# %% [markdown] +# ## Первичный поиск аномалий и очистка данных + +# %% [markdown] +# Подтверждение, что в датасете нет пустых значений: + +# %% +all((len(s) == len(df_orig)) for _, s in df_orig.items()) + +# %% +quantitative_columns_orig = ['selling_price', 'present_price', 'driven_kms', 'year'] +categorical_columns_orig = ['car_name', 'fuel_type', 'selling_type', 'transmission', 'owner'] + +# %% +for column in filter(lambda s: s not in ('car_name',), categorical_columns_orig): + # XXX: по идее, переименования категорий стоило бы делать после преобразования к типу категории, + # Series.cat.rename_categories. Однако... оно просто не работает. + if pandas.api.types.is_object_dtype(df_orig[column].dtype): + df_orig[column] = df_orig[column].map( + lambda s: ' '.join(map(lambda s2: s2.lower(), s.split())) + ) + df_orig[column] = df_orig[column].astype('category') + + +# %% +def normalize_car_name(s): + return ' '.join(map(lambda s: s.lower(), s.split())) + + +# %% [markdown] +# Нормализация текстовых названий моделей автомобилей: + +# %% +df_orig['car_name'] = df_orig['car_name'].apply(normalize_car_name) + +# %% [markdown] +# Первичные статистики по количественным признакам: + +# %% +df_orig[list(quantitative_columns_orig)].describe() + +# %% [markdown] +# Категориальные признаки: + +# %% +categorical_values_for_columns_orig = { + column: series.unique() + for column, series in df_orig[list(categorical_columns_orig)].items() +} + +for column, values in categorical_values_for_columns_orig.items(): + if len(values) <= 0x10: + values_str = ', '.join(map(repr, values)) + else: + values_str = f'({len(values)} values)' + print(f'{column!r}: {values_str}') + +# %% [markdown] raw_mimetype="" +# Просмотр распределений по отдельным признакам на предмет аномалий: + +# %% +_fig, _axis = matplotlib.pyplot.subplots(2, 1, squeeze=True) +for i, (column, series) in enumerate(df_orig[['selling_price', 'present_price']].items()): + _ax = _axis[i] + _ax.set_title(str(column)) + #_ax.set_xscale('symlog') + _ax.set_yscale('log') + _ax.grid(True) + _ = _ax.hist(series, bins=iis_project.plotting_utils.suggest_bins_num(len(series))) +_fig.tight_layout() + +# %% [markdown] +# Есть 1 объект, вероятно, аномальный по `present_price`, но это неоднозначно. + +# %% +for column, series in df_orig[['driven_kms']].items(): + _fig, _ax = matplotlib.pyplot.subplots() + _ax.set_title(str(column)) + #_ax.set_xscale('symlog') + _ax.set_yscale('log') + _ax.grid(True) + _ = _ax.hist(series, bins=iis_project.plotting_utils.suggest_bins_num(len(series))) + +# %% [markdown] +# Есть 1 аномальный объект по `driven_kms` (аномально большой пробег). + +# %% +for column, series in df_orig[['year']].items(): + _fig, _ax = matplotlib.pyplot.subplots() + _ax.set_title(str(column)) + _ax.set_yscale('log') + _ax.grid(True) + _ = _ax.hist(series, bins=iis_project.plotting_utils.suggest_bins_num(len(series))) + +# %% +for column, series in df_orig[ + list(filter(lambda s: s not in ('car_name',), categorical_columns_orig)) +].items(): + _fig, _ax = matplotlib.pyplot.subplots() + _ax.set_title(str(column)) + _ax.set_yscale('log') + _ax.grid(True) + value_counts = series.value_counts() + _ = _ax.bar(tuple(map(str, value_counts.index)), value_counts) + +# %% [markdown] +# Есть 2 исключительных объекта по топливу `fuel_type` (автомобиль на природном газе +# (CNG)) — и 1 исключительный объект по типу владельца `owner` (3). + +# %% [markdown] +# Внимательное рассмотрение аномальных объектов: + +# %% +labels_to_drop_from_orig = [] + +# %% +df_orig.loc[df_orig['owner'].isin((3,))] + +# %% [markdown] +# Объект, исключительный по `owner` (3), исключается из датасета, не в последнюю очередь +# из-за неясности смысла значений `owner`. + +# %% +labels_to_drop_from_orig.extend(df_orig.loc[df_orig['owner'].isin((3,))].index) + +# %% +df_orig.loc[(df_orig['present_price'] >= 60.) | (df_orig['driven_kms'] >= 400000) | (df_orig['fuel_type'].isin(('CNG',)))] + +# %% [markdown] +# Аномально большой пробег у автомобиля #196 ещё и является очень круглым числом. Этот объект +# исключается из датасета как вероятно недостоверный. +# +# 2 автомобиля на природном газе решено пока не исключать, т.к. с учётом и так малого размера +# датасета возможность хоть как-то предсказывать цены для автомобилей на природном газе сочтена +# сравнительно ценной. +# +# Автомобиль с исключительно высокой `present_price` не показывает других аномалий (у него и `selling_price` высокая в датасете), поэтому он оставлен. + +# %% +labels_to_drop_from_orig.extend((196,)) + +# %% +df_clean = df_orig.drop(labels_to_drop_from_orig) + +# %% +#bokeh_source_df_clean = bokeh.models.ColumnDataSource(df_clean) + +# %% [markdown] +# По названиям и распределениям признаков `selling_price` и `present_price` есть большое подозрение, +# что это изначальная цена и цена продажи с пробегом, но перепутанные местами. + +# %% [raw] raw_mimetype="" +# present_price_ratio = df_clean['selling_price'] / df_clean['present_price'] +# +# _fig, _ax = matplotlib.pyplot.subplots() +# _ = _ax.set_xlabel('driven_kms') +# _ = _ax.set_ylabel('selling_price / present_price') +# _ax.set_xscale('log') +# _ax.grid(True) +# _ = _ax.scatter(df_clean['driven_kms'], present_price_ratio, alpha=0.5) +# _ = _ax.set_ylim((0., None)) + +# %% +_src = bokeh.models.ColumnDataSource({ + **dict(df_clean[['car_name', 'driven_kms', 'year', 'selling_price', 'present_price']].items()), + 'present_price_ratio': (df_clean['selling_price'] / df_clean['present_price']), +}) +_fig = bokeh.plotting.figure( + x_axis_type='log', + x_axis_label='driven_kms', y_axis_label='selling_price / present_price', +) +_ = _fig.scatter( + 'driven_kms', 'present_price_ratio', + source=_src, + size=12., alpha=0.5, +) +_fig.y_range.start = 0 +_fig.add_tools( + bokeh.models.HoverTool( + tooltips=[ + ('present price', '@present_price'), + ('selling price ', '@selling_price'), + ('name', '@car_name'), + ('year', '@year',), + ('index', '$index',) + ], + ), +) +bokeh.plotting.show(_fig) + +# %% [markdown] +# Указанное выше подозрение подтверждается, `selling_price` и `present_price` нужно поменять местами. + +# %% +df_clean[['selling_price', 'present_price']] = df_clean[['present_price', 'selling_price']] + +# %% [markdown] jp-MarkdownHeadingCollapsed=true +# ## Сохранение очищенных данных + +# %% +if data_clean_csv: + df_clean.to_csv( + ( + data_clean_csv_path + if data_clean_csv_path is not None + else (DATA_PATH / data_clean_csv_relpath) + ), + index=False, + ) + +# %% +if data_clean_pickle: + import pickle + with open( + ( + data_clean_pickle_path + if data_clean_pickle_path is not None + else (DATA_PATH / data_clean_pickle_relpath) + ), + 'wb', + ) as out_file: + pickle.dump(df_clean, out_file) + +# %% +df = df_clean.copy(deep=False) + +# %% [markdown] +# TODO: Разделить блокнот на два — очистка данных и анализ. + +# %% [markdown] +# ## Анализ и аугментация данных + +# %% +quantitative_columns = ['selling_price', 'present_price', 'driven_kms', 'year'] +categorical_columns = ['car_name', 'fuel_type', 'selling_type', 'transmission', 'owner'] + +# %% [markdown] +# Количество объектов: + +# %% +len(df) + +# %% [markdown] +# Количество непустых значений и тип каждого столбца: + +# %% +df.info() + +# %% [markdown] +# Добавим синтетический признак возраста. Для отсчёта предполагается актуальность датасета на 2019 год; +# учитывая, что год в датасете задан целым числом, это даёт возраст минимум 1 год для каждого объекта. + +# %% +df['age'] = ((max(df['year']) + 1) - df['year']).astype(float) +quantitative_columns.append('age') + +# %% [markdown] +# Вообще говоря, отношение `present_price / selling_price` может быть полезно при изучении данных +# или обучении моделей. Добавим такой признак `present_price_ratio`: + +# %% +df['present_price_ratio'] = df['present_price'] / df['selling_price'] +quantitative_columns.append('present_price_ratio') + +# %% [markdown] +# Добавим некоторые потенциально полезные синтетические признаки - логарифмы некоторых количественных признаков: + +# %% +for column in ('selling_price', 'present_price', 'driven_kms'): + df[f'log_{column}'] = numpy.log10(df[column]) + +df['log_age'] = numpy.log10(numpy.maximum(1., df['age'])) + +# %% +bokeh_source_df = bokeh.models.ColumnDataSource(df) + +# %% [markdown] +# Первичные статистики по количественным признакам: + +# %% +df[list(quantitative_columns)].describe() + +# %% [markdown] +# Категориальные признаки: + +# %% +categorical_values_for_columns = { + column: series.unique() + for column, series in df[list(categorical_columns)].items() +} + +for column, values in categorical_values_for_columns.items(): + if len(values) <= 0x10: + values_str = ', '.join(map(repr, values)) + else: + values_str = f'({len(values)} values)' + print(f'{column!r}: {values_str}') + +# %% [markdown] +# Матрица корреляций количественных признаков: + +# %% +df_corr = df[[ + 'present_price', 'log_present_price', + 'selling_price', 'log_selling_price', + 'present_price_ratio', + 'driven_kms', 'log_driven_kms', + 'age', 'log_age', +]].corr('pearson', min_periods=2) + +# %% [markdown] +# Из неочевидных выводов по матрице корреляций, существует слабая, но заметная прямая корреляция +# между изначальной ценой автомобиля и пробегом к дате последующей продажи. + +# %% +_fig, _ax = matplotlib.pyplot.subplots() +_im = _ax.imshow(df_corr.to_numpy(), cmap='RdBu', vmin=-1., vmax=+1., origin='upper') +_ax.tick_params(top=True, labeltop=True, bottom=False, labelbottom=False) +_ = _ax.set_xticks(range(len(df_corr.columns)), labels=df_corr.columns, rotation=90.) +_ = _ax.set_yticks(range(len(df_corr.index)), labels=df_corr.index) +if len(df_corr.columns) <= 10: + for i in range(len(df_corr.index)): + for j in range(len(df_corr.columns)): + if i == j: + continue + val = df_corr.iloc[(i, j)] + _ = _ax.text( + j, i, '{:+.2f}'.format(val), + ha='center', va='center', + color=('white' if abs(val) >= 0.5 else 'black'), + fontsize='small', + ) +else: + _ = _fig.colorbar(_im) + +# %% [markdown] +# Совместное распределение изначальной цены продажи и цены с пробегом: + +# %% [raw] raw_mimetype="" +# _fig, _ax = matplotlib.pyplot.subplots() +# _ = _ax.set_xlabel('selling_price') +# _ = _ax.set_ylabel('present_price') +# _ax.grid(True) +# _ = seaborn.histplot( +# x=df['selling_price'], y=df['present_price'], +# bins=tuple( +# numpy.geomspace( +# min(series), max(series), +# (iis_project.plotting_utils.suggest_bins_num(len(series)) + 1), +# ) +# for _, series in df[['selling_price', 'present_price']].items() +# ), +# #thresh=None, palette='Blues', +# cbar=True, +# #hue_norm=matplotlib.colors.LogNorm(0, 64), +# ax=_ax, +# ) +# _ax.set_xscale('log') +# _ax.set_yscale('log') + +# %% +_fig, _ax = matplotlib.pyplot.subplots() +_ = _ax.set_xlabel('selling_price') +_ = _ax.set_ylabel('present_price') +_ax.set_xscale('log') +_ax.set_yscale('log') +_ax.grid(True) +_scatter = _ax.scatter( + df['selling_price'], df['present_price'], c=df['selling_type'].cat.codes, + alpha=0.5, +) +_ = _ax.legend( + *_scatter.legend_elements( + fmt=matplotlib.ticker.FuncFormatter(lambda i, _: df['selling_type'].cat.categories[int(i)]), + ), +) + +# %% [markdown] +# Существует очень сильное разделение по ценам при продаже подержанных автомобилей дилерами +# и частными лицами; частные лица обычно продают автомобили намного дешевле, чем дилеры (хотя этот +# вывод не учитывает возможное влияние других переменных). + +# %% [markdown] +# Совместные распределения отношения цены с пробегом к изначальной, пробега, года выпуска: + +# %% +_fig, _ax = matplotlib.pyplot.subplots() +_ = _ax.set_xlabel('driven_kms') +_ = _ax.set_ylabel('present_price_ratio') +_ax.grid(True) +_ = seaborn.histplot( + x=df['driven_kms'], y=df['present_price_ratio'], + bins=( + numpy.geomspace( + min(df['driven_kms']), max(df['driven_kms']), + (iis_project.plotting_utils.suggest_bins_num(len(df['driven_kms'])) + 1), + ), + iis_project.plotting_utils.suggest_bins_num(len(df['present_price_ratio'])), + ), + #thresh=None, palette='Blues', + cbar=True, + #hue_norm=matplotlib.colors.LogNorm(0, 64), + ax=_ax, +) +_ax.set_xscale('log') +_ = _ax.set_ylim((0., None)) + +# %% +_fig, _ax = matplotlib.pyplot.subplots() +_ = _ax.set_xlabel('age') +_ = _ax.set_ylabel('present_price / selling_price') +_ax.grid(True) +_ = seaborn.histplot( + x=df['age'], y=df['present_price_ratio'], + bins=( + iis_project.plotting_utils.suggest_bins_num(len(df['age'])), + iis_project.plotting_utils.suggest_bins_num(len(df['present_price_ratio'])), + ), + #thresh=None, palette='Blues', + cbar=True, + #hue_norm=matplotlib.colors.LogNorm(0, 64), + ax=_ax, +) +#_ax.set_xscale('log') +_ = _ax.set_ylim((0., None)) + +# %% [raw] raw_mimetype="" +# _fig, _ax = matplotlib.pyplot.subplots() +# _ = _ax.set_xlabel('age') +# _ = _ax.set_ylabel('driven_kms') +# _ax.grid(True) +# _ = seaborn.histplot( +# x=df['age'], y=df['driven_kms'], +# bins=( +# iis_project.plotting_utils.suggest_bins_num(len(df['age'])), +# numpy.geomspace( +# min(df['driven_kms']), max(df['driven_kms']), +# (iis_project.plotting_utils.suggest_bins_num(len(df['driven_kms'])) + 1), +# ), +# ), +# #thresh=None, palette='Blues', +# cbar=True, +# #hue_norm=matplotlib.colors.LogNorm(0, 64), +# ax=_ax, +# ) +# #_ax.set_xscale('log') +# _ax.set_yscale('log') + +# %% +_fig = bokeh.plotting.figure( + x_axis_type='linear', y_axis_type='log', + x_axis_label='age', y_axis_label='driven_kms', +) +_mapper = bokeh.models.LinearColorMapper( + palette='Viridis256', + low=min(0., df['present_price_ratio'].min()), high=max(1., df['present_price_ratio'].max()), +) +_ = _fig.scatter( + 'age', 'driven_kms', + color=bokeh.transform.transform('present_price_ratio', _mapper), + source=bokeh_source_df, + size=12., alpha=0.75, +) +_fig.add_tools( + bokeh.models.HoverTool( + tooltips=[ + ('present price', '@present_price'), + ('selling price ', '@selling_price'), + ('year', '@year',), + ('index', '$index',), + ], + ), +) +_fig.add_layout(bokeh.models.ColorBar(color_mapper=_mapper), 'right') +bokeh.plotting.show(_fig) + +# %% [markdown] +# В частности, существует сильная связь между и возрастом автомобиля и отношением цены с пробегом +# к изначальной. Довольно много объектов, но далеко не все, сосредоточены около одной точки +# в пространстве данных. + +# %% [markdown] +# Распределения цен с пробегом по категориям: + +# %% +_fig, _ax = matplotlib.pyplot.subplots() +_ = _ax.set_yscale('log') +_ax.grid(True) +_ = df.boxplot('present_price', by='fuel_type', ax=_ax, patch_artist=False) +#_ax.set_ylim((0, None)) + +# %% [markdown] +# Автомобили на дизеле дороже автомобилей на бензине, а также реже продаются +# за крайне низкие цены. + +# %% +_fig, _ax = matplotlib.pyplot.subplots() +_ = _ax.set_yscale('log') +_ax.grid(True) +_ = df.boxplot('present_price', by='selling_type', ax=_ax, patch_artist=False) +#_ax.set_ylim((0, None)) + +# %% [markdown] +# Частные лица обычно продают автомобили намного дешевле, чем дилеры (хотя этот вывод не учитывает +# возможное влияние других переменных). Отмечены множество автомобилей, продаваемых дилерами +# по особо высоким ценам. + +# %% [markdown] +# Проверка возможной систематической разницы в пробеге между категориями: + +# %% +_fig, _ax = matplotlib.pyplot.subplots() +_ = _ax.set_yscale('log') +_ax.grid(True) +_ = df.boxplot('driven_kms', by='fuel_type', ax=_ax, patch_artist=False) +#_ax.set_ylim((0, None)) + +# %% +_fig, _ax = matplotlib.pyplot.subplots() +_ = _ax.set_yscale('log') +_ax.grid(True) +_ = df.boxplot('driven_kms', by='selling_type', ax=_ax, patch_artist=False) +#_ax.set_ylim((0, None)) + +# %% [markdown] +# Большой систематической разницы в пробеге между категориями нет. + +# %% [markdown] +# ## Сохранение аугментированных данных + +# %% +if data_aug_csv: + df.to_csv( + (data_aug_csv_path if data_aug_csv_path is not None else (DATA_PATH / data_aug_csv_relpath)), + index=False, + ) + +# %% +if data_aug_pickle: + import pickle + with open( + ( + data_aug_pickle_path + if data_aug_pickle_path is not None + else (DATA_PATH / data_aug_pickle_relpath) + ), + 'wb', + ) as out_file: + pickle.dump(df, out_file) + +# %% [markdown] +# ## Выводы по исследованию + +# %% [markdown] +# Выполнена очистка датасета: удалены несколько аномальных объектов, переименованы некоторые +# ошибочно названные признаки. (Пропущенных значений в датасете нет.) + +# %% [markdown] +# Датасет дополнен (аугментирован) потенциально полезными синтетическими признаками: +# отношение цены с пробегом к изначальной цене, возраст (предполагаемый на основе года выпуска +# автомобиля и распределения этих годов выпуска в датасете), логарифмы количественных величин. +# Аугментированная версия сохраняется отдельно. + +# %% [markdown] +# Предварительно подтверждена возможность определения рыночной цены автомобиля с пробегом +# по использованным признакам, **в особенности** по следующим: исходная цена, возраст и пробег +# автомобиля, тип продающего лица (дилер или частное лицо), топливо (автомобили на дизельном +# топливе редко бывают дешёвыми). +# +# * Цена продажи с пробегом сильно линейно коррелирует с изначальной ценой. +# +# * Интересно, что возраст автомобиля является заметно лучшим предиктором снижения стоимости, +# чем пробег, при этом корреляция между возрастом и пробегом существенная, но не определяющая. +# +# * Существует огромная разница в ценах у дилеров и частных лиц (у частных лиц дешевле в разы). +# +# * Существует слабая, но заметная прямая корреляция между изначальной ценой автомобиля и пробегом +# к дате последующей продажи. +# +# * Датасет не очень однороден (у него есть "тяжёлый центр"), и с малым количеством объектов +# это может создать проблемы с устойчивостью предсказания цен. Рекомендуется применение +# робастных методов ограниченной сложности; однако прямая линейная регрессия для предсказания +# цены проодажи может всё-таки оказаться не лучшим методом. diff --git a/eda/cars_eda_figures/README.txt b/eda/cars_eda_figures/README.txt new file mode 100644 index 0000000..a2ba32d --- /dev/null +++ b/eda/cars_eda_figures/README.txt @@ -0,0 +1 @@ +Эта директория существует по указанию преподавателя. diff --git a/eda/cars_eda_figures/boxplots_mileage_by_fuel_type.png b/eda/cars_eda_figures/boxplots_mileage_by_fuel_type.png new file mode 100644 index 0000000..ea92c87 Binary files /dev/null and b/eda/cars_eda_figures/boxplots_mileage_by_fuel_type.png differ diff --git a/eda/cars_eda_figures/boxplots_mileage_by_seller_type.png b/eda/cars_eda_figures/boxplots_mileage_by_seller_type.png new file mode 100644 index 0000000..5b3477d Binary files /dev/null and b/eda/cars_eda_figures/boxplots_mileage_by_seller_type.png differ diff --git a/eda/cars_eda_figures/boxplots_present_price_by_fuel_type.png b/eda/cars_eda_figures/boxplots_present_price_by_fuel_type.png new file mode 100644 index 0000000..cb1bc8f Binary files /dev/null and b/eda/cars_eda_figures/boxplots_present_price_by_fuel_type.png differ diff --git a/eda/cars_eda_figures/boxplots_present_price_by_seller_type.png b/eda/cars_eda_figures/boxplots_present_price_by_seller_type.png new file mode 100644 index 0000000..70dbd95 Binary files /dev/null and b/eda/cars_eda_figures/boxplots_present_price_by_seller_type.png differ diff --git a/eda/cars_eda_figures/joint_hist_age_and_present_price_ratio.png b/eda/cars_eda_figures/joint_hist_age_and_present_price_ratio.png new file mode 100644 index 0000000..c968c6e Binary files /dev/null and b/eda/cars_eda_figures/joint_hist_age_and_present_price_ratio.png differ diff --git a/eda/cars_eda_figures/joint_hist_mileage_and_present_price_ratio.png b/eda/cars_eda_figures/joint_hist_mileage_and_present_price_ratio.png new file mode 100644 index 0000000..74c4e7d Binary files /dev/null and b/eda/cars_eda_figures/joint_hist_mileage_and_present_price_ratio.png differ diff --git a/eda/cars_eda_figures/quantitative_features_corr_matrix.png b/eda/cars_eda_figures/quantitative_features_corr_matrix.png new file mode 100644 index 0000000..fad6720 Binary files /dev/null and b/eda/cars_eda_figures/quantitative_features_corr_matrix.png differ diff --git a/eda/cars_eda_figures/scatter_age_vs_mileage_colored_by_present_price_ratio.png b/eda/cars_eda_figures/scatter_age_vs_mileage_colored_by_present_price_ratio.png new file mode 100644 index 0000000..739c161 Binary files /dev/null and b/eda/cars_eda_figures/scatter_age_vs_mileage_colored_by_present_price_ratio.png differ diff --git a/eda/cars_eda_figures/scatter_mileage_vs_inv_present_price_ratio_speculative.png b/eda/cars_eda_figures/scatter_mileage_vs_inv_present_price_ratio_speculative.png new file mode 100644 index 0000000..d1a199d Binary files /dev/null and b/eda/cars_eda_figures/scatter_mileage_vs_inv_present_price_ratio_speculative.png differ diff --git a/eda/cars_eda_figures/scatter_selling_vs_present_price_by_seller_type.png b/eda/cars_eda_figures/scatter_selling_vs_present_price_by_seller_type.png new file mode 100644 index 0000000..254fa57 Binary files /dev/null and b/eda/cars_eda_figures/scatter_selling_vs_present_price_by_seller_type.png differ diff --git a/eda/eda.ipynb b/eda/eda.ipynb deleted file mode 100644 index 06c3843..0000000 --- a/eda/eda.ipynb +++ /dev/null @@ -1,1314 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "import pathlib\n", - "import re\n", - "import sys" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [], - "source": [ - "import matplotlib.pyplot\n", - "import numpy\n", - "import pandas" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [], - "source": [ - "BASE_PATH = pathlib.Path('..')" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [], - "source": [ - "CODE_PATH = BASE_PATH\n", - "sys.path.insert(0, str(CODE_PATH.resolve()))" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [], - "source": [ - "import iis_project.pandas_utils\n", - "import iis_project.plotting_utils" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [], - "source": [ - "DATA_PATH = BASE_PATH / 'data'" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [], - "source": [ - "df_orig = pandas.read_csv(DATA_PATH / 'cars.csv')\n", - "df_orig = df_orig.rename(columns=lambda s: re.sub(r'\\s', '_', s.lower().replace(' ', '_')))" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
car_nameyearselling_pricepresent_pricedriven_kmsfuel_typeselling_typetransmissionowner
0ritz20143.355.5927000PetrolDealerManual0
1sx420134.759.5443000DieselDealerManual0
2ciaz20177.259.856900PetrolDealerManual0
3wagon r20112.854.155200PetrolDealerManual0
4swift20144.606.8742450DieselDealerManual0
5vitara brezza20189.259.832071DieselDealerManual0
6ciaz20156.758.1218796PetrolDealerManual0
7s cross20156.508.6133429DieselDealerManual0
8ciaz20168.758.8920273DieselDealerManual0
9ciaz20157.458.9242367DieselDealerManual0
10alto 80020172.853.602135PetrolDealerManual0
11ciaz20156.8510.3851000DieselDealerManual0
12ciaz20157.509.9415000PetrolDealerAutomatic0
13ertiga20156.107.7126000PetrolDealerManual0
14dzire20092.257.2177427PetrolDealerManual0
15ertiga20167.7510.7943000DieselDealerManual0
\n", - "
" - ], - "text/plain": [ - " car_name year selling_price present_price driven_kms fuel_type \\\n", - "0 ritz 2014 3.35 5.59 27000 Petrol \n", - "1 sx4 2013 4.75 9.54 43000 Diesel \n", - "2 ciaz 2017 7.25 9.85 6900 Petrol \n", - "3 wagon r 2011 2.85 4.15 5200 Petrol \n", - "4 swift 2014 4.60 6.87 42450 Diesel \n", - "5 vitara brezza 2018 9.25 9.83 2071 Diesel \n", - "6 ciaz 2015 6.75 8.12 18796 Petrol \n", - "7 s cross 2015 6.50 8.61 33429 Diesel \n", - "8 ciaz 2016 8.75 8.89 20273 Diesel \n", - "9 ciaz 2015 7.45 8.92 42367 Diesel \n", - "10 alto 800 2017 2.85 3.60 2135 Petrol \n", - "11 ciaz 2015 6.85 10.38 51000 Diesel \n", - "12 ciaz 2015 7.50 9.94 15000 Petrol \n", - "13 ertiga 2015 6.10 7.71 26000 Petrol \n", - "14 dzire 2009 2.25 7.21 77427 Petrol \n", - "15 ertiga 2016 7.75 10.79 43000 Diesel \n", - "\n", - " selling_type transmission owner \n", - "0 Dealer Manual 0 \n", - "1 Dealer Manual 0 \n", - "2 Dealer Manual 0 \n", - "3 Dealer Manual 0 \n", - "4 Dealer Manual 0 \n", - "5 Dealer Manual 0 \n", - "6 Dealer Manual 0 \n", - "7 Dealer Manual 0 \n", - "8 Dealer Manual 0 \n", - "9 Dealer Manual 0 \n", - "10 Dealer Manual 0 \n", - "11 Dealer Manual 0 \n", - "12 Dealer Automatic 0 \n", - "13 Dealer Manual 0 \n", - "14 Dealer Manual 0 \n", - "15 Dealer Manual 0 " - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "df_orig.head(0x10)" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "301" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "len(df_orig)" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
lengthdtype
car_name301object
year301int64
selling_price301float64
present_price301float64
driven_kms301int64
fuel_type301object
selling_type301object
transmission301object
owner301int64
\n", - "
" - ], - "text/plain": [ - " length dtype\n", - "car_name 301 object\n", - "year 301 int64\n", - "selling_price 301 float64\n", - "present_price 301 float64\n", - "driven_kms 301 int64\n", - "fuel_type 301 object\n", - "selling_type 301 object\n", - "transmission 301 object\n", - "owner 301 int64" - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "iis_project.pandas_utils.describe_df(df_orig)" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [], - "source": [ - "numeric_columns_orig = ('selling_price', 'present_price', 'driven_kms')\n", - "categorical_columns_orig = ('car_name', 'fuel_type', 'selling_type', 'transmission', 'owner')" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
selling_pricepresent_pricedriven_kms
count301.000000301.000000301.000000
mean4.6612967.62847236947.205980
std5.0828128.64258438886.883882
min0.1000000.320000500.000000
25%0.9000001.20000015000.000000
50%3.6000006.40000032000.000000
75%6.0000009.90000048767.000000
max35.00000092.600000500000.000000
\n", - "
" - ], - "text/plain": [ - " selling_price present_price driven_kms\n", - "count 301.000000 301.000000 301.000000\n", - "mean 4.661296 7.628472 36947.205980\n", - "std 5.082812 8.642584 38886.883882\n", - "min 0.100000 0.320000 500.000000\n", - "25% 0.900000 1.200000 15000.000000\n", - "50% 3.600000 6.400000 32000.000000\n", - "75% 6.000000 9.900000 48767.000000\n", - "max 35.000000 92.600000 500000.000000" - ] - }, - "execution_count": 12, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "df_orig[list(numeric_columns_orig)].describe()" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 13, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "all((len(s) == len(df_orig)) for _, s in df_orig.items())" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "'car_name': (98 values)\n", - "'fuel_type': 'Petrol', 'Diesel', 'CNG'\n", - "'selling_type': 'Dealer', 'Individual'\n", - "'transmission': 'Manual', 'Automatic'\n", - "'owner': np.int64(0), np.int64(1), np.int64(3)\n" - ] - } - ], - "source": [ - "categorical_values_for_columns_orig = {\n", - " column: series.unique()\n", - " for column, series in df_orig[list(categorical_columns_orig)].items()\n", - "}\n", - "\n", - "for column, values in categorical_values_for_columns_orig.items():\n", - " if len(values) <= 0x10:\n", - " values_str = ', '.join(map(repr, values))\n", - " else:\n", - " values_str = f'({len(values)} values)'\n", - " print(f'{column!r}: {values_str}')" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAiYAAAGzCAYAAAAbjdwrAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjYsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvq6yFwwAAAAlwSFlzAAAPYQAAD2EBqD+naQAAIg1JREFUeJzt3XtwVPX9//HXJuRihHAxkAsEwkVhwiWUCBmKSoBwiZZykSkOtUTsIJfEYqMdgZkK1rFQvDRW1tLWEWrHC4ICVSzlIhdFhIBEaqMMoUFRboJCQgIh3f18//CX/TUmXBI3OZ/dfT5mmHHPLmff55MDebp7yLqMMUYAAAAWCHN6AAAAgBqECQAAsAZhAgAArEGYAAAAaxAmAADAGoQJAACwBmECAACsQZgAAABrECYAAMAahAmAWlasWCGXy6UjR474tmVmZiozM9N3+8iRI3K5XFqxYkWzz9cUvnt8AJxDmAAAAGu0cHoAAIGnS5cuunDhgiIiIpwexS82btzo9AgA/h9eMQHQYC6XS9HR0QoPD3d6lO+lsrJSkhQZGanIyEiHpwEgESZA0CgvL9cDDzyglJQURUVFqUOHDho5cqQ+/PBD32N2796tMWPGqHXr1oqJidHQoUO1c+fOBj9XfdeY3HPPPWrZsqW+/PJLjR8/Xi1btlT79u310EMPyePx1Pr9Z86c0c9+9jPFxsaqTZs2ysnJ0UcffdTg61a2bdsml8ullStXav78+UpISND111+vH//4xzp69Gitx2ZmZqpPnz7at2+fbrvtNsXExGj+/Pm++757jcnFixe1cOFC3XTTTYqOjlZiYqImTpyow4cP+x7j9XpVUFCg3r17Kzo6WvHx8ZoxY4a++eabaz4GALXxVg4QJGbOnKnVq1crLy9PqampOnPmjN577z198sknGjBggN555x1lZ2crPT1dCxYsUFhYmJYvX67hw4fr3Xff1aBBg773DB6PR6NHj1ZGRoaefPJJbd68WU899ZS6d++uWbNmSfr2m/nYsWO1Z88ezZo1S7169dK6deuUk5PT6Od9/PHH5XK59PDDD+vUqVMqKChQVlaWioqKdN111/ked+bMGWVnZ+uuu+7S3Xffrfj4+Msex49+9CNt2bJFd911l+bMmaPy8nJt2rRJH3/8sbp37y5JmjFjhlasWKFp06bpF7/4hUpLS7V06VLt379fO3fuDJq3uoBmZQAEhdatW5vc3Nx67/N6vebGG280o0ePNl6v17e9srLSdO3a1YwcOdK3bfny5UaSKS0t9W0bOnSoGTp0qO92aWmpkWSWL1/u25aTk2Mkmd/85je1nvsHP/iBSU9P991+/fXXjSRTUFDg2+bxeMzw4cPr7PNqtm7daiSZjh07mrKyMt/21157zUgyzzzzTK1jkGSWLVtWZz/fPb4XXnjBSDJPP/10ncfWrN+7775rJJmXXnqp1v0bNmyodzuAa8NbOUCQaNOmjXbv3q1jx47Vua+oqEiHDh3SlClTdObMGZ0+fVqnT59WRUWFRowYoR07dsjr9fpljpkzZ9a6feutt+o///mP7/aGDRsUERGh6dOn+7aFhYUpNze30c85depUtWrVynd70qRJSkxM1Ntvv13rcVFRUZo2bdpV9/f6668rLi5O999/f537XC6XJGnVqlVq3bq1Ro4c6VvP06dPKz09XS1bttTWrVsbfTxAKOOtHCBILFmyRDk5OUpOTlZ6erpuv/12TZ06Vd26ddOhQ4ck6Ypvl5w7d05t27b9XjNER0erffv2tba1bdu21jUXn332mRITExUTE1PrcT169Gj089544421brtcLvXo0aPWz2KRpI4dO17TRa6HDx9Wz5491aLF5f+KPHTokM6dO6cOHTrUe/+pU6euPjiAOggTIEj85Cc/0a233qo1a9Zo48aNeuKJJ/S73/1Ob7zxhu/VkCeeeEL9+/ev9/e3bNnye89g+7/S+d/rTb4vr9erDh066KWXXqr3/u8GGoBrQ5gAQSQxMVGzZ8/W7NmzderUKQ0YMECPP/64fv/730uSYmNjlZWV5eiMXbp00datW1VZWVnrVZOSkpJG77PmFaEaxhiVlJSoX79+jdpf9+7dtXv3blVXV1/2Atbu3btr8+bNGjJkiF+DBwh1XGMCBAGPx6Nz587V2tahQwclJSWpqqpK6enp6t69u5588kmdP3++zu//6quvmmtUjR49WtXV1frLX/7i2+b1euV2uxu9zxdffFHl5eW+26tXr9bx48eVnZ3dqP3deeedOn36tJYuXVrnPmOMpG9fofJ4PHrsscfqPOa///2vzp4926jnBkIdr5gAQaC8vFydOnXSpEmTlJaWppYtW2rz5s0qLCzUU089pbCwMD3//PPKzs5W7969NW3aNHXs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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAicAAAGzCAYAAAD0T7cVAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjYsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvq6yFwwAAAAlwSFlzAAAPYQAAD2EBqD+naQAAI4xJREFUeJzt3XtwVOXBx/HfJiQbIkm4RBICCaGIxQQRG5KI2heUm4ig4gUnXiJYOpaNQjNVoY4I06EwtR1R2daiI9Qqioh4wYpiAK2KEFBQjCBUVBQTQSQriYY1+7x/dLLjNtw2bnKezX4/M4yes4dnn+xDyJfdc3ZdxhgjAAAAS8Q5PQEAAIAfI04AAIBViBMAAGAV4gQAAFiFOAEAAFYhTgAAgFWIEwAAYBXiBAAAWIU4AQAAViFOAOB/LFmyRC6XS5988onTUwFiEnECwDpLly7VggULnJ4GAIe4+GwdALa55JJLtH37dseeuWhsbJTf75fb7ZbL5XJkDkAs45kTIIYEAgF9//33Tk/DWnV1dZKk+Ph4JSUlESaAQ4gTIArNnj1bLpdLO3bs0NVXX63U1FR169ZN06ZNC4kPl8ulsrIyPf7448rPz5fb7dbq1aslSV988YUmT56sjIwMud1u5efn65FHHml2Xw888IDy8/OVnJysLl26aPDgwVq6dGnIMScz1vr16+VyufTUU09p7ty56tWrl5KSkjR8+HDt3r07eNywYcP04osv6tNPP5XL5ZLL5VJubu5JPza5ubm65JJL9Morr2jQoEFKSkpSXl6ennnmmZDjms4ree211zR16lR1795dvXr1Crntf5+5eemllzR06FClpKQoNTVVhYWFzR6LjRs36qKLLlJaWpqSk5M1dOhQvfnmmyc9fwBSB6cnAKDlrr76auXm5mrevHl6++23df/99+ubb77Ro48+Gjxm7dq1euqpp1RWVqb09HTl5uaqpqZG55xzTjBeTj31VL300ku66aab5PP5NH36dEnSQw89pFtvvVVXXnllMHzee+89bdy4USUlJZJ00mM1mT9/vuLi4vS73/1OtbW1+tOf/qRrr71WGzdulCTdeeedqq2t1eeff657771XktSpU6ewHpddu3Zp4sSJuvnmm1VaWqrFixfrqquu0urVqzVy5MiQY6dOnapTTz1Vs2bNCj5zcjRLlizR5MmTlZ+fr5kzZ6pz58569913tXr16uBjsXbtWo0ZM0YFBQW6++67FRcXp8WLF+vCCy/Uv//9bxUVFYX1dQAxywCIOnfffbeRZMaPHx+yf+rUqUaS2bZtmzHGGEkmLi7OfPDBByHH3XTTTaZHjx7mwIEDIfuvueYak5aWZurr640xxlx66aUmPz//uHM52bHWrVtnJJkzzjjDNDQ0BI+77777jCTz/vvvB/eNHTvW9O7d+yQeieZ69+5tJJkVK1YE99XW1poePXqYs88+O7hv8eLFRpI5//zzzQ8//BAyRtNte/bsMcYYc+jQIZOSkmKKi4vNd999F3JsIBAI/rdfv35m9OjRwX3GGFNfX2/69OljRo4c2aKvB4hFvKwDRDGPxxOyfcstt0iS/vWvfwX3DR06VHl5ecFtY4xWrFihcePGyRijAwcOBH+NHj1atbW1eueddyRJnTt31ueff67Kysqj3n84YzWZNGmSEhMTg9u//OUvJUkff/zxT3gkQmVlZenyyy8PbqempuqGG27Qu+++q+rq6pBjp0yZovj4+OOOt2bNGn377beaMWOGkpKSQm5rOi9l69at2rVrl0pKSvT1118HH4e6ujoNHz5cr7/+ugKBQIS+QqB942UdIIr169cvZLtv376Ki4sLOVeiT58+Icfs379fhw4d0qJFi7Ro0aKjjvvVV19Jku644w69+uqrKioq0mmnnaZRo0appKRE5513XthjNcnJyQnZ7tKliyTpm2++OcFXe/JOO+20Zieznn766ZKkTz75RJmZmcH9//v4HM1//vMfSdKAAQOOecyuXbskSaWlpcc8pra2Nvj1Ajg24gRoR452dUnHjh1Dtpv+9X7dddcd8wfpwIEDJUlnnHGGdu7cqVWrVmn16tVasWKF/vrXv2rWrFmaM2dOWGM1OdazFMahdzX438enpZoei3vuuUeDBg066jHhnjsDxCriBIhiu3btCvmX/+7duxUIBI57dcupp56qlJQUNTY2asSIESe8j1NOOUUTJ07UxIkTdeTIEU2YMEFz587VzJkzwx7rZP3US3h3794tY0zIOB999JEkhXXlT5O+fftKkrZv367TTjvtuMekpqZG9LEAYhHnnABRzOv1hmw/8MADkqQxY8Yc8/fEx8friiuu0IoVK7R9+/Zmt+/fvz/4/19//XXIbYmJicrLy5MxRn6/P6yxwnHKKaeo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JZo4caL279+vWbNmqbq6WoMGDdLq1aubnSQbLq/XK6/Xq8bGxp80DtBSuTNedHoKYftk/linpwAAYQs7ToYNG6YTvTVKWVmZysrKWjypo/F4PPJ4PPL5fEpLS4vo2AAAwB6OfLYOAADAsRAnAADAKsQJAACwCnECAACsQpwAAACrRE2ceL1e5eXlqbCw0OmpAACAVhQ1ceLxeFRVVaXKykqnpwIAAFpR1MQJAACIDcQJAACwCnECAACsQpwAAACrECcAAMAqxAkAALAKcQIAAKwSNXHCm7ABABAboiZOeBM2AABiQ9TECQAAiA3ECQAAsApxAgAArEKcAAAAqxAnAADAKsQJAACwCnECAACsEjVxwpuwAQAQG6ImTngTNgAAYkPUxAkAAIgNxAkAALAKcQIAAKxCnAAAAKsQJwAAwCrECQAAsApxAgAArEKcAAAAqxAnAADAKlETJ7x9PQAAsSFq4oS3rwcAIDZETZwAAIDYQJwAAACrECcAAMAqxAkAALAKcQIAAKxCnAAAAKsQJwAAwCrECQAAsApxAgAArEKcAAAAqxAnAADAKsQJAACwStTECZ9KDABAbIiaOOFTiQEAiA1REycAACA2ECcAAMAqxAkAALAKcQIAAKxCnAAAAKsQJwAAwCrECQAAsApxAgAArEKcAAAAqxAnAADAKsQJAACwCnECAACsQpwAAACrECcAAMAqxAkAALAKcQIAAKwSNXHi9XqVl5enwsJCp6cCAABaUdTEicfjUVVVlSorK52eCgAAaEVREycAACA2ECcAAMAqxAkAALAKcQIAAKxCnAAAAKsQJwAAwCrECQAAsApxAgAArEKcAAAAqxAnAADAKsQJAACwCnECAACsQpwAAACrECcAAMAqxAkAALAKcQIAAKxCnAAAAKsQJwAAwCrECQAAsApxAgAArEKcAAAAqxAnAADAKsQJAACwStTEidfrVV5engoLC52eCgAAaEVREycej0dVVVWqrKx0eioAAKAVRU2cAACA2ECcAAAAqxAnAADAKsQJAACwCnECAACsQpwAAACrECcAAMAqxAkAALAKcQIAAKxCnAAAAKsQJwAAwCrECQAAsApxAgAArEKcAAAAqxAnAADAKsQJAACwCnECAACsQpwAAACrECcAAMAqxAkAALAKcQIAAKxCnAAAAKsQJwAAwCrECQAAsApxAgAA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7FgzefLkkH0TJkww1157rTGGdXBKzL6sc+TIEW3ZskUjRowI7ouLi9OIESO0YcMGB2cWW2prayVJXbt2lSRt2bJFfr8/ZF369++vnJwc1iXCPB6Pxo4dG/JYS6xBW3n++ec1ePBgXXXVVerevbvOPvtsPfTQQ8Hb9+zZo+rq6pB1SEtLU3FxMesQQeeee64qKir00UcfSZK2bdumN954Q2PGjJHEOjgl6j6VOFIOHDigxsZGZWRkhOzPyMjQjh07HJpVbAkEApo+fbrOO+88DRgwQJJUXV2txMREde7cOeTYjIwMVVdXOzDL9unJJ5/UO++8o8rKyma3sQZt4+OPP9bf/vY3lZeX6/e//70qKyt16623KjExUaWlpcHH+mh/R7EOkTNjxgz5fD71799f8fHxamxs1Ny5c3XttddKEuvgkJiNEzjP4/Fo+/bteuONN5yeSkzZu3evpk2bpjVr1igpKcnp6cSsQCCgwYMH649//KMk6eyzz9b27dv14IMPqrS01OHZxY6nnnpKjz/+uJYuXar8/Hxt3bpV06dPV1ZWFuvgoJh9WSc9PV3x8fHNrkCoqalRZmamQ7OKHWVlZVq1apXWrVunXr16BfdnZmbqyJEjOnToUMjxrEvkbNmyRV999ZV+8YtfqEOHDurQoYNee+013X///erQoYMyMjJYgzbQo0cP5eXlhew744wz9Nlnn0lS8LHm76jWddttt2nGjBm65pprdOaZZ+r666/Xb3/7W82bN08S6+CUmI2TxMREFRQUqKKiIrgvEAiooqJCQ4YMcXBm7ZsxRmVlZVq5cqXWrl2rPn36hNxeUFCghISEkHXZuXOnPvvsM9YlQoYPH673339fW7duDf4aPHiwrr322uD/swat77zzzmt2Gf1HH32k3r17S5L69OmjzMzMkHXw+XzauHEj6xBB9fX1iosL/VEYHx+vQCAgiXVwjNNn5DrpySefNG632yxZssRUVVWZX//616Zz586murra6am1W7/5zW9MWlqaWb9+vfnyyy+Dv+rr64PH3HzzzSYnJ8esXbvWbN682QwZMsQMGTLEwVm3fz++WscY1qAtbNq0yXTo0MHMnTvX7Nq1yzz++OMmOTnZPPbYY8Fj5s+fbzp37myee+45895775lLL72US1gjrLS01PTs2TN4KfEzzzxj0tPTze233x48hnVoezEdJ8YY88ADD5icnByTmJhoioqKzNtvv+30lNo1SUf9tXjx4uAx3333nZk6darp0qWLSU5ONpdffrn58ssvnZt0DPjfOGEN2sYLL7xgBgwYYNxut+nfv79ZtGhRyO2BQMDcddddJiMjw7jdbjN8+HCzc+dOh2bbPvl8PjNt2jSTk5NjkpKSzM9+9jNz5513moaGhuAxrEPbcxnzo7fBAwAAcFjMnnMCAADsRJwAAACrECcAAMAqxAkAALAKcQIAAKxCnAAAAKsQJwAAwCrECQAAsApxAgAArEKcAAAAqxAnAADAKv8Pk6E2Ks3I3rgAAAAASUVORK5CYII=", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "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s44M5hwZzDky+nLOxhi1tbUpNzdXcXE9f+aJ4371ExcXF1KJhSotLY1vgghgzpHDrCODOUcGc46Mvppzbz4CxzFPpgUAALGHUAEAANYiVP6P2+1WdXW13G53tJfSrzHnyGHWkcGcI4M5R4aNc3bck2kBAEDs4BEVAABgLUIFAABYi1ABAADWIlQAAIC1CBUAAGAtQuX/eL1e5efnKzk5WcXFxdq+fXu0lxQ1W7Zs0axZs5SbmyuXy6U1a9YEXW+M0aJFizR06FClpKSotLRU77//ftA+J0+e1P3336+0tDRlZGTor//6r3XmzJmgffbs2aNbbrlFycnJysvL07Jly7qt5ZVXXtENN9yg5ORkjRs3Tq+99lrIa7HRkiVLVFhYqIEDByorK0uzZ8/WgQMHgvb5/PPP5fF49LWvfU0DBgzQ3Xffrebm5qB9Pv74Y82cOVOpqanKysrST37yE124cCFon02bNummm26S2+3WyJEjtWLFim7rudL9vydrsdWzzz6r8ePHB95ps6SkRK+//nrgeubcN5YuXSqXy6XHHnsssI1ZX72amhq5XK6gPzfccEPg+n45YwOzcuVKk5SUZH75y1+a9957zzz44IMmIyPDNDc3R3tpUfHaa6+Zv//7vze/+c1vjCSzevXqoOuXLl1q0tPTzZo1a8zu3bvNHXfcYa699lpz7ty5wD7f/e53zYQJE8xbb71l/ud//seMHDnS3HvvvYHrT58+bbKzs839999vGhsbza9//WuTkpJinn/++cA+W7duNfHx8WbZsmWmqanJ/MM//INJTEw0e/fuDWktNiorKzMvvviiaWxsNLt27TK33367GTFihDlz5kxgn4ceesjk5eWZ+vp6s2PHDvPNb37TfOtb3wpcf+HCBTN27FhTWlpq3n33XfPaa6+ZzMxMs3DhwsA+H374oUlNTTVVVVWmqanJPP300yY+Pt6sXbs2sE9P7v9XWovNfve735lXX33V/O///q85cOCA+bu/+zuTmJhoGhsbjTHMuS9s377d5Ofnm/Hjx5tHH300sJ1ZX73q6mozZswYc/To0cCf48ePB67vjzMmVIwxRUVFxuPxBC77fD6Tm5trlixZEsVV2eHLoeL3+01OTo554oknAttOnTpl3G63+fWvf22MMaapqclIMg0NDYF9Xn/9deNyucwnn3xijDHmmWeeMYMG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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "for column, series in df_orig[list(numeric_columns_orig)].items():\n", - " _fig, _ax = matplotlib.pyplot.subplots()\n", - " _ax.set_title(str(column))\n", - " #_ax.set_xscale('symlog')\n", - " _ax.set_yscale('log')\n", - " _ax.grid(True)\n", - " _ = _ax.hist(series, bins=iis_project.plotting_utils.suggest_bins_num(len(series)))" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAiYAAAGzCAYAAAAbjdwrAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjYsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvq6yFwwAAAAlwSFlzAAAPYQAAD2EBqD+naQAAIV5JREFUeJzt3Xl0VPX9//HXJGSBbBADhCVsAYQgmyGgYL8sBQMqi5bFNUFbweMgeIC2pBUMINKqxWgd3HqAKqAUFU5PURAjKAdpjShLDdCAiaLsIkRAQpj5/P7wxxxjAhKccD8zeT7O4Xjm3jt33hMv4ZmZeycuY4wRAACABcKcHgAAAOAcwgQAAFiDMAEAANYgTAAAgDUIEwAAYA3CBAAAWIMwAQAA1iBMAACANQgTAABgDcIEqOUKCgrUu3dvxcTEyOVyacuWLQF/jH79+qlfv34B3y+A0FPH6QEAOKe8vFyjRo1SdHS0nnzySdWrV08tW7Z0eixJ0vz581WvXj2NHTvW6VEAXEaECVCL7dmzR59//rlefPFF/eY3v3F6nArmz5+vpKQkwgSoZXgrB6jFDh06JEmqX7++s4MAwP9HmAC11NixY9W3b19J0qhRo+RyufznglR1PsjYsWPVqlWrCst8Pp/y8vLUqVMnRUdHq3Hjxho/fry++eabnzVbq1at9Omnn+q9996Ty+Xyz/bZZ5/J5XLpySefrHSfDz74QC6XS6+88ookKTc3Vy6XSzt37tTo0aMVHx+vK664QpMmTdLp06cr3X/x4sVKT09X3bp1lZiYqFtvvVV79+79Wc8DQPURJkAtNX78eP3hD3+QJE2cOFEvv/yy/vjHP1Z7H7/97W/Vp08fPfXUU7r77ru1ZMkSZWZmqry8/JJny8vLU/PmzdWhQwe9/PLL/tnatGmjPn36aMmSJZXus2TJEsXFxWn48OEVlo8ePVqnT5/W3LlzdcMNN+jpp5/WuHHjKmwzZ84cZWVlqV27dpo3b54efPBB5efn6//+7/907NixS34eAC6BAVBrrVu3zkgyy5cv9y/r27ev6du3b6Vts7OzTcuWLf23N2zYYCSZJUuWVNhu9erVlZafb58X0qlTpyrv8/zzzxtJZseOHf5lZ86cMUlJSSY7O9u/7OGHHzaSzLBhwyrc//777zeSzNatW40xxpSUlJjw8HAzZ86cCttt377d1KlTp9JyADWLV0wAXJLly5crISFBgwYN0pEjR/x/0tPTFRsbq3Xr1tXI444ePVrR0dEVXjVZs2aNjhw5ojvvvLPS9m63u8LtBx54QJL05ptvSpLeeOMN+Xw+jR49usLzSE5OVrt27WrseQCoGlflALgkRUVFOn78uBo1alTl+nMn1gZa/fr1NXToUC1dulSzZ8+W9P3bOM2aNdOAAQMqbd+uXbsKt1NTUxUWFqaSkhJJ3z8PY0yl7c6JiIgI7BMAcEGECYAKXC6XjDGVlnu93gq3fT6fGjVqVOX5HpLUsGHDGplPkrKysrR8+XJ98MEH6ty5s/75z3/q/vvvV1jYT78I7HK5Ktz2+XxyuVx66623FB4eXmn72NjYgM0N4KcRJgAqaNCggT777LNKyz///PMKt1NTU/XOO++oT58+qlu3bsDn+HFA/NDgwYPVsGFDLVmyRL169dKpU6d01113VbltUVGRWrdu7b+9e/du+Xw+/xVGqampMsaodevWat++fUCfA4Dq4xwTABWkpqZq586dOnz4sH/Z1q1btXHjxgrbjR49Wl6v1/92yg+dPXv2Z1/NEhMTc9591KlTR7fddpv+8Y9/aNGiRercubO6dOlS5bYej6fC7b/+9a+SpCFDhkiSbrnlFoWHh2vmzJmVXikyxujrr7/+Wc8DQPXwigmACu655x7NmzdPmZmZ+vWvf61Dhw7pueeeU6dOnVRaWurfrm/fvho/frzmzp2rLVu26Prrr1dERISKioq0fPlyPfXUUxo5cuQlz5Genq5nn31WjzzyiNq2batGjRpVOIckKytLTz/9tNatW6c///nP591PcXGxhg0bpsGDB2vTpk1avHixbr/9dnXt2lXS9yH2yCOPKCcnRyUlJRoxYoTi4uJUXFysFStWaNy4cZo6deolPw8A1eToNUEAHFXV5cLGGLN48WLTpk0bExkZabp162bWrFlT6XLhc1544QWTnp5u6tata+Li4kznzp3N7373O7Nv3z7/NpdyufCBAwfMjTfeaOLi4oykKu/fqVMnExYWZr788stK685dLlxYWGhGjhxp4uLiTIMGDcyECRPMd999V2n7119/3Vx33XUmJibGxMTEmA4dOhi322127dpVrbkB/DwuY6o4yw0AgkD37t2VmJio/Pz8Sutyc3M1c+ZMHT58WElJSQ5MB+BScI4JgKD0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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAksAAAGzCAYAAAA/lFPrAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjYsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvq6yFwwAAAAlwSFlzAAAPYQAAD2EBqD+naQAALnhJREFUeJzt3XtUVXXC//HP4eJdvIFcFMHK1oAmKIrLC6FHyjB5xJkaGx0BZ0anCWdSHnOontRqomzKYaWMZqWWo8VjiV0kS9HR0RwviC5bmCWjxZMCMpQGFuI5+/dH0/lJwFdAEMX3ay3+OPt893d/D0vg7d77gM2yLEsAAAColVtLLwAAAOBaRiwBAAAYEEsAAAAGxBIAAIABsQQAAGBALAEAABgQSwAAAAbEEgAAgAGxBAAAYEAsAbhurF69WjabTSdPnnRtGz16tEaPHu16fPLkSdlsNq1evfqqrw9A60QsAUAzOHXqlBYuXKhDhw619FIAXCGPll4AADSloKAgffvtt/L09GzRdZw6dUqPP/64goODFR4e3qJrAXBliCUArYrNZlO7du1aehkAWhEuwwFodt98841mz56t4OBgtW3bVj179tQdd9yhgwcPusbs3btXd911l7p06aIOHTooOjpau3fvbvCxartnKSkpSZ06ddKXX36p+Ph4derUST4+Ppo7d64cDke1/f/9739r2rRp8vLyUteuXZWYmKjDhw836D6ov//97xo6dKgkafr06bLZbK79FyxYIE9PT505c6bGfjNnzlTXrl313XffSZKCg4M1YcIEffjhhwoPD1e7du0UGhqqDRs21Nj366+/1uzZsxUYGKi2bdvqlltu0aJFi+R0Ouv5mQNQF2IJQLO7//77tWzZMv3sZz/TX//6V82dO1ft27fX0aNHJUnbtm3T7bffrnPnzmnBggVKS0vT119/Lbvdrn379jXJGhwOh8aNG6cePXroueeeU3R0tJ5//nmtWLHCNcbpdCouLk6vv/66EhMT9dRTT+n06dNKTExs0LFCQkL0xBNPSPo+gNasWaM1a9bo9ttv17Rp03Tx4kVlZmZW2+fChQt688039bOf/azambHPPvtMkydPVmxsrJ5++ml5eHjo3nvv1ZYtW1xjzp8/r+joaP3tb39TQkKCXnjhBY0cOVIPP/ywUlJSGvPpAnApCwCaWZcuXazk5ORan3M6nVa/fv2scePGWU6n07X9/PnzVt++fa077rjDtW3VqlWWJOvEiROubdHR0VZ0dLTr8YkTJyxJ1qpVq1zbEhMTLUnWE088Ue3YgwYNsiIiIlyP33rrLUuSlZ6e7trmcDgsu91eY87L2b9/f537DB8+3Bo2bFi1bRs2bLAkWdu3b3dtCwoKsiRZb731lmvb2bNnLX9/f2vQoEGubU8++aTVsWNH69NPP602Z2pqquXu7m598cUX9V43gJo4swSg2XXt2lV79+7VqVOnajx36NAhffbZZ5oyZYr+/e9/q7S0VKWlpaqoqNDYsWO1c+fOJruUdP/991d7HBUVpX/961+ux5s3b5anp6dmzJjh2ubm5qbk5OQmOf4PEhIStHfvXhUUFLi2rV27VoGBgYqOjq42NiAgQJMmTXI99vLyUkJCgvLy8lRUVCRJWr9+vaKiotStWzfX56+0tFQxMTFyOBzauXNnk64fuNEQSwCa3bPPPquPP/5YgYGBioyM1MKFC12R8tlnn0mSEhMT5ePjU+3j5ZdfVmVlpc6ePXvFa2jXrp18fHyqbevWrZu++uor1+PPP/9c/v7+6tChQ7Vxt9xyyxUf/1KTJ09W27ZttXbtWknS2bNn9d5772nq1Kmy2Ww1jv3jbbfeeqskuX7f1GeffabNmzfX+PzFxMRIkkpKSpp0/cCNhnfDAWh2P//5zxUVFaWsrCx9+OGH+vOf/6xFixZpw4YNrrNGf/7zn+t8i32nTp2ueA3u7u5XPEdT6datmyZMmKC1a9dq/vz5evPNN1VZWalf/vKXjZrP6XTqjjvu0Lx582p9/oe4AtA4xBKAq8Lf318PPPCAHnjgAZWUlGjw4MF66qmn9Je//EXS95eXfjgT0lKCgoK0fft2nT9/vtrZpePHjzd4rh+fDfqxhIQETZw4Ufv379fatWs1aNAg9e/fv8a448ePy7KsavN9+umnkr5/t5wk3XzzzSovL2/xzx/QWnEZDkCzcjgcNS6j9ezZUwEBAaqsrFRERIRuvvlmPffccyovL6+xf21vsW8u48aNU1VVlV566SXXNqfTqYyMjAbP1bFjR0nfv6W/NrGxsfL29taiRYu0Y8eOOs8qnTp1SllZWa7H586d02uvvabw8HD5+flJ+v7M3Z49e/TBBx/U2P/rr7/WxYsXG7x+AP8fZ5YANKtvvvlGvXv31j333KOwsDB16tRJW7du1f79+/X888/Lzc1NL7/8smJjY9W/f39Nnz5dvXr10pdffqnt27fLy8tL77777lVZa3x8vCIjI/Xf//3fOn78uH7yk5/onXfeUVlZmaTLny261M0336yuXbtq+fLl6ty5szp27Khhw4apb9++kiRPT0/dd999Wrp0qdzd3fWLX/yi1nluvfVW/frXv9b+/fvl6+urlStXqri4WKtWrXKNeeihh/TOO+9owoQJSkpKUkREhCoqKnTkyBG9+eabOnnypLy9va/gMwPc2IglAM2qQ4cOeuCBB/Thhx+67lG65ZZb9Ne//lW/+93vJH3/x3D37NmjJ598UkuXLlV5ebn8/Pw0bNgw/fa3v71qa3V3d9emTZv04IMP6tVXX5Wbm5smTZqkBQsWaOTIkQ36zeCenp569dVX9fDDD+v+++/XxYsXtWrVKlcsSd9filu6dKnGjh0rf3//Wufp16+flixZooceekjHjh1T3759lZmZqXHjxrnGdOjQQTt27FBaWprWr1+v1157TV5eXrr11lv1+OOPq0uXLo3/pACQzbIsq6UXAQDXso0bN2rSpEnatWuXRo4c2WTzHj58WOHh4Xrttdc0bdq0Gs8HBwdrwIABeu+995rsmAAajnuWAOAS3377bbXHDodDS5YskZeXlwYPHtykx3rppZfUqVMn/fSnP23SeQE0LS7DAcAlfv/73+vbb7/V8OHDVVlZqQ0bNuijjz5SWlqa2rdvrwsXLrjuYapLly5d1L59+zqff/fdd5Wfn68VK1Zo1qxZrpvBAVybiCUAuITdbtfzzz+v9957T999951uueUWLVmyRLNmzZIkffTRRxozZoxxjlWrVikpKanO53//+9+ruLhY48eP1+OPP96UywfQDLhnCQAa4KuvvlJubq5xTP/+/eu8YRvA9YdYukRhYaGmTZumkpISeXh46LHHHtO9997b0ssCAAAtiFi6xOnTp1VcXKzw8HAVFRUpIiJCn376KfcTAABwA+OepUv4+/u7Tp37+fnJ29tbZWVll40lp9OpU6dOqXPnzg36pXUAAKDlWJalb775RgEBAXJzM/yCAOsqSEtLs4YMGWJ16tTJ8vHxsSZOnGh98sknTXqMHTt2WBMmTLD8/f0tSVZWVlat45YuXWoFBQVZbdu2tSIjI629e/fWOu7AgQNW//79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GjlypAYMGFDnuICAAG3btk27du3SlClTZLfbFRMTo2XLljX62KWlpXI4HPL19a223dfXV0VFRZK+v/yXmZmpjRs3Kjw8XOHh4Tpy5EijjwkAAK5vV/3dcMnJyfr444+1a9euy47t06eP1qxZo+joaN1000165ZVXZLPZmnV9o0aNktPpbNZjAACA68dVPbM0a9Ysvffee9q+fbt69+592fHFxcWaOXOm4uLidP78ec2ZM+eKju/t7S13d/caN4gXFxfLz8/viuYGAACt01WJJcuyNGvWLGVlZWnbtm3q27fvZfcpLS3V2LFjFRISog0bNignJ0eZmZmaO3duo9fRpk0bRUREKCcnx7XN6XQqJydHw4cPb/S8AACg9WrUZbjy8nIdP37c9fjEiRM6dOiQunfvrj59+mjp0qXKyspyRUlycrLWrVunt99+W507d3bdH9SlSxe1b9++xvxOp1OxsbEKCgpSZmamPDw8FBoaqi1btshut6tXr161nmW63LokKSUlRYmJiRoyZIgiIyOVnp6uiooK17vjAAAALtWoWDpw4IDGjBnjepySkiJJSkxM1OrVq1VaWqqCggLX8z/clD169Ohq86xatUpJSUk15ndzc1NaWpqioqLUpk0b1/awsDBt3bpVPj4+jVqXJE2ePFlnzpzR/PnzVVRUpPDwcG3evLnGTd8AAACSZLMsy2rpRVzvzp07py5duujs2bPy8vJq0rmDUzc16XxovLbulp6NdGjePndVOpr3jQaov5PP3N3SS0ArU1VVpezsbI0fP16enp4tvRw0o/r+/G6R37MEAABwvSCWAAAADIglAAAAA2IJAADAgFgCAAAwIJYAAAAMiCUAAAADYgkAAMCAWAIAADAglgAAAAyIJQAAAANiCQAAwIBYAgAAMCCWAAAADIglAAAAA2IJAADAgFgCAAAwIJYAAAAMiCUAAAADYgkAAMCAWAIAADAglgAAAAyIJQAAAANiCQAAwIBYAgAAMCCWAAAADIglAAAAA2IJAADAgFgCAAAwIJYAAAAMiCUAAAADYgkAAMCAWAIAADAglgAAAAyIJQAAAANiCQAAwIBYAgAAMCCWAAAADIglAAAAA2IJAADAgFgCAAAwIJYAAAAMiCUAAAADYgkAAMCAWAIAADAglgAAAAyIJQAAAANiCQAAwIBYAgAAMCCWAAAADIglAAAA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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "for column, series in df_orig[list(filter(lambda s: s not in ('car_name',), categorical_columns_orig))].items():\n", - " _fig, _ax = matplotlib.pyplot.subplots()\n", - " _ax.set_title(str(column))\n", - " _ax.set_yscale('log')\n", - " _ax.grid(True)\n", - " value_counts = series.value_counts()\n", - " _ = _ax.bar(tuple(map(str, value_counts.index)), value_counts)" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": {}, - "outputs": [], - "source": [ - "labels_to_drop_from_orig = []" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
car_nameyearselling_pricepresent_pricedriven_kmsfuel_typeselling_typetransmissionowner
85camry20062.523.73142000PetrolIndividualAutomatic3
\n", - "
" - ], - "text/plain": [ - " car_name year selling_price present_price driven_kms fuel_type \\\n", - "85 camry 2006 2.5 23.73 142000 Petrol \n", - "\n", - " selling_type transmission owner \n", - "85 Individual Automatic 3 " - ] - }, - "execution_count": 18, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "df_orig.loc[df_orig['owner'].isin((3,))]" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "metadata": {}, - "outputs": [], - "source": [ - "labels_to_drop_from_orig.extend(df_orig.loc[df_orig['owner'].isin((3,))].index)" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
car_nameyearselling_pricepresent_pricedriven_kmsfuel_typeselling_typetransmissionowner
18wagon r20153.255.0935500CNGDealerManual0
35sx420112.957.7449998CNGDealerManual0
86land cruiser201035.0092.6078000DieselDealerManual0
196Activa 3g20080.170.52500000PetrolIndividualAutomatic0
\n", - "
" - ], - "text/plain": [ - " car_name year selling_price present_price driven_kms fuel_type \\\n", - "18 wagon r 2015 3.25 5.09 35500 CNG \n", - "35 sx4 2011 2.95 7.74 49998 CNG \n", - "86 land cruiser 2010 35.00 92.60 78000 Diesel \n", - "196 Activa 3g 2008 0.17 0.52 500000 Petrol \n", - "\n", - " selling_type transmission owner \n", - "18 Dealer Manual 0 \n", - "35 Dealer Manual 0 \n", - "86 Dealer Manual 0 \n", - "196 Individual Automatic 0 " - ] - }, - "execution_count": 20, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "df_orig.loc[(df_orig['present_price'] >= 60.) | (df_orig['driven_kms'] >= 400000) | (df_orig['fuel_type'].isin(('CNG',)))]" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "metadata": {}, - "outputs": [], - "source": [ - "labels_to_drop_from_orig.extend((196,))" - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "metadata": {}, - "outputs": [], - "source": [ - "df = df_orig.drop(labels_to_drop_from_orig)" - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "299" - ] - }, - "execution_count": 23, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "len(df)" - ] - }, - { - "cell_type": "code", - "execution_count": 24, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
lengthdtype
car_name299object
year299int64
selling_price299float64
present_price299float64
driven_kms299int64
fuel_type299object
selling_type299object
transmission299object
owner299int64
\n", - "
" - ], - "text/plain": [ - " length dtype\n", - "car_name 299 object\n", - "year 299 int64\n", - "selling_price 299 float64\n", - "present_price 299 float64\n", - "driven_kms 299 int64\n", - "fuel_type 299 object\n", - "selling_type 299 object\n", - "transmission 299 object\n", - "owner 299 int64" - ] - }, - "execution_count": 24, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "iis_project.pandas_utils.describe_df(df)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": 25, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
selling_pricepresent_pricedriven_kms
count299.000000299.000000299.000000
mean4.6835457.59839535047.187291
std5.0916118.61133527607.236346
min0.1000000.320000500.000000
25%0.9000001.23000015000.000000
50%3.6500006.40000032000.000000
75%6.0000009.87500047500.000000
max35.00000092.600000213000.000000
\n", - "
" - ], - "text/plain": [ - " selling_price present_price driven_kms\n", - "count 299.000000 299.000000 299.000000\n", - "mean 4.683545 7.598395 35047.187291\n", - "std 5.091611 8.611335 27607.236346\n", - "min 0.100000 0.320000 500.000000\n", - "25% 0.900000 1.230000 15000.000000\n", - "50% 3.650000 6.400000 32000.000000\n", - "75% 6.000000 9.875000 47500.000000\n", - "max 35.000000 92.600000 213000.000000" - ] - }, - "execution_count": 25, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "df[list(numeric_columns_orig)].describe()" - ] - }, - { - "cell_type": "code", - "execution_count": 26, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "'car_name': (97 values)\n", - "'fuel_type': 'Petrol', 'Diesel', 'CNG'\n", - "'selling_type': 'Dealer', 'Individual'\n", - "'transmission': 'Manual', 'Automatic'\n", - "'owner': np.int64(0), np.int64(1)\n" - ] - } - ], - "source": [ - "categorical_values_for_columns = {\n", - " column: series.unique()\n", - " for column, series in df[list(categorical_columns_orig)].items()\n", - "}\n", - "\n", - "for column, values in categorical_values_for_columns.items():\n", - " if len(values) <= 0x10:\n", - " values_str = ', '.join(map(repr, values))\n", - " else:\n", - " values_str = f'({len(values)} values)'\n", - " print(f'{column!r}: {values_str}')" - ] - }, - { - "cell_type": "code", - "execution_count": 29, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAicAAAG4CAYAAACeiEfWAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjYsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvq6yFwwAAAAlwSFlzAAAPYQAAD2EBqD+naQAAIPhJREFUeJzt3X9wFPX9x/HXJZCLgQQD0YTwKw6i9WJJOiFJ/VUSBWOKUFA0nbQSo2WmY9LaSWsL0/nyYzoOjK2Y1l6HUgeQVjsRqbQFjUAMpYMIAcRKU5TUYBGaEEQTkmgId/v9w29uvjEQc8kl+9nc8zHD4O3t7b1zc0ue3u3euSzLsgQAAGCICLsHAAAA+P+IEwAAYBTiBAAAGIU4AQAARiFOAACAUYgTAABgFOIEAAAYhTgBAABGIU4AAIBRiBMA+JyNGzfK5XLpxIkTdo8ChCXiBIBxnn/+eZWXl9s9BgCbuPhuHQCmufvuu3X06FHbXrnw+Xzq7OyU2+2Wy+WyZQYgnPHKCRBG/H6/Pv30U7vHMFZbW5skKTIyUtHR0YQJYBPiBHCgFStWyOVy6dixY7r//vsVFxencePG6dFHH+0WHy6XS6WlpXruueeUmpoqt9utyspKSdKpU6f00EMPKTExUW63W6mpqVq/fn2P+3r66aeVmpqqmJgYxcfHa8aMGXr++ee7rdOXbe3evVsul0svvPCCHn/8cU2cOFHR0dG64447VFdXF1gvJydH27dv1/vvvy+XyyWXy6WUlJQ+PzYpKSm6++67tWPHDqWnpys6Oloej0d/+tOfuq3XdVzJ3/72Nz3yyCO6+uqrNXHixG7Xff6Vm1deeUUzZ85UbGys4uLilJmZ2eOx2L9/v+666y6NGTNGMTExmjlzpvbu3dvn+QFII+weAED/3X///UpJSdGqVav0xhtv6Fe/+pU++ugjbdq0KbDOa6+9phdeeEGlpaVKSEhQSkqKGhsb9dWvfjUQL1dddZVeeeUVPfzww2ppadEPfvADSdLvfvc7ff/739fChQsD4fOPf/xD+/fvV2FhoST1eVtdVq9erYiICP3oRz9Sc3OznnjiCX3rW9/S/v37JUk//elP1dzcrA8++EBPPfWUJGn06NFBPS7Hjx9XQUGBvvvd76qoqEgbNmzQfffdp8rKSs2ePbvbuo888oiuuuoqLVu2LPDKyaVs3LhRDz30kFJTU7V06VJdeeWVevPNN1VZWRl4LF577TXl5+crIyNDy5cvV0REhDZs2KDbb79df//735WVlRXUzwGELQuA4yxfvtySZM2bN6/b8kceecSSZL311luWZVmWJCsiIsL65z//2W29hx9+2Bo/frx19uzZbsu/+c1vWmPGjLHa29sty7Ksb3zjG1Zqamqvs/R1W9XV1ZYk64YbbrA6OjoC6/3yl7+0JFlvv/12YNmcOXOsKVOm9OGR6GnKlCmWJGvLli2BZc3Nzdb48eOtr3zlK4FlGzZssCRZt956q3Xx4sVu2+i6rr6+3rIsy/r444+t2NhYKzs72/rkk0+6rev3+wN/T5s2zcrLywsssyzLam9vt6655hpr9uzZ/fp5gHDE2zqAg5WUlHS7/L3vfU+S9PLLLweWzZw5Ux6PJ3DZsixt2bJFc+fOlWVZOnv2bOBPXl6empubdfjwYUnSlVdeqQ8++EA1NTWXvP9gttWluLhYUVFRgcu33XabJOm9994bwCPRXXJyshYsWBC4HBcXp0WLFunNN99UQ0NDt3UXL16syMjIXre3c+dOnT9/XkuWLFF0dHS367qOSzly5IiOHz+uwsJCffjhh4HHoa2tTXfccYf27Nkjv98fop8QGN54WwdwsGnTpnW7PHXqVEVERHQ7VuKaa67ptk5TU5M+/vhjrVu3TuvWrbvkds+cOSNJ+slPfqJdu3YpKytL1157re68804VFhbqlltuCXpbXSZPntztcnx8vCTpo48++oKftu+uvfbaHgezXnfddZKkEydOKCkpKbD884/Ppfz73/+WJN14442XXef48eOSpKKiosuu09zcHPh5AVwecQIMI5c6u+SKK67odrnr/96//e1vX/YX6fTp0yVJN9xwg9555x1t27ZNlZWV2rJli37zm99o2bJlWrlyZVDb6nK5Vyksmz7V4POPT391PRY///nPlZ6efsl1gj12BghXxAngYMePH+/2f/51dXXy+/29nt1y1VVXKTY2Vj6fT7NmzfrC+xg1apQKCgpUUFCgCxcu6J577tHjjz+upUuXBr2tvhroKbx1dXWyLKvbdt59911JCurMny5Tp06VJB09elTXXnttr+vExcWF9LEAwhHHnAAO5vV6u11++umnJUn5+fmXvU1kZKTuvfdebdmyRUePHu1xfVNTU+C/P/zww27XRUVF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1alTp9Ta2qpXXnlFeXl5do0MGI+3quEUfXmuWpalBx98ULfffrseeOCBkNyvI+IkKipKGRkZqqqqCizz+/2qqqrSTTfdZONkw19f3lIbMWKEnnzySeXm5io9PV0//OEPOVMH6EVf36qeNWuW7rvvPr388suaOHEi4YIh15fn6t69e1VRUaGtW7cqPT1d6enpevvttwd0vyMGdOshVFZWpqKiIs2YMUNZWVkqLy9XW1ubiouL7R4NkubNm6d58+bZPQYwrOzatcvuEYAvdOutt8rv94d0m46Jk4KCAjU1NWnZsmVqaGhQenq6Kisre9QcQou31IDQY7+CU9j1XHXE2zpdSktL9f7776ujo0P79+9Xdna23SMNe7ylBoQe+xWcwq7nqmNeOcHgaW1tVV1dXeByfX29jhw5orFjx2ry5Mm8pQb0A/sVnMLI52pIzvmBo1VXV1uSevwpKioKrPP0009bkydPtqKioqysrCzrjTfesG9gwAHYr+AUJj5XHfPdOgAAIDw46pgTAAAw/BEnAADAKMQJAAAwCnECAACMQpwAAACjECcAAMAoxAkAADAKcQIAAIxCnAAAAKMQJwAAwCjECQAAMApxAgAAjEKcAAAAo/wvDrd3+Se43tMAAAAASUVORK5CYII=", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "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aorbb7/9kH0+/PDD+M9//nNM54aTnTsmUAQaGxtj6NChMWXKlBg1alT06tUrVq5cGfX19TFv3rwoLS2Nhx56KGpqamLkyJExderUGDJkSGzdujVWr14d5eXl8Yc//OGEzHrVVVfFmDFj4uabb46NGzfGueeeG7///e/j3//+d0T8/5dL26Nfv35x8cUXx9SpU2P79u0xf/78GDFiRKsXbNvjuuuui8WLF8esWbNi7dq1cckll8TevXtj5cqVMX369PjqV78a48aNi2nTpsWdd94Z69evjy984QvRrVu32LBhQyxZsiTuu+++mDJlyjGdH05mwgSKQM+ePWP69OmxYsWKlndKRowYEQ8++GDL3x8yfvz4eOmll+L222+PBx54IPbs2RMDBw6MsWPHxrRp007YrF26dImlS5fGzJkz41e/+lWUlpbG5MmTY+7cuXHRRRdFjx492n3MOXPmxN/+9re48847o7GxMS677LJ48MEHD3nBtj0zLlu2LO6444749a9/HY8//nicdtppcfHFF8dnPvOZlv0WLFgQVVVV8Ytf/CLmzJkTXbt2jYqKirj22mvjoosuOqZzw8muJH/wviRAhp588smYPHlyPP/8823+pv7MM8/EhAkTYsmSJe5OQJHwjglwwr333nutlpuamuL++++P8vLyOP/88zOaCkiBRznACXfTTTfFe++9FxdeeGHs378/nnjiiXjxxRfjJz/5SZxyyinxwQcftLxzciR9+vQ5QdMCJ5IwAU64Sy+9NObNmxdPPfVUvP/++zFixIi4//77Y8aMGRER8eKLL8aECROOeoyFCxdGRUXFCZgWOJG8YwIk55133ol169YddZ+RI0fGoEGDTtBEwIkiTACAZHj5FQBIRsG9Y9Lc3Bzbtm2L3r17H9NfxAQAnHj5fD4aGxtj8ODBUVp65PsiBRcm27Zti2HDhmU9BgBwDLZs2RJDhw494vaCC5PevXtHRMSmTZuiX79+GU9Dexw4cCBWrFjR8ld3A8XL9c5H7d69O4YNG9byffxICi5MDj6+6d27d5SXl2c8De1x4MCB6NmzZ5SXl/uDCoqc650j+bjXMLz8CgAkQ5gAAMkQJgBAMgomTHK5XFRWVkZ1dXXWowAAnaRgwqSuri4aGhqivr4+61EAgE5SMGECABQ/YQIAJEOYAADJECYAQDKECQCQDGECACRD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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "for column, series in df_orig[['present_price', 'selling_price']].items():\n", - " _fig, _ax = matplotlib.pyplot.subplots()\n", - " _ax.set_title(str(column))\n", - " _ax.set_xscale('symlog')\n", - " _ax.set_yscale('log')\n", - " _ax.grid(True)\n", - " _ = _ax.hist(series, bins=numpy.logspace(\n", - " numpy.log10(min(series)), numpy.log10(max(series)), (iis_project.plotting_utils.suggest_bins_num(len(series)) + 1), endpoint=True, base=10),\n", - " )\n", - " _ = _ax.set_xlim((0, None))" - ] - }, - { - "cell_type": "code", - "execution_count": 32, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "_fig, _ax = matplotlib.pyplot.subplots()\n", - "_ax.set_xscale('symlog')\n", - "_ax.set_yscale('symlog')\n", - "_ax.grid(True)\n", - "_ = _ax.scatter(df['selling_price'], df['present_price'])" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": ".venv", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.12" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/iis_project/numpy_utils.py b/iis_project/numpy_utils.py new file mode 100644 index 0000000..4c90778 --- /dev/null +++ b/iis_project/numpy_utils.py @@ -0,0 +1,8 @@ +from functools import wraps +from math import log + +from numpy import logspace as numpy_logspace + +@wraps(numpy_logspace, assigned=('__annotations__', '__type_params__')) +def logspace(start, stop, *args_rest, **kwargs): + return numpy_logspace(log(start), log(stop), *args_rest, **kwargs) diff --git a/iis_project/pandas_utils.py b/iis_project/pandas_utils.py deleted file mode 100644 index 8cb2197..0000000 --- a/iis_project/pandas_utils.py +++ /dev/null @@ -1,8 +0,0 @@ -import pandas - -from .common import zip_n - -def describe_df(df: pandas.DataFrame) -> pandas.DataFrame: - df_items = df.items() - names, series = zip_n(*df_items, n=2) - return pandas.DataFrame(({'length': len(s), 'dtype': s.dtype} for s in series), index=names) diff --git a/requirements.txt b/requirements.txt index fd19a4d..f861a2e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,8 @@ +bokeh >=3.7.2,<4 ipykernel >=6.30.1,<7 +ipympl ~=0.9.6 matplotlib >=3.10.1,<4 numpy >=2.3.1,<3 pandas >=2.3.1,<3 +scipy >=1.16.1,<2 seaborn ~=0.13.2