Python非负矩阵分解能处理零值和缺失数据吗?

我在寻找一个具有Python接口的NMF实现,并且能够处理缺失数据和零值。

我不想在开始分解之前对缺失值进行填补,我希望它们在最小化函数中被忽略。

似乎scikit-learn、nimfa、graphlab和mahout都没有提供这样的选项。

谢谢!


回答:

使用这个Matlab到Python代码转换表,我能够重写来自Matlab工具箱库的NMF。
我需要分解一个40k X 1k的矩阵,稀疏度为0.7%。使用500个潜在特征,我的机器在100次迭代中花了20分钟。

这是方法:

import numpy as npfrom scipy import linalgfrom numpy import dotdef nmf(X, latent_features, max_iter=100, error_limit=1e-6, fit_error_limit=1e-6):    """    Decompose X to A*Y    """    eps = 1e-5    print 'Starting NMF decomposition with {} latent features and {} iterations.'.format(latent_features, max_iter)    X = X.toarray()  # I am passing in a scipy sparse matrix    # mask    mask = np.sign(X)    # initial matrices. A is random [0,1] and Y is A\X.    rows, columns = X.shape    A = np.random.rand(rows, latent_features)    A = np.maximum(A, eps)    Y = linalg.lstsq(A, X)[0]    Y = np.maximum(Y, eps)    masked_X = mask * X    X_est_prev = dot(A, Y)    for i in range(1, max_iter + 1):        # ===== updates =====        # Matlab: A=A.*(((W.*X)*Y')./((W.*(A*Y))*Y'));        top = dot(masked_X, Y.T)        bottom = (dot((mask * dot(A, Y)), Y.T)) + eps        A *= top / bottom        A = np.maximum(A, eps)        # print 'A',  np.round(A, 2)        # Matlab: Y=Y.*((A'*(W.*X))./(A'*(W.*(A*Y))));        top = dot(A.T, masked_X)        bottom = dot(A.T, mask * dot(A, Y)) + eps        Y *= top / bottom        Y = np.maximum(Y, eps)        # print 'Y', np.round(Y, 2)        # ==== evaluation ====        if i % 5 == 0 or i == 1 or i == max_iter:            print 'Iteration {}:'.format(i),            X_est = dot(A, Y)            err = mask * (X_est_prev - X_est)            fit_residual = np.sqrt(np.sum(err ** 2))            X_est_prev = X_est            curRes = linalg.norm(mask * (X - X_est), ord='fro')            print 'fit residual', np.round(fit_residual, 4),            print 'total residual', np.round(curRes, 4)            if curRes < error_limit or fit_residual < fit_error_limit:                breakreturn A, Y

在这里,我使用了Scipy稀疏矩阵作为输入,缺失值通过toarray()方法转换为0。因此,使用numpy.sign()函数创建了掩码。然而,如果你有nan值,你可以通过使用numpy.isnan()函数获得相同的结果。

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注