Машинное обучение в трейдинге: теория, модели, практика и алготорговля - страница 3516

 

Сделал немного визуализации, для лучшего понимания процесса ухудшения результатов модели.

Ниже представлен график, на котором ZZ по балансу взвешенных ошибки квантового отрезка на выборке train.


Видно, что в целом тенденция хорошая, положительное смещение вероятности, а что же на двух следующих выборках - test и exam?

Ниже графики на этих выборках.

Наблюдаем флэт и к конце периода тренд на положительное смещение вероятности. Скорей всего модель, с участием этого квантового отрезка остановим - не дождавшись подъёма.

А что ждёт дальше?

На выборке exam, подъём продолжился в начале, но опять всё свалилось во флэт. Как же так получается, что на train был длительный тренд, а в последствии видим эпизодические всплески - нечто изменилось? Остаётся только гадать - или делать дополнительный сплит по другому квантовому отрезку, но как его сделать на train. ведь там уже не плохо всё - загадка.

Но, бывает, что удаётся найти и вполне сносные варианты, вот к примеру - сразу три выборки ниже.

Мысли, идеи, соображения - приветствуются!

 
Aleksey Vyazmikin #:
Мысли, идеи, соображения - приветствуются!

Если train переобучен, значит меньше обучать.

 

Есть, в общем-то, простая до гениальности вещь, которая позволяет определить, будет ли ваше МО работать на новых данных.

Для этого достаточно иметь только набор меток :) Потому что они являются бинаризованным представлением исходного ряда.

def calculate_entropy(series):
  """
  Calculates the entropy of a binary series using Shannon's formula.

  Args:
      series: A list of binary values (0s and 1s).

  Returns:
      The entropy of the series (float value).
  """
  counts = {0: 0, 1: 0}
  for bit in series:
    counts[bit] += 1
  total_length = len(series)
  probabilities = {key: value / total_length for key, value in counts.items()}
  entropy = 0
  for p in probabilities.values():
    if p > 0:  # Avoid log2(0) which is undefined
      entropy += -p * math.log2(p)
  return entropy
 
Forester #:

Если train переобучен, значит меньше обучать.

Я удивляюсь, если меня не слышат, то и других не слышат - значит каждый разговаривает тут сам с собой.

Я же написал про квантовый отрезок - фактически диапазон любого предиктора - другого тут нет. Берём диапазон, берём все нули и единицы из выборки - взвешиваем их для сбалансированности и строим баланс - если метка "1", то +1, если "0", то -1*К_Балансировки.

Фактически это график изменения смещения вероятности в динамике - по хронологии выборки.

 
Maxim Dmitrievsky #:

посмотри у себя, вроди не пустышка, по моим первым тестам

 
Maxim Dmitrievsky #:

Есть, в общем-то, простая до гениальности вещь, которая позволяет определить, будет ли ваше МО работать на новых данных.

Для этого достаточно иметь только набор меток :) Потому что они являются бинаризованным представлением исходного ряда.

Нужны пруфы с графиками :)

 

Такой вот эксперимент для наглядности, говорящий о том, что относительно даже хорошая классификация не даст гарантированно прибыль.

В коде массив (sequence) из "-1" - убыток и "1" - прибыль, в сумме дающие ноль. Но есть и два нормальных распределения - из одного извлекаем убыточный фин результат, а из другого прибыльный.

Эксперимент проводим 100 раз и наблюдаем разные графики баланса и гистограмму их распределения.

По умолчанию распределение для прибыли больше, чем для убытков, можете поиграть с разными вариантами - код ниже. У меня нет фиксированных стоп уровней, поэтому такой эксперимент очень наглядно показывает, что модель нельзя оценивать только по балансу или только по метрикам классификации, нужен некий комплексный критерий.

import numpy as np
import matplotlib.pyplot as plt

# Параметры нормальных распределений
mean_N1, std_N1 = -50, 25  # для первого распределения (от -100 до 0)
mean_N2, std_N2 = 100, 25  # для второго распределения (от 0 до 200)

# Заданная последовательность
sequence = np.array([1, 1, -1, 1, 1, -1, -1, -1, 1, -1])

# Количество экспериментов
num_experiments = 100

# Массив для сохранения результатов баланса
balances = []

# Проведение экспериментов
for _ in range(num_experiments):
    values = np.where(sequence == 1, np.random.normal(mean_N2, std_N2, len(sequence)), np.random.normal(mean_N1, std_N1, len(sequence)))
    balance = np.cumsum(values)  # Используем кумулятивную сумму для отслеживания баланса на каждом этапе
    balances.append(balance)

# Визуализация балансов
plt.figure(figsize=(12, 6))

# Построение графиков баланса
plt.subplot(1, 2, 1)
for i, balance_curve in enumerate(balances):
    plt.plot(balance_curve, label=f'Experiment {i + 1}', alpha=0.7)  # Используем alpha для прозрачности
plt.title('Balances Over Experiments')
plt.xlabel('Step')
plt.ylabel('Balance')
#plt.legend()

# Построение гистограммы распределения итоговых балансов
plt.subplot(1, 2, 2)
final_balances = [balance[-1] for balance in balances]
plt.hist(final_balances, bins=20, color='skyblue', edgecolor='black')
plt.title('Distribution of Final Balances')
plt.xlabel('Balance')
plt.ylabel('Frequency')

plt.tight_layout()
plt.show()
 
СанСаныч Фоменко #:
lstm работает с радикально разбалансированными классами - для 2 классов в десятки раз?

Сбросьте выборку, как минимум оценю потенциал для обучения своим методом.

 
Aleksey Vyazmikin #:

Нужны пруфы с графиками :)

Пруфов пока нет, потому что делаю случайный семплинг и энтропия такого ряда всегда стремится к 1, то есть рэндом

Причина обращения: