一、KNN算法概述
K近邻(K-Nearest Neighbors,简称KNN)算法是一种简单而有效的监督学习算法,常用于分类和回归问题。它基于一个简单的思想:如果一个样本在特征空间中的k个最近邻居中的大多数属于某个类别,那么该样本也属于这个类别。KNN算法在模式识别、图像处理、语音识别等领域取得了显著的成果。
二、KNN算法原理
KNN算法的原理主要涉及到样本之间的距离度量和最邻近的邻居数量(K值)。当给定一个未标记样本时,算法计算该样本与训练集中所有样本的距离,然后选择离它最近的K个样本。最后,通过这K个邻居的类别进行投票,将未标记样本归类为票数最多的类别。
三、KNN的关键
三.1. 距离计算
距离计算是KNN算法中的关键步骤,它用于度量样本在特征空间中的相似性。欧氏距离是KNN中最常用的距离度量方法,下面将对欧氏距离的计算过程进行超详细的解释。
假设有两个样本点A和B,它们在n维特征空间中的坐标分别为 和 �=
1. 计算差值
首先,需要计算样本点A和B在每个维度上的差值。对于第i维度,差值为。
差值
这样就得到了n个维度上的差值。
2. 计算差值的平方
接下来,将每个维度上的差值求平方。
这样得到了n个维度上的平方值。
3. 求和
将所有维度上的平方值求和,得到平方和。
4. 开方
最后,对平方和进行开方操作,即可得到欧氏距离。
这就是欧氏距离的详细计算过程。它衡量了两个样本点在每个维度上的差异,通过平方和和开方的操作,将这些差异综合考虑,得到样本点之间的整体相似性度量。欧氏距离越小,说明样本点越相似;距离越大,说明样本点越不相似。在KNN中,计算这样的距离可以帮助我们找到最近邻的样本点,从而进行分类或回归。
三.2. K值选择
K值的选择在K近邻算法中至关重要,它决定了在进行分类或回归时考虑多少个最近邻居。下面详细解释K值的选择过程。
1. K值选择的目标
K值的选择的核心目标是找到一个能够在新样本上取得最佳性能的值。K值过小可能导致模型对噪声敏感,而K值过大可能导致模型过于平滑,无法捕捉数据的局部特征。
2. 常用的K值选择方法
2.1 经验法则
经验法则中,常用的K值一般为奇数,以避免在二分类问题中出现投票平局的情况。典型的K值选择如3、5、7等,具体取值通常由实践经验和问题的性质来决定。
2.2 交叉验证
交叉验证是一种更为准确的K值选择方法。它通过在训练集中留出一部分数据作为验证集,然后在验证集上评估不同K值下的性能。通过交叉验证的方式,可以选择出在验证集上性能最佳的K值。
3. K值选择的步骤
3.1 划分训练集和验证集
首先,将数据集划分为训练集和验证集。通常,可以采用一定比例的交叉验证,例如80%的数据作为训练集,20%的数据作为验证集。
3.2 尝试不同的K值
在训练集上尝试不同的K值,例如K=1、K=3、K=5等。
3.3 在验证集上评估性能
对于每个K值,在验证集上进行模型评估,记录其性能指标,如准确率、精确率、召回率等。
3.4 选择性能最佳的K值
根据在验证集上的性能,选择性能最佳的K值作为模型的最终选择。
4. 考虑数据规模
在选择K值时,还需要考虑数据集的规模。当数据集较小时,选择较小的K值可能更合适,以避免过拟合。而在数据集较大时,可以选择较大的K值,以确保模型的稳定性。
5. K值的影响
K值的选择不同会影响模型的复杂度,选择一个适当的K值是平衡模型复杂度和性能的关键。通常,可以通过实验和交叉验证来调整K值,以达到最佳的模型性能。
四.KNN实例
导入必要的库:我们使用numpy
进行数值计算,并使用math
模块进行数学运算。
from numpy import *
import math
定义数据集:我们创建了一个简化的学生成绩数据集cj
,其中包含了每个学生的语文平时成绩、语文期末成绩、数学平时成绩、数学期末成绩和最终等级。
cj = [
[90, 85, 88, 92, "excellent"],
[78, 80, 75, 82, "good"],
[60, 70, 65, 68, "fail"],
# ... 其他数据
]
用户输入数据:用户被要求输入自己的语文平时成绩、语文期末成绩、数学平时成绩和数学期末成绩。
testData = []
ywodscroe = float(input('请输入:语文平时成绩'))
ywtscroe = float(input('请输入:语文期末成绩'))
sxodscroe = float(input('请输入:数学平时成绩'))
sxtscroe = float(input('请输入:数学期末成绩'))
testData.append(ywodscroe)
testData.append(ywtscroe)
testData.append(sxodscroe)
testData.append(sxtscroe)
计算距离:通过欧氏距离计算用户输入数据与数据集中每个学生数据之间的距离。
distance = []
for item in cj:
result = math.sqrt((testData[0] - float(item[0]))**2 + (testData[1] - float(item[1]))**2
+ (testData[2] - float(item[2]))**2 + (testData[3] - float(item[3]))**2)
distance.append({
'data': result,
'species': item[4]
})
根据距离排序:将距离按照升序进行排序。
distance.sort(key=lambda x: x['data'])
选择前k个数据:选择排序后的前k个数据。
k = 9
top_k = distance[:k]
统计等级数量:统计前k个数据中每个等级的数量。
count = {"excellent": 0, "good": 0, "fail": 0}
for item in top_k:
count[item['species']] += 1
找到数量最多的等级:找到统计数量最多的等级,即为最终的预测等级。
predicted_species = max(count, key=count.get)
输出预测结果:输出最终的预测等级。
print('预测您的等级为:' + predicted_species)
该实例演示了K近邻(KNN)算法在学生成绩预测方面的应用。具体来说,通过输入用户的语文平时成绩、语文期末成绩、数学平时成绩和数学期末成绩,该程序利用KNN算法预测用户的最终等级。
四、实验总结与体会
-
KNN算法灵活性: KNN算法简单而灵活,适用于多种领域,本实例展示了其在学生成绩预测中的应用。
-
K值的重要性: K值的选择直接影响模型性能,需要根据具体问题和数据规模进行调整。
-
实际应用考虑: 在实际应用中,除了理论知识,还需考虑数据的质量、特征选择等因素,以获得更准确的预测结果。
-
综合性能评估: 通过交叉验证等手段,可以更准确地评估模型在未知数据上的性能,有助于选择最佳的K值。