机器学习实验报告- KNN算法

目录

一、算法介绍

1.1算法背景

1.2基本假设

1.3算法原理阐述

1.4算法关键点

二、数据集描述

2.1数据集介绍

2.2 数据处理

三、算法实现

3.1代码实现(python)

3.2代码复现结果

四、实验讨论

4.1关于KNN算法优缺点的讨论

4.2关于k值对实验结果(准确率)影响的讨论

4.3关于测试集数目对KNN算法准确率的讨论

五、实验总结


一、算法介绍

1.1算法背景

K最近邻(KNN)算法是一种基本的模式识别和机器学习算法,发展于20世纪60年代。它是一种基于“类的相似性”进行分类的无参数算法,在许多实际应用中取得了良好的效果。在分类问题中,KNN算法将一个测试样本所在区域内训练样本的多数类作为该测试样本的预测类别;在回归问题中,KNN算法利用k个最近邻居的平均值或加权平均值预测连续变量。

1.2基本假设

KNN算法的基本假设是相似的样本具有相似的类别。这意味着,如果两个样本在特征空间中越相似,它们所属的类别也越相似。因此,KNN算法认为,未知样本所属的类别应该与其最近邻居的类别相同或相似。

1.3算法原理阐述

当我们要对一个未知样本进行分类时,K最近邻(KNN)算法会找出与该未知样本最相似的K个已知样本。这里的相似性是通过计算它们在特征空间中的距离来衡量的。然后,KNN算法会查看这K个最近邻居中哪个类别出现得最多,将该类别作为未知样本的预测类别。

我认为我们可以将KNN算法类比为选择身边K个朋友的方式。如果想知道某家餐厅的好坏,但你没有去过。可以问询身边的K个朋友他们对这家餐厅的评价。然后,你会选择其中出现最多次的评价作为你对这家餐厅的评价,认为它的好坏程度和多数朋友的评价相似。

简单的说,KNN算法的原理就是根据已知样本的特征和类别,在特征空间中找出与未知样本最相似的K个样本,通过多数投票的方式确定未知样本所属的类别。这种算法简单直观,可以应用于分类和回归问题,并且不需要事先训练模型,被广泛应用于各种领域的机器学习任务中。

1.4算法关键点

1.选择合适的K值,以避免过拟合或欠拟合。

KNN中的k是一个超参数,需要我们进行指定,一般情况下这个k和数据有很大关系,都是通过网格搜索、交叉验证(将样本数据按照一定比例,拆分出训练用的数据和验证用的数据,比如6:4拆分出部分训练数据和验证数据)进行选择,从选取一个较小的k值开始,不断增加k的值,然后计算验证集合的方差,最终找到一个比较合适的K值。

但是建议使用交叉验证的时候,k∈[2,20],使用交叉验证得到一个很好的k值。需注意最好k的取值为奇数,防止出现平票而无法分类的情况。

如下图

假设实线圈为k=3,圈内红色点更多,因此将新来的绿点归为红色点一类;    假设虚线圈为k=5,圈内则是蓝色点更多,便将新来的绿点归为蓝色点一类。

               

k值还可以表示我们的模型复杂度,k值越小,意味着模型复杂度变大,更容易过拟合(用极少数的样例来绝对这个预测的结果,很容易产生偏见,这就是过拟合)。k值越大,学习的估计误差越小,但是学习的近似误差就会增大,容易造成欠拟合。

2.选择合适的距离度量方法,以确保准确地衡量样本之间的相似性。

以下列出三种常用的距离度量方法,并解释欧式距离为KNN算法最合适的距离度量算法的原因

I  欧式距离(Euclidean Distance)(2-范数)

欧式距离是最常用的距离度量方法,它计算样本之间的几何距离。在二维空间中,欧式距离计算公式为:

                

欧式距离对于连续特征适用,在高维空间中具有较好的表现。

II   曼哈顿距离(Manhattan Distance)(1-范数)

曼哈顿距离是计算样本之间城市街区距离(也称为L1距离)的方法。在二维空间中,曼哈顿距离计算公式为:

               

曼哈顿距离对于稀疏数据和离散特征适用,在某些应用场景下比欧氏距离更合适。

III  切比雪夫距离(Chebyshev Distance):

切比雪夫距离是计算样本之间的最大坐标差的方法。在二维空间中,切比雪夫距离计算公式为:

切比雪夫距离对于异常值不敏感,在离群值较多的情况下可以使用。

在K最近邻(KNN)算法中,欧式距离常被用作KNN算法的距离度量方法,这是因为以下几个原因:

I 几何直观性:欧式距离对于连续特征的数据具有直观的几何解释。它衡量了样本在特征空间中的直线距离,更接近的样本在空间中更接近。

II 特征权重一致性:欧式距离在对各个特征值赋予相同权重时表现有效。KNN算法将每个特征都视为同等重要,欧式距离能够满足这个要求。

III 高效性:计算两个样本之间的欧式距离是一种简单而高效的计算方式。通过向量操作,可以快速地计算出所有训练样本与测试样本之间的欧式距离。

3.选取合理的分类决策规则

分类决策规则一般使用多数表决法。即如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别。

二、数据集描述

为了进一步掌握KNN算法,尝试使用KNN算法改进约会网站的配对效果。

2.1数据集介绍

这个数据集是由1000条数据组成,其中每条数据都有三个数值型特征和一个类别标签,具体信息如下:

(1)每年获得的飞行常客里程数(Continuous):

这个数值型特征表示一个人每年在飞机上旅行的里程数,即获得的飞行常客里程数。该特征为连续型变量。

(2)玩视频游戏所耗时间百分比(Continuous):

这个数值型特征表示一个人用于玩视频游戏的时间占其可用时间的百分比。该特征为连续型变量。

(3)每周消费的冰淇淋公升数(Continuous):

这个数值型特征表示一个人每周消费的冰淇淋的公升数。该特征为连续型变量。

(4)类别标签(Categorical):

类别标签表示一个人的魅力水平,共分为3个类别,分别是:

1代表“不喜欢的人”:表示该人的社交能力较差。

2代表“魅力一般的人”:表示该人有一定的社交魅力。

3代表“极具魅力的人”:表示该人在社交方面非常有魅力。

数据集格式如下,仅呈现部分数据

2.2 数据处理

(1)数据清洗:

数据清洗是指检查和处理数据集中的错误、缺失值和异常值等问题。常见的数据清洗方法包括:处理缺失值、处理异常值

(2)特征选择:

特征选择是指从原始数据集中选择最具有预测能力的特征子集。常用的特征选择方法包括:

过滤式选择、包装式选择、嵌入式选择

(3)归一化:

归一化是指将不同范围的特征值映射到统一的区间,以消除特征之间的量纲差异。

常见的归一化方法有:

最小-最大归一化(Min-Max Scaling)、标准化(Standardization)。

此次实验,在完成前期对数据的清洗和特征选择后,测试代码中的auto_norm(dataSet)函数实现了对数据的归一化处理。相关代码如下图所示:

通过对数据集进行归一化处理,可使得数据集中的特征值都在0到1之间。这可以消除不同特征之间的量纲差异,使得它们具有相同的重要性。

在对数据进行预处理后,得到有效的1000条数据,并依据其利用KNN算法进行实例测试。​​​​​​​

三、算法实现

3.1代码实现(python)

完整代码由四个功能函数file_matrix()、auto_norm()、KNN()、datingClassTest()组成,最后进行调用。完整代码来自网络。为更好的理解KNN算法原理,本次实验对其进行复现,分析代码功能。

import numpy as np
import pandas as pd
import operator


def load_dataset(filename):
    """
    加载数据集并进行预处理
    :param filename: 数据集文件名
    :return: 特征矩阵和标签向量
    """
    data = pd.read_csv(filename, sep='\t').values
    features = data[:, 0:3]
    labels = data[:, -1]
    return features, labels


def normalize_dataset(dataset):
    """
    数据集归一化
    :param dataset: 特征矩阵
    :return: 归一化后的特征矩阵,范围和最小值
    """
    min_vals = dataset.min(0)
    max_vals = dataset.max(0)
    ranges = max_vals - min_vals
    norm_dataset = (dataset - min_vals) / ranges
    return norm_dataset, ranges, min_vals


def kNN(inX, dataset, labels, k):
    """
    kNN算法
    :param inX: 需要分类的数据
    :param dataset: 样本数据集
    :param labels: 样本数据的标签
    :param k: 需要取出的前k个
    :return: 最有可能的分类
    """
    dataset_size = dataset.shape[0]
    diff_mat = np.tile(inX, (dataset_size, 1)) - dataset
    sq_diff_mat = diff_mat ** 2
    sq_distances = sq_diff_mat.sum(axis=1)
    distances = sq_distances ** 0.5
    sorted_dist_indices = distances.argsort()
    class_count = {}
    for i in range(k):
        vote_i_label = labels[sorted_dist_indices[i]]
        class_count[vote_i_label] = class_count.get(vote_i_label, 0) + 1
    sorted_class_count = sorted(class_count.items(), key=operator.itemgetter(1), reverse=True)
    return sorted_class_count[0][0]


def dating_class_test():
    ho_ratio = 0.10  # 用于测试的数据比例
    dataset, labels = load_dataset('datingTestSet2.txt')  # 加载数据集
    norm_dataset, ranges, min_vals = normalize_dataset(dataset)  # 归一化数据集
    m = norm_dataset.shape[0]
    num_test_vecs = int(m * ho_ratio)
    error_count = 0.0
    for i in range(num_test_vecs):
        classifier_result = kNN(norm_dataset[i, :], norm_dataset[num_test_vecs:m, :], labels[num_test_vecs:m], 4)
        print("预测结果:%d,真实结果:%d" % (classifier_result, labels[i]))
        if classifier_result != labels[i]:
            error_count += 1.0
    print("测试集大小:%d,分类错误个数:%d" % (num_test_vecs, error_count))
    print("分类错误率:%.2f%%" % (error_count / float(num_test_vecs) * 100))
    accuracy = (1 - error_count / float(num_test_vecs)) * 100
    print("准确率:%.2f%%" % accuracy)


if __name__ == '__main__':
    dating_class_test()

代码功能简要分析:

(1)file_matrix(filename)函数

该函数的目的是读取源数据文件并将其转换为规整好的数据矩阵和类标签向量。

(2)auto_norm(dataSet)函数

该函数的目的是对数据集进行归一化处理,使得数据集中的特征值都在0到1之间。这可以消除不同特征之间的量纲差异,使得它们具有相同的重要性。

(3)kNN(inX,dataSet,lables,k)函数

此函数实现了k最近邻(kNN)算法。kNN算法用于分类问题,通过计算待分类数据点与已知类别数据点之间的距离,并选择距离最近的k个邻居来确定待分类数据点的类别。即根据样本数据集和标签,在给定一个待分类数据点时,利用k最近邻算法预测其所属的类别。

(4)datingClassTest()函数

此函数实现了一个名为datingClassTest的函数。该函数用于测试kNN算法在约会数据集上的分类准确率。该函数通过将数据集分为训练集和测试集,使用kNN算法对测试集中的样本进行分类预测,并计算分类错误率和分类准确率。

3.2代码复现结果

(1)测试集为100(下图仅截取了部分展示),k=4

测试的结果是错误率为4.00%,在接受范围之内。

(2)改变测试集大小,hoRatio取0.20,即测试集大小为200,k=4

测试的结果是准确率为92.50%

四、实验讨论

4.1关于KNN算法优缺点的讨论

(1)优点

I   KNN算法是一种非参数方法,不需要对数据的分布进行假设,因此可以适用于各种数据类型和分布情况。

II   KNN算法简单易懂,容易实现,在处理小规模数据时表现良好。

III  KNN算法可以用于分类和回归问题,并可以处理多分类和回归问题。

IV  KNN算法对噪声数据具有高度的鲁棒性,因为它可以排除异常值的影响。

(2)缺点

I   KNN算法需要保存全部的训练数据,因此在处理大规模数据时,存储和计算复杂度都会较高。

II  KNN算法对输入数据的维度非常敏感,如果特征空间的维度很高,则距离计算会变得非常困难,同时分类器的效果会受到影响。

III  KNN算法的预测速度较慢,因为需要计算每个测试样本与所有训练样本之间的距离,时间复杂度为O(Nd),其中N为训练样本数,d为特征维数。

IV  KNN算法对样本不平衡问题敏感。如果某个类别的样本数量远远超过其他类别,则会导致分类器准确率降低。

4.2关于k值对实验结果(准确率)影响的讨论

为了测试k值对KNN算法准确率的影响,分别从1到10取k进行准确率的计算,利用python绘制出了如下折线图

观察折线图,可得到如下结论:

I 随着k值的增大,分类错误率逐渐减小,并趋于稳定,但并不是k越大越好,因为如果k值过大,会使模型变得过于简单,无法捕捉到数据的复杂规律,导致误差增大。

II 在这个数据集上,选择k=4或7时可以得到最佳的分类准确率。

4.3关于测试集数目对KNN算法准确率的讨论

通过在原有代码的基础上进行修改,测试集大小将在10到500的范围内进行遍历,并绘制了测试集大小对准确率的影响图表,如下所示:

通过观察测试结果和准确率与测试集大小的关系图表,可以得出在200-300左右的测试集大小范围内,KNN算法能够获得较高的准确率。超过这个范围后,增加测试集的大小对准确率的提升较为有限。因为数据集的特性和分布导致了准确率的限制。

五、实验总结

K最近邻算法(KNN)是一种监督学习算法,属于非参数学习方法,其核心思想是如果一个样本在特征空间中的k个最临近的样本中的大多数属于某一个类别,则该样本也属于这个类别。

在本次实验中,我复现了K最近邻(KNN)算法,并对代码进行了分析和讨论。KNN算法是一种简单易懂且容易实现的分类算法,适用于各种数据类型和分布情况,并具有较高的鲁棒性。但是,KNN算法在处理大规模数据时存储和计算复杂度较高,对输入数据的维度敏感,并且预测速度较慢。在实验中,我们还讨论了K值对准确率的影响以及测试集大小对KNN算法准确率的影响。根据实验结果,选择合适的K值和测试集大小可以获得较高的准确率。

总的来说,KNN算法是一个简单但有效的分类算法,能够在很多问题中得到应用。通过本次实验,我对KNN算法有了更深入的理解,对其在实际应用中的优缺点有了更清晰的认识;除此之外,我对机器学习这门学科也有了更深厚的兴趣,因为不再是课堂上复杂深奥的机器学习理论。通过对代码的复现,算法也变得有趣起来。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

HTML JavaScript 数字变化特效

效果 案例一&#xff1a;上下滚动 案例二&#xff1a;本身变化 代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta http-equiv"X-UA-Compatible" content"IEedge" /><met…

【Python代码】以线性模型为例,详解深度学习算法流程,包括数据生成、定义模型、损失函数、优化算法和训练

**使用带有噪声的线性模型构造数据集&#xff0c;并根据有限的数据恢复该线性模型的参数。**其中包括数据集构造、模型参数初始化、损失函数定义、定义优化算法和训练等过程。是大多数算法实现过程的一个缩影&#xff0c;理解此过程有助于在开发或改进算法时更深刻了解其算法的…

【Oracle】收集Oracle数据库内存相关的信息

文章目录 【Oracle】收集Oracle数据库内存相关的信息收集Oracle数据库内存命令例各命令的解释输出结果例参考 【声明】文章仅供学习交流&#xff0c;观点代表个人&#xff0c;与任何公司无关。 编辑|SQL和数据库技术(ID:SQLplusDB) 【Oracle】收集Oracle数据库内存相关的信息 …

受电端协议芯片是如何让Type-C接口设备实现快充?

随着科技的不断进步&#xff0c;USB Type-C接口在电子产品中越来越普及。而在这个接口中&#xff0c;Type-c受电端协议芯片起着至关重要的作用。那么&#xff0c;什么是Type-c受电端协议芯片&#xff1f;它又是如何工作的呢&#xff1f;本文将为您揭开Type-c受电端协议芯片的神…

pip安装之后还是无法使用问题处理

最近由于需要使用到Python 相关功能&#xff0c; 记录下一些入门小技巧 1 python 下载安装 在window10 环境下载免安装版本&#xff0c; 并解压 安装包下载地址&#xff1a; https://www.python.org/ftp/python/3.12.1/python-3.12.1-embed-amd64.zip 2. 安装pip, 由于是内嵌…

QQ数据包解密

Windows版qq数据包格式&#xff1a; android版qq数据包格式&#xff1a; 密钥&#xff1a;16个0 算法&#xff1a;tea_crypt算法 pc版qq 0825数据包解密源码&#xff1a; #include "qq.h" #include "qqcrypt.h" #include <WinSock2.h> #include…

【php】php去除excel导入时的空格

背景 PHPExcel_1.8.0导入excel&#xff0c;遇到trim无法处理的空格。 解决方案 $excelVal preg_replace(“/(\s| | |\xc2\xa0)/”, ‘’, $excelVal); 完整代码 thinkphp5代码 function readExcel($file) {require_once EXTEND_PATH . PHPExcel_1.8.0/Classes/PHPExcel.p…

汽车制动器行业调查:市场将继续呈现稳中向好发展态势

汽车制动器是汽车的制动装置&#xff0c;汽车所用的制动器几乎都是摩擦式的&#xff0c;可分为鼓式和盘式两大类。鼓式制动器摩擦副中的旋转元件为制动鼓&#xff0c;其工作表面为圆柱面;盘式制动器的旋转元件则为旋转的制动盘&#xff0c;以端面为工作表面。 目前市场上主流的…

WebSocket-黑马好客租房

文章目录 网站中的消息功能如何实现&#xff1f;什么是WebSocket&#xff1f;http与websocket的区别httpwebsocket 浏览器支持情况快速入门创建itcast-websocket工程websocket的相关注解说明实现websocket服务测试编写js客户端 SpringBoot整合WebSocket导入依赖编写WebSocketHa…

全网最高质量文章:重新学习Java中的HashMap!!

前言 本文参考了美团技术团队的科普文章Java 8系列之重新认识HashMap - 知乎 (zhihu.com) 这篇文章的质量极其高&#xff0c;高到很有可能是全网介绍HashMap这个知识点最优秀的文章&#xff0c;没有之一&#xff01;&#xff01;&#xff01;因此&#xff0c;我决定在我自己的…

智能安全帽定制_基于联发科MT6762平台的智能安全帽方案

智能安全帽是一种具备多项功能的高科技产品&#xff0c;其功能集成了视频通话监控、高清图像采集、无线数据传输、语音广播对讲、定位轨迹回放、静默报警、危险救援报警、脱帽报警、碰撞报警、近电报警以及智能调度系统等&#xff0c;同时还支持多功能模块的自由添加&#xff0…

设计模式-责任链

之前写代码的时候看到过有审批场景使用了责任链&#xff0c;当时大概看了一下代码实现&#xff0c;今天终于有时间抽出来梳理一下&#xff0c;下面是本文的大纲&#xff1a; 使用场景 审批场景的普遍应用 实际案例&#xff1a;HttpClient中的责任链模式 责任链模式在事件处理、…

RocketMQ学习总结

一、架构 1、NameServer&#xff1a;注册中心。Broker信息注册到NameServer&#xff1b;producer/consumer根据某个topic通过NameServer获取对应broker的路由信息 &#xff1b; 2、Broker&#xff1a;负责存储、拉取、转发消息&#xff1b; 3、Producer&#xff1a;消息生产者…

creature_summon_groups

字段介绍 这个表保存了关于临时召唤生物的数据 creature_summon_groups summonerId&#xff08;召唤者ID&#xff09; summonerType 0 时&#xff0c;此处为 creature 的 entrysummonerType 1 时&#xff0c;此处为 gameobject 的 entrysummonerType 2 时&#xff0c;此处…

从设备维修到机器视觉:我的职业发展之路

大家好&#xff01;我是学员向工&#xff0c;今天很高兴有机会与大家分享我的职业经历。十年前&#xff0c;18岁中专毕业的那年&#xff0c;我踏入社会&#xff0c;至今已经过去了十年。一开始&#xff0c;我主要从事设备的维修、装配、钳工和电工等多岗位工作。 然而&#xff…

大数据关联规则挖掘:Apriori算法的深度探讨

文章目录 大数据关联规则挖掘&#xff1a;Apriori算法的深度探讨一、简介什么是关联规则挖掘&#xff1f;什么是频繁项集&#xff1f;什么是支持度与置信度&#xff1f;Apriori算法的重要性应用场景 二、理论基础项和项集支持度&#xff08;Support&#xff09;置信度&#xff…

༺༽༾ཊ—Unity之-02-简单工厂模式—ཏ༿༼༻

首先我们打开一个项目 在这个初始界面我们需要做一些准备工作 建基础通用包 创建一个Plane 重置后 缩放100倍 加一个颜色 任务&#xff1a;使用【简单工厂模式】生成四种不同怪物 【按不同路径移动】 首先资源商店下载四个怪物模型 接下来我们选取四个怪物作为预制体并分别起名…

【Java并发】聊聊concurrentHashMap扩容核心流程

扩容 什么时候扩容 链表转红黑树。需要判断数组长度&#xff0c;触发扩容调用putAll() , 触发tryPresize() 方法数据量达到阈值 tryPresize-初始化数组 // 扩容前操作&#xff0c;putAll or 链表转红黑树 // size是原数组长度 * 2private final void tryPresize(int size) {…

如何在Servlet中获取请求参数的值

看看这个大佬做的动图吧&#xff01; 在Servlet中&#xff0c;你可以使用HttpServletRequest对象来获取请求参数的值。HttpServletRequest对象提供了一些方法&#xff0c;允许你访问从客户端发送的请求信息。以下是一些获取请求参数的常用方法&#xff1a; getParameter(String…

《SPSS统计学基础与实证研究应用精解》视频讲解:变量和样本观测值基本操作

《SPSS统计学基础与实证研究应用精解》4.1 视频讲解 视频为《SPSS统计学基础与实证研究应用精解》张甜 杨维忠著 清华大学出版社 一书的随书赠送视频讲解4.1节内容。本书已正式出版上市&#xff0c;当当、京东、淘宝等平台热销中&#xff0c;搜索书名即可。本书旨在手把手教会使…