一. KNN算法简介
KNN算法(K-Nearest Neighbors)是一种基于实例的学习算法,它通过度量样本之间的相似性来进行分类或回归。
KNN算法的基本思想很简单:对于一个未知样本,它的类别或输出值可以通过与训练集中最近邻居的比较来确定。这里的"最近邻"是指距离新样本最近的K个训练集样本。
KNN算法的优点是简单易懂,不需要进行显式的训练过程,而且在处理非线性问题或数据较为复杂的情况下表现良好。
然而,KNN算法也有一些限制。例如,它在处理大规模数据时可能会变得较慢,因为需要计算新样本与所有训练样本之间的距离。此外,KNN算法对于特征的选择和处理、距离度量的选择等方面也需要谨慎考虑。
二. KNN算法步骤
- 计算新样本与训练集中每个样本之间的距离。距离可以使用欧几里德距离、曼哈顿距离或其他距离度量方法来衡量。(下面会提距离度量。)
- 选择距离最近的K个样本作为新样本的邻居。
- 对于分类问题,通过观察邻居的标签来确定新样本的类别。可以使用多数表决的方式,即选择邻居中最常见的类别作为新样本的类别。
- 对于回归问题,通过观察邻居的输出值来确定新样本的输出。可以使用平均值或加权平均值来计算邻居的输出,并将该值作为新样本的输出。
三. K值选择
在KNN算法中,K代表选择的邻居数量。K的选择是KNN算法中一个重要的超参数,需要根据具体问题和数据集进行调整。
当K的值较小时(比如K=1),模型对噪声敏感,可能会受到单个离群点的影响。这意味着预测结果可能不够稳定,可能会出现过拟合的情况。
当K的值较大时,模型对噪声的影响较小,更加平滑。然而,选择较大的K值可能会导致模型偏向于多数类别,可能会出现欠拟合的情况。
因此,在实践中,选择适当的K值是很重要的,通常通过交叉验证等技术来确定最佳的K值。
四. 距离度量
在KNN算法中,我们可以根据具体情况选择适当的距离度量方法来计算样本之间的距离。欧几里德距离也称为欧式距离,用于衡量样本在标准坐标系上的直线距离,计算公式如下:
d i s t a n c e = ( x 1 − x 2 ) 2 + ( y 1 − y 2 ) 2 distance = \sqrt{(x_1 - x_2)^2 + (y_1 - y_2)^2} distance=(x1−x2)2+(y1−y2)2
对于更高维度的情况,欧几里德距离的计算公式类似,将每个维度上的差值平方相加后取平方根。
曼哈顿距离也叫出租车距离,用来衡量样本在标准坐标系上的绝对轴距总和,计算公式如下:
d i s t a n c e = ∣ x 1 − x 2 ∣ + ∣ y 1 − y 2 ∣ distance = |x_1 - x_2| + |y_1 - y_2| distance=∣x1−x2∣+∣y1−y2∣
对于更高维度的情况,曼哈顿距离的计算公式将每个维度上的差值取绝对值后相加。
在sklearn
库中,我们可以通过指定metric
参数来选择使用欧几里德距离或曼哈顿距离,以及其他距离度量方法。
这些不同的距离度量方法可以根据问题的特点来选择,以获得更好的KNN算法性能。
下面是两个简单的代码实例,一个用于分类问题,另一个用于回归问题,以说明KNN算法的应用。
五. 代码实例
实例1:KNN分类
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
# 假设你有一个包含特征和标签的数据集
# 特征通常是一个二维数组,标签是一个一维数组
features = [[2, 4], [4, 6], [3, 7], [6, 2], [7, 4], [5, 8]]
labels = ['A', 'B', 'A', 'B', 'B', 'A']
# 将数据集拆分为训练集和测试集
train_features, test_features, train_labels, test_labels = train_test_split(features, labels, test_size=0.2)
# 创建KNN分类器对象,设定K值为3
knn = KNeighborsClassifier(n_neighbors=3, metric='euclidean')
# 在训练集上训练KNN分类器
knn.fit(train_features, train_labels)
# 使用训练好的分类器进行预测
predictions = knn.predict(test_features)
# 计算预测的准确率
accuracy = accuracy_score(test_labels, predictions)
print(f"测试标签: {test_labels}")
print(f"预测结果: {predictions}")
print(f"准确率: {accuracy}")
在这个代码实例中,我们使用了sklearn
库的KNeighborsClassifier
类来构建KNN分类器。我们使用了train_test_split
函数将数据集拆分为训练集和测试集,然后创建了一个KNN分类器对象,并设置K值为3,距离度量方法为欧几里德距离。接下来,我们使用训练集对KNN分类器进行训练,然后对测试集进行预测,并计算预测的准确率。
实例2:KNN回归
from sklearn.neighbors import KNeighborsRegressor
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
# 假设你有一个包含特征和目标值的数据集
# 特征通常是一个二维数组,目标值是一个一维数组
features = [[2, 4], [4, 6], [3, 7], [6, 2], [7, 4], [5, 8]]
targets = [5, 8, 9, 3, 2, 6]
# 将数据集拆分为训练集和测试集
train_features, test_features, train_targets, test_targets = train_test_split(features, targets, test_size=0.2)
# 创建KNN回归器对象,设定K值为3,并指定距离度量为曼哈顿距离
knn = KNeighborsRegressor(n_neighbors=3, metric='manhattan')
# 在训练集上训练KNN回归器
knn.fit(train_features, train_targets)
# 使用训练好的回归器进行预测
predictions = knn.predict(test_features)
# 计算预测结果的均方误差(Mean Squared Error,MSE)
mse = mean_squared_error(test_targets, predictions)
print(f"预测结果: {predictions}")
print(f"测试目标值: {test_targets}")
print(f"均方误差: {mse}")
我们使用sklearn
库的KNeighborsRegressor
类来构建KNN回归器。再使用train_test_split
函数将数据集拆分为训练集和测试集,然后创建了一个KNN回归器对象,并设置K值为3,距离度量方法为曼哈顿距离。接下来,我们使用训练集对KNN回归器进行训练,然后对测试集进行预测,并使用mean_squared_error
函数计算预测结果的均方误差(MSE)。