【python】KNN(K近邻算法)实现及可视化

KNN(K近邻算法)实现及可视化

1 算法描述:

KNN的工作原理::给定一个已知标签类别的训练数据集,输入没有标签的新数据后,在训练数据集中找到与新数据最邻 近的k个实例,如果这k个实例的多数属于某个类别,那么新数据就属于这个类别。可以简单理解为:由那些离X最 近的k个点来投票决定X归为哪一类。

它的算法步骤为:(1) 计算已知类别数据集中的点与当前点之间的距离; (2) 按照距离递增次序排序; (3) 选取与当前点距离最小的k个点; (4) 确定前k个点所在类别的出现频率; (5) 返回前k个点出现频率最高的类别作为当前点的预测类别。

2 KNN算法的Python实现:

2.1 实践问题背景:

现要将目标分为四类,分别记为第0类、第1类、第2类、第3类。

2.2 目标:

给定目标向量,得出其所属类别。

image-20201126101741196

目标数据集是一个15行,每行有两个特征值的数据集。

2.3 数据集:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tsQIaCgx-1609429162595)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20201126101025891.png)]

数据集从上至下依次代表了第0类到第3类数据。每个数据集有50行数据,每行有两个特征值。

2.4 要求:

通过python实现k最近邻算法。

2.5 实施步骤:

① 准备数据:

# loadtxt()函数是读取txt 文件,注意被读取的文件需要数据文件要求每一行数据的格式相同
data1 = np.loadtxt('data1.txt')
#绘制散点图
#scatter中的参数,第一个为横轴值,第二个为纵轴值,第三个为点的颜色
plt.scatter(data1[:,0],data1[:,1],color="r")
data2 = np.loadtxt('data2.txt')
plt.scatter(data2[:,0],data2[:,1],color="g")
data3 = np.loadtxt('data3.txt')
plt.scatter(data3[:,0],data3[:,1],color="b")
data4 = np.loadtxt('data4.txt')
plt.scatter(data4[:,0],data4[:,1],color="k")
# 给定的目标向量
objdata = np.loadtxt('objdata.txt')
plt.scatter(objdata[:,0],objdata[:,1],color="y")
plt.show()

# objdata 为待预测的数据集,Trains是已知的数据集(该数据集的类别是四类,分别对应0,1,2,3)
#vstack()能够合并所读取的数据集
Trains = np.vstack([data1,data2,data3,data4])
#为已知数据集,创建分类标签。
TrainsClass = np.vstack([np.zeros((50,1)),np.ones((50,1)),2*np.ones((50,1)),3*np.ones((50,1))])

②计算已知类别数据集中的点与当前点之间的距离

# 开始假设k值 k=10
k=10
for i in range(15):
    # 求已知类别的值与位置类别点的距离
    dist = (((Trains - objdata[i,:])**2).sum(1))**0.5
    # 对算出的距离进行排序,由小到大,所排的内容是已知数据集数据的下标
    # 这个下标与已知数据集的标签下标一致,可以借此找到数据所对应的标签
    sortedDist = dist.argsort()

③将距离升序排列,然后选取距离最小的k个点。

    #classCount空字典是用来,做分类计数。这是判断最终分类结果的关键。
    classCount = {
   }
    # k =10
    for i in range(k):
        # voteLabel 获得的是Trains数据集的分类
        voteLabel = str(TrainsClass[sortedDist[i]])
        #get 获取字典的值,参数1为键,参数2为默认的值。默认值在键所对应的值不存在的时候被触发,返回的是键所对应的值。
        #确定前K个点所在类别的出现频率
        classCount[voteLabel] = classCount.get(voteLabel,0)+1

④选择频率最高的类别作为当前点的预测类别。

	maxType = 0
    maxCount = -1
    # 找出出现次数最多的类别
    for key,value in classCount.items()
  • 0
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面给您提供一个 Python 实现的 k-近邻算法示例: 首先,我们需要导入必要的库:numpy 用于矩阵计算和 matplotlib 用于可视化。 ```python import numpy as np import matplotlib.pyplot as plt ``` 接下来,我们定义一个函数用于计算测试数据点与训练数据集中各个数据点的欧式距离。 ```python def euclidean_distance(x1, x2): return np.sqrt(np.sum((x1 - x2)**2)) ``` 然后,我们定义一个 KNN 类,其中包含一个 fit 方法和一个 predict 方法。fit 方法用于训练模型,predict 方法用于预测测试数据点的标签。 ```python class KNN: def __init__(self, k=3): self.k = k def fit(self, X, y): self.X_train = X self.y_train = y def predict(self, X): predicted_labels = [self._predict(x) for x in X] return np.array(predicted_labels) def _predict(self, x): distances = [euclidean_distance(x, x_train) for x_train in self.X_train] k_indices = np.argsort(distances)[:self.k] k_nearest_labels = [self.y_train[i] for i in k_indices] most_common = Counter(k_nearest_labels).most_common(1) return most_common[0][0] ``` 在 predict 方法中,我们首先通过调用 _predict 方法来获得测试数据点的预测标签。在 _predict 方法中,我们计算测试数据点与训练数据集中各个数据点的距离,然后选择距离最近的 k 个数据点,获取它们的标签,并通过 Counter 类统计出现次数最多的标签,作为测试数据点的预测标签。 最后,我们使用 iris 数据集来测试我们的 KNN 算法。iris 数据集是一个经典的分类数据集,包含 3 种不同种类的鸢尾花,每个种类有 50 个样本,每个样本有 4 个特征。我们只使用其中的前两个特征和前 100 个样本来进行测试。 ```python from sklearn.datasets import load_iris from collections import Counter iris = load_iris() X = iris.data[:, :2] y = iris.target[:100] knn = KNN(k=3) knn.fit(X, y) # 绘制决策边界 x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1 y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1 xx, yy = np.meshgrid(np.arange(x_min, x_max, 0.1), np.arange(y_min, y_max, 0.1)) Z = knn.predict(np.c_[xx.ravel(), yy.ravel()]) Z = Z.reshape(xx.shape) plt.contourf(xx, yy, Z, alpha=0.5) plt.scatter(X[:, 0], X[:, 1], c=y, alpha=0.8) plt.xlabel('Sepal length') plt.ylabel('Sepal width') plt.show() ``` 运行上述代码,我们可以得到如下的决策边界图像: ![knn](https://img-blog.csdnimg.cn/20210611094912330.png) 在图像中,蓝色点表示第一类鸢尾花,红色点表示第二类鸢尾花。我们可以看到,KNN 算法成功将两种不同类别的鸢尾花分割开来。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值