608 KiB
Начало лабораторной¶
https://www.kaggle.com/datasets/nikhil1e9/goodreads-books?resource=download Данный набор данных представляет книги с Goodreads Примр цели — создание системы рекомендаций для книг, прогнозирование рейтингов для новых книг. Входные данные: Название, Автор, Средняя оценка, Общее количество оценок, Количество добавлений на полки, Год публикации, Описание, Изображение
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
df_books = pd.read_csv(".//static//csv//Popular-Books.csv")
print("Столбцы в Popular-Books:")
print(df_books.columns)
Посмотрим краткое содержание датасета.
print("Информация о датасете Popular-Books:")
df_books.info()
df_books.head()
Анализируем датафрейм при помощи "ящика с усами". Проверяет на пустые значения.
# Настройка стиля графиков
sns.set_theme(style="whitegrid")
plt.figure(figsize=(12, 6))
sns.boxplot(x='Score', data=df_books)
plt.title('Распределение оценок книг')
plt.xlabel('Оценка')
plt.show()
# Проверка на пустые значения для каждого набора данных
def check_missing_values(dataframe, name):
missing_values = dataframe.isnull().sum()
print(f"Проверка на пустые значения в наборе данных '{name}':")
print(missing_values[missing_values > 0]) # Отображаем только столбцы с пропущенными значениями
print("\n")
check_missing_values(df_books, "Popular Books")
Удаляем все найденные пустые значения.
# Функция для удаления строк с пустыми значениями
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
cleaned_df_books = drop_missing_values(df_books, "Popular Books")
Очистка данных от шумов
# Визуализация перед очисткой
plt.figure(figsize=(10, 6))
plt.scatter(cleaned_df_books['Ratings'], cleaned_df_books['Score'])
plt.xlabel('Ratings')
plt.ylabel('Score')
plt.title('Scatter Plot of Ratings vs Score (Before Cleaning)')
plt.show()
# Рассчитываем квартиль 1 (Q1) и квартиль 3 (Q3) для Score
Q1 = cleaned_df_books["Score"].quantile(0.25)
Q3 = cleaned_df_books["Score"].quantile(0.75)
# Рассчитываем межквартильный размах (IQR)
IQR = Q3 - Q1
# Определяем порог для выбросов
threshold = 1.5 * IQR
lower_bound = Q1 - threshold
upper_bound = Q3 + threshold
# Фильтруем выбросы
outliers = (cleaned_df_books["Score"] < lower_bound) | (cleaned_df_books["Score"] > upper_bound)
# Вывод выбросов
print("Выбросы в Popular Books:")
print(cleaned_df_books[outliers])
# Заменяем выбросы на медианные значения
median_score = cleaned_df_books["Score"].median()
cleaned_df_books.loc[outliers, "Score"] = median_score
# Визуализация данных после обработки
plt.figure(figsize=(10, 6))
plt.scatter(cleaned_df_books['Ratings'], cleaned_df_books['Score'])
plt.xlabel('Ratings')
plt.ylabel('Score')
plt.title('Scatter Plot of Ratings vs Score (After Cleaning)')
plt.show()
Разбиение набора данных на обучающую, контрольную и тестовую выборки
from sklearn.model_selection import train_test_split
# Разделение на обучающую и тестовую выборки
train_df, test_df = train_test_split(cleaned_df_books, 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['Ratings'].value_counts()
print(f"Распределение Ratings в {name}:")
print(counts)
print()
check_balance(train_df, "обучающей выборке")
check_balance(val_df, "контрольной выборке")
check_balance(test_df, "тестовой выборке")
Используем oversample и undersample
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, 'Ratings')
val_df_oversampled = oversample(val_df, 'Ratings')
test_df_oversampled = oversample(test_df, 'Ratings')
train_df_undersampled = undersample(train_df, 'Ratings')
val_df_undersampled = undersample(val_df, 'Ratings')
test_df_undersampled = undersample(test_df, 'Ratings')
# Проверка сбалансированности после oversampling
print("Оверсэмплинг:")
check_balance(train_df_oversampled, "обучающей выборке")
check_balance(val_df_oversampled, "контрольной выборке")
check_balance(test_df_oversampled, "тестовой выборке")
# Проверка сбалансированности после undersampling
print("Андерсэмплинг:")
check_balance(train_df_undersampled, "обучающей выборке")
check_balance(val_df_undersampled, "контрольной выборке")
check_balance(test_df_undersampled, "тестовой выборке")
https://www.kaggle.com/datasets/gallo33henrique/bitcoin-btc-usd-stock-dataset Данный набор данных относится к анализу и прогнозированию финансовых временных рядов, связанных с криптовалютами. Примр цели — разработка модели машинного обучения для прогнозирования цен на основе временных рядов. Входные данные: Дата, Цена открытия на начало торговли, Самая высокая цена, Самая низкая цена, Цена закрытия в конце торговли, Скорректированная цена закрытия, Количество проданных.
df_btc = pd.read_csv(".//static//csv//BTC-USD_stock_data.csv")
print("Столбцы в Popular-Books:")
print(df_btc.columns)
Посмотрим краткое содержание датасета
# Добавляем бинарную переменную 'Price_Change': 'up' - цена выросла, 'down' - цена упала
df_btc['Price_Change'] = df_btc['Close'].diff(-1).apply(lambda x: 'up' if x < 0 else 'down')
# Удаляем строки с NaN значениями, возникшими из-за сдвига
df_btc.dropna()
# Вывод первых строк для проверки
print(df_btc[['Date', 'Close', 'Price_Change']].head())
print("\nИнформация о датасете BTC-USD:")
print(df_btc.info())
df_btc.head()
Анализируем датафрейм при помощи "ящика с усами". Проверяет на пустые значения.
plt.figure(figsize=(12, 6))
sns.boxplot(x='Close', data=df_btc)
plt.title('Распределение цен закрытия BTC-USD')
plt.xlabel('Цена закрытия (USD)')
plt.show()
check_missing_values(df_btc, "BTC-USD")
Видно, что выборка относительно сбалансированна, пустых значений нет.
plt.figure(figsize=(10, 6))
plt.scatter(df_btc['Date'], df_btc['Close'])
plt.xlabel('Date')
plt.ylabel('Close Price')
plt.title('Scatter Plot of Date vs Close Price (Before Cleaning)')
plt.xticks(rotation=45)
plt.show()
Убираем шумы
# Рассчитываем квартиль 1 (Q1) и квартиль 3 (Q3) для Close
Q1 = df_btc["Close"].quantile(0.25)
Q3 = df_btc["Close"].quantile(0.75)
# Рассчитываем межквартильный размах (IQR)
IQR = Q3 - Q1
# Определяем порог для выбросов
threshold = 1.5 * IQR
lower_bound = Q1 - threshold
upper_bound = Q3 + threshold
# Фильтруем выбросы
outliers = (df_btc["Close"] < lower_bound) | (df_btc["Close"] > upper_bound)
# Вывод выбросов
print("Выбросы в BTC-USD Stock Data:")
print(df_btc[outliers])
# Заменяем выбросы на медианные значения
median_close = df_btc["Close"].median()
df_btc.loc[outliers, "Close"] = median_close
# Визуализация данных после обработки
plt.figure(figsize=(10, 6))
plt.scatter(df_btc['Date'], df_btc['Close'])
plt.xlabel('Date')
plt.ylabel('Close Price')
plt.title('Scatter Plot of Date vs Close Price (After Cleaning)')
plt.xticks(rotation=45)
plt.show()
Разбиение набора данных на обучающую, контрольную и тестовую выборки
# Разделение на обучающую и тестовую выборки
train_df, test_df = train_test_split(df_btc, 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['Price_Change'].value_counts()
print(f"Распределение Price_Change в {name}:")
print(counts)
print()
check_balance(train_df, "обучающей выборке")
check_balance(val_df, "контрольной выборке")
check_balance(test_df, "тестовой выборке")
Используем oversample и undersample
train_df_oversampled = oversample(train_df, 'Price_Change')
val_df_oversampled = oversample(val_df, 'Price_Change')
test_df_oversampled = oversample(test_df, 'Price_Change')
train_df_undersampled = undersample(train_df, 'Price_Change')
val_df_undersampled = undersample(val_df, 'Price_Change')
test_df_undersampled = undersample(test_df, 'Price_Change')
# Проверка сбалансированности после oversampling
print("Оверсэмплинг:")
check_balance(train_df_oversampled, "обучающей выборке")
check_balance(val_df_oversampled, "контрольной выборке")
check_balance(test_df_oversampled, "тестовой выборке")
# Проверка сбалансированности после undersampling
print("Андерсэмплинг:")
check_balance(train_df_undersampled, "обучающей выборке")
check_balance(val_df_undersampled, "контрольной выборке")
check_balance(test_df_undersampled, "тестовой выборке")
https://www.kaggle.com/datasets/junaid512/random-student-data-set-for-education-purpose Набор данных включает случайные данные о студентах, которые используются для целей моделирования в сфере образования. Примр цели — образовательная аналитика. Входные данные: Полные имена студентов, Класс/программа обучения, Возраст, IQ, Совокупный средний балл успеваемости, Навыки
df_students = pd.read_csv(".//static//csv//student_data_01.csv")
print(df_students.columns)
Посмотрим краткое содержание датасета
print("\nИнформация о датасете BTC-USD:")
print(df_students.info())
df_students.head()
Анализируем датафрейм при помощи "ящика с усами". Проверяет на пустые значения.
plt.figure(figsize=(12, 6))
sns.boxplot(x='Class_or_Program', data=df_students)
plt.title('Распределение Class_or_Program студентов')
plt.xlabel('Class_or_Program')
plt.show()
check_missing_values(df_students, "Student")
Видно, что выборка относительно сбалансированна, пустых значений нет.
from sklearn.preprocessing import LabelEncoder
# Преобразование категориального столбца в числовой для hexbin
label_encoder = LabelEncoder()
df_students['Class_or_Program_encoded'] = label_encoder.fit_transform(df_students['Class_or_Program'])
# Визуализация плотности точек с использованием hexbin
plt.figure(figsize=(10, 6))
plt.hexbin(df_students['Class_or_Program_encoded'], df_students['IQ'], gridsize=30, cmap='coolwarm')
plt.colorbar(label='IQ')
# Настройка оси X, чтобы отображать текстовые метки вместо чисел
plt.xticks(ticks=range(len(label_encoder.classes_)), labels=label_encoder.classes_)
plt.xlabel('Class_or_Program')
plt.ylabel('IQ')
plt.title('Scatter Plot of Class_or_Program vs IQ (Before Cleaning)')
plt.show()
Убираем шумы
# Рассчитываем квартиль 1 (Q1) и квартиль 3 (Q3) для IQ
Q1 = df_students["IQ"].quantile(0.25)
Q3 = df_students["IQ"].quantile(0.75)
# Рассчитываем межквартильный размах (IQR)
IQR = Q3 - Q1
# Определяем порог для выбросов
threshold = 1.5 * IQR
lower_bound = Q1 - threshold
upper_bound = Q3 + threshold
# Фильтруем выбросы
outliers = (df_students["IQ"] < lower_bound) | (df_students["IQ"] > upper_bound)
# Вывод выбросов
print("Выбросы в Student Data:")
print(df_students[outliers])
# Заменяем выбросы на медианные значения
median_iq = df_students["IQ"].median()
df_students.loc[outliers, "IQ"] = median_iq
# Визуализация плотности точек с использованием hexbin
plt.figure(figsize=(10, 6))
plt.hexbin(df_students['Class_or_Program_encoded'], df_students['IQ'], gridsize=30, cmap='coolwarm')
plt.colorbar(label='IQ')
# Настройка оси X, чтобы отображать текстовые метки вместо чисел
plt.xticks(ticks=range(len(label_encoder.classes_)), labels=label_encoder.classes_)
plt.xlabel('Class_or_Program')
plt.ylabel('IQ')
plt.title('Scatter Plot of Class_or_Program vs IQ (Before Cleaning)')
plt.show()
Разбиение набора данных на обучающую, контрольную и тестовую выборки
# Разделение на обучающую и тестовую выборки
train_df, test_df = train_test_split(df_students, 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['Class_or_Program'].value_counts()
print(f"Распределение Class_or_Program в {name}:")
print(counts)
print()
check_balance(train_df, "обучающей выборке")
check_balance(val_df, "контрольной выборке")
check_balance(test_df, "тестовой выборке")
Используем oversample и undersample
train_df_oversampled = oversample(train_df, 'Class_or_Program')
val_df_oversampled = oversample(val_df, 'Class_or_Program')
test_df_oversampled = oversample(test_df, 'Class_or_Program')
train_df_undersampled = undersample(train_df, 'Class_or_Program')
val_df_undersampled = undersample(val_df, 'Class_or_Program')
test_df_undersampled = undersample(test_df, 'Class_or_Program')
# Проверка сбалансированности после oversampling
print("Оверсэмплинг:")
check_balance(train_df_oversampled, "обучающей выборке")
check_balance(val_df_oversampled, "контрольной выборке")
check_balance(test_df_oversampled, "тестовой выборке")
# Проверка сбалансированности после undersampling
print("Андерсэмплинг:")
check_balance(train_df_undersampled, "обучающей выборке")
check_balance(val_df_undersampled, "контрольной выборке")
check_balance(test_df_undersampled, "тестовой выборке")