此笔记只为了记录学习最近邻算法的一些心得,用来方便日后回来复习,所以不具备任何教学目的。(当然如果你从这篇文章学到了东西,我还是很开心的)
本人还是一名初入数据挖掘领域的大学生。如果你觉的文章水平低,你可以去看其它大佬的文章但不要出现任何谩骂、嘲讽行为。
如果有任何不对以及错误的地方,希望大家评论区指出.
K最邻近(KNN,K-NearestNeighbor)分类算法是数据挖掘中最简单的方法之一。这种算法非常直观:如果一个样本在空间中最近K个样本大多都属于同一类,则该样本也属于这一类。该计算方法只依靠相邻的K个结点来判断该结点的属性,所以正确率有待商榷。比如图1,一条河流分割出了穷人区和富人区,使用K相邻算法的时候可以成功判别每个图形属于穷人区还是富人区。但这时候有一个穷人定居在了富人区(图2红色圆圈),这时候与其最近的则是富人区的住宅所以K相邻算法则会把其定义为富人。
图一
图二
上述例子是基于二维平面。我们知道在平面直角坐标系中两点的距离公式是y=√(x1-x2)^2+(y1-y2)^2。现实中可以基于三维甚至更高维,虽然我们无法用视觉来观察这种抽象的空间,但其实在根号里多添加几个数而已。
代码实现
关于最近邻算法的过程其实可以分为三步:
- 数据处理
- 模型训练
- 模型验证
关于数据处理我们又可以分为加载数据,交叉验证以及归一化三步。
加载数据不用介绍,我们讲一下交叉验证和归一化是什么。
交叉验证:将原有的数据分为训练集和验证集。训练集用来训练分类器,验证集则验证分类器的成果,最后用准确率作为分类器的成果展示。
归一化:因为处理的数据都是不同,有可能是在一定范围内,也有可能是不限制范围。所以我们需要将数据的权重都是一致的。除了归一化还有标准化这个方法。
首先我们要加载数据用来处理。
#使用莺尾花数据集
from sklearn import datasets
iris = datasets.load_iris()
iris_x = iris.data
iris_y = iris.target
接下来我们发现iris_y的值有一定规律性,0-49为0,50-99为1,100-149为2。当我们选取训练集和验证集的时候可能会出现内容全0或1或2,所以我们在交叉验证前要先将其顺序打乱。
randomArr = np.random.permutation(len(iris_x))
iris_x_train = iris_x[randomArr[:-10]]
iris_y_train = iris_y[randomArr[:-10]]
iris_x_test = iris_x[randomArr[-10:]]
iris_y_test = iris_y[randomArr[-10:]]
这里我确定了随机数组的后十数组为验证集的序号,其余为训练集,这里数值不一定可以修改。甚至如果还可以偷懒使用sklearn的内置函数。
iris_x_train, iris_x_test, iris_y_train, iris_y_test = train_test_split(iris_x, iris_y)
归一化和标准化
离异标准化是一种线性变化,通过公式将数据的范围局限为[0,1]之间。
max-min是极差
def minmaxscale(data):
data=(data-data.min())/(data.max()-data.min())
return data
标准差标准化可以将数据均值为0,标准差为1,同时数据的范围不再局限于[0,1],甚至可能会出现负数。
下面符号表示原始数据的标准差。
def StandardScaler(data):
data=(data-data.mean())/data.std()
return data
同样也可以使用sklearn的内置函数 preprocessing.scale
训练
最后生成分类器,并进行训练和预测的得分。
iris_y_predict = knn.predict(iris_x_test)
score = knn.score(iris_x_test, iris_y_test, sample_weight= None)
最后输出结果
#输出结果
print('iris_y_predict = ', end='')
print(iris_y_predict)
#原始数据进行对比
print('iris_y_test = ', end='')
print(iris_y_test)
print('Accuracy=', score)