KNN模型在分类和回归任务中超级详细介绍,以及具体KNN运用实例

一、KNN简介

  KNN作为一种监督学习方法,其工作机制为:给定测试样本,基于某种距离度量找出训练几种与其最靠近的k个训练样本,然后基于这k个“邻居”的信息进行预测。
  上述提到的某种距离度量主要有三种方法:曼哈顿距离、欧式距离和闵可夫斯基距离。在本文中,距离的计算采用的是欧式距离:
在这里插入图片描述

  KNN模型是一种“懒惰学习”的代表,此类学习技术在训练阶段仅仅是把样本保存起来,训练时间开销为零,待收到测试样本后再处理。
  KNN可以在分类和回归两种任务中使用,下面将依次介绍。



二、分类任务

基本思想:
通常,在分类任务中可以使用“投票法”,即选择这k个样本中出现最多的类别标记作为预测结果。
使用最近邻的类标号决定未知记录的类标号 (例如, 多数表决)
在这里插入图片描述
实例
  训练数据包含特征值feature:扔球的位置;标签label:球落入的篮筐。
数据如下图所示,本文最后附有数据下载地址。
在这里插入图片描述
思路:
1、把数据划充分打散,并划分为训练数据和测试数据两部分。
2、计算预测点与训练集中每个数据的距离;然后排序,选择最近的前k个;找出前k个中标签值最多的那个,即为预测值。
3、比较预测值和真实标签值是否相同。
4、重复2,3步骤,直到测试数据都被预测一遍,并计算最终预测准确率


代码:

import numpy as np
import  collections as co

def knn(k,predictPoint,feature,label):
    # 计算每个投置地与predictPoint的距离
    distance = list(map(lambda x: abs(predictPoint - x), feature))
    # 对distance的集合元素冲销到大排序,返回的是下表 np.sort()只是把集合里面的内容进行排序
    sortindex = np.argsort(distance)
    # 用排序的sortindex来操作lable集合
    sortlabel = label[sortindex]
    # 返回前k个中出现最多次数的标签值
    return co.Counter(sortlabel[0:k]).most_common(1)[0][0]

if __name__ == '__main__':

    data = np.loadtxt("数据/data0.csv", delimiter=",")
    # 处理数据,把数据充分打散,拆分成训练集和测试集
    np.random.shuffle(data)
    #测试数据
    testdata = data[:100]
    #训练数据
    traindata = data[100:-1]
    # 输入值,特征数据
    feature = traindata[:,0]
    # label 标签值
    label = traindata[:,-1]
    #k的取值,取值不同,准确率也会相应的变化。
    k=5
    count = 0
    for item in testdata:
        predict=knn(k,item[0],feature,label)
        real=item[1]
        if predict ==real:
            count=count+1
    print("k值为:{}; 准确率:{}%".format(k,count*100.0/len(testdata)))

运行截图:
在这里插入图片描述
多个维度:
上述在预测时只考虑到了投掷位置对其的影响,然而在实际中,影响因素常常有多个,即特征值有多个。比如在上述基础上加一个球的弹性特征值:
在这里插入图片描述
与一维不同的是,要注意以下几点:

  1. 由于球的颜色为汉字,要把其转化为相应的数字,转化方法:在用np.loadtxt()加载数据文件时,它提供了converters参数,可以进行转化,官方给出的使用说明如下图片所示。
      即例如converters={1: color2num}意思是将文件中第一列数据通过调用color2num函数将字符串解析为所需值。
    在这里插入图片描述
  2. 涉及到多维向量计算欧氏距离时不能再采用 distance = list(map(lambda x: abs(predictPoint - x), feature))
    可以采用以下通用方法:
 #计算xi-yi
 matrixtemp = (feature - predictPoint)
 #计算(xi-yi)的平方
 matrixtemp2 = np.square(matrixtemp)
 #计算欧式距离, 此处一定要设置axis=1,它表示按行的方向相加,返回每个行的值;
 # axis=0按列相加,返回每个列的值;如果不写则返回的是所有值相加的结构
 distance = np.sqrt(np.sum(matrixtemp2, axis=1))

全部代码:

import numpy as np
import  collections as co

def color2num(str):
    dict={"红":0.50,"黄":0.51,"蓝":0.52,"绿":0.53,"紫":0.54,"粉":0.55}
    return dict[str]
#考虑多个维度
def knn2(k,predictPoint,feature,label):
    #计算xi-yi
    matrixtemp = (feature - predictPoint)
    #计算(xi-yi)的平方
    matrixtemp2 = np.square(matrixtemp)
    #计算欧式距离, 此处一定要设置axis=1,它表示按行的方向相加,返回每个行的值;
    # axis=0按列相加,返回每个列的值;如果不写则返回的是所有值相加的结构
    distance = np.sqrt(np.sum(matrixtemp2, axis=1))
    # 对distance的集合元素冲销到大排序,返回的是下表 np.sort()只是把集合里面的内容进行排序
    sortindex = np.argsort(distance)
    # 用排序的sortindex来操作lable集合
    sortlabel = label[sortindex]
    # 返回前k个中出现最多次数的标签值
    return co.Counter(sortlabel[0:k]).most_common(1)[0][0]

if __name__ == '__main__':
    # 由于数据中颜色值为中文需要把它转化为数字
    # 通过converters={1: color2num}进行转化,
    # 意思是将文件中第一列数据通过调用color2num函数将字符串解析为所需值。
    data = np.loadtxt("数据/data1.csv", delimiter=",", converters={1: color2num}, encoding="gbk")
    np.random.shuffle(data)
    testdata = data[:100]
    traindata = data[100:-1]
    # 输入值,特征数据
    feature = traindata[:,0:2]
    # label 标签值
    label = traindata[:,-1]
    k=5
    x_test=testdata[:,0:2]
    y_test=testdata[:,-1]
    count = 0
    for i in range(len(x_test)):
        predict=knn2(k,x_test[i],feature,label)
        real=y_test[i]
        if predict ==real:
            count=count+1
    print("k值为:{}; 准确率:{}%".format(k,count*100.0/len(testdata)))

运行截图:
在这里插入图片描述
从上面实验结果我们也可以看出,当考虑的特征值增加时,准确率也相应的增加。


三、回归任务

&embp;&embp;在回归任务中可以使用“平均法”,即选择k个样本中出现最多的类别标记的平均值作为预测结果;还可以基于距离远近进行加权平均,距离越近的样本权重越大。

实例
预测房价时,考虑特征值:经度,维度,面积。label标签值为房的具体价格
由于给出的数据文件中含有很多数据,因此需要挑出我们实验所需要用到的
feature = np.loadtxt(“数据/kc_house_data.csv”,delimiter=",",skiprows=1,usecols=(17,18,6))
label = np.loadtxt(“数据/kc_house_data.csv”, delimiter=",", skiprows=1, usecols=(2))
usecols=(17,18,6)表示选择第17,18,6列作为特征值。

代码:

import numpy as np
def knn(k,predictPoint,feature,label):
    matrixtemp = (feature - predictPoint)
    matrixtemp2 = np.square(matrixtemp)
    distance = np.sqrt(np.sum(matrixtemp2, axis=1))
    sortindex = np.argsort(distance)
    sortlabel = label[sortindex]
    predictprice = np.sum(sortlabel[0:k]) / k
    return predictprice

if __name__ == '__main__':
    feature = np.loadtxt("数据/data2.csv",delimiter=",",skiprows=1,usecols=(17,18,6))
    label = np.loadtxt("数据/data2.csv", delimiter=",", skiprows=1, usecols=(2))
    predictPoint=np.array([47.5112,-122.257,5660])
    predict=knn(450,predictPoint,feature,label)
    print("预测房价为:{}美元".format(predict))

运行截图:
在这里插入图片描述
上面用到的实验数据请从下面链接中获取
提取码为4xkx

链接:https://pan.baidu.com/s/1qD4zj3L6054UCiVxDsLX0Q
提取码:4xkx

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值