Обсуждение статьи "Продвинутый ресемплинг и выбор CatBoost моделей брутфорс методом" - страница 14

 
mytarmailS:

Кароч не знаю, может у меня не такой gmm )) Но я не вижу разницы что с ним что без него, по моему все решает целевая и больше ничего...


всего данных у меня 60к

беру первые 10к и рендомно выбираю из них 500 точек 

на них обучаю либо сразу модель  либо обучаю gmm и потом обучаю модель 

тестирую на оставшихся  50к

 

И даже обычным способом можно находить такие модели  как и с     gmm , и с такой же частотой они гененрируються

вот например 

модель  без  gmm обучена по 500 точкам , тест на 50к 


=================================================================================================

Увидел интересную вещь над которой есть смысл подумать...

Есть такая точка зрения что рынок надо разбить на состояния и торговать в каждом состоянии свою стратегию, но все известные мне попытки были без успешными, либо состояния не виделить либо модель торгует плохо даже в "типа одном" состоянии

  А вот в этом подходе довольно четко видно какой рынок модель "любит" , а какой нет

Наверное из- за ретурнов от машки в качестве признаков  модель лучше работает во флете

Можно вручную разделить на состояния и подмешать в трейн эти периоды. Нужна балансировка примеров по ‘состояниям’, либо сделать искусственных через гмм. Да как так, у меня не получалось на голой модели таких результатов. Может быть несколько Машек такое дают.
 
Maxim Dmitrievsky:
Можно вручную разделить на состояния и подмешать в трейн эти периоды. Нужна балансировка примеров по ‘состояниям’, либо сделать искусственных через гмм

Да, можно  HMM сделать по состояниям , но это все будет распознаваться скользящим окном , а значит с запаздыванием на размер окна , а значит ..... )

Просто увидел что тут реально четко видны состояния , показалось интересным

 
mytarmailS:

Да, можно  HMM сделать по состояниям , но это все будет распознаваться скользящим окном , а значит с запаздыванием на размер окна , а значит ..... )

Просто увидел что тут реально четко видны состояния , показалось интересным

Трендов обычно меньше чем флэтов, поэтому мне кажется что всегда так будет, надо семплить их. Через ту же кластеризацию можно разделить на состояния.
 
Maxim Dmitrievsky:
. Да как так, у меня не получалось на голой модели таких результатов. Может быть несколько Машек такое дают.

А это уже с гмм было, я пробую по разному, то так то так

 
Maxim Dmitrievsky:

У меня есть навязчивая идея , создать обучающую выборку методом оптимизации из распределений или функций

Те не отталкиваясь вообще ни от какой выборки, просто генерим "как то" и тестим на реал. данных

Но пока не знаю как это реализовать 

=====================================================

так же есть идея улучшить качество путем удаления плохих деревьев из модели, это тоже может помочь

 
mytarmailS:

У меня есть навязчивая идея , создать обучающую выборку методом оптимизации из распределений или функций

Те не отталкиваясь вообще ни от какой выборки, просто генерим "как то" и тестим на реал. данных

Но пока не знаю как это реализовать 

=====================================================

так же есть идея улучшить качество путем удаления плохих деревьев из модели, это тоже может помочь

Это ты в дебри стохастического моделирования хочешь войти
 
Maxim Dmitrievsky:

Любопытный подход. Для балансировки классов. Можно как-то обыграть для наших целей. Просто попалось на глаза.

https://towardsdatascience.com/augmenting-categorical-datasets-with-synthetic-data-for-machine-learning-a25095d6d7c8

Неплохо, Вам, так попалось на глаза.   Я попробовал интегрировать в кластеризатор из статьи этот подход, только не в качестве метода балансировки классов, а как генератор нового сбалансированного датасета. 

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

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

https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.mahalanobis.html

для расчета этого показателя  нужно 2 одномерных массива и ковариационная матрица.

В нашем случае, первый массив это сгенерированный признак, второй массив средних распределений признаков из GMM. Ковариационная матрица тоже берется из GMM. GMM готовится для каждого класса отдельно. Еще генерится, средние,  стандартные отклонения для каждого признака и меток. Они нужны для генерации новых данных. 

import numpy.linalg as lnalg
from scipy.spatial.distance import mahalanobis

#initialization 
gmms = dict()
desc_df = list()
inv_sig = dict()
arr_classes = np.sort(X.labels.unique())
cols = X.columns.tolist()
pr_c = add_labels(pr.copy(), min=60, max=120, add_noize=0.0)
X = pr_c[pr_c.columns[2:]]
x_train = X.copy()

#create descriptive statistics, train gmm, extract means and covariances for each classes
for ind, cls in enumerate(arr_classes):

    desc_df.append(x_train[x_train['labels'] == cls].describe())

    x_trainGMM = x_train[x_train['labels'] == cls].values[:, :-1]
    gmm = mixture.GaussianMixture(n_components=1, covariance_type='full').fit(x_trainGMM)
    gmms[cls] = (gmm.means_, gmm.covariances_)

    # invert the matrix for mahalanobis calc
    mu, sig = gmms[cls]
    isig = lnalg.inv(sig)
    inv_sig[cls] = mu, isig

Все готово для генерации и выбора новых данных. Ниже случайным образом на основе среднего и отклонения, генерируется признаки для каждого класса в количестве большем в 60 раз чем задано. Это необходимо чтобы было из чего выбрать. Ну и метки приводятся к состоянию 0 -1

 def brute_force(samples=5000):
    import numpy.linalg as lnalg
    gen = []

    for index_cl, cls in enumerate(arr_classes):

        dlt = samples * 60
        sub_arr = np.zeros((dlt, len(cols), 1))
        
        #generate samples ahd lables for cls class
        col_counter = 0
        for col in cols:
            sub_arr[:, col_counter] = np.random.normal(loc=desc_df[index_cl][col]['mean'],
                                                       scale=desc_df[index_cl][col]['std'],
                                                       size=(dlt, 1)
                                                       )
            col_counter += 1
        sub_arr = sub_arr.reshape((sub_arr.shape[:-1]))

        #normalization lables
        sub_arr[-1] = np.where(sub_arr[-1] >= 0.5, 1, 0)

        mh = np.zeros((arr_classes.shape[0]))
        counter = 0

        #selection of the most successful samples
        for index, i in enumerate(sub_arr):
            for m_index, m_cls in enumerate(arr_classes):
                mu, isig = inv_sig[m_cls]
                mh[m_index] = mahalanobis(i[:-1], mu, isig)
            
            #if gmm assignment the same as the original label add in gen
            if np.argmin(mh) == i[-1]:
                gen = np.append(gen, i)
                counter += 1
            if counter == int(samples / 2):
                break


...

После для каждого обраца вычисляется показатель расстояния Махаланобиса, в отношении массивов средних распределений GMM для  обоих классов. получается массив из 2 значений которые показывают близость сгенерированного образца к обоим классам. минимальное значение покажет к какому. Eсли метка с ним совпадает, добавляем её в обучающую выборку. Ну и когда выборка заполнится до заданного значения переходим к следующему классу.  Так получается идеально сбалансированная выборка. 

Но это не отменяет танцев с бубном, и сложные отношения со случайностью. Но если постораться можно получить норм результат:

Будут силы и время, попробую в генераторе  посечь распределения признаков от 25 до 75 квантили, может это даст что нибудь

Еще попробовал использовать показатель расстояния для оценки выбора целевой - признаков. Идея заключалась в том что при правильно подобранных метках  и целевых среднее значение этого показателя будет уменьшаться. 

results = np.zeros(x_train.shape[0])
mh = np.zeros((arr_classes.shape[0]))
for index, i in enumerate(x_train.to_numpy()):
    for m_ind, m_cls in enumerate(arr_classes):
        mu, isig = inv_sig[m_ind]
        mh[m_ind] = mahalanobis(i[:-1], mu, isig)

    if np.argmin(mh) == i[-1]:
        results[index] = mh[np.argmin(mh)]

acc = results.sum() / results.shape[0]

print('Accuracy:', acc)

Прогнал все имеющиеся у меня "удачные" комбинации целевой и признаков а так же воспроизводимиые "неудачные" комбинации. При таком беглом анализе показатель уменьшается для удачных и увеличивается для неудачных вариантов. Возможно есть какая то корреляция. но надо проверять. Если у вас есть какой нибудь релиз сканера по сетке  или ГА, то можно проверить

 
welimorn:

Неплохо, Вам, так попалось на глаза.   Я попробовал интегрировать в кластеризатор из статьи этот подход, только не в качестве метода балансировки классов, а как генератор нового сбалансированного датасета. 

Прогнал все имеющиеся у меня "удачные" комбинации целевой и признаков а так же воспроизводимиые "неудачные" комбинации. При таком беглом анализе показатель уменьшается для удачных и увеличивается для неудачных вариантов. Возможно есть какая то корреляция. но надо проверять. Если у вас есть какой нибудь релиз сканера по сетке  или ГА, то можно проверить

Пока нет сканера. Отлично, нужно будет посмотреть внимательно. Я пока собирал информацию о дополнительных подходах, которые могут улучшить модель (помимо кодеров). Возможно, скоро оформлю статью.

 
Maxim Dmitrievsky:

Пока нет сканера. Отлично, нужно будет посмотреть внимательно. Я пока собирал информацию о дополнительных подходах, которые могут улучшить модель (помимо кодеров). Возможно, скоро оформлю статью.

К Вами вышеупомянутому объединению удачных моделей в процессе поиска, я попробовал объединять удачные модели с разными признаками. Этот прием выравнивает просадку на некоторых участках истории. Еще было замечено, что добавление моделей с R^2 от 0.65 улучшает результаты, даже при наличии моделей с R^2 0.85-0.95.

 
welimorn:

К Вами вышеупомянутому объединению удачных моделей в процессе поиска, я попробовал объединять удачные модели с разными признаками. Этот прием выравнивает просадку на некоторых участках истории. Еще было замечено, что добавление моделей с R^2 от 0.65 улучшает результаты, даже при наличии моделей с R^2 0.85-0.95.

Да, но часто за счет снижения кол-ва сделок на 10-20%