python学习打卡day21

什么时候需要用到降维?

1.数据可视化

高维数据难以直接可视化(如超过3维),通过降维(如PCA、t-SNE、UMAP)投影到2D/3D空间,揭示数据分布、聚类或流形结构。

适用算法:t-SNE(非线性可视化)、PCA(线性全局结构)、UMAP(高效非线性)。

2.特征冗余与噪声去除

数据中存在高度相关或冗余特征(如多重共线性),降维可提取独立成分,去除噪声。

适用算法:PCA(最大化方差去噪)、ICA(独立成分分析)。

3.模型加速与防止过拟合

高维特征导致计算成本高且易过拟合(如文本、图像数据),降维可减少参数数量,提升效率。

适用算法:PCA、LDA(有监督分类场景)、Autoencoder(深度学习方法)。

4.提高分类性能

有监督任务中,通过降维增强类别可分性(如投影到判别性更强的子空间)。

适用算法:LDA(优化类间距离)、NCA(邻域成分分析)。

5.数据压缩与存储优化

对高维数据进行压缩(如人脸识别、信号处理),减少存储需求。

适用算法:PCA、SVD(基于线性压缩)。

降维方法的选择:

降维方法 适用场景 数据类型 优点 缺点
主成分分析(PCA) 数据具有线性关系,适用于数据可视化、去除噪声、特征提取等 数值型数据 计算简单,能有效提取主要特征,可解释性强 对非线性数据处理效果不佳,可能丢失一些重要的非线性信息
线性判别分析(LDA) 有监督的降维,用于分类任务,可提高分类性能 数值型数据,且有类别标签 考虑了类别信息,能使不同类别数据更好地分离 对数据分布有一定要求,如类内方差相等,当类别过多时效果可能受影响
多维缩放(MDS) 用于保持数据点之间的相似性或距离关系,常用于数据可视化和探索性分析 适用于各种类型的数据,但通常需要事先定义数据点之间的距离或相似性度量 能较好地保持数据的原始结构和距离关系 计算复杂度较高,对于大规模数据处理困难,对数据中的噪声敏感
等距映射(Isomap) 适用于处理具有非线性流形结构的数据,用于数据可视化和特征提取 数值型数据 能有效处理非线性数据,保留数据的全局几何结构 计算量较大,对数据的局部连通性要求较高,当数据存在噪声或离群点时效果可能受影响
局部线性嵌入(LLE) 用于发现数据的局部线性结构,适用于非线性降维 数值型数据 能很好地捕捉数据的局部几何特征,对非线性数据的降维效果较好 对数据的局部邻域选择敏感,可能会出现局部最优解问题,计算复杂度较高
t - 分布随机邻域嵌入(t - SNE) 主要用于数据可视化,特别是在处理高维数据中的复杂分布和聚类结构时表现出色 数值型数据 能够将高维数据映射到低维空间中,同时很好地保留数据的局部结构和聚类信息 计算速度较慢,对参数设置较为敏感,不适合用于大规模数据的降维
因子分析 用于探索数据背后的潜在因子结构,常用于社会科学、心理学等领域的数据处理 数值型数据 可以揭示数据的潜在结构,减少变量的数量 对数据的正态性和独立性要求较高,模型的解释和估计可能较为复杂

导入库: 

import pandas as pd
data=pd.read_csv("heart.csv")
data.info()

默认参数的随机森林 :

from sklearn.model_selection import  train_test_split
from sklearn.ensemble import RandomForestClassifier #随机森林分类器
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score # 用于评估分类器性能的指标
from sklearn.metrics import classification_report, confusion_matrix #用于生成分类报告和混淆矩阵
import warnings #用于忽略警告信息
warnings.filterwarnings("ignore") # 忽略所有警告信息
X = data.drop(['target'], axis=1)  # 特征,axis=1表示按列删除
y = data['target'] # 标签
# 按照8:2划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)  # 80%训练集,20%测试集
# --- 1. 默认参数的随机森林 ---
# 评估基准模型,这里确实不需要验证集
print("--- 1. 默认参数随机森林 (训练集 -> 测试集) ---")
import time # 这里介绍一个新的库,time库,主要用于时间相关的操作,因为调参需要很长时间,记录下会帮助后人知道大概的时长
start_time = time.time() # 记录开始时间
rf_model = RandomForestClassifier(random_state=42)
rf_model.fit(X_train, y_train) # 在训练集上训练
rf_pred = rf_model.predict(X_test) # 在测试集上预测
end_time = time.time() # 记录结束时间
 
print(f"训练与预测耗时: {end_time - start_time:.4f} 秒")
print("\n默认随机森林 在测试集上的分类报告:")
print(classification_report(y_test, rf_pred))
print("默认随机森林 在测试集上的混淆矩阵:")
print(confusion_matrix(y_test, rf_pred))

PCA降维: 

from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import classification_report, confusion_matrix
import time
import numpy as np # 确保numpy导入
 
# 假设 X_train, X_test, y_train, y_test 已经准备好了
 
print(f"\n--- 2. PCA 降维 + 随机森林 (不使用 Pipeline) ---")
 
 
# 步骤 1: 特征缩放
scaler_pca = StandardScaler()
X_train_scaled_pca = scaler_pca.fit_transform(X_train)
X_test_scaled_pca = scaler_pca.transform(X_test) # 使用在训练集上fit的scaler
 
# 步骤 2: PCA降维
# 选择降到10维,或者你可以根据解释方差来选择,例如:
pca_expl = PCA(random_state=42)
pca_expl.fit(X_train_scaled_pca)
cumsum_variance = np.cumsum(pca_expl.explained_variance_ratio_)
n_components_to_keep_95_var = np.argmax(cumsum_variance >= 0.95) + 1
print(f"为了保留95%的方差,需要的主成分数量: {n_components_to_keep_95_var}")
# 我们测试下降低到10维的效果
n_components_pca = 10
pca_manual = PCA(n_components=n_components_pca, random_state=42)
X_train_pca = pca_manual.fit_transform(X_train_scaled_pca)
X_test_pca = pca_manual.transform(X_test_scaled_pca) # 使用在训练集上fit的pca
print(f"PCA降维后,训练集形状: {X_train_pca.shape}, 测试集形状: {X_test_pca.shape}")
start_time_pca_manual = time.time()
# 步骤 3: 训练随机森林分类器
rf_model_pca = RandomForestClassifier(random_state=42)
rf_model_pca.fit(X_train_pca, y_train)
# 步骤 4: 在测试集上预测
rf_pred_pca_manual = rf_model_pca.predict(X_test_pca)
end_time_pca_manual = time.time()
print(f"手动PCA降维后,训练与预测耗时: {end_time_pca_manual - start_time_pca_manual:.4f} 秒")
print("\n手动 PCA + 随机森林 在测试集上的分类报告:")
print(classification_report(y_test, rf_pred_pca_manual))
print("手动 PCA + 随机森林 在测试集上的混淆矩阵:")
print(confusion_matrix(y_test, rf_pred_pca_manual))

t-SNE 

from sklearn.manifold import TSNE
from sklearn.preprocessing import StandardScaler
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import classification_report, confusion_matrix
import time
import numpy as np
import matplotlib.pyplot as plt # 用于可选的可视化
import seaborn as sns # 用于可选的可视化
print(f"\n--- 3. t-SNE 降维 + 随机森林  ---")
print("       标准 t-SNE 主要用于可视化,直接用于分类器输入可能效果不佳。")
# 步骤 1: 特征缩放
scaler_tsne = StandardScaler()
X_train_scaled_tsne = scaler_tsne.fit_transform(X_train)
X_test_scaled_tsne = scaler_tsne.transform(X_test) # 使用在训练集上fit的scale
# n_components_tsne = 10 # 与PCA的例子保持一致,但计算量会很大
n_components_tsne = 2    # 更典型的t-SNE用于分类的维度,如果想快速看到结果
# 对训练集进行 fit_transform
tsne_model_train = TSNE(n_components=n_components_tsne,
                        perplexity=30,    # 常用的困惑度值
                        n_iter=1000,      # 足够的迭代次数
                        init='pca',       # 使用PCA初始化,通常更稳定
                        learning_rate='auto', # 自动学习率 (sklearn >= 1.2)
                        random_state=42,  # 保证结果可复现
                        n_jobs=-1)        # 使用所有CPU核心
print("正在对训练集进行 t-SNE fit_transform...")
start_tsne_fit_train = time.time()
X_train_tsne = tsne_model_train.fit_transform(X_train_scaled_tsne)
end_tsne_fit_train = time.time()
print(f"训练集 t-SNE fit_transform 完成,耗时: {end_tsne_fit_train - start_tsne_fit_train:.2f} 秒")
# 对测试集进行 fit_transform
# 再次强调:这是独立于训练集的变换
tsne_model_test = TSNE(n_components=n_components_tsne,
                       perplexity=30,
                       n_iter=1000,
                       init='pca',
                       learning_rate='auto',
                       random_state=42, # 保持参数一致,但数据不同,结果也不同
                       n_jobs=-1)
print("正在对测试集进行 t-SNE fit_transform...")
start_tsne_fit_test = time.time()
X_test_tsne = tsne_model_test.fit_transform(X_test_scaled_tsne) # 注意这里是 X_test_scaled_tsne
end_tsne_fit_test = time.time()
print(f"测试集 t-SNE fit_transform 完成,耗时: {end_tsne_fit_test - start_tsne_fit_test:.2f} 秒")

print(f"t-SNE降维后,训练集形状: {X_train_tsne.shape}, 测试集形状: {X_test_tsne.shape}")

start_time_tsne_rf = time.time()
# 步骤 3: 训练随机森林分类器
rf_model_tsne = RandomForestClassifier(random_state=42)
rf_model_tsne.fit(X_train_tsne, y_train)

# 步骤 4: 在测试集上预测
rf_pred_tsne_manual = rf_model_tsne.predict(X_test_tsne)
end_time_tsne_rf = time.time()

print(f"t-SNE降维数据上,随机森林训练与预测耗时: {end_time_tsne_rf - start_time_tsne_rf:.4f} 秒")
total_tsne_time = (end_tsne_fit_train - start_tsne_fit_train) + \
                  (end_tsne_fit_test - start_tsne_fit_test) + \
                  (end_time_tsne_rf - start_time_tsne_rf)
print(f"t-SNE 总耗时 (包括两次fit_transform和RF): {total_tsne_time:.2f} 秒")


print("\n手动 t-SNE + 随机森林 在测试集上的分类报告:")
print(classification_report(y_test, rf_pred_tsne_manual))
print("手动 t-SNE + 随机森林 在测试集上的混淆矩阵:")
print(confusion_matrix(y_test, rf_pred_tsne_manual))

@浙大疏锦行

你可能感兴趣的:(python学习打卡,python,学习,开发语言)