t-SNE(t-distributed Stochastic Neighbor Embedding)是一种非线性降维技术,常用于高维数据的可视化。本文通过不同的困惑度值(perplexity)对t-SNE算法进行可视化分析,探讨了不同参数对算法结果的影响。困惑度是t-SNE中的一个重要参数,它影响着数据点之间的相似度权重。随着困惑度值的增加,算法倾向于产生更清晰的聚类形状,但聚类的大小、距离和形状可能会因初始化、困惑度值的不同而有所变化,并且并不总是具有实际意义。
在下面的分析中,可以看到,对于更高困惑度值的t-SNE,能够找到两个同心圆数据集有意义的拓扑结构,尽管圆的大小和距离与原始数据略有不同。与两个圆数据集相反,即使对于较大的困惑度值,S曲线数据集的形状在视觉上也与S曲线拓扑结构有所偏离。这些观察结果表明,t-SNE算法的结果受到多种因素的影响,包括困惑度值、初始化方式等,因此在实际应用中需要仔细调整这些参数。
为了更深入地理解t-SNE算法的效果,可以参考文章《How to Use t-SNE Effectively》(),该文章详细讨论了各种参数的影响,并提供了交互式图表来探索这些效果。在本文中,通过Python代码实现了t-SNE算法,并展示了不同困惑度值下的结果。代码中使用了matplotlib库来绘制散点图,以及sklearn库中的t-SNE实现。
以下是使用t-SNE算法对不同数据集进行降维的Python代码示例。代码中首先生成了两个同心圆的数据集,然后使用不同的困惑度值进行t-SNE降维,并绘制了结果。可以看到,随着困惑度值的增加,同心圆的聚类效果逐渐变得清晰。此外,代码还展示了S曲线数据集和2D均匀网格数据集的t-SNE结果,进一步说明了困惑度值对算法结果的影响。
from sklearn import manifold, datasets
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.ticker import NullFormatter
import time
n_samples = 150
n_components = 2
(plt.figure, plt.subplots) = (plt.Figure, plt.subplots)
perplexities = [5, 30, 50, 100]
# 生成两个同心圆的数据集
X, y = datasets.make_circles(n_samples=n_samples, factor=0.5, noise=0.05, random_state=0)
red = y == 0
green = y == 1
# 绘制原始数据集
ax = plt.subplots[0][0]
ax.scatter(X[red, 0], X[red, 1], c="r")
ax.scatter(X[green, 0], X[green, 1], c="g")
ax.xaxis.set_major_formatter(NullFormatter())
ax.yaxis.set_major_formatter(NullFormatter())
plt.axis("tight")
# 对不同的困惑度值进行t-SNE降维并绘制结果
for i, perplexity in enumerate(perplexities):
ax = plt.subplots[0][i + 1]
t0 = time.time()
tsne = manifold.TSNE(n_components=n_components, init="random", random_state=0, perplexity=perplexity, max_iter=300)
Y = tsne.fit_transform(X)
t1 = time.time()
print("circles, perplexity=%d in %.2g sec" % (perplexity, t1 - t0))
ax.set_title("Perplexity=%d" % perplexity)
ax.scatter(Y[red, 0], Y[red, 1], c="r")
ax.scatter(Y[green, 0], Y[green, 1], c="g")
ax.xaxis.set_major_formatter(NullFormatter())
ax.yaxis.set_major_formatter(NullFormatter())
ax.axis("tight")
# 绘制S曲线数据集的t-SNE结果
X, color = datasets.make_s_curve(n_samples, random_state=0)
ax = plt.subplots[1][0]
ax.scatter(X[:, 0], X[:, 2], c=color)
ax.xaxis.set_major_formatter(NullFormatter())
ax.yaxis.set_major_formatter(NullFormatter())
for i, perplexity in enumerate(perplexities):
ax = plt.subplots[1][i + 1]
t0 = time.time()
tsne = manifold.TSNE(n_components=n_components, init="random", random_state=0, perplexity=perplexity, learning_rate="auto", max_iter=300)
Y = tsne.fit_transform(X)
t1 = time.time()
print("S-curve, perplexity=%d in %.2g sec" % (perplexity, t1 - t0))
ax.set_title("Perplexity=%d" % perplexity)
ax.scatter(Y[:, 0], Y[:, 1], c=color)
ax.xaxis.set_major_formatter(NullFormatter())
ax.yaxis.set_major_formatter(NullFormatter())
ax.axis("tight")
# 绘制2D均匀网格数据集的t-SNE结果
x = np.linspace(0, 1, int(np.sqrt(n_samples)))
xx, yy = np.meshgrid(x, x)
X = np.hstack([xx.ravel().reshape(-1, 1), yy.ravel().reshape(-1, 1)])
color = xx.ravel()
ax = plt.subplots[2][0]
ax.scatter(X[:, 0], X[:, 1], c=color)
ax.xaxis.set_major_formatter(NullFormatter())
ax.yaxis.set_major_formatter(NullFormatter())
for i, perplexity in enumerate(perplexities):
ax = plt.subplots[2][i + 1]
t0 = time.time()
tsne = manifold.TSNE(n_components=n_components, init="random", random_state=0, perplexity=perplexity, max_iter=400)
Y = tsne.fit_transform(X)
t1 = time.time()
print("uniform grid, perplexity=%d in %.2g sec" % (perplexity, t1 - t0))
ax.set_title("Perplexity=%d" % perplexity)
ax.scatter(Y[:, 0], Y[:, 1], c=color)
ax.xaxis.set_major_formatter(NullFormatter())
ax.yaxis.set_major_formatter(NullFormatter())
ax.axis("tight")
plt.show()
通过上述代码,可以看到t-SNE算法在不同困惑度值下对同心圆、S曲线和2D均匀网格数据集的降维效果。这些结果进一步证实了困惑度值对t-SNE算法结果的重要影响。在实际应用中,需要根据数据集的特点和需求,合理选择困惑度值,以达到最佳的可视化效果。