目录
编辑
引言
KNN算法的数学基础
1. 距离度量
欧氏距离
曼哈顿距离
2. 寻找最近邻
3. 决策规则
分类
回归
4. 权重
KNN算法的实现步骤
1. 参数选择
2. 实现
导入必要的库
加载数据集
划分训练集和测试集
创建KNN模型
训练模型
预测测试集
计算准确率
结论
引言
K-Nearest Neighbors(KNN)算法是一种简单而强大的机器学习算法,它基于一个直观的概念:相似的实例倾向于有相似的标签。这种基于实例的学习意味着KNN不需要从训练数据中学习一个判别函数或决策规则;相反,它仅仅是将训练数据存储起来,并且在预测时寻找训练集中与新数据点最相似的实例。本文将详细介绍KNN算法的数学基础和实现步骤,帮助读者理解并实现这一算法。
KNN算法的数学基础
1. 距离度量
KNN算法的核心在于计算实例之间的距离。以下是几种常用的距离度量方法:
欧氏距离
欧氏距离是最常用的距离度量之一,它源自欧几里得几何学。对于两个点 ( x = (x_1, x_2, ..., x_n) ) 和 ( y = (y_1, y_2, ..., y_n) ),欧氏距离定义为:
[
d(x, y) =
]
这个公式计算了两点在n维空间中的直线距离。在实际应用中,欧氏距离因其直观性和计算简单而被广泛使用。它适用于许多不同类型的数据集,尤其是当所有特征都在同一尺度上并且对结果有相似影响时。
为了更好地理解欧氏距离的计算,我们可以添加一个简单的Python函数来计算两个点之间的欧氏距离:
import math
def euclidean_distance(x, y):
return math.sqrt(sum((a - b) ** 2 for a, b in zip(x, y)))
# 示例使用
point1 = (1, 2, 3)
point2 = (4, 5, 6)
print("欧氏距离:", euclidean_distance(point1, point2))
曼哈顿距离
曼哈顿距离,也称为城市街区距离,是另一种常用的距离度量方法。对于两个点 ( x ) 和 ( y ),曼哈顿距离定义为:
[
d(x, y) =
]
这个公式计算了两点在n维空间中的“街区”距离,即沿着坐标轴移动的总距离。曼哈顿距离在某些情况下比欧氏距离更具有鲁棒性,尤其是在特征空间的各个维度是正交的情况下。这种距离度量对于那些特征之间相互独立且对结果影响不同的数据集特别有用。
同样,我们可以编写一个Python函数来计算两个点之间的曼哈顿距离:
def manhattan_distance(x, y):
return sum(abs(a - b) for a, b in zip(x, y))
# 示例使用
point1 = (1, 2, 3)
point2 = (4, 5, 6)
print("曼哈顿距离:", manhattan_distance(point1, point2))
2. 寻找最近邻
在确定了距离度量方法后,下一步是寻找最近邻。对于一个新的实例,算法需要计算它与训练集中每个实例的距离,并找出距离最小的K个实例。这个过程可以通过遍历训练集中的所有实例来实现,然后根据计算出的距离进行排序,选择距离最小的K个实例。这一步骤是KNN算法中的关键,因为它直接影响到分类或回归的准确性。
为了实现这一步骤,我们可以编写一个函数来找到给定点的K个最近邻:
def find_k_nearest_neighbors(X_train, y_train, test_point, k):
distances = [(manhattan_distance(test_point, train_point), label) for train_point, label in zip(X_train, y_train)]
sorted_distances = sorted(distances, key=lambda x: x[0])
neighbors = sorted_distances[:k]
return neighbors
# 示例使用
X_train = [(1, 2), (3, 4), (5, 6), (7, 8)]
y_train = [0, 1, 0, 1]
test_point = (2, 3)
k = 2
k_nearest_neighbors = find_k_nearest_neighbors(X_train, y_train, test_point, k)
print("K个最近邻:", k_nearest_neighbors)
3. 决策规则
分类
在分类问题中,最常见的决策规则是多数投票法。即在K个最近邻中,出现次数最多的类别将被赋予新实例。这种方法简单直观,但在某些情况下可能需要更复杂的决策规则,例如加权投票,其中距离新实例更近的邻居具有更大的权重。加权投票可以提高分类的准确性,尤其是在数据集中的类别分布不均匀时。
为了实现多数投票法,我们可以编写一个函数来根据K个最近邻的标签进行预测:
def predict_classification(k_nearest_neighbors):
labels = [neighbor[1] for neighbor in k_nearest_neighbors]
most_common = max(set(labels), key=labels.count)
return most_common
# 示例使用
k_nearest_neighbors = [(1, 0), (2, 1), (3, 0)]
predicted_label = predict_classification(k_nearest_neighbors)
print("预测的标签:", predicted_label)
回归
在回归问题中,可以通过取K个最近邻的目标值的平均值来预测新实例的目标值。这种方法称为KNN回归,它是一种非参数方法,不需要对数据的分布做出任何假设。KNN回归对于捕捉数据中的局部模式非常有效,尤其是在数据集具有复杂结构时。
为了实现KNN回归,我们可以编写一个函数来计算K个最近邻的目标值的平均值:
def predict_regression(k_nearest_neighbors):
labels = [neighbor[1] for neighbor in k_nearest_neighbors]
return sum(labels) / len(labels)
# 示例使用
k_nearest_neighbors = [(1, 10), (2, 20), (3, 15)]
predicted_value = predict_regression(k_nearest_neighbors)
print("预测的值:", predicted_value)
4. 权重
在某些情况下,可以给不同的邻居分配不同的权重,这通常基于它们与新实例的距离。权重通常与距离成反比,即距离越近的邻居对预测结果的影响越大。这种方法称为加权KNN,它可以提高模型的预测精度。权重的分配可以是线性的,也可以是非线性的,具体取决于问题的性质和数据的特点。
为了实现加权KNN,我们可以修改预测函数来考虑权重:
def predict_weighted(k_nearest_neighbors):
total_weight = sum(1 / neighbor[0] for neighbor in k_nearest_neighbors)
weighted_sum = sum((neighbor[1] / neighbor[0]) for neighbor in k_nearest_neighbors)
return weighted_sum / total_weight
# 示例使用
k_nearest_neighbors = [(1, 10), (2, 20), (3, 15)]
predicted_value = predict_weighted(k_nearest_neighbors)
print("加权预测的值:", predicted_value)
KNN算法的实现步骤
1. 参数选择
KNN算法中的一个关键参数是K值的选择。K值的选择会影响模型的性能,通常需要通过交叉验证等方法来确定最优的K值。太小的K值可能会导致过拟合,而太大的K值可能会导致欠拟合。因此,选择合适的K值对于模型的性能至关重要。此外,距离度量的选择和权重的分配也是影响模型性能的重要因素。
为了选择最优的K值,我们可以使用交叉验证:
from sklearn.model_selection import cross_val_score
def select_optimal_k(X_train, y_train, max_k):
best_score = 0
best_k = 0
for k in range(1, max_k + 1):
knn = KNeighborsClassifier(n_neighbors=k)
scores = cross_val_score(knn, X_train, y_train, cv=5)
if scores.mean() > best_score:
best_score = scores.mean()
best_k = k
return best_k
# 示例使用
X_train = [[1, 2], [3, 4], [5, 6], [7, 8]]
y_train = [0, 1, 0, 1]
max_k = 10
optimal_k = select_optimal_k(X_train, y_train, max_k)
print("最优的K值:", optimal_k)
2. 实现
在实际编程实现中,可以使用各种编程语言和库,如Python中的scikit-learn库,它提供了KNN算法的实现。以下是使用Python实现KNN算法的详细步骤:
导入必要的库
首先,我们需要导入实现KNN所需的库,包括数据处理和模型训练所需的库。
from sklearn.neighbors import KNeighborsClassifier
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
加载数据集
接下来,我们加载一个标准的数据集,例如iris数据集,用于训练和测试KNN模型。
# 加载数据集
iris = load_iris()
X = iris.data
y = iris.target
划分训练集和测试集
为了评估模型的性能,我们需要将数据集划分为训练集和测试集。
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
创建KNN模型
然后,我们创建一个KNN分类器,并设置K值。
# 创建KNN模型,设置K=3
knn = KNeighborsClassifier(n_neighbors=3)
训练模型
使用训练集数据训练KNN模型。
# 训练模型
knn.fit(X_train, y_train)
预测测试集
使用训练好的模型对测试集进行预测。
# 预测测试集
y_pred = knn.predict(X_test)
计算准确率
最后,我们计算模型的准确率,以评估模型的性能。
# 计算准确率
accuracy = accuracy_score(y_test, y_pred)
print(f'Accuracy: {accuracy:.2f}')
结论
KNN算法以其简单性和有效性在机器学习领域占有一席之地。通过理解其数学基础和实现步骤,我们可以更好地应用这一算法解决实际问题。随着技术的发展,KNN算法也在不断地被优化和改进,以适应更复杂的数据和应用场景。