python实现knn算法

本文介绍了如何通过自定义KNN算法对鸢尾花数据进行分类,包括数据预处理(归一化),计算欧式距离以及确定最优的k值。作者还展示了如何使用sklearn库,并通过实例演示了正确率测试。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        关于knn的理论算法已经有很多博客了,这里就不再重述。对于代码可以直接调用sklearn。但是直接利用逻辑实现,可能会对算法理解更通透。这里大家所需要修改的就是k和df,k是所选区的周围样本个数,df是路径,按照自己的路径修改就可以了。这里是对鸢尾花进行的分类处理,由于鸢尾花每个特征有的数值大,有的数值小,所以要进行归一化处理。原来的代码里没有对数据进行归一化处理,这里修改了一下。在运行时会发现,如果k很小效果不够理想,k太大也不行,在中间某个区间里,效果是不错的

from sklearn.model_selection import train_test_split
import pandas as pd  
import numpy as np 
from collections import Counter
from sklearn.preprocessing import StandardScaler

k = 40# 选定的待分类点的所处位置周围点的个数,理论上来所k值会呈现一个山峰形式,中间某个值是最好的,超过这个值,预测效果就会越来越差

df= pd.read_csv("C:/Users/wxc/Desktop/xuexi/python/pythonProject/机器学习/分类与聚类/knn/ris.csv")  # 放置文件路径

df_x= np.array(df.iloc[:, 0:4]) #这里是在读取特征与标签,并把它们全部都变成ndarray类型,便于后续处理
scaler = StandardScaler()
df_x = scaler.fit_transform(df_x)  #对x的标签进行归一化
df_y= np.array(df.iloc[:,-1])

train_x,test_x,train_y,test_y=train_test_split(df_x,df_y,test_size=0.3,random_state=42)  #划分测试集与训练集

# KNN算法
def calculate_distance(test_x, train_x):  # 计算目标点与训练集的欧式距离,并且根据距离最近的k个选择出来
    distances = []
    train_yth = []
    for  i in range(len(test_x)):
        dist=[]    
        j_list = [] 
        for j in range(len(train_x)): #这里用的是长度,这样子便于后续找到标签
            d = np.linalg.norm(test_x[i] - train_x[j])
            dist.append((j, d)) # 这里j表示在train_x中的位置是第几个,d表示测试集与训练集特征参数的欧式距离
            
        dist.sort(key=lambda item: item[1])  #排序,按照d的大小进行排序,筛选出距离最近的k个值
        distances.append(dist[:k])  # 将所有的数据全部储存起来,便于后续输出
        j_list = [item[0] for item in dist[:k]] # 提取出j,这里是为了后面筛选出对应的train_y的标签
        train_yth.append(j_list) # 把所有的j全部储存起来
    return train_yth # 这里k设置的是15,所以每一组会有15对数

# 统计在train_x中的标签个数
test_x_pre = []
t = calculate_distance(test_x,train_x)
train_labels = []
for i in t:# 这里是在寻找对应的train_y的标签,并且保存下来
    labels = [train_y[index] for index in i]
    train_labels.append(labels)

for i in train_labels:  # 统计train_labels中的出现最多次数的元素
    counter = Counter(i)
    most_common = counter.most_common(1)
    most_common_element = most_common[0][0]
    most_common_count = most_common[0][1]
    test_x_pre.append(most_common_element)

# 这里是在进行正确率测试
o = 0
for i in range(len(test_x_pre)):
    if test_x_pre[i] == test_y[i]:
        o = o+1
z= o/len(test_y)
print('准确率:',z)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值