Корреляция временных рядов "один ко многим" в Python с очень большими размерностями - PullRequest
0 голосов
/ 07 августа 2020

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

В настоящее время она содержит два столбца: «поисковый запрос» (запрос пользователя) и «объем» (количество запросов для поисковый запрос, сделанный в данном месяце). База данных разбита на ежемесячные таблицы за последние 10 лет. Средний объем - 18 в месяц. В некоторых поисковых запросах отсутствуют разделы на несколько месяцев, если они не были запрошены пользователями. .

Из-за своего размера создание всей корреляционной матрицы было бы расточительным с точки зрения памяти и ЦП.

Какая структура и функция фрейма данных лучше всего подходят для этого сравнения один-ко-многим в python? И будет ли эта функция требовать проведения детрендинга?

1 Ответ

1 голос
/ 07 августа 2020

Вы можете строить полную матрицу корреляции каждый месяц или, возможно, не полную, а только взяв список интересных терминов по принципу «несколько ко всем». Таким образом, вы сохраняете статистику в файле.

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

Чтобы вычислить корреляцию одного термина со всеми остальными, вы можете использовать DataFrame.corrwith :

Допустим, у вас есть следующий df :

import string

terms_list = [''.join((a, b, c))
            for a in string.ascii_lowercase[:25]
            for b in string.ascii_lowercase[:20]
            for c in string.ascii_lowercase[:20]]
np.random.seed(1)
df = pd.Series(
    np.random.choice(list(np.arange(10, 26)) + [np.nan], int(120e4)),
    index = pd.MultiIndex.from_product([terms_list, range(120)],
        names=['term', 'month'])
    )
df = df.dropna().unstack()
pivot_term = terms_list[0]

print (df)

aaa    15.0  21.0  22.0  18.0  19.0  21.0  15.0  ...   NaN  15.0  23.0  11.0  20.0  10.0  17.0
aab    10.0  24.0  23.0  21.0  16.0  23.0  25.0  ...   NaN  15.0  12.0  11.0  21.0  15.0  19.0
aac    21.0  11.0  10.0  17.0  10.0  12.0  13.0  ...  10.0  10.0  25.0  14.0  20.0  22.0  15.0
aad     NaN  10.0  21.0  22.0  21.0  13.0  22.0  ...  11.0  17.0  12.0  14.0  15.0  17.0  22.0
aae    23.0  10.0  17.0  25.0  19.0  11.0  11.0  ...  10.0  25.0  18.0  16.0  10.0  16.0  11.0
...     ...   ...   ...   ...   ...   ...   ...  ...   ...   ...   ...   ...   ...   ...   ...
ytp    24.0  18.0  16.0  23.0   NaN  19.0  18.0  ...  20.0  15.0  21.0  11.0  14.0  18.0  19.0
ytq    22.0  11.0  17.0  24.0  12.0  20.0  17.0  ...  16.0   NaN  13.0  13.0  18.0  22.0  15.0
ytr    22.0  19.0  20.0  11.0  10.0  20.0  14.0  ...  24.0  21.0   NaN  19.0  10.0  24.0  22.0
yts    22.0   NaN  22.0  17.0  14.0  14.0  25.0  ...  14.0  22.0   NaN  23.0  14.0  25.0  10.0
ytt    17.0  16.0  15.0  21.0  11.0  19.0  16.0  ...  10.0  19.0  19.0  13.0  21.0  18.0  16.0

[10000 rows x 120 columns]

код

t1 = time()
max_periods = 120
df = df.iloc[:, -max_periods:]
### get correlations
corr = df.drop(pivot_term, axis=0).corrwith(df.loc[pivot_term], axis=1)
t1 = time() - t1
print(corr)
print(t1)

Вывод

term
aab    0.045972
aac    0.064941
aad   -0.057009
aae   -0.187645
aaf   -0.075473
         ...
ytp    0.103756
ytq   -0.054769
ytr   -0.115004
yts    0.123223
ytt    0.230628
Length: 9999, dtype: float64
9.76

Отсюда можно отфильтровать интересное условия с corr.nlargest или corr.nsmallest.

PS

Вы также можете изучить меньший тип данных, который по-прежнему соответствует максимальному объему в месяц, например np.int16 .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...