Decomposition class
Classes:
|
Class wrapper for coupled matrix factorizations. |
Functions:
|
Generate a list of all matrices represented by the coupled matrix factorisation. |
|
Generate a single matrix from the coupled matrix factorisation. |
|
Alias for |
|
Alias for |
|
Generate the tensor represented by the coupled matrix factorization. |
|
Generate the unfolded tensor represented by the coupled matrix factorization. |
|
Generate the vectorized tensor represented by the coupled matrix factorization. |
- class matcouply.coupled_matrices.CoupledMatrixFactorization(cmf_matrices)[source]
Class wrapper for coupled matrix factorizations.
Coupled matrix factorizations decompositions represent stacks of matrices and are on the form \((\mathbf{A} [\mathbf{B}^{(0)}, \mathbf{B}^{(1)}, ..., \mathbf{B}^{(I-1)}] \mathbf{C})\), such that the i-th matrix, \(\mathbf{X}^{(i)}\) is given by
\[\mathbf{X}^{(i)} = \mathbf{B}^{(i)} \text{diag}(\mathbf{a}_i) \mathbf{C}^T,\]where \(\text{diag}(\mathbf{a}_i)\) is the diagonal matrix whose nonzero entries are equal to the \(i\)-th row of the \(I \times R\) factor matrix \(\mathbf{A}\), \(\mathbf{B}^{(i)}\) is a \(J_i \times R\) factor matrix, and \(\mathbf{C}\) is a \(K \times R\) factor matrix. For more information about coupled matrix decompositions, see What are coupled matrix factorizations?.
This class validates the decomposition and provides conversion to dense formats via methods.
- Parameters:
cmf (CoupledMatrixFactorization - (weights, factors)) –
Coupled matrix factorization represented by weights and factors as described in What are coupled matrix factorizations?.
- weights1D array of shape (rank,) or None
weights of the factors
- factorsList of factors of the coupled matrix decomposition
List on the form
[A, [B_0, B_1, ..., B_i], C]
, whereA
represents \(\mathbf{A}\),[B_0, B_1, ..., B_i]
represents a list of all \(\mathbf{B}^{(i)}\)-matrices andC
represents \(\mathbf{C}\)
Examples
>>> from tensorly.random import random_tensor >>> from matcouply.coupled_matrices import CoupledMatrixFactorization >>> A = random_tensor((5, 3)) >>> B_is = [random_tensor((10, 3)) for i in range(5)] >>> C = random_tensor((15, 3)) >>> cmf = CoupledMatrixFactorization((None, (A, B_is, C)))
We can then convert the factorization to a dense format easily
>>> matrices = cmf.to_matrices() >>> len(matrices) 5
>>> tl.shape(matrices[0]) (10, 15)
We see that we can get the shape of the decomposition without converting it to a dense format first also.
>>> len(cmf.shape) 5
>>> cmf.shape[0] (10, 15)
We can also extract the weights and factor matrices from the decomposition object as if it was a tuple.
>>> weights, (A, B_is, C) = cmf
And if the decomposition is invalid, then a helpful error message will be printed.
>>> A = random_tensor((5, 3)) >>> B_is = [random_tensor((10, 3)) for i in range(5)] >>> C = random_tensor((15, 15, 3)) >>> cmf = CoupledMatrixFactorization((None, (A, B_is, C))) Traceback (most recent call last): ... ValueError: The last factor matrix, C, should be a second order tensor. However C has shape (15, 15, 3)
>>> A = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] >>> B_is = [random_tensor((10, 3)) for i in range(5)] >>> C = random_tensor((15, 3)) >>> cmf = CoupledMatrixFactorization((None, (A, B_is, C))) Traceback (most recent call last): ... TypeError: The first factor matrix, A, should be a second order tensor of size (I, rank)), not <class 'list'>
Methods:
from_CPTensor
(cp_tensor[, shapes])Convert a CP tensor into a coupled matrix factorization.
from_Parafac2Tensor
(parafac2_tensor)Convert a PARAFAC2 tensor into a coupled matrix factorization.
Convert to a list of matrices.
to_matrix
(matrix_idx)Construct a single dense matrix from the decomposition.
Convert to a dense tensor (pad uneven slices by zeros).
to_unfolded
(mode[, pad])Convert to a matrix by first converting to a dense tensor and unfolding.
to_vec
([pad])Convert to a vector by first converting to a dense tensor and unraveling.
- classmethod from_CPTensor(cp_tensor, shapes=None)[source]
Convert a CP tensor into a coupled matrix factorization.
- Parameters:
cp_tensor (tl.cp_tensor.CPTensor) – CP tensor to convert into a coupled matrix factorization
- Returns:
A coupled matrix factorization that represents the same tensor as
cp_tensor
.- Return type:
- Raises:
ValueError – If the CP tensor has more than tree modes.
- classmethod from_Parafac2Tensor(parafac2_tensor)[source]
Convert a PARAFAC2 tensor into a coupled matrix factorization.
- Parameters:
parafac2_tensor (tl.parafac2_tensor.Parafac2Tensor) – PARAFAC2 tensor to convert into a coupled matrix factorization
- Returns:
A coupled matrix factorization that represents the same tensor as
parafac2_tensor
.- Return type:
- to_unfolded(mode, pad=True)[source]
Convert to a matrix by first converting to a dense tensor and unfolding.
See also
- matcouply.coupled_matrices.cmf_to_matrices(cmf, validate=True)[source]
Generate a list of all matrices represented by the coupled matrix factorisation.
The decomposition is on the form \((\mathbf{A} [\mathbf{B}^{(0)}, \mathbf{B}^{(1)}, ..., \mathbf{B}^{(I-1)}] \mathbf{C})\) such that the i-th matrix, \(\mathbf{X}^{(i)}\) is given by
\[\mathbf{X}^{(i)} = \mathbf{B}^{(i)} \text{diag}(\mathbf{a}_i) \mathbf{C}^T,\]where \(\text{diag}(\mathbf{a}_i)\) is the diagonal matrix whose nonzero entries are equal to the \(i\)-th row of the \(I \times R\) factor matrix \(\mathbf{A}\), \(\mathbf{B}^{(i)}\) is a \(J_i \times R\) factor matrix, and \(\mathbf{C}\) is a \(K \times R\) factor matrix.
- Parameters:
cmf (CoupledMatrixFactorization - (weights, factors)) –
Coupled matrix factorization represented by weights and factors as described in What are coupled matrix factorizations?.
- weights1D array of shape (rank,) or None
weights of the factors
- factorsList of factors of the coupled matrix decomposition
List on the form
[A, [B_0, B_1, ..., B_i], C]
, whereA
represents \(\mathbf{A}\),[B_0, B_1, ..., B_i]
represents a list of all \(\mathbf{B}^{(i)}\)-matrices andC
represents \(\mathbf{C}\)
validate (bool) – If true, then the decomposition is validated before the matrix is constructed (see
CoupledMatrixFactorization
).
- Returns:
List of all \(\mathbf{X}^{(i)}\)-matrices, where the
i
-th element of the list has shape[B_is[i].shape[0], C.shape[0]]
, whereB_is
is a list containing all the \(\mathbf{B}^{(i)}\)-factor matrices.- Return type:
List of ndarray
Examples
We can convert a coupled matrix factorization to a list of matrices
>>> from matcouply.random import random_coupled_matrices >>> from matcouply.coupled_matrices import cmf_to_matrix >>> shapes = ((5, 10), (6, 10), (7, 10)) >>> cmf = random_coupled_matrices(shapes, rank=3) >>> matrices = cmf_to_matrices(cmf) >>> for matrix in matrices: ... print(tl.shape(matrix)) (5, 10) (6, 10) (7, 10)
- matcouply.coupled_matrices.cmf_to_matrix(cmf, matrix_idx, validate=True)[source]
Generate a single matrix from the coupled matrix factorisation.
The decomposition is on the form \((\mathbf{A} [\mathbf{B}^{(0)}, \mathbf{B}^{(1)}, ..., \mathbf{B}^{(I-1)}] \mathbf{C})\) such that the i-th matrix, \(\mathbf{X}^{(i)}\) is given by
\[\mathbf{X}^{(i)} = \mathbf{B}^{(i)} \text{diag}(\mathbf{a}_i) \mathbf{C}^T,\]where \(\text{diag}(\mathbf{a}_i)\) is the diagonal matrix whose nonzero entries are equal to the \(i\)-th row of the \(I \times R\) factor matrix \(\mathbf{A}\), \(\mathbf{B}^{(i)}\) is a \(J_i \times R\) factor matrix, and \(\mathbf{C}\) is a \(K \times R\) factor matrix.
- Parameters:
cmf (CoupledMatrixFactorization - (weights, factors)) –
Coupled matrix factorization represented by weights and factors as described in What are coupled matrix factorizations?.
- weights1D array of shape (rank,) or None
weights of the factors
- factorsList of factors of the coupled matrix decomposition
List on the form
[A, [B_0, B_1, ..., B_i], C]
, whereA
represents \(\mathbf{A}\),[B_0, B_1, ..., B_i]
represents a list of all \(\mathbf{B}^{(i)}\)-matrices andC
represents \(\mathbf{C}\)
matrix_idx (int) – Index of the matrix we want to construct, \(i\) in the equations above.
validate (bool) – If true, then the decomposition is validated before the matrix is constructed (see
CoupledMatrixFactorization
).
- Returns:
Dense tensor of shape
[B_is[matrix_idx].shape[0], C.shape[0]]
, whereB
is a list containing all the \(\mathbf{B}^{(i)}\)-factor matrices.- Return type:
ndarray
Examples
An example where we calculate one of the matrices described by a coupled matrix factorization
>>> from matcouply.random import random_coupled_matrices >>> from matcouply.coupled_matrices import cmf_to_matrix >>> shapes = ((5, 10), (6, 10), (7, 10)) >>> cmf = random_coupled_matrices(shapes, rank=3) >>> matrix = cmf_to_matrix(cmf, matrix_idx=1) >>> tl.shape(matrix) (6, 10)
- matcouply.coupled_matrices.cmf_to_slice(cmf, slice_idx, validate=True)[source]
Alias for
cmf_to_matrix
.See also
- matcouply.coupled_matrices.cmf_to_slices(cmf, validate=True)[source]
Alias for
cmf_to_matrices
.See also
- matcouply.coupled_matrices.cmf_to_tensor(cmf, validate=True)[source]
Generate the tensor represented by the coupled matrix factorization.
If all \(\mathbf{B}^{(i)}\)-factor matrices have the same number of rows, then this function returnes a tensorized version of
cmf_to_matrices
. Otherwise, each matrix is padded by zeros to have the same number of rows before forming the tensor.The decomposition is on the form \((\mathbf{A} [\mathbf{B}^{(0)}, \mathbf{B}^{(1)}, ..., \mathbf{B}^{(I-1)}] \mathbf{C})\) such that the i-th matrix, \(\mathbf{X}^{(i)}\) is given by
\[\mathbf{X}^{(i)} = \mathbf{B}^{(i)} \text{diag}(\mathbf{a}_i) \mathbf{C}^T,\]where \(\text{diag}(\mathbf{a}_i)\) is the diagonal matrix whose nonzero entries are equal to the \(i\)-th row of the \(I \times R\) factor matrix \(\mathbf{A}\), \(\mathbf{B}^{(i)}\) is a \(J_i \times R\) factor matrix, and \(\mathbf{C}\) is a \(K \times R\) factor matrix.
- Parameters:
cmf (CoupledMatrixFactorization - (weights, factors)) –
Coupled matrix factorization represented by weights and factors as described in What are coupled matrix factorizations?.
- weights1D array of shape (rank,) or None
weights of the factors
- factorsList of factors of the coupled matrix decomposition
List on the form
[A, [B_0, B_1, ..., B_i], C]
, whereA
represents \(\mathbf{A}\),[B_0, B_1, ..., B_i]
represents a list of all \(\mathbf{B}^{(i)}\)-matrices andC
represents \(\mathbf{C}\)
validate (bool) – If true, then the decomposition is validated before the matrix is constructed (see
CoupledMatrixFactorization
).
- Returns:
Full tensor of shape
[A.shape[0], J, C.shape[0]]
, whereJ
is the maximum number of rows in all the \(\mathbf{B}^{(i)}\)-factor matrices.- Return type:
ndarray
Examples
We can convert a coupled matrix factorization to a tensor. This will be equivalent to stacking the matrices using axis=0.
>>> from matcouply.random import random_coupled_matrices >>> from matcouply.coupled_matrices import cmf_to_tensor >>> shapes = ((5, 10), (5, 10), (5, 10), (5, 10)) >>> cmf = random_coupled_matrices(shapes, rank=3) >>> tensor = cmf_to_tensor(cmf) >>> tl.shape(tensor) (4, 5, 10)
We can also convert a coupled matrix factorization that represent matrices with different numbers of columns. Then, the smaller matrices will be padded by zeros so all have the same shape.
>>> shapes = ((5, 10), (5, 10), (5, 10), (3, 10)) >>> cmf = random_coupled_matrices(shapes, rank=3) >>> tensor = cmf_to_tensor(cmf) >>> tl.shape(tensor) (4, 5, 10)
It is only the last matrix which has a different shape. It has two fewer rows than the rest, which means that it has 20 zero-valued elements (\(20 = 2 \times 10\)).
>>> num_zeros = (tensor == 0).sum() >>> num_zeros 20
- matcouply.coupled_matrices.cmf_to_unfolded(cmf, mode, pad=True, validate=True)[source]
Generate the unfolded tensor represented by the coupled matrix factorization.
By default the function is an alias for first constructing a tensor (
cmf_to_tensor
) and then vectorizing that tensor. Note that if the matrices have a different number of rows, then they will be padded when the tensor is constructed, and thus, there will be zeros in the unfolded tensor too.If the zero-padding is unwanted, then setting the
pad
parameter toFalse
(only available formode=2
) will instead construct each matrix and concatenate them.- Parameters:
cmf (CoupledMatrixFactorization - (weights, factors)) –
Coupled matrix factorization represented by weights and factors as described in What are coupled matrix factorizations?.
- weights1D array of shape (rank,) or None
weights of the factors
- factorsList of factors of the coupled matrix decomposition
List on the form
[A, [B_0, B_1, ..., B_i], C]
, whereA
represents \(\mathbf{A}\),[B_0, B_1, ..., B_i]
represents a list of all \(\mathbf{B}^{(i)}\)-matrices andC
represents \(\mathbf{C}\)
pad (bool (default=True)) – If true, then the coupled matrix factorization will be converted into a dense tensor, padding the matrices with zeros so all have the same size, and then unfolded. Can only be
False
ifmode=2
.validate (bool (default=True)) – If true, then the decomposition is validated before the matrix is constructed (see
CoupledMatrixFactorization
).
- Returns:
Matrix of an appropriate shape (see
cmf_to_tensor
andtensorly.unfold
).- Return type:
ndarray
- Raises:
ValueError – If
pad=False
andmode!=2
.
Examples
Here, we show how to unfold a coupled matrix factorization along a given mode.
>>> from matcouply.random import random_coupled_matrices >>> from matcouply.coupled_matrices import cmf_to_tensor >>> shapes = ((5, 10), (5, 10), (5, 10), (5, 10)) >>> cmf = random_coupled_matrices(shapes, rank=3) >>> matrix_0 = cmf_to_unfolded(cmf, mode=0) >>> tl.shape(matrix_0) (4, 50)
We can also unfold the tensor using
mode=1
>>> matrix_1 = cmf_to_unfolded(cmf, mode=1) >>> tl.shape(matrix_1) (5, 40)
And using
mode=2
>>> matrix_2 = cmf_to_unfolded(cmf, mode=2) >>> tl.shape(matrix_2) (10, 20)
We can also unfold a coupled matrix factorization where the matrices have a varying number of rows
>>> shapes = ((5, 10), (3, 10), (2, 10), (4, 10)) >>> cmf = random_coupled_matrices(shapes, rank=3) >>> matrix_0 = cmf_to_unfolded(cmf, mode=0) >>> tl.shape(matrix_0) (4, 50)
However, as we see, the shape of the unfolded tensor is still (4, 50) despite some matrices being shorter. This is because the matrices are padded by zeros to construct the tensor, which is subsequently unfolded.
This padding happens independently of the unfolding mode.
>>> matrix_1 = cmf_to_unfolded(cmf, mode=1) >>> tl.shape(matrix_1) (5, 40)
>>> matrix_2 = cmf_to_unfolded(cmf, mode=2) >>> tl.shape(matrix_2) (10, 20)
We can see the padding by counting the number of zeros. The number of zeros should be \(((5 - 5) + (5 - 3) + (5 - 2) + (5 - 4)) \times 10 = 60\).
>>> nonzeros_0 = tl.sum(matrix_0 == 0) >>> nonzeros_1 = tl.sum(matrix_1 == 0) >>> nonzeros_2 = tl.sum(matrix_2 == 0) >>> nonzeros_0, nonzeros_1, nonzeros_2 (60, 60, 60)
If we want to unfold with
mode=2
without padding with zeros, then we can use thepad
argument>>> shapes = ((5, 10), (3, 10), (2, 10), (4, 10)) >>> cmf = random_coupled_matrices(shapes, rank=3) >>> matrix_3 = cmf_to_unfolded(cmf, pad=False, mode=2) >>> tl.shape(matrix_3) (10, 14)
- matcouply.coupled_matrices.cmf_to_vec(cmf, pad=True, validate=True)[source]
Generate the vectorized tensor represented by the coupled matrix factorization.
By default the function is an alias for first constructing a tensor (
cmf_to_tensor
) and then vectorizing that tensor. Note that if the matrices have a different number of rows, then they will be padded when the tensor is constructed, and thus, there will be zeros in the vectorized tensor too.If the zero-padding is unwanted, then setting the
pad
parameter toFalse
will instead construct and vectorize each matrix described by the decomposition and then concatenate these vectors forming one vector with no padded zero values.- Parameters:
cmf (CoupledMatrixFactorization - (weights, factors)) –
Coupled matrix factorization represented by weights and factors as described in What are coupled matrix factorizations?.
- weights1D array of shape (rank,) or None
weights of the factors
- factorsList of factors of the coupled matrix decomposition
List on the form
[A, [B_0, B_1, ..., B_i], C]
, whereA
represents \(\mathbf{A}\),[B_0, B_1, ..., B_i]
represents a list of all \(\mathbf{B}^{(i)}\)-matrices andC
represents \(\mathbf{C}\)
pad (bool (default=True)) – If true then if the matrices described by the decomposition have a different number of rows, then they will be padded by zeros to construct a tensor which are vectorized, and there will be zeros in the vectorized tensor too. If false, the matrices will not be padded.
validate (bool (default=True)) – If true, then the decomposition is validated before the matrix is constructed (see
CoupledMatrixFactorization
).
- Returns:
Vector of length
A.shape[0] * J * C.shape[0]
, whereJ
is the maximum number of rows in all the \(\mathbf{B}^{(i)}\)-factor matrices.- Return type:
ndarray
Examples
Here, we show how to vectorize a coupled matrix factorization
>>> from matcouply.random import random_coupled_matrices >>> from matcouply.coupled_matrices import cmf_to_tensor >>> shapes = ((5, 10), (5, 10), (5, 10), (5, 10)) >>> cmf = random_coupled_matrices(shapes, rank=3) >>> vector = cmf_to_vec(cmf) >>> tl.shape(vector) (200,)
We can also vectorize a coupled matrix factorization where the matrices have a varying number of rows
>>> shapes = ((5, 10), (3, 10), (2, 10), (4, 10)) >>> cmf = random_coupled_matrices(shapes, rank=3) >>> vector = cmf_to_vec(cmf) >>> tl.shape(vector) (200,)
However, as we see, the length of the vectorized coupled matrix factorization is still 200, despite some matrices being shorter. This is because the matrices are padded by zeros to construct a tensor, which is subsequently unfolded.
We can see the padding by counting the number of zeros. The number of zeros should be \(((5 - 5) + (5 - 3) + (5 - 2) + (5 - 4)) \times 10 = 60\).
>>> tl.sum(vector == 0) 60
If we want to vectorize without padding with zeros, we can use the
pad
argument>>> shapes = ((5, 10), (3, 10), (2, 10), (4, 10)) >>> cmf = random_coupled_matrices(shapes, rank=3) >>> vector = cmf_to_vec(cmf, pad=False) >>> tl.shape(vector) (140,)