day 20

利用SVD奇异值分解进行降维

奇异值分解(SVD)将原始矩阵 A 分解为 A = UΣVᵀ,可完全重构 A 且无信息损失。实际应用中,常筛选排序靠前的奇异值及对应向量实现降维或数据压缩:

1. 排序特性 :Σ 矩阵对角线上奇异值降序排列,大值代表主要信息,小值代表次要信息或噪声,其大小反映对 A 的贡献程度。
2. 筛选规则 :选前 k 个奇异值(k 小于矩阵秩),常见规则有固定数量、累计方差贡献率达阈值、按奇异值下降“拐点”截断。
3. 降维近似 :取 U 前 k 列、Σ 前 k 个值、Vᵀ 前 k 行得 Aₖ = UₖΣₖVₖᵀ,为 A 的低秩近似,用于 PCA、图像压缩、推荐系统等。
4. 向量意义 :Uₖ、Vₖ 列向量分别代表行、列空间主要方向,与奇异值构成数据主要模式。
综上,SVD 筛选奇异值可降维,保留主信息,减少计算量与噪声,是诸多降维及数据处理算法基础。

训练集也要用进行降维处理,但是不能单独降维,得用测试集的Vᵀ进行降维:

1. 训练阶段:对训练集 X_train 进行 SVD 分解,得到 U、Σ 和 Vᵀ,并保存 Vᵀ 矩阵(或其前 k 行)用于降维变换。
2. 测试阶段:使用从训练集得到的 Vᵀ 矩阵,将测试集 X_test 投影到相同的低维空间,得到降维后的测试数据。
3. 原因:Vᵀ 矩阵定义了从原始特征空间到低维特征空间的映射关系,测试集必须使用相同的映射以保持一致性。

代码案例实现

import pandas as pd
import pandas as pd    #用于数据处理和分析,可处理表格数据。
import numpy as np     #用于数值计算,提供了高效的数组操作。
import matplotlib.pyplot as plt    #用于绘制各种类型的图表
import seaborn as sns   #基于matplotlib的高级绘图库,能绘制更美观的统计图形。
from sklearn.preprocessing import StandardScaler, MinMaxScaler  #用于数据预处理,进行归一化
 
 # 设置中文字体(解决中文显示问题)
plt.rcParams['font.sans-serif'] = ['SimHei']  # Windows系统常用黑体字体
plt.rcParams['axes.unicode_minus'] = False    # 正常显示负号

data = pd.read_csv('heart.csv') 

#划分数据集
from sklearn.model_selection import train_test_split
X = data.drop(['target'], axis=1)  # 去掉标签特征,axis=1表示按列删除
y = data['target']  # 标签
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)  # 划分数据集,20%作为测试集,随机种子为42
# 训练集和测试集的形状
print(f"训练集形状: {X_train.shape}, 测试集形状: {X_test.shape}")  # 打印训练集和测试集的形状

#标准化数据
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score



# 对训练集进行 SVD 分解
U_train, sigma_train, Vt_train = np.linalg.svd(X_train_scaled, full_matrices=False)
print(f"Vt_train 矩阵形状: {Vt_train.shape}")

# 选择保留的奇异值数量 k
k = 10
Vt_k = Vt_train[:k, :]  # 保留前 k 行,形状为 (k, 50)
print(f"保留 k={k} 后的 Vt_k 矩阵形状: {Vt_k.shape}")

# 降维训练集:X_train_reduced = X_train @ Vt_k.T
X_train_reduced = X_train_scaled @ Vt_k.T
print(f"降维后训练集形状: {X_train_reduced.shape}")

# 使用相同的 Vt_k 对测试集进行降维:X_test_reduced = X_test @ Vt_k.T
X_test_reduced = X_test_scaled @ Vt_k.T
print(f"降维后测试集形状: {X_test_reduced.shape}")

# 训练模型(以逻辑回归为例)
model = LogisticRegression(random_state=42)
model.fit(X_train_reduced, y_train)

# 预测并评估
y_pred = model.predict(X_test_reduced)
accuracy = accuracy_score(y_test, y_pred)
print(f"测试集准确率: {accuracy}")

# 计算训练集的近似误差(可选,仅用于评估降维效果)
X_train_approx = U_train[:, :k] @ np.diag(sigma_train[:k]) @ Vt_k
error = np.linalg.norm(X_train - X_train_approx, 'fro') / np.linalg.norm(X_train, 'fro')
print(f"训练集近似误差 (Frobenius 范数相对误差): {error}")

day 20_第1张图片

@浙大疏锦行

你可能感兴趣的:(60天计划,python)