本文目录导读:

我来详细讲解如何使用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' |
注意事项
- 计算复杂度:t-SNE计算量大,大数据集建议先采样
- 随机性:结果随随机种子变化,建议固定random_state
- 解释性:t-SNE保留下来的距离没有明确含义
- 预处理:降维前建议对数据做标准化处理
这些示例涵盖了t-SNE的主要应用场景,包括基础降维、参数调优、方法对比和实际应用分析。