115 KiB
Объекты наблюдения и их атрибуты¶
Объекты наблюдения: В данном случае объекты наблюдения — это акции компании Starbucks. Каждая запись в наборе данных представляет собой отдельный день торговли акциями.
Атрибуты акций Starbucks могут включают в себя: Date: Дата торгового дня. Open: Открывающая цена акций Starbucks на данный день. High: Наивысшая цена акций Starbucks в течение торгового дня. Low: Наименьшая цена акций Starbucks в течение торгового дня. Close: Закрывающая цена акций Starbucks на данный день. Adj Close: Скорректированная закрывающая цена акций Starbucks. Volume: Объем торгов акциями Starbucks на данный день.
Связи между объектами могут проявляться в виде: Временных зависимостей: Например, изменения цен акций в разные дни могут быть связаны с событиями, происходящими в компании или на рынке в целом. Корреляции: Например, высокая цена акций в один день может быть связана с высоким объемом торгов, что может указывать на повышенный интерес инвесторов.
Бизнес-цели
Оптимизация инвестиционных решений: Эффект для бизнеса: Более обоснованные инвестиционные решения могут привести к увеличению доходности инвестиций. Цели технического проекта: Разработка модели прогнозирования, которая будет предсказывать будущие изменения цен акций на основе исторических данных. Входные данные: Данные о ценах акций, объемах торгов и других рыночных индикаторах. Целевой признак: Прогнозируемая цена акций на следующий день.
Анализ влияния сезонности на цены акций: Эффект для бизнеса: Понимание сезонных колебаний цен акций может помочь в планировании инвестиционных решений и управлении активами. Цели технического проекта: Разработка системы, которая будет анализировать данные о ценах акций Starbucks в зависимости от времени года, выявляя сезонные тренды и аномалии. Входные данные: Данные о ценах акций (Close, Adj Close) и дате (Date), чтобы определить сезонные паттерны. Целевой признак: Изменение цен акций в зависимости от сезона, что может быть измерено через процентное изменение цен в разные временные промежутки (например, кварталы или месяцы).
Загрузка набора данных¶
import pandas as pd
import numpy as np
starbucks = pd.read_csv("data/starbucks.csv")
# Проверяем результат
print(starbucks.head())
Унитарное кодирование¶
Преобразование категориального признака в несколько бинарных признаков
Унитарное кодирование признака Дата (Date) и объем продаж (Volume)¶
Кодирование
from sklearn.preprocessing import OneHotEncoder
# Преобразуем столбец 'Date' в формат даты
starbucks["Date"] = pd.to_datetime(starbucks["Date"])
# Функция для определения сезона
def get_season(date):
if date.month in [12, 1, 2]:
return "Winter"
elif date.month in [3, 4, 5]:
return "Spring"
elif date.month in [6, 7, 8]:
return "Summer"
elif date.month in [9, 10, 11]:
return "Autumn"
# Применяем функцию к столбцу 'Date'
starbucks["Season"] = starbucks["Date"].apply(get_season)
# Кодируем сезоны с помощью OneHotEncoder
encoder = OneHotEncoder(sparse_output=False, drop=None) # Изменили drop на None
encoded_values = encoder.fit_transform(starbucks[["Season"]])
# Получаем названия закодированных столбцов
encoded_columns = encoder.get_feature_names_out(["Season"])
# Проверяем результат
print(starbucks.head())
Добавление признаков в исходный Dataframe
# Создаем DataFrame с закодированными значениями
encoded_values_df = pd.DataFrame(encoded_values, columns=encoded_columns)
# Объединяем закодированные значения с исходным DataFrame
starbucks = pd.concat([starbucks, encoded_values_df], axis=1)
starbucks
# Проверяем уникальные значения в столбце 'Season'
print(starbucks["Season"].unique())
print(starbucks.columns)
Вывод: Предсказательная способность: признак Season может помочь в предсказании объема продаж, так как спрос на акции может варьироваться в зависимости от времени года (что используется в одной из бизнес целей).
Скорость вычисления:
Признаки должны быть вычисляемыми за разумное время. Например, создание признака Season с использованием функции apply может быть медленным, однако на данном наборе данных все вычисляется очень быстро
Надежность: данные о продажах не меняются -> созданные признаки должны оставаться актуальными.
Корреляция: Признаки имеют низкую степень корреляции
Дискретизация признаков¶
Равномерное разделение данных на 3 группы (по объему продаж)
labels = ["low", "medium", "high"]
num_bins = 3
hist1, bins1 = np.histogram(starbucks["Volume"].fillna(starbucks["Volume"].median()), bins=num_bins)
bins1, hist1
pd.concat([starbucks["Volume"], pd.cut(starbucks["Volume"], list(bins1))], axis=1).head(20)
pd.concat([starbucks["Volume"], pd.cut(starbucks["Volume"], list(bins1), labels=labels)], axis=1
).head(20)
Вывод: Предсказательная способность Признак Volume_Group, который делит объем продаж на группы, также может быть полезен для выявления паттернов в данных.
Скорость вычисления Признаки должны вычисляемыми за разумное время.
Надежность Признаки должны быть стабильными и не подвергаться значительным изменениям при небольших изменениях в данных. Например, если данные о продажах не меняются, то и созданные признаки должны оставаться актуальными. Это важно для обеспечения консистентности в предсказаниях.
Корреляция Признаки не должны быть сильно коррелированы между собой, чтобы избежать мультиколлинеарности. Например, если Volume и Open имеют высокую корреляцию, это может привести к проблемам в моделях, которые предполагают независимость признаков. Необходимо провести анализ корреляции между признаками и исключить избыточные.
Целостность Признаки должны быть логически обоснованными и соответствовать бизнес-логике. Например, признак Volume_Group, который делит объем продаж на группы, должен быть понятным и полезным для анализа. Это поможет в интерпретации результатов и принятии бизнес-решений.
Пример анализа распределения объема продаж Для анализа распределения объема продаж можно использовать гистограмму. Код, который используется, создает гистограмму для объема продаж, что позволяет визуализировать, как распределены продажи по группам.
Равномерное разделение данных на 3 группы c установкой собственной границы диапазона значений
bins2 = np.linspace(1504000, 585508800, 4)
tmp_bins2 = np.digitize(starbucks["Volume"].fillna(starbucks["Volume"].median()), bins2)
hist2 = np.bincount(tmp_bins2 - 1)
bins2, hist2
pd.concat([starbucks["Volume"], pd.cut(starbucks["Volume"], list(bins2))], axis=1).head(20)
pd.concat(
[starbucks["Volume"], pd.cut(starbucks["Volume"], list(bins2), labels=labels)], axis=1
).head(20)
Равномерное разделение данных на 3 группы c установкой собственных интервалов (1504000 - МИН, МЕДИАНА - 11698150, МАКС 585508800)
hist3, bins3 = np.histogram(
starbucks["Volume"].fillna(starbucks["Volume"].median()),
bins=[1504000, 6601075, 298603475, 585508800],
)
bins3, hist3
pd.concat([starbucks["Volume"], pd.cut(starbucks["Volume"], list(bins3))], axis=1).head(20)
pd.concat(
[starbucks["Volume"], pd.cut(starbucks["Volume"], list(bins3), labels=labels)], axis=1
).head(20)
Квантильное разделение данных на 3 группы
pd.concat(
[starbucks["Volume"], pd.qcut(starbucks["Volume"], q=3, labels=False)], axis=1
).head(20)
pd.concat(
[starbucks["Volume"], pd.qcut(starbucks["Volume"], q=3, labels=labels)], axis=1
).head(20)
конструирование признаков на основе существующих¶
Season - время года (winter, autumn, summer, spring)
Volume - количество проданных акций
Open - цена открытия торгов
Close - цена закрытия
High - наивысшая цена торговли
Low - наименьшая цена торговли
# Создаем признак "Price_change" - изменение цены закрытия по сравнению с предыдущим днем
starbucks["Price_change"] = starbucks["Close"].diff().fillna(0)
# Создаем признак "High_Low_diff" - разница между наивысшей и наименьшей ценой за день
starbucks["High_Low_diff"] = starbucks["High"] - starbucks["Low"]
# Создаем признак "Open_Close_diff" - разница между ценой открытия и закрытия
starbucks["Open_Close_diff"] = starbucks["Open"] - starbucks["Close"]
starbucks = starbucks.drop(
[
"High",
"Low",
"Open",
"Close",
"Season_Autumn",
"Season_Summer",
"Season_Winter",
"Season_Spring",
],
axis=1,
)
# Выводим итоговый DataFrame
print(starbucks)
Предсказательная способность
Price_change: Этот признак может быть полезен для предсказания будущих цен, так как показывает изменение цены закрытия по сравнению с предыдущим днем. Если цена закрытия растет, это может указывать на положительный тренд.
High_Low_diff: Разница между максимальной и минимальной ценой за день может служить индикатором волатильности. Высокая волатильность может указывать на неопределенность на рынке, что может повлиять на будущие цены.
Open_Close_diff: Этот признак показывает, как цена акций себя вела в течение дня. Если цена закрытия значительно отличается от цены открытия, это может указывать на сильные колебания в течение дня.
Volume_category: Объем торгов может быть индикатором интереса инвесторов к акциям. Высокий объем может указывать на сильные движения цен, что также может быть полезно для предсказания.
Скорость вычисления Все предложенные признаки могут быть вычислены быстро, так как они основаны на простых арифметических операциях и использовании встроенных функций библиотеки Pandas. Это делает их подходящими для анализа больших объемов данных.
Надежность Признаки, основанные на исторических данных, как правило, надежны, если данные корректны и не содержат выбросов. Однако, важно учитывать, что прошлые данные не всегда гарантируют будущие результаты, особенно в условиях изменяющегося рынка.
Корреляция Необходимо провести анализ корреляции между признаками и целевой переменной (например, ценой закрытия на следующий день). Высокая корреляция может указывать на то, что признак имеет предсказательную силу. Однако, следует избегать мультиколлинеарности, когда два или более признаков сильно коррелируют между собой.
Целостность Признаки должны быть целостны и не содержат пропусков.
Отсечение значений признаков¶
Определение выбросов с помощью boxplot
starbucks.boxplot(column="Volume")
Отсечение данных для признака Volume, значение которых больше 200000000 т.к. выше этой границы были выбросы
starbucks_norm = starbucks.copy()
starbucks_norm["VolumeClip"] = starbucks["Volume"].clip(0, 200000000)
starbucks_norm[starbucks_norm["Volume"] > 200000000][["Date", "Volume", "VolumeClip"]]
Винсоризация признака
from scipy.stats.mstats import winsorize
print(starbucks_norm[starbucks_norm["Volume"] > 200000000][["Date", "Volume", "VolumeClip"]]
["Volume"].quantile(q=0.95))
starbucks_norm["VolumeWinsorize"] = winsorize(
starbucks_norm["Volume"].fillna(starbucks_norm["Volume"].mean()), (0, 0.05), inplace=False
)
starbucks_norm[starbucks_norm["Volume"] > 200000000][["Date", "Volume", "VolumeWinsorize"]]
Нормализация значений¶
from sklearn import preprocessing
min_max_scaler = preprocessing.MinMaxScaler()
min_max_scaler_2 = preprocessing.MinMaxScaler(feature_range=(-1, 1))
starbucks_norm["VolumeNorm"] = min_max_scaler.fit_transform(
starbucks_norm["Volume"].to_numpy().reshape(-1, 1)
).reshape(starbucks_norm["Volume"].shape)
starbucks_norm["VolumeClipNorm"] = min_max_scaler.fit_transform(
starbucks_norm["VolumeClip"].to_numpy().reshape(-1, 1)
).reshape(starbucks_norm["Volume"].shape)
starbucks_norm["VolumeWinsorizeNorm"] = min_max_scaler.fit_transform(
starbucks_norm["VolumeWinsorize"].to_numpy().reshape(-1, 1)
).reshape(starbucks_norm["Volume"].shape)
starbucks_norm["VolumeWinsorizeNorm2"] = min_max_scaler_2.fit_transform(
starbucks_norm["VolumeWinsorize"].to_numpy().reshape(-1, 1)
).reshape(starbucks_norm["Volume"].shape)
starbucks_norm[
["Date", "Volume", "VolumeNorm", "VolumeClipNorm", "VolumeWinsorizeNorm", "VolumeWinsorizeNorm2"]
].head(20)
Стандартизация значений¶
from sklearn import preprocessing
stndart_scaler = preprocessing.StandardScaler()
starbucks_norm["VolumeStand"] = stndart_scaler.fit_transform(
starbucks_norm["Volume"].to_numpy().reshape(-1, 1)
).reshape(starbucks_norm["Volume"].shape)
starbucks_norm["VolumeClipStand"] = stndart_scaler.fit_transform(
starbucks_norm["VolumeClip"].to_numpy().reshape(-1, 1)
).reshape(starbucks_norm["Volume"].shape)
starbucks_norm["VolumeWinsorizeStand"] = stndart_scaler.fit_transform(
starbucks_norm["VolumeWinsorize"].to_numpy().reshape(-1, 1)
).reshape(starbucks_norm["Volume"].shape)
starbucks_norm[["Date", "Volume", "VolumeStand", "VolumeClipStand", "VolumeWinsorizeStand"]].head(20)
Выводы:
- Предсказательная способность
Нормализация и стандартизация: Эти методы могут улучшить предсказательную способность признаков, так как они приводят данные к единому масштабу. Это особенно важно для алгоритмов, чувствительных к масштабу, таких как K-ближайших соседей или нейронные сети. Признаки, такие как Price_change, High_Low_diff, и Open_Close_diff, могут стать более информативными после этих преобразований.
Винсоризация: Этот метод помогает уменьшить влияние выбросов, что может улучшить предсказательную способность модели, так как она будет менее подвержена искажениям из-за аномальных значений.
- Скорость вычисления Применение нормализации и стандартизации может немного увеличить время вычислений, так как требуется дополнительный шаг для преобразования данных. Однако, в данном случае это незначительное увеличение времени.
Винсоризация также может добавить некоторую вычислительную нагрузку, но она в данном случае незначительна. 3. Надежность
Нормализация и стандартизация могут повысить надежность признаков, так как они уменьшают влияние выбросов и делают данные более однородными. Это может привести к более стабильным и надежным результатам при обучении модели.
Винсоризация помогает устранить аномальные значения, что также способствует повышению надежности. 4. Корреляция
После нормализации и стандартизации корреляции между признаками могут измениться. Это может помочь выявить более сильные связи между признаками и целевой переменной. Однако важно следить за мультиколлинеарностью, так как некоторые признаки могут стать слишком коррелированными.
Винсоризация может помочь уменьшить влияние выбросов на корреляцию, что может привести к более точным оценкам взаимосвязей между признаками. 5. Целостность
Нормализация и стандартизация не влияют на целостность данных, если они применяются корректно. Однако важно следить за тем, чтобы не было пропусков в данных, так как это может повлиять на качество модели.
Винсоризация и отсечение выбросов помогают поддерживать целостность данных, так как они устраняют аномальные значения, которые могут исказить результаты.
Заключение В целом, применение нормализации, стандартизации, винсоризации и отсечения выбросов может значительно улучшить качество признаков для предсказания цен акций Starbucks. Эти методы помогают сделать данные более однородными, надежными и информативными, что в свою очередь может привести к более точным и стабильным результатам при использовании методов машинного обучения.