sklearn降维方法举例(RandomProjection,TSVD,t-SNE)
来源:互联网 发布:js ajax视频教程 编辑:程序博客网 时间:2024/06/08 11:34
sklearn降维方法举例
以datasets.digits数据为例导入相关包
import numpy as npimport pandas as pdimport matplotlib.pyplot as pltimport timefrom sklearn.datasets import load_digits
大样本数据的可视化是一个相对比较麻烦的事情,
一般情况下我们都要用到降维的方法先处理特征。我们找一个例子来看看,可以怎么做,比如我们数据集取经典的『手写数字集』
Each datapoint is a 8x8 image of a digit.
Classes->10
Samples per class->180
Samples total->1797
Dimensionality->64
Features integers->0-16
导入数据,0,1,2,3,4,5,6这7个数字的手写图像
digits = load_digits(n_class=7)#integerX = digits.datay = digits.targetn_samples,n_features = X.shape
输出图像
from matplotlib import offsetboxdef 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)#正则化 print X plt.figure(figsize=(10, 10)) 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': 12}) #打印彩色字体 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)
1.随机投射(Random-Projection)
首先我们来看一个问题, 如果你手头有一组数据X∈Rn , 它的维数太高, 从而不得不进行降维至Rk , 你会怎么办?
相信不少人反射性地求它的x′x ,然后转化为延最大方差展开的问题。 当然这个方法需要求解固有值和固有向量。对于测试用的小数据一切似乎都很好, 但如果我给你的是50G大小csv格式的Twitter发言呢?如果需要对全部单词降维, 恐怕半个月吧。 因此我们需要个更加快速的方法。
那么现在再来想, 既然要快, 那我们就用个最简单的方法: 随机在高维空间里选几个单位向量ei , 但注意, 这里我们仅仅要求是单位向量, 并没有要求它们之间必须正交<ei,ej>=0 , 因此你可以随便选。 最后, 我们把高维数据投影到选择的这一组基上。也就完成了降维。
随便选的轴如何能保证降维效果? 但它是有数学依据的, 叫做Johnson-Lindenstrauss Lemma。这个定理保证了任何降维方法的精度上下限。
Johnson-Lindenstrauss Lemma
假设我们有数据x∈Rn , 而我们通过一种方法f(x) 将其降维成y∈Rk , 那么, 将为前后任意两点a,b 之间的距离有不等式保证:
对于随机映射来说, 只要注意到下面几点就行了:
1.不定式中的精度仅仅受制于维数、数据大小等因素, 与将为方法无关。
2.在维数差不是很大时, 总可以保证一个相对较高的精度, 不论用什么方法。
3.到这里一切就很明显了, 既然精度有上界, 那我们也就不必担心轴的选取,那么最简单的方法自然就是随机挑选了, 这也就产生的Random Projection这一方法。
Random Projection
简单来说,Random Projection流程就是
选择影射矩阵R∈RK×N 。
用随机数填充影射矩阵。 可以选择uniform或者gaussian。
归一化每一个新的轴(影射矩阵中的每一行)。
对数据降维y=RX 。
上个小节里面的JL-lemma保证的降维的效果不会太差。
从直观上来看看。
首先假设我们有数据X={x|fi(θ)+σ} , 其中θ 是一组参数, σ 则是高斯噪声。 回想PCA方法, 我们很自然的认为所有的特征都是正交的, 我们既没有考虑它是不是有多个中心, 也没有考虑是不是有特殊结构, 然而对于实际数据, 很多时候并不是这样。 比如我们把取f(θ)=Si(θi)N(A,σi)∈R3 , 其中Si∈SO(3) , 这样我们得到的数据可能会像× 或者∗ 一样, 显然用PCA并不能得到好的结果。
在这种情况下, 考虑在非常高维度的空间, 可以想象random projection这种撞大运的方法总会选到一些超平面能够接近数据的特征, 同时也能够想象如果目标维数过低, 那么命中的概率就会大大降低。
实现:
from sklearn import random_projectionrp = random_projection.SparseRandomProjection(n_components=2, random_state=42)#随机映射算法start_time = time.time()X_projected = rp.fit_transform(X)#随机投射plot_embedding(X_projected, "Random Projection of the digits (time: %.3fs)" % (time.time() - start_time))plt.show()
时间很短但效果一般
官方描述:
def sparse_random_matrix(n_components, n_features, density='auto', random_state=None): """Generalized Achlioptas random sparse matrix for random projection Setting density to 1 / 3 will yield the original matrix by Dimitris Achlioptas while setting a lower value will yield the generalization by Ping Li et al. If we note :math:`s = 1 / density`, the components of the random matrix are drawn from: - -sqrt(s) / sqrt(n_components) with probability 1 / 2s - 0 with probability 1 - 1 / s - +sqrt(s) / sqrt(n_components) with probability 1 / 2s Read more in the :ref:`User Guide <sparse_random_matrix>`. Parameters ---------- n_components : int, Dimensionality of the target projection space. n_features : int, Dimensionality of the original source space. density : float in range ]0, 1] or 'auto', optional (default='auto') Ratio of non-zero component in the random projection matrix. If density = 'auto', the value is set to the minimum density as recommended by Ping Li et al.: 1 / sqrt(n_features). Use density = 1 / 3.0 if you want to reproduce the results from Achlioptas, 2001. random_state : integer, RandomState instance or None (default=None) Control the pseudo random number generator used to generate the matrix at fit time. Returns ------- components: numpy array or CSR matrix with shape [n_components, n_features] The generated Gaussian random matrix. """ _check_input_size(n_components, n_features) density = _check_density(density, n_features) rng = check_random_state(random_state) if density == 1: # skip index generation if totally dense components = rng.binomial(1, 0.5, (n_components, n_features)) * 2 - 1 return 1 / np.sqrt(n_components) * components else: # Generate location of non zero elements indices = [] offset = 0 indptr = [offset] for i in xrange(n_components): # find the indices of the non-zero components for row i n_nonzero_i = rng.binomial(n_features, density) indices_i = sample_without_replacement(n_features, n_nonzero_i, random_state=rng) indices.append(indices_i) offset += n_nonzero_i indptr.append(offset) indices = np.concatenate(indices) # Among non zero components the probability of the sign is 50%/50% data = rng.binomial(1, 0.5, size=np.size(indices)) * 2 - 1 # build the CSR structure by concatenating the rows components = sp.csr_matrix((data, indices, indptr), shape=(n_components, n_features)) return np.sqrt(1 / density) / np.sqrt(n_components) * components
2.TSVD(截断奇异值分解, TruncatedSVD,PCA的一种实现)
截断奇异值分解(Truncated singular value decomposition,TSVD)是一种矩阵因式分解(factorization)技术,将矩阵 M 分解成 U , Σ 和 V 。它与PCA很像,只是SVD分解是在数据矩阵上进行,而PCA是在数据的协方差矩阵上进行。通常,SVD用于发现矩阵的主成份。对于病态矩阵,目前主要的处理办法有预调节矩阵方法、区域分解法、正则化方法等,截断奇异值分解技术TSVD就是一种正则化方法,它牺牲部分精度换去解的稳定性,使得结果具有更高的泛化能力。
对于原始数据矩阵A(N*M) ,N代表样本个数,M代表维度,对其进行SVD分解:
上式中的δ 就是数据的奇异值,且δ1 >δ2 >δ3 …,通常如果A非常病态,delta的后面就越趋向于0,δ1δn 就是数据的病态程度,越大说明病态程度越高,无用的特征越多,通常会截取前p个最大的奇异值,相应的U截取前p列,V截取前p列,这样A依然是N*M的矩阵,用这样的计算出来的A代替原始的A,就会比原始的A更稳定。
TSVD与一般SVD不同的是它可以产生一个指定维度的分解矩阵。例如,有一个 n×n 矩阵,通过SVD分解后仍然是一个 n×n 矩阵,而TSVD可以生成指定维度的矩阵。这样就可以实现降维了。
演示一下TSVD工作原理
In[1]:import numpy as npfrom scipy.linalg import svdD = np.array([[1, 2], [1, 3], [1, 4]])D
Out[1]:array([[1, 2], [1, 3], [1, 4]])
In[2]:U, S, V = svd(D, full_matrices=False)#我们可以根据SVD的定义,用 UU , SS 和 VV 还原矩阵 DD U.shape, S.shape, V.shape
Out[2]:((3, 2), (2, 1), (2, 2))
In[3]:np.dot(U.dot(np.diag(S)), V)#还原
Out[3]:array([[ 1., 2.], [ 1., 3.], [ 1., 4.]])
TruncatedSVD返回的矩阵是 U 和 S 的点积。如果我们想模拟TSVD,我们就去掉最新奇异值和对于 U 的列向量。例如,我们想要一个主成份,可以这样:
In[4]:new_S = S[0]new_U = U[:, 0]new_U.dot(new_S)
Out[4]:array([-2.20719466, -3.16170819, -4.11622173])
TruncatedSVD有个“陷阱”。随着随机数生成器状态的变化,TruncatedSVD连续地拟合会改变输出的符合。为了避免这个问题,建议只用TruncatedSVD拟合一次,然后用其他变换。这正是管线命令的另一个用处。
实现:
from sklearn import decompositionX_pca = decomposition.TruncatedSVD(n_components=2).fit_transform(X)start_time = time.time()plot_embedding(X_pca,"Principal Components projection of the digits (time: %.3fs)" % (time.time() - start_time))plt.show()
效果稍微好一些
3.t-SNE(t-分布邻域嵌入算法)
流形学习方法(Manifold Learning),简称流形学习,可以将流形学习方法分为线性的和非线性的两种,线性的流形学习方法如我们熟知的主成份分析(PCA),非线性的流形学习方法如等距映射(Isomap)、拉普拉斯特征映射(Laplacian eigenmaps,LE)、局部线性嵌入(Locally-linear embedding,LLE)。
t-SNE详细介绍:http://lvdmaaten.github.io/tsne/
from sklearn import manifold#降维tsne = manifold.TSNE(n_components=2, init='pca', random_state=0)start_time = time.time()X_tsne = tsne.fit_transform(X)#绘图plot_embedding(X_tsne, "t-SNE embedding of the digits (time: %.3fs)" % (time.time() - start_time))plt.show()#这个非线性变换降维过后,仅仅2维的特征,就可以将原始数据的不同类别,在平面上很好地划分开。#不过t-SNE也有它的缺点,一般说来,相对于线性变换的降维,它需要更多的计算时间。
阅读全文
0 0
- sklearn降维方法举例(RandomProjection,TSVD,t-SNE)
- Python中T-SNE实现降维
- DeepLearning:二、t-SNE(Stochastic Neighbor Embedding )降维方法
- 数据降维与可视化——t-SNE
- t-SNE
- t-SNE
- 诠释数据降维算法:一文讲尽t-分布邻域嵌入算法(t-SNE)如何有效利用
- 诠释数据降维算法:一文讲尽t-分布邻域嵌入算法(t-SNE)如何有效利用
- t-SNE介绍
- t-SNE初学
- t-SNE理解
- t-SNE详细介绍
- t-SNE学习笔记
- Visualizing with t-SNE
- 高维数据的可视化 Visualizing data using t-SNE
- t-SNE高维数据可视化(python)
- 理解 t-SNE (Python)
- 非常好的t-SNE介绍
- 小程序文档整理之 -- API(网络请求)
- Max Sum Plus Plus m段连续子序列最大和
- 使用bazel编译tensorflow serving是报错:src/create_embedded_tools.sh: line 93: zip: command not found
- fasd
- android 定时器
- sklearn降维方法举例(RandomProjection,TSVD,t-SNE)
- python基础之模块之os模块
- PostgreSQL新手入门
- 转载资深程序员的总结经验
- selenium之unittest批量执行测试用例、生成html报告
- 嵌入式-1 uboot模式烧写镜像文件
- 【LintCode】数组的全排序(1)
- 如何限制checkbox最多勾选个数
- OpenCv--Mat矩阵(图像容器)的创建及CV_8UC1,CV_8UC2等参数详解