420 KiB
Датасет №1 (Использование мобильных устройств и поведение пользователей)¶
Ссылка: https://www.kaggle.com/datasets/valakhorasani/mobile-device-usage-and-user-behavior-dataset
Проблемная область: прогнозирование пользовательского поведения и сегментация пользователей для улучшения работы приложений, оптимизации потребления энергии, анализа пользовательского опыта или рекламы.
Объекты наблюдения: пользователи мобильных устройств, чьи данные об использовании собираются и анализируются.
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.model_selection import train_test_split
from imblearn.over_sampling import SMOTE
df_mobiles = pd.read_csv("..//..//static//csv//user_behavior_data.csv")
print(df_mobiles.columns)
Атрибуты объектов:
- User ID — уникальный идентификатор пользователя.
- Device Model — модель устройства.
- Operating System — операционная система устройства.
- App Usage Time (min/day) — время использования приложений в минутах в день.
- Screen On Time (hours/day) — время включенного экрана в часах в день.
- Battery Drain (mAh/day) — потребление батареи в мАч в день.
- Number of Apps Installed — количество установленных приложений.
- Data Usage (MB/day) — объем данных в мегабайтах в день.
- Age — возраст пользователя.
- Gender — пол пользователя.
- User Behavior Class — класс поведения пользователя (категория для классификации).
Связи между объектами: Атрибуты, такие как модель устройства, ОС и время использования приложений, могут быть связаны с классом поведения, представляя зависимости между действиями пользователя и его характеристиками.
Примеры бизнес-целей и целей технического проекта:
Оптимизация энергопотребления устройств:
- Бизнес-цель: Оптимизировать работу приложений для снижения расхода батареи, что увеличит время работы устройства и улучшит пользовательский опыт.
- Эффект: Повышение удовлетворенности клиентов и снижение вероятности перехода на конкурентные приложения.
Сегментация пользователей для рекламы:
- Бизнес-цель: Создание таргетированной рекламы на основе поведения пользователей (классы поведения).
- Эффект: Увеличение конверсий и доходов от рекламных кампаний за счет более точной сегментации.
Цель: Построение модели для прогнозирования расхода батареи.
- Вход: Модель устройства, ОС, время использования приложений, количество приложений, возраст.
- Целевой признак: Battery Drain (mAh/day).
Проверка на пустые значения и дубликаты
null_values = df_mobiles.isnull().sum()
print("Пустые значения по столбцам:")
print(null_values)
duplicates = df_mobiles.duplicated().sum()
print(f"\nКоличество дубликатов: {duplicates}")
Пустых значений и дубликатов нет, проверим на выбросы:
columns_to_check = ['App Usage Time (min/day)', 'Screen On Time (hours/day)', 'Battery Drain (mAh/day)', 'Number of Apps Installed', 'Data Usage (MB/day)', 'User Behavior Class']
def count_outliers(data, columns):
outliers_count = {}
for col in columns:
Q1 = data[col].quantile(0.25)
Q3 = data[col].quantile(0.75)
IQR = Q3 - Q1
lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR
outliers = data[(data[col] < lower_bound) | (data[col] > upper_bound)]
outliers_count[col] = len(outliers)
return outliers_count
outliers_count = count_outliers(df_mobiles, columns_to_check)
for col, count in outliers_count.items():
print(f"Количество выбросов в столбце '{col}': {count}")
plt.figure(figsize=(15, 10))
for i, col in enumerate(columns_to_check, 1):
plt.subplot(2, 3, i)
sns.boxplot(x=df_mobiles[col])
plt.title(f'Box Plot of {col}')
plt.tight_layout()
plt.show()
Выбросов нет
Разбиение набора данных на обучающую, контрольную и тестовую выборки
train_df, test_df = train_test_split(df_mobiles, test_size=0.2, random_state=42)
train_df, val_df = train_test_split(train_df, test_size=0.25, random_state=42)
print("Размер обучающей выборки:", len(train_df))
print("Размер контрольной выборки:", len(val_df))
print("Размер тестовой выборки:", len(test_df))
def check_balance(df, name):
counts = df['User Behavior Class'].value_counts()
print(f"Распределение \"Класс поведения пользователя\" в {name}:")
print(counts)
print()
check_balance(train_df, "обучающей выборке")
check_balance(val_df, "контрольной выборке")
check_balance(test_df, "тестовой выборке")
Оверсемплинг и андерсемплинг
from imblearn.over_sampling import RandomOverSampler
from imblearn.under_sampling import RandomUnderSampler
def oversample(df, target_column):
X = df.drop(target_column, axis=1)
y = df[target_column]
oversampler = RandomOverSampler(random_state=42)
x_resampled, y_resampled = oversampler.fit_resample(X, y) # type: ignore
resampled_df = pd.concat([x_resampled, y_resampled], axis=1)
return resampled_df
def undersample(df, target_column):
X = df.drop(target_column, axis=1)
y = df[target_column]
undersampler = RandomUnderSampler(random_state=42)
x_resampled, y_resampled = undersampler.fit_resample(X, y) # type: ignore
resampled_df = pd.concat([x_resampled, y_resampled], axis=1)
return resampled_df
train_df_oversampled = oversample(train_df, 'User Behavior Class')
val_df_oversampled = oversample(val_df, 'User Behavior Class')
test_df_oversampled = oversample(test_df, 'User Behavior Class')
train_df_undersampled = undersample(train_df, 'User Behavior Class')
val_df_undersampled = undersample(val_df, 'User Behavior Class')
test_df_undersampled = undersample(test_df, 'User Behavior Class')
print("Оверсэмплинг:")
check_balance(train_df_oversampled, "обучающей выборке")
check_balance(val_df_oversampled, "контрольной выборке")
check_balance(test_df_oversampled, "тестовой выборке")
print("Андерсэмплинг:")
check_balance(train_df_undersampled, "обучающей выборке")
check_balance(val_df_undersampled, "контрольной выборке")
check_balance(test_df_undersampled, "тестовой выборке")
Датасет №2 (качество воды)¶
Ссылка: https://www.kaggle.com/datasets/adityakadiwal/water-potability
Проблемная область: качество питьевой воды и факторы, влияющие на ее безопасность для здоровья.
Объекты наблюдения: водоемы, содержащие воду разного качества.
# вывод всех столбцов
df = pd.read_csv("..//..//static//csv//water_potability.csv")
print(df.columns)
Атрибуты:
- ph – параметр для оценки кислотно-щелочного баланса воды;
- Hardness – жесткость воды, определяемая содержанием кальция и магния;
- Solids – общее количество растворенных веществ, указывающее на минерализацию воды;
- Chloramines – концентрация хлора и хлораминов, использующихся для дезинфекции воды;
- Sulfate – содержание сульфатов, присутствующих в воде;
- Conductivity – электропроводность воды, измеряющая уровень ионов в растворе;
- Organic_carbon – уровень органического углерода, происходящего из разлагающихся органических веществ;
- Trihalomethanes – концентрация трихалометанов, образующихся при обработке хлором;
- Turbidity – мутность воды, указывающая на количество взвешенных твердых частиц;
- Potability – показатель пригодности воды для питья (1 – пригодна, 0 – непригодна).
Примеры бизнес целей и целей технического проекта:
- Совершенствование систем очистки воды.
- Бизнес-цель: разработка и внедрение инновационных технологий очистки воды, чтобы уменьшить расходы на водоочистные сооружения и повысить их эффективность.
- Цель технического проекта: проектирование и тестирование новых фильтров и процессов очистки на основе данных о загрязнении воды.
- Интеграция данных для управления водными ресурсами.
- Бизнес-цель: объединение данных о водных ресурсах для комплексного анализа и управления, что позволит более эффективно распределять ресурсы.
- Цель технического проекта: разработка платформы для интеграции данных с различных датчиков и источников информации, использующей машинное обучение для прогнозирования изменений качества воды.
- Повышение осведомленности о качестве воды.
- Бизнес-цель: информирование населения о состоянии водоемов и возможных рисках для здоровья.
- Цель технического проекта: разработка платформы для публичного доступа к данным о качестве воды.
Входные данные и целевой признак могут быть следующими:
- Входные данные:
- pH значение;
- Жесткость воды;
- Общее количество растворенных веществ;
- Концентрация хлора и хлораминов;
- Содержание сульфатов;
- Электропроводность;
- Уровень органического углерода;
- Концентрация трихалометанов;
- Мутность воды.
- Целевой признак:
- Пригодность воды для питья.
Актуальность: анализ качества питьевой воды и факторов, влияющих на ее безопасность, играет очень важную роль в охране здоровья населения. Так мониторинг факторов, влияющих на качество воды, позволит предотвращать вспышки заболеваний и способствовать повышению уровня жизни.
Проверяем на выбросы¶
columns_to_check = ['Hardness', 'Solids', 'Organic_carbon']
def count_outliers(df, columns):
outliers_count = {}
for col in columns:
Q1 = df[col].quantile(0.25)
Q3 = df[col].quantile(0.75)
IQR = Q3 - Q1
lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR
outliers = df[(df[col] < lower_bound) | (df[col] > upper_bound)]
outliers_count[col] = len(outliers)
return outliers_count
outliers_count = count_outliers(df, columns_to_check)
for col, count in outliers_count.items():
print(f"Количество выбросов в столбце '{col}': {count}")
plt.figure(figsize=(15, 10))
for i, col in enumerate(columns_to_check, 1):
plt.subplot(2, 2, i)
sns.boxplot(x=df[col])
plt.title(f'Box Plot of {col}')
plt.tight_layout()
plt.show()
В каждом из выбранных столбцов присутствуют выбросы. Очистим их.
# Выбираем столбцы для очистки
columns_to_clean = ['Hardness', 'Solids', 'Organic_carbon']
# Функция для удаления выбросов
def remove_outliers(df, columns):
for col in columns:
Q1 = df[col].quantile(0.25)
Q3 = df[col].quantile(0.75)
IQR = Q3 - Q1
lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR
# Удаляем строки, содержащие выбросы
df = df[(df[col] >= lower_bound) & (df[col] <= upper_bound)]
return df
# Удаляем выбросы
df_cleaned = remove_outliers(df, columns_to_clean)
# Выводим количество удаленных строк
print(f"Количество удаленных строк: {len(df) - len(df_cleaned)}")
# Создаем диаграммы размаха для очищенных данных
plt.figure(figsize=(15, 6))
# Диаграмма размаха для Hardness
plt.subplot(1, 3, 1)
sns.boxplot(x=df_cleaned['Hardness'])
plt.title('Box Plot of Hardness (Cleaned)')
plt.xlabel('Hardness')
# Диаграмма размаха для Solids
plt.subplot(1, 3, 2)
sns.boxplot(x=df_cleaned['Solids'])
plt.title('Box Plot of Solids (Cleaned)')
plt.xlabel('Solids')
# Диаграмма размаха для Organic_carbon
plt.subplot(1, 3, 3)
sns.boxplot(x=df_cleaned['Organic_carbon'])
plt.title('Box Plot of Organic_carbon (Cleaned)')
plt.xlabel('Organic_carbon')
plt.tight_layout()
plt.show()
# Сохраняем очищенный датасет
df_cleaned.to_csv("..//..//static//csv//water_potability_cleaned.csv", index=False)
df = df_cleaned
Теперь проверим на пустые значения¶
# Количество пустых значений признаков
print(df.isnull().sum())
print()
# Есть ли пустые значения признаков
print(df.isnull().any())
print()
# Процент пустых значений признаков
for i in df.columns:
null_rate = df[i].isnull().sum() / len(df) * 100
if null_rate > 0:
print(f"{i} процент пустых значений: %{null_rate:.2f}")
В трех столбцах встречается большое число пустых значений. Поэтому вместо удаления заменим их значения на медиану.
# Замена значений
df["ph"] = df["ph"].fillna(df["ph"].median())
df["Sulfate"] = df["Sulfate"].fillna(df["Sulfate"].median())
df["Trihalomethanes"] = df["Trihalomethanes"].fillna(df["Trihalomethanes"].median())
# Проверка на пропущенные значения после замены
missing_values_after_drop = df.isnull().sum()
# Вывод результатов после замены
print("\nКоличество пустых значений в каждом столбце после замены:")
print(missing_values_after_drop)
Выборки¶
X = df.drop('Potability', axis=1)
y = df['Potability']
X_train, X_rem, y_train, y_rem = train_test_split(X, y, train_size=0.6, random_state=42)
X_val, X_test, y_val, y_test = train_test_split(X_rem, y_rem, test_size=0.5, random_state=42)
print("Размер обучающей выборки:", X_train.shape)
print("Размер контрольной выборки:", X_val.shape)
print("Размер тестовой выборки:", X_test.shape)
def analyze_balance(y_train, y_val, y_test):
print("Распределение классов в обучающей выборке:")
print(y_train.value_counts(normalize=True))
print("\nРаспределение классов в контрольной выборке:")
print(y_val.value_counts(normalize=True))
print("\nРаспределение классов в тестовой выборке:")
print(y_test.value_counts(normalize=True))
analyze_balance(y_train, y_val, y_test)
Используем метод оверсемплинг
smote = SMOTE(random_state=42)
# Применение SMOTE для балансировки обучающей выборки
X_train_resampled, y_train_resampled = smote.fit_resample(X_train, y_train)
# Проверка сбалансированности после SMOTE
print("Сбалансированность обучающей выборки после SMOTE:")
print(y_train_resampled.value_counts(normalize=True))
Датасет №3 (Экономика стран)¶
Ссылка: https://www.kaggle.com/datasets/pratik453609/economic-data-9-countries-19802020
Проблемная область: экономический анализ и прогнозирование макроэкономических показателей.
Объекты наблюдения: экономические индексы по странам за определённые годы.
df_countries = pd.read_csv("..//..//static//csv//economic_data.csv")
print(df_countries.columns)
Атрибуты объектов:
- stock index — индекс акций.
- country — страна.
- year — год.
- index price — цена индекса.
- log_indexprice — логарифм цены индекса.
- inflationrate — уровень инфляции.
- oil prices — цены на нефть.
- exchange_rate — валютный курс.
- gdppercent — процент роста ВВП.
- percapitaincome — доход на душу населения.
- unemploymentrate — уровень безработицы.
- manufacturingoutput — объём производства.
- tradebalance — торговый баланс.
- USTreasury — доходность казначейских облигаций США.
Связи между объектами: Некоторые атрибуты могут быть связаны друг с другом, например, уровень инфляции и процент роста ВВП могут коррелировать с ценами на нефть, уровнем безработицы и торговым балансом.
Примеры бизнес-целей и эффект:
Прогнозирование экономического роста и планирование инвестиций:
- Бизнес-цель: Создать модель прогнозирования роста экономики для стран, чтобы принять стратегические инвестиционные решения.
- Эффект: Повышение точности экономических прогнозов и улучшение прибыльности инвестиционных стратегий.
Анализ и оптимизация торговой политики:
- Бизнес-цель: Изучение влияния изменений торгового баланса и валютных курсов на экономику стран.
- Эффект: Улучшение торговых соглашений и политики, что приведёт к более устойчивому экономическому росту.
Примеры целей технического проекта:
Цель: Построение модели для прогнозирования уровня инфляции.
- Вход: Уровень безработицы, ВВП, доход на душу населения, валютный курс, цены на нефть.
- Целевой признак: inflationrate.
Цель: Построение модели для оценки экономического роста.
- Вход: Торговый баланс, доход на душу населения, валютный курс, инфляция.
- Целевой признак: gdppercent.
Проверка на пустые значения и дубликаты
null_values = df_countries.isnull().sum()
print("Пустые значения по столбцам:")
print(null_values)
duplicates = df_countries.duplicated().sum()
print(f"\nКоличество дубликатов: {duplicates}")
Видим, что есть пустые данные, но нет дубликатов. Удаляем их
def drop_missing_values(dataframe, name):
before_shape = dataframe.shape
cleaned_dataframe = dataframe.dropna()
after_shape = cleaned_dataframe.shape
print(f"В наборе данных '{name}' было удалено {before_shape[0] - after_shape[0]} строк с пустыми значениями.")
return cleaned_dataframe
df_countries = drop_missing_values(df_countries, "Countries")
Проверка на выбросы:
columns_to_check = ['year', 'index price', 'log_indexprice',
'inflationrate', 'oil prices', 'exchange_rate', 'gdppercent',
'percapitaincome', 'unemploymentrate', 'manufacturingoutput',
'tradebalance', 'USTreasury']
outliers_count = count_outliers(df_countries, columns_to_check)
for col, count in outliers_count.items():
print(f"Количество выбросов в столбце '{col}': {count}")
plt.figure(figsize=(15, 10))
for i, col in enumerate(columns_to_check, 1):
plt.subplot(3, 4, i)
sns.boxplot(x=df_countries[col])
plt.title(f'Box Plot of {col}')
plt.tight_layout()
plt.show()
В большинстве из выбранных столбцов присутствуют выбросы. Очистим их.
columns_to_clean = ['index price', 'log_indexprice',
'inflationrate', 'exchange_rate', 'gdppercent', 'unemploymentrate', 'manufacturingoutput',
'tradebalance', 'USTreasury']
df_countries_clean = remove_outliers(df_countries, columns_to_clean)
print(f"Количество удаленных строк: {len(df_countries) - len(df_countries_clean)}")
plt.figure(figsize=(15, 6))
plt.figure(figsize=(15, 10))
for i, col in enumerate(columns_to_clean, 1):
plt.subplot(3, 3, i)
sns.boxplot(x=df_countries_clean[col])
plt.title(f'Box Plot of {col}')
plt.tight_layout()
plt.show()
plt.tight_layout()
plt.show()
df_countries = df_countries_clean
Разбиение набора данных на обучающую, контрольную и тестовую выборки
train_df, test_df = train_test_split(df_countries, test_size=0.2, random_state=42)
train_df, val_df = train_test_split(train_df, test_size=0.25, random_state=42)
print("Размер обучающей выборки:", len(train_df))
print("Размер контрольной выборки:", len(val_df))
print("Размер тестовой выборки:", len(test_df))
def check_balance(df, name):
counts = df['inflationrate'].value_counts()
print(f"Распределение \"Уровень инфляции\" в {name}:")
print(counts)
print()
check_balance(train_df, "обучающей выборке")
check_balance(val_df, "контрольной выборке")
check_balance(test_df, "тестовой выборке")
Оверсемплинг и андерсемплинг
def binning(target, bins):
return pd.qcut(target, q=bins, labels=False)
train_df['inflationrate_binned'] = binning(train_df['inflationrate'], bins=2)
val_df['inflationrate_binned'] = binning(val_df['inflationrate'], bins=2)
test_df['inflationrate_binned'] = binning(test_df['inflationrate'], bins=2)
train_df_oversampled = oversample(train_df, 'inflationrate_binned')
val_df_oversampled = oversample(val_df, 'inflationrate_binned')
test_df_oversampled = oversample(test_df, 'inflationrate_binned')
train_df_undersampled = undersample(train_df, 'inflationrate_binned')
val_df_undersampled = undersample(val_df, 'inflationrate_binned')
test_df_undersampled = undersample(test_df, 'inflationrate_binned')
print("Оверсэмплинг:")
check_balance(train_df_oversampled, "обучающей выборке")
check_balance(val_df_oversampled, "контрольной выборке")
check_balance(test_df_oversampled, "тестовой выборке")
print("Андерсэмплинг:")
check_balance(train_df_undersampled, "обучающей выборке")
check_balance(val_df_undersampled, "контрольной выборке")
check_balance(test_df_undersampled, "тестовой выборке")