什么是降维?

一、降维的概念

        降维是一种减少数据集中特征数量的技术,目的是减少计算复杂性,同时尽量保留原始数据的重要信息。降维通常用于高维数据集,其中可能包含成千上万个特征。降维可以分为两类:一类是特征选择,指从现有特征中选择一个子集的过程,不创建新的特征;另一类是特征提取,通过转换原始特征空间以生成新的特征表示。本文主要介绍后者。

二、常见的降维方法

1、主成分分析(Principal Component Analysis, PCA)

        主成分分析(Principal Component Analysis,PCA)是一种统计方法,用于通过正交变换将可能相关的变量转换为一组值数量更少的线性不相关变量(称为主成分)。PCA的目的是找到数据中的主要变化方向,并将数据投影到这些方向上,以保留最多的数据方差。这些方向被称为主成分,它们是原始数据集的线性组合。设有一个数据集X,其中x_{i}是n个样本中的一个,p是特征(变量)的数量。PCA的计算如下:

(1)中心化数据

X_{centered} = X-\bar{X}

        其中,\bar{X}是X的列均值。

(2)计算协方差矩阵

\Sigma = \frac{1}{n-1}X_{centered}^{T}X_{centered}

(3)求解特征值和特征向量

\Sigma v_{i} = \lambda_{i} v_{i}

        其中\lambda_{i}是特征值,v_{i}是对应的特征向量。

(4)选择主成分

        选择k个最大的特征值对应的特征向量v_{1},v_{2},...,v_{k},构成矩阵V。

(5)构造新特征空间

Y = X_{centered}V

        其中,Y就是降维后的新数据。

import pandas as pd
from sklearn.decomposition import PCA
from sklearn.preprocessing import StandardScaler
from sklearn.datasets import load_wine

# 加载红酒数据集
data = load_wine()
X = data.data
y = data.target

# 数据预处理,标准化特征
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

# 初始化PCA,设置降维后的维度,例如降至2维
pca = PCA(n_components=2)

# 训练PCA模型并降维
X_pca = pca.fit_transform(X_scaled)

# 查看降维后的数据
print("降维后的数据:")
print(X_pca)

# 还原数据可以使用inverse_transform方法
X_reconstructed = pca.inverse_transform(X_pca)

# 查看主成分解释的方差比例
print("主成分解释的方差比例:")
print(pca.explained_variance_ratio_)

# 可视化降维后的数据
import matplotlib.pyplot as plt
colors = ['red', 'green', 'blue']
markers = ['s', 'x', 'o']
for color, marker, i in zip(colors, markers, [0, 1, 2]):
    plt.scatter(X_pca[y == i, 0], X_pca[y == i, 1], c=color, label=data.target_names[i], marker=marker)
plt.title('PCA of Wine Dataset')
plt.xlabel('Principal Component 1')
plt.ylabel('Principal Component 2')
plt.legend()
plt.show()

2、线性判别分析(Linear Discriminant Analysis, LDA)

        线性判别分析(Linear Discriminant Analysis,简称LDA)是一种有监督学习的降维技术(主题模型也有个叫LDA的,全称是隐含狄利克雷分布,注意区分!),它的目标是寻找一个特征的线性组合,以最大化类间的差异和最小化类内的差异。LDA的原理基于寻找最佳的投影方向,使得在这个方向上,不同类别的数据点尽可能地分离(最大化类间距离),同时同类数据点尽可能地靠近(最小化类内距离)。

        给定一个数据集,其中包含k个类别,每个类别j有n_{j}个样本,\mu_{j}是类别j的样本均值向量,\Sigma_{j}是类别j的协方差矩阵。LDA试图找到一个线性组合的方向w,以最大化类间散度矩阵S_{B}与类内散度矩阵S_{W}的比例:

S_{B} = \sum_{j=1}^{k}N_{j}(\mu_{j}-\mu)(\mu_{j}-\mu)^{T}

S_{W} = \sum_{j=1}^{k}\sum_{x_{i} \in X_{j}}(x_{i}-\mu_{j})(x_{i}-\mu_{j})^{T}

        其中,\mu是全局样本均值,N_{j}是类别j中的样本数量,X_{j}是类别j中的样本集合。优化目标可以表示为:

w = argmax_{w}\frac{w^{T}S_{B}w}{w^{T}S_{W}w}

        可以通过求解S_{W}^{-1}S_{B}的最大特征值对应的特征向量来找到w。

import numpy as np
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis as LDA
from sklearn.preprocessing import StandardScaler
from sklearn.datasets import load_wine
import matplotlib.pyplot as plt

# 加载红酒数据集
wine = load_wine()
X = wine.data
y = wine.target

# 数据预处理,标准化特征
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

# 初始化LDA,设置降维后的维度,例如降至2维
lda = LDA(n_components=2)

# 训练LDA模型并降维
X_lda = lda.fit_transform(X_scaled, y)

# 查看降维后的数据
print("降维后的数据:")
print(X_lda)

# 还原数据可以使用inverse_transform方法
X_reconstructed = lda.inverse_transform(X_lda)

# 可视化降维后的数据
colors = ['red', 'green', 'blue']
markers = ['s', 'x', 'o']
plt.figure()
for i, color, marker in zip(range(3), colors, markers):
    plt.scatter(X_lda[y == i, 0], X_lda[y == i, 1], c=color, label=wine.target_names[i], marker=marker)
plt.title('LDA of Wine Dataset')
plt.xlabel('LD1')
plt.ylabel('LD2')
plt.legend()
plt.show()

3、t-分布随机邻域嵌入(t-SNE)

        t-SNE(t-distributed Stochastic Neighbor Embedding)是一种非线性降维算法,其工作原理主要包括以下几个步骤:

(1)计算高维空间的概率分布

        首先,t-SNE通过高斯分布(正态分布)计算高维空间中数据点之间的相似度,使用条件概率来表达点与点之间的相似度。

(2)映射到低维空间:

        其次,t-SNE通过优化一个目标函数,将高维空间中的数据点映射到低维空间(通常是2维或3维),同时尝试保持高维空间中的概率分布与低维空间中的概率分布尽可能相似。

(3)优化目标函数

        t-SNE使用KL散度(Kullback-Leibler divergence)作为目标函数来度量高维和低维空间的概率分布之间的差异,并通过梯度下降法来最小化这个差异。目标函数定义如下:

C = \sum_{i}\sum_{j}p_{j|i}log\frac{p_{j|i}}{q_{j|i}}

        其中,p_{j|i}是高维空间中数据点x_{i}x_{j}之间的条件概率。q_{j|i}是低维空间中数据点y_{i}y_{j}之间的条件概率。

(4)使用t分布

        在低维空间中,t-SNE使用t分布而不是高斯分布来计算点之间的相似度,这有助于解决数据点在低维空间中的拥挤问题。

from sklearn.manifold import TSNE
from sklearn.datasets import load_wine
import matplotlib.pyplot as plt

# 加载红酒数据集
wine = load_wine()
X = wine.data
y = wine.target

# 初始化t-SNE模型,设置降维后的维度为2
tsne = TSNE(n_components=2, random_state=0)

# 训练t-SNE模型并降维
X_tsne = tsne.fit_transform(X)

# 可视化降维后的数据
plt.figure(figsize=(8, 6))
for i in range(3):
    plt.scatter(X_tsne[y == i, 0], X_tsne[y == i, 1], label=wine.target_names[i])
plt.legend()
plt.title('t-SNE projection of Wine dataset')
plt.xlabel('t-SNE feature 1')
plt.ylabel('t-SNE feature 2')
plt.show()

4、奇异值分解(Singular Value Decomposition, SVD)

        奇异值分解(Singular Value Decomposition, SVD)是一种的矩阵分解方法。SVD通过保留最大的几个奇异值(对应于矩阵Σ的非零元素)及其对应的左右奇异向量来实现。这些奇异值代表了数据中最重要的方差,而舍弃较小的奇异值则相当于去除了噪声和冗余信息。SVD能够将任意一个矩阵分解为三个特定的矩阵,其数学表达式定义为:

A = U \Sigma V^{T}

        其中:

  • A是一个m×n的矩阵。
  • U是一个m×m的正交矩阵,其列向量称为左奇异向量。
  • Σ(通常用大写的希腊字母Σ表示)是一个m×n的对角矩阵,对角线上的元素称为奇异值,按降序排列。
  • V^{T}是一个n×n矩阵的转置,V的列向量称为右奇异向量,也是一个正交矩阵。
import numpy as np
from sklearn.datasets import load_wine
from sklearn.decomposition import TruncatedSVD
import matplotlib.pyplot as plt

# 加载红酒数据集
wine = load_wine()
X = wine.data
y = wine.target

# 初始化TruncatedSVD模型,设置降维后的维度为2
svd = TruncatedSVD(n_components=2)

# 训练SVD模型并降维
X_svd = svd.fit_transform(X)

# 可视化降维后的数据
plt.figure(figsize=(8, 6))
for i in range(3):
    plt.scatter(X_svd[y == i, 0], X_svd[y == i, 1], label=wine.target_names[i])
plt.legend()
plt.title('SVD projection of Wine dataset')
plt.xlabel('SVD feature 1')
plt.ylabel('SVD feature 2')
plt.show()

5、umap(Uniform Manifold Approximation and Projection)

        UMAP(Uniform Manifold Approximation and Projection)是一种用于降维的非线性技术,它适合于高维数据的可视化。UMAP的目标是在低维空间中保持高维空间中数据点的局部和全局结构。UMAP的数学公式涉及到构建一个高维的模糊简单复形(fuzzy simplicial complex),然后通过优化过程找到其在低维空间的最佳表示。这个过程可以表示为:

(1)构造高维图

G = \begin{Bmatrix} (x_{i},x_{j})|(x_{i} \ is \ a \ neigbhor \ of \ x_{j}) \end{Bmatrix}

(2)计算边权重

w_{ij} = \frac{1}{1+exp(-d(x_{i},x_{j})^{2}/2\sigma _{i}^{2})}

        其中,d(x_{i},x_{j})是点x_{i}x_{j}之间的距离,\sigma_{i}是基于邻近点的距离确定的尺度参数。

(3)优化低维嵌入

min_{Y}\sum_{i,j}w_{i,j}log\frac{w_{i,j}}{q(y_{i},y_{j})}

        其中y_{i}y_{j}是低维空间中的点,q是低维空间中的概率分布。

(注意umap库安装指令应该写:pip install umap-learn)

import umap
from sklearn.datasets import load_wine
import matplotlib.pyplot as plt

# 加载红酒数据集
wine = load_wine()
X = wine.data
y = wine.target

# 初始化UMAP对象
reducer = umap.UMAP(n_neighbors=15, min_dist=0.1, n_components=2, random_state=42)

# 执行降维
embedding = reducer.fit_transform(X)

# 可视化降维结果
plt.figure(figsize=(10, 8))
plt.scatter(embedding[:, 0], embedding[:, 1], c=y, cmap='Spectral', s=5)
plt.colorbar()
plt.title('UMAP projection of Wine dataset')
plt.xlabel('Component 1')
plt.ylabel('Component 2')
plt.show()

三、总结

        降维方法在探索性数据分析阶段非常有用,不论是通过降维可视化查看数据分布,还是可视化给老板看。不同的降维方法也有其适用场景,对于NLP任务,笔者常用的是umap降维,经验上看它在文本表示降维方面表现更好,以及它速度较快,比其他方法效率高不少;而对于数值型数据挖掘,PCA、t-SNE都是不错的方法。

### 在CNN处理图像数据中的作用及方法 #### 作用 - 减少计算量:图像数据通常具有较高的度,通过可以显著减少数据量,从而低卷积神经网络的计算复杂度,提高训练和推理速度。例如,对于一张高分辨率的图像,如果不进行处理,卷积层的计算量会非常大。 - 防止过拟合:过多的数据度可能会导致模型过拟合,即模型在训练数据上表现很好,但在测试数据上表现不佳。可以去除一些噪声和冗余信息,使模型更加泛化,提高模型的鲁棒性。 - 提取关键特征:过程中,CNN可以提取图像的关键特征,去除不重要的信息。卷积层能够提取图像的局部特征,同时保留图像的空间结构信息,实现数据的有效,更好地捕捉图像的内在特征,在图像识别等任务中表现出色[^2]。 #### 方法 - 卷积层:卷积层是CNN中实现的重要手段。卷积核在图像上滑动进行卷积操作,通过共享卷积核的参数,减少了模型的参数数量,从而实现数据的。例如,一个3x3的卷积核在图像上滑动,对每个局部区域进行卷积计算,得到一个新的特征图,其度通常会比原始图像小。 - 池化层:池化层可以对特征图进行下采样,进一步减少数据的度。常见的池化操作有最大池化和平均池化。最大池化是在每个池化窗口中选择最大值作为输出,平均池化则是计算池化窗口中所有值的平均值。例如,使用2x2的最大池化窗口,将特征图的尺寸缩小为原来的一半。以下是使用Keras实现最大池化层的代码示例: ```python from tensorflow.keras.layers import MaxPooling2D import tensorflow as tf # 假设输入特征图的形状为 (batch_size, height, width, channels) input_layer = tf.keras.Input(shape=(32, 32, 3)) pooling_layer = MaxPooling2D(pool_size=(2, 2))(input_layer) model = tf.keras.Model(inputs=input_layer, outputs=pooling_layer) ``` ### 在CNN处理其他数据中的作用及方法 #### 作用 - 去除噪声和冗余信息:对于其他类型的数据,如时间序列数据、文本数据等,也可能存在噪声和冗余信息。可以去除这些不必要的信息,提高数据的质量和模型的性能。 - 提高模型效率:当处理高数据时,模型的训练和推理时间会显著增加。可以减少数据的度,从而提高模型的训练和推理效率。 #### 方法 - 卷积操作:如果其他数据具有一定的局部相关性,也可以使用卷积操作进行。例如,在处理时间序列数据时,可以将时间序列看作一的“图像”,使用一卷积核进行卷积操作,提取局部特征并实现。 - 全连接层:在某些情况下,可以使用全连接层将高数据映射到低空间。全连接层可以学习数据的非线性映射关系,将输入数据转换为低的特征表示。以下是一个使用全连接层进行的简单代码示例: ```python from tensorflow.keras.layers import Dense import tensorflow as tf # 假设输入数据的形状为 (batch_size, input_dim) input_layer = tf.keras.Input(shape=(100,)) dense_layer = Dense(10, activation='relu')(input_layer) model = tf.keras.Model(inputs=input_layer, outputs=dense_layer) ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值