K-近邻算法(KNN)学习心得
一、算法综述
K-近邻算法是数据挖掘中常用的也是最简单基础的一种算法,没有之一!哈哈哈。
解决的问题:
如果有一堆数据,它们的标签已知,那么对于一个全新的样本数据,我们如何对其进行分类呢?最简单的办法就是使用KNN算法进行分类。KNN算法分类的分类原理大概可以表述如下:对于新来的数据X,我们计算特征空间中和X最相似的,也就是距离最近的K个样本,查看这个K个数据的类标签,进行投票,哪一个类别得票分数最高,这个新的数据点X就属于这个类别(有的时候也可以基于距离的远近进行加权投票,距离越近的样本的权重越大),这样就完成了对新数据点的分类。
这个距离可以使用欧式距离,也可以使用曼哈段距离:
具体K-近邻算法步骤如下:
- 计算所有已知类别的数据点与当前的未知标签样本点的距离
- 按照距离的长短从小到大排序
- 选取与未知标签样本点距离最小的K个数据点
- 确定所选取的K个点的标签分布
- 以出现频率最高的类别作为未知样本点的标签类
需要考虑的问题是:
这个 K 值是一个超参数,如何确定?
当K=3时,图中绿色的样本点属于红色三角标签一方;而当K=5时该样本点又属于蓝色方块标签一方。那绿色究竟该属于哪一方呢?也就是究竟K=?
k=1的K近邻算法被称为最近邻算法,此时将训练集中与测试样本点最接近的点的类别作为测试样本的分类标签。
k比较小时:
- 优点:只有与输入实例较近的的训练实例才会对预测起作用。
- 缺点:因为参考的点很少,所以其“学习”的估计误差会增大,预测结果对近邻的点非常敏感。如果近邻的实例点刚好事噪声, 那么预测可能出错的概率变大。
k比较大时:
- 优点:有效的减少“学习“的估计误差。
- 缺点:“学习”的近似误差会增加,此时离实例较远的点也会对预测起作用,使得出现预测错误的概率加大。其实K值加大意味着模型变得简单,如果K=样本点数,那么所有的测试点的类标签都是训练集中出现最多的那一类标签。
可以使用交叉验证的方法来选取最优的K值,每测试一个K值就计算其平均误差率,最后选择其中最小的平均误差率所对应的K值
二、python实现
#导入需要的包
import numpy as np
import matplotlib.pyplot as plt
from math import sqrt
from collections import Counter
from sklearn.model_selection import train_test_split
#定义KNN分类函数
def knn_classify(x_train,y_train,x,k):
assert 1<=k<=x_train.shape[0],"k must be a valid"
assert x_train.shape[0]==y_train.shape[0],"the size of x_train must be equal to the size of y_train"
assert x_train.shape[1]==x.shape[1],"the feature of x must be equal to x_train" # 进行数据监测断言
label=[]
for i