K-NN算法实操及介绍

一.KNN算法介绍

1.1简要介绍

模式识别领域中,最近邻居法KNN算法,又译K-近邻算法)是一种用于分类回归非参数统计方法[1],由美国统计学家伊芙琳·费克斯小约瑟夫·霍奇斯于1951年首次提出,后来由托马斯·寇弗扩展。在这两种情况下,输入包含特征空间中的k个最接近的训练样本。

  • k-NN分类中,输出是一个分类族群。一个对象的分类是由其邻居的“多数表决”确定的,k个最近邻居(k为正整数,通常较小)中最常见的分类决定了赋予该对象的类别。若k = 1,则该对象的类别直接由最近的一个节点赋予。
  • k-NN回归中,输出是该对象的属性值。该值是其k个最近邻居的值的平均值。

最近邻居法采用向量空间模型来分类,概念为相同类别的案例,彼此的相似度高,而可以借由计算与已知类别案例之相似度,来评估未知类别案例可能的分类。

以上部分来自维基百科,大致意思就是根据已有数据的标签进行新数据标签的预测,也就是说,通过一个人身边高收入者的数量判断这个人是不是高收入者,一个人身边的高收入朋友越多,这个人就越有可能是高收入者。通过这个思路,通过了解这个人身边富人朋友的数量是否多到一个阈值k,我们就可以预测其是否为富人。而这个k值,就是该算法的一个重点。

1.2 算法流程介绍

1.2.1数据收集

要进行这个算法的实现,首先需要一定的数据的训练和测试以确定预测正确率最高的k值,所以第一步时进行数据的收集,这一步可以通过上网寻找或者通过其他大佬的博客进行下载,或者通过调取python的sklearn库中的内置数据集进行实现

1.2.2数据处理

这一步需要对已有的数据进行结构化处理,即对单个样本拥有的标签进行格式化规范化,形成表格式的数据集。

再之后,还需要对数据进行归一化或者赋予比重。因为部分样本不同标签下的数据完全不成比例,在这种情况下如果完全不对其进行处理,那么将会出现某个标签在进行判断时判断权重很小甚至完全被忽略的情况。

进行归一化的公式为

即以该值减去该标签下的最小值除以标签下最大值和最小值的差,将数据进行该处理后可保证哥哥标签下的范围为[0,1]。

1.2.3 算法实施

该算法需要计算在n维空间中,预测点与其他已知样本点的距离,然后选取与之最近的k个点,然后在k个点中选取出现频率最高的属性,并将之作为预测结果。

此处的距离可采用欧几里得距离,公式为

其中n值为标签数量,i表示第i个标签,x和y分别为预测点和已知样本点。

二. 实操

2.1数据准备

本次使用的数据为橙子苹果梨的判断,每个样本点有两个标签,分别为直径和高度,范围设置如下表格(范围为帖主本人瞎编,数据集全部为随机数生成,如有雷同纯属巧合)。

数据文本示例如下图

此为一部分内容,本次实践设置了200个数据样本作为训练集。

2.2 数据导入

首先导入保存于.txt中的数据,对每行的数据进行分割,并将前两项数据加入至data_set中,标签存入lables中。

def createDataSet(filename):
    data_set = []  # 保存数据
    data_labels = []  # 保存标签
    with open(filename, 'r', encoding='utf-8') as file:
        for line in file:
            d, h, name = line.strip().split(',')
            data_set.append([int(d), int(h)])
            data_labels.append(name)
    return np.array(data_set), data_labels

2.3 数据归一化

在这段函数中通过numpy库的内置函数找到训练集中的最大最小值并依照上面给出的公式进行处理,最后返回处理过的数据。

def normalize(dataset, mydata):
    mindata = np.min(dataset, axis=0)  # axis=0按行进行比较
    maxdata = np.max(dataset, axis=0)
    my_data = (mydata - mindata) / (maxdata - mindata)
    data_set = (dataset - mindata) / (maxdata - mindata)
    return data_set, my_data

2.4 knn算法主体部分

在这段函数中,通过.shape[0]获取data_set的行数,再通过numpy库中的tile函数,根据mydata生成一个与data_set行数相同的矩阵并与data_set进行计算,获取平方后再使用.sum方法,获取平方后的各个值的和,再依据和的大小按从小到大的顺序进行排列。

完成排列后的列表中,依次选取k个值并获取其数目最大的标签并且返回。

def knn(data_set, data_labels, k, mydata):
    data_size = data_set.shape[0]
    temp_distance = (np.tile(mydata, (data_size, 1)) - data_set) ** 2
    distances = temp_distance.sum(axis=1) ** 0.5
    sorted_distances_indices = distances.argsort()
    data_dict = {}
    for i in range(k):
        data_label = data_labels[sorted_distances_indices[i]]
        data_dict[data_label] = data_dict.get(data_label, 0) + 1
    sort_dict = sorted(data_dict.items(), key=operator.itemgetter(1), reverse=True)
    return sort_dict[0][0]

2.5 测试集的验证及k值的选取

knn算法的一个重点就是k值的选取,这个值的选取应该通过验证来选取,因此,在这次实操中加载了一个含有100组数据的测试集,依次测试k的值不同时得到的正确率有多高,最后打印折线图并且返回最佳的k

def find_k():
    # 获取数据集以及标签
    data_set, data_labels = createDataSet("fruit_data.txt")
    test_set, test_labels = createDataSet("fruit_2.txt")

    # 初始化准确率列表
    accuracy_list = []

    # 遍历 k 值从 1 到 30
    for k in range(1, 31):
        correct_count = 0
        # 遍历测试集
        for i in range(len(test_set)):
            # 进行归一化
            set_data, test_data = normalize(data_set, test_set[i])
            # 使用 KNN 算法进行预测
            predicted_label = knn(set_data, data_labels, k, test_data)
            # 比较预测结果与实际标签
            if predicted_label == test_labels[i]:
                correct_count += 1
        # 计算准确率
        accuracy = correct_count / len(test_set)
        accuracy_list.append(accuracy)

    # 绘制准确率随 k 值变化的折线图
    plt.plot(range(1, 31), accuracy_list, marker='o', linestyle='-', color='blue', label='Accuracy')
    plt.xlabel('k')
    plt.ylabel("accuracy")
    plt.title("result")
    plt.legend()
    plt.grid(True)
    plt.show()

    # 找出最优的 k 值
    max_accuracy = max(accuracy_list)
    optimal_k = accuracy_list.index(max_accuracy) + 1
    print(f"Best value of k: {optimal_k} with an accuracy of {max_accuracy:.2f}")
    return optimal_k

最后得到的折线图和结果如下

2.6主函数

依据find_k函数找到k值,再根据读入的数据进行判断即可

def main():
    # 获取数据集以及标签
    data_set, data_labels = createDataSet("fruit_data.txt")
    my_test = [int(input("请输入待分类水果的直径:\n")), int(input("请输入待分类水果的高:\n"))]
    # 进行归一化
    k = find_k()
    set_data, test_data = normalize(data_set, my_test)
    print('输入的数据所对应的水果类别是:{}'.format(knn(set_data, data_labels, k, test_data)))

结果图如下

三.总结

本次实践对knn算法有了一定的理解

首先其核心内容易理解,思想较为简单,但由于每次运算都需要跑完全部的数据集,因而计算量较大,较为花费时间。而当k值选取有误时容易出现过拟合现象。

作为本学期的第一个实验,完整顺下来之后对于python的函数等内容有了一定的了解,但在编码能力上还有欠缺,多多学习吧

  • 28
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Hadoop K-NN算法是一种基于分布式计算框架的机器学习算法,它通过将数据集拆分成多个小数据集,并通过多个节点进行并行计算,以提高算法的处理效率和精度。在学习和实践Hadoop K-NN算法的过程中,我有以下几点感悟: 首先,Hadoop K-NN算法的分布式计算模式和MapReduce编程模型是算法的核心。通过将数据集拆分成多个小数据集,然后在多个节点上进行并行计算,可以大大提高算法的处理效率和精度。同时,MapReduce编程模型提供了一种简单易用的编程方式,可以让开发者快速构建分布式计算应用。 其次,Hadoop K-NN算法的实现需要考虑数据的分布和负载均衡问题。由于数据集被拆分成多个小数据集,数据的分布情况会影响到算法的处理效率和精度。因此,在实现Hadoop K-NN算法时,需要考虑数据的分布情况和负载均衡问题,以保证算法的效率和精度。 最后,Hadoop K-NN算法的应用场景非常广泛。例如,它可以应用在电商网站中的商品推荐、医疗领域中的疾病诊断、金融领域中的风险评估等方面。通过对数据进行分类、聚类和预测等分析,可以帮助企业和个人更好地了解数据,从而作出更加准确的决策。 总之,Hadoop K-NN算法是一种非常有意义的机器学习算法,它可以帮助我们更好地理解大数据,从而作出更加准确的决策。在学习和实践Hadoop K-NN算法的过程中,我们需要注重算法的理论和实践结合,以便更好地理解算法的核心思想和应用场景。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值