大数跨境
0
0

【机器学习 课后习题 系列教程】第3章 习题解答

【机器学习 课后习题 系列教程】第3章 习题解答 简博士数据分析吧
2025-01-14
1



内容提要:

 * 习题 3.1 详解

 * 习题 3.2 详解

 * 习题 3.3 详解

点击蓝字 |关注我们

习题 3.1 详解

「习题 3.1」参照图 3.1,在二维空间中给出实例点,画出   为 1 和 2 时的 近邻法构成的空间划分,并对其进行比较,体会 值选择与模型复杂度及预测准确率的关系。

书中的图3.1

「解」

根据题意,首先参照《统计学习方法(第 2 版)》中的图 3.1 给出二维空间中的实例点,然后对于 ,分别训练 近邻模型并绘制决策边界,最后比较不同 值下的模型复杂度与预测准确率。

1. 给出二维空间中的实例点

在《统计学习方法(第 2 版)》的图 3.1 上添加坐标网格,提取实例点坐标。

在图3.1上添加坐标网格

表示点类实例集合,

表示叉类实例集合,

得到数据集

2. 训练 近邻模型并绘制决策边界

近邻法对数据集 进行空间划分的 Python 代码如下。

# 导入相关模块
import numpy as np
import matplotlib.pyplot as plt
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import accuracy_score
from matplotlib.colors import ListedColormap


# 点类数据集,类别设为 0
T_1 = np.array([[0.820],
                 [1.85.70],
                 [2.64.60],
                 [33.60],
                 [3.92.40],
                 [3.93.80],
                 [45.40],
                 [5.22.80],
                 [5.24.20],
                 [5.930],
                 [6.64.80]])

# 叉类数据集,类别设为 1
T_2 = np.array([[2.20.81],
                 [2.41.61],
                 [13.31],
                 [23.21],
                 [3.431],
                 [4.51.21],
                 [61.31]])

# 两个类别合并之后的数据集 T
T = np.vstack((T_1, T_2))

# 提取特征和标签
X = T[:, 0:2]  # 点坐标
y = T[:, 2]    # 类别标签


# 自定义图片颜料池
cmap_light = ListedColormap(['#FFAAAA''#AAFFAA']) # 浅色系
cmap_bold = ListedColormap(['#FF0000''#00FF00'])  # 深色系


# 创建函数绘制决策边界
def plot_decision_boundary(X, y, model, ax, title):
    
    h = 0.02  # 设置网格的步长, 数值越小,划分空间之间的分隔线越清晰
    x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
    y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
    xx, yy = np.meshgrid(np.arange(x_min, x_max, h),
                         np.arange(y_min, y_max, h))

    # 用训练好的模型预测每个点的类别
    Z = model.predict(np.c_[xx.ravel(), yy.ravel()])
    Z = Z.reshape(xx.shape)

    # 绘制决策边界
    ax.contourf(xx, yy, Z, alpha=0.8, cmap=cmap_light)
    ax.scatter(X[:, 0], X[:, 1], c=y, edgecolors='k', marker='o', s=100, cmap=cmap_bold)
    ax.set_title(title)
    ax.set_xticks(())
    ax.set_yticks(())

# 创建 k 近邻模型并分别设置k=1和k=2
fig, axs = plt.subplots(12, figsize=(126))

# k=1
knn1 = KNeighborsClassifier(n_neighbors=1, n_jobs=-1# n_jobs 用于指定并行计算时使用的CPU核心数
knn1.fit(X, y)
plot_decision_boundary(X, y, knn1, axs[0], "k=1")

# k=2
knn2 = KNeighborsClassifier(n_neighbors=2, n_jobs=-1)
knn2.fit(X, y)
plot_decision_boundary(X, y, knn2, axs[1], "k=2")

# 显示图形
plt.tight_layout()
plt.show()

# 计算预测准确率
y_pred_1 = knn1.predict(X)
y_pred_2 = knn2.predict(X)

accuracy_1 = accuracy_score(y, y_pred_1)
accuracy_2 = accuracy_score(y, y_pred_2)

print(f"Accuracy for k=1: {accuracy_1:.2f}")
print(f"Accuracy for k=2: {accuracy_2:.2f}")

运行代码,可以得到 分别为 1 和 2 时的分类决策边界,并且预测准确率分别为 100% 和 89%。

的分类决策边界

)

3. 比较不同 值下的模型复杂度与预测准确率

仔细观察可以发现, 时决策边界较为复杂,呈现更多的锯齿状,这是因为每个测试点都依赖于最近的一个训练点,很容易受到噪声的影响,导致过拟合; 时决策边界略显平滑一些,因为每个测试点的分类依赖于最近的两个训练点,边界变得稍微稳定,且减少了对局部噪声的敏感性。

另外,从输出的预测准确率可以看出, 时的准确率更高,但如果数据中存在噪声或者不均衡,它可能导致过拟合; 时的准确率略低,无法很好地捕捉数据的细节,但因为模型复杂度低一些,可能具有更好的泛化能力。

很明显, 值的选取对模型有一定的影响,具体内容见下表。

值的选取对模型的影响

习题 3.2 详解

「习题 3.2」 利用例题 3.2 构造的 树求点 的最近邻点。

例题 3.2 构造的
例题 3.2 的空间划分

「解」

1. 寻找“当前最近点”

从根结点开始, 在根结点 的左子区域内,继续探寻,进入 所确定的上子区域内,最终到达 的左子区域中, 就是“当前最近邻点”。

2. 回溯验证

为圆心, 之间的距离为半径画一个圆,如图所示。

第一次回溯

这个区域内有两个结点,分别是 。计算 到这两点的距离,发现 之间的距离最近,那么 为“当前最近点”。接着,再以 为圆心, 之间的距离为半径画一个圆,此时圆里没有其他结点,说明可以确认 就是 的最近邻点,如图所示。

第二次回溯

习题 3.3 详解

「习题 3.3」参照算法 3.3,写出输出为 近邻的算法。

「解」

先将算法 3.3列出如下:

算法 3.3 (用 树的最近邻搜索)

输入:已构造的 树,目标点

输出: 的最近邻。

(1)在 树中找出包含目标点 的叶结点:从根结点出发,递归地向下访问 树。若目标点 当前维的坐标小于切分点的坐标,则移动到左子结点,否则移动到右子结点。直到子结点为叶结点为止。

(2)以此叶结点为"当前最近点"。

(3)递归地向上回退,在每个结点进行以下操作:

(a)如果该结点保存的实例点比当前最近点距离目标点更近,则以该实例点为"当前最近点"。

(b)当前最近点一定存在于该结点一个子结点对应的区域。检查该子结点的父结点的另一子结点对应的区域是否有更近的点。具体地,检查另一子结点对应的区域是否与以目标点为球心,以目标点与"当前最近点"间的距离为半径的超球体相交。

如果相交,可能在另一个子结点对应的区域内存在距目标点更近的点,移动到另一个子结点。接着,递归地进行最近邻搜索;

如果不相交,向上回退。

(4)当回退到根结点时,搜索结束。最后的"当前最近点"即为 的最近邻点。

仿照算法 3.3,得到用 树的 近邻搜索的算法如下。

输入:已构造的 树,目标点

输出: 近邻。

(1) 在 树中找出包含目标点 的叶结点:从根结点出发,递归地向下访问 树。若目标点 当前维的坐标小于切分点的坐标,则移动到左子结点,否则移动到右子结点。直到子结点为叶结点为止。

(2) 以该叶结点作为当前最近邻实例记录在列表中,若 ,确定“当前 近邻”个实例。若 ,先搜索子结点的父结点的另一子结点对应的区域是否有近邻点,若有,记录到列表中,否则退回上一层结点继续寻找。直到列表中满足 个实例点则停止记录,否则继续向上搜索,确定“当前 近邻”个实例。

(3) 递归地向上回退,在每个结点进行以下操作:

(a) 如果目标点与当前结点的距离小于目标点与“当前 近邻”个实例中的最远距离,则将该结点记录到“当前 近邻”中。

(b) 检查该子结点的父结点的另一子结点对应的区域是否有更近的点。具体地,检查另一子结点对应的区域是否与以目标实例 为球心,“当前 近邻”中与目标实例 最远的距离为半径的超球体相交。如果相交,可能在另一个子结点对应的区域内存在距目标点更近的点,移动到另一个子结点。接着,递归地进行近邻搜索;如果不相交,向上回退。

(4) 当回退到根结点时,搜索结束。最后的“当前 近邻”即为 近邻点。

下面以一个例子来试验以上算法。给定数据集

如图所示。

根据构造平衡 树的算法,对数据集进行划分得到如下结果。

空间划分

接下来,我们以欧式距离为距离度量,搜索目标实例 个近邻点。具体的搜索步骤如下。

(1) 寻找当前 近邻:从根结点出发, 在根结点  的左子区域内,接着搜索到深度为 1 的叶子结点 所确定的下子区域内,记录 为“当前 近邻点”。

(2) 回溯验证:

(a) 计算 的欧式距离,分别为 2.91 和 1.63。 ,以 为圆心, 之间的距离为半径画圆,这个区域内还包含 1 个父结点 ,则更新 为“当前 近邻点”。

第一次回溯

(b) 计算 的距离,分别为 1.80 和 1.63。 ,以 为圆心,  之间的距离为半径画圆,这个区域内没有其他结点,说明可以确认 近邻点。

第二次回溯

好啦,关于第三章的习题解答就说到这里,希望大家可以耐心看完!

如果这个免费讲义对你的学习有所帮助,请帮助我们推荐给更多的朋友,回复「入群」,也可以加入我们的学习来哦!我们下期不见不散。

欢迎大家关注简博士的B站和公众号,在公众号私信“入群”,可以与小伙伴们一起讨论问题哦。


【声明】内容源于网络
0
0
简博士数据分析吧
信息时代最不缺的是什么?数据!最缺的是什么?数据分析的思维!在这里,你将获取神秘的力量,推开数据之门!
内容 181
粉丝 0
简博士数据分析吧 信息时代最不缺的是什么?数据!最缺的是什么?数据分析的思维!在这里,你将获取神秘的力量,推开数据之门!
总阅读42
粉丝0
内容181