一、K-近邻算法
K-近邻(K-NN)算法可以说是最简单的机器算法。构建模型只需要保存训练数据集即可。想要对新数据点做出预测,算法会在训练数据集中找到最近的数据点,也就是它的“最近邻”。
这里实现的是一个监督学习中的分类(二分类)问题。我们需要预测出测试数据的所属类别。
二、实现步骤
1.获取数据集
导入Numpy方便操作数据,pyplot用来绘图
解释:np.random.uniform(1,5,(50,2)):生成一个50X2的矩阵
其中的元素值是1~5之间的随机数。
x_data = np.concatenate([x_data1,x_data2]):合并两个矩阵为一个矩阵。
最终的源数据集为:
x_data(代表坐标):
…一共100组数据
y_data(代表类别):
也是100组数据。一个坐标对应一个类别。
2.将数据集分为训练集和测试集
训练集获取:
解释:np.split(x_data,[75])[0]表示将x_data分割为2个部分,我们取下标为0的,指前75组数据。测试集数据获取:
解释:相应的测试数据我们就取后面25组数据作为测试集。
3.构建模型
1.绘制散点图:
2.k-NN的过程:
解释:蓝色的点表示需要预测的数据,我们需要求出离它最近的几个点的类别,利用投票法决定蓝色点的类别,由图可知蓝色点最后的类别和红色点一样为1具体算法:(求距离就是求两坐标点间的距离)
最后结果预测是1和红色点的类别相同至此构建模型结束。
4.用测试集的数据测试求出精度
解释:这里其实就是对测试集数据重复之前的操作,然后将测试集数据的预测结果和其正确的类别进行比较,记录预测正确的个数,最后除以总共测试的数据就求出了此模型的精度。
三、算法实现
?代码是顺序的
#产生数据的模块
import numpy as np
import matplotlib.pyplot as plt
#源数据的产生
x_data1 = np.random.uniform(1,5,(50,2))
x_data2 = np.random.uniform(3,9,(50,2))
x_data = np.concatenate([x_data1,x_data2])
#表示源数据的类别(K-NN算法处理基于监督学习的分类问题)
y_data = [0,1]*50
y_data = np.sort(y_data)
#产生训练集(源数据的百分之75)
x_train = np.split(x_data,[75])[0]
y_train = np.split(y_data,[75])[0]
#产生测试集(源数据的百分之25)
x_test = np.split(x_data,[75])[1]
y_test = np.split(y_data,[75])[1]
#绘制训练集
plt.scatter(x_train[y_train==0,0],x_train[y_train==0,1],color='g',label="symbol 0")
plt.scatter(x_train[y_train==1,0],x_train[y_train==1,1],color='r',label="symbol 1")
plt.title("k-NN view")
plt.xlabel("x axis")
plt.ylabel("y axis")
plt.legend()
plt.show()
#新增加一个数据判断其的类别为1还是0
x = np.array([4.1227123,7.26324127])
plt.scatter(x_train[y_train==0,0],x_train[y_train==0,1],color='g',label="symbol 0")
plt.scatter(x_train[y_train==1,0],x_train[y_train==1,1],color='r',label="symbol 1")
plt.scatter(x[0],x[1],color='b',label="symbol ?")
plt.title("k-NN view")
plt.xlabel("x axis")
plt.ylabel("y axis")
plt.legend()
plt.show()
#K-NN过程(计算距离,并将其存储到列表)
from math import sqrt
distances = []
for x0 in x_train:
d = sqrt(np.sum(x-x0)**2)
distances.append(d)
#将距离排序(由大到小)返回的是元素下标
near = np.argsort(distances)
k = 5
#选择出前5个最近元素的类别
topK_y = [y_train[i] for i in near[:k]]
from collections import Counter
#统计元素出现的个数
votes = Counter(topK_y)
#找出票数最多的一个元素,该方法返回的是一个元组,我们只需要第一个元素的横坐标(也就是类别)
result = votes.most_common(1)[0][0]
result
#注意这里用的是上面的数据,但是步骤是重新开始的因为要一个个遍历测试集并将预测结果与源数据中的结果比较得出正确率
#统计测试数据的精度
count = 0
index = 0
for j in x_test:
distance = []
x = j;
#计算距离
for x1 in x_train:
t = sqrt(np.sum((x-x1)**2))
distance.append(t)
near = np.argsort(distance)
topK_y = [y_train[i] for i in near[:k]]
votes = Counter(topK_y)
result = votes.most_common(1)[0][0]
if y_test[index]==result:
count=count+1
index=index+1
else:
index=index+1
score=count/25
score