KNN算法(k-NearestNeighbor)
k-近邻:基于分类与回归,属于有监督学习
此处讨论分类问题中的k-近邻算法。
三个基本要素:k值的选择,距离的度量,分类决策
KNN工作原理:
- 假设一个带有标签的样本数据集(训练样本集),包含每条数据与所属分类的对应关系
- 输入没有标签的新数据后,将新数据的每个特征与样本集中数据对应的特征进行比较。
- 计算新数据与样本数据集中每条数据的距离。
- 对求得的所有距离进行排序(从小到大,越小表示越相似)。
- 取前k(k<=20的奇数)个样本数据对应的分类标签。
- 求k个数据中出现次数最多的分类标签作为新数据的分类。
KNN算法思想:
- 计算所有样本点与待分类样本之间的距离。
- 计算样本距离进行排序。
- 选取距离样本最近的k个点。
- 针对这k个点,统计下各个类别分别有多少个。
- K个点中某个类别最多,就将该样本划归为该类别。
KNN算法模型流程与实现:
- 搜集数据;
- 准备数据;处理为统一格式
- 分析数据;根据分析结果,选择不同模型。
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 |