K-近邻算法的python实现代码分享

  • Post category:Python

下面是详细讲解“K-近邻算法的Python实现代码分享”的完整攻略。

K-近邻算法

K-近邻算法是一种常用的分类算法,其基本思想是在训练集中找到与测试样本最近的K个样本,然后根据这K个样本的类别投票,将测试样本归为票数最多的类别。

下面是一个Python实现K-近邻算法的示例:

import numpy as np

def knn(X_train, y_train, X_test, k=3):
    distances = []
    for i in range(len(X_train)):
        distance = np.sqrt(np.sum(np.square(X_test - X_train[i, :])))
        distances.append([distance, i])
    distances = sorted(distances)
    k_neighbors = [y_train[distances[i][1]] for i in range(k)]
    return max(k_neighbors, key=k_neighbors.count)

X_train = np.array([[1, 2], [2, 3], [3, 1], [4, 2]])
y_train = np.array([0, 0, 1, 1])
X_test = np.array([3, 2])

prediction = knn(X_train, y_train, X_test, k=3)
print("Prediction: ", prediction)

上述代码中,首先定义了一个knn函数,函数接受训练集X_train、训练集标签y_train、测试集X_test和K值k。在函数中,计算测试样本与训练样本之间的距离,并将距离和训练样本的索引存储在distances列表中。然后,对distances列表进行排序,并选取前K个距离最近的训练样本的标签,将其存储在k_neighbors列表中。最后,返回k_neighbors中出现次数最多的标签。

然后,定义了一个训练集X_train、训练集标签y_train和测试集X_test。在本例中,训练集包含4个样本,每个样本有2个特征,标签分别为0和1。测试集包含1个样本,也有2个特征。

最后,使用测试集调用knn函数,计算测试样本的标签。

K-近邻算法的优化

K-邻算法的计算复杂度较高,因为需要计算测试样本与所有训练样本之间的距离。为了提高算的效率,可以使用KD树来优化K-近邻算法。

下面是一个使用KD树优化K-近邻算法的Python示例:

from collections import Counter
import numpy as np

class KDTree:
    def __init__(self, data, depth=0):
        if len(data) > 0:
            k = len(data[0])
            axis = depth % k
            sorted_data = sorted(data, key=lambda x: x[axis])
            mid = len(sorted_data) // 2
            self.location = sorted_data[mid]
            self.left_child = KDTree(sorted_data[:mid], depth+1)
            self.right_child = KDTree(sorted_data[mid+1:], depth+1)
        else:
            self.location = None
            self.left_child = None
            self.right_child = None

    def search_knn(self, point, k=3, dist_func=lambda x, y: np.sqrt(np.sum(np.square(x - y)))):
        knn = []
        self._search_knn(point, k, knn, dist_func)
        return [x[1] for x in sorted(knn)]

    def _search_knn(self, point, k, knn, dist_func):
        if self.location is None:
            return
        distance = dist_func(point, self.location)
        if len(knn) < k:
            knn.append((distance, self.location))
        elif distance < knn[-1][0]:
            knn.pop()
            knn.append((distance, self.location))
        axis = len(point) % len(self.location)
        if point[axis] < self.location[axis]:
            self.left_child._search_knn(point, k, knn, dist_func)
        else:
            self.right_child._search_knn(point, k, knn, dist_func)

def knn(X_train, y_train, X_test, k=3):
    tree = KDTree(X_train)
    knn_indices = tree.search_knn(X_test, k=k)
    k_neighbors = [y_train[i] for i in knn_indices]
    return Counter(k_neighbors).most_common(1)[0][0]

X_train = np.array([[1, 2], [2, 3], [3, 1], [4, 2]])
y_train = np.array([0, 0, 1, 1])
X_test = np.array([3, 2])

prediction = knn(X_train, y_train, X_test, k=3)
print("Prediction: ", prediction)

上述代码中,首先定义了一个KDTree类,该类用于构建KD树。在类的构造函数中,根据当前深度选择划分的维度,然后将数据集按照该维度排序,并选择中位数作为当前节点的位置。然后,递归构建左子树和右子树。

然后,定义了一个search_knn方法,该方法用于搜索距离测试样本最近的K个训练样本。在方法中,使用递归搜索KD树,找到距离测试样本最近的K个训练样本,并将其存储在knn列表中。

最后,定义了一个knn函数,该函数接受训练集X_train、训练集标签y_train、测试集X_test和K值k。在函数中,使用KD树搜索距离测试样本最近的K个训练样本的标签,并返回出现次数最多的标签。

然后,定义了一个训练集X_train、训练集标签y_train和测试集X_test。在本例中,训练集包4个样本,每个样本有2个特征,标签分别为0和1。测试集包含1个样本,也有2个征。

最后,使用测试集调用knn函数,计算测试样本的标签。

总结

K-近邻算法是一种常用的分类算法,可以使用KD树来优化算法的效率。Python中可以使用NumPy库和collections库进行实现。在实现过程中,需要定义KDTree类和knn函数,并使用递归KD树,找到距离测试样本最近的K个训练样本的标签。