首页 > 解决方案 > 计算大矩阵的均值和协方差(300000 x 70000)

问题描述

我正在使用 Numpy 并尝试计算大矩阵(300000 x 70000)的均值和协方差。我有 32GB 大小的可用内存。就计算效率和易于实施而言,这项任务的最佳实践是什么?

我目前的实现如下:

def compute_mean_variance(mat, chunk_size):
    row_count = mat.row_count
    col_count = mat.col_count
    # maintain the `x_sum`, `x2_sum` array
    # mean(x) = x_sum / row_count
    # var(x) = x2_sum / row_count - mean(x)**2
    x_sum = np.zeros([1, col_count])
    x2_sum = np.zeros([1, col_count])

    for i in range(0, row_count, chunk_size):
        sub_mat = mat[i:i+chunk_size, :]
        # in-memory sub_mat of size chunk_size x num_cols
        sub_mat = sub_mat.read().val
        x_sum += np.sum(sub_mat, 0)
        x2_sum += x2_sum + np.sum(sub_mat**2, 0)
    x_mean = x_sum / row_count
    x_var = x2_sum / row_count - x_mean ** 2
    return x_mean, x_var

有什么改进建议吗?

我发现下面的实现应该更容易理解。它还使用 numpy 计算列块的平均值和标准差。所以它应该更有效并且在数值上更稳定。

def compute_mean_std(mat, chunk_size):
    row_count = mat.row_count
    col_count = mat.col_count
    mean = np.zeros(col_count)
    std = np.zeros(col_count)

    for i in xrange(0, col_count, chunk_size):
        sub_mat = mat[:, i : i + chunk_size]
        # num_samples x chunk_size
        sub_mat = sub_mat.read().val
        mean[i : i + chunk_size] = np.mean(sub_mat, axis=0)
        std[i : i + chunk_size] = np.std(sub_mat, axis=0)

    return mean, std

标签: pythonnumpymatrixlinear-algebra

解决方案


所以我在大学有一个项目,涉及不同矩阵乘法算法的时间复杂度测试。

我在这里上传了源代码。

我发现的优化之一是您可以通过更改 for 循环的结构来优化数组访问,以一次只关注行而不是遍历列。这是由于缓存在空间局部性上的行为方式(即您的计算机尝试针对二维数组中并排而不是逐行的数组元素进行优化)

此外,如果这些是“稀疏”矩阵(很多零元素),您可以更改数据结构以仅记录非零元素。

显然,如果给定一个普通矩阵,将它们转换为稀疏矩阵的计算可能不值得,但我只是认为这些观察值得分享:)


推荐阅读