KNN回归:实现预测鸢尾花的花瓣宽度

KNN最近邻法实现回归预测的基本思想:****

根据前3个特征属性,寻找最近的k个邻居,然后再根据k个邻居的第4个特征属性,去预测当前样本的第4个特征属性(花瓣宽度)


import numpy as np
import pandas as pd

data = pd.read_csv('Iris.csv',header = 0)
data.drop(['Id','Species'],axis = 1,inplace=True)
data.drop_duplicates(inplace = True)

class KNN:
    '''K近邻回归预测
    根据前3个特征属性,寻找最近的k个邻居,然后再根据k个邻居的第4个特征属性,去预测当前样本的第4个特征属性(花瓣宽度)
    '''
    
    def __init__(self,k):
        '''初始化方法
        
        Parameters
        k: int
            邻居个数
        '''
        self.k = k
    
    def fit(self,X,y):
        '''训练方法
        
        Parameters
        X: 类数组类型,形状为:[样本数量,特征数量]
            带训练的样本特征(属性)
        
        y: 类数组类型,形状为:【样本数量】
            每个样本的目标值(标签)
        '''
        self.X = np.asarray(X)
        self.y = np.asarray(y)

    def predict(self,X):
        '''根据参数传递的样本,对样本数据进行预测
        
        Parameters
        X: 类数组类型,形状为:[样本数量,特征数量]
            带训练的样本特征(属性)
        
        Return: 数组类型
            预测结果
        
        '''
        X = np.asarray(X)
        result = []
        
        for x in X:
            # 计算测试集中每个样本与训练集中所有样本的欧式距离
            distance = np.sqrt(np.sum((x - self.X)**2,axis=1)) 
            #返回数组排序后,每个元素在原数组中(排序之前的数组)的索引
            index = np.argsort(distance)
            # 取前k个距离最近的索引(在原数组的索引)
            index = index[:self.k]
            
            result.append(np.mean(self.y[index]))
            
        return np.array(result)
    
    def predict2(self,X):
        '''根据参数传递的样本,对样本数据进行预测 ( 有权重的设置)
        权重的计算方式: 使用每个节点距离的倒数 / 所有距离倒数之和
        
        Parameters
        X: 类数组类型,形状为:[样本数量,特征数量]
            带训练的样本特征(属性)
        
        Return: 数组类型
            预测结果
        
        '''
        X = np.asarray(X)
        result = []
        
        for x in X:
            # 计算测试集中每个样本与训练集中所有样本的欧式距离
            distance = np.sqrt(np.sum((x - self.X)**2,axis=1)) 
            
            #返回数组排序后,每个元素在原数组中(排序之前的数组)的索引
            index = np.argsort(distance)
            # 取前k个距离最近的索引(在原数组的索引)
            index = index[:self.k]
            # 求所有邻居节点距离的倒数之和【最后加个0.001很小的值,为了避免分母为0的情况】
            weights_sum = np.sum(1 / (distance[index]+0.001))
           # 使用每个节点距离的倒数,除以倒数之和,得到权重
            weights = (1 /( distance[index] +0.001)) / weights_sum
			# 使用邻居节点的标签值,乘以对应的权重,然后相加,得到最终的预测结果
            predict2_result = np.sum(self.y[index] * weights)
            result.append(predict2_result)
         return np.array(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)
# 计算误差
wucha = np.mean((result - test_y)**2)
display(wucha)

# 带权重的回归
result2 = knn.predict2(test_x)
display(result2)
wucha2 = np.mean((result2 - test_y)**2)
display(wucha2)

# 显示
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()

在这里插入图片描述

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值