两个input_t-SNE实践(可视化两个图片数据集合的差异)
任务陈述:在Images目录下有两种图片,各500张,前500张为第一类,后500张为第二类如下图,可以看到两类的风格不一样,需要想办法将这两类降到2维或者3维聚类可视化。
两类图片数据集
在看下面内容之前,可以先看一下利用t-SEN手写数据集分类的例子,(文末也有实现)这也是各大博客最喜欢贴的例子,或者结合起来看。
直接上代码
确保python安装好了各个依赖库,特别是sklearn
第一部分是获取数据的代码:
无论你是什么类型的数据(图片,音频,文本等等),先将它先处理成np.array类型,确保data的形状为(数据条数,每条数据维度),label的形状(数据条数,) 方便后面调用t-SNE方法
import os import numpy as np import cv2 from time import time import numpy as np import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D from sklearn import datasets #手写数据集要用到 from sklearn.manifold import TSNE #该函数是关键,需要根据自己的数据加以修改,将图片存到一个np.array里面,并且制作标签 #因为是两类数据,所以我分别用0,1来表示 def get_data(Input_path): #Input_path为你自己原始数据存储路径,我的路径就是上面的'./Images' Image_names=os.listdir(Input_path) #获取目录下所有图片名称列表 data=np.zeros((len(Image_names),40000)) #初始化一个np.array数组用于存数据 label=np.zeros((len(Image_names),)) #初始化一个np.array数组用于存数据 #为前500个分配标签1,后500分配0 for k in range(500): label[k]=1 #读取并存储图片数据,原图为rgb三通道,而且大小不一,先灰度化,再resize成200x200固定大小 for i in range(len(Image_names)): image_path=os.path.join(Input_path,Image_names[i]) img=cv2.imread(image_path) img_gray=cv2.cvtColor(img,cv2.COLOR_RGB2GRAY) img=cv2.resize(img_gray,(200,200)) img=img.reshape(1,40000) data[i]=img n_samples, n_features = data.shape return data, label, n_samples, n_features ‘’‘下面的两个函数, 一个定义了二维数据,一个定义了3维数据的可视化 不作详解,也无需再修改感兴趣可以了解matplotlib的常见用法 ’‘’ def plot_embedding_2D(data, label, title): x_min, x_max = np.min(data, 0), np.max(data, 0) data = (data - x_min) / (x_max - x_min) fig = plt.figure() for i in range(data.shape[0]): plt.text(data[i, 0], data[i, 1], str(label[i]), color=plt.cm.Set1(label[i]), fontdict={'weight': 'bold', 'size': 9}) plt.xticks([]) plt.yticks([]) plt.title(title) return fig def plot_embedding_3D(data,label,title): x_min, x_max = np.min(data,axis=0), np.max(data,axis=0) data = (data- x_min) / (x_max - x_min) ax = plt.figure().add_subplot(111,projection='3d') for i in range(data.shape[0]): ax.text(data[i, 0], data[i, 1], data[i,2],str(label[i]), color=plt.cm.Set1(label[i]),fontdict={'weight': 'bold', 'size': 9}) return fig #主函数 def main(): data, label, n_samples, n_features = get_data('./Images') #根据自己的路径合理更改 print('Begining......') #时间会较长,所有处理完毕后给出finished提示 tsne_2D = TSNE(n_components=2, init='pca', random_state=0) #调用TSNE result_2D = tsne_2D.fit_transform(data) tsne_3D = TSNE(n_components=3, init='pca', random_state=0) result_3D = tsne_3D.fit_transform(data) print('Finished......') #调用上面的两个函数进行可视化 fig1 = plot_embedding_2D(result_2D, label,'t-SNE') plt.show(fig1) fig2 = plot_embedding_3D(result_3D, label,'t-SNE') plt.show(fig2) if __name__ == '__main__': main()
下面给出结果图:
降到2d可视化
降到3d的可视化
可以明显看出两类数据的差异巨大。t-SNE的降维能力实在是强悍!上面提到了”手写数据集“的例子,下面也作一个说明:
将上述get_data改成:
def get_data(Input_path) digits = datasets.load_digits(n_class=6) data = digits.data label = digits.target n_samples, n_features = data.shape return data, label, n_samples, n_features
这样就能实现手写数据集的分类可视化。
手写数据2d
手写数字3d