481 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
import pandas as pd
data = pd.read_csv("../static/csv/mobile phone price prediction.csv",delimiter=',')
print(df.columns)
Проблема область: Данные о мобильных телефонах, включая их характеристику.
Объект наблюдения: Мобильные телефоны.
Атрибуты: Имя, рейтинг, оценка, поддержка двух SIM-карт, оперативная память, аккумулятор, дисплей, камера, внешняя память, версия Android телефона, цена, компания производителя, разрешение экрана, харатеристика процессора, название процессора.
Пример бизнес-цели:
- Анализ данных: Изучение и очистка данных для выявления закономерностей и корреляций между характеристиками мобильных телефонов и их ценами.
- Разработка модели: Создание и обучение модели машинного обучения, которая будет прогнозировать цены на мобильные телефоны на основе их характеристик.
- Внедрение: Интеграция модели в систему ценообразования компании для автоматического расчета цен на мобильные телефоны.
Актуальность: Данный датасет является актуальным и ценным ресурсом для компаний, занимающихся продажей мобильных телефонов, а также для исследователей и инвесторов, поскольку он предоставляет обширную информацию о ценах и характеристиках мобильных телефонов на вторичном рынке. Эти данные могут быть использованы для разработки моделей прогнозирования цен, анализа рыночных тенденций и принятия обоснованных бизнес-решений.
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
# Загрузка данных
data = pd.read_csv("../static/csv/mobile phone price prediction.csv",delimiter=',')
data.drop(['Unnamed: 0'], axis=1, inplace=True)
data['Price'] = data['Price'].str.replace(',', '').astype(float)
data.describe(include='all')
f, ax = plt.subplots(figsize=(10,6))
sns.despine(f)
sns.scatterplot(data=data, x='Spec_score', y='Price')
При проверке на шум можно заметить выброс в 75 оценке. Цена там запредельная.
Для удаления выбросов из датасета можно использовать метод межквартильного размаха. Зашумленность не очень высокая. Покрытие данных высокое и подошло бы для поставленной задачи по актуальности.
import pandas as pd
import matplotlib.pyplot as plt
# Загрузка данных
df = pd.read_csv("..//static//csv//mobile phone price prediction.csv")
df['Spec_score'] = df['Spec_score'].astype(int)
df['Price'] = df['Price'].str.replace(',', '').astype(float)
# Выбор столбцов для анализа
column1 = 'Spec_score'
column2 = 'Price'
# Функция для удаления выбросов
def remove_outliers(df, column):
Q1 = df[column].quantile(0.25)
Q3 = df[column].quantile(0.75)
IQR = Q3 - Q1
lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR
return df[(df[column] >= lower_bound) & (df[column] <= upper_bound)]
# Удаление выбросов для каждого столбца
df_cleaned = df.copy()
for column in [column1, column2]:
df_cleaned = remove_outliers(df_cleaned, column)
# Построение точечной диаграммы после удаления выбросов
plt.figure(figsize=(10, 6))
plt.scatter(df_cleaned[column1], df_cleaned[column2], alpha=0.5)
plt.xlabel(column1)
plt.ylabel(column2)
plt.title(f'Scatter Plot of {column1} vs {column2} (After Removing Outliers)')
plt.show()
# Вывод количества строк до и после удаления выбросов
print(f"Количество строк до удаления выбросов: {len(df)}")
print(f"Количество строк после удаления выбросов: {len(df_cleaned)}")
Теперь очистим датасет от пустых строк
import pandas as pd
# Загрузка данных
df = pd.read_csv("..//static//csv//mobile phone price prediction.csv")
# Вывод общей информации о датасете
print("Общая информация о датасете:")
print(df.info())
# Вывод общей информации о датасете
print("Общая информация о датасете:")
print(df.info())
# Вывод таблицы анализа пропущенных значений
missing_values = df.isnull().sum()
missing_values_percentage = (missing_values / len(df)) * 100
missing_data = pd.concat([missing_values, missing_values_percentage], axis=1, keys=['Количество пропущенных значений', 'Процент пропущенных значений'])
print("\nТаблица анализа пропущенных значений:")
print(missing_data)
df.dropna(inplace=True)
print(df.shape)
print(df.isnull().any())
Создадим выборки.
# Разделение на обучающую и тестовую выборки
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))
Проанализируем сбалансированность выборки
def check_balance(df, name):
counts = df['company'].value_counts()
print(f"Распределение company в {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
# Разделение на обучающую и тестовую выборки
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['company'].value_counts()
print(f"Распределение company в {name}:")
print(counts)
print()
def oversample(df):
X = df.drop('company', axis=1)
y = df['company']
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('company', axis=1)
y = df['company']
undersampler = RandomUnderSampler(random_state=42) # type: ignore
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")
Цены на автомобили¶
import pandas as pd
df = pd.read_csv("..//static//csv//car_price_prediction.csv")
print(df.columns)
Проблемная область: Данные о ценах на автомобили, включая их характеристики
Объект наблюдения: автомобиль
Атрибуты: идентификатор, цена, налог, производитель, модель, год производства, категория, наличие кожаного салона, тип топлива, объем двигателя, пробег автомобиля, количество цилиндров в двигателе, тип коробки передач, тип привода, количество дверей, расположение руля, цвет, количество подушек безопасностей.
Пример бизнес-цели:
- Анализ данных: Изучение и очистка данных для выявления закономерностей и корреляций между характеристиками автомобилей и их ценами.
- Разработка модели: Создание и обучение модели машинного обучения, которая будет прогнозировать цены на автомобили на основе их характеристик.
- Внедрение: Интеграция модели в систему ценообразования компании для автоматического расчета цен на автомобили.
Актуальность: Данный датасет является актуальным и ценным ресурсом для компаний, занимающихся продажей автомобилей, а также для исследователей и инвесторов, поскольку он предоставляет обширную информацию о ценах и характеристиках автомобилей на вторичном рынке. Эти данные могут быть использованы для разработки моделей прогнозирования цен, анализа рыночных тенденций и принятия обоснованных бизнес-решений.
import matplotlib.pyplot as plt
# Преобразуем год производства в целочисленный тип
df['Prod. year'] = df['Prod. year'].astype(int)
# Визуализация данных
plt.figure(figsize=(10, 6))
plt.scatter(df['Prod. year'], df['Price'])
plt.xlabel('Production Year')
plt.ylabel('Price')
plt.title('Scatter Plot of Price vs Production Year')
plt.show()
Зашумленность не очень высокая. Покрытие данных высокое и подошло бы для поставленной задачи по актуальности.
# Преобразуем год производства в целочисленный тип
df['Prod. year'] = df['Prod. year'].astype(int)
# Статистический анализ для определения выбросов
Q1 = df['Price'].quantile(0.25)
Q3 = df['Price'].quantile(0.75)
IQR = Q3 - Q1
# Определение порога для выбросов
threshold = 1.5 * IQR
outliers = (df['Price'] < (Q1 - threshold)) | (df['Price'] > (Q3 + threshold))
# Вывод выбросов
print("Выбросы:")
print(df[outliers])
# Обработка выбросов
# В данном случае мы заменим выбросы на медианное значение
median_price = df['Price'].median()
df.loc[outliers, 'Price'] = median_price
# Визуализация данных после обработки
plt.figure(figsize=(10, 6))
plt.scatter(df['Prod. year'], df['Price'])
plt.xlabel('Production Year')
plt.ylabel('Price')
plt.title('Scatter Plot of Price vs Production Year (After Handling Outliers)')
plt.show()
Смртрем, есть ли пропущенные значения. Пропущенных данных не обнаружено.
# Количество пустых значений признаков
print(df.isnull().sum())
print()
Теперь создадим выборки.
# Загрузка данных
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, "тестовой выборке")
Цены на кофе¶
import pandas as pd
df = pd.read_csv("..//static//csv//Starbucks Dataset.csv")
print(df.columns)
Проблемная область: Данные о ценах на акции кофе Starbucks Corporation.
Объект наблюдения: цены на акции кофе.
Атрибуты: дата , цена открытия , самая высокая цена дня, самая низкая цена дня, цена закрытия , скорректированная цена закрытия и объем торгов.
Пример бизнес-цели:
- Анализ данных: Изучение и очистка данных для выявления закономерностей и корреляций между объёмом торгов и цены на акции кофе Starbucks Corporation.
- Разработка модели: Создание и обучение модели машинного обучения, которая будет прогнозировать цены на акции кофе Starbucks Corporation.
- Внедрение: Интеграция модели в систему ценообразования компании для автоматического расчета цен на акции кофе.
Актуальность:Эти данные бесценны для проведения исторического анализа , прогнозирования будущей динамики акций и понимания рыночных тенденций, связанных с акциями Starbucks.
import pandas as pd
import matplotlib.pyplot as plt
# Загрузка данных
df = pd.read_csv("..//static//csv//Starbucks Dataset.csv")
plt.figure(figsize=(10, 6))
plt.scatter(df['Adj Close'], df['Volume'])
plt.xlabel('Adj Close')
plt.ylabel('Volume')
plt.title('Scatter Plot of Adj Close vs Volume')
plt.show()
Выброс присутствует. Сделаем очистку данных.
Для удаления выбросов из датасета можно использовать метод межквартильного размаха. Зашумленность не очень высокая. Покрытие данных высокое и подошло бы для поставленной задачи по актуальности.
# Загрузка данных
df = pd.read_csv("..//static//csv//Starbucks Dataset.csv")
# Функция для удаления выбросов с использованием IQR
def remove_outliers_iqr(df, column):
Q1 = df[column].quantile(0.25)
Q3 = df[column].quantile(0.75)
IQR = Q3 - Q1
lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR
return df[(df[column] >= lower_bound) & (df[column] <= upper_bound)]
# Удаление выбросов для столбцов 'Adj Close' и 'Volume'
df_cleaned = remove_outliers_iqr(df, 'Adj Close')
df_cleaned = remove_outliers_iqr(df_cleaned, 'Volume')
# Построение графика для очищенных данных
plt.figure(figsize=(10, 6))
plt.scatter(df_cleaned['Adj Close'], df_cleaned['Volume'])
plt.xlabel('Adj Close')
plt.ylabel('Volume')
plt.title('Scatter Plot of Adj Close vs Volume (Cleaned)')
plt.show()
Теперь посмотрим, если пустые значения. Пустых значений не оказалось.
# Количество пустых значений признаков
print(df.isnull().sum())
print()
# Есть ли пустые значения признаков
print(df.isnull().any())
print()
Теперь создадим выборки.
# Выбор признаков и целевой переменной
X = df.drop('Volume', axis=1) # Признаки (все столбцы, кроме 'volume')
y = df['Volume'] # Целевая переменная ('volume')
# Разбиение данных на обучающую и оставшуюся часть (контрольную + тестовую)
X_train, X_temp, y_train, y_temp = train_test_split(X, y, test_size=0.4, random_state=42)
# Разбиение оставшейся части на контрольную и тестовую выборки
X_val, X_test, y_val, y_test = train_test_split(X_temp, y_temp, test_size=0.5, random_state=42)
# Вывод размеров выборок
print(f"Размер обучающей выборки: {X_train.shape[0]}")
print(f"Размер контрольной выборки: {X_val.shape[0]}")
print(f"Размер тестовой выборки: {X_test.shape[0]}")
Проанализируем сбалансированность выборки.
# Функция для анализа распределения и вывода результатов
def analyze_distribution(data, title):
print(f"Распределение Price в {title}:")
distribution = data.value_counts().sort_index()
print(distribution)
total = len(data)
positive_count = (data > 0).sum()
negative_count = (data < 0).sum()
positive_percent = (positive_count / total) * 100
negative_percent = (negative_count / total) * 100
print(f"Процент положительных значений: {positive_percent:.2f}%")
print(f"Процент отрицательных значений: {negative_percent:.2f}%")
print("\nНеобходима аугментация данных для балансировки классов.\n")
# Анализ распределения для каждой выборки
analyze_distribution(y_train, "обучающей выборке")
analyze_distribution(y_val, "контрольной выборке")
analyze_distribution(y_test, "тестовой выборке")
Выборка недостаточно сбалансирована. Выполним аугментацию данных.
# Применение oversampling к обучающей выборке
oversampler = RandomOverSampler(random_state=42)
X_train_resampled, y_train_resampled = oversampler.fit_resample(X_train, y_train)
# Функция для анализа распределения и вывода результатов
def analyze_distribution(data, title):
print(f"Распределение Volume в {title}:")
distribution = data.value_counts().sort_index()
print(distribution)
total = len(data)
positive_count = (data > 0).sum()
negative_count = (data < 0).sum()
positive_percent = (positive_count / total) * 100
negative_percent = (negative_count / total) * 100
print(f"Процент положительных значений: {positive_percent:.2f}%")
print(f"Процент отрицательных значений: {negative_percent:.2f}%")
# Анализ распределения для каждой выборки
analyze_distribution(y_train_resampled, "обучающей выборке после oversampling")
analyze_distribution(y_val, "контрольной выборке")
analyze_distribution(y_test, "тестовой выборке")