421 KiB
Лабораторная работа №2¶
Ход выполнения работы.
- Выбрать три набора данных, которые не соответствуют Вашему варианту задания.
- Провести анализ сведений о каждом наборе данных со страницы загрузки в Kaggle. Какова проблемная область?
- Провести анализ содержимого каждого набора данных. Что является объектом/объектами наблюдения? Каковы атрибуты объектов? Есть ли связи между объектами?
- Привести примеры бизнес-целей, для достижения которых могут подойти выбранные наборы данных. Каков эффект для бизнеса?
- Привести примеры целей технического проекта для каждой выделенной ранее бизнес-цели. Что поступает на вход, что является целевым признаком?
- Определить проблемы выбранных наборов данных: зашумленность, смещение, актуальность, выбросы, просачивание данных.
- Привести примеры решения обнаруженных проблем для каждого набора данных.
- Оценить качество каждого набора данных: информативность, степень покрытия, соответствие реальным данным, согласованность меток.
- Устранить проблему пропущенных данных. Для каждого набора данных использовать разные методы: удаление, подстановка константного значения (0 или подобное), подстановка среднего значения.
- Выполнить разбиение каждого набора данных на обучающую, контрольную и тестовую выборки.
- Оценить сбалансированность выборок для каждого набора данных. Оценить необходимость использования методов приращения (аугментации) данных.
- Выполнить приращение данных методами выборки с избытком (oversampling) и выборки с недостатком (undersampling). Должны быть представлены примеры реализации обоих методов для выборок каждого набора данных.
- Все выводы и программный код должны быть оформлены в виде ноутбука. Для выполнения данной лабораторной работы следует создать новый файл-ноутбук.
Пункты 1-5.
Были выбраны датасеты:
- Объекты вокруг Земли (https://www.kaggle.com/datasets/sameepvani/nasa-nearest-earth-objects)
- Экономика стран (https://www.kaggle.com/datasets/pratik453609/economic-data-9-countries-19802020)
- Цены на мобильное устройство (https://www.kaggle.com/datasets/dewangmoghe/mobile-phone-price-prediction)
Объекты вокруг Земли
Проблемная область: космические объекты и их угроза для Земли
Объект наблюдения: астероиды и другие малые тела Солнечной системы
Атрибуты: имя объекта, минимальный и максимальный оценочные диаметры, относительная скорость, расстояние промаха, орбитальное тело, объекты программы "Сентри", абсолютная звездная величина, опасность
Пример бизнес-цели:
Разработка и продажа страховых продуктов для космических рисков. Цель технического проекта: разработка системы оценки рисков и ценообразования для страховых продуктов, защищающих от космических угроз.
Разработка и продажа технологий для мониторинга и предотвращения космических угроз. Цель технического проекта: создание системы мониторинга и прогнозирования траекторий небесных тел для предотвращения космических угроз.
Образовательные программы и сервисы. Цель технического проекта: разработка интерактивных образовательных материалов и сервисов, основанных на данных о небесных телах. Актуальность: Исследования астероидов и разработка технологий для их отклонения не только помогают защитить Землю от потенциальных угроз, но и стимулируют научные открытия в различных областях, включая астрономию, физику, инженерию и образование. Эта тема имеет важное значение для будущего нашей планеты и человечества в целом.
Экономика стран
Проблемная область: экономические данные по странам
Объект наблюдения: каждая страна (например, США, Франция) выступает отдельным объектом наблюдения.
Атрибуты: фондовый индекс: среднегодовая цена индекса, инфляция (inflationrate): годовой уровень инфляции, цена на нефть (oil prices): среднегодовая стоимость нефти, обменный курс (exchange_rate): курс национальной валюты к доллару США, ВВП в процентах (gdppercent): прирост ВВП, доход на душу населения (percapitaincome): средний доход на человека в стране.
Пример бизнес-цели:
- Определение факторов, влияющих на рост фондового рынка в различных странах (эффект для бизнеса: позволяет финансовым компаниям и инвесторам создавать более эффективные стратегии вложений)
- Прогнозирование инфляции и курсов валют (эффект для бизнеса: помогает компаниям адаптироваться к колебаниям на валютных рынках и снижать риски при операциях с иностранной валютой)
Цены на мобильные устройства
Проблемная область: цены, характеристики мобильных устройств разных компаний.
Объект наблюдения: каждый мобильный телефон представляет собой отдельный объект.
Атрибуты: фондовый индекс: рейтинг, спецификации, количество SIM-карт, поддержка сетей (3G, 4G, 5G), оперативная память (RAM), батарея: емкость батареи, экран (размер и разрешение), камера: характеристика камеры (основной и фронтальной), встроенная и внешняя память, версия Android, процессор, поддержка быстрой зарядки.
Пример бизнес-цели:
- Анализ характеристик, влияющих на рейтинг и популярность модели. Эффект для бизнеса: помогает производителям оптимизировать параметры устройства для увеличения спроса.
- Оптимизация ценовой стратегии в зависимости от характеристик. Эффект для бизнеса: позволяет разработать ценовые сегменты, соответствующие характеристикам, и повысить конкурентоспособность.
№6. Сперва напишем функции для определения проблем выбранных наборов данных: зашумленности, смещения, актуальности, выбросов, просачивания данных.
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
#Проверка на зашумленность
def check_noise(dataframe):
total_values = dataframe.size
missing_values = dataframe.isnull().sum().sum()
noise_percentage = (missing_values / total_values) * 100
return f"Зашумленность: {noise_percentage:.2f}%"
#Проверка на смещение
def check_bias(dataframe, target_column):
if target_column in dataframe.columns:
unique_values = dataframe[target_column].nunique()
total_values = len(dataframe)
bias_percentage = (unique_values / total_values) * 100
return (
f"Смещение по {target_column}: {bias_percentage:.2f}% уникальных значений"
)
return "Целевой признак не найден."
#Проверка на дубликаты
def check_duplicates(dataframe):
duplicate_percentage = dataframe.duplicated().mean() * 100
return f"Количество дубликатов: {duplicate_percentage:.2f}%"
#Проверка на выбросы
def check_outliers(dataframe, column):
if column in dataframe.columns:
Q1 = dataframe[column].quantile(0.25)
Q3 = dataframe[column].quantile(0.75)
IQR = Q3 - Q1
lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR
outlier_count = dataframe[
(dataframe[column] < lower_bound) | (dataframe[column] > upper_bound)
].shape[0]
total_count = dataframe.shape[0]
outlier_percentage = (outlier_count / total_count) * 100
return f"Выбросы по {column}: {outlier_percentage:.2f}%"
return f"Признак {column} не найден."
#Проверка на просачивание данных
def check_data_leakage(dataframe, target_column):
if target_column in dataframe.columns:
correlation_matrix = dataframe.select_dtypes(include=[np.number]).corr()
leakage_info = correlation_matrix[target_column].abs().nlargest(10)
leakage_report = ", ".join(
[
f"{feature}: {value:.2f}"
for feature, value in leakage_info.items()
if feature != target_column
]
)
return f"Признаки просачивания данных: {leakage_report}"
return "Целевой признак не найден."
Датасет 1. Объекты вокруг земли
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# Вывод всех столбцов
df_neo = pd.read_csv("neo.csv")
print(df_neo.columns)
noise_columns = check_noise(df_neo)
bias_info = check_bias(df_neo, "miss_distance")
duplicate_count = check_duplicates(df_neo)
outliers_data = check_outliers(df_neo, "relative_velocity")
leakage_info = check_data_leakage(df_neo, "absolute_magnitude")
print(noise_columns)
print(bias_info)
print(duplicate_count)
print(outliers_data)
print(leakage_info)
Датасет 7. Экономика стран
df_ed = pd.read_csv("economic_data.csv")
print(df_ed.columns)
noise_columns = check_noise(df_ed)
bias_info = check_bias(df_ed, "index price")
duplicate_count = check_duplicates(df_ed)
outliers_data = check_outliers(df_ed, "unemploymentrate")
leakage_info = check_data_leakage(df_ed, "inflationrate")
print(noise_columns)
print(bias_info)
print(duplicate_count)
print(outliers_data)
print(leakage_info)
Датасет 18. Цена на мобильные устройства
df_mp = pd.read_csv("mobile_phone_price_prediction.csv")
print(df_mp.columns)
noise_columns = check_noise(df_mp)
bias_info = check_bias(df_mp, "Name")
duplicate_count = check_duplicates(df_mp)
outliers_data = check_outliers(df_mp, "Spec_score")
leakage_info = check_data_leakage(df_mp, "Rating")
print(noise_columns)
print(bias_info)
print(duplicate_count)
print(outliers_data)
print(leakage_info)
Датасет 1. Объекты вокруг Земли
df_neo.isnull().sum()
Пропущенных значений нет, поэтому пропускаем.
Датасет 7. Экономика стран
df_ed.isnull().sum()
Имеются пустые значения. На их место поставим "No value"
df_ed["index price"] = df_ed["index price"].fillna("No value")
df_ed["inflationrate"] = df_ed["inflationrate"].fillna("No value")
df_ed["exchange_rate"] = df_ed["exchange_rate"].fillna("No value")
df_ed["gdppercent"] = df_ed["gdppercent"].fillna("No value")
df_ed["percapitaincome"] = df_ed["percapitaincome"].fillna("No value")
df_ed["unemploymentrate"] = df_ed["unemploymentrate"].fillna("No value")
df_ed["manufacturingoutput"] = df_ed["manufacturingoutput"].fillna("No value")
df_ed["tradebalance"] = df_ed["tradebalance"].fillna("No value")
df_ed["index price"] = df_ed["index price"].replace("No value", 0)
df_ed["inflationrate"] = df_ed["inflationrate"].replace("No value", 0)
df_ed["exchange_rate"] = df_ed["exchange_rate"].replace("No value", 0)
df_ed["gdppercent"] = df_ed["gdppercent"].replace("No value", 0)
df_ed["percapitaincome"] = df_ed["percapitaincome"].replace("No value", 0)
df_ed["unemploymentrate"] = df_ed["unemploymentrate"].replace("No value", 0)
df_ed["manufacturingoutput"] = df_ed["manufacturingoutput"].replace("No value", 0)
df_ed["tradebalance"] = df_ed["tradebalance"].replace("No value", 0)
Снова проверим датафрейм на наличие пустых значений:
df_ed.isnull().sum()
Датасет 18. Цены на мобильные устройства
df_mp.isnull().sum()
df_mp["Android_version"] = df_mp["Android_version"].fillna("No value")
df_mp["Inbuilt_memory"] = df_mp["Inbuilt_memory"].fillna("No value")
df_mp["fast_charging"] = df_mp["fast_charging"].fillna("No value")
df_mp["Screen_resolution"] = df_mp["Screen_resolution"].fillna("No value")
df_mp["Processor"] = df_mp["Processor"].fillna("No value")
df_mp["Android_version"] = df_mp["Android_version"].replace("No value", 0)
df_mp["Inbuilt_memory"] = df_mp["Inbuilt_memory"].replace("No value", 0)
df_mp["fast_charging"] = df_mp["fast_charging"].replace("No value", 0)
df_mp["Screen_resolution"] = df_mp["Screen_resolution"].replace("No value", 0)
df_mp["Processor"] = df_mp["Processor"].replace("No value", 0)
df_mp.isnull().sum()
- Выполнить разбиение каждого набора данных на обучающую, контрольную и тестовую выборки.
from sklearn.model_selection import train_test_split
# Разбиение df_neo
original_df_neo_size = len(df_neo)
train_df_neo, temp_df_neo = train_test_split(df_neo, test_size=0.2, random_state=42)
val_df_neo, test_df_neo = train_test_split(temp_df_neo, test_size=0.5, random_state=42)
print("df_neo Dataset:")
print(f"Train: {len(train_df_neo)/original_df_neo_size*100:.2f}%")
print(f"Validation: {len(val_df_neo)/original_df_neo_size*100:.2f}%")
print(f"Test: {len(test_df_neo)/original_df_neo_size*100:.2f}%\n")
# Разбиение df_ed
original_df_ed_size = len(df_ed)
train_df_ed, temp_df_ed = train_test_split(df_ed, test_size=0.2, random_state=42)
val_df_ed, test_df_ed = train_test_split(temp_df_ed, test_size=0.5, random_state=42)
print("df_ed Dataset:")
print(f"Train: {len(train_df_ed)/original_df_ed_size*100:.2f}%")
print(f"Validation: {len(val_df_ed)/original_df_ed_size*100:.2f}%")
print(f"Test: {len(test_df_ed)/original_df_ed_size*100:.2f}%\n")
# Разбиение df_mp
original_df_mp_size = len(df_mp)
train_df_mp, temp_df_mp = train_test_split(df_mp, test_size=0.2, random_state=42)
val_df_mp, test_df_mp = train_test_split(temp_df_mp, test_size=0.5, random_state=42)
print("df_mp Dataset:")
print(f"Train: {len(train_df_mp)/original_df_mp_size*100:.2f}%")
print(f"Validation: {len(val_df_mp)/original_df_mp_size*100:.2f}%")
print(f"Test: {len(test_df_mp)/original_df_mp_size*100:.2f}%\n")
- Оценить сбалансированность выборок для каждого набора данных. Оценить необходимость использования методов приращения (аугментации) данных.
def plot_sample_balance(y, sample_name):
plt.figure(figsize=(8, 5))
sns.histplot(y, bins=30, kde=True)
plt.title(f"Распределение целевой переменной для {sample_name}")
plt.xlabel(sample_name)
plt.ylabel("Частота")
plt.show()
# Оценка сбалансированности выборок
plot_sample_balance(train_df_neo["relative_velocity"], "Train df_neo")
plot_sample_balance(val_df_neo["relative_velocity"], "Validation df_neo")
plot_sample_balance(test_df_neo["relative_velocity"], "Test df_neo")
Кажется, выборки сбалансированы.
# Оценка сбалансированности выборок
plot_sample_balance(train_df_ed["inflationrate"], "Train df_ed")
plot_sample_balance(val_df_ed["inflationrate"], "Validation df_ed")
plot_sample_balance(test_df_ed["inflationrate"], "Test df_ed")
Выборки выглядят схоже, но у всех трех разное количество значений. В дальнейшем мы не сможем обучить какую-либо модель. Если модель обучается на несбалансированных данных, она будет предсказывать какой-то гораздо чаще, даже если в тестовой выборке классы распределены более равномерно.
# Оценка сбалансированности выборок
plot_sample_balance(train_df_mp["Ram"], "Train df_mp")
plot_sample_balance(val_df_mp["Ram"], "Validation df_mp")
plot_sample_balance(test_df_mp["Ram"], "Test df_mp")
Выборки явно не сбалансированы, пока что не можем обучить модель.
- Выполнить приращение данных методами выборки с избытком (oversampling) и выборки с недостатком (undersampling). Должны быть представлены примеры реализации обоих методов для выборок каждого набора данных.
from imblearn.over_sampling import SMOTE
Датасет 1.
X_df_neo = df_neo.drop("hazardous", axis=1)
y_df_neo = df_neo["hazardous"]
# Кодирование категориальных признаков
for column in X_df_neo.select_dtypes(include=["object"]).columns:
X_df_neo[column] = X_df_neo[column].astype("category").cat.codes
# Теперь применяем SMOTE
smote = SMOTE(random_state=42)
X_resampled_df_neo, y_resampled_df_neo = smote.fit_resample(X_df_neo, y_df_neo)
# Получаем результаты
print(f"После oversampling (df_neo): {pd.Series(y_resampled_df_neo).value_counts()}")
from imblearn.under_sampling import RandomUnderSampler
# Undersampling df_neo
undersample = RandomUnderSampler(random_state=42)
X_under_df_neo, y_under_df_neo = undersample.fit_resample(X_df_neo, y_df_neo)
print(f"После undersampling (df_neo): {pd.Series(y_under_df_neo).value_counts()}")
Датасет 7.
X_df_ed = df_ed.drop("country", axis=1)
y_df_ed = df_ed["country"]
# Кодирование категориальных признаков
for column in X_df_ed.select_dtypes(include=["object"]).columns:
X_df_ed[column] = X_df_ed[column].astype("category").cat.codes
# Теперь применяем SMOTE
smote = SMOTE(random_state=42)
X_resampled_df_ed, y_resampled_df_ed = smote.fit_resample(X_df_ed, y_df_ed)
# Получаем результаты
print(f"После oversampling (df_ed): {pd.Series(y_resampled_df_ed).value_counts()}")
from imblearn.under_sampling import RandomUnderSampler
# Undersampling df_ed
undersample = RandomUnderSampler(random_state=42)
X_under_df_ed, y_under_df_ed = undersample.fit_resample(X_df_ed, y_df_ed)
print(f"После undersampling (df_ed): {pd.Series(y_under_df_ed).value_counts()}")
Датасет 18.
X_df_mp = df_mp.drop("Battery", axis=1)
y_df_mp = df_mp["Battery"]
# Кодирование категориальных признаков
for column in X_df_mp.select_dtypes(include=["object"]).columns:
X_df_mp[column] = X_df_mp[column].astype("category").cat.codes
# Теперь применяем SMOTE
smote = SMOTE(random_state=42)
X_resampled_df_mp, y_resampled_df_mp = smote.fit_resample(X_df_mp, y_df_mp)
# Получаем результаты
print(f"После oversampling (df_mp): {pd.Series(y_resampled_df_mp).value_counts()}")
В данном случае у нас есть два датасета, предназначенных для решения задачи классификации (df_neo, df_ed). Проблему дисбаланса в них мы решили применив undersampling и oversampling.
Последний датасет не подходит для обучения, т.к предназначен для решения задачи регрессии (цены мобильного устройства), поэтому выполнять приращение данных не требуется.