158 KiB
Выбранные темы: прогнозирование стоимости страховки, данные о населении, цены на автомобили.
Выделим вспомогательные функции
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelEncoder
from imblearn.over_sampling import RandomOverSampler
from imblearn.under_sampling import RandomUnderSampler
import seaborn as sns
import numpy as np
label_encoder = LabelEncoder()
# Функция для применения oversampling
def apply_oversampling(X, y):
oversampler = RandomOverSampler(random_state=42)
X_resampled, y_resampled = oversampler.fit_resample(X, y)
return X_resampled, y_resampled
# Функция для применения undersampling
def apply_undersampling(X, y):
undersampler = RandomUnderSampler(random_state=42)
X_resampled, y_resampled = undersampler.fit_resample(X, y)
return X_resampled, y_resampled
def split_stratified_into_train_val_test(
df_input,
stratify_colname="y",
frac_train=0.6,
frac_val=0.15,
frac_test=0.25,
random_state=None,
):
"""
Splits a Pandas dataframe into three subsets (train, val, and test)
following fractional ratios provided by the user, where each subset is
stratified by the values in a specific column (that is, each subset has
the same relative frequency of the values in the column). It performs this
splitting by running train_test_split() twice.
Parameters
----------
df_input : Pandas dataframe
Input dataframe to be split.
stratify_colname : str
The name of the column that will be used for stratification. Usually
this column would be for the label.
frac_train : float
frac_val : float
frac_test : float
The ratios with which the dataframe will be split into train, val, and
test data. The values should be expressed as float fractions and should
sum to 1.0.
random_state : int, None, or RandomStateInstance
Value to be passed to train_test_split().
Returns
-------
df_train, df_val, df_test :
Dataframes containing the three splits.
"""
if frac_train + frac_val + frac_test != 1.0:
raise ValueError(
"fractions %f, %f, %f do not add up to 1.0"
% (frac_train, frac_val, frac_test)
)
if stratify_colname not in df_input.columns:
raise ValueError("%s is not a column in the dataframe" % (stratify_colname))
X = df_input # Contains all columns.
y = df_input[
[stratify_colname]
] # Dataframe of just the column on which to stratify.
# Split original dataframe into train and temp dataframes.
df_train, df_temp, y_train, y_temp = train_test_split(
X, y, stratify=y, test_size=(1.0 - frac_train), random_state=random_state
)
# Split the temp dataframe into val and test dataframes.
relative_frac_test = frac_test / (frac_val + frac_test)
df_val, df_test, y_val, y_test = train_test_split(
df_temp,
y_temp,
stratify=y_temp,
test_size=relative_frac_test,
random_state=random_state,
)
assert len(df_input) == len(df_train) + len(df_val) + len(df_test)
return df_train, df_val, df_test
Анализ наборов данных
- Прогнозирование стоимости страховки
Проблемная область: Медицинское страхование.
Описание: Набор данных содержит информацию о клиентах медицинского страхования, включая возраст, пол, индекс массы тела (ИМТ), количество детей, курение, регион и стоимость страхового взноса.
Связи между объектами: Нет явных связей, кроме того, что все объекты относятся к клиентам медицинского страхования.
Бизнес-цель: Оптимизация тарифов страховых взносов.
Эффект для бизнеса: Снижение рисков и повышение прибыльности за счет более точного определения стоимости страхования для разных групп клиентов.
Цель технического проекта: Разработка модели машинного обучения для прогнозирования стоимости страхового взноса на основе характеристик клиента.
Входные признаки: Возраст, пол, ИМТ, количество детей, курение, регион.
Целевой признак: Стоимость страхового взноса.
Данный график позволят увидеть изменения стоимости страховки от возраста.
df1 = pd.read_csv("../data/Medical_insurance.csv")
df1.info()
print(df1.isnull().sum())
print(df1.describe())
plt.scatter(df1["charges"], df1["age"])
plt.show()
Зашумленность: Возможны ошибки в данных, например, некорректные значения ИМТ.
Смещение: Может быть смещение в данных, например, если выборка нерепрезентативна по полу или региону.
Актуальность: Данные должны быть актуальными, чтобы модель давала точные прогнозы.
Выбросы: Выбросы в данных, например, очень высокие значения стоимости страхового взноса.
Просачивание данных: Не должно быть просачивания данных, например, если стоимость страхового взноса используется в качестве признака.
Примеры решения обнаруженных проблем:
Зашумленность: Очистка данных, удаление или исправление ошибочных значений.
Смещение: Балансировка данных, использование техники выборки.
Актуальность: Использование актуальных данных.
Выбросы: Удаление выбросов или использование техники обработки выбросов.
Просачивание данных: Удаление целевого признака из обучающих данных.
Оценка:
Информативность: Высокая, так как данные содержат много релевантных признаков для прогнозирования стоимости страхового взноса.
Степень покрытия: Высокая, так как данные содержат информацию о большом количестве клиентов.
Соответствие реальным данным: Высокое, так как данные взяты из реальной базы данных медицинского страхования.
Согласованность меток: Высокая, так как данные имеют четко определенные метки.
Чтобы устранить проблемы прощенных строк, необходимо удалить строки с пропущенными значениями.
Разбиение набора данных на обучающую, контрольную и тестовую выборки
Также потребуется приращение данных, если выборки несбалансированы по какому-либо признаку
data = df1[["age", "charges", "children"]].copy()
data["Charges_Grouped"] = pd.cut(data["age"], bins=6, labels=False)
interval_counts = data["Charges_Grouped"].value_counts().sort_index()
min_samples_per_interval = 10
for interval, count in interval_counts.items():
if count < min_samples_per_interval:
data.loc[data["Charges_Grouped"] == interval, "Charges_Grouped"] = -1
df_insurance_train, df_insurance_val, df_insurance_test = split_stratified_into_train_val_test(
data, stratify_colname="Charges_Grouped", frac_train=0.60, frac_val=0.20, frac_test=0.20)
print("Обучающая выборка: ", df_insurance_train.shape)
print(df_insurance_train["Charges_Grouped"].value_counts())
X_resampled, y_resampled = apply_oversampling(df_insurance_train, df_insurance_train["Charges_Grouped"])
df_insurance_train_adasyn = pd.DataFrame(X_resampled)
print("Обучающая выборка после oversampling: ", df_insurance_train_adasyn.shape)
print(df_insurance_train_adasyn["Charges_Grouped"].value_counts())
print("Контрольная выборка: ", df_insurance_val.shape)
print(df_insurance_val["Charges_Grouped"].value_counts())
print("Тестовая выборка: ", df_insurance_test.shape)
print(df_insurance_test["Charges_Grouped"].value_counts())
Данные хорошо подходят для построения модели прогнозирования стоимости страхового взноса. Возможны проблемы с зашумленностью и смещением данных.
- Цены на автомобили
Проблемная область: Автомобильная индустрия.
Описание: Набор данных содержит информацию о характеристиках автомобилей, таких как марка, модель, год выпуска, пробег, тип топлива, тип трансмиссии и цена продажи. Нет явных связей, кроме того, что все объекты относятся к автомобилям.
Бизнес-цель: Оптимизация ценообразования на вторичном рынке автомобилей.
Эффект для бизнеса: Увеличение продаж и прибыли за счет более точной оценки рыночной стоимости автомобилей.
Цель технического проекта: Разработка модели машинного обучения для прогнозирования рыночной стоимости автомобиля на основе его характеристик.
Входные признаки: Марка, модель, год выпуска, пробег, тип топлива, тип трансмиссии.
Целевой признак: Цена продажи.
df2 = pd.read_csv("../data/car_price_prediction.csv")
df2.info()
print(df2.isnull().sum())
print(df2.describe())
mean_price_per_year = df2.groupby('Prod. year')['Price'].mean()
plt.figure(figsize=(8, 6))
mean_price_per_year.plot(kind='line', marker='o', color='blue')
plt.title('Зависимость средней цены от года выпуска автомобиля')
plt.xlabel('Год выпуска')
plt.ylabel('Средняя цена ($)')
plt.grid(True)
plt.show()
Зашумленность: Возможны ошибки в данных, например, некорректные значения пробега.
Смещение: Может быть смещение в данных, например, если выборка нерепрезентативна по марке или модели автомобиля.
Актуальность: Данные должны быть актуальными, чтобы модель давала точные прогнозы.
Выбросы: Возможны выбросы в данных, например, очень высокие или низкие значения цены продажи.
Просачивание данных: Не должно быть просачивания данных, например, если цена продажи используется в качестве признака.
Решение этих проблем:
Зашумленность: Очистка данных, удаление или исправление ошибочных значений.
Смещение: Балансировка данных, использование техники выборки.
Актуальность: Использование актуальных данных.
Выбросы: Удаление выбросов или использование техники обработки выбросов.
Просачивание данных: Удаление целевого признака из обучающих данных.
Оценка:
Информативность: Высокая, так как данные содержат много релевантных признаков для прогнозирования стоимости страхового взноса.
Степень покрытия: Высокая, так как данные содержат информацию о большом количестве клиентов.
Соответствие реальным данным: Высокое, так как данные взяты из реальной базы данных медицинского страхования.
Согласованность меток: Высокая, так как данные имеют четко определенные метки.
Разбиение набора данных на обучающую, контрольную и тестовую выборки
Также потребуется приращение данных, если выборки несбалансированы по какому-либо признаку
df2 = df2[df2['Price'] <= 10000000]
data = df2[["Price", "Prod. year", "Airbags"]].copy()
data["Price_Grouped"] = pd.cut(data["Price"], bins=50, labels=False)
interval_counts = data["Price_Grouped"].value_counts().sort_index()
min_samples_per_interval = 5
for interval, count in interval_counts.items():
if count < min_samples_per_interval:
data.loc[data["Price_Grouped"] == interval, "Price_Grouped"] = -1
df_price_train, df_price_val, df_price_test = split_stratified_into_train_val_test(
data, stratify_colname="Price_Grouped", frac_train=0.60, frac_val=0.20, frac_test=0.20)
print("Обучающая выборка: ", df_price_train.shape)
print(df_price_train["Price_Grouped"].value_counts())
X_resampled, y_resampled = apply_oversampling(df_price_train, df_price_train["Price_Grouped"])
df_price_train_adasyn = pd.DataFrame(X_resampled)
print("Обучающая выборка после oversampling: ", df_price_train_adasyn.shape)
print(df_price_train_adasyn["Price_Grouped"].value_counts())
print("Контрольная выборка: ", df_price_val.shape)
print(df_price_val["Price_Grouped"].value_counts())
print("Тестовая выборка: ", df_price_test.shape)
print(df_price_test["Price_Grouped"].value_counts())
Данные хорошо подходят для построения модели прогнозирования цены продажи автомобиля. Возможны проблемы с зашумленностью и смещением данных.
- Цены на кофе
Проблемная область: Финансы и инвестиции.
Описание: Набор данных содержит исторические данные о ценах на акции Starbucks (тикер: SBUX) с 1992 по 2021 год. Данные включают информацию о ценах открытия, закрытия, максимальных и минимальных ценах, объеме торгов и скорректированных ценах закрытия.
Связи между объектами: Данные представлены временным рядом, где каждая строка соответствует одному торговому дню. Между объектами существует временная зависимость, так как цены на акции зависят от предыдущих значений.
Бизнес-цель: Прогнозирование будущих цен на акции Starbucks.
Эффект для бизнеса:
Для инвесторов: Повышение точности прогнозов позволяет инвесторам принимать более обоснованные решения о покупке и продаже акций, что может привести к увеличению прибыли.
Для компании Starbucks: Понимание динамики цен на акции может помочь в разработке стратегий привлечения инвестиций и повышения рыночной стоимости компании.
Цель технического проекта: Разработка модели машинного обучения для прогнозирования цены закрытия акций Starbucks на следующий день.
Входные признаки:
Open (цена открытия)
High (максимальная цена)
Low (минимальная цена)
Close (цена закрытия)
Volume (объем торгов)
Adj Close (скорректированная цена закрытия)
Целевой признак: Close (цена закрытия на следующий день).
df3 = pd.read_csv("../data/Starbucks Dataset.csv")
df3.info()
print(df3.isnull().sum())
print(df3.describe())
plt.plot(df3["Date"], df3["High"])
plt.show()
Зашумленность: Возможны случайные колебания цен, которые могут быть вызваны внешними факторами.
Смещение: Нет явного смещения, так как данные представляют собой временной ряд.
Актуальность: Данные актуальны до 2021 года, но для более точного прогнозирования могут потребоваться более свежие данные.
Выбросы: Возможны выбросы в данных, например, резкие скачки цен, вызванные внешними событиями (кризисы, слияния и поглощения).
Просачивание данных: Не должно быть просачивания данных, так как целевой признак (цена закрытия на следующий день) не должен использоваться в качестве признака.
Примеры их решений:
Зашумленность: Использование методов сглаживания временных рядов, таких как скользящее среднее или экспоненциальное сглаживание.
Выбросы: Удаление выбросов или использование техники обработки выбросов, такой как Winsorization.
Актуальность: Обновление данных до последней доступной даты.
Оценка набора данных:
Информативность: Высокая, так как данные содержат много релевантных признаков для прогнозирования цен на акции.
Степень покрытия: Высокая, так как данные охватывают длительный период времени (1992-2021).
Соответствие реальным данным: Высокое, так как данные взяты из реальной торговой платформы.
Согласованность меток: Высокая, так как данные имеют четко определенные метки.
Выборки сбалансированы, так как данные представляют собой временной ряд, и каждая строка соответствует одному торговому дню. Данные представлены в виде временного ряда, поэтому не требуется исмпользовать методы приращения данных.
Для временных рядов методы oversampling и undersampling обычно не применяются, так как они могут нарушить временную структуру данных.
data = df3[["Volume", "High", "Low"]].copy()
data["Volume_Grouped"] = pd.cut(data["Volume"], bins=50, labels=False)
interval_counts = data["Volume_Grouped"].value_counts().sort_index()
min_samples_per_interval = 5
for interval, count in interval_counts.items():
if count < min_samples_per_interval:
data.loc[data["Volume_Grouped"] == interval, "Volume_Grouped"] = -1
df_coffee_train, df_coffee_val, df_coffee_test = split_stratified_into_train_val_test(
data, stratify_colname="Volume_Grouped", frac_train=0.60, frac_val=0.20, frac_test=0.20)
print("Обучающая выборка: ", df_coffee_train.shape)
print(df_coffee_train["Volume_Grouped"].value_counts())
print("Контрольная выборка: ", df_coffee_val.shape)
print(df_coffee_val["Volume_Grouped"].value_counts())
print("Тестовая выборка: ", df_coffee_test.shape)
print(df_coffee_test["Volume_Grouped"].value_counts())
Вывод:
Данные хорошо подходят для построения модели прогнозирования цен на акции Starbucks.
Возможны проблемы с зашумленностью и выбросами в данных.
Для улучшения качества модели можно использовать методы сглаживания временных рядов и обработки выбросов.