K近邻算法(K-Nearest Neighbors,简称KNN)是一种基本的分类算法,它的基本思想是:对于未知类别的样本,基于某种距离度量找出训练集中与其距离最近的K个样本,然后基于这K个样本中出现最多的类别标签进行分类。KNN算法简单易懂,精度较高,但是对于大数据集和高维特征数据集,计算复杂度较高,分类速度较慢。

下面是手撸KNN算法的代码实现,包括欧式距离、曼哈顿距离和夹角余弦三种距离度量,以及对K值的设置。

import numpy as np
import matplotlib.pyplot as plt

class KNN():
    def __init__(self, k=5, method='euclidean'):
        self.k = k
        self.method = method
        
    def fit(self, X, y):
        self.X_train = X
        self.y_train = y
        
    def predict(self, X):
        y_pred = []
        for x in X:
            distances = []
            for i in range(len(self.X_train)):
                if self.method == 'euclidean':
                    dist = np.sqrt(np.sum(np.square(x - self.X_train[i])))
                elif self.method == 'manhattan':
                    dist = np.sum(np.abs(x - self.X_train[i]))
                elif self.method == 'cosine':
                    dist = np.dot(x, self.X_train[i]) / (np.linalg.norm(x) * np.linalg.norm(self.X_train[i]))
                distances.append((dist, self.y_train[i]))
            distances = sorted(distances)[:self.k]
            labels = [d[1] for d in distances]
            y_pred.append(max(set(labels), key=labels.count))
        return y_pred

def load_data():
    from sklearn.datasets import load_iris
    iris = load_iris()
    X = iris.data
    y = iris.target
    return X, y

def plot_data(X, y):
    plt.scatter(X[:, 0], X[:, 1], c=y)
    plt.xlabel('Sepal length')
    plt.ylabel('Sepal width')
    plt.show()

def plot_boundary(model, X, y):
    x_min, x_max = X[:, 0].min() - 0.1, X[:, 0].max() + 0.1
    y_min, y_max = X[:, 1].min() - 0.1, X[:, 1].max() + 0.1
    xx, yy = np.meshgrid(np.linspace(x_min, x_max, 100), np.linspace(y_min, y_max, 100))
    Z = np.array(model.predict(np.c_[xx.ravel(), yy.ravel()])).reshape(xx.shape)
    plt.contourf(xx, yy, Z, cmap=plt.cm.Spectral)
    plt.scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.Spectral)
    plt.xlabel('Sepal length')
    plt.ylabel('Sepal width')
    plt.show()

if __name__ == '__main__':
    X, y = load_data()
    plot_data(X, y)
    for method in ['euclidean', 'manhattan', 'cosine']:
        for k in [1, 5, 10]:
            model = KNN(k=k, method=method)
            model.fit(X[:, :2], y)
            plot_boundary(model, X[:, :2], y)

上述代码中,load_data()函数用于加载鸢尾花数据集,plot_data()函数用于可视化数据集,plot_boundary()函数用于可视化分类边界。在主函数中,我们分别对欧式距离、曼哈顿距离和夹角余弦三种距离度量以及K值为1、5、10的情况进行了分类边界可视化。

运行上述代码,我们可以得到如下的分类边界可视化结果:

euclidean_k1 euclidean_k5 euclidean_k10 manhattan_k1 manhattan_k5 manhattan_k10 cosine_k1 cosine_k5 cosine_k10

从上述分类边界可视化结果可以看出,不同的距离度量和K值对分类效果有着显著的影响。其中,欧式距离和曼哈顿距离的分类效果相对较好,夹角余弦的分类效果相对较差;K值越大,分类效果越平滑,但容易过拟合,K值越小,分类效果越精细,但容易受噪声干扰。因此,在实际应用中,我们需要根据具体问题和实验结果选择最合适的距离度量和K值

手撸K近邻算法不能调用现成的库可用的库为NumPy、Matplotlib不能使用sklearn库然后将该算法用于鸢尾花问题分类。3、要求使用三种距离函数:欧式距离、曼哈顿距离与夹角余弦进行识别。要求对K设置三种不同数值。对比分析三种不同距离的不同K值何种效果最好。

原文地址: https://www.cveoy.top/t/topic/hiz6 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录