{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Лабораторная работа 2.\n", "\n", "### Первый набор данных. Цены на золото (14 вариант).\n", "### Второй набор данных. Продажи домов (6 вариант).\n", "### Третий набор данных. Данные о миллионерах (19 вариант)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Проблемная область 14 варианта.\n", " - Проблемная область описания относится к финансовой аналитике и прогнозированию цен активов, в частности, к регрессионному анализу цен на золото.\n", "# Проблемная область 6 варианта.\n", " - Проблемная область в данном случае связана с регрессией в области анализа цен на недвижимость\n", "# Проблемная область 19 варианта.\n", " - Анализ и прогнозирование богатства, документальное подтверждение и составление рейтингов состоятельных людей." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import pandas as pd\n", "\n", "df_house = pd.read_csv('kc_house_data.csv')\n", "\n", "df_house.head()\n", "df_house.info()\n", "\n", "# Устранение проблемы пропущенных данных\n", "# Преобразование столбца 'your_column' из float в int\n", "df_house[\"floors\"] = df_house[\"floors\"].astype(int)\n", "\n", "# Сохранение измененного DataFrame обратно в CSV\n", "df_house.to_csv(\"houses.csv\", index=False)\n", "# Удаление строк с полностью пустыми значениями\n", "df_cleaned = df_house.dropna(how=\"all\", inplace=True)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from src.utils import split_stratified_into_train_val_test\n", "import pandas as pd\n", "\n", "df_house = pd.read_csv(\"houses.csv\")\n", "display(df_house.floors.value_counts())\n", "display()\n", "\n", "data = df_house[[\"bedrooms\", \"floors\", \"condition\"]].copy()\n", "\n", "df_train, df_val, df_test, y_train, y_val, y_test = (\n", " split_stratified_into_train_val_test(\n", " data,\n", " stratify_colname=\"floors\",\n", " frac_train=0.60,\n", " frac_val=0.20,\n", " frac_test=0.20,\n", " )\n", ")\n", "\n", "display(\"Обучающая выборка: \", df_train.shape)\n", "display(df_train.floors.value_counts())\n", "\n", "display(\"Контрольная выборка: \", df_val.shape)\n", "display(df_val.floors.value_counts())\n", "\n", "display(\"Тестовая выборка: \", df_test.shape)\n", "display(df_test.floors.value_counts())" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from imblearn.over_sampling import ADASYN\n", "\n", "ada = ADASYN()\n", "\n", "display(\"Обучающая выборка: \", df_train.shape)\n", "display(df_train.floors.value_counts())\n", "\n", "X_resampled, y_resampled = ada.fit_resample(df_train, df_train[\"floors\"]) # type: ignore\n", "df_train_adasyn = pd.DataFrame(X_resampled)\n", "\n", "display(\"Обучающая выборка после oversampling: \", df_train_adasyn.shape)\n", "display(df_train_adasyn.floors.value_counts())\n", "\n", "df_train_adasyn" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Пример бизнес целей для 6 варианта.\n", " - Ценообразование и прогнозирование цен на недвижимость. Эффект: Упрощение процесса оценки для риэлторов, улучшение точности ценообразования.\n", "\n", " Техническая цель: Построить модель машинного обучения для прогнозирования стоимости недвижимости.\n", " Вход:\n", "\n", " Количество спален (bedrooms)\n", " Количество ванных комнат (bathrooms)\n", " Площадь жилого пространства (sqft_living)\n", " Площадь участка (sqft_lot)\n", " Год постройки (yr_built)\n", " Рейтинг дома (grade)\n", " Вид, состояние, близость к воде (view, condition, waterfront)\n", " Почтовый индекс и координаты (zipcode, lat, long)\n", " Целевой признак:\n", "\n", " Цена недвижимости (price).\n", "\n", " - Идентификация перспективных районов. Эффект: Помощь инвесторам в выборе объектов для вложений.\n", "\n", " Техническая цель: Анализ динамики цен недвижимости по районам для выявления быстро растущих районов.\n", " Вход:\n", "\n", " Средняя цена домов в почтовом индексе за предыдущие годы.\n", " Координаты домов (lat, long).\n", " Число продаж в каждом районе за период.\n", " Целевой признак:\n", "\n", " Рост средней цены домов в районе.\n", "\n", "\n", "### 6.Определить проблемы выбранных наборов данных: зашумленность, смещение, актуальность, выбросы, просачивание данных.\n", "#### 1.1. Зашумленность данных\n", " Возможные ошибки ввода: некорректные значения площади или количества комнат (например, площадь 0, количество комнат слишком велико).\n", " Сильная корреляция признаков: например, площадь дома и количество комнат могут дублировать информацию.\n", "#### 1.2. Смещение данных\n", " Набор данных может не охватывать все районы и типы недвижимости, например, роскошные или дешевые дома могут быть представлены неравномерно.\n", " Временная зависимость: если данные устарели (например, цены из старого периода), это может привести к смещению в прогнозах.\n", "#### 1.3. Актуальность данных\n", " Если рынок недвижимости изменился (например, после 2020 года из-за пандемии), старые данные могут быть малоактуальны для современных прогнозов.\n", "#### 1.4. Выбросы\n", " Очень высокие или низкие цены (например, элитная недвижимость или заброшенные дома).\n", " Аномальные значения площади (например, слишком большие или маленькие площади).\n", "#### 1.5. Просачивание данных (Data Leakage)\n", " Если в модели используются признаки, которые недоступны на момент прогноза (например, цена или площадь после ремонта), это приведет к завышенной точности модели.\n", "\n", "### 7.Привести примеры решения обнаруженных проблем для каждого набора данных.\n", "\n", "#### 1.1. Зашумленность данных\n", " Решение:\n", "\n", " Проверка данных на наличие некорректных значений:\n", " Исключить записи с площадью 0 или нереалистично большими значениями.\n", " Проверить диапазон значений для числовых признаков (например, количество комнат не превышает разумных пределов).\n", " Удаление или сглаживание дублирующихся признаков:\n", " Если два признака, например, sqft_living и sqft_living15, имеют очень высокую корреляцию, можно исключить один из них.\n", "#### 1.2. Смещение данных\n", " Решение:\n", "\n", " Применение стратифицированного отбора данных, чтобы обеспечить равномерное покрытие различных типов недвижимости (дешевые, средние, элитные дома).\n", " Актуализация данных: объединение с дополнительными источниками, которые отражают текущие цены.\n", "#### 1.3. Актуальность данных\n", " Решение:\n", "\n", " Удаление устаревших записей (например, с датой продажи старше 10 лет).\n", " Добавление новых данных о ценах и характеристиках недвижимости для текущего рынка.\n", "#### 1.4. Выбросы\n", " Решение:\n", "\n", " Использование статистических методов (например, межквартильный размах) для выявления выбросов:\n", " Исключение аномально высоких или низких цен.\n", " Логическая проверка площадей и количества этажей.\n", "#### 1.5. Просачивание данных\n", " Решение:\n", "\n", " Исключение признаков, которые невозможно знать в момент прогноза (например, год реновации, если он произошел после продажи).\n", " Разделение данных на тренировочный и тестовый наборы с учетом временного разрыва.\n", "\n", "\n", "### 8.Оценить качество каждого набора данных: информативность, степень покрытия, соответствие реальным данным, согласованность меток.\n", "\n", "#### 1.1. Информативность\n", " Положительные стороны:\n", " Набор включает множество характеристик недвижимости (размеры, состояние, год постройки, координаты), что позволяет решать широкий спектр задач (прогнозирование цены, классификация).\n", " Ограничения:\n", " Некоторые признаки, такие как yr_renovated, имеют много нулевых значений, что может снижать информативность.\n", " Почтовый индекс (zipcode) предоставляет лишь ограниченную информацию о районе.\n", "#### 1.2. Степень покрытия\n", " Положительные стороны:\n", " Набор охватывает более 21 000 объектов недвижимости, что достаточно для генерализации моделей.\n", " Ограничения:\n", " Данные представлены только для одного региона (вероятно, Сиэтл или его окрестности), что ограничивает применение моделей для других территорий.\n", "#### 1.3. Соответствие реальным данным\n", " Положительные стороны:\n", " Данные хорошо описывают основные характеристики недвижимости, которые действительно влияют на цены.\n", " Ограничения:\n", " Устаревшие записи (например, дома, проданные более 10 лет назад) могут не отражать текущие рыночные тенденции.\n", "#### 1.4. Согласованность меток\n", " Положительные стороны:\n", " Основной целевой признак (price) представлен четко и корректно.\n", " Ограничения:\n", " Возможны редкие выбросы или ошибки в данных о цене (например, нереалистично высокая или низкая стоимость)." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import pandas as pd\n", "\n", "df = pd.read_csv('Forbes Billionaires.csv')\n", "\n", "df.head()\n", "df.info()\n", "\n", "# Устранение проблемы пропущенных данных, а именно - замена на const.\n", "df['AgeFillNA'] = df['Age'].fillna(50)\n", "\n", "# Разделение столбца Networth на 3 группы\n", "df[\"Networth_Group\"] = pd.qcut(df[\"Networth\"], q=3, labels=[1, 2, 3])\n", "df" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from src.utils import split_stratified_into_train_val_test\n", "import pandas as pd\n", "\n", "display(df.Networth_Group.value_counts())\n", "display()\n", "\n", "data = df[[\"Networth_Group\", \"Networth\", \"AgeFillNA\"]].copy()\n", "\n", "df_train, df_val, df_test, y_train, y_val, y_test = (\n", " split_stratified_into_train_val_test(\n", " data,\n", " stratify_colname=\"Networth_Group\",\n", " frac_train=0.60,\n", " frac_val=0.20,\n", " frac_test=0.20,\n", " )\n", ")\n", "\n", "display(\"Обучающая выборка: \", df_train.shape)\n", "display(df_train.Networth_Group.value_counts())\n", "\n", "display(\"Контрольная выборка: \", df_val.shape)\n", "display(df_val.Networth_Group.value_counts())\n", "\n", "display(\"Тестовая выборка: \", df_test.shape)\n", "display(df_test.Networth_Group.value_counts())" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from imblearn.over_sampling import ADASYN\n", "\n", "ada = ADASYN()\n", "\n", "display(\"Обучающая выборка: \", df_train.shape)\n", "display(df_train.Networth_Group.value_counts())\n", "\n", "X_resampled, y_resampled = ada.fit_resample(df_train, df_train[\"Networth_Group\"]) # type: ignore\n", "df_train_adasyn = pd.DataFrame(X_resampled)\n", "\n", "display(\"Обучающая выборка после oversampling: \", df_train_adasyn.shape)\n", "display(df_train_adasyn.Networth_Group.value_counts())\n", "\n", "df_train_adasyn" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "В данном примере мы можем видеть достаточную сбалансированность (или же распределение почти равно, метод ADASYN не смог создать новые примеры, как так это не нужно). Это произошло из за дорабатывания исходного файла, так как на стандартном - выполнить данное задание не представляется возможным." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Пример бизнес цели для 19 варианта\n", " - Анализ целевой аудитории для элитных товаров и услуг. Эффект: Повышение доходов за счёт фокусировки на платежеспособных клиентах.\n", " - Определение перспективных индустрий для инвестиций. Эффект: Увеличение доходности инвестиций за счёт выбора наиболее прибыльных секторов.\n", "\n", "### 6.Определить проблемы выбранных наборов данных: зашумленность, смещение, актуальность, выбросы, просачивание данных.\n", "\n", "Проблемы и их решения:\n", "1. Зашумленность данных\n", " Проблема: Возможны дублирующиеся или некорректные записи (например, одинаковые имена с разными рангами).\n", " Решение: Проверить и удалить дубликаты, если они есть.\n", "2. Смещение данных\n", " Проблема: Набор может быть смещен в сторону представителей более крупных стран или популярных отраслей.\n", " Решение: Провести анализ распределения по странам и индустриям, а также сбалансировать данные для более равномерного анализа.\n", "3. Актуальность данных\n", " Проблема: Устаревшие данные могут не отражать текущее состояние богатства.\n", " Решение: Проверить год публикации данных и, если необходимо, дополнить их более актуальной информацией.\n", "4. Выбросы\n", " Проблема: Возможны выбросы в данных состояния (например, ошибки ввода).\n", " Решение: Проверить распределение состояния (например, с помощью диаграммы размаха) и устранить аномалии.\n", "5. Просачивание данных\n", " Проблема: Если использовать ранги или источники состояния для предсказания состояний, это может привести к неправильной интерпретации.\n", " Решение: Исключить признаки, которые содержат информацию о целевой переменной.\n", "\n", "### 8.Оценить качество каждого набора данных: информативность, степень покрытия, соответствие реальным данным, согласованность меток.\n", "\n", "1. Информативность\n", " Положительные стороны:\n", " Набор данных предоставляет ключевые параметры: состояние, возраст, страна, индустрия и источник дохода.\n", " Полезен для анализа распределения богатства по странам, индустриям и возрастным группам.\n", " Ограничения:\n", " Возможно, не хватает дополнительных параметров (например, гендер или тренды изменения состояния).\n", "2. Степень покрытия\n", " Положительные стороны:\n", " Набор включает информацию о 2600 миллиардерах, что является большим объемом для глобального анализа.\n", " Ограничения:\n", " Отсутствие данных о миллиардерах из менее известных стран или отраслей может снижать репрезентативность.\n", "3. Соответствие реальным данным\n", " Положительные стороны:\n", " Данные соответствуют информации из открытых источников (Forbes).\n", " Ограничения:\n", " Актуальность данных зависит от года публикации (нужно уточнить).\n", "4. Согласованность меток\n", " Положительные стороны:\n", " Столбцы (Rank, Networth, Country, Industry) логически согласованы и не содержат явных ошибок.\n", " Ограничения:\n", " Возможны дублирующиеся записи или опечатки в текстовых данных (например, в именах или странах)." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import pandas as pd\n", "\n", "df = pd.read_csv('FINAL_USO.csv')\n", "df.head()\n", "df.info()\n", "\n", "# Устранение проблемы пропущенных данных - медианное значение.\n", "median_value = df['DJ_high'].median()\n", "df['DJ_high'].fillna(median_value, inplace=True)\n", "\n", "df\n" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "PLT_Trend\n", "0 886\n", "1 832\n", "Name: count, dtype: int64" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "'Обучающая выборка: '" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "(1030, 3)" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "PLT_Trend\n", "0 531\n", "1 499\n", "Name: count, dtype: int64" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "'Контрольная выборка: '" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "(344, 3)" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "PLT_Trend\n", "0 177\n", "1 167\n", "Name: count, dtype: int64" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "'Тестовая выборка: '" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "(344, 3)" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "PLT_Trend\n", "0 178\n", "1 166\n", "Name: count, dtype: int64" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "from src.utils import split_stratified_into_train_val_test\n", "import pandas as pd\n", "\n", "display(df.PLT_Trend.value_counts())\n", "display()\n", "\n", "data = df[[\"PLT_Trend\", \"High\", \"Low\"]].copy()\n", "\n", "df_train, df_val, df_test, y_train, y_val, y_test = (\n", " split_stratified_into_train_val_test(\n", " data,\n", " stratify_colname=\"PLT_Trend\",\n", " frac_train=0.60,\n", " frac_val=0.20,\n", " frac_test=0.20,\n", " )\n", ")\n", "\n", "display(\"Обучающая выборка: \", df_train.shape)\n", "display(df_train.PLT_Trend.value_counts())\n", "\n", "display(\"Контрольная выборка: \", df_val.shape)\n", "display(df_val.PLT_Trend.value_counts())\n", "\n", "display(\"Тестовая выборка: \", df_test.shape)\n", "display(df_test.PLT_Trend.value_counts())" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'Обучающая выборка: '" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "(1030, 3)" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "PLT_Trend\n", "0 531\n", "1 499\n", "Name: count, dtype: int64" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "'Обучающая выборка после oversampling: '" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "(1046, 3)" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "PLT_Trend\n", "0 531\n", "1 515\n", "Name: count, dtype: int64" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", " | PLT_Trend | \n", "High | \n", "Low | \n", "
---|---|---|---|
0 | \n", "0 | \n", "118.459999 | \n", "118.070000 | \n", "
1 | \n", "0 | \n", "114.949997 | \n", "114.410004 | \n", "
2 | \n", "0 | \n", "109.769997 | \n", "108.940002 | \n", "
3 | \n", "0 | \n", "126.120003 | \n", "125.309998 | \n", "
4 | \n", "1 | \n", "122.610001 | \n", "122.220001 | \n", "
... | \n", "... | \n", "... | \n", "... | \n", "
1041 | \n", "1 | \n", "135.325901 | \n", "133.909193 | \n", "
1042 | \n", "1 | \n", "136.613181 | \n", "135.565760 | \n", "
1043 | \n", "1 | \n", "136.154196 | \n", "130.907531 | \n", "
1044 | \n", "1 | \n", "153.542436 | \n", "150.981407 | \n", "
1045 | \n", "1 | \n", "136.182537 | \n", "131.184275 | \n", "
1046 rows × 3 columns
\n", "