208 KiB
Датасет: Tesla Insider Trading.¶
Описание датасета:¶
Датасет представляет собой выборку операций с ценными бумагами компании Tesla, совершённых инсайдерами, и является частью более крупного проекта "Insider Trading S&P500 – Inside Info". Данные охватывают транзакции с участием крупных акционеров и должностных лиц компании, включая такие операции, как покупка, продажа и опционы, начиная с 10 ноября 2021 года и до 27 июля 2022 года.
Анализ сведений:¶
Проблемная область: Проблемная область данного датасета касается анализа инсайдерских сделок в публичных компаниях, а также их влияния на ценообразование акций. Инсайдерские транзакции, совершаемые людьми с доступом к непубличной информации (такими как руководители, крупные акционеры или члены совета директоров), могут быть индикаторами будущих изменений стоимости акций. Исследование таких транзакций помогает понять, как информация внутри компании отражается в действиях ключевых участников, и может выявить паттерны поведения, которые влияют на рынки.
Актуальность: Анализ инсайдерских сделок становится особенно важным в условиях высокой волатильности рынка и неопределенности. Инвесторы, аналитики и компании используют такие данные, чтобы лучше понимать сигналы от крупных акционеров и должностных лиц. Действия инсайдеров, такие как покупки и продажи акций, нередко рассматриваются как индикаторы доверия к компании, что может оказывать значительное влияние на рыночные ожидания и прогнозы.
Объекты наблюдений: Объектами наблюдений в датасете являются инсайдеры компании Tesla — лица, имеющие значительное влияние на управление и информацию компании. Каждый объект характеризуется различными параметрами, включая должность, тип транзакции, количество акций и общую стоимость сделок.
Атрибуты объектов:
- Insider Trading: ФИО лица, совершившего транзакцию.
- Relationship: Должность или статус данного лица в компании Tesla.
- Date: Дата завершения транзакции.
- Transaction: Тип транзакции.
- Cost: Цена одной акции на момент совершения транзакции.
- Shares: Количество акций, участвующих в транзакции.
- Value ($): Общая стоимость транзакции в долларах США.
- Shares Total: Общее количество акций, принадлежащих этому лицу после завершения данной транзакции.
- SEC Form 4: Дата записи транзакции в форме SEC Form 4, обязательной для отчётности о сделках инсайдеров.
Выгрузка данных из файла в DataFrame:¶
import pandas as pd
from pandas import DataFrame
df: DataFrame = pd.read_csv("..//static//csv//TSLA.csv")
# Преобразование типов данных
df["Insider Trading"] = df["Insider Trading"].astype("category") # Преобразование в категорию
df["Relationship"] = df["Relationship"].astype("category") # Преобразование в категорию
df["Transaction"] = df["Transaction"].astype("category") # Преобразование в категорию
df["Cost"] = pd.to_numeric(df["Cost"], errors="coerce") # Преобразование в float
df["Shares"] = pd.to_numeric(df["Shares"].str.replace(",", ""), errors="coerce") # Преобразование в float с удалением запятых
df["Value ($)"] = pd.to_numeric(df["Value ($)"].str.replace(",", ""), errors="coerce") # Преобразование в float с удалением запятых
df["Shares Total"] = pd.to_numeric(df["Shares Total"].str.replace(",", ""), errors="coerce") # Преобразование в float с удалением запятых
Краткая информация о DataFrame:¶
# Краткая информация о DataFrame
df.info()
# Статистическое описание числовых столбцов
df.describe().transpose()
Выбор входных данных и целевого признака:¶
Входные данные:
- Transaction (Тип транзакции): Категориальная переменная, указывающая на тип операции (Sale, Option Exercise).
- Shares (Количество акций): Числовая переменная, указывающая количество акций в транзакции.
- Value ($): Числовая переменная, представляющая общую стоимость транзакции.
Целевой признак:
Cost (Цена акции): Числовая переменная, показывающая стоимость одной акции на момент совершения транзакции.
Определение лингвистических переменных:¶
Лингвистическая переменная – это переменная, значениями которой являются слова или фразы вместо чисел. Она используется в нечеткой логике и теории нечетких множеств для описания понятий, которые нельзя точно выразить числовыми значениями.
Для каждой переменной определим количество термов, типы и параметры функций принадлежности.
import numpy as np
from skfuzzy import control as ctrl
transaction = ctrl.Antecedent(np.arange(0, 2, 1), "Transaction")
shares = ctrl.Antecedent(np.arange(0, 12000000, 1), "Shares")
value = ctrl.Antecedent(np.arange(0, 2.3e9, 1e6), "Value")
cost = ctrl.Consequent(np.arange(0, 1200, 1), "Cost")
Определение нечетких переменных:¶
import skfuzzy as fuzz
transaction["Option Exercise"] = fuzz.trimf(transaction.universe, [0, 0, 1])
transaction["Sale"] = fuzz.trimf(transaction.universe, [0, 1, 1])
transaction.view()
# shares["Few"] = fuzz.zmf(shares.universe, 0, 20000)
# shares["Moderate"] = fuzz.trimf(shares.universe, [10000, 50000, 500000])
# shares["Many"] = fuzz.smf(shares.universe, 400000, 12000000)
shares.automf(3, names=["Few", "Moderate", "Many"])
shares.view()
# value["Low"] = fuzz.zmf(value.universe, 0, 5e7)
# value["Medium"] = fuzz.trimf(value.universe, [5e7, 1e8, 1e9])
# value["High"] = fuzz.smf(value.universe, 1e9, 2.3e9)
value.automf(3, names=["Low", "Medium", "High"])
value.view()
# cost["Low"] = fuzz.zmf(cost.universe, 0, 300)
# cost["Medium"] = fuzz.trimf(cost.universe, [250, 500, 750])
# cost["High"] = fuzz.smf(cost.universe, 700, 1200)
cost.automf(3, names=["Low", "Medium", "High"])
cost.view()
Определение нечётких правил:¶
rule1 = ctrl.Rule(transaction["Option Exercise"] & shares["Few"] & value["Low"], cost["Low"])
rule2 = ctrl.Rule(transaction["Option Exercise"] & shares["Few"] & value["Medium"], cost["Low"])
rule3 = ctrl.Rule(transaction["Option Exercise"] & shares["Few"] & value["High"], cost["Medium"])
rule4 = ctrl.Rule(transaction["Option Exercise"] & shares["Moderate"] & value["Low"], cost["Low"])
rule5 = ctrl.Rule(transaction["Option Exercise"] & shares["Moderate"] & value["Medium"], cost["Medium"])
rule6 = ctrl.Rule(transaction["Option Exercise"] & shares["Moderate"] & value["High"], cost["High"])
rule7 = ctrl.Rule(transaction["Option Exercise"] & shares["Many"] & value["Low"], cost["Medium"])
rule8 = ctrl.Rule(transaction["Option Exercise"] & shares["Many"] & value["Medium"], cost["High"])
rule9 = ctrl.Rule(transaction["Option Exercise"] & shares["Many"] & value["High"], cost["High"])
rule10 = ctrl.Rule(transaction["Sale"] & shares["Few"] & value["Low"], cost["Low"])
rule11 = ctrl.Rule(transaction["Sale"] & shares["Few"] & value["Medium"], cost["Low"])
rule12 = ctrl.Rule(transaction["Sale"] & shares["Few"] & value["High"], cost["Medium"])
rule13 = ctrl.Rule(transaction["Sale"] & shares["Moderate"] & value["Low"], cost["Low"])
rule14 = ctrl.Rule(transaction["Sale"] & shares["Moderate"] & value["Medium"], cost["Medium"])
rule15 = ctrl.Rule(transaction["Sale"] & shares["Moderate"] & value["High"], cost["High"])
rule16 = ctrl.Rule(transaction["Sale"] & shares["Many"] & value["Low"], cost["Medium"])
rule17 = ctrl.Rule(transaction["Sale"] & shares["Many"] & value["Medium"], cost["High"])
rule18 = ctrl.Rule(transaction["Sale"] & shares["Many"] & value["High"], cost["High"])
# Всё ещё не нравится
Создание нечеткой системы:¶
fuzzy_rules: list[ctrl.Rule] = [
rule1,
rule2,
rule3,
rule4,
rule5,
rule6,
rule7,
rule8,
rule9,
rule10,
rule11,
rule12,
rule13,
rule14,
rule15,
rule16,
rule17,
rule18,
]
# Создание системы управления
cost_ctrl = ctrl.ControlSystem(fuzzy_rules)
# Стимуляция системы управления
cost_sim = ctrl.ControlSystemSimulation(cost_ctrl)
fuzzy_rules
Тестирование нечёткой системы:¶
from sklearn.model_selection import train_test_split
# Функция для предсказания значений
def predict_value(row):
cost_sim.input["Transaction"] = row["Transaction"]
cost_sim.input["Shares"] = row["Shares"]
cost_sim.input["Value"] = row["Value ($)"]
cost_sim.compute()
return cost_sim.output["Cost"]
# Выбор нужных столбцов
data: DataFrame = df[["Transaction", "Shares", "Value ($)", "Cost"]]
# Разделение данных на обучающую и тестовую выборки (80% / 20%)
train_data, test_data = train_test_split(data, test_size=0.2, random_state=42)
# Применение модели к обучающей выборке
train_data["Predicted cost"] = train_data.apply(predict_value, axis=1)
display(train_data.head(15))
# Применение модели к тестовой выборке
test_data["Predicted cost"] = test_data.apply(predict_value, axis=1)
display(test_data.head(15))
Оценка результатов на метриках:¶
~ Спустя n часов, проведенных в попытках улучшить показатели метрик и танцев с бубном вокруг настройки параметров лингвистических переменных я сдался.
import math
from typing import Union
from numpy import ndarray
from sklearn import metrics
metrics_results: dict[str, Union[float, ndarray]] = {}
metrics_results["RMSE_train"] = math.sqrt(
metrics.mean_squared_error(train_data["Cost"], train_data["Predicted cost"])
)
metrics_results["RMSE_test"] = math.sqrt(
metrics.mean_squared_error(test_data["Cost"], test_data["Predicted cost"])
)
metrics_results["RMAE_test"] = math.sqrt(
metrics.mean_absolute_error(test_data["Cost"], test_data["Predicted cost"])
)
metrics_results["R2_test"] = metrics.r2_score( # type: ignore
test_data["Cost"], test_data["Predicted cost"]
)
metrics_results