Группировка похожих данных для максимизации внутригрупповой корреляции и минимизации межгрупповой корреляции

Так что это моя проблема. У меня есть ежедневные данные о доходах 2000 акций, и ниже приводится небольшая их выборка (от s1 до s8, от дня1 до дня15)

Я назову мои данные "DF".

> df[1:15,1:8]
          s1        s2         s3         s4        s5        s6        s7        s8
1  -0.026410 -0.001030 -0.0027660  0.0126500 -0.030110  0.001476 -0.008271 -0.005299
2  -0.018990 -0.013680 -0.0092050 -0.0008402 -0.002739 -0.014170 -0.006091 -0.011920
3   0.004874  0.024140 -0.0002107 -0.0084770 -0.006825 -0.001448 -0.002724 -0.003132
4   0.019300 -0.004649  0.0223400  0.0080200 -0.008197 -0.015270  0.004064 -0.008149
5   0.010350 -0.010650  0.0087780  0.0059960 -0.001390 -0.006454  0.018990  0.002822
6   0.028650  0.010490  0.0157200 -0.0004123  0.019750 -0.005902  0.004261  0.019110
7   0.004203 -0.002682 -0.0099840 -0.0070060 -0.025670 -0.014550 -0.016700 -0.011580
8  -0.042170 -0.019490 -0.0023140 -0.0083030 -0.018170  0.021160 -0.006864 -0.009438
9   0.017250  0.026600  0.0031630 -0.0069090  0.035990  0.008429  0.001500 -0.011830
10 -0.037400 -0.022370  0.0088460  0.0012690 -0.050820 -0.025300 -0.028040 -0.023790
11 -0.091140 -0.018830  0.0052160 -0.0403000  0.001410 -0.007050 -0.024340 -0.013110
12 -0.051620  0.004791  0.0336000 -0.0094320 -0.018320 -0.019490 -0.044080 -0.024020
13  0.007711  0.002158 -0.0177400  0.0090470 -0.004346 -0.001562 -0.096030  0.015840
14  0.041440 -0.001072 -0.0168400  0.0180300 -0.012980 -0.015280  0.059780  0.014730
15 -0.042620 -0.025560 -0.0180200 -0.0115200  0.033320 -0.015150 -0.014580 -0.012710

Мне нужен способ сгруппировать их так, чтобы внутригрупповая корреляция была максимальной, а межгрупповая корреляция - минимальной.

Так, например, я могу случайным образом сгруппировать их в две группы следующим образом: (s1, s2, s3, s4) и (s5, s6, s7, s8). Проблема в том, что некоторые акции могут быть связаны друг с другом, и некоторые не могут.

Поэтому мое решение было:

получить матрицу корреляции (при условии, что метод Пирсона работает нормально)

cor_df <- cor(df)

растопить (сгладить) список корреляции в порядке убывания и удалить дубликаты и строки с коэффициентом корреляции = 1 (использованная библиотека изменения формы)

cor_df_melt <- melt(cor_df)
names(cor_df_melt)[1] <- "x1"
names(cor_df_melt)[2] <- "x2"
names(cor_df_melt)[3] <- "corr"
cor_df_ordered <- cor_df_melt[order(-cor_df_sample_melt["corr"]),]

Затем я пронумеровал уплощенную матрицу, удалил дубликаты (даже пронумерованные) и строки с коэффициентом корреляции = 1

cor_df_numbered <- cbind(row=c(1:nrow(cor_df_ordered)),cor_df_ordered)
cor_df_ready <- cor_df_numbered[cor_df_numbered$row%%2==0&cor_df_numbered$corr%%2!=1,2:4]

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

> cor_df_ready
   x1 x2       corr
63 s7 s8 0.49223783
57 s1 s8 0.42518667
50 s2 s7 0.42369762
49 s1 s7 0.40824283
58 s2 s8 0.40395569
42 s2 s6 0.40394894
54 s6 s7 0.39408677
62 s6 s8 0.38536734
34 s2 s5 0.36882709
53 s5 s7 0.36066870
45 s5 s6 0.35734278
59 s3 s8 0.34295713
51 s3 s7 0.34163733
61 s5 s8 0.33264868
9  s1 s2 0.32812763
41 s1 s6 0.31221715
18 s2 s3 0.30692909
43 s3 s6 0.29390325
33 s1 s5 0.28845243
35 s3 s5 0.27859972
17 s1 s3 0.25039209
52 s4 s7 0.12989487
60 s4 s8 0.12095196
25 s1 s4 0.10902471
26 s2 s4 0.09471694
44 s4 s6 0.08039435
36 s4 s5 0.06957264
27 s3 s4 0.06027389

(кстати, я понятия не имею, почему номер строки так неупорядочен... кто-нибудь может объяснить?)

Отсюда моя интуиция была для старшей пары с наивысшим коэффициентом корреляции 0,49223783 (s7, s8), они должны были быть в одной группе.

Итак, из моего фрейма данных cor_df_ready я выбрал все пары с включенным "s7", извлек 4 акции, которые появляются вверху списка (s7, s8, s2, s1) и назвал их группой 1.

Затем я исключил все строки, включая (s7, s8, s2, s1) из моего cor_df_ready, и повторил процесс, чтобы создать вторую группу (s3, s4, s5, s6).

в этом примере мне не нужно было повторять процесс, так как остался только один последний сет.

Затем я получил матрицу корреляции для каждой группы и добавил сумму каждого коэффициента корреляции:

group1_cor <- cor(group1)
group2_cor <- cor(group2)

cor_sum <- sum(group1_cor) + sum(group2_cor)

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

Наконец, я рассчитал для: cor_sum_mean/cor_sum

Интуиция заключалась в том, что максимизированная корреляция внутри группы максимизирует cor_sum, где минимизированная корреляция между группами также минимизирует cor_sum_mean.

Я хочу получить как можно больше cor_sum (внутригрупповая корреляция) и как можно меньше cor_sum_mean (внутригрупповая корреляция).

Используя мой метод для полных данных, я разделил 2000 акций на 10 групп, и я получил

#cor_sum = 131923.1
#cor_sum_mean = 83.1731
#cor_sum_mean/cor_sum = 0.0006305

Я ЗНАЮ, что могу получить cor_sum_mean / cor_sum до 0,000542 (или даже меньше), но я просто застрял.

Я искал в google, stackru, crossvalidated, и у меня появилась идея, что машинное обучение / кластеризация / классификация временных рядов могут быть ответом, который я ищу.

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

https://stats.stackexchange.com/questions/9475/time-series-clustering/19042

https://stats.stackexchange.com/questions/3238/time-series-clustering-in-r

Может кто-нибудь объяснить или направить меня, что искать в конкретных?

Это был длинный вопрос... Спасибо за чтение!

1 ответ

Используйте иерархическую кластеризацию.

При средней связи вы оптимизируете среднюю корреляцию.

Другие вопросы по тегам