t-SNE初学

http://www.datakit.cn/blog/2015/08/06/t_SNE.html

本文主要参考wikipedia,介绍t-SNE算法,以及python下的一些实现可视化应用。

目录

1、概述

最开始接触t-SNE是在kaggle的比赛里,看到很多人提到t-SNE,用于降维和可视化。以前在可视化高维数据的时候,一般是降维到2维里可视化,降维的方法通常选择PCA,但是PCA是线性的,效果比较一般。这里介绍的t-SNE(t-distributed stochastic neighbor embedding)是用于降维的一种机器学习算法,是由 Laurens van der Maaten 和 Geoffrey Hinton在08年提出来的,论文参见JMLR-Visualizing High-Dimensional Data Using t-SNE。t-SNE 是一种非线性降维算法,非常适用于高维数据降维到2维或者3维,进行可视化。

2、原理

2.1基本原理

t-SNE主要包括两个步骤:第一、t-SNE构建一个高维对象之间的概率分布,使得相似的对象有更高的概率被选择,而不相似的对象有较低的概率被选择。第二,t-SNE在低维空间里在构建这些点的概率分布,使得这两个概率分布之间尽可能的相似(这里使用KL散度(Kullback–Leibler divergence)来度量两个分布之间的相似性)。

2.2详细过程

具体来说,给定一个N个高维的数据 x1,...,xN x1,...,xN(注意N不是维度!), t-SNE首先是计算概率 pij pij,正比于 xi xi xj xj之间的相似度(这种概率是我们自主构建的),公式如下:

pji=exp(xixj2/(2σ2i))kiexp(xixk2/(2σ2i)) pj∣i=exp(−∣∣xi−xj∣∣2/(2σi2))∑k≠iexp(−∣∣xi−xk∣∣2/(2σi2))
pij=pjipij2N pij=pj∣ipi∣j2N

这里看到是用高斯核来构建了概率分布,那么怎么选择高斯核中的 σi σi呢?使用二分搜索得到条件概率分布的perplexity(后面再提到)。

t-SNE的目标是学习一个d维度的映射 yi,...,yN,yiRd yi,...,yN,yi∈Rd, 这里定义 yi yi yj yj之间的相似度 qij qij如下:

qij=(1+yiyj2)1kl(1+ykyl2)1 qij=(1+∣∣yi−yj∣∣2)−1∑k≠l(1+∣∣yk−yl∣∣2)−1

这里使用了学生分布来衡量低维度下点之间的相似度。最后,我们使用KL散度来度量Q和P之间的相似度:

C=KL(P)=ijpi,jlogpijqij C=KL(P∣∣)=∑i≠jpi,jlog⁡pijqij

之后使用梯度下降来最小化KL散度,梯度值如下:

dCdyi=4j(pijqij)(yiyj)(1+yiyj2)1 dCdyi=4∑j(pij−qij)(yi−yj)(1+∣∣yi−yj∣∣2)−1

t-SNE几乎在所有论文中的数据集上效果比 Sammon mapping, Isomap, and Locally Linear Embedding 要好。

2.4理由
  • 为什么选择这样的分布 论文中,开始使用了高斯核,之后改用了heavy-tailed t分布,因为这种t分布中  (1+yiyj2)1 (1+∣∣yi−yj∣∣2)−1与低维空间里 yiyj ∣∣yi−yj∣∣的二次成反比,能够使得不相似的两个对象被更好的分割
  • 高斯核中 σi σi的选择 高斯核中 σi σi的选择, 不同的i是对应了不同的 σi σi,取值是用perplexity,当然可以直接看wiki和论文了,这里简单的叙述下perplexity定义为:  Perp(Pi)=2H(Pi) Perp(Pi)=2H(Pi) ,其中, H(Pi) H(Pi) Pi Pi的信息熵,即 H(Pi)=jpjilog2p(ji) H(Pi)=−∑jpj∣ilog2⁡p(j∣i), 可以解释为实际有效近邻数。

3、算法流程

Simple version of t-Distributed Stochastic Neighbor Embedding

  • Data:  X=x1,...,xn X=x1,...,xn
  • 计算cost function的参数: perplexity Perp
  • 优化参数: 设置迭代次数T, 学习速率 η η, 动量 α(t) α(t)
  • 目标结果是低维数据表示  YT=y1,...,yn YT=y1,...,yn
  • 开始优化
    • 计算在给定Perp下的条件概率 pji pj∣i(参见上面公式)
    • 令  pij=pji+pij2n pij=pj∣i+pi∣j2n
    • 用  N(0,104I) N(0,10−4I) 随机初始化 Y
    • 迭代,从 t = 1 到 T, 做如下操作:
      • 计算低维度下的  qij qij(参见上面的公式)
      • 计算梯度(参见上面的公式)
      • 更新  Yt=Yt1+ηdCdY+α(t)(Yt1Yt2) Yt=Yt−1+ηdCdY+α(t)(Yt−1−Yt−2)
    • 结束
  • 结束

4、python试用

# Authors: Fabian Pedregosa <fabian.pedregosa@inria.fr>
#          Olivier Grisel <olivier.grisel@ensta.org>
#          Mathieu Blondel <mathieu@mblondel.org>
#          Gael Varoquaux
# License: BSD 3 clause (C) INRIA 2011

print(__doc__)
from time import time

import numpy as np
import matplotlib.pyplot as plt
from matplotlib import offsetbox
from sklearn import (manifold, datasets, decomposition, ensemble, lda,
                     random_projection)

digits = datasets.load_digits(n_class=6)
X = digits.data
y = digits.target
n_samples, n_features = X.shape
n_neighbors = 30


#----------------------------------------------------------------------
# Scale and visualize the embedding vectors
def plot_embedding(X, title=None):
    x_min, x_max = np.min(X, 0), np.max(X, 0)
    X = (X - x_min) / (x_max - x_min)

    plt.figure()
    ax = plt.subplot(111)
    for i in range(X.shape[0]):
        plt.text(X[i, 0], X[i, 1], str(digits.target[i]),
                 color=plt.cm.Set1(y[i] / 10.),
                 fontdict={'weight': 'bold', 'size': 9})

    if hasattr(offsetbox, 'AnnotationBbox'):
        # only print thumbnails with matplotlib > 1.0
        shown_images = np.array([[1., 1.]])  # just something big
        for i in range(digits.data.shape[0]):
            dist = np.sum((X[i] - shown_images) ** 2, 1)
            if np.min(dist) < 4e-3:
                # don't show points that are too close
                continue
            shown_images = np.r_[shown_images, [X[i]]]
            imagebox = offsetbox.AnnotationBbox(
                offsetbox.OffsetImage(digits.images[i], cmap=plt.cm.gray_r),
                X[i])
            ax.add_artist(imagebox)
    plt.xticks([]), plt.yticks([])
    if title is not None:
        plt.title(title)


#----------------------------------------------------------------------
# Plot images of the digits
n_img_per_row = 20
img = np.zeros((10 * n_img_per_row, 10 * n_img_per_row))
for i in range(n_img_per_row):
    ix = 10 * i + 1
    for j in range(n_img_per_row):
        iy = 10 * j + 1
        img[ix:ix + 8, iy:iy + 8] = X[i * n_img_per_row + j].reshape((8, 8))

plt.imshow(img, cmap=plt.cm.binary)
plt.xticks([])
plt.yticks([])
plt.title('A selection from the 64-dimensional digits dataset')


#----------------------------------------------------------------------
# Projection on to the first 2 principal components

print("Computing PCA projection")
t0 = time()
X_pca = decomposition.TruncatedSVD(n_components=2).fit_transform(X)
plot_embedding(X_pca,
               "Principal Components projection of the digits (time %.2fs)" %
               (time() - t0))

#----------------------------------------------------------------------
# Projection on to the first 2 linear discriminant components

print("Computing LDA projection")
X2 = X.copy()
X2.flat[::X.shape[1] + 1] += 0.01  # Make X invertible
t0 = time()
X_lda = lda.LDA(n_components=2).fit_transform(X2, y)
plot_embedding(X_lda,
               "Linear Discriminant projection of the digits (time %.2fs)" %
               (time() - t0))

#----------------------------------------------------------------------
# t-SNE embedding of the digits dataset
print("Computing t-SNE embedding")
tsne = manifold.TSNE(n_components=2, init='pca', random_state=0)
t0 = time()
X_tsne = tsne.fit_transform(X)

plot_embedding(X_tsne,
               "t-SNE embedding of the digits (time %.2fs)" %
               (time() - t0))

plt.show()

附录:Manifold Learning 可以参考sklearn的文档

### 回答1: t-sne是一种流行的非线性降维算法,可用于将高维数据可视化为二维或三维空间中的分布。在Matlab中,t-sne可以通过使用“t-SNE Toolbox”扩展包实现。该工具包提供了一组功能丰富的函数,使用户能够轻松地将高维数据集转换为低维表示。 使用t-SNE Toolbox进行t-sne分析的基本流程如下: 1. 准备数据:将数据加载到Matlab工作空间中,并将其整理成一个矩阵,其中每一行对应于一个观测值,每一列对应于一个特征。 2. 配置参数: T-SNE Toolbox提供了几个参数,可用于控制t-sne分析的参数,例如,迭代次数、惯性、邻域尺度等。 3. 运行t-sne算法:使用t-SNE Toolbox提供的函数运行t-sne算法,从而将高维数据可视化为低维空间中的分布。 4. 可视化结果:在低维空间中可视化数据,并对其中的聚类、局部密度等进行分析,以获得对始数据集的更深入的理解。 例如,可以使用t-SNE Toolbox中的“tsne_d”函数将高维数据降维到二维空间中,并使用“scatter”函数在二维空间中绘制散点图,展示从高维数据中提取的特征和模式。 总之,t-sne是一种常用的非线性降维算法,它可以帮助我们更好地理解高维数据集中的复杂模式,而在Matlab中,使用t-SNE Toolbox工具包能够很方便地实现这种算法,并可视化分析结果。 ### 回答2: t-SNE(T-Stochastic Neighbor Embedding)是一种用于数据降维和可视化的算法。在matlab中,用户可以使用t-SNE工具箱来实现t-SNE算法。 使用t-SNE工具箱的第一步是加载数据,可以将数据加载为矩阵或读取外部文件。然后,可以使用t-SNE函数将数据集投影到二维平面或三维空间中。在使用t-SNE函数之前,需要设置一些参数,例如迭代次数、数据集的维数、正则化参数等。用户还可以通过指定不同的颜色、符号和标签等方式来定制可视化图形。 t-SNE算法的一个实际应用是分析人脑神经元活动。可以将神经元活动数据投影到二维图中,并通过可视化来发现神经元之间的联系和集群。此外,t-SNE还可以在其他领域中被广泛应用,例如计算机视觉、自然语言处理和基因组学等领域。 ### 回答3: t-sne是一种流行的降维算法,它可以将高维数据映射到二维或三维空间,方便数据可视化和分析。在Matlab中,可以通过调用t-sne函数来实现这一过程。 在Matlab中调用t-sne函数的方法非常简单。首先,需要将数据读入Matlab中,并进行必要的预处理,如归一化和特征选择等。然后,调用t-sne函数,并设置一些参数,如输入数据、输出维度、学习率等。最后,可以将结果可视化,以便进一步分析和研究。 例如,假设我们有一个高维数据集,其中包含1000个样本和100个特征。我们想将这些数据映射到二维空间中以便进行可视化。在Matlab中,可以按照以下步骤操作: 1.读入数据并进行预处理,如标准化和PCA。 2.调用t-sne函数,设置参数。例如,我们可以设置输入数据为标准化后的数据、输出维度为2、学习率为200和迭代次数为1000。这个函数会返回一个二维矩阵,其中每一行表示一个样本在二维空间中的坐标。 3.将结果可视化,以便进一步分析和研究。在Matlab中,可以使用plot或scatter函数绘制散点图,其中x和y坐标为t-sne函数输出的二维矩阵的第一列和第二列。 t-sne在Matlab中的实例应用非常广泛,其应用范围包括图像识别、文本分类、时间序列分析等。无论是初学者还是专业人士,都可以轻松地使用这个强大的工具来降低数据的维度,增强数据可视化和分析的能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值