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

标签 python machine-learning scikit-learn collaborative-filtering matrix-factorization

我寻找具有 python 接口(interface)并处理丢失数据和零的 NMF 实现。

我不想在开始因式分解之前估算缺失值,我希望它们在最小化函数中被忽略。

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

谢谢!

最佳答案

使用这个 Matlab to python code conversion sheet我能够从 Matlab toolbox 重写 NMF图书馆。
我必须分解一个稀疏度为 0.7% 的 40k X 1k 矩阵。使用 500 个潜在特征,我的机器需要 20 分钟进行 100 次迭代。

方法如下:

import numpy as np
from scipy import linalg
from numpy import dot

def 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:
                break

return A, Y

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

关于处理零和缺失数据的 Python 非负矩阵分解?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22767695/

相关文章:

python - 计算预测连续值的准确度分数

python - 在Python中搜索带有扩展名的文件并复制到目录?

c++ - 使用 Boost::Python 获取指向 Python 实例的 C++ 指针

python - 重复随机选择中不重复元素

python - Pyspark:将参数传递给数据帧中的字符串列

machine-learning - 连续人体事件加速度计的无监督分类(聚类)

python - 如何解决由 Get_dummies 引起的内存错误

machine-learning - GridSearch中的sklearn逻辑回归参数

python - scikit-learn 中递归特征消除 (RFE) 的排名和分数

python - 用于提取 ngram 的 TF-IDF 向量化器