机器学习之KNN算法(最邻近结点算法)
前言
KNN算法是数据挖掘分类技术中最简单的方法之一,所谓K最近邻,就是K个最近的邻居的意思,说的是每个样本都可以用它最接近的K个邻近值来代表。近邻算法就是将数据集合中每一个记录进行分类的方法。
一、KNN算法的结构
- 算距离:计算测试对象和训练集中每个对象的距离。
- 找邻居:圈定距离最近的K个训练对象作为测试对象的近邻。
- 做分类:根据这K个近邻归属的类别,对测试对象进行分类。
二、用Python实现KNN算法
1.导入需要的库
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib as mpl
from sklearn.datasets import make_blobs
%matplotlib inline
plt.rcParams['font.sans-serif'] = ['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False #用来正常显示负号
2.制作数据集
k = 3 #距离测试点最近的三个点
#返回的x是样本数据,y是每个样本数据的标签
x,y = make_blobs(n_samples=50,
cluster_std=[0.3,0.3,0.3],
centers = [[0,0],[1,1],[-1,1]],
random_state =4)
sim_data = pd.DataFrame(x,columns=['x1','x2'])
sim_data['label'] = y
datasets = sim_data.copy()
p = [1,0] #设置测试点的位置
plt.scatter(datasets['x1'],datasets['x2'],c=datasets['label'])
plt.scatter(p[0],p[1],color='red',marker='x')
plt.show()
0,1,2分别紫色、绿色、黄色
查看数据集
3.计算距离
x = datasets.iloc[:,[0,1]] #特征
y = datasets.iloc[:,-1] #标签
#套用欧式距离公式求出距离distance
distance = np.power(x - [0.5,0.5],2).sum(axis=1)
df_dist = pd.DataFrame({'distance':distance,'label':y})
4.找邻居并分类
#将数据进行顺序排序,然后取标签列进行取众数就可以预测测试点的类别
#mode()函数是提取出现最多次数的元素,取众数
df_dist.sort_values(by='distance').iloc[:k,-1].mode()[0]
得到的结果为0,那么可以推测出坐标为(1,0)的点的颜色为紫色。
将算法进行封装
def knn_classify(p,datasets,k): #p是测试点的坐标,datasets是数据集,k是距离p最近的k个元素
x = datasets.iloc[:,[0,1]]
y = datasets.iloc[:,-1]
distance = np.power(x - p,2).sum(axis=1)
df_dist = pd.DataFrame({'distance':distance,'label':y})
predict = df_dist.sort_values(by='distance').iloc[:k,-1].mode()[0]
return predict
举例测试算法
data = {'电影名称':['无问东西','后来的我们','前任3','红海行动','唐人街探案3','战狼2'],
'打斗镜头':[1,5,12,108,112,115],
'接吻头像':[101,89,97,5,9,8],
'电影类型':['爱情片','爱情片','爱情片','动作片','动作片','动作片']
}
movie = pd.DataFrame(data)
datasets = movie.iloc[:,1:]
knn_classify((15,65),datasets,3)
可以看出打斗镜头为15次,接吻镜头为65次的电影预测为爱情片。
总结
KNN算法的核心思想就是,如果一个样本在特征空间中的K个最相邻的样本中的大多数属于某一个类别,则该样本也属于这个类别,并具有这个类别上样本的特性。该方法在确定分类决策上只依据最邻近的一个或者几个样本的类别来决定待分样本所属的类别。
KNN方法思路简单,易于理解,易于实现,无需估计参数。但是该算法在分类时有个主要的不足是,当样本不平衡时,如一个类的样本容量很大,而其他类样本容量很小时,有可能导致当输入一个新样本时,该样本的K个邻居中大容量类的样本占多数。该方法的另一个不足之处是计算量较大,因为对每一个待分类的文本都要计算它到全体已知样本的距离,才能求得它的K个最近邻点。