带有多个时间序列的PCA作为sklearn的一个实例的特征

Min*_* L. 12 python time-series pca scikit-learn

我想在一个具有20个时间序列作为一个实例的特征的数据集上应用PCA。我有大约1000个此类实例,我正在寻找一种降低维数的方法。对于每个实例,我都有一个熊猫数据框,例如:

import pandas as pd
import numpy as np
df = pd.DataFrame(data=np.random.normal(0, 1, (300, 20)))
Run Code Online (Sandbox Code Playgroud)

有没有一种方法可以sklearn.fit所有实例上使用,每个实例都有一组时间序列作为特征空间。我的意思是我可以将sklearn.fit分别应用于所有实例,但是我希望所有实例都具有相同的主要组成部分。

有办法吗?到目前为止,我唯一不满意的想法是将一个实例的所有那些序列附加到一个实例上,这样我就有一个实例的时间序列。

Gio*_*Gio 7

我觉得其他答案并不令人满意。主要是因为您应该考虑数据的时间序列结构和横截面信息。您不能简单地将每个实例的功能视为一个系列。这样做将不可避免地导致信息丢失,并且简单地说,在统计上是错误的。

也就是说,如果你真的需要去 PCA,你至少应该保留时间序列信息

主成分分析

silgon之后,我们将数据转换为一个 numpy 数组:

# your 1000 pandas instances
instances = [pd.DataFrame(data=np.random.normal(0, 1, (300, 20))) for _ in range(1000)]
# transformation to be able to process more easily the data as a numpy array
data=np.array([d.values for d in instances]) 
Run Code Online (Sandbox Code Playgroud)

这使得应用 PCA 的方式更容易:

reshaped_data = data.reshape((1000*300, 20))    # create one big data panel with 20 series and 300.000 datapoints
n_comp=10                                       #choose the number of features to have after dimensionality reduction
pca = PCA(n_components=n_comp)                  #create the pca object       
pca.fit(pre_data)                               #fit it to your transformed data
transformed_data=np.empty([1000,300,n_comp])
for i in range(len(data)):
     transformed_data[i]=pca.transform(data[i])           #iteratively apply the transformation to each instance of the original dataset
Run Code Online (Sandbox Code Playgroud)

最终输出形状:transformed_data.shape: Out[]: (1000,300,n_comp).

PLS

但是,您可以(并且在我看来应该)使用偏最小二乘PLS从特征矩阵构建因子。这也将进一步降低维度。

假设您的数据具有以下形状。T=1000, N=300, P=20.

那么我们有y =[T,1], X =[N,P,T]。

现在,很容易理解,要使其工作,我们需要让我们的矩阵符合乘法。在我们的例子中,我们将有:y =[T,1]=[1000,1], X pca =[T,P*N]=[1000,20*300]

直观地说,我们正在做的是为每个P=20基本特征的每个滞后 ( 299=N-1 )创建一个新特征。

即对于给定的实例i,我们将有这样的事情:

实例i : x 1,i , x 1,i-1 ,..., x 1,ij , x 2,i , x 2,i-1 ,..., x 2,ij ,..., x P,i , x P,i-1 ,..., x P,ijj=1,...,N-1

现在,在 python 中实现 PLS 非常简单。

# your 1000 pandas instances
instances = [pd.DataFrame(data=np.random.normal(0, 1, (300, 20))) for _ in range(1000)]
# transformation to be able to process more easily the data as a numpy array
data=np.array([d.values for d in instances]) 

# reshape your data:
reshaped_data = data.reshape((1000, 20*300))

from sklearn.cross_decomposition import PLSRegression

n_comp=10
pls_obj=PLSRegression(n_components=n_comp)
factorsPLS=pls_obj.fit_transform(reshaped_data,y)[0] 
factorsPLS.shape
Out[]: (1000, n_comp)
Run Code Online (Sandbox Code Playgroud)

PLS在做什么?

为了让事情更容易掌握,我们可以看一下三遍回归过滤器这里的工作论文)(3PRF)。Kelly 和 Pruitt 表明 PLS 只是他们 3PRF 的一个特例:

(三个步骤)

其中Z表示代理矩阵。我们没有这些,但幸运的是凯利和普鲁伊特已经表明我们可以没有它。我们需要做的就是确保回归量(我们的特征)是标准化的,并且在没有截距的情况下运行前两个回归。这样做,代理将被自动选择。

因此,简而言之,PLS 允许您

  1. 实现比 PCA 更进一步的降维。
  2. 在创建因子时,要考虑每个序列的特征和时间序列信息之间的横截面变异性。