Python案例如何用Scikit-learn做降维TSNE

wen python案例 1

本文目录导读:

Python案例如何用Scikit-learn做降维TSNE

  1. 基础t-SNE降维示例
  2. 不同参数对比
  3. 完整的数据分析流程
  4. 与其他降维方法对比
  5. 高级t-SNE配置
  6. 实际应用:高维数据聚类分析
  7. 关键参数说明
  8. 注意事项

我来详细讲解如何使用Scikit-learn进行t-SNE降维的案例。

基础t-SNE降维示例

1 导入必要的库

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.datasets import load_digits, load_iris
from sklearn.manifold import TSNE
from sklearn.preprocessing import StandardScaler
import seaborn as sns

2 使用手写数字数据集

# 加载数据集
digits = load_digits()
X = digits.data
y = digits.target
print(f"原始数据维度: {X.shape}")
# 数据标准化
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
# t-SNE降维
tsne = TSNE(n_components=2, random_state=42)
X_tsne = tsne.fit_transform(X_scaled)
print(f"降维后数据维度: {X_tsne.shape}")
# 可视化
plt.figure(figsize=(12, 8))
scatter = plt.scatter(X_tsne[:, 0], X_tsne[:, 1], c=y, cmap='tab10', 
                     alpha=0.6, s=50)
plt.colorbar(scatter)'t-SNE Visualization of Digits Dataset', fontsize=16)
plt.xlabel('t-SNE Component 1')
plt.ylabel('t-SNE Component 2')
plt.show()

不同参数对比

def compare_tsne_params():
    """比较不同的t-SNE参数效果"""
    iris = load_iris()
    X = iris.data
    y = iris.target
    # 准备不同参数组合
    configs = [
        {'perplexity': 5, 'learning_rate': 200},
        {'perplexity': 30, 'learning_rate': 200},
        {'perplexity': 50, 'learning_rate': 200},
        {'perplexity': 30, 'learning_rate': 50}
    ]
    fig, axes = plt.subplots(2, 2, figsize=(14, 12))
    axes = axes.ravel()
    for idx, params in enumerate(configs):
        tsne = TSNE(n_components=2, random_state=42, **params)
        X_tsne = tsne.fit_transform(X)
        ax = axes[idx]
        scatter = ax.scatter(X_tsne[:, 0], X_tsne[:, 1], 
                           c=y, cmap='viridis', s=60)
        ax.set_title(f'Perplexity={params["perplexity"]}, '
                    f'Learning Rate={params["learning_rate"]}')
        ax.set_xlabel('Component 1')
        ax.set_ylabel('Component 2')
    plt.tight_layout()
    plt.show()
compare_tsne_params()

完整的数据分析流程

class TSNEAnalyzer:
    """t-SNE分析器"""
    def __init__(self, n_components=2, random_state=42):
        self.tsne = TSNE(n_components=n_components, random_state=random_state)
        self.embedding = None
    def fit_transform(self, X):
        """执行t-SNE降维"""
        # 数据标准化
        scaler = StandardScaler()
        X_scaled = scaler.fit_transform(X)
        # t-SNE降维
        self.embedding = self.tsne.fit_transform(X_scaled)
        return self.embedding
    def plot_embedding(self, labels=None, title="t-SNE Visualization"):
        """可视化降维结果"""
        plt.figure(figsize=(12, 8))
        if labels is not None:
            scatter = plt.scatter(self.embedding[:, 0], self.embedding[:, 1],
                                c=labels, cmap='tab10', alpha=0.6, s=50)
            plt.colorbar(scatter, label='Class')
        else:
            plt.scatter(self.embedding[:, 0], self.embedding[:, 1],
                       alpha=0.6, s=50)
        plt.title(title, fontsize=16)
        plt.xlabel('t-SNE Component 1')
        plt.ylabel('t-SNE Component 2')
        plt.grid(True, alpha=0.3)
        plt.show()
# 使用示例
tsne_analyzer = TSNEAnalyzer()
iris = load_iris()
X_tsne = tsne_analyzer.fit_transform(iris.data)
tsne_analyzer.plot_embedding(iris.target, "Iris Dataset t-SNE")

与其他降维方法对比

from sklearn.decomposition import PCA
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis as LDA
def compare_dimensionality_reduction():
    """比较不同降维方法"""
    iris = load_iris()
    X = iris.data
    y = iris.target
    # 不同降维方法
    methods = {
        'PCA': PCA(n_components=2),
        't-SNE': TSNE(n_components=2, random_state=42),
        'LDA': LDA(n_components=2)
    }
    fig, axes = plt.subplots(1, 3, figsize=(18, 5))
    for idx, (name, method) in enumerate(methods.items()):
        if name == 'LDA':
            X_transformed = method.fit_transform(X, y)
        else:
            X_transformed = method.fit_transform(X)
        ax = axes[idx]
        scatter = ax.scatter(X_transformed[:, 0], X_transformed[:, 1],
                           c=y, cmap='viridis', s=60)
        ax.set_title(f'{name} Visualization', fontsize=14)
        ax.set_xlabel('Component 1')
        ax.set_ylabel('Component 2')
        ax.grid(True, alpha=0.3)
        # 添加图例
        legend_elements = [plt.Line2D([0],[0], marker='o', color='w', 
                                    markerfacecolor=scatter.cmap(scatter.norm(i)), 
                                    markersize=10, label=f'Class {i}) 
                          for i in range(3)]
        ax.legend(handles=legend_elements, loc='best')
    plt.tight_layout()
    plt.show()
compare_dimensionality_reduction()

高级t-SNE配置

def advanced_tsne_example():
    """高级t-SNE配置示例"""
    # 生成模拟数据
    np.random.seed(42)
    n_samples = 300
    # 创建3个不同的簇
    X1 = np.random.randn(n_samples//3, 50) + [2]*50
    X2 = np.random.randn(n_samples//3, 50) + [-2]*50
    X3 = np.random.randn(n_samples//3, 50) + [0]*50
    X = np.vstack([X1, X2, X3])
    y = np.repeat([0, 1, 2], n_samples//3)
    # 高级t-SNE配置
    tsne_advanced = TSNE(
        n_components=2,           # 目标维度
        perplexity=30,            # 困惑度参数
        learning_rate=200,        # 学习率
        n_iter=1000,              # 迭代次数
        metric='euclidean',       # 距离度量
        init='pca',               # 初始化方法
        random_state=42,
        method='barnes_hut',      # 计算方法
        angle=0.5                 # 角度参数
    )
    X_tsne = tsne_advanced.fit_transform(X)
    # 可视化
    fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 6))
    # 原始数据维度
    ax1.bar(range(50), X[0, :50], alpha=0.6)
    ax1.set_title('原始数据维度 (50维)', fontsize=12)
    ax1.set_xlabel('特征维度')
    ax1.set_ylabel('特征值')
    # t-SNE降维结果
    scatter = ax2.scatter(X_tsne[:, 0], X_tsne[:, 1], 
                         c=y, cmap='Set2', s=50, alpha=0.7)
    ax2.set_title(f't-SNE降维结果\n迭代次数={tsne_advanced.n_iter}, '
                 f'困惑度={tsne_advanced.perplexity}', fontsize=12)
    ax2.set_xlabel('t-SNE Component 1')
    ax2.set_ylabel('t-SNE Component 2')
    plt.colorbar(scatter, ax=ax2, label='Cluster')
    plt.tight_layout()
    plt.show()
    # 输出t-SNE信息
    print(f"t-SNE KL散度: {tsne_advanced.kl_divergence_:.4f}")
    print(f"迭代次数: {tsne_advanced.n_iter_}")
advanced_tsne_example()

实际应用:高维数据聚类分析

def tsne_with_clustering():
    """t-SNE结合聚类分析"""
    from sklearn.cluster import KMeans
    from sklearn.metrics import silhouette_score
    # 使用make_classification生成高维数据
    from sklearn.datasets import make_classification
    X, y = make_classification(
        n_samples=500,
        n_features=20,
        n_informative=10,
        n_redundant=5,
        n_clusters_per_class=2,
        random_state=42
    )
    print(f"数据形状: {X.shape}")
    print(f"类别分布: {np.bincount(y)}")
    # t-SNE降维
    tsne = TSNE(n_components=2, random_state=42)
    X_tsne = tsne.fit_transform(X)
    # 在t-SNE空间进行聚类
    kmeans = KMeans(n_clusters=2, random_state=42)
    clusters = kmeans.fit_predict(X_tsne)
    # 计算轮廓系数
    silhouette_tsne = silhouette_score(X_tsne, clusters)
    silhouette_original = silhouette_score(X, clusters)
    # 可视化
    fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 6))
    # 真实标签
    scatter1 = ax1.scatter(X_tsne[:, 0], X_tsne[:, 1], 
                          c=y, cmap='coolwarm', s=50, alpha=0.7)
    ax1.set_title('真实类别标签', fontsize=14)
    ax1.set_xlabel('t-SNE Component 1')
    ax1.set_ylabel('t-SNE Component 2')
    plt.colorbar(scatter1, ax=ax1, label='True Class')
    # K-Means聚类结果
    scatter2 = ax2.scatter(X_tsne[:, 0], X_tsne[:, 1], 
                          c=clusters, cmap='Set1', s=50, alpha=0.7)
    ax2.set_title('K-Means聚类结果', fontsize=14)
    ax2.set_xlabel('t-SNE Component 1')
    ax2.set_ylabel('t-SNE Component 2')
    plt.colorbar(scatter2, ax=ax2, label='Cluster')
    plt.tight_layout()
    plt.show()
    print(f"t-SNE空间轮廓系数: {silhouette_tsne:.4f}")
    print(f"原始空间轮廓系数: {silhouette_original:.4f}")
tsne_with_clustering()

关键参数说明

参数 说明 建议值
n_components 降维目标维度 通常2或3
perplexity 困惑度,平衡局部/全局结构 5-50
learning_rate 学习率 10-1000
n_iter 最大迭代次数 250-1000
metric 距离度量 'euclidean'常用
init 初始化方法 'random'或'pca'

注意事项

  1. 计算复杂度:t-SNE计算量大,大数据集建议先采样
  2. 随机性:结果随随机种子变化,建议固定random_state
  3. 解释性:t-SNE保留下来的距离没有明确含义
  4. 预处理:降维前建议对数据做标准化处理

这些示例涵盖了t-SNE的主要应用场景,包括基础降维、参数调优、方法对比和实际应用分析。

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