206 KiB
Лабораторная работа №2¶
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 RandomOverSampler
from imblearn.under_sampling import RandomUnderSampler
from sklearn.preprocessing import LabelEncoder
Цены на автомобили¶
https://www.kaggle.com/datasets/deepcontractor/car-price-prediction-challenge
Этот набор данных предоставляет подробную информацию о продаже автомобилей, включая их уникальные идентификаторы, цены, сборы и налоги, а также характеристики производителя и модели. В данных представлены год производства, категория автомобиля, наличие кожаного салона, тип топлива, объем двигателя, пробег, количество цилиндров, тип коробки передач, привод, количество дверей, расположение руля, цвет и количество подушек безопасности. Эти данные могут быть использованы для анализа рынка автомобилей, прогнозирования цен на основе различных факторов, а также для изучения влияния технических и визуальных характеристик на стоимость автомобилей.
Выгрузка данных из csv файла "Цены на автомобили" в датафрейм
df1 = pd.read_csv("..//static//csv//car_price_prediction.csv")
print(df1.columns)
# Преобразуем год производства в целочисленный тип
df1['Prod. year'] = df1['Prod. year'].astype(int)
# Визуализация данных
plt.figure(figsize=(10, 6))
plt.scatter(df1['Prod. year'], df1['Price'])
plt.xlabel('Production Year')
plt.ylabel('Price')
plt.title('Scatter Plot of Price vs Production Year')
plt.show()
Зашумленность не очень высокая. Покрытие данных высокое и подошло бы для поставленной задачи по актуальности.
# Преобразуем год производства в целочисленный тип
df1['Prod. year'] = df1['Prod. year'].astype(int)
# Статистический анализ для определения выбросов
Q1 = df1['Price'].quantile(0.25)
Q3 = df1['Price'].quantile(0.75)
IQR = Q3 - Q1
# Определение порога для выбросов
threshold = 1.5 * IQR
outliers = (df1['Price'] < (Q1 - threshold)) | (df1['Price'] > (Q3 + threshold))
# Вывод выбросов
print("Выбросы:")
print(df1[outliers])
# Обработка выбросов
# В данном случае мы заменим выбросы на медианное значение
median_price = df1['Price'].median()
df1.loc[outliers, 'Price'] = median_price
# Визуализация данных после обработки
plt.figure(figsize=(10, 6))
plt.scatter(df1['Prod. year'], df1['Price'])
plt.xlabel('Production Year')
plt.ylabel('Price')
plt.title('Scatter Plot of Price vs Production Year (After Handling Outliers)')
plt.show()
Очистим от строк с пустыми значениями наш датасет
# Удаление строк с пропущенными значениями
df_dropna = df1.dropna()
# Вывод количества удаленных строк
num_deleted_rows = len(df1) - len(df_dropna)
print(f"\nКоличество удаленных строк: {num_deleted_rows}")
print("\nDataFrame после удаления строк с пропущенными значениями:")
print(df_dropna)
Теперь создадим выборки
# Загрузка данных
df = pd.read_csv("..//static//csv//car_price_prediction.csv")
# Разделение данных на обучающую и временную выборки
train_df, temp_df = train_test_split(df, test_size=0.4, random_state=42)
# Разделение остатка на контрольную и тестовую выборки
val_df, test_df = train_test_split(temp_df, test_size=0.5, random_state=42)
# Проверка размеров выборок
print("Размер обучающей выборки:", len(train_df))
print("Размер контрольной выборки:", len(val_df))
print("Размер тестовой выборки:", len(test_df))
# Сохранение выборок в файлы
train_df.to_csv("..//static//csv//train_data.csv", index=False)
val_df.to_csv("..//static//csv//val_data.csv", index=False)
test_df.to_csv("..//static//csv//test_data.csv", index=False)
Проанализируем сбалансированность выборок
train_df = pd.read_csv("..//static//csv//train_data.csv")
val_df = pd.read_csv("..//static//csv//val_data.csv")
test_df = pd.read_csv("..//static//csv//test_data.csv")
# Оценка сбалансированности
def check_balance(df, name):
counts = df['Category'].value_counts()
print(f"Распределение Category в {name}:")
print(counts)
print(f"Процент автомобилей категории 'Седан': {counts['Sedan'] / len(df) * 100:.2f}%")
print(f"Процент автомобилей категории 'Джип': {counts['Jeep'] / len(df) * 100:.2f}%")
print()
# Определение необходимости аугментации данных
def need_augmentation(df):
counts = df['Category'].value_counts()
ratio = counts['Sedan'] / counts['Jeep']
if ratio > 1.5 or ratio < 0.67:
print("Необходима аугментация данных для балансировки классов.")
else:
print("Аугментация данных не требуется.")
check_balance(train_df, "обучающей выборке")
check_balance(val_df, "контрольной выборке")
check_balance(test_df, "тестовой выборке")
need_augmentation(train_df)
need_augmentation(val_df)
need_augmentation(test_df)
По результатам анализа требуется приращение, соотношения отзывов вне допустимого диапазона
# Загрузка данных
train_df = pd.read_csv("..//static//csv//train_data.csv")
val_df = pd.read_csv("..//static//csv//val_data.csv")
test_df = pd.read_csv("..//static//csv//test_data.csv")
# Преобразование категориальных признаков в числовые
def encode(df):
label_encoders = {}
for column in df.select_dtypes(include=['object']).columns:
if column != 'Category': # Пропускаем целевую переменную
le = LabelEncoder()
df[column] = le.fit_transform(df[column])
label_encoders[column] = le
return label_encoders
# Преобразование целевой переменной в числовые значения
def encode_target(df):
le = LabelEncoder()
df['Category'] = le.fit_transform(df['Category'])
return le
# Применение кодирования
label_encoders = encode(train_df)
encode(val_df)
encode(test_df)
# Кодирование целевой переменной
le_target = encode_target(train_df)
encode_target(val_df)
encode_target(test_df)
# Проверка типов данных
def check_data_types(df):
for column in df.columns:
if df[column].dtype == 'object':
print(f"Столбец '{column}' содержит строковые данные.")
check_data_types(train_df)
check_data_types(val_df)
check_data_types(test_df)
# Функция для выполнения oversampling
def oversample(df):
if 'Category' not in df.columns:
print("Столбец 'Category' отсутствует.")
return df
X = df.drop('Category', axis=1)
y = df['Category']
oversampler = RandomOverSampler(random_state=42)
X_resampled, y_resampled = oversampler.fit_resample(X, y)
resampled_df = pd.concat([X_resampled, y_resampled], axis=1)
return resampled_df
# Функция для выполнения undersampling
def undersample(df):
if 'Category' not in df.columns:
print("Столбец 'Category' отсутствует.")
return df
X = df.drop('Category', axis=1)
y = df['Category']
undersampler = RandomUnderSampler(random_state=42)
X_resampled, y_resampled = undersampler.fit_resample(X, y)
resampled_df = pd.concat([X_resampled, y_resampled], axis=1)
return resampled_df
# Применение oversampling и undersampling к каждой выборке
train_df_oversampled = oversample(train_df)
val_df_oversampled = oversample(val_df)
test_df_oversampled = oversample(test_df)
train_df_undersampled = undersample(train_df)
val_df_undersampled = undersample(val_df)
test_df_undersampled = undersample(test_df)
# Обратное преобразование целевой переменной в строковые метки
def decode_target(df, le_target):
df['Category'] = le_target.inverse_transform(df['Category'])
decode_target(train_df_oversampled, le_target)
decode_target(val_df_oversampled, le_target)
decode_target(test_df_oversampled, le_target)
decode_target(train_df_undersampled, le_target)
decode_target(val_df_undersampled, le_target)
decode_target(test_df_undersampled, le_target)
# Проверка результатов
def check_balance(df, name):
if 'Category' not in df.columns:
print(f"Столбец 'Category' отсутствует в {name}.")
return
counts = df['Category'].value_counts()
print(f"Распределение Category в {name}:")
print(counts)
if 'Sedan' in counts and 'Jeep' in counts:
print(f"Процент автомобилей категории 'Седан': {counts['Sedan'] / len(df) * 100:.2f}%")
print(f"Процент автомобилей категории 'Джип': {counts['Jeep'] / len(df) * 100:.2f}%")
else:
print("Отсутствуют одна или обе категории (Седан/Внедорожник).")
print()
# Проверка сбалансированности после 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, "тестовой выборке")
Классические рок-треки (по данным Spotify)¶
https://www.kaggle.com/datasets/thebumpkin/14400-classic-rock-tracks-with-spotify-data
Этот набор данных, содержащий 1200 уникальных альбомов и 14 400 треков, представляет собой не просто коллекцию — это хроника эволюции классического рока. Каждый трек тщательно каталогизирован с 18 столбцами данных, включая ключевые метаданные, такие как название трека, исполнитель, альбом и год выпуска, наряду с функциями Spotify audio, которые позволяют получить представление о звуковом ландшафте этих неподвластных времени мелодий. Бизнес-цель может заключаться в улучшении стратегии маркетинга и продвижения музыкальных треков. Предположим как этот набор может быть полезен для бизнеса: Персонализированные рекомендации: Создание алгоритмов, которые будут рекомендовать пользователям музыку на основе их предпочтений. Цель технического проекта: Разработать и внедрить систему рекомендаций, которая будет предсказывать и рекомендовать пользователям музыкальные треки на основе их предпочтений и поведения. Входные данные: Данные о пользователях: Идентификатор пользователя, история прослушиваний, оценки треков, время прослушивания, частота прослушивания. Данные о треках: Атрибуты треков (название, исполнитель, альбом, год, длительность, танцевальность, энергичность, акустичность и т.д.). Данные о взаимодействии: Время и частота взаимодействия пользователя с определенными треками. Целевой признак: Рекомендации: Булева переменная, указывающая, должен ли конкретный трек быть рекомендован пользователю (1 - рекомендуется, 0 - не рекомендуется).
Выгрузка данных из csv файла "Данные о клиентах" в датафрейм
df = pd.read_csv("..//static//csv//UltimateClassicRock.csv")
print(df.columns)
Анализируем датафрейм при помощи "ящика с усами". Есть смещение в сторону меньших значений, это можно исправить при помощи oversampling и undersampling.
# Box plot для столбца 'Popularity'
plt.figure(figsize=(10, 6))
sns.boxplot(x=df['Popularity'])
plt.title('Box Plot для Popularity')
plt.xlabel('Popularity')
plt.show()
Решим проблему пустых значений при помощи удаления таких строк.
df_cleaned = df.dropna()
Разбиение набора данных на обучающую, контрольную и тестовую выборки
# Разделение на обучающую и тестовую выборки
train_df, test_df = train_test_split(df_cleaned, 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['Popularity'].value_counts()
print(f"Распределение Popularity в {name}:")
print(counts)
print()
check_balance(train_df, "обучающей выборке")
check_balance(val_df, "контрольной выборке")
check_balance(test_df, "тестовой выборке")
Выполним овер- и андер- слемпинг.
def oversample(df):
X = df.drop('Popularity', axis=1)
y = df['Popularity']
oversampler = RandomOverSampler(random_state=42)
X_resampled, y_resampled = oversampler.fit_resample(X, y)
resampled_df = pd.concat([X_resampled, y_resampled], axis=1)
return resampled_df
train_df_oversampled = oversample(train_df)
val_df_oversampled = oversample(val_df)
test_df_oversampled = oversample(test_df)
check_balance(train_df_oversampled, "обучающей выборке после oversampling")
check_balance(val_df_oversampled, "контрольной выборке после oversampling")
check_balance(test_df_oversampled, "тестовой выборке после oversampling")
def undersample(df):
X = df.drop('Popularity', axis=1)
y = df['Popularity']
undersampler = RandomUnderSampler(random_state=42)
X_resampled, y_resampled = undersampler.fit_resample(X, y)
resampled_df = pd.concat([X_resampled, y_resampled], axis=1)
return resampled_df
train_df_undersampled = undersample(train_df)
val_df_undersampled = undersample(val_df)
test_df_undersampled = undersample(test_df)
check_balance(train_df_undersampled, "обучающей выборке после undersampling")
check_balance(val_df_undersampled, "контрольной выборке после undersampling")
check_balance(test_df_undersampled, "тестовой выборке после undersampling")
Онлайн обучение¶
https://www.kaggle.com/datasets/shariful07/student-flexibility-in-online-learning
Этот набор данных предоставляет информацию о студентах и их характеристиках, связанных с обучением и использованием технологий. В данных представлены следующие атрибуты: уровень образования студента (например, бакалавриат, магистратура), тип учебного заведения (государственное или частное), пол, возраст, тип используемого устройства, является ли студент IT-специалистом, местоположение, финансовое состояние, тип интернета, тип сети и уровень гибкости в обучении. Эти данные могут быть использованы для анализа влияния различных факторов на успеваемость студентов, оптимизации образовательных программ и разработки стратегий поддержки студентов в условиях цифровизации образования.
Выгрузка данных из csv файла "Онлайн обучение" в датафрейм
df = pd.read_csv("..//static//csv//students_adaptability_level_online_education.csv")
print(df.columns)
При помощи ящика с усами и колонки возраста проверим набор на баланс.
# Box plot для столбца 'Age'
plt.figure(figsize=(10, 6))
sns.boxplot(x=df['Age'])
plt.title('Box Plot для Age')
plt.xlabel('Age')
plt.show()
Теперь проверим на шум
# Scatter plot для столбцов 'Age' и 'Financial Condition'
plt.figure(figsize=(10, 6))
sns.scatterplot(x='Age', y='Financial Condition', data=df)
plt.title('Scatter Plot для Age и Financial Condition')
plt.xlabel('Age')
plt.ylabel('Financial Condition')
plt.show()
Удаление строк с пустыми значениями
df_cleaned = df.dropna()
Разбиение набора данных на обучающую, контрольную и тестовую выборки
# Разделение на обучающую и тестовую выборки
train_df, test_df = train_test_split(df, 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))
Применение методов приращения данных (аугментации)
# Разделение на обучающую и тестовую выборки
train_df, test_df = train_test_split(df, test_size=0.2, random_state=42)
# Разделение обучающей выборки на обучающую и контрольную
train_df, val_df = train_test_split(train_df, test_size=0.25, random_state=42)
def check_balance(df, name):
counts = df['Gender'].value_counts()
print(f"Распределение Gender в {name}:")
print(counts)
print()
def oversample(df):
X = df.drop('Gender', axis=1)
y = df['Gender']
oversampler = RandomOverSampler(random_state=42)
X_resampled, y_resampled = oversampler.fit_resample(X, y)
resampled_df = pd.concat([X_resampled, y_resampled], axis=1)
return resampled_df
train_df_oversampled = oversample(train_df)
val_df_oversampled = oversample(val_df)
test_df_oversampled = oversample(test_df)
check_balance(train_df_oversampled, "обучающей выборке после oversampling")
check_balance(val_df_oversampled, "контрольной выборке после oversampling")
check_balance(test_df_oversampled, "тестовой выборке после oversampling")
def undersample(df):
X = df.drop('Gender', axis=1)
y = df['Gender']
undersampler = RandomUnderSampler(random_state=42)
X_resampled, y_resampled = undersampler.fit_resample(X, y)
resampled_df = pd.concat([X_resampled, y_resampled], axis=1)
return resampled_df
train_df_undersampled = undersample(train_df)
val_df_undersampled = undersample(val_df)
test_df_undersampled = undersample(test_df)
check_balance(train_df_undersampled, "обучающей выборке после undersampling")
check_balance(val_df_undersampled, "контрольной выборке после undersampling")
check_balance(test_df_undersampled, "тестовой выборке после undersampling")