使用Python实现基于K-Nearest Neighbors (KNN)的分类算法
在机器学习领域,分类是监督学习的一种重要任务。它旨在根据已知的数据集(训练集)对未知数据进行类别划分。K-Nearest Neighbors(KNN)是一种简单而有效的分类算法,它通过计算待分类样本与训练集中所有样本的距离,选择距离最近的K个邻居,并根据这些邻居所属的类别来确定待分类样本的类别。
本文将详细介绍如何使用Python实现一个基本的KNN分类器,并结合实际案例进行说明。代码示例将采用Python语言,并利用numpy
库进行矩阵运算和matplotlib
库进行可视化展示。
KNN算法原理
KNN的核心思想非常直观:对于一个新的输入实例,在训练集中找到与该实例最相似的K个样本点,然后根据这K个样本点的多数表决决定新实例的类别。
具体步骤如下:
准备数据:收集并整理用于训练和测试的数据集。计算距离:通常使用欧氏距离(Euclidean Distance)、曼哈顿距离(Manhattan Distance)或马氏距离(Mahalanobis Distance)等度量方式来衡量两个样本之间的相似性。选择K个最近邻:根据计算出的距离排序,选取距离最小的K个样本作为参考对象。投票决策:统计K个邻居中每个类别的出现次数,选择出现频率最高的类别作为最终预测结果。Python实现
为了更好地理解KNN的工作机制,我们先从简单的二维平面中的点开始,构建一个模拟数据集,并编写相应的KNN分类函数。
1. 导入必要的库
import numpy as npimport matplotlib.pyplot as pltfrom collections import Counter
2. 创建模拟数据集
我们将创建一个包含两类不同颜色点的数据集,每类各50个随机分布的点。
def create_dataset(): # 类别A的数据点 class_A = np.random.randn(50, 2) + np.array([2, 2]) # 类别B的数据点 class_B = np.random.randn(50, 2) - np.array([2, 2]) # 合并成一个数据集 X = np.vstack((class_A, class_B)) y = np.hstack((np.zeros(len(class_A)), np.ones(len(class_B)))) return X, yX, y = create_dataset()plt.scatter(X[:, 0], X[:, 1], c=y, cmap='viridis')plt.show()
这段代码生成了一个由蓝色和橙色点组成的散点图,分别代表了两个不同的类别。接下来我们需要定义一个KNN分类器。
3. 定义KNN分类器
def knn_predict(test_point, X_train, y_train, k=3): """ 预测单个测试点的类别 参数: test_point (array-like): 测试点坐标 X_train (array-like): 训练集特征 y_train (array-like): 训练集标签 k (int): 最近邻居数量 返回: int: 预测类别 """ # 计算所有训练样本到测试点的距离 distances = np.sqrt(np.sum((X_train - test_point)**2, axis=1)) # 找到距离最小的k个索引 nearest_indices = np.argsort(distances)[:k] # 获取对应的标签 nearest_labels = y_train[nearest_indices] # 统计各类别出现次数最多的那个作为预测结果 most_common_label = Counter(nearest_labels).most_common(1)[0][0] return most_common_label
4. 测试KNN分类器
现在我们可以用刚才定义好的knn_predict
函数来对新的数据点进行分类了。为了更直观地看到效果,我们可以在原图基础上添加一些新点,并用不同颜色标记它们的实际类别以及预测类别。
# 新增几个测试点test_points = np.array([[0, 0], [2, 0], [-2, -2]])# 对每个测试点进行预测predictions = []for point in test_points: prediction = knn_predict(point, X, y, k=5) predictions.append(prediction)# 可视化结果colors = ['red' if pred == 0 else 'green' for pred in predictions]plt.scatter(X[:, 0], X[:, 1], c=y, cmap='viridis', alpha=0.6)plt.scatter(test_points[:, 0], test_points[:, 1], c=colors, marker='x', s=100, linewidths=2)plt.title('KNN Classification Results')plt.show()
上述代码会在原始散点图上用红色叉号表示被预测为类别A的新点,绿色叉号表示被预测为类别B的新点。你可以调整参数k
的值来看看不同情况下KNN的表现。
通过上述过程,我们不仅了解了KNN算法的基本原理,还亲手实现了这样一个简单但功能强大的分类工具。当然,实际应用中可能会遇到更多复杂的问题,比如高维数据处理、噪声干扰等。此外,选择合适的K值也非常重要,因为它直接影响到模型的泛化能力和准确性。因此,在面对真实世界的数据时,还需要结合交叉验证等方法不断优化我们的KNN模型。
KNN作为一种基础且易于理解的机器学习算法,为我们提供了一种快速入门机器学习的有效途径。希望这篇文章能够帮助读者加深对KNN的理解,并激发进一步探索其他高级算法的兴趣。