从Word2vec可视化算法t-SNE谈起

刚好最近经常看一些word2vec的文章,在最后往往看到作者说用t-SNE可视化结果,也即把高维度的数据降维并可视化。很奇怪作者为何不用PCA或者LDA,深挖下去挖出了一个未曾了解过的可视化算法领域
降维,所有人都知道就是把特征维度降低后并力求保留有用的信息。
说起降维,大部分人知道PCA(Principal Components Analysis)
说起降维,部分人知道LDA(Linear Discriminant Analysis)
【从Word2vec可视化算法t-SNE谈起】说起降维,少部分人知道一般分为线性降维和非线性降:
1,线性降维:PCA(Principal Components Analysis)
LDA(Linear Discriminant Analysis)
MDS(Classical Multidimensional Scaling)
2,非线性降维:
Isomap(Isometric Mapping)
LLE(Locally Linear Embedding)
LE(Laplacian Eigenmaps)
t-SNE(t-Distributed Stochastic Neighbor Embedding)
大家可能对线性降维中的一些方法比较熟悉了,但是对非线性降维并不了解,非线性降维中用到的方法大多属于流形学习范畴,本文主要通过聊聊怎么使用其中的t-SNE来入门下流形学习。
我们的少部分人知道t-SNE算法已经成为了Scikit-learn的功能模块,主要用于可视化和理解高维数据。在此文中,将学习其基本算法核心思想,并结合些例子演示如何使用Scikit-learn来调用t-SNE。
t-SNE sklearn实现 1)t-SNE是什么?
t-SNE字面上的理解是t分布与SNE结合,所以问题变成了SNE是什么,为何要和t分布结合。
SNE:即stochastic neighbor embedding,由Hinton于2002年提出的可视化算法:在高维空间相似的数据点,映射到低维空间距离也是相似的。
t-SNE:2008年Maaten 和Hinton结合t分布改进了SNE,解决了SNE棘手的问题之一:拥挤问题,即不同类别边缘不清晰,当然t-SNE还有其他缺点,如大数据可视化有点吃力。
2)首先使用Iris dataset可视化说明t-SNE与PCA的线性与非线性可视化:
如下图所示:类别只有三类的情况下,我们看到t-SNE和PCA都可以较好的分类并进行可视化。

从Word2vec可视化算法t-SNE谈起
文章图片
三类可视化对比

from sklearn.manifold import TSNE from sklearn.decomposition import PCA

我们注意到PCA在sklearn使用decomposition模块,而t-SNE使用manifold模块,那manifold模块(翻译成流形学习)的功能是什么呢,首先得了解什么是流形学习:
流形学习为拓扑学与机器学习的结合,可以用来对高维数据降维,如果将维度降到2维或3维,我们就能将原始数据可视化,从而对数据的分布有直观的了解,发现一些可能存在的规律。
流形学习的前提假设,即某些高维数据,实际是一种低维的流形结构嵌入在高维空间中。流形学习的目的是将其映射回低维空间中,揭示其本质。如下图所示:右图为左图的降维后的展示,是不是更直观,更“流形”。(图片来源知乎)

从Word2vec可视化算法t-SNE谈起
文章图片
image.png Manifold learning is an approach to non-linear dimensionality reduction。传统的线性降维(PCA,LDA)会经常学不到重要的非线性数据特征,也即官网所说: it learns the high-dimensional structure of the data from the data itself, without the use of predetermined classifications,主要流行算法如下图所示:

从Word2vec可视化算法t-SNE谈起
文章图片
主要流行算法 3)当维度较高时,且数据较稀缺的时候我们比较下PCA和t-SNE的可视化效果
我们使用sklearn关于20newsgroups,如官网介绍:
The 20 newsgroups dataset comprises around 18000 newsgroups posts on 20 topics split in two subsets: one for training (or development) and the other one for testing (or for performance evaluation).
我们可以通过设置参数subset调用对应的训练或测试数据或者全部数据
subset='train'
subset='test'
subset='all'
选择所有数据,类目限制四个主题文章,并调用TfidfVectorizer抽取文本为特征向量。
categories = ['alt.atheism','talk.religion.misc', 'comp.graphics', 'sci.space'] newsgroups = fetch_20newsgroups(subset="all", categories=categories) vectorizer = TfidfVectorizer() vectors = vectorizer.fit_transform(newsgroups.data)

理解所使用的实验数据,我们发现数据非常稀缺,稀缺度为0.42%
计算样本数2588个
print(newsgroups.filenames.shape)

计算向量维度38137维向量
print(vectors.shape)

计算非0共406180个
print(vectors.nnz)

计算每个样本有多少个非0features,共156个。
print(vectors.nnz / float(vectors.shape[0]))

计算非0特征占比,判断特征稀缺程度,结果为0.42%,非常稀缺
print(vectors.nnz / float(vectors.shape[0])/38137)

通过help(TSNE)我们发现其往往会根据稀缺程度来决定选择PCA还是truncatedSVD先降维至50维。由上可知,数据非常稀缺,择TruncatedSVD先降维至50维,我们发现t-SNE可视化效果要明显好于PCA。
TSNE可视化:
reduced = TruncatedSVD(n_components=50).fit_transform(vectors) embedded = TSNE(n_components=2, perplexity=30).fit_transform(reduced)fig = plt.figure(figsize=(15, 5)) plt.subplot(131) plt.title('The 20 newsgroups datasetwith TSNE') plt.scatter(embedded[:, 0], embedded[:, 1],c=newsgroups.target, marker="x") ![image.png](https://upload-images.jianshu.io/upload_images/1676597-8216faad09544183.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

PCA可视化(注意要先转换vectors.todense())
reduced_with_PCA = PCA(n_components=2).fit_transform(vectors.todense()) plt.subplot(133) plt.title('The 20 newsgroups dataset with PCA') plt.scatter(reduced_with_PCA[:, 0], reduced_with_PCA[:, 1],\ c=newsgroups.target, marker="x")

从Word2vec可视化算法t-SNE谈起
文章图片
image.png
from sklearn.manifold import TSNE import matplotlib.pyplot as plt from sklearn.decomposition import PCA from sklearn.datasets import fetch_20newsgroups from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.decomposition import TruncatedSVD#选择所有数据,并抽取四个主题文章 categories = ['alt.atheism','talk.religion.misc', 'comp.graphics', 'sci.space'] newsgroups = fetch_20newsgroups(subset="all", categories=categories) vectorizer = TfidfVectorizer() vectors = vectorizer.fit_transform(newsgroups.data) #计算样本数2588个 print(newsgroups.filenames.shape) #计算向量维度38137维向量 print(vectors.shape) #计算非0共406180个 print(vectors.nnz) #计算每个样本有多少个非0features,共156个。 print(vectors.nnz / float(vectors.shape[0])) #计算非0特征占比,判断特征稀缺程度,结果为0.42%,非常稀缺 print(vectors.nnz / float(vectors.shape[0])/38137)#由于非常稀缺,根据 help(t-SNE),选择TruncatedSVD先降维至50维 #reduced = TruncatedSVD(n_components=50).fit_transform(vectors) reduced = PCA(n_components=50).fit_transform(vectors.todense())#传入TSNE中 embedded = TSNE(n_components=2, perplexity=30).fit_transform(reduced) #可视化fig = plt.figure(figsize=(15, 5))plt.subplot(131) plt.title('The 20 newsgroups datasetwith TSNE') plt.scatter(embedded[:, 0], embedded[:, 1],c=newsgroups.target, marker="x") reduced_with_TruncatedSVD = TruncatedSVD(n_components=2).fit_transform(vectors) plt.subplot(132)plt.title('The 20 newsgroups dataset with TruncatedSVD') plt.scatter(reduced_with_TruncatedSVD[:, 0], reduced_with_TruncatedSVD[:, 1],c=newsgroups.target, marker="x")reduced_with_PCA = PCA(n_components=2).fit_transform(vectors.todense()) plt.subplot(133) plt.title('The 20 newsgroups dataset with PCA') plt.scatter(reduced_with_PCA[:, 0], reduced_with_PCA[:, 1],\ c=newsgroups.target, marker="x")

参考:
从SNE到t-SNE再到LargeVis
http://bindog.github.io/blog/2016/06/04/from-sne-to-tsne-to-largevis?utm_source=tuicool&utm_medium=referral
http://nbviewer.jupyter.org/urls/gist.githubusercontent.com/AlexanderFabisch/1a0c648de22eff4a2a3e/raw/59d5bc5ed8f8bfd9ff1f7faa749d1b095aa97d5a/t-SNE.ipynb

    推荐阅读