k-近邻算法(k-Nearest Neighbors, k-NN)是一种基本且广泛使用的分类与回归算法。它的工作原理非常直观:通过测量不同特征点之间的距离,来进行分类或回归分析。
1.K-NN算法
基本概念
1.基于实例的学习:k-NN是一种基于实例的学习,意味着它直接记忆训练数据集,并通过这些数据进行预测,而不需要明确地学习一个模型。
2.懒惰学习(Lazy Learning):k-NN属于懒惰学习算法,因为它基本上不在训练阶段进行计算,而是将所有的计算推迟到分类阶段。
3.非参数方法:k-NN是一种非参数方法,这意味着它不对数据的分布做任何假设。这是一个优点,因为它不需要先验知识关于数据分布的形式。
工作原理
1.选择邻居数目(k值):算法运行时,首先需要指定“k”,即最近邻居的数目。k是一个预先选定的常数,通常是一个较小的整数。k的选择会影响算法的结果。
2.计算距离:计算查询点(即测试点)与每个训练数据点之间的距离。常用的距离度量包括欧氏距离、曼哈顿距离或余弦距离等。
3.识别最近的k个邻居:选择距离最近的k个训练数据点作为最近邻。
4.进行投票或平均:
-
分类:在k个最近邻中,根据多数投票原则来决定新数据点的类别。即在这k个邻居中,哪个类别的元素最多,新数据点就被标记为那个类别。
-
回归:如果用于回归,通常是计算这k个邻居的输出变量的平均值,来预测新数据点的输出。
应用
-
k-NN可以用在许多类型的数据场景中,包括政治科学、手写识别、图像识别和视频识别等领域。
-
在金融行业中,k-NN可用于信用评分和预测公司破产。
-
在医疗领域,k-NN被用来预测疾病的发展和分类疾病类型。
优缺点
-
优点:简单易懂;理论成熟;易于实现;不需要假设数据分布,适用于复杂或真实的数据集。
-
缺点:计算量大,尤其是在有大量训练数据的情况下;对不相关的功能或噪音敏感;k值的选择和距离度量的选择可能会显著影响性能。
因此,k-NN虽然是一个简单有效的算法,但在使用时需要仔细选择参数,并考虑其对大数据集的计算和存储影响。
2.k-NN 算法的简单理解:水果分类
假设有一篮子水果,水果可以是苹果、梨或橙子。每种水果我们都测量了两个属性:重量和颜色深浅(这里简化颜色深浅为一个从 0 到 1 的数值,0 是最浅,1 是最深)。现在有一些标记好的水果数据(即知道每个数据点是哪种水果),你想用这些数据来帮助你分类一些新的水果。
已知的标记数据示例:
重量(克) | 颜色深浅 | 类型 |
---|---|---|
150 | 0.8 | 苹果 |
170 | 0.5 | 梨 |
140 | 0.9 | 苹果 |
130 | 0.4 | 橙子 |
160 | 0.7 | 梨 |
新的水果数据:
重量(克) | 颜色深浅 |
---|---|
145 | 0.6 |
k-NN 算法操作步骤:
1.选择 k 的值:在这个例子中,选择 k = 3,意味着将查找三个最近的邻居。
2.计算距离:使用欧氏距离来计算新水果与已知标记数据之间的距离。例如,计算新水果与第一个苹果的距离:
类似地,计算与所有水果的距离。
3.找到最近的 k 个邻居:根据计算出的距离,找出最近的三个水果。
4.进行投票:看这三个最近的水果中哪种类型最多。假设最近的三个水果是两个梨和一个苹果,那么新的水果将被分类为“梨”。
可视化解释:
可以把这些水果想象成散布在一个图表上的点,其中横轴是重量,纵轴是颜色深浅。新水果也是图表上的一个点,而找到的最近的三个点(邻居)决定了这个新点(新水果)的类别。
通过这个简单的例子,k-NN 的直观含义就是“告诉我你的朋友是谁,我就告诉你你是谁”——一个事物通常与它最近的几个其他事物类似。这种方法不需要一个复杂的模型,只是简单地查找最近的已知点,并基于它们的类型来决定新点的类型。这使得 k-NN 成为一个易于实现且直观的机器学习算法。
3.k-NN 算法实例
import numpy as np # 数据操作
import matplotlib.pyplot as plt # 可视化
from sklearn import datasets # 生成模拟数据
from sklearn.model_selection import train_test_split # 将数据分为训练集和测试集
from sklearn.neighbors import KNeighborsClassifier # 实现k-NN算法的类
from sklearn.metrics import accuracy_score # 计算模型的准确度
# 生成数据
X, y = datasets.make_classification(n_features=2, n_redundant=0, n_informative=2,random_state=1, n_clusters_per_class=1, n_samples=100) # 生成一个随机的二分类数据集,其中包含100个样本,每个样本有2个特征
rng = np.random.RandomState(2)
X += 2 * rng.uniform(size=X.shape) # 向数据中添加一些随机噪声,使得数据分布更加自然,不完全线性可分
# 划分数据集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) # 将数据随机分为训练集和测试集,其中测试集占20%
# 创建k-NN分类器实例
k = 3 # 邻居数k为3
classifier = KNeighborsClassifier(n_neighbors=k)
# 训练模型
classifier.fit(X_train, y_train)
# 预测测试集
y_pred = classifier.predict(X_test)
# 计算并打印准确率
print("Accuracy:", accuracy_score(y_test, y_pred))
# 可视化结果
plt.figure(figsize=(10, 6))
plt.title("k-NN classification with k=" + str(k))
# 绘制训练集
plt.scatter(X_train[:, 0], X_train[:, 1], c=y_train, cmap='winter', marker='o', edgecolor='k', label='Train Data')
# 绘制测试集
plt.scatter(X_test[:, 0], X_test[:, 1], c=y_pred, cmap='winter', marker='s', edgecolor='k', label='Test Data')
# 绘制图例
plt.legend(loc='best')
plt.show()
可视化结果中,圆点代表训练数据,方点代表测试数据。
以上内容总结自网络,如有帮助欢迎转发,我们下次再见!