KNN算法(k-NearestNeighbor)笔记

KNN算法(k-NearestNeighbor


k-近邻:基于分类与回归,属于有监督学习

此处讨论分类问题中的k-近邻算法。

三个基本要素:k值的选择,距离的度量,分类决策

KNN工作原理:

  1. 假设一个带有标签的样本数据集(训练样本集),包含每条数据与所属分类的对应关系
  2. 输入没有标签的新数据后,将新数据的每个特征与样本集中数据对应的特征进行比较。
  3. 计算新数据与样本数据集中每条数据的距离。
  4. 对求得的所有距离进行排序(从小到大,越小表示越相似)。
  5. 取前k(k<=20的奇数)个样本数据对应的分类标签。
  6. 求k个数据中出现次数最多的分类标签作为新数据的分类。

KNN算法思想:

  1. 计算所有样本点与待分类样本之间的距离。
  2. 计算样本距离进行排序。
  3. 选取距离样本最近的k个点。
  4. 针对这k个点,统计下各个类别分别有多少个。
  5. K个点中某个类别最多,就将该样本划归为该类别。

KNN算法模型流程与实现:

  1. 搜集数据;
  2. 准备数据;处理为统一格式
  3. 分析数据;根据分析结果,选择不同模型。

knn.py:

import jieba

import numpy as np

import math

import operator

from numpy import *

import matplotlib

import matplotlib.pyplot as plt

#中文显示

import matplotlib.font_manager as fm

# 解决可视化显示时,中文乱码

myfont=fm.FontProperties(fname='C:\Windows\Fonts\simkai.ttf')

# 返回数据集和标签

def creat_dataset():

    datasets=array([[5,2,7],[4,3,5],[1,2,2],[2,0,3],[2,1,1],[3,1,3],[2,1,3],[2,1,1]])  #数据集

    labels=['非常热','非常热','一般热','一般热','一般热','非常热','一般热','非常热'] #类标签

    return datasets,labels

# 返回数据集和标签

def creat_datasets():

    datasets=array([[5,2,7],[4,3,5],[1,2,2],[3,0,3],[2,1,3],[3,1,3],[3,1,3],[2,1,1]])  #数据集

    labels=[0,0,1,1,1,0,1,0] #类标签0-'非常热',1-'一般热'

    return datasets,labels

# 可视化分析数据

# def analyze_data_plot(x,y):

#     fig=plt.figure()

#     # 将画布划分为一行一列一块

#     ax=fig.add_subplot(111)

#     ax.scatter(x,y)

#     # 设置散点图标题和横纵坐标

#     plt.title("游客冷热感知点散点图",fontsize=25,fontname='宋体',fontproperties=myfont)

#     plt.xlabel("天热吃冰激凌数目",fontsize=25,fontname='宋体',fontproperties=myfont)

#     plt.ylabel("天热喝水数目",fontsize=25,fontname='宋体',fontproperties=myfont)

#     # 保存截图

#     # plt.savefig('datasets_plot.png',bbox_inches='tight')

#     plt.show()

# 构造KNN分类器

    # 1、获取新的样本数据

    # 2、获取样本库的数据

    # 3、计算样本数据与样本库数据之间的距离

    # 4、根据距离进行排序

    # 5、选择k值

    # 6、针对k个点,统计各个类别的数量

    # 7、投票机制,少数服从多数原则输出类别

def knn_Classifier(newV,datasets,labels,k):

    # 1、计算样本数据与样本库数据之间的距离

    sqrtDist=Euclidean_distance_calculation3(newV,datasets)

    # 2、根据距离进行排序

    sortDistIndexs=sqrtDist.argsort(axis=0)

    # 3、针对k个点,统计各个类别的数量

    classCount={} #统计各个类别分别的数量

    for i in range(k):

        for j in range(len(sortDistIndexs)):

            if i==sortDistIndexs[j]:

                votelabel=labels[j]

                # 统计类标签的键值对

        classCount[votelabel]=classCount.get(votelabel,0)+1

                #classCount.get(votelabel,0):https://blog.youkuaiyun.com/weixin_38705903/article/details/79231551

    # print(classCount)

    # 4、投票机制,少数服从多数原则输出类别

    # 对各个分类字典进行排序,降序,itemgetter按照value排序:https://blog.youkuaiyun.com/dongtingzhizi/article/details/12068205

    sortedClassCount=sorted(classCount.items(),key=operator.itemgetter(1),reverse=True)

    # print(newV,'KNN投票预测结果是:',sortedClassCount[0][0])

    return sortedClassCount[0][0]

# 欧氏距离计算1:d2=(x1-x2)^2+(y1-y2)^2

# def Euclidean_distance_calculation1(x1,x2,y1,y2):

#     d = math.sqrt(math.pow((x1 - x2), 2) + math.pow((y1 - y2), 2))

#     return d

# 欧氏距离计算2

# def Euclidean_distance_calculation2(instance1,instance2,dimension):

#     d=0

#     for i in range(dimension):

#         d+=math.pow(instance1[i]-instance2[i],2)

#     return math.sqrt(d)

# 欧氏距离计算3

def Euclidean_distance_calculation3(newV,datasets):

    # 获取样本库数据向量的行向量维度和纵向量维度

    rowsize,colsize = datasets.shape

    # shape:https://blog.youkuaiyun.com/qq_28618765/article/details/78081959

    #各特征向量之间做差值

    diffMat = tile(newV,(rowsize,1))-datasets

    # numpy.tile:https://blog.youkuaiyun.com/ksearch/article/details/21388985

    # print(diffMat)

    # 对差值平方

    sqDiffMat = diffMat ** 2

    # print(sqDiffMat)

    # 差值平方和进行开方

    sqrtDist=sqDiffMat.sum(axis=1) ** 0.5

    # sum(axis=1):https://www.cnblogs.com/yyxayz/p/4033736.html

    return sqrtDist

# 利用KNN分类器预测随机访客天气感知度

def Predict_temperature():

    #1.创建数据集和类标签

    datasets,labels=creat_dataset()

    # 2.采访新游客

    iceCream=float(input('Q:请问你今天喝了几瓶水?\n'))

    drinkWater=float(input('Q:请问你今天吃了几个冰激凌?\n'))

    outTime=float(input('Q:请问你今天户外活动几个小时?\n'))

    newV=array([iceCream,drinkWater,outTime])

    res=knn_Classifier(newV,datasets,labels,5)

    print("该访客认为成都天气是:",res)

if __name__ == '__main__':

    # 1.创建数据集和类标签

    # datasets,labels=creat_dataset()

    # print('数据集:\n',datasets,'\n类标签:\n',labels)

    # 2.可视化分析数据

    # analyze_data_plot(datasets[:,0],datasets[:,1])

    # # 3.1欧氏距离计算1

    # d = Euclidean_distance_calculation1(2,5,6,2)

    # print(d)

    # # 3.2欧氏距离计算2

    # d = Euclidean_distance_calculation2([2,6],[5,2],2)

    # print(d)

    # 3.3欧氏距离计算3

    # Euclidean_distance_calculation3(newV,datasets)

    # # 4.1单例knn分类器构造

    # newV = [2, 4, 4]

    # res=knn_Classifier(newV,datasets,labels,3)

    # print('KNN投票预测结果是:',res)

    # 4.2多例knn分类器构造

    # vesc=array([[2,4,4],[3,0,0],[5,4,7]])

    # for i in vesc:

    #     res=knn_Classifier(i,datasets,labels,5)

    #     print(i,'KNN投票预测结果是:',res)

    Predict_temperature()

import numpy 和 from numpy import*的区别:

import numpy,如果使用numpy的属性都需要在前面加上numpy

from numpy import *,则不需要加入numpy

后者不建议使用,如果下次引用和numpy里的函数一样的情况,就会出现命名冲突。

 

# 调用机器学习库knn分类器算法

Knnsklearn.py


from sklearn import neighbors

from numpy import *

import knn as KNN

def knn_sklearn_predict(newV,datasets,labels):

    # 调用机器学习库knn分类器算法

    knn=neighbors.KNeighborsClassifier()  # KNeighborsClassifier此函数没加括号,出现错误:TypeError: fit() missing 1 required positional argument: 'y'

    # 传入参数,特征数据,分类标签

    knn.fit(datasets,labels)

    #knn预测

    predictRes=knn.predict([newV])

    return predictRes

# 利用KNN分类器预测随机访客天气感知度

def Predict_temperature():

    # 调用模块下的方法,返回数据集和标签

    datasets, labels = KNN.creat_datasets()

    # 2.采访新游客

    iceCream=float(input('Q:请问你今天喝了几瓶水?\n'))

    drinkWater=float(input('Q:请问你今天吃了几个冰激凌?\n'))

    outTime=float(input('Q:请问你今天户外活动几个小时?\n'))

    newV=array([iceCream,drinkWater,outTime])

    res=knn_sklearn_predict(newV,datasets,labels)

    print("该访客认为成都天气是:\t",'非常热' if res[0]==0 else '一般热')

if __name__ == '__main__':

    Predict_temperature()
 

参考视频网址:https://www.imooc.com/learn/1069

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值