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;
}
1、你会如何定义机器学习?
机器学习是让计算机编程后能从数据中学习的科学(和艺术);
是让计算机具备无需明确编程就能学习能力的研究领域;
若一个计算机程序在任务T上,依据性能指标P衡量,其表现会随经验E提升,
就称该程序从经验E中学习。
2、两种最常见的监督学习任务是什么?
回归(预测数值)和分类(预测类别)
3、要让机器人在各种未知地形上行走,你会使用哪种机器学习算法?
强化学习算法
4、你会使用哪种类型的算法将你的客户划分为多个群体?
可以使用聚类算法,通过基于客户的购买行为和网站活动等信息进行聚类,从而将客户划分为不同的群体。
5、什么是核外学习?
核外学习通常离线进行,可看作增量学习。核外学习算法将数据分割成小批量,运用在线学习技术从这些小批量数据中学习,能处理无法装入计算机主内存的大量数据。
6、哪种类型的学习算法依靠相似度度量来进行预测?
基于实例的学习算法依靠相似度度量来进行预测。这种算法会记住训练数据,当遇到新实例时,使用相似度度量找出最相似的已学实例,并据此进行预测。
7、模型参数和学习算法的超参数有什么区别?
模型参数与超参数的区别
模型参数决定模型在给定新实例时的预测结果,例如线性模型的斜率。学习算法会尝试找到这些参数的最优值,使模型能很好地泛化到新实例。
而超参数是学习算法本身的参数,并非模型的参数,例如要应用的正则化量。它不受学习算法影响,必须在训练前设置好,且在训练期间保持不变。
8、基于模型的学习算法搜索的是什么?它们最常用的成功策略是什么?它们如何进行预测?
基于模型的学习算法
基于模型的学习算法搜索模型参数的最优值,以使模型能很好地推广到新实例。
常用策略
最小化一个成本函数,该函数衡量系统在训练数据上的预测效果
若模型经过正则化,则还会加上模型复杂度的惩罚项
进行预测
将新实例的特征输入到模型的预测函数中
使用学习算法找到的参数值进行计算
9、如果你的模型在训练数据上表现出色,但对新实例的泛化能力很差,这是怎么回事?请列举三种可能的解决方案。
如果模型在训练数据上表现出色,但对新实例的泛化能力很差,意味着模型对训练数据
过拟合
。三种可能的解决方案如下:
采用留出验证法
留出部分训练集作为验证集,评估多个候选模型并选择最佳模型,之后在完整训练集上训练最佳模型,最后在测试集上评估最终模型。
进行重复交叉验证
若验证集大小不合适,可使用多个小验证集,每个模型在其余数据上训练后在每个验证集上评估一次,通过平均评估结果更准确衡量模型性能。
确保数据代表性
验证集和测试集应尽可能代表生产中使用的数据,避免数据不匹配问题。
10、什么是测试集,为什么要使用它?
测试集的定义与作用
测试集是在机器学习和数据挖掘中使用的一组数据样本,用于在模型投入生产之前,估计模型对新实例会产生的泛化误差。
使用测试集的原因是:
训练集
:用于训练模型;
验证集
:用于调整模型的超参数;
测试集
:用于评估模型在未见过的数据上的真实表现。
通过使用测试集,可以确保模型具有良好的泛化能力,避免过拟合等问题,从而可以更可靠地应用于实际场景中。
11、验证集的目的是什么?
验证集的作用与使用方法
验证集用于比较模型,能帮助选择最佳模型并调整超参数。
具体做法:
训练集缩减
:从完整训练集中划分出一部分作为验证集。
模型训练
:在缩减后的训练集(即完整训练集减去验证集)上,使用不同超参数训练多个模型。
模型选择
:选择在验证集上表现最佳的模型作为最优模型。
验证过程结束后的步骤:
最终模型训练
:在完整训练集(包括验证集)上训练选择出的最佳模型,得到最终模型。
模型评估
:在测试集上评估该最终模型,以估计其泛化误差。
12、什么是训练开发集,何时需要它,以及如何使用它?
训练开发集的作用与使用方式
训练开发集是训练集的一部分,模型不对其进行训练。当训练数据与验证和测试数据集存在不匹配风险时需要使用它。
使用方式
模型在训练集的其余部分上进行训练
并在训练开发集和验证集上进行评估
情况分析
若模型在训练集上表现良好,但在训练开发集上表现不佳,那么模型可能对训练集过拟合
若模型在训练集和训练开发集上表现良好,但在验证集上表现不佳,那么训练数据与验证和测试数据之间可能存在显著的数据不匹配
此时应尝试改进训练数据,使其更接近验证和测试数据
13、如果使用测试集调整超参数,可能会出现什么问题?
如果使用测试集调整超参数,有过拟合测试集的风险,并且测量到的泛化误差会过于乐观,可能会推出一个表现比预期更差的模型。
14、在机器学习模型调参时,尝试用RandomizedSearchCV替换GridSearchCV,并给出具体示例代码。
当超参数搜索空间较小时,网格搜索(
GridSearchCV
)是可行的;但当搜索空间较大时,使用
RandomizedSearchCV
更好。它与
GridSearchCV
使用方式相似,不过它不是尝试所有可能组合,而是在每次迭代中为每个超参数随机选择一个值,评估给定数量的随机组合。
以下是替换示例:
from sklearn.model_selection import RandomizedSearchCV
from sklearn.ensemble import RandomForestRegressor
import numpy as np
# 定义随机搜索的参数分布
param_dist = {
'n_estimators': np.arange(3, 31),
'max_features': np.arange(2, 9),
'bootstrap': [False, True]
}
forest_reg = RandomForestRegressor()
# 使用RandomizedSearchCV进行随机搜索
random_search = RandomizedSearchCV(forest_reg, param_dist, n_iter=10, cv=5,
scoring='neg_mean_squared_error',
return_train_score=True)
# 假设 housing_prepared 和 housing_labels 是准备好的特征和标签
random_search.fit(housing_prepared, housing_labels)
# 获取最佳参数
print(random_search.best_params_)
# 获取最佳估计器
print(random_search.best_estimator_)
上述代码中,
n_iter=10
表示进行 10 次随机组合的评估。你可以根据需要调整这个值来控制计算预算。
15、使用GridSearchCV自动探索RandomForestRegressor的一些参数选项,并给出示例代码。
要使用
GridSearchCV
自动探索参数选项,需告知它要试验的超参数及尝试的值,它会用交叉验证评估所有可能的超参数值组合。
例如探索
RandomForestRegressor
的最佳超参数值组合,代码如下:
from sklearn.model_selection import GridSearchCV
param_grid = [
{'n_estimators': [3, 10, 30], 'max_features': [2, 4, 6, 8]},
{'bootstrap': [False], 'n_estimators': [3, 10], 'max_features': [2, 3, 4]}
]
forest_reg = RandomForestRegressor()
grid_search = GridSearchCV(forest_reg, param_grid, cv=5, scoring='neg_mean_squared_error', return_train_score=True)
grid_search.fit(housing_prepared, housing_labels)
上述代码中,
param_grid
定义了要探索的超参数及其取值。
GridSearchCV
会先评估第一个字典中
n_estimators
和
max_features
超参数值的 12 种组合,再尝试第二个字典中超参数值的 6 种组合,且第二个字典中
bootstrap
超参数设为
False
。最后用
fit
方法在数据上进行训练。
16、尝试为MNIST数据集构建一个在测试集上准确率超过97%的分类器。提示:KNeighborsClassifier在这个任务中表现很好;你只需要找到合适的超参数值(尝试对weights和n_neighbors超参数进行网格搜索)。
可使用
KNeighborsClassifier
构建分类器,通过网格搜索来寻找
weights
和
n_neighbors
超参数的合适值,以使得分类器在 MNIST 数据集的测试集上准确率超过 97%。
17、处理泰坦尼克号数据集,为什么说Kaggle是一个很好的起点?
Kaggle 是一个知名的数据科学平台,上面有泰坦尼克号数据集以及相关的竞赛、讨论和解决方案,适合作为处理该数据集的起点。
18、构建一个垃圾邮件分类器(这是一个更具挑战性的练习):从 Apache SpamAssassin 的公共数据集中下载垃圾邮件和正常邮件的示例。解压数据集并熟悉数据格式。将数据集拆分为训练集和测试集。编写一个数据预处理管道,将每封电子邮件转换为特征向量。你的预处理管道应将电子邮件转换为一个(稀疏)向量,该向量指示每个可能的单词是否存在。例如,如果所有电子邮件只包含四个单词,“Hello”、“how”、“are”、“you”,那么电子邮件“Hello you Hello Hello you”将被转换为向量 [1, 0, 0, 1](意味着 [“Hello”存在,“how”不存在,“are”不存在,“you”存在]),或者如果你想统计每个单词的出现次数,则转换为 [3, 0, 0, 2]。你可能想在预处理管道中添加超参数,以控制是否去除电子邮件头、将每封电子邮件转换为小写、去除标点符号、将所有 URL 替换为“URL”、将所有数字替换为“NUMBER”,甚至进行词干提取(即去除单词结尾;有可用的 Python 库可以完成此操作)。最后,尝试几种分类器,看看是否能构建一个具有高召回率和高精度的优秀垃圾邮件分类器。
以下是完成构建垃圾邮件分类器任务的步骤总结:
从 Apache SpamAssassin 公共数据集下载垃圾邮件和正常邮件示例。
解压数据集并熟悉数据格式。
把数据集拆分为训练集和测试集。
编写数据预处理管道,将邮件转换为特征向量,可选择统计单词出现次数。
在预处理管道添加超参数,控制去除邮件头、转换大小写、去除标点、替换 URL 和数字、词干提取等操作。
尝试多种分类器,构建高召回率和高精度的分类器。
19、如果你有一个包含数百万个特征的训练集,你可以使用哪种线性回归训练算法?
可以使用以下方法:
批量梯度下降(Batch GD)
随机梯度下降(Stochastic GD)
因为在处理大量特征时:
正规方程(Normal Equation)和奇异值分解(SVD)较慢
批量梯度下降和随机梯度下降在处理大量特征时速度较快
20、假设你的训练集中的特征具有非常不同的尺度。哪些算法可能会因此受到影响,以及会受到怎样的影响?你可以采取什么措施来解决这个问题?
受影响的算法及影响
梯度下降算法
由于特征尺度不同,代价函数会呈细长碗状,导致算法收敛时间变长。
正则化模型
由于正则化会惩罚大权重,小值特征会比大值特征更容易被忽略,可能收敛到次优解。
解决办法
在训练模型前对数据进行缩放。
注意
:正规方程或奇异值分解方法在不进行缩放的情况下也能正常工作。
21、在训练逻辑回归模型时,梯度下降会陷入局部最小值吗?
不会,因为逻辑回归模型的代价函数是凸函数,梯度下降不会陷入局部最小值。
22、假设你使用批量梯度下降法,并在每个轮次绘制验证误差。如果你注意到验证误差持续上升,可能发生了什么?如何解决这个问题?
验证误差持续上升,可能是模型对训练集过拟合了。可以尝试以下方法解决:
降低多项式次数,减少模型自由度以降低过拟合风险;
对模型进行正则化,如在成本函数中添加 ℓ 惩罚(岭回归)或 ℓ 惩罚(套索回归),同样可减少模型自由度;
增加训练集的大小。
23、当验证误差上升时,立即停止小批量梯度下降训练是个好主意吗?
不是。由于随机性质,小批量梯度下降不能保证每次训练迭代都有进展。若验证误差上升就立即停止训练,可能会在达到最优解之前过早停止。更好的做法是:
定期保存模型
当模型长时间没有改进时,再恢复到保存的最佳模型
24、在我们讨论过的梯度下降算法中,哪种算法能最快到达最优解附近?哪种算法能真正收敛?如何让其他算法也收敛?
梯度下降方法比较
随机梯度下降(Stochastic Gradient Descent)
每个训练步骤很快
在到达最优解附近方面可能最快
批量梯度下降(Batch Gradient Descent)
在代价函数为凸函数且斜率变化不剧烈时
使用固定学习率最终会收敛到最优解
随机梯度下降的改进方法
可通过逐渐降低学习率
使用学习调度函数,让其收敛到全局最小值
25、假设你正在使用多项式回归。你绘制了学习曲线,发现训练误差和验证误差之间存在很大差距。这是怎么回事?有哪三种方法可以解决这个问题?
这种情况表明模型出现了过拟合,即模型在训练数据上的表现明显优于验证数据。
解决方法有:
提供更多训练数据,直到验证误差接近训练误差;
减少模型的复杂度,避免使用自由度过多的模型;
清理数据,修复数据源问题或去除异常值以降低不可约误差。
26、假设你正在使用岭回归,并且你发现训练误差和验证误差几乎相等且相当高。你认为该模型是存在高偏差还是高方差?你应该增大正则化超参数α还是减小它?
当训练误差和验证误差几乎相等且相当高时,模型可能存在
高偏差
。
高偏差
意味着模型过于简单,不能很好地拟合数据。
例如,假设数据是线性的,但实际关系是二次的,这会导致模型
欠拟合
。
对于
岭回归
:
α 控制正则化的程度。
α 越大,模型复杂度越低,权重越接近零。
由于当前模型存在高偏差,需要
增加模型复杂度
,因此应
减小正则化超参数 α
。
27、为什么你会想使用:a. 岭回归而非普通线性回归(即无任何正则化)?b. 套索回归而非岭回归?c. 弹性网络而非套索回归?
a. 通常最好有至少一点正则化,普通线性回归没有正则化,所以一般会倾向于使用
岭回归
。
b. 如果你怀疑只有少数特征有用,应该首选
套索回归
,因为它会将无用特征的权重降为零,实现自动特征选择。
c. 套索回归在某些情况下(如多个特征强相关或特征数量多于训练实例)可能表现不稳定,而
弹性网络
通常更受青睐,不过它需要调整额外的超参数。
28、假设你想将图片分类为室外/室内和白天/夜晚。你应该实现两个逻辑回归分类器还是一个 Softmax 回归分类器?
由于这些类别并非互斥(即四种组合都有可能),你应该训练两个逻辑回归分类器。
29、支持向量机背后的基本思想是什么?
支持向量机背后的基本思想是在类别之间拟合尽可能宽的“街道”,即让分离两个类别的
决策边界
与训练实例之间有最大可能的间隔。
进行
软间隔分类
时,支持向量机会在完美分离两个类别和获得最宽“街道”之间寻找平衡;
在
非线性数据集
上训练时会使用
核函数
。
30、什么是支持向量?
训练 SVM 后,支持向量是位于“街道”(包括其边界)上的任何实例。
决策边界完全由支持向量决定,任何非支持向量(即不在街道上)的实例对决策边界没有任何影响。
计算预测时只涉及支持向量,而非整个训练集。
31、SVM分类器在对实例进行分类时能否输出置信度分数?能否输出概率?
SVM分类器可以输出测试实例与决策边界之间的距离,可将其作为置信度分数。但该分数不能直接转换为类概率估计。若在Scikit-Learn中创建SVM时设置
probability=True
,训练后会使用逻辑回归对SVM的分数进行校准,此时会添加
predict_proba()
和
predict_log_proba()
方法来输出概率。
32、在包含数百万个实例和数百个特征的训练集上训练模型时,应该使用支持向量机(SVM)问题的原始形式还是对偶形式?
应该使用原始形式,因为对偶形式会非常慢。
33、假设你用径向基函数(RBF)核训练了一个支持向量机(SVM)分类器,但它似乎对训练集拟合不足。你应该增大还是减小γ(伽马)?C 呢?
如果用 RBF 核训练的 SVM 分类器对训练集拟合不足,可能存在过度正则化问题。为减少正则化,需要增大 $gamma$ 或 $C$,或者同时增大两者。
34、如何设置二次规划(QP)参数(H、f、A和b),以便使用现成的QP求解器来解决软间隔线性支持向量机(SVM)分类器问题?
软间隔问题的QP参数设置如下:
n_p = n + 1 + m
,
n_c = 2m
,其中:
–
n
是特征数量
–
m
是训练实例数量
H
等于硬间隔问题的
H′
,并在:
– 右侧增加
m 列 0
– 底部增加
m 行 0
f
等于硬间隔问题的
f′
,并增加
m 个元素
,且这些元素都等于超参数
C
的值。
b
等于硬间隔问题的
b′
,并增加
m 个元素
,且这些元素都等于
0
。
A
等于硬间隔问题的
A′
,并在:
– 右侧附加一个
m×m 的单位矩阵 I
– 其正下方为
-I
– 其余部分填充
0
35、在包含一百万个实例的训练集上无限制训练的决策树的大致深度是多少?
决策树的深度约为 log₂(10⁶) ≈ 20(实际上会稍大一些,因为树通常不会完全平衡)。
36、如果决策树对训练集过拟合,尝试减小最大深度(max_depth)是个好主意吗?
是的,减小最大深度(max_depth)会对模型进行正则化,从而降低过拟合的风险,所以是个好主意。
37、如果决策树对训练集欠拟合,尝试对输入特征进行缩放是个好主意吗?
不是。决策树对特征缩放不敏感,当决策树欠拟合时,更好的做法是选择更强大的模型、提供更好的特征或减少模型约束。
38、如果在包含100万个实例的训练集上训练决策树需要1小时,那么在包含1000万个实例的训练集上训练另一个决策树大约需要多长时间?
大约11.7小时
39、如果你的训练集包含100,000个实例,设置presort=True会加快训练速度吗?
不会,设置presort=True会显著减慢训练速度。
40、按照以下步骤为月牙形数据集训练并微调决策树:a. 使用 make_moons(n_samples = 10000, noise = 0.4) 生成月牙形数据集。b. 使用 train_test_split() 函数将数据集拆分为训练集和测试集。c. 使用网格搜索和交叉验证(借助 GridSearchCV 类)为 DecisionTreeClassifier 找到合适的超参数值。提示:尝试不同的 max_leaf_nodes 值。d. 使用这些超参数在完整的训练集上训练模型,并在测试集上评估模型的性能。你应该能得到大约 85% 到 87% 的准确率。
以下是实现上述步骤的 Python 代码示例:
from sklearn.datasets import make_moons
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score
# a. 生成月牙形数据集
X, y = make_moons(n_samples = 10000, noise = 0.4)
# b. 拆分数据集为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# c. 使用网格搜索和交叉验证寻找合适的超参数值
param_grid = {'max_leaf_nodes': list(range(2, 100))}
clf = DecisionTreeClassifier(random_state=42)
grid_search = GridSearchCV(clf, param_grid, cv=5, scoring='accuracy')
grid_search.fit(X_train, y_train)
# 获取最佳超参数
best_max_leaf_nodes = grid_search.best_params_['max_leaf_nodes']
# d. 使用最佳超参数在完整的训练集上训练模型
best_clf = DecisionTreeClassifier(max_leaf_nodes=best_max_leaf_nodes, random_state=42)
best_clf.fit(X_train, y_train)
# 在测试集上评估模型的性能
y_pred = best_clf.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
print(f'模型在测试集上的准确率: {accuracy * 100:.2f}%')
运行上述代码,你应该能得到大约 85% 到 87% 的准确率。
41、按以下步骤构建一个森林:a. 从训练集中随机生成1000个子集,每个子集包含100个实例。提示:可以使用Scikit – Learn的ShuffleSplit类来完成。b. 使用已找到的最佳超参数值,在每个子集上训练一棵决策树。在测试集上评估这1000棵决策树。由于它们是在较小的数据集上训练的,这些决策树的表现可能比第一棵决策树差,准确率仅约为80%。c. 对于测试集中的每个实例,生成1000棵决策树的预测结果,并只保留最频繁的预测(可以使用SciPy的mode()函数来实现)。这种方法可以让你在测试集上得到多数投票的预测结果。d. 在测试集上评估这些预测结果:你应该会得到比第一个模型略高的准确率(大约高0.5%到1.5%)。恭喜你,你已经训练出了一个随机森林分类器!
通过上述步骤,可完成随机森林分类器的训练:
先从训练集随机生成 1000 个含 100 个实例的子集
用最佳超参数在子集上训练决策树
评估其准确率约 80%
再用多数投票法得到测试集预测结果
最终评估预测结果,准确率比第一个模型高 0.5% 到 1.5%
42、能否将这些模型组合以获得更好的结果?如果可以,怎么做?如果不行,为什么?
可以将模型组合以获得更好的结果。可使用硬投票或软投票的方式将不同分类器组合成集成模型,还可以通过运行各分类器在验证集上进行预测,用这些预测结果创建新的训练集,训练一个混合器,与各分类器一起形成堆叠集成。
43、硬投票分类器和软投票分类器有什么区别?
硬投票分类器
:统计集成中每个分类器的投票,选择获得最多投票的类别。
软投票分类器
:计算每个类别的平均估计类别概率,选择概率最高的类别。
软投票给予高置信度投票更多权重,通常表现更好,但要求每个分类器都能估计类别概率。
44、是否可以通过在多台服务器上分布训练来加速装袋集成的训练?粘贴集成、提升集成、随机森林或堆叠集成呢?
可以通过在多台服务器上分布训练来加速装袋集成的训练,因为集成中的每个预测器相互独立。同理,粘贴集成和随机森林也可以。
但提升集成中每个预测器基于前一个预测器构建,训练必须按顺序进行,分布训练无法加速。
堆叠集成中,给定层的所有预测器相互独立,可在多台服务器上并行训练,但一层的预测器必须在前一层的预测器全部训练完成后才能训练。