非负矩阵分解#

sklearn.decomposition.non_negative_factorization(X, W=None, H=None, n_components='auto', *, init=None, update_H=True, solver='cd', beta_loss='frobenius', tol=0.0001, max_iter=200, alpha_W=0.0, alpha_H='same', l1_ratio=0.0, random_state=None, verbose=0, shuffle=False)[source]#

计算非负矩阵分解 (NMF)。

找到两个非负矩阵 (W, H),其乘积近似非负矩阵 X。这种分解可用于例如降维、源分离或主题提取。

目标函数为

\[ \begin{align}\begin{aligned}L(W, H) &= 0.5 * ||X - WH||_{loss}^2\\ &+ alpha\_W * l1\_ratio * n\_features * ||vec(W)||_1\\ &+ alpha\_H * l1\_ratio * n\_samples * ||vec(H)||_1\\ &+ 0.5 * alpha\_W * (1 - l1\_ratio) * n\_features * ||W||_{Fro}^2\\ &+ 0.5 * alpha\_H * (1 - l1\_ratio) * n\_samples * ||H||_{Fro}^2,\end{aligned}\end{align} \]

其中 \(||A||_{Fro}^2 = \sum_{i,j} A_{ij}^2\) (Frobenius 范数) 和 \(||vec(A)||_1 = \sum_{i,j} abs(A_{ij})\) (逐元素 L1 范数)。

通用范数 \(||X - WH||_{loss}^2\) 可以表示 Frobenius 范数或另一种支持的 beta-散度损失。选项的选择由 beta_loss 参数控制。

W 的正则化项按 n_features 缩放,H 的正则化项按 n_samples 缩放,以使它们之间的影响相互平衡,并使数据拟合项尽可能独立于训练集的大小 n_samples

目标函数通过 W 和 H 的交替最小化来最小化。如果 H 已知且 update_H=False,则只求解 W。

请注意,变换后的数据名为 W,分量矩阵名为 H。在 NMF 文献中,由于数据矩阵 X 是转置的,命名约定通常是相反的。

参数:
X形状为 (n_samples, n_features) 的 {类数组, 稀疏矩阵}

常量矩阵。

W形状为 (n_samples, n_components) 的类数组, 默认为 None

如果 init='custom',它将用作解决方案的初始猜测。如果 update_H=False,它将初始化为全零数组,除非 solver='mu',否则它将用 np.sqrt(X.mean() / self._n_components) 计算的值填充。如果为 None,则使用 init 中指定的初始化方法。

H形状为 (n_components, n_features) 的类数组, 默认为 None

如果 init='custom',它将用作解决方案的初始猜测。如果 update_H=False,它将用作常量,仅求解 W。如果为 None,则使用 init 中指定的初始化方法。

n_componentsint 或 {‘auto’} 或 None, 默认为 ‘auto’

分量数量。如果为 None,则保留所有特征。如果 n_components='auto',则分量数量将从 WH 的形状中自动推断。

版本 1.4 中更改: 添加了 'auto' 值。

版本 1.6 中更改: 默认值从 None 更改为 'auto'

init{‘random’, ‘nndsvd’, ‘nndsvda’, ‘nndsvdar’, ‘custom’}, 默认为 None

用于初始化过程的方法。

可用选项

  • None: 如果 n_components < n_features 则为 ‘nndsvda’,否则为 ‘random’。

  • ‘random’: 非负随机矩阵,按 sqrt(X.mean() / n_components) 缩放

  • ‘nndsvd’: 非负双奇异值分解 (NNDSVD) 初始化(更适用于稀疏性)

  • ‘nndsvda’: NNDSVD,零值用 X 的平均值填充(在不希望稀疏性时更好)

  • ‘nndsvdar’: NNDSVD,零值用小的随机值填充(通常更快,在不希望稀疏性时是 NNDSVDa 的精度较低的替代方案)

  • ‘custom’: 如果 update_H=True,使用必须同时提供的自定义矩阵 W 和 H。如果 update_H=False,则仅使用自定义矩阵 H。

版本 0.23 中更改: init 的默认值在 0.23 版本中从 ‘random’ 更改为 None。

版本 1.1 中更改: init=None 且 n_components 小于 n_samples 和 n_features 时,默认为 nndsvda 而非 nndsvd

update_H布尔值, 默认为 True

设置为 True,W 和 H 都将从初始猜测中估计。设置为 False,则只估计 W。

solver{‘cd’, ‘mu’}, 默认为 ‘cd’

要使用的数值求解器

  • ‘cd’ 是使用快速分层交替最小二乘法 (Fast HALS) 的坐标下降求解器。

  • ‘mu’ 是乘法更新求解器。

版本 0.17 新增: 坐标下降求解器。

版本 0.19 新增: 乘法更新求解器。

beta_loss浮点数 或 {‘frobenius’, ‘kullback-leibler’, ‘itakura-saito’}, 默认为 ‘frobenius’

要最小化的 beta 散度,用于衡量 X 和点积 WH 之间的距离。请注意,与 ‘frobenius’ (或 2) 和 ‘kullback-leibler’ (或 1) 不同的值会导致显著慢的拟合。请注意,对于 beta_loss <= 0 (或 ‘itakura-saito’),输入矩阵 X 不能包含零。仅在 ‘mu’ 求解器中使用。

版本 0.19 新增。

tol浮点数, 默认为 1e-4

停止条件的容差。

max_iter整型, 默认为 200

超时前的最大迭代次数。

alpha_W浮点数, 默认为 0.0

乘以 W 的正则化项的常数。将其设置为零(默认值)表示不对 W 进行正则化。

版本 1.0 新增。

alpha_H浮点数 或 “same”, 默认为 “same”

乘以 H 的正则化项的常数。将其设置为零表示不对 H 进行正则化。如果为 “same”(默认值),则其值与 alpha_W 相同。

版本 1.0 新增。

l1_ratio浮点数, 默认为 0.0

正则化混合参数,0 <= l1_ratio <= 1。当 l1_ratio = 0 时,惩罚项是逐元素的 L2 惩罚(即 Frobenius 范数)。当 l1_ratio = 1 时,惩罚项是逐元素的 L1 惩罚。当 0 < l1_ratio < 1 时,惩罚项是 L1 和 L2 的组合。

random_stateint, RandomState 实例 或 None, 默认为 None

用于 NMF 初始化(当 init == ‘nndsvdar’ 或 ‘random’ 时),以及在坐标下降法中。传入一个整数以在多次函数调用中获得可重现的结果。参见 术语表

verbose整型, 默认为 0

详细程度。

shuffle布尔值, 默认为 False

如果为 true,则在 CD 求解器中随机化坐标的顺序。

返回:
W形状为 (n_samples, n_components) 的 ndarray

非负最小二乘问题的解。

H形状为 (n_components, n_features) 的 ndarray

非负最小二乘问题的解。

n_iter整型

实际迭代次数。

参考文献

[1]

“Fast local algorithms for large scale nonnegative matrix and tensor factorizations” Cichocki, Andrzej, and P. H. A. N. Anh-Huy. IEICE transactions on fundamentals of electronics, communications and computer sciences 92.3: 708-721, 2009.

[2]

“Algorithms for nonnegative matrix factorization with the beta-divergence” Fevotte, C., & Idier, J. (2011). Neural Computation, 23(9).

示例

>>> import numpy as np
>>> X = np.array([[1,1], [2, 1], [3, 1.2], [4, 1], [5, 0.8], [6, 1]])
>>> from sklearn.decomposition import non_negative_factorization
>>> W, H, n_iter = non_negative_factorization(
...     X, n_components=2, init='random', random_state=0)