题解 | 单主成分压缩后的均方重建误差

单主成分压缩后的均方重建误差

https://www.nowcoder.com/practice/1c24cd561bb84a33bf1c41b536794cd9

import sys
import json
import numpy as np

from numpy.random import f

def cal_mse(train, test):
    train_array = np.array(train, dtype=float)
    test_array = np.array(test, dtype=float)

    n_samples = train_array.shape[0]
    # 计算均值
    mu = np.mean(train_array, axis=0)
    # 广播机制
    X_c = train_array - mu

    # 机选协方差矩阵
    sigma = np.matmul(X_c.T, X_c) / n_samples

    # 使用线性代数的库得到特征值和特征向量
    eigenvalues, eigenvectors = np.linalg.eigh(sigma)

    # 返回特征值最大的索引
    eigen_max_idx = np.argmax(eigenvalues)
    # 一列是一个特征向量
    vec_max = eigenvectors[:, eigen_max_idx]
    
    # 获取所有非零元素的索引, 我自己实现肯定是循环迭代了
    nonzero_indices = np.nonzero(vec_max)[0]
    # 如果存在非零的元素, 可能全是0向量
    if nonzero_indices.size > 0:
        first_nonzero_idx = nonzero_indices[0]
        if vec_max[first_nonzero_idx] < 0:
            # 变换方向
            vec_max = -vec_max
    
    # 投影-重建
    mse_list = []
    for i in range(len(test_array)):
        x = test_array[i]
        x_center = x - mu
        z = np.dot(x_center, vec_max)

        # 重构的x为
        x_hat = mu + z * vec_max

        # 计算重构损失
        mse = np.mean((x - x_hat)**2)
        mse_list.append(f"{mse:.2f}")
    
    return mse_list


if __name__ == "__main__":
    data = json.load(sys.stdin)
    train = data["train"]
    test = data["test"]

    mse_list = cal_mse(train, test)
    print(json.dumps(mse_list))

全部评论

相关推荐

给个offer灞:校友 是不是金die
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务