昇思25天学习打卡营第24天|MindSpore红酒分类实验

一、简介:

K近邻算法实现红酒分类,本实验主要介绍使用MindSpore在部分wine数据集上进行KNN实验。 实现目的:①了解KNN的基本概念;②了解如何使用MindSpore进行KNN实验。

二、K近邻算法原理介绍:

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

  • K值,一个样本的分类是由K个邻居的"多数表决"确定的。K值越小,容易受噪声影响,反之,会使类别之间的界限变得模糊。

  • 距离度量,反映了特征空间中两个样本间的相似度,距离越小,越相似。常用的有Lp距离(p=2时,即为欧式距离)、曼哈顿距离、海明距离等。

  • 分类决策规则,通常是多数表决,或者基于距离加权的多数表决(权值与距离成反比)。

1、分类问题:

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

(1)在训练样本集中找出距离待测样本x_test最近的k个样本,并保存至集合N中;

(2)统计集合N中每一类样本的个数𝐶𝑖,𝑖=1,2,3,...,𝑐;

(3)最终的分类结果为argmax𝐶𝑖(最大的对应的𝐶𝑖)那个类。

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

2、回归问题:

假设离测试样本最近的k个训练样本的标签值为𝑦𝑖𝑦𝑖,则对样本的回归预测输出值为:

即为所有邻居的标签均值。

带样本权重的回归预测函数为:

其中𝑤𝑖𝑤𝑖为第个𝑖𝑖样本的权重。

3、距离定义:

KNN算法的实现依赖于样本之间的距离,其中最常用的距离函数就是欧氏距离(欧几里得距离)。𝑅𝑛空间中的两点𝑥𝑥和𝑦𝑦,它们之间的欧氏距离定义为:

需要特别注意的是,使用欧氏距离时,应将特征向量的每个分量归一化,以减少因为特征值的尺度范围不同所带来的干扰,否则数值小的特征分量会被数值大的特征分量淹没。

其它的距离计算方式还有Mahalanobis距离、Bhattacharyya距离等。

三、环境准备:

预备知识:

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

实验环境:

四、数据处理:

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,脯氨酸
python 复制代码
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)

2、数据的读取和处理:

导入MindSpore模块和辅助模块

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

python 复制代码
%matplotlib inline
import os
import csv
import numpy as np
import matplotlib.pyplot as plt

import mindspore as ms
from mindspore import nn, ops

ms.set_context(device_target="CPU")

读取Wine数据集wine.data,并查看部分数据:

python 复制代码
with open('wine.data') as csv_file:
    data = list(csv.reader(csv_file, delimiter=','))
print(data[56:62]+data[130:133])

取三类样本(共178条),将数据集的13个属性作为自变量𝑋𝑋。将数据集的3个类别作为因变量𝑌:

python 复制代码
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维可视化,可以看到在某两个属性上样本的分布情况以及可分性:

python 复制代码
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 + 1
    plt.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划分为训练集(已知类别样本)和验证集(待验证样本):

python 复制代码
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]

五、模型构建------计算距离:

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

python 复制代码
class KnnNet(nn.Cell):
    def __init__(self, k):
        super(KnnNet, self).__init__()
        self.k = k

    def 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 indices

def 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]] += 1
    cls = np.argmax(topk_cls)
    return cls

六、模型预测:

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

python 复制代码
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)))
相关推荐
学步_技术2 小时前
人工智能深度学习系列—探索余弦相似度损失:深度学习中的相似性度量神器
人工智能·深度学习·机器学习·分类·自动驾驶
逐梦苍穹2 小时前
【卷积神经网络】基于CIFAR10数据集实现图像分类【构建、训练、预测】
人工智能·分类·cnn
Python大数据分析@4 小时前
吴恩达:如何系统学习机器学习?
人工智能·学习·机器学习
Python_trys4 小时前
Python爬虫入门实战(详细步骤)
开发语言·爬虫·python·学习·pycharm·python基础·编程语言
努力学习的小趴菜。4 小时前
函数的学习(三)
学习·算法
1900_5 小时前
【QT学习】自定义标题栏
数据库·qt·学习
叫我:松哥5 小时前
【优秀python案例】基于python爬虫的深圳房价数据分析与可视化实现
爬虫·python·信息可视化·数据挖掘·数据分析·数据可视化
为更好遇见6 小时前
C:关于static 和 extern 关键字的介绍-学习笔记
c语言·开发语言·笔记·学习·知识点
夏季疯6 小时前
学习笔记 韩顺平 零基础30天学会Java(2024.8.6)
java·笔记·学习
lovemelater6187 小时前
C语言练习--给定两个数 ,取最大公约数
c语言·开发语言·学习