机器学习算法与实践详解

内容分享2天前发布
1 0 0

table {
border-collapse: collapse;
width: 100%;
margin-bottom: 1rem;
}
th, td {
border: 1px solid #ddd;
padding: 8px;
text-align: left;
}
th {
background-color: #f2f2f2;
}
tr:nth-child(even) {
background-color: #f9f9f9;
}
pre {
background-color: #f8f8f8;
padding: 15px;
border-radius: 4px;
overflow-x: auto;
}

45、包外评估的好处是什么?

由于预测器在训练期间从未见过包外(OOB)实例,因此可以在这些实例上对其进行评估,而无需单独的验证集。还可以通过对每个预测器的 OOB 评估结果求平均值来评估整个集成模型。

46、是什么让极端随机树(Extra – Trees)比普通随机森林更随机?这种额外的随机性有什么帮助?极端随机树比普通随机森林慢还是快?

极端随机树的特点

极端随机树在每个节点分裂时,不仅像随机森林一样考虑特征的随机子集,还使用随机阈值,而不是像普通决策树那样搜索最佳阈值,这使其更随机。

这种额外的随机性起到了正则化的作用,如果随机森林过拟合训练数据,极端随机树可能表现更好。

极端随机树训练速度比普通随机森林快,但在进行预测时,两者速度没有明显差异。

47、如果你的 AdaBoost 集成模型对训练数据欠拟合,应该调整哪些超参数以及如何调整?

可以尝试增加估计器的数量、减少基估计器的正则化超参数,也可以稍微提高学习率。

48、如果你的梯度提升集成模型对训练集过拟合,你应该提高还是降低学习率?

应该降低学习率。

49、降低数据集维度的主要动机是什么?主要缺点是什么?

主要动机与缺点

主要动机

加快后续训练算法的速度(有时可去除噪声和冗余特征,使训练算法表现更好)

可视化数据并深入了解最重要的特征

节省空间(压缩)

主要缺点

会丢失一些信息,可能降低后续训练算法的性能

计算量可能很大

会增加机器学习流程的复杂度

转换后的特征通常难以解释

50、什么是维度诅咒?

维度诅咒

维度诅咒指的是许多在低维空间中不存在的问题在高维空间中会出现。

在机器学习中,一个常见表现是随机采样的高维向量通常非常稀疏,这增加了过拟合的风险,并且在没有大量训练数据的情况下很难识别数据中的模式。

51、一旦数据集的维度被降低,是否可以逆转该操作?如果可以,如何操作?如果不可以,原因是什么?

使用讨论过的算法降低数据集维度后,几乎不可能完美逆转操作,因为降维过程中会丢失一些信息。此外,有些算法(如 PCA)有简单的逆变换程序,能重建出与原始数据集相对相似的数据集,但其他算法(如 T-SNE)则没有。

52、PCA 能否用于降低高度非线性数据集的维度?

可以。PCA 可显著降低大多数数据集的维度,即使是高度非线性的数据集,因为它至少能去除无用的维度。不过,如果数据集中没有无用维度,如瑞士卷数据集,使用 PCA 降低维度会丢失过多信息。

53、在哪些情况下你会使用普通PCA、增量PCA、随机PCA或核PCA?


普通PCA适用于数据集较小,能全部加载到内存中时。  
增量PCA适用于处理大型训练集,或需要在线应用PCA(即新实例到来时实时处理)的场景,它允许将训练集拆分为小批量进行处理。  
随机PCA适用于样本数m或特征数n大于500,且主成分数d小于m或n的80%的情况,可自动使用随机算法;若要强制使用完整SVD方法,可将`svd_solver`超参数设为“full”。  
核PCA适用于需要进行复杂非线性投影以降维的场景,它能在投影后较好地保留实例的簇结构,或展开靠近扭曲流形的数据集。

54、如何评估降维算法在数据集上的性能?

可以通过在降维后的数据集上运行一个机器学习算法,并将其性能与在原始数据集上运行同一算法的性能进行比较。如果降维没有损失太多信息,那么该算法的性能应与使用原始数据集时一样好。

55、将两种不同的降维算法串联起来有意义吗?

有意义。常见的做法是先用主成分分析(PCA)快速去除大量无用维度,再应用另一种速度慢得多的降维算法,如局部线性嵌入(LLE)。这种两步法可能会产生与仅使用LLE相同的性能,但耗时会大幅减少。

56、使用t – SNE将MNIST数据集降维到二维,并使用Matplotlib绘制结果。你可以使用散点图,用10种不同的颜色来表示每个图像的目标类别。或者,你可以用相应实例的类别(0到9的数字)替换散点图中的每个点,甚至可以绘制数字图像的缩小版本(如果你绘制所有数字,可视化效果会过于杂乱,所以你应该要么随机抽样,要么仅在近距离内没有其他实例已经绘制的情况下绘制一个实例)。你应该能得到一个数字聚类良好分离的漂亮可视化效果。尝试使用其他降维算法,如PCA、LLE或MDS,并比较得到的可视化效果。


对于使用 t-SNE 将 MNIST 数据集降维到二维并绘制结果,可按以下步骤操作:先使用 t-SNE 算法对 MNIST 数据集进行降维,再用 Matplotlib 绘制散点图,用 10 种颜色区分不同目标类别。也可将散点替换为对应类别数字或绘制缩小版数字图像,为避免杂乱,可随机抽样或仅在近距离无其他实例时绘制。对于使用其他降维算法(PCA、LLE、MDS),同样先对数据集进行降维,再绘制可视化结果,然后对比不同算法得到的可视化中数字聚类的分离情况、分布形态等差异。

57、如何定义聚类?请列举一些聚类算法。

聚类概述

聚类是将相似实例分组在一起的无监督任务。相似性的概念取决于具体任务。

常见的聚类算法

K-均值

DBSCAN

凝聚聚类

BIRCH

均值漂移

亲和传播

谱聚类

58、聚类算法的一些主要应用有哪些?

聚类算法的主要应用

聚类算法的主要应用包括:

数据分析

客户细分

推荐系统

搜索引擎

指纹分割

半监督学习

降维

异常检测

新奇检测

具体应用场景

客户细分

可用于客户细分,基于客户购买行为和网站活动进行聚类,以了解客户需求并调整产品和营销活动。

数据分析

用于数据分析,分析新数据集时运行聚类算法并分别分析每个聚类。

降维

作为降维技术,聚类后测量实例与每个聚类的亲和度。

59、描述使用K-Means时选择合适簇数量的两种技术。

避免凭直觉设置簇数量,例如对于手写数字数据集,由于每个数字有多种书写方式,选择较大的簇数量(如

50

)比按数字种类设为

10

更合适。

当K-Means作为分类管道的预处理步骤时,可使用

GridSearchCV

进行交叉验证,找出使分类性能最佳的簇数量

k

,如在某个例子中,通过此方法找到

k=99

时能显著提升准确率。

60、什么是标签传播?为什么要实施它,以及如何实施?


标签传播是一种将部分(或全部)有标签实例的标签复制到相似的无标签实例的技术。

实施标签传播的原因在于标注数据集既昂贵又耗时,通常有大量无标签实例和少量有标签实例,标签传播可大幅增加有标签实例的数量,使监督算法达到更好的性能。

实施方法是先手动标注每个聚类的代表性图像,获取代表性标签,然后将每个代表性实例的标签传播到同一聚类的其他实例。

例如,使用代码

```python
y_train_propagated = np.empty(len(X_train), dtype=np.int32)

创建一个空数组,通过

for

循环


for i in range(k):
    y_train_propagated[kmeans.labels_ == i] = y_representative_digits[i]

将代表性标签传播到同一聚类的实例。



##61、请说出两种可处理大型数据集的聚类算法,以及两种寻找高密度区域的聚类算法。
可处理大型数据集的聚类算法:  
- Agglomerative clustering(凝聚聚类)  
- BIRCH  

寻找高密度区域的聚类算法:  
- DBSCAN  
- HDBSCAN

##62、异常检测和新奇检测之间的区别是什么?
新奇检测假定算法在一个“干净”、未受异常值污染的数据集上训练,旨在检测与训练集中所有实例不同的新实例;而异常检测不做此假设,系统在训练时主要查看正常实例,学习识别它们,当看到新实例时,判断其是否像正常实例或可能是异常。

例如,若训练集中有少量吉娃娃图片:

- **新奇检测算法**:不应将新的吉娃娃图片视为新奇事物。
- **异常检测算法**:可能将其归类为异常。

##63、什么是高斯混合模型?可以用它完成哪些任务?
# 高斯混合模型(GMM)

高斯混合模型(GMM)是一种概率模型,假设实例由几个参数未知的高斯分布混合生成。

## 应用场景

- **聚类**
  - 将实例分配到最可能的簇(**硬聚类**)
  - 或估计其属于特定簇的概率(**软聚类**)

- **异常检测**
  - 将低密度区域的实例视为异常

## 特性

- **生成模型**
  - 可从中采样新实例
  - 也能估计模型在任意位置的密度

##64、使用高斯混合模型时,能说出两种确定合适簇数量的技术吗?
可以使用 AIC 和 BIC 指标,也可使用 `BayesianGaussianMixture` 类自动消除不必要的簇。

##65、在奥利维蒂人脸数据集上训练一个高斯混合模型。为了加速算法,可能需要降低数据集的维度(例如,使用主成分分析(PCA),保留99%的方差)。使用该模型生成一些新的人脸(使用sample()方法),并将它们可视化(如果使用了PCA,需要使用其inverse_transform()方法)。尝试修改一些图像(例如,旋转、翻转、变暗),看看模型是否能检测到异常(即比较正常图像和异常图像的score_samples()方法的输出)。
本题可按以下步骤操作:

1. 加载奥利维蒂人脸数据集;
2. 使用PCA降低数据集维度,保留99%的方差;
3. 在降维后的数据集上训练高斯混合模型;
4. 使用模型的`sample()`方法生成新的人脸;
5. 若使用了PCA,使用其`inverse_transform()`方法将生成的人脸还原到原始维度并可视化;
6. 修改一些图像(如旋转、翻转、变暗);
7. 比较正常图像和异常图像的`score_samples()`方法的输出,判断模型是否能检测到异常。

##66、请简述利用主成分分析(PCA)对奥利维蒂人脸数据集进行异常检测的具体步骤,并说明为何修改后的图像重构误差会较大。
利用降维技术(如 PCA)进行异常检测的方法如下:

以奥利维蒂人脸数据集为例:

1. 先通过 PCA 降维,保留 99% 方差;
2. 计算正常图像的重构误差;
3. 对修改后的图像计算重构误差,发现其误差大很多;
4. 绘制重构图像可以看出,PCA 在尝试重构“正常人脸”,因此修改后的图像重构误差较大。

##67、TensorFlow Playground是由TensorFlow团队构建的便捷神经网络模拟器。在这个模拟器中,可通过点击操作训练多个二元分类器,并调整模型的架构及其超参数,以直观了解神经网络的工作原理以及超参数的作用。请描述在该模拟器中进行以下操作时的观察结果:a. 训练默认的神经网络;b. 将tanh激活函数替换为ReLU激活函数后训练网络;c. 将网络架构修改为只有一个包含三个神经元的隐藏层并多次训练;d. 移除一个神经元,只保留两个神经元进行训练;e. 将神经元数量设置为八个并多次训练网络;f. 选择螺旋数据集,并将网络架构改为有四个隐藏层,每层有八个神经元进行训练;g. 花大约一个小时左右的时间尝试其他参数。
在TensorFlow Playground这个神经网络模拟器中,不同操作及观察点如下:

a. 训练默认网络,能看到不同隐藏层学习不同复杂程度的模式,层数越多模式越复杂;

b. 把 `tanh` 激活函数换成 `ReLU` 后,网络找解决方案更快,但边界呈线性;

c. 网络设为一个含三个神经元的隐藏层,多次训练时训练时间差异大,可能陷入局部最小值;

d. 网络只剩两个神经元时,因参数少会对训练集欠拟合;

e. 神经元设为八个时,网络训练快且不易陷入局部最小值,即便陷入局部最优也接近全局最优,但可能在长平台停留;

f. 选螺旋数据集并设四个含八个神经元的隐藏层,训练慢且常停在长平台,高层神经元进化快,出现梯度消失问题,可通过一些方法缓解;

g. 花一小时左右探索其他参数,增进对神经网络的直观认识。

##68、使用原始的人工神经元绘制一个能计算A ⊕ B(其中⊕表示异或运算)的人工神经网络。提示:A ⊕ B = (A ∧ ¬ B) ∨ (¬ A ∧ B)。
要绘制一个能计算 A ⊕ B 的人工神经网络,可按以下步骤进行:

1. **构建两个子网络**:
   - 一个用于计算 A ∧ ¬B
   - 另一个用于计算 ¬A ∧ B

2. **否定操作的实现**:
   - 在每个子网络中,对于否定操作,可以添加一个输入为 1,权重为 -1 的连接来实现。

3. **与操作的实现**:
   - 在每个子网络中,对于与操作,可以设置神经元的激活条件为至少两个输入为激活状态。

4. **或操作子网络的构建**:
   - 将这两个子网络的输出作为一个或操作子网络的输入。
   - 该或操作子网络的神经元激活条件为至少一个输入为激活状态。

5. **最终输出**:
   - 或操作子网络的输出即为 A ⊕ B 的结果。

##69、为什么通常更倾向于使用逻辑回归分类器而不是经典感知机(即使用感知机训练算法训练的单层阈值逻辑单元)?如何调整感知机使其等同于逻辑回归分类器?
通常更倾向于使用逻辑回归分类器而非经典感知机,原因在于:

- 经典感知机只有在数据集线性可分时才会收敛,且无法估计类别概率;
- 而逻辑回归分类器即使数据集不是线性可分,也能收敛到一个较好的解,并且会输出类别概率。

要使感知机等同于逻辑回归分类器,可以采取以下措施:

- 将感知机的激活函数改为逻辑激活函数(若有多个神经元则使用 `softmax` 激活函数);
- 并使用梯度下降(或其他最小化成本函数,通常是最小化交叉熵的优化算法)进行训练。

##70、为什么逻辑激活函数是训练第一代多层感知机(MLP)的关键要素?
因为阶跃函数只有平坦的线段,没有梯度可供利用(梯度下降法无法在平坦表面移动),而逻辑函数处处有定义明确的非零导数,能让梯度下降法在每一步都取得进展。

##71、假设你有一个多层感知机(MLP),由一个包含10个直通神经元的输入层、一个包含50个人工神经元的隐藏层和一个包含3个人工神经元的输出层组成。所有人造神经元都使用ReLU激活函数。输入矩阵X的形状是什么?隐藏层的权重向量W及其偏置向量b的形状是什么?输出层的权重向量W及其偏置向量b的形状是什么?网络输出矩阵Y的形状是什么?写出将网络输出矩阵Y表示为X、W、b、W和b的函数的方程。
输入矩阵 `X` 的形状是 `m × 10`,其中 `m` 表示训练批次大小。  
隐藏层的权重向量 `W` 的形状是 `10 × 50`,其偏置向量 `b` 的长度是 `50`。  
输出层的权重向量 `W` 的形状是 `50 × 3`,其偏置向量 `b` 的长度是 `3`。  
网络输出矩阵 `Y` 的形状是 `m × 3`。

计算网络输出矩阵 `Y` 的方程是:

Y = ReLU(ReLU(XW₁ + b₁)W₂ + b₂)



这里为区分两层的权重和偏置,将隐藏层的权重和偏置记为 `W₁`、`b₁`,输出层的权重和偏置记为 `W₂`、`b₂`。

##72、如果想将电子邮件分类为垃圾邮件或正常邮件,输出层需要多少个神经元?输出层应使用什么激活函数?如果要处理MNIST数据集,输出层需要多少个神经元,应使用什么激活函数?如果要让网络预测房价,情况又如何?
将电子邮件分类为垃圾邮件或正常邮件,输出层需要1个神经元,使用逻辑激活函数;

处理MNIST数据集,输出层需要10个神经元,使用softmax激活函数;

预测房价,若预测单个值则输出层需要1个神经元,通常输出层不使用激活函数,若要保证输出为正,可使用ReLU或softplus激活函数。

##73、什么是反向传播,它是如何工作的?反向传播和反向模式自动微分有什么区别?
反向传播是一种用于训练人工神经网络的技术。它先计算成本函数关于每个模型参数(所有权重和偏差)的梯度,然后使用这些梯度执行梯度下降步骤。这个步骤通常会使用许多训练批次进行数千或数百万次,直到模型参数收敛到使成本函数最小的值。

具体工作时,它一次处理一个小批量数据,多次遍历整个训练集,每次遍历称为一个轮次。每个小批量数据传入网络输入层,算法计算每一层神经元的输出并传递到下一层。反向传播使用反向模式自动微分来计算梯度。

### 区别说明

- **反向传播**:指的是使用多个反向传播步骤训练人工神经网络的整个过程,每个步骤计算梯度并用于执行梯度下降步骤。
- **反向模式自动微分**:是一种有效计算梯度的技术,恰好被反向传播所使用。

##74、只要使用何氏初始化(He initialization)随机选择一个值,将所有权重初始化为该相同值是否可行?
不可行。所有权重应独立采样,不能都有相同的初始值。随机采样权重的一个重要目标是打破对称性,如果所有权重初始值相同,即使该值不为零,对称性也无法打破,反向传播也无法打破它,会导致给定层中的所有神经元总是具有相同的权重,就像每层只有一个神经元,且收敛到良好解决方案的可能性极低。

##75、将偏置项初始化为 0 是否可行?
可行。将偏置项初始化为零没问题,也有人喜欢像初始化权重一样初始化它们,这也无妨,差别不大。

##76、请列举SELU激活函数相对于ReLU激活函数的三个优点。
1. 它可以取负值,使任何给定层中神经元的平均输出通常比使用 ReLU 激活函数时更接近零,有助于缓解梯度消失问题。
2. 它始终有非零导数,避免了可能影响 ReLU 单元的神经元死亡问题。
3. 在条件合适时(模型是顺序的、权重使用 LeCun 初始化、输入标准化且没有不兼容的层或正则化),SELU 激活函数可确保模型自归一化,解决梯度爆炸/消失问题。

##77、在哪些情况下你会想要使用以下每种激活函数:SELU、Leaky ReLU(及其变体)、ReLU、tanh、Logistic 和 Softmax?
# 激活函数应用场景

- **SELU**
  - 在由密集层堆叠组成的神经网络中,且所有隐藏层使用该函数时,网络会自归一化,能解决梯度消失/爆炸问题。
  - 常用于深度神经网络。

- **Leaky ReLU(及其变体)**
  - 如果在意运行时延迟,可优先选择。
  - 若不想调整超参数,可使用Keras默认的α值。
  - 网络过拟合时可考虑RReLU。

- **ReLU**
  - 是最常用的激活函数。
  - 很多库和硬件加速器有针对它的优化,若追求速度,它可能是最佳选择。
  - 其输出精确为零的特性在某些情况下有用。

- **tanh**
  - 需要在输出层输出 -1 到 1 之间的数值时可使用。
  - 现在在隐藏层较少使用(循环网络除外)。

- **Logistic**
  - 需要在输出层估计概率时(如二元分类)有用。
  - 在隐藏层很少使用(变分自编码器的编码层等情况除外)。

- **Softmax**
  - 在输出层输出互斥类别的概率时有用。
  - 很少用于隐藏层。

##78、当使用SGD优化器时,如果将动量超参数设置得过于接近1(例如0.99999),可能会发生什么?
若将动量超参数设置得过于接近1,意味着**几乎没有摩擦**。这可能导致动量不断增大且难以控制,优化器可能会大幅超调,在最小值附近反复振荡,**难以稳定收敛到最优解**。

##79、使用Nadam优化算法和早停法,在CIFAR10数据集上训练网络。你可以使用keras.datasets.cifar10.load_data()加载该数据集。该数据集由60000张32×32像素的彩色图像组成(50000张用于训练,10000张用于测试),有10个类别,所以你需要一个具有10个神经元的softmax输出层。每次更改模型架构或超参数时,记得寻找合适的学习率。
以下是一个使用Keras实现上述要求的示例代码:

```python
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras.callbacks import EarlyStopping
from tensorflow.keras.optimizers import Nadam

# 加载CIFAR10数据集
(x_train, y_train), (x_test, y_test) = keras.datasets.cifar10.load_data()

# 数据预处理
x_train = x_train / 255.0
x_test = x_test / 255.0

# 构建模型
model = keras.Sequential([ 
    # 可以根据需要添加更多隐藏层,这里示例构建一个简单的模型 
    keras.layers.Flatten(input_shape=(32, 32, 3)), 
    keras.layers.Dense(200, activation='elu', kernel_initializer='he_normal'), 
    keras.layers.Dense(200, activation='elu', kernel_initializer='he_normal'), 
    # 可以继续添加更多隐藏层 
    keras.layers.Dense(10, activation='softmax')
])

# 编译模型
model.compile(optimizer=Nadam(), loss='sparse_categorical_crossentropy', metrics=['accuracy'])

# 早停回调
early_stopping = EarlyStopping(patience=10, restore_best_weights=True)

# 训练模型
model.fit(x_train, y_train, epochs=100, batch_size=64, validation_data=(x_test, y_test), callbacks=[early_stopping])

# 评估模型
test_loss, test_acc = model.evaluate(x_test, y_test)
print(f'Test accuracy: {test_acc}')

此代码构建了一个简单的神经网络模型,使用Nadam优化器和早停法在CIFAR10数据集上进行训练。你可以根据需要调整隐藏层的数量和神经元的数量。每次更改模型架构或超参数时,需要重新寻找合适的学习率。

80、现在尝试添加批量归一化并比较学习曲线:它是否比之前收敛得更快?是否能产生更好的模型?它对训练速度有何影响?

添加批量归一化后收敛通常更快,能产生更好的模型。它会使每个训练轮次耗时增加,导致训练速度看起来变慢,但由于收敛快,达到相同性能所需的轮次减少,总体耗时通常会更短。

81、尝试用SELU替换批量归一化(Batch Normalization),并进行必要的调整以确保网络实现自归一化(即标准化输入特征、使用LeCun正态初始化、确保深度神经网络仅包含一系列全连接层等)。

要完成此操作,需进行以下调整:

对输入特征进行标准化处理,使其均值为0,标准差为1;

对每个隐藏层的权重使用LeCun正态初始化,在Keras中可通过设置

kernel_initializer = "lecun_normal"

来实现;

确保网络架构为顺序结构,即仅由一系列全连接层组成。

82、尝试使用阿尔法丢弃法对模型进行正则化。然后,在不重新训练模型的情况下,查看是否可以使用蒙特卡罗丢弃法(MC Dropout)来获得更高的准确率。

可以按以下步骤操作:

首先,若要正则化基于SELU激活函数的自归一化网络,应使用

阿尔法丢弃法

,因为普通丢弃法会破坏自归一化。

接着,使用

MC Dropout

提升模型性能,无需重新训练模型,示例代码如下:

python
y_probas = np.stack([model(X_test_scaled, training=True) for sample in range(100)])
y_proba = y_probas.mean(axis=0)

这里对测试集进行100次预测。

设置

training=True

确保丢弃层处于激活状态。

然后将预测结果堆叠起来。


蒙特卡罗样本数量

(此例中为100)是可调整的超参数:

– 数量越高,预测及其不确定性估计越准确。

– 但推理时间也会增加,需根据应用找到延迟和准确性之间的平衡。

如果模型包含在训练期间有特殊行为的其他层(如批量归一化层),应将丢弃层替换为

MCDropout

类,代码如下:

python
class MCDropout(keras.layers.Dropout):
def call(self, inputs):
return super().call(inputs, training=True)

同样,也可以通过继承

AlphaDropout

类来定义

MCAlphaDropout

类。

© 版权声明

相关文章

暂无评论

none
暂无评论...