IT评测·应用市场-qidao123.com

标题: 昇思MindSpore 应用学习-K近邻算法实现红酒聚类-CSDN [打印本页]

作者: 嚴華    时间: 2024-7-24 07:39
标题: 昇思MindSpore 应用学习-K近邻算法实现红酒聚类-CSDN
K近邻算法实现红酒聚类-AI代码剖析

本实验重要介绍使用MindSpore在部分wine数据集上举行KNN实验。
1、实验目的


2、K近邻算法原理介绍

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

2.1 分类题目

推测算法(分类)的流程如下:
在上述实现过程中,k 的取值尤为紧张。它可以根据题目和数据特点来确定。在详细实现时,可以思量样本的权重,即每个样本有差异的投票权重,这种方法称为带权重的 k 近邻算法,它是一种变种的 k 近邻算法。
2.2 回归题目

假设离测试样本最近的 k 个训练样本的标签值为 (y_{i}),则对样本的回归推测输出值为:

即为全部邻居的标签均值。
带样本权重的回归推测函数为:

此中 (w_{i}) 为第个 (i) 样本的权重。
2.3 距离的界说

KNN算法的实现依靠于样本之间的距离,此中最常用的距离函数就是欧氏距离(欧几里得距离)。( \mathbb{R}^{n} )空间中的两点 (x) 和 (y),它们之间的欧氏距离界说为:

必要特别留意的是,使用欧氏距离时,应将特性向量的每个分量归一化,以减少因为特性值的标准范围差异所带来的干扰,否则数值小的特性分量会被数值大的特性分量沉没。
别的的距离计算方式还有 Mahalanobis 距离、Bhattacharyya 距离等。
3、实验环境

预备知识:

实验环境:

4、数据处理

4.1 数据准备

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

  1. %%capture captured_output
  2. # 实验环境已经预装了 mindspore==2.2.14,如需更换 mindspore 版本,可更改下面 mindspore 的版本号
  3. !pip uninstall mindspore -y  # 卸载当前的 mindspore 版本
  4. !pip install -i https://pypi.mirrors.ustc.edu.cn/simple mindspore==2.2.14  # 从指定的镜像源安装指定版本的 mindspore
  5. # 查看当前 mindspore 版本
  6. !pip show mindspore  # 显示当前安装的 mindspore 包的信息
  7. from download import download  # 导入 download 函数用于下载文件
  8. # 下载红酒数据集
  9. url = "https://ascend-professional-construction-dataset.obs.cn-north-4.myhuaweicloud.com:443/MachineLearning/wine.zip"  
  10. path = download(url, "./", kind="zip", replace=True)  # 下载红酒数据集压缩文件
复制代码
剖析:
4.2 数据读取与处理

导入 MindSpore 模块和辅助模块

在生成数据之前,导入必要的 Python 库。
目前使用到 os 库,为方便理解,其他必要的库,我们在详细使用到时再阐明。
详细的 MindSpore 的模块阐明,可以在 MindSpore API 页面中搜刮查询。
可以通过 context.set_context 来配置运行必要的信息,比方运行模式、后端信息、硬件等信息。
导入 context 模块,配置运行必要的信息。
  1. %matplotlib inline
  2. # 使得在 Jupyter Notebook 中绘制的图形被嵌入在输出单元格中,而不是在新窗口中显示
  3. import os  # 导入 os 模块,用于与操作系统进行交互
  4. import csv  # 导入 csv 模块,用于处理 CSV 文件
  5. import numpy as np  # 导入 numpy,用于科学计算和数组操作
  6. import matplotlib.pyplot as plt  # 导入 matplotlib 的 pyplot 模块,用于绘制图形
  7. import mindspore as ms  # 导入 mindspore 库
  8. from mindspore import nn, ops  # 从 mindspore 中导入 nn(神经网络模块)和 ops(操作模块)
  9. ms.set_context(device_target="CPU")  # 设置 MindSpore 的运行环境为 CPU
复制代码
剖析:
读取 Wine 数据集 wine.data,并查看部分数据。

  1. with open('wine.data') as csv_file:
  2.     # 以默认模式(只读)打开名为 'wine.data' 的 CSV 文件
  3.     data = list(csv.reader(csv_file, delimiter=','))  
  4.     # 使用 csv.reader 读取文件内容,并将其转换为列表
  5.     # delimiter=',' 指定 CSV 文件的分隔符为逗号
  6. print(data[56:62] + data[130:133])  
  7. # 打印数据列表中第 57 到 62 行(不包括第 62 行)以及第 131 到 133 行(不包括第 133 行)的内容
复制代码
剖析:
取三类样本(共 178 条),将数据集的 13 个属性作为自变量 (X)。将数据集的 3 个类别作为因变量 (Y)。

  1. X = np.array([[float(x) for x in s[1:]] for s in data[:178]], np.float32)
  2. # 创建一个二维 numpy 数组 X,包含前 178 行数据的特征部分
  3. # 使用列表推导式,将每行数据中的第 1 个元素到最后一个元素转换为 float 类型
  4. # np.float32 指定数组的数据类型为 32 位浮点数
  5. Y = np.array([s[0] for s in data[:178]], np.int32)
  6. # 创建一维 numpy 数组 Y,包含前 178 行数据的标签部分
  7. # 使用列表推导式,提取每行数据的第 0 个元素(标签)并转换为 int 类型
  8. # np.int32 指定数组的数据类型为 32 位整数
复制代码
剖析:
取样本的某两个属性举行 2 维可视化,可以看到在某两个属性上样本的分布情况以及可分性。

  1. attrs = ['Alcohol', 'Malic acid', 'Ash', 'Alcalinity of ash', 'Magnesium', 'Total phenols',
  2.          'Flavanoids', 'Nonflavanoid phenols', 'Proanthocyanins', 'Color intensity', 'Hue',
  3.          'OD280/OD315 of diluted wines', 'Proline']
  4. # 定义一个列表 attrs,包含不同的葡萄酒属性名称
  5. plt.figure(figsize=(10, 8))
  6. # 创建一个新的图形,设定图形的大小为 10x8 英寸
  7. for i in range(0, 4):
  8.     # 循环从 0 到 3,生成 4 个子图
  9.     plt.subplot(2, 2, i+1)
  10.     # 创建一个 2 行 2 列的子图,并选择第 i+1 个子图进行绘制
  11.    
  12.     a1, a2 = 2 * i, 2 * i + 1
  13.     # 计算当前子图中要绘制的两个属性的索引 a1 和 a2
  14.    
  15.     plt.scatter(X[:59, a1], X[:59, a2], label='1')
  16.     # 绘制前 59 个样本的属性 a1 和 a2 的散点图,标签为 '1'
  17.    
  18.     plt.scatter(X[59:130, a1], X[59:130, a2], label='2')
  19.     # 绘制第 60 到 130 个样本的属性 a1 和 a2 的散点图,标签为 '2'
  20.    
  21.     plt.scatter(X[130:, a1], X[130:, a2], label='3')
  22.     # 绘制第 131 个样本到最后的样本的属性 a1 和 a2 的散点图,标签为 '3'
  23.    
  24.     plt.xlabel(attrs[a1])
  25.     # 设置 x 轴标签为对应属性的名称
  26.    
  27.     plt.ylabel(attrs[a2])
  28.     # 设置 y 轴标签为对应属性的名称
  29.    
  30.     plt.legend()
  31.     # 添加图例,以显示不同类别的样本标签
  32. plt.show()
  33. # 显示绘制的图形
复制代码
剖析:
将数据集按 128:50 分别为训练集(已知类别样本)和验证集(待验证样本):

  1. train_idx = np.random.choice(178, 128, replace=False)
  2. # 随机选择 128 个不重复的索引从 0 到 177(共 178 个样本),用于训练集
  3. # np.random.choice 的参数为样本总数、选择的数量和是否允许重复选择
  4. test_idx = np.array(list(set(range(178)) - set(train_idx)))
  5. # 创建测试集的索引
  6. # set(range(178)) 生成一个包含 0 到 177 的集合
  7. # set(train_idx) 生成训练集索引的集合
  8. # 通过集合的差集操作得到未被选择的索引,转化为 NumPy 数组
  9. X_train, Y_train = X[train_idx], Y[train_idx]
  10. # 根据训练集索引 train_idx 提取训练数据 X 和标签 Y 的相应部分
  11. X_test, Y_test = X[test_idx], Y[test_idx]
  12. # 根据测试集索引 test_idx 提取测试数据 X 和标签 Y 的相应部分
复制代码
剖析:
5、模子构建–计算距离

利用 MindSpore 提供的 tile, square, ReduceSum, sqrt, TopK 等算子,通过矩阵运算的方式同时计算输入样本 x 和已明白分类的其他样本 X_train 的距离,并计算出 top k 近邻。
  1. class KnnNet(nn.Cell):
  2.     def __init__(self, k):
  3.         super(KnnNet, self).__init__()
  4.         self.k = k
  5.         # 初始化 KNN 网络,k 表示最近邻的数量
  6.     def construct(self, x, X_train):
  7.         # 平铺输入 x 以匹配 X_train 中的样本数
  8.         x_tile = ops.tile(x, (128, 1))
  9.         # 使用 ops.tile 将输入 x 复制 128 次,以便与训练样本 X_train 的形状匹配
  10.         
  11.         square_diff = ops.square(x_tile - X_train)
  12.         # 计算 x_tile 和 X_train 之间的平方差
  13.         
  14.         square_dist = ops.sum(square_diff, 1)
  15.         # 对每一行的平方差求和,以得到每个样本的平方距离
  16.         
  17.         dist = ops.sqrt(square_dist)
  18.         # 计算每个样本的欧几里得距离
  19.         
  20.         # -dist 表示值越大,样本就越接近
  21.         values, indices = ops.topk(-dist, self.k)
  22.         # 获取距离最近的 k 个样本的索引,-dist 确保距离越小的样本排在前面
  23.         
  24.         return indices
  25.         # 返回 k 个最近邻的索引
  26. def knn(knn_net, x, X_train, Y_train):
  27.     x, X_train = ms.Tensor(x), ms.Tensor(X_train)
  28.     # 将输入 x 和训练样本 X_train 转换为 Tensor 类型,适合后续计算
  29.    
  30.     indices = knn_net(x, X_train)
  31.     # 使用 knn_net 模型对输入 x 和训练样本 X_train 进行预测,获取最近邻的索引
  32.    
  33.     topk_cls = [0] * len(indices.asnumpy())
  34.     # 初始化一个计数器列表,用于记录每个类的出现次数
  35.     for idx in indices.asnumpy():
  36.         topk_cls[Y_train[idx]] += 1
  37.         # 根据最近邻的索引,增加对应类在 topk_cls 中的计数
  38.    
  39.     cls = np.argmax(topk_cls)
  40.     # 找到计数最多的类作为最终的预测结果
  41.    
  42.     return cls
  43.     # 返回预测的类标签
复制代码
剖析:
6、模子推测

在验证集上验证 KNN 算法的有效性,取 (k = 5),验证精度接近 80%,阐明 KNN 算法在该 3 分类任务上有效,能根据酒的 13 种属性判断出酒的品种。
  1. acc = 0
  2. # 初始化准确率计数器 acc 为 0
  3. knn_net = KnnNet(5)
  4. # 创建一个 KNN 网络实例,指定最近邻数量 k 为 5
  5. for x, y in zip(X_test, Y_test):
  6.     # 遍历测试集中的每个样本 x 和其对应的标签 y
  7.     pred = knn(knn_net, x, X_train, Y_train)
  8.     # 使用 knn 函数进行预测,得到预测结果 pred
  9.    
  10.     acc += (pred == y)
  11.     # 如果预测结果 pred 与真实标签 y 相同,则 acc 加 1
  12.    
  13.     print('label: %d, prediction: %s' % (y, pred))
  14.     # 打印每个样本的真实标签和预测结果
  15. print('Validation accuracy is %f' % (acc / len(Y_test)))
  16. # 计算并打印验证集的准确率,准确率为正确预测的数量除以测试样本总数
复制代码
剖析:
实验小结

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

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


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 IT评测·应用市场-qidao123.com (https://dis.qidao123.com/) Powered by Discuz! X3.4