机器学习基础教程笔记

机器学习基础教程笔记

参考书籍:《python机器学习基础教程》
该书讲述了如何用python实现scikit-learn库中的机器学习算法,但书内很多算法讲的不够详细,代码注释也较少,所以想着提炼补充一下。

1、认识一些样本的数据集

  1. 二分类数据集 – forge数据集

forge 数据集是一个用于演示目的的合成二分类数据集。它通常被用来展示和理解不同机器学习模型的工作原理,特别是用于分类问题。forge 数据集的特点包括:

  • 二维特征空间:这个数据集包含两个特征,这使得它特别适合于可视化,因为每个数据点可以在二维平面上表示。
  • 简单的线性可分性:forge 数据集中的数据点可以通过直线大致分为两类。
import mglearn
import matplotlib.pyplot as plt

X,y = mglearn.datasets.make_forge()
mglearn.discrete_scatter(X[:,0],X[:,1],y)
plt.xlabel("FIRST FEATURE")
plt.ylabel("SECOND FEATURE")
print("X.shape:{}".format(X.shape))

结果:
在这里插入图片描述

  1. wave数据集

wave 数据集是另一个在 mglearn 库中提供的合成数据集,主要用于演示回归算法。

X,y = mglearn.datasets.make_wave(n_samples=64)
plt.plot(X,y,'o')
plt.ylim(-3,3)
plt.xlabel("Feature")
plt.ylabel("Target")

结果:
在这里插入图片描述
3. cancer数据集

在 scikit-learn中,乳腺癌数据集(breast cancer dataset)是一个用于分类任务的著名数据集。这个数据集包含乳腺癌肿瘤的特征和对应肿瘤是恶性还是良性的标签。

关于乳腺癌数据集的主要特点:

  • 数据点数量:数据集包含569个数据点
  • 特征数量:每个样本有30个特征,这些特征是从数字化图像的细胞核计算得出的。这些特征包括细胞核的半径、纹理、周长、面积、平滑度、紧凑度、凹度、凹点、对称性和分形维数的平均值、标准误差和“最坏”或最大值(这三种测量的平均值、标准误差和最大值)
  • 标签:肿瘤分类为两类——恶性(malignant)和良性(benign)
from sklearn.datasets import load_breast_cancer

# 加载数据集
cancer = load_breast_cancer()

# 打印数据集的形状
print("Data shape:", cancer.data.shape)

# 打印所有特征名
print("Feature names:", cancer.feature_names)

结果:
在这里插入图片描述

2、K近邻分类

k近邻算法的原理是根据最近的k个邻居的标签来预测新数据点的类别或回归值,基于“近者类似”的假设

# 这里邻居数量为 1,即预测结果为距离他最近的那个类别
mglearn.plots.plot_knn_classification(n_neighbors=1)

在这里插入图片描述

# 这里邻居数量为 3,即预测结果为距离他最近的3个邻居进行“投票”来决定预测类别
mglearn.plots.plot_knn_classification(n_neighbors=3)

在这里插入图片描述
下面是使用scikit-learn来实现k近邻算法的过程:

from sklearn.model_selection import train_test_split
X,y = mglearn.datasets.make_forge()

X_train, X_test , y_train ,y_test = train_test_split(X,y,random_state=0)

#导入类并实例化,设定k近邻的参数
from sklearn.neighbors import KNeighborsClassifier
clf = KNeighborsClassifier(n_neighbors=3)

#通过数据集对分类器进行训练
clf.fit(X_train,y_train)

#通过训练好的分类器进行预测
print("测试集预测结果为:{}".format(clf.predict(X_test)))
print("实际测试集结果为:{}".format(y_test))
print("测试集准确率为:{}".format(clf.score(X_test,y_test)))

结果为:
在这里插入图片描述
我们还可以在二维平面上通过对平面进行着色来查看决策边界:

# 使用Matplotlib创建一个1行3列的子图,每个子图的大小为10x3英寸
fig, axes = plt.subplots(1, 3, figsize=(10, 3))

# 对于k值分别为1, 3, 9的情况,进行遍历
for n_neighbors, ax in zip([1, 3, 9], axes):
    # 创建并训练k-近邻分类器模型
    clf = KNeighborsClassifier(n_neighbors=n_neighbors).fit(X, y)
    # 在当前子图上绘制决策边界。fill=True表示填充颜色,eps是边缘扩展距离,ax指定绘图的子图,alpha是透明度
    mglearn.plots.plot_2d_separator(clf, X, fill=True, eps=0.5, ax=ax, alpha=.4)
    # 在当前子图上绘制数据点
    mglearn.discrete_scatter(X[:, 0], X[:, 1], y, ax=ax)
    # 设置子图的标题,显示当前的邻居数
    ax.set_title("{} neighbor(s)".format(n_neighbors))
    # 设置x轴和y轴的标签
    ax.set_xlabel("feature 0")
    ax.set_ylabel("feature 1")

# 在第一个子图上添加图例,位置在左下角
axes[0].legend(loc=3)

结果为:
在这里插入图片描述
从图中可以看出,随着邻居数量的增多,决策边界变得平滑,也就是说使用更少的邻居对应更更高的模型复杂度,使用更多的邻居对应更更低的模型复杂度。

更少的邻居(较低的k值)意味着更高的模型复杂度:当k值较小,模型在做出预测时只考虑非常接近的几个邻居。这会导致模型对训练数据中的小波动或噪声更敏感,从而产生更复杂或更不规则的决策边界。换句话说,模型更倾向于精确匹配训练数据中的特定样本,可能导致过拟合。
更多的邻居(较高的k值)意味着更低的模型复杂度:当k值较大时,模型在做出决策时会考虑更多的邻居。这种情况下,模型不太受个别数据点的影响,决策边界会变得更平滑、更简单。这样的模型对训练数据中的异常值或噪声不那么敏感,通常对新数据有更好的泛化能力,但可能会导致欠拟合。

我们还可以在乳腺癌数据集上研究不同邻居的个数对训练集和测试集上性能的影响:

# 加载乳腺癌数据集
cancer = load_breast_cancer()

# 将数据分为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(cancer.data, cancer.target, stratify=cancer.target, random_state=66)

# 初始化存储训练准确率和测试准确率的列表
training_accuracy = []
test_accuracy = []

# 设置要测试的邻居数的范围:1到10
neighbors_settings = range(1, 11)

# 对每个邻居数进行迭代
for n_neighbors in neighbors_settings:
    # 创建k-近邻分类器实例,并设置邻居数
    clf = KNeighborsClassifier(n_neighbors=n_neighbors)

    # 在训练集上训练分类器
    clf.fit(X_train, y_train)

    # 记录训练集的准确率
    training_accuracy.append(clf.score(X_train, y_train))

    # 记录测试集的准确率
    test_accuracy.append(clf.score(X_test, y_test))

# 使用Matplotlib绘制邻居数与训练集准确率之间的关系
plt.plot(neighbors_settings, training_accuracy, label="训练集准确率")

# 绘制邻居数与测试集准确率之间的关系
plt.plot(neighbors_settings, test_accuracy, label="测试集准确率")

# 设置y轴标签为"准确率"
plt.ylabel("准确率")

# 设置x轴标签为"邻居数"
plt.xlabel("邻居数")

# 添加图例
plt.legend()

结果:
在这里插入图片描述
从图中可以看出,仅考虑单一邻近时,训练集的结果很完美,但在测试集上表现的很不好,模型过于复杂 ; 随着邻居数增多,在测试集上的精度有所提升。

3、k近邻回归

k近邻回归(k-Nearest Neighbors, k-NN regression)是一种基本的机器学习方法,用于回归分析。它是k近邻算法的一种应用,旨在用于连续变量的预测。与k近邻分类相似,k近邻回归的核心思想是找到一个样本点的k个最近邻居(即在特征空间中与该样本点最接近的k个样本),然后用这些邻居的值来预测目标样本点的值

工作原理

  • 距离度量:首先,定义一个距离度量(如欧氏距离、曼哈顿距离等),用于计算测试点与训练数据集中每个点之间的距离
  • 找到k个最近邻:对于给定的测试样本,根据距离度量找出训练集中与其最近的k个样本点
  • 回归预测:然后,根据这k个最近邻的目标变量的值来预测测试点的目标值。在k近邻回归中,这通常通过取这些最近邻的目标值的平均值或加权平均值来实现

单一近邻回归示例

mglearn.plots.plot_knn_regression(n_neighbors=1)

在这里插入图片描述
从图像中可以看到,回归的结果就是和最近的邻居具有相同的target值

mglearn.plots.plot_knn_regression(n_neighbors=3)

在这里插入图片描述
当邻居的数量变为三个后,回归的结果就是三个最近邻居的target值的平均值

k近邻回归在scikit-learn中的KNeighborsRegressor类中实现:

from sklearn.neighbors import KNeighborsRegressor

X,y = mglearn.datasets.make_wave(n_samples=40)
X_train,X_test,y_train,y_test = train_test_split(X,y,random_state=0)

reg = KNeighborsRegressor(n_neighbors=3)
reg.fit(X_train,y_train)
print("测试集预测结果为:\n{}".format(reg.predict(X_test)))

在这里插入图片描述
回归的结果可以用R2分数来进行评估:
在这里插入图片描述

print("R^2分数为{:.2f}".format{reg.score(X_test,y_test})

在这里插入图片描述
下面我们通过图像分析不同邻居数对k近邻回归结果的影响

import numpy as np
import matplotlib.pyplot as plt
from sklearn.neighbors import KNeighborsRegressor

# 创建一个1行3列的子图布局,每个子图的大小为15x4
fig, axes = plt.subplots(1, 3, figsize=(15, 4))

# 生成一个线性空间,用于模型预测
line = np.linspace(-3, 3, 1000).reshape(-1, 1)

# 遍历不同的邻居数(1, 3, 9),在三个子图上分别展示结果
for n_neighbors, ax in zip([1, 3, 9], axes):
    # 使用指定的邻居数初始化k近邻回归模型
    reg = KNeighborsRegressor(n_neighbors=n_neighbors)
    # 使用训练数据拟合模型
    reg.fit(X_train, y_train)
    # 在子图上绘制模型预测结果
    ax.plot(line, reg.predict(line))
    # 在子图上用蓝色三角形标记训练数据点
    ax.plot(X_train, y_train, '^', c=mglearn.cm2(0), markersize=8)
    # 在子图上用绿色三角形标记测试数据点
    ax.plot(X_test, y_test, '^', c=mglearn.cm2(1), markersize=8)
    # 设置子图的标题,包括邻居数、训练分数和测试分数
    ax.set_title("{} neighbor(s)\n train score:{:.2f} test score:{:.2f}".format(
        n_neighbors, reg.score(X_train, y_train), reg.score(X_test, y_test)))
    # 设置x轴和y轴的标签
    ax.set_xlabel("Feature")
    ax.set_ylabel("Target")

# 在第一个子图上添加图例,标识模型预测、训练数据点和测试数据点
axes[0].legend(["Model predictions", "Train data/target", "Test data/target"])

在这里插入图片描述
从图像上看,随着邻居数的增加,预测结果曲线变得平滑,但拟合的效果变得较差,这需要不断进行调试来达到一种平衡。

K近邻回归的优缺点:
k近邻回归是一种直观的非参数学习方法,能够适应任何形式的数据分布,不需要复杂的数学建模,使其易于实现和理解。它特别适用于具有较少数据点的问题,因为这种情况下模型的预测能力往往更加准确。然而,k近邻回归的主要缺点包括高计算成本,尤其是在处理大型数据集时,因为它需要为每个预测计算输入样本与训练集中所有样本点的距离。此外,它对异常值敏感,且在高维数据下性能下降(维度诅咒),还需要合理选择邻居数目(k值)来确保最佳性能。

  • 18
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值