Python案例如何实现数据降维?

wen python案例 2

本文目录导读:

Python案例如何实现数据降维?

  1. 主成分分析(PCA)- 最常用的线性降维
  2. t-SNE - 非线性降维,适合可视化
  3. 线性判别分析(LDA)- 监督降维
  4. 自动编码器(Autoencoder)- 深度学习降维
  5. 对比不同降维方法
  6. 实战案例:高维数据降维
  7. 选择建议

我来介绍几种Python实现数据降维的常用方法,并给出具体案例:

主成分分析(PCA)- 最常用的线性降维

导入库和数据准备

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA
from sklearn.preprocessing import StandardScaler
from sklearn.datasets import load_iris
# 加载数据
iris = load_iris()
X = iris.data
y = iris.target
feature_names = iris.feature_names
print("原始数据形状:", X.shape)
print("特征名称:", feature_names)

PCA实施

# 1. 数据标准化(PCA对尺度敏感)
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
# 2. 应用PCA
pca = PCA()
X_pca = pca.fit_transform(X_scaled)
# 查看解释方差比
print("各主成分解释方差比:", pca.explained_variance_ratio_)
print("累计解释方差比:", np.cumsum(pca.explained_variance_ratio_))
# 可视化解释方差
plt.figure(figsize=(10, 4))
plt.subplot(1, 2, 1)
plt.bar(range(1, 5), pca.explained_variance_ratio_)
plt.xlabel('主成分')
plt.ylabel('解释方差比')'各主成分解释方差比')
plt.subplot(1, 2, 2)
plt.plot(range(1, 5), np.cumsum(pca.explained_variance_ratio_), 'bo-')
plt.xlabel('主成分数量')
plt.ylabel('累计解释方差比')'累计解释方差比')
plt.grid(True)
plt.tight_layout()
plt.show()
# 降维到2维
pca_2d = PCA(n_components=2)
X_pca_2d = pca_2d.fit_transform(X_scaled)
print("\n降维到2维后的数据形状:", X_pca_2d.shape)
print("2个主成分解释方差比:", pca_2d.explained_variance_ratio_)
print("累计解释方差比:", sum(pca_2d.explained_variance_ratio_))
# 可视化降维结果
plt.figure(figsize=(8, 6))
colors = ['red', 'blue', 'green']
for i, color in enumerate(colors):
    plt.scatter(X_pca_2d[y == i, 0], X_pca_2d[y == i, 1], 
                c=color, label=iris.target_names[i])
plt.xlabel('第一主成分')
plt.ylabel('第二主成分')'PCA降维到2D')
plt.legend()
plt.grid(True)
plt.show()

t-SNE - 非线性降维,适合可视化

from sklearn.manifold import TSNE
# t-SNE降维
tsne = TSNE(n_components=2, random_state=42, perplexity=30)
X_tsne = tsne.fit_transform(X_scaled)
print("t-SNE降维后数据形状:", X_tsne.shape)
# 可视化
plt.figure(figsize=(8, 6))
for i, color in enumerate(colors):
    plt.scatter(X_tsne[y == i, 0], X_tsne[y == i, 1], 
                c=color, label=iris.target_names[i])
plt.xlabel('t-SNE特征1')
plt.ylabel('t-SNE特征2')'t-SNE降维到2D')
plt.legend()
plt.grid(True)
plt.show()

线性判别分析(LDA)- 监督降维

from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
# LDA降维(注意:LDA是监督方法,需要标签)
lda = LinearDiscriminantAnalysis(n_components=2)
X_lda = lda.fit_transform(X_scaled, y)
print("LDA降维后数据形状:", X_lda.shape)
# 可视化
plt.figure(figsize=(8, 6))
for i, color in enumerate(colors):
    plt.scatter(X_lda[y == i, 0], X_lda[y == i, 1], 
                c=color, label=iris.target_names[i])
plt.xlabel('LDA特征1')
plt.ylabel('LDA特征2')'LDA降维到2D')
plt.legend()
plt.grid(True)
plt.show()

自动编码器(Autoencoder)- 深度学习降维

from sklearn.neural_network import MLPRegressor
from sklearn.model_selection import train_test_split
# 使用简单的神经网络实现自动编码器
class SimpleAutoencoder:
    def __init__(self, input_dim, encoding_dim):
        self.input_dim = input_dim
        self.encoding_dim = encoding_dim
        # 编码器:从输入到编码层
        self.encoder = MLPRegressor(
            hidden_layer_sizes=(8, encoding_dim),
            activation='relu',
            max_iter=1000,
            random_state=42
        )
        # 解码器:从编码层到输出
        self.decoder = MLPRegressor(
            hidden_layer_sizes=(encoding_dim, 8),
            activation='relu',
            max_iter=1000,
            random_state=42
        )
        self.encoded_data = None
    def fit(self, X):
        # 训练编码器
        self.encoder.fit(X, X)  # 自监督学习
        # 获取编码表示
        self.encoded_data = self.encoder.transform(X)
        # 训练解码器
        self.decoder.fit(self.encoded_data, X)
        return self
    def transform(self, X):
        return self.encoder.transform(X)
    def reconstruct(self, X):
        encoded = self.encoder.transform(X)
        return self.decoder.transform(encoded)
# 使用自动编码器
ae = SimpleAutoencoder(input_dim=4, encoding_dim=2)
ae.fit(X_scaled)
# 获取降维结果
X_ae = ae.transform(X_scaled)
print("自动编码器降维后数据形状:", X_ae.shape)
# 可视化
plt.figure(figsize=(8, 6))
for i, color in enumerate(colors):
    plt.scatter(X_ae[y == i, 0], X_ae[y == i, 1], 
                c=color, label=iris.target_names[i])
plt.xlabel('编码特征1')
plt.ylabel('编码特征2')'自动编码器降维到2D')
plt.legend()
plt.grid(True)
plt.show()

对比不同降维方法

# 比较不同方法的性能
methods = {
    'PCA': PCA(n_components=2),
    't-SNE': TSNE(n_components=2, random_state=42),
    'LDA': LinearDiscriminantAnalysis(n_components=2)
}
fig, axes = plt.subplots(1, 3, figsize=(15, 5))
for ax, (name, method) in zip(axes, methods.items()):
    if name == 'LDA':
        X_transformed = method.fit_transform(X_scaled, y)
    else:
        X_transformed = method.fit_transform(X_scaled)
    for i, color in enumerate(colors):
        ax.scatter(X_transformed[y == i, 0], X_transformed[y == i, 1], 
                  c=color, label=iris.target_names[i], alpha=0.7)
    ax.set_title(f'{name}降维结果')
    ax.legend()
    ax.grid(True)
plt.tight_layout()
plt.show()

实战案例:高维数据降维

from sklearn.datasets import make_classification
from sklearn.model_selection import cross_val_score
from sklearn.ensemble import RandomForestClassifier
# 生成高维数据
X_high, y_high = make_classification(
    n_samples=200, 
    n_features=50, 
    n_informative=10,
    n_redundant=10,
    random_state=42
)
print("高维数据形状:", X_high.shape)
# 标准化
scaler = StandardScaler()
X_high_scaled = scaler.fit_transform(X_high)
# 使用PCA降维
pca_high = PCA(n_components=0.95)  # 保留95%的方差
X_high_pca = pca_high.fit_transform(X_high_scaled)
print("\n保留95%方差所需的主成分数:", X_high_pca.shape[1])
print("各主成分解释方差比:", pca_high.explained_variance_ratio_)
# 比较降维前后的分类性能
# 原始数据
rf_original = RandomForestClassifier(random_state=42)
score_original = cross_val_score(rf_original, X_high_scaled, y_high, cv=5)
# 降维后数据
rf_reduced = RandomForestClassifier(random_state=42)
score_reduced = cross_val_score(rf_reduced, X_high_pca, y_high, cv=5)
print("\n原始数据分类准确率: {:.2f} (+/- {:.2f})".format(
    score_original.mean(), score_original.std() * 2))
print("降维后数据分类准确率: {:.2f} (+/- {:.2f})".format(
    score_reduced.mean(), score_reduced.std() * 2))
  1. PCA:最常用的线性降维,适合数据各维度相关性较高的情况
  2. t-SNE:非线性降维,擅长保持数据的局部结构,主要用於可视化
  3. LDA:监督降维,最大化类间距离,最小化类内距离
  4. 自动编码器:适合复杂非线性结构的数据,但需要较多数据

选择建议

  • 特征数量多且线性相关 → PCA
  • 需要可视化高维数据 → t-SNE
  • 有标签数据,分类任务 → LDA
  • 数据复杂且数据量大 → 自动编码器
  • 需要保持全局结构 → PCA
  • 需要保持局部结构 → t-SNE

通过上述案例,你可以根据具体需求选择合适的降维方法,降维不仅能减少计算复杂度,还能去除噪声、可视化数据分布、提升模型性能。

抱歉,评论功能暂时关闭!