t-SNE : 降维快速食用方法

因为最近用到分类训练器,所以使用降维和聚类策略可以检验分类效果,所以选取PCA和t-SNE
在这里分享一个拼凑的可以直接copy使用的代码
数据的传入类型: txt格式 每一行的第一个属性是分类值,剩余元素为属性值,传入txt即可画出图像
在这里插入图片描述

import os
import gzip
import numpy as np
import time
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patheffects as PathEffects
import seaborn as sns

# 这里choose 选择1使用PCA降维 选择2使用PCA降高维+t-SNE分类的策略
choose = 0

# 加载mnist数据函数进行分类测试
def load_mnist(path, kind='t10k'):
    """Load MNIST data from `path`"""
    labels_path = os.path.join(path,'%s-labels-idx1-ubyte.gz'% kind)
    images_path = os.path.join(path,'%s-images-idx3-ubyte.gz'% kind)

    with gzip.open(labels_path, 'rb') as lbpath:
        labels = np.frombuffer(lbpath.read(), dtype=np.uint8,
                               offset=8)
    with gzip.open(images_path, 'rb') as imgpath:
        images = np.frombuffer(imgpath.read(), dtype=np.uint8,
                               offset=16).reshape(len(labels), 784)

    return images, labels

def load_data():
    path="./info256_1.txt"
    df=pd.read_table(path,sep=',',header=None)
    x=np.array(df.iloc[:,0])
    x=np.around(x,0)
    y=np.array(df.iloc[:,1:])
    y=np.around(y,1)
    return y,x

#该函数会根据不同的label进行染色
def fashion_scatter(x, colors):
    '''
    :param x:二维矩阵输入
    :param colors:接受一个一维的标签函数
    :return: 返回根据不同label对散点X进行染色的图像
    '''
    # choose a color palette with seaborn.
    num_classes = len(np.unique(colors))
    palette = np.array(sns.color_palette("hls", num_classes))

    # create a scatter plot.
    f = plt.figure(figsize=(10,10))
    ax = plt.subplot(aspect='equal')
    # sc = ax.scatter(x[:,0], x[:,1], lw=0, s=40, c=palette[colors.astype(np.int)])
    sc = ax.scatter(x[:,0], x[:,1], lw=0, s=40, c=palette[colors.astype(np.int)])
    plt.xlim(-25, 25)
    plt.ylim(-25, 25)
    ax.axis('off')
    ax.axis('tight')
    
    # add the labels for each digit corresponding to the label
    txts = []
    for i in range(num_classes):
        # Position of each label at median of data points.
        xtext, ytext = np.median(x[colors == i, :], axis=0)
        txt = ax.text(xtext, ytext, str(i), fontsize=24)
        txt.set_path_effects([
            PathEffects.Stroke(linewidth=5, foreground="w"),
            PathEffects.Normal()])
        txts.append(txt)
    return f, ax, sc, txts


if __name__ == '__main__':
    #描点的设置
    sns.set_style('darkgrid')
    sns.set_palette('muted')
    sns.set_context("notebook", font_scale=1.5,rc={"lines.linewidth": 2.5})
    RS = 123 # 保持随机一致

    # X_train,y_train=load_mnist('.',kind='t10k')
    X_train,y_train=load_data()

    #对数据集进行取子集操作
    X_subset=X_train[:]
    y_subset=y_train[:]

    # #-------------------------------------------------------------------------
    # PCA算法
    if choose == 1:
        from sklearn.decomposition import PCA
        start_pca=time.time()
        # n_components:这个参数可以帮我们指定希望PCA降维后的特征维度数目。
        # 最常用的做法是直接指定降维到的维度数目
        pca=PCA(n_components=4)
        # fit_transform(trainData)对部分数据先拟合fit,
        # 找到该part的整体指标,如均值、方差、最大值最小值等等(根据具体转换的目的),
        # 然后对该trainData进行转换transform,从而实现数据的标准化、归一化等等
        pca_result=pca.fit_transform(X_subset)
        print(f'PCA done! Time elapsed: {time.time() - start_pca} seconds')
        # 现在可以将pca_reuslt存入DataFrame中,之后我们可以检查这四个主成分的各自的数据方差
        pca_df = pd.DataFrame(columns=['pca1', 'pca2', 'pca3', 'pca4'])
        pca_df['pca1'] = pca_result[:, 0]
        pca_df['pca2'] = pca_result[:, 1]
        pca_df['pca3'] = pca_result[:, 2]
        pca_df['pca4'] = pca_result[:, 3]
        print(f'Variance explained per principal component: {pca.explained_variance_ratio_}')
        # [0.3004553  0.17395465 0.05908141 0.04897887]
        # 根据以上数据进行的分析,前两个主成分的解释方差到了47%,所以这里使用前两项进行主成分分析作图

        # taking first and second principal component
        top_two_comp = pca_df[['pca1', 'pca2']]
        f, ax, sc, txts = fashion_scatter(top_two_comp.values, y_subset)
        # Visualizing the PCA output
        plt.show()
    # #-------------------------------------------------------------------------



    #---------------------------------------------------------------------------
    # t-SNE
    if choose == 2:
        from sklearn.manifold import TSNE
        from sklearn.decomposition import PCA


        # 当维度较大时,使用PCA降到低维再使用sne可以极大的抑制噪声
        start_pca = time.time()
        pca_50 = PCA(n_components=20)
        pca_result_50 = pca_50.fit_transform(X_subset)
        # pca_result_50 numpy.ndarray (2000,50)
        print(f'PCA with 50 components done! Time elapsed: {time.time() - start_pca} seconds')
        print(f'Cumulative variance explained by 50 principal components: {np.sum(pca_50.explained_variance_ratio_)}')

        fashion_pca_tsne = TSNE(random_state=RS, n_jobs=-1).fit_transform(pca_result_50)
        print(f't-SNE done! Time elapsed: {time.time() - start_pca} seconds')
        # 速度提升至7.546259641647339 seconds
        print(y_subset)
        print(y_subset.shape)
        print(fashion_pca_tsne.shape)
        print(fashion_pca_tsne)
        f, ax, sc, txts = fashion_scatter(fashion_pca_tsne, y_subset)
        plt.show()
    #---------------------------------------------------------------------------

这里也提供了一个手写字体识别的分类样例供大家使用,效果大概如下图:
第一幅是PCA降维使用前两个主成分得出的
第二幅是先PCA从256到50维去噪,然后使用t-SNE得出的
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值