import random
import csv  # csv 包可以读写 csv 文件

K = 5

# 数据读取
with open('iris.csv', 'r') as file:  # 打开 iris.csv 文件
    reader = csv.DictReader(file)  # 使用 csv 包的 DictReader() 方法读取文件内容,将 csv 文件转换为字典形式,每一行数据都是一个字典
    datas = [row for row in reader]  # 将每一行数据的字典存储到一个列表中

# 分组
random.shuffle(datas)  # 将数据集打乱顺序,相当于洗牌
n = len(datas) // 3  # 整除,避免小数的出现
# 2/3 是训练集 1/3 是测试集
test_set = datas[0:n]  # 取列表中的前 n 个作为测试集
train_set = datas[n:]  # 取列表中的第 n 个及以后的数据作为训练集   

# 定义一个函数,用于计算两个数据点之间的距离
def distance(d1, d2):
    res = 0  # 定义距离初始值为 0
    for key in ('sepal_length', 'sepal_width', 'petal_length', 'petal_width'):  # 循环遍历每一个要计算距离的属性
        res += (float(d1[key]) - float(d2[key])) ** 2  # 将每个属性的差值平方后累加,得到两个数据点之间的总距离
    return res ** 0.5  # 返回两个数据点之间的欧氏距离

# 定义一个函数,用于预测测试集中每一个数据点对应的分类结果
def knn(data):
    # KNN 算法过程
    # 1. 求距离
    # 2. 排序——升序
    # 3. 取前 K 个
    # 4. 加权平均

    # 1. 求距离
    res = [
        {'result': train['species'], 'distance': distance(data, train)}  # 计算测试集中每一个数据点与训练集中每一个数据点之间的距离,将结果存储为字典
        for train in train_set
    ]
    # 排序-升序
    res = sorted(res, key=lambda item: item['distance'])  # 将结果列表按照距离从小到大进行排序,使用 lambda 表达式指定按照字典中的 distance 键值进行排序
    # 取前 K 个
    resK = res[0:K]  # 取排序后的结果列表中前 K 个,即距离最近的 K 个数据点
    # 4. 加权平均(离的近的权重高,离得远的权重低)
    result = {'setosa': 0, 'versicolor': 0, 'virginica': 0}  # 定义一个字典,用于存储每个分类的权重
    # 算前 K 个的总距离
    sum_distance = 0  # 定义前 K 个数据点中的总距离
    for r in resK:  # 循环遍历前 K 个数据点
        sum_distance += r['distance']  # 将每个数据点的距离累加
    for r in resK:  # 循环遍历前 K 个数据点
        result[r['result']] += 1 - r['distance'] / sum_distance  # 计算每个分类的权重,离得近的数据点权重高,离得远的数据点权重低
    return (sorted(result, key=lambda x: result[x])[-1])  # 返回字典中最大 value 对应的 key,即预测的分类结果

# 对测试集中的每一个数据点进行分类预测,并计算准确率
correct = 0  # 定义初始正确分类的数据点数为 0
for test in test_set:  # 循环遍历测试集中的每一个数据点
    result = test['species']  # 获取该数据点的真实分类结果
    result_predict = knn(test)  # 对该数据点进行分类预测
    if result == result_predict:  # 如果预测分类结果与真实分类结果一致,则正确分类的数据点数加 1
        correct += 1

score = correct / len(test_set)  # 计算准确率
print('test Accuracy:{:.2f}'.format(score))  # 输出准确率,保留两位小数
KNN 鸢尾花分类:使用 Python 实现 K 近邻算法

原文地址: https://www.cveoy.top/t/topic/mzLs 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录