首页 > 解决方案 > Python中具有非常高维度的一对多时间序列相关性

问题描述

我的数据库包含输入到我网站的搜索框中的 100 万个唯一术语。

它目前包含两列:“搜索词”(用户请求)和“量”(给定月份对搜索词的请求数)。该数据库被划分为过去 10 年的月度表。平均数量为每月 18 个。如果没有任何用户请求,某些搜索会丢失一些月份分区。

我希望能够分析任何单个术语,以使用 python 快速识别其前 n 个最有意义、相关的术语。

由于它的大小,生成一个完整的相关矩阵在内存和 CPU 方面都是浪费的。

哪种数据框结构和功能最适合python中的这种一对多比较?这个功能是否需要进行任何去趋势?

标签: pythonpandascorrelationcross-correlationpearson-correlation

解决方案


您可以每个月构建完整的相关矩阵,或者可能不完整,但仅以少数对全部的方法列出有趣的术语。这样,您就可以将统计信息保存在文件中。

如果您选择按需获取一对多的相关性,您至少可以构建一个用作缓存的 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]

打印(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

附言

您可能还想研究一个仍然适合每月最大数量的较小数据类型,例如np.int16


推荐阅读