我的形状(n_samples, n_steps, n_features)
中有一个 tensor 。我想将其分解为形状(n_samples, n_components)
的张量。
我需要一种具有.fit(...)
的分解方法,以便我可以将相同的分解应用于新批次的样本。我一直在关注Tucker Decomposition和PARAFAC Decomposition,但它们都没有那个至关重要的.fit(...)
和.transform(...)
功能。 (或者至少我认为他们没有?)
我可以使用PCA并在代表性样本上训练它,然后在剩余的样本上调用.transform(...)
,但我宁愿进行某种张量分解,它可以同时处理所有样本,从而更好地了解每个样本之间的差异。
这就是我所说的“张量”:
事实上,张量只是标量和向量的推广;标量是零秩张量,矢量是第一级张量。张量的等级(或顺序)由描述它所需的方向数(以及因此数组的维数)定义。
如果您有任何疑问,请询问,如果需要,我会尽力澄清我的问题。
编辑:最好的解决方案是某种类型的内核,但我还没有找到可以处理n级张量而不仅仅是2D数据的内核
答案 0 :(得分:0)
您可以使用TensorLy的开发(主版)版本执行此操作。具体来说,您可以使用新的partial_tucker
函数(文档中尚未更新...)。
请注意,以下解决方案保留了张量的结构,即形状(n_samples, n_steps, n_features)
的张量被分解为(较小的)形状(n_samples, n_components_1, n_components_2)
的张量。
简短的回答:这是一个非常基本的类,可以完成您想要的任务(并且可以在任意顺序的张量上工作)。
import tensorly as tl
from tensorly.decomposition._tucker import partial_tucker
class TensorPCA:
def __init__(self, ranks, modes):
self.ranks = ranks
self.modes = modes
def fit(self, tensor):
self.core, self.factors = partial_tucker(tensor, modes=self.modes, ranks=self.ranks)
return self
def transform(self, tensor):
return tl.tenalg.multi_mode_dot(tensor, self.factors, modes=self.modes, transpose=True)
给定输入张量,您可以使用前一个类,首先使用所需的等级(核心张量的大小)和执行分解的模式进行实例化(在3D情况下,1和2,因为索引开始于零):
tpca = TensorPCA(ranks=[4, 5], modes=[1, 2])
tpca.fit(tensor)
给定一个最初称为new_tensor
的新张量,您可以使用transform
方法进行投影:
tpca.transform(new_tensor)
让我们通过一个例子来看看代码:首先让我们导入必要的位:
import numpy as np
import tensorly as tl
from tensorly.decomposition._tucker import partial_tucker
然后我们生成一个随机张量:
tensor = np.random.random((10, 11, 12))
下一步是沿着它的第二维和第三维或模式分解它(因为第一个维度对应于样本):
core, factors = partial_tucker(tensor, modes=[1, 2], ranks=[4, 5])
核心对应于变换的输入张量,而factors
是两个投影矩阵的列表,一个用于第二模式,一个用于第三模式。给定一个新的张量,你可以通过投影它的最后两个维度将它投影到同一个子空间(transform
方法):
tl.tenalg.multi_mode_dot(tensor, factors, modes=[1, 2], transpose=True)
这里的换位相当于逆,因为因子是正交的。
最后,关于术语的说明:一般来说,即使有时完成,最好不要使用交替的顺序和张量等级。张量的阶数就是它的维数,而张量的阶数通常是一个更复杂的概念,你可以把它看作是矩阵秩概念的推广。