按照题意一步一步实现即可。
数据读取与转换
train 和测试集 test。numpy 数组方便后续矩阵运算。均值向量计算(Mean Centering)
协方差矩阵计算
题目要求使用总体方差(ddof=0),协方差矩阵公式:
其中 n 是训练样本数。
第一主成分提取(PCA)
numpy.linalg.eigh 求协方差矩阵的特征值和特征向量(适用于对称矩阵)。投影与重建
对测试集样本 x:
投影系数:
z=(x−μ)Tvmax重建:
x^=μ+z νmax
均方误差计算
对每个测试样本,计算:
$$MSE(x) = \frac{1}{m} \sum_{j=1}^m (x_j - \hat{x}_j)^2 $$保留两位小数,并转成字符串输出 JSON 数组。
import sys
import json
import numpy as np
def main():
    # 读取 JSON 输入
    raw = sys.stdin.read().strip()
    if not raw:
        print("[]")
        return
    data = json.loads(raw)
    # 转成 numpy 数组
    train = np.array(data["train"], dtype=float)
    test  = np.array(data["test"], dtype=float)
    # 1. 均值向量 μ
    mu = train.mean(axis=0)
    # 2. 去均值
    Xc = train - mu
    # 3. 协方差矩阵(总体方差)
    n = train.shape[0]
    cov = (Xc.T @ Xc) / n
    # 4. 求第一主成分
    vals, vecs = np.linalg.eigh(cov)
    vmax = vecs[:, np.argmax(vals)]
    # 方向标准化
    nz = np.flatnonzero(np.abs(vmax) > 1e-12)
    if nz.size > 0 and vmax[nz[0]] < 0:
        vmax = -vmax
    # 5. 投影到第一主成分
    z = (test - mu) @ vmax
    # 6. 重建数据
    x_hat = mu + np.outer(z, vmax)
    # 7. 计算 MSE
    mse = np.mean((test - x_hat) ** 2, axis=1)
    # 8. 保留两位小数并输出 JSON 数组
    out = [f"{x:.2f}" for x in mse]
    print(json.dumps(out, ensure_ascii=False))
if __name__ == "__main__":
    main()
        给定一批训练样本与若干测试样本,请你手写实现主成分分析 (PCA) 并仅保留第一主成分来压缩-重建数据,最后输出每个测试样本在重建后的均方误差 (MSE) 。
1.输入读取
train - 二维列表,每行是一个 m 维数值特征向量
test - 二维列表,维度同上
2.去均值 (mean−center)
Xc=X−μ,μ=mean(Xtrain)
3.协方差矩阵(总体方差,ddof=0)
∑=n1XcTXc 。
4.求第一主成分
用 numpy.linalg.eigh 得到全部特征对 (λi,νi)
按特征值从大到小选取第一主成分 νmax
方向标准化规则 -- 若 νmax 首个非零分量为负,则整体乘以 −1 ;这样方向唯一
5.投影-重建
z=(x−μ)Tνmax, x^=μ+z νmax
6.输出
MSE(x)=m1∑j=1m(xj−x^j)2
结果保留两位小数,使用字符串形式
所有测试样本的误差按输入顺序组成 JSON 数组一行输出
标准输入仅一行,为如下 JSON 对象:
{
"train":[[...],[...],...],
"test":[[...],[...],...]
}
其中
train 长度 n≥2 ,每行长度 m≥2
test 任意条数,维度同 train
标准输出仅一行 -- 测试集中 每个样本 MSE 的字符串形式(两位小数),用 JSON 数组包裹.
1.算法不含随机过程(无需设置随机种子)。
2.为了确保通过所有测试用例,仅允许使用 Numpy库与Pandas库实现本题。
3.使用总体方差 np.var(x,ddof=0).
输入
{"train": [[0,0],[0,1],[1,0],[1,1]],"test":[[0.5,0.5],[1.5,1.5]]}
输出
["0.00","0.50"]