1.KNN算法思想
2.实现KNN算法要提供的数据
3.KNN算法核心程序
4.KNN完整程序
一,KNN算法思想
KNN算法是用于判断一个物品是属于哪一类的算法。如要判断一电影(如电影A)是爱情片还是动作片,可以通过其接吻镜头和打斗镜头的次数来判断,设 x = 接吻镜头,y = 动作镜头。则形成一个坐标点(x,y)。而其他已定好类型的电影(例如10部电影---5部爱情片,5部动作片),它们同样也有(x,y)坐标,这些坐标作为一个点集。这样就在xOy平面中,就有11个点,用电影A的坐标与其他 k (k值可有自己设置) 部电影的坐标的距离进行比较,看看在距离上 电影A的坐标时靠近 动作片电影的坐标次数多一点还是爱情片坐标的次数多一点以判断电影A是哪种类型的电影。
如图,以绿圆与其他图形的距离远近,比较最近的 K 个。来确定绿圆是属于哪一种类型。
距离计算公式:
如有 点A(Ax,Ay) 和 点B(Bx,By),计算A,B直接的距离
二,实现KNN算法要提供的数据
1.首先是未确定类型的测试点
2.已确定类型的点集,否则你的测试点要跟谁比较
3.点集对应的类型集。
4.K值,取 点集里 k 个与测试点最近的点。
如有点集dataset:1,4,11,3,13,20.
若 10 以内的点都归为A类,10以外的点都归为B类
则 label = ['A',‘A’,'B',‘A’,‘B’,‘B’]
三,KNN算法核心程序
from numpy import *
from operator import *
'''
input:表示一个测试点,通过knn算法来测试该点是属于什么类型的点
dataset:一个矩阵,表示一堆各个类型的坐标点。knn通过input点和dadtaset中的点的距离来判断input点是属于什么类型的点
label:只有一行的矩阵,表示datdaset中的点分别对应的类型,labels的个数与dataet的行数相同。
k:一个整数,表示input点与 dataset中的 k 个点进行比对,
'''
def knn(input,dataset,labels,k):
datasetSize = dataset.shape[0] #shape[0]表示矩阵dataset的行数,也就是dataset中的坐标点个数
DiffMat = tile(input,(datasetSize,1)) - dataset
SqDiffMat = DiffMat ** 2 #矩阵中每一个元素都平方
SqDistances = sum(SqDiffMat,axis = 1) #sum方法返回的一定时只有一行的矩阵,当axis = 1,矩阵每行的所有列相加
#当axis = 0,矩阵的每列的所有行相加
Distances = SqDistances ** 0.5 #矩阵中每一个元素都开方
'''argsort:根据元素的大小从小到大排序,返回下标.如某元素是最小的,则该元素的位置为0'''
SortDistances = Distances.argsort()
LabelsCount = {}
'''选择距离最小的 k 个点'''
for i in range(k):
Label = labels[SortDistances[i]]
LabelsCount[Label] = LabelsCount.get(Label,0) + 1 #统计距离最近的 label们 的个数
'''在前k个距离最近的点中,出现最多次的label就是测试点的类型'''
MaxNum = 0
for key,num in LabelsCount.items():
if num > MaxNum:
MaxNum = num
InputLabel = key
return InputLabel
分开了三个文件: knn.py ,test.py(用与生成点集和label集),main.py(开始执行的模块)
test.py
from numpy import *
'''生成点集'''
def TestData():
dataset = array([
[1.4,2.7],
[0.7,1.8],
[5,2],
[10,7],
[1,4],
[14, 4],
[2, 4]
])
#'''点集中每个点对应的label(类型)'''
labels = ['A','A','B','B','A','B','A']
return dataset,labels
knn.py
from numpy import *
from operator import *
'''
input:表示一个测试点,通过knn算法来测试该点是属于什么类型的点
dataset:一个矩阵,表示一堆各个类型的坐标点。knn通过input点和dadtaset中的点的距离来判断input点是属于什么类型的点
label:只有一行的矩阵,表示datdaset中的点分别对应的类型,labels的个数与dataet的行数相同。
k:一个整数,表示input点与 dataset中的 k 个点进行比对,
'''
def knn(input,dataset,labels,k):
datasetSize = dataset.shape[0] #shape[0]表示矩阵dataset的行数,也就是dataset中的坐标点个数
DiffMat = tile(input,(datasetSize,1)) - dataset
SqDiffMat = DiffMat ** 2 #矩阵中每一个元素都平方
SqDistances = sum(SqDiffMat,axis = 1) #sum方法返回的一定时只有一行的矩阵,当axis = 1,矩阵每行的所有列相加
#当axis = 0,矩阵的每列的所有行相加
Distances = SqDistances ** 0.5 #矩阵中每一个元素都开方
'''argsort:根据元素的大小从小到大排序,返回下标.如某元素是最小的,则该元素的位置为0'''
SortDistances = Distances.argsort()
LabelsCount = {}
'''选择距离最小的 k 个点'''
for i in range(k):
Label = labels[SortDistances[i]]
LabelsCount[Label] = LabelsCount.get(Label,0) + 1 #统计距离最近的 label们 的个数
'''在前k个距离最近的点中,出现最多次的label就是测试点的类型'''
MaxNum = 0
for key,num in LabelsCount.items():
if num > MaxNum:
MaxNum = num
InputLabel = key
return InputLabel
main.py
from numpy import *
import KNN.knn as knn #导入 KNN包中的knn模块的knn方法和KNN模块的test方法,这些包和模块都是个人创建的。
import KNN.test as test
input = array([13.1,2.7])
dataset,labels = test.TestData()
InputLabel = knn.knn(input, dataset, labels, 3)
print(InputLabel)