一.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值选取有误时容易出现过拟合现象。文章来源:https://www.toymoban.com/news/detail-844907.html
作为本学期的第一个实验,完整顺下来之后对于python的函数等内容有了一定的了解,但在编码能力上还有欠缺,多多学习吧文章来源地址https://www.toymoban.com/news/detail-844907.html
到了这里,关于K-NN算法实操及介绍的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!