赞
踩
【KNN回归】
学习课程:B站【超实用】Python实现机器学习算法(全) BV1V7411P7wL
数据集:鸢尾花数据集(Iris.csv)
- import numpy as np
- import pandas as pd
- # 读取鸢尾花数据集,header参数来指定标题的行,默认为0,如果没有标题,则使用None
- data=pd.read_csv(r"C:/Users/DELL/Desktop/Iris.csv")
- # 使用花萼长度、花萼宽度、花瓣长度来预测花瓣宽度
- # 删除不需要的species列(特征),按列删除
- data.drop(["species"],axis=1,inplace=True)
- # 删除重复记录
- data.drop_duplicates(inplace=True)
# 定义KNN的类 class KNN: """使用python语言实现KNN算法(回归预测) 该算法用于回归预测,根据前3个特征属性,寻找最近的k个邻居,然后再根据k个邻居的第4个特征 属性,预测当前样本的第4个特征值 """ def __init__(self,k): """初始化方法 parameters ---- k:int 表示邻居的个数 """ self.k=k def fit(self,X,y): """训练方法 parameters ---- X:类数组类型,形状为:{样本数量,特征数量} 待训练的样本特征(属性) y:类数组类型,形状为:{样本数量} 每个样本的目标值(标签) """ ## 将X转换成ndarray数据类型 self.X=np.asarray(X) self.y=np.asarray(y) def predict(self,X): """根据参数传递的样本,对样本数据进行预测 parameters ---- X:类数组类型,形状为:{样本数量,特征数量} 待训练的样本特征(属性) returns ---- result:数组类型 预测的结果 """ X=np.asarray(X) result=[]; # 对ndarray数组进行遍历,每次取数组中的一行 for x in X: # 对于测试集中的每一个样本,依次与训练集中的所有样本求距离 dis=np.sqrt(np.sum((x-self.X)**2,axis=1)) # 返回数组排序后,每个元素在原数组(排序之前的数组)中的索引 index=dis.argsort() # 进行截断,只取前k个元素(取距离最近的k各元素的索引) index=index[:self.k] # 计算均值,然后加入到结果列表当中 result.append(np.mean(self.y[index])) return np.asarray(result) def predict2(self,X): """根据参数传递的样本,对样本数据进行预测(考虑权重) 权重的计算方式:每个节点(每个邻居)距离的倒数/所有节点(所有邻居)的距离倒数之和 parameters ---- X:类数组类型,形状为:{样本数量,特征数量} 待训练的样本特征(属性) returns ---- result:数组类型 预测的结果 """ X=np.asarray(X) result=[]; # 对ndarray数组进行遍历,每次取数组中的一行 for x in X: # 对于测试集中的每一个样本,依次与训练集中的所有样本求距离 dis=np.sqrt(np.sum((x-self.X)**2,axis=1)) # 返回数组排序后,每个元素在原数组(排序之前的数组)中的索引 index=dis.argsort() # 进行截断,只取前k个元素(取距离最近的k各元素的索引) index=index[:self.k] # 计算所有节点的距离倒数之和,注意最后加上一个很小的值,为了避免除数为零的情况 s=np.sum(1/(dis[index]+0.001)) # 使用每个节点距离的倒数,除以倒数之和,得到权重 weight=(1/(dis[index]+0.001))/s # 使用邻居节点的标签值,乘以对应的权重,然后相加,得到最终的预测结果 result.append(np.sum(self.y[index]*weight)) return np.asarray(result)
- # 测试与训练
- t=data.sample(len(data),random_state=0)
- train_X=t.iloc[:120,:-1]
- train_y=t.iloc[:120,-1]
- test_X=t.iloc[120:,:-1]
- test_y=t.iloc[120:,-1]
- knn=KNN(k=3)
- knn.fit(train_X,train_y)
- result=knn.predict(test_X)
- display(result)
- display(np.mean((result-test_y)**2))
- display(test_y.values)
- # 考虑权重的结果
- result2=knn.predict2(test_X)
- display(np.mean((result2-test_y)**2))
# 可视化 import matplotlib as mpl import matplotlib.pyplot as plt mpl.rcParams["font.family"]="SimHei" mpl.rcParams["axes.unicode_minus"]=False plt.figure(figsize=(10,10)) # 绘制预测值 plt.plot(result,"ro-",label="预测值") # 绘制真实值 plt.plot(test_y.values,"go-",label="真实值") plt.title("KNN连续值预测展示") plt.xlabel("节点序号") plt.ylabel("花瓣宽度") plt.legend() plt.show()
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。