昇思MindSpore 应用学习-K近邻算法实现红酒聚类-CSDN

K近邻算法实现红酒聚类-AI代码解析

本实验主要介绍使用MindSpore在部分wine数据集上进行KNN实验。

1、实验目的

  • 了解KNN的基本概念;
  • 了解如何使用MindSpore进行KNN实验。

2、K近邻算法原理介绍

K近邻算法(K-Nearest-Neighbor, KNN)是一种用于分类和回归的非参数统计方法,最初由 Cover 和 Hart 于 1968 年提出,是机器学习最基础的算法之一。它的基本思想是:要确定一个样本的类别,可以计算它与所有训练样本的距离,然后找出和该样本最接近的 k 个样本,统计出这些样本的类别并进行投票,票数最多的那个类就是分类的结果。
KNN的三个基本要素:

  • K值:一个样本的分类是由 K 个邻居的“多数表决”确定的。K 值越小,容易受噪声影响,反之,会使类别之间的界限变得模糊。
  • 距离度量:反映了特征空间中两个样本间的相似度,距离越小,越相似。常用的有 Lp 距离(p=2 时,即为欧式距离)、曼哈顿距离、海明距离等。
  • 分类决策规则:通常是多数表决,或者基于距离加权的多数表决(权值与距离成反比)。

2.1 分类问题

预测算法(分类)的流程如下:

  1. 在训练样本集中找出距离待测样本 x_test 最近的 k 个样本,并保存至集合 N 中;
  2. 统计集合 N 中每一类样本的个数 (C_{i}, i=1,2,3,…,c);
  3. 最终的分类结果为 ( \text{argmax} C_{i} )(最大的对应的 (C_{i}))那个类。

在上述实现过程中,k 的取值尤为重要。它可以根据问题和数据特点来确定。在具体实现时,可以考虑样本的权重,即每个样本有不同的投票权重,这种方法称为带权重的 k 近邻算法,它是一种变种的 k 近邻算法。

2.2 回归问题

假设离测试样本最近的 k 个训练样本的标签值为 (y_{i}),则对样本的回归预测输出值为:
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
即为所有邻居的标签均值。
带样本权重的回归预测函数为:
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
其中 (w_{i}) 为第个 (i) 样本的权重。

2.3 距离的定义

KNN算法的实现依赖于样本之间的距离,其中最常用的距离函数就是欧氏距离(欧几里得距离)。( \mathbb{R}^{n} )空间中的两点 (x) 和 (y),它们之间的欧氏距离定义为:
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
需要特别注意的是,使用欧氏距离时,应将特征向量的每个分量归一化,以减少因为特征值的尺度范围不同所带来的干扰,否则数值小的特征分量会被数值大的特征分量淹没。
其它的距离计算方式还有 Mahalanobis 距离、Bhattacharyya 距离等。

3、实验环境

预备知识:

  • 熟练使用 Python;
  • 具备一定的机器学习理论知识,如 KNN、无监督学习、欧式距离等。

实验环境:

  • MindSpore 2.0(MindSpore 版本会定期更新,本指导也会定期刷新,与版本配套);
  • 本案例支持 win_x86 和 Linux 系统,CPU/GPU/Ascend 均可运行;
  • 如果在本地运行此实验,请参考《MindSpore 环境搭建实验手册》在本地安装 MindSpore。

4、数据处理

4.1 数据准备

Wine 数据集是模式识别最著名的数据集之一,Wine 数据集的官网:Wine Data Set。这些数据是对来自意大利同一地区但来自三个不同品种的葡萄酒进行化学分析的结果。数据集分析了三种葡萄酒中每种所含 13 种成分的量。这些 13 种属性是:

  1. Alcohol,酒精
  2. Malic acid,苹果酸
  3. Ash,灰
  4. Alcalinity of ash,灰的碱度
  5. Magnesium,镁
  6. Total phenols,总酚
  7. Flavanoids,类黄酮
  8. Nonflavanoid phenols,非黄酮酚
  9. Proanthocyanins,原花青素
  10. Color intensity,色彩强度
  11. Hue,色调
  12. OD280/OD315 of diluted wines,稀释酒的OD280/OD315
  13. Proline,脯氨酸
  • 方式一,从 Wine 数据集官网下载 wine.data 文件。
  • 方式二,从华为云 OBS 中下载 wine.data 文件。
    | Key | Value | Key | Value |
    | — | — | — | — |
    | Data Set Characteristics: | Multivariate | Number of Instances: | 178 |
    | Attribute Characteristics: | Integer, Real | Number of Attributes: | 13 |
    | Associated Tasks: | Classification | Missing Values? | No |
%%capture captured_output
# 实验环境已经预装了 mindspore==2.2.14,如需更换 mindspore 版本,可更改下面 mindspore 的版本号
!pip uninstall mindspore -y  # 卸载当前的 mindspore 版本
!pip install -i https://pypi.mirrors.ustc.edu.cn/simple mindspore==2.2.14  # 从指定的镜像源安装指定版本的 mindspore
# 查看当前 mindspore 版本
!pip show mindspore  # 显示当前安装的 mindspore 包的信息
from download import download  # 导入 download 函数用于下载文件# 下载红酒数据集
url = "https://ascend-professional-construction-dataset.obs.cn-north-4.myhuaweicloud.com:443/MachineLearning/wine.zip"  
path = download(url, "./", kind="zip", replace=True)  # 下载红酒数据集压缩文件

解析:

  1. %%capture captured_output:这是一个 Jupyter Notebook 的魔法命令,用于捕获单元格的输出,防止输出在屏幕上显示。
  2. !pip uninstall mindspore -y:使用 pip 命令卸载当前安装的 mindspore 包,-y 参数表示自动确认卸载,避免提示用户。
  3. !pip install -i https://pypi.mirrors.ustc.edu.cn/simple mindspore==2.2.14:安装指定版本(2.2.14)的 mindspore 包,-i 后面跟的是安装源的地址,这里使用的是中国科学技术大学的 PyPI 镜像。
  4. !pip show mindspore:该命令用于显示当前安装的 mindspore 包的详细信息,包括版本、位置等。
  5. from download import download:导入 download 函数,假设该函数用于处理文件下载。
  6. url = "https://ascend-professional-construction-dataset.obs.cn-north-4.myhuaweicloud.com:443/MachineLearning/wine.zip":定义一个变量 url,它包含了要下载的红酒数据集的链接。
  7. path = download(url, "./", kind="zip", replace=True):调用 download 函数下载红酒数据集。参数说明:
    • url: 要下载的文件的地址;
    • "./": 下载的目标路径,这里表示当前目录;
    • kind="zip": 指定下载文件的类型为 zip 格式;
    • replace=True: 如果目标路径已存在同名文件,是否替换,True 表示替换。

4.2 数据读取与处理

导入 MindSpore 模块和辅助模块

在生成数据之前,导入需要的 Python 库。
目前使用到 os 库,为方便理解,其他需要的库,我们在具体使用到时再说明。
详细的 MindSpore 的模块说明,可以在 MindSpore API 页面中搜索查询。
可以通过 context.set_context 来配置运行需要的信息,例如运行模式、后端信息、硬件等信息。
导入 context 模块,配置运行需要的信息。

%matplotlib inline
# 使得在 Jupyter Notebook 中绘制的图形被嵌入在输出单元格中,而不是在新窗口中显示import os  # 导入 os 模块,用于与操作系统进行交互
import csv  # 导入 csv 模块,用于处理 CSV 文件
import numpy as np  # 导入 numpy,用于科学计算和数组操作
import matplotlib.pyplot as plt  # 导入 matplotlib 的 pyplot 模块,用于绘制图形import mindspore as ms  # 导入 mindspore 库
from mindspore import nn, ops  # 从 mindspore 中导入 nn(神经网络模块)和 ops(操作模块)ms.set_context(device_target="CPU")  # 设置 MindSpore 的运行环境为 CPU

解析:

  1. %matplotlib inline:这是一个 Jupyter Notebook 的魔法命令,它使得生成的图形可以直接嵌入在 Notebook 的输出单元格中,而不是在新窗口中弹出。
  2. import os:导入 os 模块,它提供了一些与操作系统交互的功能,比如文件和目录操作。
  3. import csv:导入 csv 模块,用于读取和写入 CSV 格式的数据文件。
  4. import numpy as np:导入 numpy 库,并将其简写为 np,它是用于数组计算和科学计算的基础库。
  5. import matplotlib.pyplot as plt:导入 matplotlib.pyplot 模块,并简写为 plt,该模块提供了绘制图形的功能。
  6. import mindspore as ms:导入 mindspore 库,并将其简写为 ms,它是华为开发的深度学习框架。
  7. from mindspore import nn, ops:从 mindspore 库中导入神经网络模块 nn 和操作模块 ops,这两个模块包含了构建深度学习模型和执行各种运算的工具。
  8. ms.set_context(device_target="CPU"):设置 MindSpore 的上下文环境,指定计算设备为 CPU。这意味着接下来的计算将在 CPU 上进行,而不是使用 GPU 或其他计算设备。
读取 Wine 数据集 wine.data,并查看部分数据。
with open('wine.data') as csv_file:# 以默认模式(只读)打开名为 'wine.data' 的 CSV 文件data = list(csv.reader(csv_file, delimiter=','))  # 使用 csv.reader 读取文件内容,并将其转换为列表# delimiter=',' 指定 CSV 文件的分隔符为逗号print(data[56:62] + data[130:133])  
# 打印数据列表中第 57 到 62 行(不包括第 62 行)以及第 131 到 133 行(不包括第 133 行)的内容

解析:

  1. with open('wine.data') as csv_file::以上下文管理器的方式打开名为 wine.data 的文件。这种方式确保文件在处理完成后能够自动关闭。
  2. data = list(csv.reader(csv_file, delimiter=','))
    • csv.reader(csv_file, delimiter=','):使用 csv 模块的 reader 函数读取打开的文件 csv_file,并指定分隔符为逗号(,),这适用于 CSV 格式的文件。
    • list(...):将读取的结果转换为一个列表,data 变量将存储该列表,列表的每个元素都是一个表示 CSV 行的列表。
  3. print(data[56:62] + data[130:133])
    • data[56:62]:切片操作,获取 data 列表中索引为 56 到 61 的行(共 6 行)。
    • data[130:133]:切片操作,获取 data 列表中索引为 130 到 132 的行(共 3 行)。
    • +:将这两个切片结果合并为一个新列表,并打印输出。
取三类样本(共 178 条),将数据集的 13 个属性作为自变量 (X)。将数据集的 3 个类别作为因变量 (Y)。
X = np.array([[float(x) for x in s[1:]] for s in data[:178]], np.float32)
# 创建一个二维 numpy 数组 X,包含前 178 行数据的特征部分
# 使用列表推导式,将每行数据中的第 1 个元素到最后一个元素转换为 float 类型
# np.float32 指定数组的数据类型为 32 位浮点数Y = np.array([s[0] for s in data[:178]], np.int32)
# 创建一维 numpy 数组 Y,包含前 178 行数据的标签部分
# 使用列表推导式,提取每行数据的第 0 个元素(标签)并转换为 int 类型
# np.int32 指定数组的数据类型为 32 位整数

解析:

  1. X = np.array([[float(x) for x in s[1:]] for s in data[:178]], np.float32)
    • 这行代码使用嵌套列表推导式,首先对 data[:178] 切片进行操作,提取前 178 行的数据。
    • for s in data[:178]:遍历前 178 行的数据,s 是每一行的内容。
    • [float(x) for x in s[1:]]:对于每一行 s,提取从索引 1 开始到行末的所有元素,将其转换为浮点数(float)。
    • np.array(..., np.float32):将生成的二维列表转换为 NumPy 数组,并指定数据类型为 32 位浮点数(np.float32)。
  2. Y = np.array([s[0] for s in data[:178]], np.int32)
    • 这行代码使用列表推导式提取前 178 行数据的标签部分。
    • [s[0] for s in data[:178]]:遍历前 178 行数据,提取每行的第 0 个元素(通常为标签或目标值)。
    • np.array(..., np.int32):将生成的一维列表转换为 NumPy 数组,并指定数据类型为 32 位整数(np.int32)。
取样本的某两个属性进行 2 维可视化,可以看到在某两个属性上样本的分布情况以及可分性。
attrs = ['Alcohol', 'Malic acid', 'Ash', 'Alcalinity of ash', 'Magnesium', 'Total phenols','Flavanoids', 'Nonflavanoid phenols', 'Proanthocyanins', 'Color intensity', 'Hue','OD280/OD315 of diluted wines', 'Proline']
# 定义一个列表 attrs,包含不同的葡萄酒属性名称plt.figure(figsize=(10, 8))
# 创建一个新的图形,设定图形的大小为 10x8 英寸for i in range(0, 4):# 循环从 0 到 3,生成 4 个子图plt.subplot(2, 2, i+1)# 创建一个 2 行 2 列的子图,并选择第 i+1 个子图进行绘制a1, a2 = 2 * i, 2 * i + 1# 计算当前子图中要绘制的两个属性的索引 a1 和 a2plt.scatter(X[:59, a1], X[:59, a2], label='1')# 绘制前 59 个样本的属性 a1 和 a2 的散点图,标签为 '1'plt.scatter(X[59:130, a1], X[59:130, a2], label='2')# 绘制第 60 到 130 个样本的属性 a1 和 a2 的散点图,标签为 '2'plt.scatter(X[130:, a1], X[130:, a2], label='3')# 绘制第 131 个样本到最后的样本的属性 a1 和 a2 的散点图,标签为 '3'plt.xlabel(attrs[a1])# 设置 x 轴标签为对应属性的名称plt.ylabel(attrs[a2])# 设置 y 轴标签为对应属性的名称plt.legend()# 添加图例,以显示不同类别的样本标签plt.show()
# 显示绘制的图形

解析:

  1. attrs = [...]:定义了一个包含葡萄酒特征名称的列表,这些特征将用于绘制图形的坐标轴标签。
  2. plt.figure(figsize=(10, 8)):使用 Matplotlib 创建一个新图形,并设定其大小为 10x8 英寸。
  3. for i in range(0, 4)::循环 4 次(i 从 0 到 3),用于创建 4 个子图。
  4. plt.subplot(2, 2, i+1):在 2 行 2 列的图形布局中选择第 i+1 个子图。
  5. a1, a2 = 2 * i, 2 * i + 1:计算要在当前子图中绘制的两个特征的索引。每个子图显示两个特征的散点图。
  6. plt.scatter(...):绘制散点图:
    • X[:59, a1]X[:59, a2]:表示前 59 个样本的第 a1a2 列作为 x 和 y 轴的数据。
    • X[59:130, a1]X[59:130, a2]:表示第 60 到 130 个样本的数据。
    • X[130:, a1]X[130:, a2]:表示第 131 个样本到最后的样本的数据。
  7. plt.xlabel(attrs[a1])plt.ylabel(attrs[a2]):设置 x 轴和 y 轴的标签,显示对应的属性名称。
  8. plt.legend():添加图例,表示每个类别的样本。
  9. plt.show():显示最终绘制的图形。
将数据集按 128:50 划分为训练集(已知类别样本)和验证集(待验证样本):
train_idx = np.random.choice(178, 128, replace=False)
# 随机选择 128 个不重复的索引从 0 到 177(共 178 个样本),用于训练集
# np.random.choice 的参数为样本总数、选择的数量和是否允许重复选择test_idx = np.array(list(set(range(178)) - set(train_idx)))
# 创建测试集的索引
# set(range(178)) 生成一个包含 0 到 177 的集合
# set(train_idx) 生成训练集索引的集合
# 通过集合的差集操作得到未被选择的索引,转化为 NumPy 数组X_train, Y_train = X[train_idx], Y[train_idx]
# 根据训练集索引 train_idx 提取训练数据 X 和标签 Y 的相应部分X_test, Y_test = X[test_idx], Y[test_idx]
# 根据测试集索引 test_idx 提取测试数据 X 和标签 Y 的相应部分

解析:

  1. train_idx = np.random.choice(178, 128, replace=False)
    • 使用 np.random.choice 从 0 到 177 的范围内随机选择 128 个索引。
    • replace=False 表示不允许重复选择,即每个索引只能选择一次。
  2. test_idx = np.array(list(set(range(178)) - set(train_idx)))
    • set(range(178)) 创建一个包含 0 到 177 的集合。
    • set(train_idx) 创建一个包含训练集索引的集合。
    • 通过集合的差集操作 - 得到未被选择的索引。
    • 最后将结果转换为 NumPy 数组,存储为 test_idx
  3. X_train, Y_train = X[train_idx], Y[train_idx]
    • 根据 train_idx 提取训练集的特征数据 X 和对应的标签 Y
    • X[train_idx] 获取训练样本的特征数据,Y[train_idx] 获取训练样本的标签。
  4. X_test, Y_test = X[test_idx], Y[test_idx]
    • 根据 test_idx 提取测试集的特征数据 X 和对应的标签 Y
    • X[test_idx] 获取测试样本的特征数据,Y[test_idx] 获取测试样本的标签。

5、模型构建–计算距离

利用 MindSpore 提供的 tile, square, ReduceSum, sqrt, TopK 等算子,通过矩阵运算的方式同时计算输入样本 x 和已明确分类的其他样本 X_train 的距离,并计算出 top k 近邻。

class KnnNet(nn.Cell):def __init__(self, k):super(KnnNet, self).__init__()self.k = k# 初始化 KNN 网络,k 表示最近邻的数量def construct(self, x, X_train):# 平铺输入 x 以匹配 X_train 中的样本数x_tile = ops.tile(x, (128, 1))# 使用 ops.tile 将输入 x 复制 128 次,以便与训练样本 X_train 的形状匹配square_diff = ops.square(x_tile - X_train)# 计算 x_tile 和 X_train 之间的平方差square_dist = ops.sum(square_diff, 1)# 对每一行的平方差求和,以得到每个样本的平方距离dist = ops.sqrt(square_dist)# 计算每个样本的欧几里得距离# -dist 表示值越大,样本就越接近values, indices = ops.topk(-dist, self.k)# 获取距离最近的 k 个样本的索引,-dist 确保距离越小的样本排在前面return indices# 返回 k 个最近邻的索引def knn(knn_net, x, X_train, Y_train):x, X_train = ms.Tensor(x), ms.Tensor(X_train)# 将输入 x 和训练样本 X_train 转换为 Tensor 类型,适合后续计算indices = knn_net(x, X_train)# 使用 knn_net 模型对输入 x 和训练样本 X_train 进行预测,获取最近邻的索引topk_cls = [0] * len(indices.asnumpy())# 初始化一个计数器列表,用于记录每个类的出现次数for idx in indices.asnumpy():topk_cls[Y_train[idx]] += 1# 根据最近邻的索引,增加对应类在 topk_cls 中的计数cls = np.argmax(topk_cls)# 找到计数最多的类作为最终的预测结果return cls# 返回预测的类标签

解析:

  1. KnnNet 类
    • class KnnNet(nn.Cell)::定义一个 KNN 网络类,继承自 nn.Cell
    • def __init__(self, k)::构造函数,初始化 KNN 中的 k 值。
    • self.k = k:保存 k 的值。
  2. construct 方法
    • def construct(self, x, X_train)::定义前向传播的方法,接收输入 x 和训练数据 X_train
    • x_tile = ops.tile(x, (128, 1)):对输入样本 x 进行平铺,以与 X_train 的样本数匹配。
    • square_diff = ops.square(x_tile - X_train):计算 x 和每个训练样本之间的平方差。
    • square_dist = ops.sum(square_diff, 1):计算每个样本的平方距离。
    • dist = ops.sqrt(square_dist):计算每个样本的欧几里得距离。
    • values, indices = ops.topk(-dist, self.k):获取距离最近的 k 个样本的索引(使用负值确保较小的距离优先)。
  3. knn 函数
    • def knn(knn_net, x, X_train, Y_train)::定义 KNN 函数,执行预测。
    • x, X_train = ms.Tensor(x), ms.Tensor(X_train):将输入数据转换为适合计算的 Tensor 格式。
    • indices = knn_net(x, X_train):调用 KNN 网络进行预测,获取最近邻的索引。
    • topk_cls = [0] * len(indices.asnumpy()):初始化一个计数器列表,记录最近邻的类别。
    • for idx in indices.asnumpy()::遍历最近邻索引,更新计数器。
    • cls = np.argmax(topk_cls):找到出现次数最多的类别作为预测结果。
    • return cls:返回最终的预测类别。

6、模型预测

在验证集上验证 KNN 算法的有效性,取 (k = 5),验证精度接近 80%,说明 KNN 算法在该 3 分类任务上有效,能根据酒的 13 种属性判断出酒的品种。

acc = 0
# 初始化准确率计数器 acc 为 0knn_net = KnnNet(5)
# 创建一个 KNN 网络实例,指定最近邻数量 k 为 5for x, y in zip(X_test, Y_test):# 遍历测试集中的每个样本 x 和其对应的标签 ypred = knn(knn_net, x, X_train, Y_train)# 使用 knn 函数进行预测,得到预测结果 predacc += (pred == y)# 如果预测结果 pred 与真实标签 y 相同,则 acc 加 1print('label: %d, prediction: %s' % (y, pred))# 打印每个样本的真实标签和预测结果print('Validation accuracy is %f' % (acc / len(Y_test)))
# 计算并打印验证集的准确率,准确率为正确预测的数量除以测试样本总数

解析:

  1. 初始化准确率计数器
    • acc = 0:初始化一个变量 acc 作为正确预测的数量计数器,初始值为 0。
  2. 创建 KNN 网络实例
    • knn_net = KnnNet(5):实例化 KnnNet 类,设置最近邻数 k 为 5。
  3. 遍历测试集
    • for x, y in zip(X_test, Y_test)::将测试数据 X_test 和对应的标签 Y_test 进行配对,逐一遍历。
    • pred = knn(knn_net, x, X_train, Y_train):调用 knn 函数进行预测,传入当前测试样本 x 和训练数据,得到预测结果 pred
  4. 更新准确率计数器
    • acc += (pred == y):检查预测结果 pred 是否等于真实标签 y,如果相等则将 acc 加 1,表示正确预测。
  5. 打印每个样本的结果
    • print('label: %d, prediction: %s' % (y, pred)):输出每个测试样本的真实标签和预测结果,以便观察模型性能。
  6. 计算并打印验证集的准确率
    • print('Validation accuracy is %f' % (acc / len(Y_test))):计算验证集的准确率,将正确预测的数量 acc 除以测试样本总数 len(Y_test),并格式化输出。

实验小结

本实验使用 MindSpore 实现了 KNN 算法,用来解决 3 分类问题。取 wine 数据集上的 3 类样本,分为已知类别样本和待验证样本,从验证结果可以看出 KNN 算法在该任务上有效,能根据酒的 13 种属性判断出酒的品种。

整体代码

# K近邻算法实现红酒聚类# 本实验主要介绍使用MindSpore在部分wine数据集上进行KNN实验。## 1、实验目的
# - 了解KNN的基本概念;
# - 了解如何使用MindSpore进行KNN实验。## 2、K近邻算法原理介绍
# K近邻算法(K-Nearest-Neighbor, KNN)是一种用于分类和回归的非参数统计方法,最初由 Cover和Hart于1968年提出。
# 它正是基于以上思想:要确定一个样本的类别,可以计算它与所有训练样本的距离,然后找出和该样本最接近的k个样本,
# 统计出这些样本的类别并进行投票,票数最多的那个类就是分类的结果。# KNN的三个基本要素:
# - K值,一个样本的分类是由K个邻居的“多数表决”确定的。
# - 距离度量,反映了特征空间中两个样本间的相似度。
# - 分类决策规则,通常是多数表决,或者基于距离加权的多数表决。### 2.1 分类问题
# 预测算法(分类)的流程如下:
# (1)在训练样本集中找出距离待测样本x_test最近的k个样本,并保存至集合N中;
# (2)统计集合N中每一类样本的个数C_{i}, i=1,2,3,...,c;
# (3)最终的分类结果为argmaxC_{i} (最大的对应的C_{i})那个类。### 2.2 回归问题
# 假设离测试样本最近的k个训练样本的标签值为y_{i},则对样本的回归预测输出值为:
# $\hat y = (\sum_{i=1}^{n}{y_{i}})/k$### 2.3 距离的定义
# KNN算法的实现依赖于样本之间的距离,其中最常用的距离函数就是欧氏距离。## 3、实验环境
# 实验环境:
# - MindSpore 2.0;
# - 支持win_x86和Linux系统,CPU/GPU/Ascend均可运行。## 4、数据处理### 4.1 数据准备
# Wine数据集是模式识别最著名的数据集之一,分析了三种葡萄酒中每种所含13种成分的量。# 方式一,从Wine数据集官网下载[wine.data文件](http://archive.ics.uci.edu/ml/machine-learning-databases/wine/wine.data)。# 实验环境已经预装了mindspore==2.2.14。
!pip uninstall mindspore -y
!pip install -i https://pypi.mirrors.ustc.edu.cn/simple mindspore==2.2.14# 查看当前 mindspore 版本
!pip show mindspore
from download import download# 下载红酒数据集
url = "https://ascend-professional-construction-dataset.obs.cn-north-4.myhuaweicloud.com:443/MachineLearning/wine.zip"  
path = download(url, "./", kind="zip", replace=True)### 4.2 数据读取与处理
import os
import csv
import numpy as np
import matplotlib.pyplot as pltimport mindspore as ms
from mindspore import nn, opsms.set_context(device_target="CPU")# 读取Wine数据集`wine.data`
with open('wine.data') as csv_file:data = list(csv.reader(csv_file, delimiter=','))
print(data[56:62]+data[130:133])# 取三类样本(共178条),将数据集的13个属性作为自变量X。将数据集的3个类别作为因变量Y。
X = np.array([[float(x) for x in s[1:]] for s in data[:178]], np.float32)
Y = np.array([s[0] for s in data[:178]], np.int32)# 取样本的某两个属性进行2维可视化
attrs = ['Alcohol', 'Malic acid', 'Ash', 'Alcalinity of ash', 'Magnesium', 'Total phenols','Flavanoids', 'Nonflavanoid phenols', 'Proanthocyanins', 'Color intensity', 'Hue','OD280/OD315 of diluted wines', 'Proline']
plt.figure(figsize=(10, 8))
for i in range(0, 4):plt.subplot(2, 2, i+1)a1, a2 = 2 * i, 2 * i + 1plt.scatter(X[:59, a1], X[:59, a2], label='1')plt.scatter(X[59:130, a1], X[59:130, a2], label='2')plt.scatter(X[130:, a1], X[130:, a2], label='3')plt.xlabel(attrs[a1])plt.ylabel(attrs[a2])plt.legend()
plt.show()# 将数据集按128:50划分为训练集和验证集
train_idx = np.random.choice(178, 128, replace=False)
test_idx = np.array(list(set(range(178)) - set(train_idx)))
X_train, Y_train = X[train_idx], Y[train_idx]
X_test, Y_test = X[test_idx], Y[test_idx]## 5、模型构建
class KnnNet(nn.Cell):def __init__(self, k):super(KnnNet, self).__init__()self.k = kdef construct(self, x, X_train):# 平铺输入x以匹配X_train中的样本数x_tile = ops.tile(x, (128, 1))square_diff = ops.square(x_tile - X_train)square_dist = ops.sum(square_diff, 1)dist = ops.sqrt(square_dist)# -dist表示值越大,样本就越接近values, indices = ops.topk(-dist, self.k)return indicesdef knn(knn_net, x, X_train, Y_train):x, X_train = ms.Tensor(x), ms.Tensor(X_train)indices = knn_net(x, X_train)topk_cls = [0]*len(indices.asnumpy())for idx in indices.asnumpy():topk_cls[Y_train[idx]] += 1cls = np.argmax(topk_cls)return cls## 6、模型预测
acc = 0
knn_net = KnnNet(5)
for x, y in zip(X_test, Y_test):pred = knn(knn_net, x, X_train, Y_train)acc += (pred == y)print('label: %d, prediction: %s' % (y, pred))
print('Validation accuracy is %f' % (acc/len(Y_test)))## 实验小结
# 本实验使用MindSpore实现了KNN算法,用来解决3分类问题。

解析:

  1. 实验目的
    • 学习 KNN 的基本概念和使用 MindSpore 实现 KNN 的方法。
  2. KNN 原理
    • KNN 是一种基于距离的分类和回归算法,通过计算样本距离来判定样本的类别或输出值。
  3. 数据处理
    • 下载和读取 Wine 数据集,并将数据分为特征和标签(X 和 Y)。
    • 可视化数据集中的样本分布。
  4. 模型构建
    • 定义 KNN 网络类 KnnNet,实现距离计算和最近邻索引获取。
    • 定义 knn 函数进行预测,包括分类计数和返回最终的预测结果。
  5. 模型预测
    • 在验证集上测试模型的准确性,输出每个样本的真实标签和预测结果,最后计算整体准确率。
  6. 实验小结
    • 通过实验验证 KNN 算法在 Wine 数据集分类任务上的有效性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1486112.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

传神社区|数据集合集第7期|法律NLP数据集合集

自从ChatGPT等大型语言模型(Large Language Model, LLM)出现以来,其类通用人工智能(AGI)能力引发了自然语言处理(NLP)领域的新一轮研究和应用浪潮。尤其是ChatGLM、LLaMA等普通开发者都能运行的…

类和对象:完结

1.再深构造函数 • 之前我们实现构造函数时,初始化成员变量主要使⽤函数体内赋值,构造函数初始化还有⼀种⽅ 式,就是初始化列表,初始化列表的使⽤⽅式是以⼀个冒号开始,接着是⼀个以逗号分隔的数据成 员列表&#xf…

嵌入式C/C++、FreeRTOS、STM32F407VGT6和TCP:智能家居安防系统的全流程介绍(代码示例)

1. 项目概述 随着物联网技术的快速发展,智能家居安防系统越来越受到人们的重视。本文介绍了一种基于STM32单片机的嵌入式安防中控系统的设计与实现方案。该系统集成了多种传感器,实现了实时监控、报警和远程控制等功能,为用户提供了一个安全、可靠的家居安防解决方案。 1.1 系…

c++ 高精度加法(只支持正整数)

再给大家带来一篇高精度,不过这次是高精度加法!话不多说,开整! 声明 与之前那篇文章一样,如果看起来费劲可以结合总代码来看 定义 由于加法进位最多进1位,所以我们的结果ans[]的长度定义为两个加数中最…

【Linux】HTTP 协议

目录 1. URL2. HTTP 协议2.1. HTTP 请求2.2. HTTP 响应 1. URL URL 表示着是统一资源定位符(Uniform Resource Locator), 就是 web 地址,俗称“网址”; 每个有效的 URL 可以通过互联网访问唯一的资源, 是互联网上标准资源的地址; URL 的主要由四个部分组成: sche…

如何查看jvm资源占用情况

如何设置jar的内存 java -XX:MetaspaceSize256M -XX:MaxMetaspaceSize256M -XX:AlwaysPreTouch -XX:ReservedCodeCacheSize128m -XX:InitialCodeCacheSize128m -Xss512k -Xmx2g -Xms2g -XX:UseG1GC -XX:G1HeapRegionSize4M -jar your-application.jar以上配置为堆内存4G jar项…

广州邀请媒体宣传(附媒体名单)

传媒如春雨,润物细无声,大家好,我是51媒体网胡老师。 广州地区 媒体邀约: 记者现场采访,电视台到场报道,展览展会宣传,广交会企业宣传,工厂探班,媒体专访等。 适合广州…

自监督学习在言语障碍及老年语音识别中的应用

近几十年来针对正常言语的自动语音识别(ASR)技术取得了快速进展,但准确识别言语障碍(dysarthric)和老年言语仍然是一项极具挑战性的任务。言语障碍是一种由多种运动控制疾病引起的常见言语障碍类型,包括脑瘫…

android studio中svn的使用

第一步,建立一个项目。 第二步,share project。 第三步,选择存放的位置,然后添加提交信息,最后点击share。这样就可以在svn上面看到一个空的项目名称。 第四步,看到文件变成了绿色,点击commit图…

高翔【自动驾驶与机器人中的SLAM技术】学习笔记(三)基变换与坐标变换;微分方程;李群和李代数;雅可比矩阵

一、基变换与坐标变换 字小,事不小。 因为第一反应:坐标咋变,坐标轴就咋变呀。事实却与我们想象的相反。这俩互为逆矩阵。 第一次读没有读明白,后面到事上才明白。 起因是多传感器标定:多传感器,就代表了多个坐标系,多个基底。激光雷达和imu标定。这个标定程序,网上,…

Python机器学习入门:从理论到实践

文章目录 前言一、机器学习是什么?二、机器学习基本流程三、使用Python进行机器学习1.数据读取2.数据规范化3. 数据降维(主成分分析)4. 机器学习模型的选择5. 线性回归模型的实现6. 可视化结果 总结 前言 机器学习是人工智能的一个重要分支&…

pytorch 笔记:torch.optim.Adam

torch.optim.Adam 是一个实现 Adam 优化算法的类。Adam 是一个常用的梯度下降优化方法,特别适合处理大规模数据集和参数的深度学习模型 torch.optim.Adam(params, lr0.001, betas(0.9, 0.999), eps1e-08, weight_decay0, amsgradFalse, *, foreachNone, maximizeFa…

1小时上手Alibaba Sentinel流控安全组件

微服务的雪崩效应 假如我们开发了一套分布式应用系统,前端应用分别向A/H/I/P四个服务发起调用请求: 但随着时间推移,假如服务 I 因为优化问题,导致需要 20 秒才能返回响应,这就必然会导致20秒内该请求线程会一直处于阻…

【北京迅为】《i.MX8MM嵌入式Linux开发指南》-第三篇 嵌入式Linux驱动开发篇-第三十八章 驱动模块编译进内核

i.MX8MM处理器采用了先进的14LPCFinFET工艺,提供更快的速度和更高的电源效率;四核Cortex-A53,单核Cortex-M4,多达五个内核 ,主频高达1.8GHz,2G DDR4内存、8G EMMC存储。千兆工业级以太网、MIPI-DSI、USB HOST、WIFI/BT…

OpenAI从GPT-4V到GPT-4O,再到GPT-4OMini简介

OpenAI从GPT-4V到GPT-4O,再到GPT-4OMini简介 一、引言 在人工智能领域,OpenAI的GPT系列模型一直是自然语言处理的标杆。随着技术的不断进步,OpenAI推出了多个版本的GPT模型,包括视觉增强的GPT-4V(GPT-4 with Vision&…

Sokit(TCP/UDP调试工具)

下载:http://www.winwin7.com/soft/56522.html#xiazai Sokit中文版是一款免费开源的TCP / UDP 测试(调试)工具,它主要可以用于接收和发送TCP/UDP数据包,让你更深的了解网络状况,能够有效地接收、发送、转…

Adobe国际认证详解-从零开始学做视频剪辑

从零开始学做视频剪辑,是许多初学者面临的挑战。在这个数字媒体时代,视频剪辑已经成为一种重要的技能,无论是个人爱好还是职业发展,掌握视频剪辑技能都是非常有价值的。 视频剪辑,简称“剪辑”,是视频制作过…

创建vue3项目,以及使用示例

1.在根目录下cmd:vue create myobj(没有切换淘宝镜像记得切换,这样创建项目运行快) 2. 3.(按空格键选中,选好回撤就到下一步了) 4. 5. 6. 7. 8. 9. 10. 11. 12. 13.然后输入执行以下两步就已经运行项目了 以…

SpringMVC实现文件上传

导入文件上传相关依赖 <!--文件上传--> <dependency><groupId>commons-fileupload</groupId><artifactId>commons-fileupload</artifactId><version>1.3.1</version> </dependency> <dependency><groupId>…

鱼眼摄像头-opencv校准(基于棋盘+畸变表)

一&#xff1a;主要参数说明 1&#xff1a;内参矩阵K 是3*3的矩阵&#xff0c;其类似格式 Knp.array([ [389.2109574522624, 0.0, 630.2525667489842], [0.0, 388.505701978078, 360.7886749292513], [0.0, 0.0, 1.0]]) 2&#xff1a;畸变系数 针对鱼眼相机&#xff1a;…