使用t-SNE可视化高维数据
该示例演示如何可视化MNIST数据[1],该数据由手写数字的图像组成tsne
函数。这些图像是28 × 28像素的灰度。每张图像都有一个从0到9的关联标签,这是图像所代表的数字。tsne
使用PCA将数据的维数从原来的784维减少到50维,然后使用t-SNE Barnes-Hut算法将数据的维数减少到2 - 3维。
获得数据
从获取图像和标签数据开始
http://yann.lecun.com/exdb/mnist/
解压文件。对于本例,使用t10k-images
数据。
imageFileName =“t10k-images.idx3-ubyte”;labelFileName =“t10k-labels.idx1-ubyte”;
处理文件,将它们加载到工作区中。这个处理函数的代码出现在这个示例的末尾。
[X, L] = processMNISTdata (imageFileName labelFileName);
读取MNIST图像数据…数据集中的图像数量:10000…每张图片都是28 × 28像素。图像数据被读取到一个维度的矩阵:10000 × 784…图像数据读取结束。读取MNIST标签数据…数据集中标签的数量:10000…标签数据被读取到一个维度的矩阵:10000 × 1…标签数据读取结束。
将数据降维为二
利用t-SNE获得数据簇的二维模拟。使用PCA将初始维数降低到50。使用Barnes-Hut t-SNE算法的变体可以在这个相对较大的数据集上节省时间。
rng默认的%的再现性Y = tsne (X,“算法”,“barneshut”,“NumPCAComponents”, 50);
显示结果,用正确的标签着色。
图numGroups = length(唯一的(L));clr = hsv (numGroups);gscatter (Y (: 1), Y (:, 2), L, clr)
t-SNE仅根据与真实标签密切对应的相对相似性创建点集群。
减少数据维数为3
t-SNE还可以将数据简化为三维。设置tsne
“NumDimensions”
名称-值对3.
.
rng默认的%进行公平比较Y3 = tsne (X,“算法”,“barneshut”,“NumPCAComponents”, 50岁,“NumDimensions”3);图scatter3 (Y3 (: 1), Y3 (:, 2), Y3(:, 3), 15日,clr (L + 1,:)“填充”);视图(-93,14)
下面是将数据读入工作区的函数代码。
函数[X,L] = processMNISTdata(imageFileName,labelFileName) [fileID,errmsg] = fopen(imageFileName, labelFileName)“r”,“b”);如果fileID < 0 error(errmsg);结束% %先读这个神奇的数字。图像数据的数字是2051% 2049为标签数据magicNum =从文件中读(文件标识,1“int32”0,“b”);如果magicNum == 2051 fprintf(\n读取MNIST图像数据…\n')结束% %然后读取图像的数量,行数和列数numImages =从文件中读(文件标识,1“int32”0,“b”);流('数据集中的图像数量:%6d…\n', numImages);numRows =从文件中读(文件标识,1“int32”0,“b”);numCols =从文件中读(文件标识,1“int32”0,“b”);流('每个图像的像素为%2d * %2d…\n'numRows numCols);% %%读取图像数据X =从文件中读(inf文件标识,“无符号字符”);% %将数据重塑为数组XX =重塑(X, numCols numRows numImages);X = permute(X,[2 1 3]);% %然后将每个图像数据压平为1 × (numRows*numCols)向量,并将所有图像数据存储到numImages by (numRows*numCols)数组中。X =重塑(X, numRows * numCols numImages) ';流(['图像数据被读取到一个维度矩阵:%6d by %4d…\n',...'读取图像数据结束。\n'),大小(X, 1),大小(X, 2));% %%关闭文件文件关闭(文件标识);% %同样,读取标签数据。[文件标识,errmsg] = fopen (labelFileName,“r”,“b”);如果fileID < 0 error(errmsg);结束magicNum =从文件中读(文件标识,1“int32”0,“b”);如果magicNum == 2049 fprintf(\n读取MNIST标签数据…\n')结束numItems =从文件中读(文件标识,1“int32”0,“b”);流('数据集中标签的数量:%6d…\n', numItems);L =从文件中读(inf文件标识,“无符号字符”);流(['标签数据被读取到一个维度矩阵:%6d by %2d…\n',...'标签数据读取结束。\n'),大小(L, 1),大小(L, 2));文件关闭(文件标识);
参考文献
[1] Yann LeCun(纽约大学库朗研究所)和Corinna Cortes(纽约谷歌实验室)拥有MNIST数据集的版权,该数据集是NIST原始数据集的衍生作品。MNIST数据集是根据创作共用属性相似共享3.0许可条款提供的,https://creativecommons.org/licenses/by-sa/3.0/