123 KiB
import pandas as pd
data = pd.read_csv("..//static//csv//Yamana_Gold_Inc._AUY.csv", sep=",", nrows=10000)
# Преобразование даты
data['Date'] = pd.to_datetime(data['Date'])
# Преобразование данных: создание новых признаков
data['Day_of_week'] = data['Date'].dt.dayofweek
data['Month'] = data['Date'].dt.month
data['Year'] = data['Date'].dt.year
data .columns
1. Бизнес-цели для набора данных по акции компании Yamana Gold Inc.¶
Цель 1: Прогнозирование изменения цены акции компании. Прогнозирование цен на акции является одной из ключевых задач в области финансов и инвестирования. Задача состоит в предсказании будущих изменений стоимости акции на основе исторических данных, таких как открытие и закрытие торгов, объемы торгов и другие показатели.
Цель 2: Оценка волатильности акций компании. Измерение волатильности позволяет инвесторам оценить риск и принять решения по управлению капиталом. Задача заключается в прогнозировании уровня волатильности на основе исторической динамики цен, объемов торгов и других рыночных факторов.
2. Цели технического проекта для каждой бизнес-цели¶
Цель 1: Прогнозирование изменения цены акции компании
Разработать модель машинного обучения для прогнозирования будущих цен акций на основе исторических данных. Использовать регрессионные модели, такие как линейная регрессия или более сложные модели, например, LSTM (долгосрочная краткосрочная память) для временных рядов. Цель 2: Оценка волатильности акций компании
Создать модель, которая будет прогнозировать волатильность на основе исторических данных о ценах. Использовать методы статистического анализа, такие как вычисление стандартного отклонения, или методы машинного обучения для более точной оценки волатильности.
3 Проверим датасет на пропуски и удалим при необходимости строки с недостающими данными¶
# Проверим на пропущенные значения
data.isnull().sum()
# Заполним пропуски или удалим строки с пропусками
data = data.dropna()
# Проверим, что данные очищены
data.isnull().sum()
Конструирование признаков
# Создаем новый признак - разницу между текущей и предыдущей ценой (Price_Change)
data['Price_Change'] = data['Close'].diff()
# Создадим скользящие средние для 5 и 20 дней
data['SMA_5'] = data['Close'].rolling(window=5).mean()
data['SMA_20'] = data['Close'].rolling(window=20).mean()
# Стандартное отклонение для 5 и 20 дней
data['STD_5'] = data['Close'].rolling(window=5).std()
data['STD_20'] = data['Close'].rolling(window=20).std()
data.head()
Разделение данных на обучающую, контрольную и тестовую выборки
from sklearn.model_selection import train_test_split
# Преобразуем колонку 'Date' в тип datetime для правильного сортирования
data['Date'] = pd.to_datetime(data['Date'])
# Сортируем данные по дате, чтобы не нарушить временную зависимость
data = data.sort_values(by='Date')
# Отделяем целевую переменную (например, Price_Change) и признаки
X = data[['Open', 'High', 'Low', 'Close', 'Adj Close', 'Volume', 'SMA_5', 'SMA_20', 'STD_5', 'STD_20']]
y = data['Price_Change']
# Разделение на обучающую, контрольную и тестовую выборки (60%, 20%, 20%)
X_train, X_temp, y_train, y_temp = train_test_split(X, y, test_size=0.4, shuffle=False)
X_val, X_test, y_val, y_test = train_test_split(X_temp, y_temp, test_size=0.5, shuffle=False)
# Проверка размеров выборок
(X_train.shape, X_val.shape, X_test.shape)
Конструирование признаков для решения задач
# Признаки для задачи прогнозирования изменений цен
data['Price_Change'] = data['Close'].diff()
# Скользящие средние и стандартное отклонение
data['SMA_5'] = data['Close'].rolling(window=5).mean()
data['SMA_20'] = data['Close'].rolling(window=20).mean()
data['STD_5'] = data['Close'].rolling(window=5).std()
data['STD_20'] = data['Close'].rolling(window=20).std()
# Признаки для оценки волатильности
data['Volatility'] = data['Close'].rolling(window=5).std()
Подготовка признаков: one-hot encoding, дискретизация, синтез признаков, масштабирование One-hot encoding: Применим для категориальных признаков (например, день недели). Масштабирование: Стандартизируем числовые признаки.
from sklearn.preprocessing import StandardScaler
import pandas as pd
# Преобразуем дату, если это еще не сделано
data['Date'] = pd.to_datetime(data['Date'])
# Добавим дополнительные признаки (день недели и месяц)
data['Day_of_week'] = data['Date'].dt.dayofweek
data['Month'] = data['Date'].dt.month
# Проверим, что эти столбцы добавлены
print(data[['Day_of_week', 'Month']].head())
# Выбираем признаки и целевую переменную
X = data[['Close', 'SMA_5', 'SMA_20', 'STD_5', 'STD_20', 'Day_of_week', 'Month']]
y = data['Price_Change']
# Применяем one-hot encoding для категориальных признаков (Day_of_week и Month)
X = pd.get_dummies(X, columns=['Day_of_week', 'Month'], drop_first=True)
# Масштабирование числовых признаков (Close, SMA, STD)
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
# Преобразуем обратно в DataFrame для удобства
X_scaled_df = pd.DataFrame(X_scaled, columns=X.columns)
# Проверим результат
X_scaled_df.head()
import featuretools as ft
# Создаем сущности для Featuretools
es = ft.EntitySet(id="stock_prices")
es = es.add_dataframe(dataframe_name="stock_data", dataframe=data, index="Date")
# Автоматическое создание признаков
feature_matrix, feature_defs = ft.dfs(entityset=es, target_dataframe_name="stock_data")
Оценка качества признаков¶
Оценка признаков на основе предсказательной способности модели и других критериев.
# Проверим размеры данных
print(X_scaled_df.shape[0]) # Количество строк в X_scaled_df
print(y_train.shape[0]) # Количество строк в y_train
# Приводим индексы к одному виду
y_train = y_train.reset_index(drop=True)
X_scaled_df = X_scaled_df.reset_index(drop=True)
# После этого продолжим обучение модели
model = LinearRegression()
model.fit(X_scaled_df, y_train)
# Прогнозирование и оценка качества
y_pred = model.predict(X_scaled_df)
# Оценка качества модели
mse = mean_squared_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)
mse, r2
Визуализируем
import matplotlib.pyplot as plt
# Визуализируем фактические и предсказанные значения
plt.figure(figsize=(10,6))
plt.plot(y_test.index, y_test, label='Actual Price Change', color='blue')
plt.plot(y_test.index, y_pred, label='Predicted Price Change', color='red')
plt.legend()
plt.title("Actual vs Predicted Price Change")
plt.xlabel("Date")
plt.ylabel("Price Change")
plt.show()